Merge jdk7u10-b30 into jdk7u12-b08
diff --git a/.hgtags b/.hgtags
index ced78cf..6b8fbe4 100644
--- a/.hgtags
+++ b/.hgtags
@@ -1,3 +1,30 @@
+358bf28f0e052ce5e362fdbf2af89c9aaf987e2f jdk7u10-b10
+13b3e32dde73b7e2e20ca74bcaac0448331518f2 jdk7u10-b11
+676d115cc02ac026b57d7d63239234c285956147 jdk7u10-b12
+4412577327063059f38812ccb3f06fceae039025 jdk7u10-b13
+870359fa1a77c1c2d19e72569c19b16461bab69a jdk7u10-b14
+01eac5326250f26369f6007e9642c323d26574e5 jdk7u10-b15
+3094a2adfe444e174c76b9e6a2d21847419d5b21 jdk7u10-b16
+0f3bcce55b0dc5bb36d5421b435a42a854c69190 jdk7u10-b17
+745247b0fc1e5fb9acef2669f6ee47da4d7128bf jdk7u10-b18
+9e73da607cfb89b1ebbd28590946af8b0cc5a7aa jdk7u10-b30
+fa3c94f451aa75502d11626a92a05b55bb87ea68 jdk7u7-b31
+4c6c513d0b52115ceda28e54b4ce0365e2475130 jdk7u6-b15
+30b9f362a476be4d7c03b0ab237a11be04b22851 jdk7u9-b01
+3b7a52308244da5c0a6356c09f90b53996b188e1 jdk7u9-b02
+7e28633611298b11497023e49ae67612a17e4c54 jdk7u9-b03
+941237cb8dc53b2295c8980396fbe8c64ee4ed9f jdk7u9-b04
+1dab2accf9dfc7b0b2856e2285677f5764da9b95 jdk7u9-b05
+973925dd07da2684f5aad9a2e8d31c8d3277570f jdk7u9-b31
+4517fcbb20ddc84ad68ee6b9e1fb4b0c0aceeeab jdk7u6-b30
+b4b414c07a7638d55472022f32aec63f0fadcf47 jdk7u6-b31
+68bfec67eb509e560426e7ca7b368138ec7a4364 jdk7u7-b10
+9fb01e023f78723dcc04e58f5fab7ba243a3fdd3 jdk7u7-b30
+6d56303e56cc8801da47140efd70c4b23335f1c3 jdk7u7-b11
+e133f20053851a5427d3d0700f2e2b4d8d2e27f6 jdk7u6-b24
+e5fbf5c6d121f1a3a22c2652b2a76ee8da490e44 jdk7u6-b21
+c2f7c1f26f8ca402bba397eb2cb39fc9679cce9e jdk7u8-b01
+229b1bc58d327e85d0a7ee85995dd5bc4ee174c1 jdk7u8-b02
 18229aa2e517d3d4558b2cbb21eddd5d63bedb40 jdk7u5-b01
 419630c67deb2216efcf375e25de089efce03158 jdk7u5-b02
 126956f82e1743f2f78df75da2e59077a6f8d8cb jdk7u4-b21
@@ -195,13 +222,17 @@
 4fcde9777e660274e898be8853d3e47797e8d061 jdk7u6-b20
 9378fcd3afb946e1c1f2340a51ebb65697399c9e jdk7u6-b22
 00b0ecdd286137f211cd2ddbbcda98a02c01506a jdk7u6-b23
-358bf28f0e052ce5e362fdbf2af89c9aaf987e2f jdk7u10-b10
-13b3e32dde73b7e2e20ca74bcaac0448331518f2 jdk7u10-b11
-676d115cc02ac026b57d7d63239234c285956147 jdk7u10-b12
-4412577327063059f38812ccb3f06fceae039025 jdk7u10-b13
-870359fa1a77c1c2d19e72569c19b16461bab69a jdk7u10-b14
-01eac5326250f26369f6007e9642c323d26574e5 jdk7u10-b15
-3094a2adfe444e174c76b9e6a2d21847419d5b21 jdk7u10-b16
-0f3bcce55b0dc5bb36d5421b435a42a854c69190 jdk7u10-b17
-745247b0fc1e5fb9acef2669f6ee47da4d7128bf jdk7u10-b18
-9e73da607cfb89b1ebbd28590946af8b0cc5a7aa jdk7u10-b30
+22ff36b9663cb4f479cc77684a0fdc19347f0b8b jdk7u8-b03
+1509fa37aa0f3ed29690d364f434de6eaedcf1c6 jdk7u8-b04
+31ddf7e22c975bbe0c652fcc0a349a5c8d338d3f jdk7u8-b05
+2ce690f9ace62d771a17649195baf7637196ac64 jdk7u10-b06
+990382043a4ccfeffbc465733764d4c9dd086066 jdk7u10-b07
+b0bdc3f8e737dcab8841342be38fefa87e642ec1 jdk7u10-b08
+445ae2301135aa9615deea1184f928f66ef59d6d jdk7u10-b09
+dfb6437cb5783bc7d56ccc96edb07edd9b73f0a9 jdk7u12-b01
+c295534e3ca4db0c3499b3595582b14a3f0dce91 jdk7u12-b02
+c17a6d8fa58c45d5fa36df164a862795411f9681 jdk7u12-b03
+fd6788251040b57b05a54bc843853555e9c7f73d jdk7u12-b04
+7fdff8f54b99a0b4cb82d6226f347c9323f09164 jdk7u12-b05
+d3e88043ace2cf3f2078315b7453b3044ddeba0e jdk7u12-b06
+a351be5b537af8bf265089f38477a7be340056e9 jdk7u12-b07
diff --git a/.hgtags-top-repo b/.hgtags-top-repo
index bace189..abfeb38 100644
--- a/.hgtags-top-repo
+++ b/.hgtags-top-repo
@@ -199,6 +199,7 @@
 d1c709f1196a73d1df10d04a221b10e30fd2eb48 jdk7u6-b23
 e4def733cc8c58e83b7cefa7edd89a3e2b793520 jdk7u6-b24
 f5f546dba006778854e7a81141fc1b44acd257a4 jdk7u6-b30
+43775eae8df6c874fb3631c86009505cf3821b1f jdk7u6-b31
 43775eae8df6c874fb3631c86009505cf3821b1f jdk7u7-b10
 a380c75873bfb578e605d4362edb18c08698cc3e jdk7u7-b30
 d7f2b3949f9c9ff1115ea61c496d3cd4c62e2759 jdk7u7-b11
@@ -221,3 +222,20 @@
 c8a37a49fc90ae31b864544d6d4a9f6137d4995d jdk7u10-b16
 494e838439db7f0f4e36f7dcfeba06d2bef78c8d jdk7u10-b17
 dce9058d2151e6b5c84898c13cfd1521a627a296 jdk7u10-b18
+b5fb925394331313dbe3859fdc408bfd37193476 jdk7u10-b30
+1ab3edf5061fdde3a6f6510373a92444445af710 jdk7u8-b01
+d7a94c8cbbbfadbd9e2f3e4737eb7deb572dedc9 jdk7u8-b02
+e7c504c99ab60e3b21cdc9460afaa3926d53cff1 jdk7u8-b03
+996e3145029120fd6ef2cacb3d03cb1f20862247 jdk7u8-b04
+891689cc39ff9d67bc4fe43bcb91ecdabda1f9f8 jdk7u8-b05
+f16343fe14acb4118f0a3f78fd735a4a6133c76a jdk7u10-b06
+1fa71ffbbd596086dbade86505d2d7e1c436de76 jdk7u10-b07
+e7014c55a9e55c10fe4f91ca092eb01029c36c75 jdk7u10-b08
+aaf495a24a9bb996b3955e52edff8d93ff62dc5f jdk7u10-b09
+3eddc50eb3574bf4cff4081310fd763e958ed073 jdk7u12-b01
+207c000ac697d052f84cde6e782865b209e60239 jdk7u12-b02
+a3917db5d568d9805b3c46ce67c39c475cf10e0e jdk7u12-b03
+52945b197d7c93d215067034a45e5e9452c67f78 jdk7u12-b04
+eae53fe51e79e04ca28b5790a6ae25d39a06b0ab jdk7u12-b05
+a008905ce525b88e5bdc80fe6ad7570f6f6a19ac jdk7u12-b06
+c3e42860af1cfd997fe1895594f652f0d1e9984e jdk7u12-b07
diff --git a/corba/.hgtags b/corba/.hgtags
index 3f86938..dd6be82 100644
--- a/corba/.hgtags
+++ b/corba/.hgtags
@@ -199,6 +199,7 @@
 2a8376123fbb81bc4b2f643ff7cfaf7f87b21c35 jdk7u6-b23
 02512f61591f55d84458d1ea4ce84eecb7324f89 jdk7u6-b24
 8b20875b3faa01ef56331045de88747df278eaeb jdk7u6-b30
+d7fe6c13adf9e06d98c061449d171bc06c2ba0a3 jdk7u6-b31
 d7fe6c13adf9e06d98c061449d171bc06c2ba0a3 jdk7u7-b10
 496baf62d0550c704505b0ff6f390279f6a569e0 jdk7u7-b30
 e57e4274a3575f278115cc8ef03c5bdf3c43a7ed jdk7u7-b11
@@ -221,3 +222,20 @@
 64f09d7549d304fbfd3c29b4f148bf44e8e3e979 jdk7u10-b16
 57c3355153d1624fd98618097c1a82ab3ffc66f8 jdk7u10-b17
 f2a347637a55fa4de9542a8dcab72ad6fac44d2b jdk7u10-b18
+22cf8bc2ec47498fe548b308a81be0486dd7e3d0 jdk7u10-b30
+353c15c4bc371f2f8258344c988d1403477cc140 jdk7u8-b01
+d17ca8d088f7cc0dd42230472f534c8d1e415bcb jdk7u8-b02
+7c62cfa17e9613bf69d4f9b2ae74f3724d7a2955 jdk7u8-b03
+86961c802e87688ff264a946ca647d062f538302 jdk7u8-b04
+a274cd0c309b4da766dc73cac644cb44f1c23787 jdk7u8-b05
+292eab1079e7b62db7cf848781eddf1b6fc718e5 jdk7u10-b06
+ff5e33bcfc2bb7c2a69cd20b91490922eb158af2 jdk7u10-b07
+76811225baeccd3ed77a3e2ec7745ba3d42acff5 jdk7u10-b08
+f8e8ef8e0a5eea83938dab38d9a8cf6354f5a92d jdk7u10-b09
+3f309ff1d8ecd0210340ae9cfb40cc9072f66757 jdk7u12-b01
+06a04d95a12f18f07610f5d787324e2ea15e6376 jdk7u12-b02
+665ee21ff3ef309147e7f7872e2d4f446a31b642 jdk7u12-b03
+f89f101d3dfea98b143b693cebccdefc89b691ff jdk7u12-b04
+2516fd4adf4af010c217e073cdb0a1fa9eefd827 jdk7u12-b05
+16287175b517e48da9b24d31a3e9da200b6bc563 jdk7u12-b06
+7969d5f219248de033c296ef75fff7aae7545bbd jdk7u12-b07
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaResponseWaitingRoomImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaResponseWaitingRoomImpl.java
index ce0752d..57104f2 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaResponseWaitingRoomImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/CorbaResponseWaitingRoomImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,10 @@
 
 package com.sun.corba.se.impl.transport;
 
-import java.util.Hashtable;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
 
 import org.omg.CORBA.CompletionStatus;
 import org.omg.CORBA.SystemException;
@@ -68,7 +71,7 @@
 
     private CorbaConnection connection;
     // Maps requestId to an OutCallDesc.
-    private Hashtable out_calls = null; // REVISIT - use int hastable/map
+    final private Map<Integer, OutCallDesc> out_calls;
 
     public CorbaResponseWaitingRoomImpl(ORB orb, CorbaConnection connection)
     {
@@ -76,7 +79,8 @@
         wrapper = ORBUtilSystemException.get( orb,
             CORBALogDomains.RPC_TRANSPORT ) ;
         this.connection = connection;
-        out_calls = new Hashtable();
+        out_calls =
+            Collections.synchronizedMap(new HashMap<Integer, OutCallDesc>());
     }
 
     ////////////////////////////////////////////////////
@@ -139,7 +143,7 @@
             return null;
         }
 
-        OutCallDesc call = (OutCallDesc)out_calls.get(requestId);
+        OutCallDesc call = out_calls.get(requestId);
         if (call == null) {
             throw wrapper.nullOutCall(CompletionStatus.COMPLETED_MAYBE);
         }
@@ -197,7 +201,7 @@
         LocateReplyOrReplyMessage header = (LocateReplyOrReplyMessage)
             inputObject.getMessageHeader();
         Integer requestId = new Integer(header.getRequestId());
-        OutCallDesc call = (OutCallDesc) out_calls.get(requestId);
+        OutCallDesc call = out_calls.get(requestId);
 
         if (orb.transportDebugFlag) {
             dprint(".responseReceived: id/"
@@ -248,7 +252,6 @@
 
     public int numberRegistered()
     {
-        // Note: Hashtable.size() is not synchronized
         return out_calls.size();
     }
 
@@ -264,29 +267,41 @@
             dprint(".signalExceptionToAllWaiters: " + systemException);
         }
 
-        OutCallDesc call;
-        java.util.Enumeration e = out_calls.elements();
-        while(e.hasMoreElements()) {
-            call = (OutCallDesc) e.nextElement();
+        synchronized (out_calls) {
+            if (orb.transportDebugFlag) {
+                dprint(".signalExceptionToAllWaiters: out_calls size :" +
+                       out_calls.size());
+            }
 
-            synchronized(call.done){
-                // anything waiting for BufferManagerRead's fragment queue
-                // needs to be cancelled
-                CorbaMessageMediator corbaMsgMediator =
-                             (CorbaMessageMediator)call.messageMediator;
-                CDRInputObject inputObject =
-                           (CDRInputObject)corbaMsgMediator.getInputObject();
-                // IMPORTANT: If inputObject is null, then no need to tell
-                //            BufferManagerRead to cancel request processing.
-                if (inputObject != null) {
-                    BufferManagerReadStream bufferManager =
-                        (BufferManagerReadStream)inputObject.getBufferManager();
-                    int requestId = corbaMsgMediator.getRequestId();
-                    bufferManager.cancelProcessing(requestId);
+            for (OutCallDesc call : out_calls.values()) {
+                if (orb.transportDebugFlag) {
+                    dprint(".signalExceptionToAllWaiters: signaling " +
+                            call);
                 }
-                call.inputObject = null;
-                call.exception = systemException;
-                call.done.notify();
+                synchronized(call.done) {
+                    try {
+                        // anything waiting for BufferManagerRead's fragment queue
+                        // needs to be cancelled
+                        CorbaMessageMediator corbaMsgMediator =
+                                     (CorbaMessageMediator)call.messageMediator;
+                        CDRInputObject inputObject =
+                                   (CDRInputObject)corbaMsgMediator.getInputObject();
+                        // IMPORTANT: If inputObject is null, then no need to tell
+                        //            BufferManagerRead to cancel request processing.
+                        if (inputObject != null) {
+                            BufferManagerReadStream bufferManager =
+                                (BufferManagerReadStream)inputObject.getBufferManager();
+                            int requestId = corbaMsgMediator.getRequestId();
+                            bufferManager.cancelProcessing(requestId);
+                        }
+                    } catch (Exception e) {
+                    } finally {
+                        // attempt to wake up waiting threads in all cases
+                        call.inputObject = null;
+                        call.exception = systemException;
+                        call.done.notifyAll();
+                    }
+                }
             }
         }
     }
@@ -294,7 +309,7 @@
     public MessageMediator getMessageMediator(int requestId)
     {
         Integer id = new Integer(requestId);
-        OutCallDesc call = (OutCallDesc) out_calls.get(id);
+        OutCallDesc call = out_calls.get(id);
         if (call == null) {
             // This can happen when getting early reply fragments for a
             // request which has completed (e.g., client marshaling error).
diff --git a/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java b/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java
index 277657e..39fb4fe 100644
--- a/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java
+++ b/corba/src/share/classes/com/sun/corba/se/impl/transport/SocketOrChannelConnectionImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -1521,7 +1521,7 @@
             // connection and give them the SystemException;
 
             responseWaitingRoom.signalExceptionToAllWaiters(systemException);
-
+        } finally {
             if (contactInfo != null) {
                 ((OutboundConnectionCache)getConnectionCache()).remove(contactInfo);
             } else if (acceptor != null) {
@@ -1542,7 +1542,6 @@
 
             writeUnlock();
 
-        } finally {
             if (orb.transportDebugFlag) {
                 dprint(".purgeCalls<-: "
                        + minor_code + "/" + die + "/" + lockHeld
diff --git a/get_source.sh b/get_source.sh
index bc609b3..24dca4a 100644
--- a/get_source.sh
+++ b/get_source.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,7 @@
 #
 
 # Get clones of all nested repositories
-sh ./make/scripts/hgforest.sh clone
+sh ./make/scripts/hgforest.sh clone $*
 
 # Update all existing repositories to the latest sources
 sh ./make/scripts/hgforest.sh pull -u
diff --git a/hotspot/.hgtags b/hotspot/.hgtags
index 486a4d9..9786173 100644
--- a/hotspot/.hgtags
+++ b/hotspot/.hgtags
@@ -320,6 +320,7 @@
 df57f6208cb76b4e8d1a0bd0eea3d2ad577cb79b jdk7u6-b23
 b03c2687fb16514652e79261ad68d2c601dcee62 jdk7u6-b24
 cffde29ea7cc8647f17002a4d0e94065dcd82839 jdk7u6-b30
+7566374c3c89b7d99be9bcdb9342283a3bea6930 jdk7u6-b31
 f7933fecea9aa494e4032e17ff07e5fcec4b5961 jdk7u7-b10
 eeef33dc4b40f9ba50c4c9b1ac61b30f0f2523bf jdk7u7-b30
 f1551c70c7f598b7049bcc33e530fc738a81c7a4 jdk7u7-b11
@@ -342,3 +343,81 @@
 1cb34ef50bddc334c8538cf85d8612383debc74f jdk7u10-b16
 5c154a591de987d515f5b102a988bcf96d439f53 jdk7u10-b17
 78c7e1b4a006342230e04fbb73f637834207abef jdk7u10-b18
+c6b78bbaf6976197ead9d5aa3f65e0224cd13541 jdk7u10-b30
+02a6c89432d724119565f9ba25672829b136fc5f jdk7u8-b01
+528502f930967f70c320472a002418f1e38029e0 jdk7u8-b02
+db63a909e1ad950ef2b9050389f51e68581b2d4e jdk7u8-b03
+0948731ccc7fdda064f1d961d0b9d0cbf49e1369 jdk7u8-b04
+21e2648677954145d0f12b91ab283e8908e80b08 hs23.4-b01
+baaa29c3d798ffe883091a5ad2ad1bf8324c49d2 jdk7u8-b05
+dc6893023f1121726178d9ac97df8ea5f170025a jdk7u10-b06
+0000000000000000000000000000000000000000 hs23.4-b01
+21e2648677954145d0f12b91ab283e8908e80b08 hs23.6-b01
+6f4d800251492aefcf13727965e8a7feda1338d6 hs23.6-b02
+5f67ff71653f23d7fbb0e1af26502b68b37da9aa jdk7u10-b07
+042438023396a3886a060ca14a06a4664ef85d9d hs23.6-b03
+4c525a19affa0f69c502a74a01d33f0dd74a1ade jdk7u10-b08
+d14ad18fc5168983f693bb173fa353a3846369ad jdk7u10-b09
+3b24e7e01d20ca590d0f86b1222bb7c3f1a2aa2d jdk8-b27
+975c4105f1e2ef1190a75b77124033f1fd4290b5 hs24-b01
+b183b0863611b85dbac16f3b08b40ba978756d19 jdk8-b28
+030b5306d60f140e822e4a6d301744cb110ff0c8 hs24-b02
+b45b5c564098c58ea69e7cff3f7d341f0254dd1d jdk8-b29
+d61761bf305031c94f7f8eca49abd978b7d3c5da jdk8-b30
+dfae0140457cfb2c381d7679735fbedbae862c62 hs24-b03
+f4767e53d6e0d5da7e3f1775904076cce54247c1 hs24-b04
+0cd147eaa673d1642b2f466f5dc257cf192db524 jdk8-b31
+27863e4586de38be7dd17da4163f542038f4d1d7 hs24-b05
+25410a347ebb0bef166c4338a90d9dea82463a20 jdk8-b32
+cd47da9383cd932cb2b659064057feafa2a91134 hs24-b06
+785bcf415ead2eaa5f6677aaf528481008140bac jdk8-b33
+7c6aba65acd2c334f1c3512b574f9038cddac24b hs24-b07
+f284b08835584517c1ca3dd67341f569e763841f jdk8-b34
+f621660a297baa48fab9dca28e99d318826e8304 jdk8-b35
+dff6e3459210f8dd0430b9b03ccc99280560da30 hs24-b08
+50b4400ca1ecb2ac2fde35f5e53ec8f04b86be7f jdk8-b36
+bfcf92bfefb82da00f7fdbf0d9273feaa0a9456d jdk8-b37
+7d5ec8bf38d1b12e0e09ec381f10976b8beede3b hs24-b09
+637c3f5f068f88fb9ec9c5867341cf59fd5ebedc jdk8-b38
+73147e6c48813b5fee904aa33f79a77103250ff4 hs24-b10
+96a403721094ecdaf6a1f4f52ebd0a82e07df199 jdk8-b39
+14b0e07ab9a6fa1662414496b7e07ac8450cf517 hs24-b11
+ff9decc8235d5af80ea45fda4ecbe643ea252564 jdk8-b40
+785573170238f0eae6dc8e22ecf1050fbc9ea055 hs24-b12
+37add4fa0296705f67481e1fd50e2900cd25e39b jdk8-b41
+bd568544be7fcd12a9327e6c448592198d57b043 hs24-b13
+55954061c6e8750ea39a63523fd65d580db6eeb1 jdk8-b42
+e77b8e0ed1f84e3e268239e276c7ab64fa573baa jdk8-b43
+5ba29a1db46ecb80a321ca873adb56a3fe6ad320 hs24-b14
+831e5c76a20af18f3c08c5a95ed31be0e128a010 jdk8-b44
+9d5f20961bc5846fa8d098d534effafbbdae0a58 jdk8-b45
+40e5a3f2907ed02b335c7caa8ecf068cc801380d hs24-b15
+cf37a594c38db2ea926954154636f9f81da2e032 jdk8-b46
+0c7bb1f4f9c8062b5c5bfa56b3bdca44839b4109 jdk8-b47
+66b0450071c1534e014b131892cc86b63f1d009c hs24-b16
+1e26f61bbb521642639f56fae11326f1932f5a7d jdk8-b48
+bd54fe36b5e50f9ef1e30a5047b27fee5297e268 hs24-b17
+e3619706a7253540a2d94e9e841acaab8ace7038 jdk8-b49
+72e0362c3f0cfacbbac8af8a5b9d2e182f21c17b hs24-b18
+58f237a9e83af6ded0d2e2c81d252cd47c0f4c45 jdk8-b50
+3b3ad16429701b2eb6712851c2f7c5a726eb2cbe hs24-b19
+663fc23da8d51c4c0552cbcb17ffc85f5869d4fd jdk8-b51
+4c8f2a12e757e7a808aa85827573e09f75d7459f hs24-b20
+6d0436885201db3f581523344a734793bb989549 jdk8-b52
+54240c1b8e87758f28da2c6a569a926fd9e0910a jdk8-b53
+9e3ae661284dc04185b029d85440fe7811f1ed07 hs24-b21
+e8fb566b94667f88462164defa654203f0ab6820 jdk8-b54
+09ea7e0752b306b8ae74713aeb4eb6263e1c6836 hs24-b22
+4767c78f350408f67eccb50a89f2f1c9df2328e0 hs24-b23
+b4da4e577c9992d9168d093600aa3c3e3aa5156d hs24-b24
+0601ca30c7b40026d5ac40e8aca39ea71f129f96 jdk7u12-b01
+1e5b6a49c06dd1fac6d2f579c64b7b67a8af0edf hs24-b25
+ce5983a3e0b2937cf9a672e61dbcb234f569b29e jdk7u12-b02
+94984276a8dcba53f63a5de563b14eeb5e336c55 jdk7u12-b03
+b9e0f2c87dd64fad932871fef82ee28ada04d6da hs24-b26
+ed9b424d5e4358b7886c9a115b87ef6f06e57137 jdk7u12-b04
+4e4026772caf17fbd5234d6941af8be56fc0c260 jdk7u12-b05
+364bc54d7096ed229d61fa015626276d4f1cedf5 hs24-b27
+2e497fde1807e9e97cb3dfd90bfbbcdcc19f0883 jdk7u12-b06
+c5ee80cc06234ef93e4b6a6ac77597e62fbd99f4 hs24-b28
+4f7ad6299356bfd2cfb448ea4c11e8ce0fbf69f4 jdk7u12-b07
diff --git a/hotspot/agent/make/saenv.sh b/hotspot/agent/make/saenv.sh
index 81c2d15..dcecd51 100644
--- a/hotspot/agent/make/saenv.sh
+++ b/hotspot/agent/make/saenv.sh
@@ -26,7 +26,7 @@
 # This file sets common environment variables for all SA scripts
 
 OS=`uname`
-STARTDIR=`dirname $0`
+STARTDIR=`(cd \`dirname $0 \`; pwd)`
 ARCH=`uname -m`
 
 if [ "x$SA_JAVA" = "x" ]; then
diff --git a/hotspot/agent/make/start-debug-server-proc.sh b/hotspot/agent/make/start-debug-server-proc.sh
index 791fd08..d538daf 100644
--- a/hotspot/agent/make/start-debug-server-proc.sh
+++ b/hotspot/agent/make/start-debug-server-proc.sh
@@ -25,10 +25,11 @@
 
 . `dirname $0`/saenv.sh
 
-if [ -f $STARTDIR/sa.jar ] ; then
-  CP=$STARTDIR/sa.jar
+if [ -f $STARTDIR/../lib/sa-jdi.jar ] ; then
+  CP=$STARTDIR/../lib/sa-jdi.jar
 else
   CP=$STARTDIR/../build/classes
 fi
 
-$SA_JAVA -classpath $CP ${OPTIONS} -Djava.rmi.server.codebase=file:/$CP -Djava.security.policy=$STARTDIR\/grantAll.policy sun.jvm.hotspot.DebugServer $*
+$STARTDIR/java -classpath $CP ${OPTIONS} -Djava.rmi.server.codebase=file://$CP -Djava.security.policy=${STARTDIR}/grantAll.policy sun.jvm.hotspot.DebugServer $*
+
diff --git a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c
index 5771fdd..5b49294 100644
--- a/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c
+++ b/hotspot/agent/src/os/linux/LinuxDebuggerLocal.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -55,11 +55,11 @@
 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
 
-static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
+void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
   (*env)->ThrowNew(env, (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
 }
 
-static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
+struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) {
   jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID);
   return (struct ps_prochandle*)(intptr_t)ptr;
 }
@@ -280,6 +280,7 @@
   return (err == PS_OK)? array : 0;
 }
 
+#if defined(i386) || defined(ia64) || defined(amd64) || defined(sparc) || defined(sparcv9)
 JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
   (JNIEnv *env, jobject this_obj, jint lwp_id) {
 
@@ -410,3 +411,4 @@
   (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
   return array;
 }
+#endif
diff --git a/hotspot/agent/src/os/linux/libproc.h b/hotspot/agent/src/os/linux/libproc.h
index 9c941dd..5f58363 100644
--- a/hotspot/agent/src/os/linux/libproc.h
+++ b/hotspot/agent/src/os/linux/libproc.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,15 @@
 #ifndef _LIBPROC_H_
 #define _LIBPROC_H_
 
+#include <jni.h>
 #include <unistd.h>
 #include <stdint.h>
 #include "proc_service.h"
 
+#if defined(arm) || defined(ppc)
+#include "libproc_md.h"
+#endif
+
 #if defined(sparc) || defined(sparcv9)
 /*
   If _LP64 is defined ptrace.h should be taken from /usr/include/asm-sparc64
@@ -139,4 +144,8 @@
 // address->nearest symbol lookup. return NULL for no symbol
 const char* symbol_for_pc(struct ps_prochandle* ph, uintptr_t addr, uintptr_t* poffset);
 
+struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj);
+
+void throw_new_debugger_exception(JNIEnv* env, const char* errMsg);
+
 #endif //__LIBPROC_H_
diff --git a/hotspot/agent/src/os/linux/ps_core.c b/hotspot/agent/src/os/linux/ps_core.c
index 9739e16..160e25f 100644
--- a/hotspot/agent/src/os/linux/ps_core.c
+++ b/hotspot/agent/src/os/linux/ps_core.c
@@ -440,7 +440,7 @@
       int j = 0;
       print_debug("---- sorted virtual address map ----\n");
       for (j = 0; j < ph->core->num_maps; j++) {
-        print_debug("base = 0x%lx\tsize = %d\n", ph->core->map_array[j]->vaddr,
+        print_debug("base = 0x%lx\tsize = %zu\n", ph->core->map_array[j]->vaddr,
                                          ph->core->map_array[j]->memsz);
       }
    }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
index 029c20f..2526a32 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -549,7 +549,13 @@
                     machDesc = new MachineDescriptionSPARC32Bit();
             }
         } else {
-            throw new DebuggerException("Linux only supported on x86/ia64/amd64/sparc/sparc64");
+          try {
+            machDesc = (MachineDescription)
+              Class.forName("sun.jvm.hotspot.debugger.MachineDescription" +
+                            cpu.toUpperCase()).newInstance();
+          } catch (Exception e) {
+            throw new DebuggerException("Linux not supported on machine type " + cpu);
+          }
         }
 
         LinuxDebuggerLocal dbg =
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java
index 3b89f59..92d7135 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -737,9 +737,16 @@
                machDesc = new MachineDescriptionSPARC32Bit();
             }
         } else {
-            throw new DebuggerException("Linux only supported on x86/ia64/amd64/sparc/sparc64");
+          try {
+            machDesc = (MachineDescription)
+              Class.forName("sun.jvm.hotspot.debugger.MachineDescription" +
+              cpu.toUpperCase()).newInstance();
+          } catch (Exception e) {
+            throw new DebuggerException("unsupported machine type");
+          }
         }
 
+
         // Note we do not use a cache for the local debugger in server
         // mode; it will be taken care of on the client side (once remote
         // debugging is implemented).
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java
index a9bc598..13d19e4 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeBlob.java
@@ -93,7 +93,6 @@
   public boolean isUncommonTrapStub()   { return false; }
   public boolean isExceptionStub()      { return false; }
   public boolean isSafepointStub()      { return false; }
-  public boolean isRicochetBlob()       { return false; }
   public boolean isAdapterBlob()        { return false; }
 
   // Fine grain nmethod support: isNmethod() == isJavaMethod() || isNativeMethod() || isOSRMethod()
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
index 6d0dd0f..9cb837f 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/CodeCache.java
@@ -57,7 +57,6 @@
     virtualConstructor.addMapping("BufferBlob", BufferBlob.class);
     virtualConstructor.addMapping("nmethod", NMethod.class);
     virtualConstructor.addMapping("RuntimeStub", RuntimeStub.class);
-    virtualConstructor.addMapping("RicochetBlob", RicochetBlob.class);
     virtualConstructor.addMapping("AdapterBlob", AdapterBlob.class);
     virtualConstructor.addMapping("MethodHandlesAdapterBlob", MethodHandlesAdapterBlob.class);
     virtualConstructor.addMapping("SafepointBlob", SafepointBlob.class);
@@ -127,10 +126,6 @@
       Assert.that(result.blobContains(start) || result.blobContains(start.addOffsetTo(8)),
                                                                     "found wrong CodeBlob");
     }
-    if (result.isRicochetBlob()) {
-      // This should probably be done for other SingletonBlobs
-      return VM.getVM().ricochetBlob();
-    }
     return result;
   }
 
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java
deleted file mode 100644
index 0fa8518..0000000
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/RicochetBlob.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.code;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-/** RicochetBlob (currently only used by Compiler 2) */
-
-public class RicochetBlob extends SingletonBlob {
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static void initialize(TypeDataBase db) {
-    Type type = db.lookupType("RicochetBlob");
-
-    bounceOffsetField                = type.getCIntegerField("_bounce_offset");
-    exceptionOffsetField             = type.getCIntegerField("_exception_offset");
-  }
-
-  private static CIntegerField bounceOffsetField;
-  private static CIntegerField exceptionOffsetField;
-
-  public RicochetBlob(Address addr) {
-    super(addr);
-  }
-
-  public boolean isRicochetBlob() {
-    return true;
-  }
-
-  public Address bounceAddr() {
-    return codeBegin().addOffsetTo(bounceOffsetField.getValue(addr));
-  }
-
-  public boolean returnsToBounceAddr(Address pc) {
-    Address bouncePc = bounceAddr();
-    return (pc.equals(bouncePc) || pc.addOffsetTo(Frame.pcReturnOffset()).equals(bouncePc));
-  }
-
-}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ThreadContext.java
index 64a90f5..ec6b7e6 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ThreadContext.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ThreadContext.java
@@ -24,6 +24,8 @@
 
 package sun.jvm.hotspot.debugger;
 
+import sun.jvm.hotspot.debugger.cdbg.*;
+
 /** This is a placeholder interface for a thread's context, containing
     only integer registers (no floating-point ones). What it contains
     is platform-dependent. Not all registers are guaranteed to be
@@ -54,4 +56,6 @@
   /** Set the value of the specified register (0..getNumRegisters() -
       1) as an Address */
   public void setRegisterAsAddress(int index, Address value);
+
+  public CFrame getTopFrame(Debugger dbg);
 }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/amd64/AMD64ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/amd64/AMD64ThreadContext.java
index 2861545..5b2332a 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/amd64/AMD64ThreadContext.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/amd64/AMD64ThreadContext.java
@@ -25,6 +25,7 @@
 package sun.jvm.hotspot.debugger.amd64;
 
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
 
 /** Specifies the thread context on amd64 platforms; only a sub-portion
  * of the context is guaranteed to be present on all operating
@@ -98,6 +99,10 @@
         return data[index];
     }
 
+    public CFrame getTopFrame(Debugger dbg) {
+        return null;
+    }
+
     /** This can't be implemented in this class since we would have to
      * tie the implementation to, for example, the debugging system */
     public abstract void setRegisterAsAddress(int index, Address value);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java
index 5e1bc36..4a5aa00 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/ia64/IA64ThreadContext.java
@@ -25,6 +25,7 @@
 package sun.jvm.hotspot.debugger.ia64;
 
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
 
 /** Specifies the thread context on ia64 platform; only a sub-portion
     of the context is guaranteed to be present on all operating
@@ -172,6 +173,10 @@
     return data[index];
   }
 
+  public CFrame getTopFrame(Debugger dbg) {
+    return null;
+  }
+
   /** This can't be implemented in this class since we would have to
       tie the implementation to, for example, the debugging system */
   public abstract void setRegisterAsAddress(int index, Address value);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java
index 4a155b2..f2d9474 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxCDebugger.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -107,7 +107,9 @@
        if (pc == null) return null;
        return new LinuxSPARCCFrame(dbg, sp, pc, LinuxDebuggerLocal.getAddressSize());
     } else {
-       throw new DebuggerException(cpu + " is not yet supported");
+       // Runtime exception thrown by LinuxThreadContextFactory if unknown cpu
+       ThreadContext context = (ThreadContext) thread.getContext();
+       return context.getTopFrame(dbg);
     }
   }
 
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java
index 94b56b1..44c2265 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxThreadContextFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -24,6 +24,7 @@
 
 package sun.jvm.hotspot.debugger.linux;
 
+import java.lang.reflect.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.debugger.linux.amd64.*;
 import sun.jvm.hotspot.debugger.linux.ia64.*;
@@ -41,8 +42,16 @@
          return new LinuxIA64ThreadContext(dbg);
       } else if (cpu.equals("sparc")) {
          return new LinuxSPARCThreadContext(dbg);
-      } else {
-         throw new RuntimeException("cpu " + cpu + " is not yet supported");
+      } else  {
+        try {
+          Class tcc = Class.forName("sun.jvm.hotspot.debugger.linux." +
+             cpu.toLowerCase() + ".Linux" + cpu.toUpperCase() +
+             "ThreadContext");
+          Constructor[] ctcc = tcc.getConstructors();
+          return (ThreadContext)ctcc[0].newInstance(dbg);
+        } catch (Exception e) {
+          throw new RuntimeException("cpu " + cpu + " is not yet supported");
+        }
       }
    }
 }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java
index 1d9f7ce..dbfed01 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/proc/ProcDebuggerLocal.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 import java.io.*;
 import java.net.*;
 import java.util.*;
+import java.lang.reflect.*;
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.debugger.cdbg.*;
 import sun.jvm.hotspot.debugger.proc.amd64.*;
@@ -86,7 +87,16 @@
             pcRegIndex = AMD64ThreadContext.RIP;
             fpRegIndex = AMD64ThreadContext.RBP;
         } else {
+          try {
+            Class tfc = Class.forName("sun.jvm.hotspot.debugger.proc." +
+               cpu.toLowerCase() + ".Proc" + cpu.toUpperCase() +
+               "ThreadFactory");
+            Constructor[] ctfc = tfc.getConstructors();
+            threadFactory = (ProcThreadFactory)ctfc[0].newInstance(this);
+          } catch (Exception e) {
             throw new RuntimeException("Thread access for CPU architecture " + PlatformInfo.getCPU() + " not yet supported");
+            // Note: pcRegIndex and fpRegIndex do not appear to be referenced
+          }
         }
         if (useCache) {
             // Cache portion of the remote process's address space.
@@ -375,7 +385,11 @@
         int pagesize = getPageSize0();
         if (pagesize == -1) {
             // return the hard coded default value.
-            pagesize = (PlatformInfo.getCPU().equals("x86"))? 4096 : 8192;
+            if (PlatformInfo.getCPU().equals("sparc") ||
+                PlatformInfo.getCPU().equals("amd64") )
+               pagesize = 8196;
+            else
+               pagesize = 4096;
         }
         return pagesize;
     }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java
index beb3f53..8417b8c 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/remote/RemoteDebuggerClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 
 import java.rmi.*;
 import java.util.*;
+import java.lang.reflect.*;
 
 import sun.jvm.hotspot.debugger.*;
 import sun.jvm.hotspot.debugger.cdbg.*;
@@ -70,7 +71,18 @@
         cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize);
         unalignedAccessesOkay = true;
       } else {
-        throw new DebuggerException("Thread access for CPU architecture " + cpu + " not yet supported");
+        try {
+          Class tf = Class.forName("sun.jvm.hotspot.debugger.remote." +
+            cpu.toLowerCase() + ".Remote" + cpu.toUpperCase() +
+            "ThreadFactory");
+          Constructor[] ctf = tf.getConstructors();
+          threadFactory = (RemoteThreadFactory)ctf[0].newInstance(this);
+        } catch (Exception e) {
+          throw new DebuggerException("Thread access for CPU architecture " + cpu + " not yet supported");
+        }
+        cachePageSize = 4096;
+        cacheNumPages = parseCacheNumPagesProperty(cacheSize / cachePageSize);
+        unalignedAccessesOkay = false;
       }
 
       // Cache portion of the remote process's address space.
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/sparc/SPARCThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/sparc/SPARCThreadContext.java
index 27f0132..228d919 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/sparc/SPARCThreadContext.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/sparc/SPARCThreadContext.java
@@ -25,6 +25,7 @@
 package sun.jvm.hotspot.debugger.sparc;
 
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
 
 /** Currently provides just the minimal information necessary to get
     stack traces working. FIXME: currently hardwired for v9 -- will
@@ -124,6 +125,10 @@
     return data[index];
   }
 
+  public CFrame getTopFrame(Debugger dbg) {
+    return null;
+  }
+
   /** This can't be implemented in this class since we would have to
       tie the implementation to, for example, the debugging system */
   public abstract void setRegisterAsAddress(int index, Address value);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/x86/X86ThreadContext.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/x86/X86ThreadContext.java
index 8222e92..9d51bcf 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/x86/X86ThreadContext.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/x86/X86ThreadContext.java
@@ -25,6 +25,7 @@
 package sun.jvm.hotspot.debugger.x86;
 
 import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.debugger.cdbg.*;
 
 /** Specifies the thread context on x86 platforms; only a sub-portion
     of the context is guaranteed to be present on all operating
@@ -109,6 +110,10 @@
     return data[index];
   }
 
+  public CFrame getTopFrame(Debugger dbg) {
+    return null;
+  }
+
   /** This can't be implemented in this class since we would have to
       tie the implementation to, for example, the debugging system */
   public abstract void setRegisterAsAddress(int index, Address value);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java
index d0da28b..5bd7f44 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSeq.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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,7 +42,7 @@
 public class HeapRegionSeq extends VMObject {
     // HeapRegion** _regions;
     static private AddressField regionsField;
-    // size_t _length;
+    // uint _length;
     static private CIntegerField lengthField;
 
     static {
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSetBase.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSetBase.java
index 2fbdce7..4ac8f72 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSetBase.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/gc_implementation/g1/HeapRegionSetBase.java
@@ -40,9 +40,9 @@
 // Mirror class for HeapRegionSetBase. Represents a group of regions.
 
 public class HeapRegionSetBase extends VMObject {
-    // size_t _length;
+    // uint _length;
     static private CIntegerField lengthField;
-    // size_t _region_num;
+    // uint _region_num;
     static private CIntegerField regionNumField;
     // size_t _total_used_bytes;
     static private CIntegerField totalUsedBytesField;
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java
index d28bca1..662f18e 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/ReferenceTypeImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -688,8 +688,7 @@
         if (sde == null) {
            String extension = null;
            if (saKlass instanceof InstanceKlass) {
-              Symbol sdeSym = ((InstanceKlass)saKlass).getSourceDebugExtension();
-              extension = (sdeSym != null)? sdeSym.asString() : null;
+              extension = ((InstanceKlass)saKlass).getSourceDebugExtension();
            }
            if (extension == null) {
               sde = NO_SDE_INFO_MARK;
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java
index 4cbc144..a7d7d4e 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/jdi/VirtualMachineImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -889,15 +889,9 @@
         Klass kls = ((ReferenceTypeImpl)type).ref();
         if (kls instanceof InstanceKlass) {
             InstanceKlass ik = (InstanceKlass) kls;
-            if (ik.isInterface()) {
-                if (ik.nofImplementors() == 0L) {
-                    return new ArrayList(0);
-                }
-            } else {
-                // if the Klass is final or if there are no subklasses loaded yet
-                if (ik.getAccessFlagsObj().isFinal() || ik.getSubklassKlass() == null) {
-                    includeSubtypes = false;
-                }
+            // if the Klass is final or if there are no subklasses loaded yet
+            if (ik.getAccessFlagsObj().isFinal() || ik.getSubklassKlass() == null) {
+                includeSubtypes = false;
             }
         } else {
             // no subtypes for primitive array types
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/AccessFlags.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/AccessFlags.java
index 0231415..76c7316 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/AccessFlags.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/AccessFlags.java
@@ -81,6 +81,7 @@
   // field flags
   public boolean fieldAccessWatched () { return (flags & JVM_ACC_FIELD_ACCESS_WATCHED) != 0; }
   public boolean fieldModificationWatched() { return (flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
+  public boolean fieldHasGenericSignature() { return (flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE)!= 0; }
 
   public void printOn(PrintStream tty) {
     // prints only .class flags and not the hotspot internal flags
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
index 5346d49..241cba1 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstMethod.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -47,15 +47,11 @@
   private static int HAS_LINENUMBER_TABLE;
   private static int HAS_CHECKED_EXCEPTIONS;
   private static int HAS_LOCALVARIABLE_TABLE;
+  private static int HAS_EXCEPTION_TABLE;
 
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type type                  = db.lookupType("constMethodOopDesc");
-    // Backpointer to non-const methodOop
-    method                     = new OopField(type.getOopField("_method"), 0);
-    // The exception handler table. 4-tuples of ints [start_pc, end_pc,
-    // handler_pc, catch_type index] For methods with no exceptions the
-    // table is pointing to Universe::the_empty_int_array
-    exceptionTable             = new OopField(type.getOopField("_exception_table"), 0);
+    constants                  = new OopField(type.getOopField("_constants"), 0);
     constMethodSize            = new CIntField(type.getCIntegerField("_constMethod_size"), 0);
     flags                      = new ByteField(type.getJByteField("_flags"), 0);
 
@@ -63,12 +59,14 @@
     HAS_LINENUMBER_TABLE      = db.lookupIntConstant("constMethodOopDesc::_has_linenumber_table").intValue();
     HAS_CHECKED_EXCEPTIONS     = db.lookupIntConstant("constMethodOopDesc::_has_checked_exceptions").intValue();
     HAS_LOCALVARIABLE_TABLE   = db.lookupIntConstant("constMethodOopDesc::_has_localvariable_table").intValue();
+    HAS_EXCEPTION_TABLE       = db.lookupIntConstant("constMethodOopDesc::_has_exception_table").intValue();
 
     // Size of Java bytecodes allocated immediately after constMethodOop.
     codeSize                   = new CIntField(type.getCIntegerField("_code_size"), 0);
     nameIndex                  = new CIntField(type.getCIntegerField("_name_index"), 0);
     signatureIndex             = new CIntField(type.getCIntegerField("_signature_index"), 0);
     genericSignatureIndex      = new CIntField(type.getCIntegerField("_generic_signature_index"),0);
+    idnum                      = new CIntField(type.getCIntegerField("_method_idnum"), 0);
 
     // start of byte code
     bytecodeOffset = type.getSize();
@@ -78,6 +76,9 @@
 
     type                       = db.lookupType("LocalVariableTableElement");
     localVariableTableElementSize = type.getSize();
+
+    type                       = db.lookupType("ExceptionTableElement");
+    exceptionTableElementSize = type.getSize();
   }
 
   ConstMethod(OopHandle handle, ObjectHeap heap) {
@@ -85,28 +86,31 @@
   }
 
   // Fields
-  private static OopField  method;
-  private static OopField  exceptionTable;
+  private static OopField  constants;
   private static CIntField constMethodSize;
   private static ByteField flags;
   private static CIntField codeSize;
   private static CIntField nameIndex;
   private static CIntField signatureIndex;
   private static CIntField genericSignatureIndex;
+  private static CIntField idnum;
 
   // start of bytecode
   private static long bytecodeOffset;
 
   private static long checkedExceptionElementSize;
   private static long localVariableTableElementSize;
+  private static long exceptionTableElementSize;
 
-  // Accessors for declared fields
   public Method getMethod() {
-    return (Method) method.getValue(this);
+    InstanceKlass ik = (InstanceKlass)getConstants().getPoolHolder();
+    ObjArray methods = ik.getMethods();
+    return (Method)methods.getObjAt(getIdNum());
   }
 
-  public TypeArray getExceptionTable() {
-    return (TypeArray) exceptionTable.getValue(this);
+  // Accessors for declared fields
+  public ConstantPool getConstants() {
+    return (ConstantPool) constants.getValue(this);
   }
 
   public long getConstMethodSize() {
@@ -133,6 +137,10 @@
     return genericSignatureIndex.getValue(this);
   }
 
+  public long getIdNum() {
+    return idnum.getValue(this);
+  }
+
   public Symbol getName() {
     return getMethod().getName();
   }
@@ -223,8 +231,7 @@
   public void iterateFields(OopVisitor visitor, boolean doVMFields) {
     super.iterateFields(visitor, doVMFields);
     if (doVMFields) {
-      visitor.doOop(method, true);
-      visitor.doOop(exceptionTable, true);
+      visitor.doOop(constants, true);
       visitor.doCInt(constMethodSize, true);
       visitor.doByte(flags, true);
       visitor.doCInt(codeSize, true);
@@ -315,6 +322,23 @@
     return ret;
   }
 
+  public boolean hasExceptionTable() {
+    return (getFlags() & HAS_EXCEPTION_TABLE) != 0;
+  }
+
+  public ExceptionTableElement[] getExceptionTable() {
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(hasExceptionTable(), "should only be called if table is present");
+    }
+    ExceptionTableElement[] ret = new ExceptionTableElement[getExceptionTableLength()];
+    long offset = offsetOfExceptionTable();
+    for (int i = 0; i < ret.length; i++) {
+      ret[i] = new ExceptionTableElement(getHandle(), offset);
+      offset += exceptionTableElementSize;
+    }
+    return ret;
+  }
+
   public boolean hasCheckedExceptions() {
     return (getFlags() & HAS_CHECKED_EXCEPTIONS) != 0;
   }
@@ -404,7 +428,10 @@
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(hasLocalVariableTable(), "should only be called if table is present");
     }
-    if (hasCheckedExceptions()) {
+
+    if (hasExceptionTable()) {
+      return offsetOfExceptionTable() - 2;
+    } else if (hasCheckedExceptions()) {
       return offsetOfCheckedExceptions() - 2;
     } else {
       return offsetOfLastU2Element();
@@ -421,4 +448,33 @@
     return offset;
   }
 
+  private int getExceptionTableLength() {
+    if (hasExceptionTable()) {
+      return (int) getHandle().getCIntegerAt(offsetOfExceptionTableLength(), 2, true);
+    } else {
+      return 0;
+    }
+  }
+
+  private long offsetOfExceptionTableLength() {
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(hasExceptionTable(), "should only be called if table is present");
+    }
+    if (hasCheckedExceptions()) {
+      return offsetOfCheckedExceptions() - 2;
+    } else {
+      return offsetOfLastU2Element();
+    }
+  }
+
+  private long offsetOfExceptionTable() {
+    long offset = offsetOfExceptionTableLength();
+    long length = getExceptionTableLength();
+    if (Assert.ASSERTS_ENABLED) {
+      Assert.that(length > 0, "should only be called if table is present");
+    }
+    offset -= length * exceptionTableElementSize;
+    return offset;
+  }
+
 }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
index 5752eae..874512f 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ConstantPool.java
@@ -648,7 +648,12 @@
   }
 
   public void printValueOn(PrintStream tty) {
-    tty.print("ConstantPool for " + getPoolHolder().getName().asString());
+    Oop holder = poolHolder.getValue(this);
+    if (holder instanceof Klass) {
+      tty.print("ConstantPool for " + ((Klass)holder).getName().asString());
+    } else {
+      tty.print("ConstantPool for partially loaded class");
+    }
   }
 
   public long getObjectSize() {
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ExceptionTableElement.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ExceptionTableElement.java
new file mode 100644
index 0000000..9315370
--- /dev/null
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/ExceptionTableElement.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.jvm.hotspot.oops;
+
+import java.io.*;
+import java.util.*;
+import sun.jvm.hotspot.debugger.*;
+import sun.jvm.hotspot.interpreter.*;
+import sun.jvm.hotspot.runtime.*;
+import sun.jvm.hotspot.types.*;
+import sun.jvm.hotspot.utilities.*;
+
+public class ExceptionTableElement {
+  static {
+    VM.registerVMInitializedObserver(new Observer() {
+        public void update(Observable o, Object data) {
+          initialize(VM.getVM().getTypeDataBase());
+        }
+      });
+  }
+
+  private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
+    Type type            = db.lookupType("ExceptionTableElement");
+    offsetOfStartPC      = type.getCIntegerField("start_pc").getOffset();
+    offsetOfEndPC        = type.getCIntegerField("end_pc").getOffset();
+    offsetOfHandlerPC    = type.getCIntegerField("handler_pc").getOffset();
+    offsetOfCatchTypeIndex = type.getCIntegerField("catch_type_index").getOffset();
+  }
+
+  private static long offsetOfStartPC;
+  private static long offsetOfEndPC;
+  private static long offsetOfHandlerPC;
+  private static long offsetOfCatchTypeIndex;
+
+  private OopHandle handle;
+  private long      offset;
+
+  public ExceptionTableElement(OopHandle handle, long offset) {
+    this.handle = handle;
+    this.offset = offset;
+  }
+
+  public int getStartPC() {
+    return (int) handle.getCIntegerAt(offset + offsetOfStartPC, 2, true);
+  }
+
+  public int getEndPC() {
+    return (int) handle.getCIntegerAt(offset + offsetOfEndPC, 2, true);
+  }
+
+  public int getHandlerPC() {
+    return (int) handle.getCIntegerAt(offset + offsetOfHandlerPC, 2, true);
+  }
+
+  public int getCatchTypeIndex() {
+    return (int) handle.getCIntegerAt(offset + offsetOfCatchTypeIndex, 2, true);
+  }
+}
+
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java
index f25493d..581eee8 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/GenerateOopMap.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -651,10 +651,11 @@
     boolean fellThrough = false;  // False to get first BB marked.
 
     // First mark all exception handlers as start of a basic-block
-    TypeArray excps = method().getExceptionTable();
-    for(int i = 0; i < excps.getLength(); i += 4) {
-      int handler_pc_idx = i+2;
-      markBB(excps.getIntAt(handler_pc_idx), null);
+    if (method().hasExceptionTable()) {
+      ExceptionTableElement[] excps = method().getExceptionTable();
+      for(int i = 0; i < excps.length; i++) {
+        markBB(excps[i].getHandlerPC(), null);
+      }
     }
 
     // Then iterate through the code
@@ -891,14 +892,15 @@
 
     // Mark entry basic block as alive and all exception handlers
     _basic_blocks[0].markAsAlive();
-    TypeArray excps = method().getExceptionTable();
-    for(int i = 0; i < excps.getLength(); i += 4) {
-      int handler_pc_idx = i+2;
-      BasicBlock bb = getBasicBlockAt(excps.getIntAt(handler_pc_idx));
-      // If block is not already alive (due to multiple exception handlers to same bb), then
-      // make it alive
-      if (bb.isDead())
-        bb.markAsAlive();
+    if (method().hasExceptionTable()) {
+      ExceptionTableElement[] excps = method().getExceptionTable();
+      for(int i = 0; i < excps.length; i ++) {
+        BasicBlock bb = getBasicBlockAt(excps[i].getHandlerPC());
+        // If block is not already alive (due to multiple exception handlers to same bb), then
+        // make it alive
+        if (bb.isDead())
+          bb.markAsAlive();
+      }
     }
 
     BytecodeStream bcs = new BytecodeStream(_method);
@@ -1468,12 +1470,12 @@
 
     if (_has_exceptions) {
       int bci = itr.bci();
-      TypeArray exct   = method().getExceptionTable();
-      for(int i = 0; i< exct.getLength(); i+=4) {
-        int start_pc   = exct.getIntAt(i);
-        int end_pc     = exct.getIntAt(i+1);
-        int handler_pc = exct.getIntAt(i+2);
-        int catch_type = exct.getIntAt(i+3);
+      ExceptionTableElement[] exct   = method().getExceptionTable();
+      for(int i = 0; i< exct.length; i++) {
+        int start_pc   = exct[i].getStartPC();
+        int end_pc     = exct[i].getEndPC();
+        int handler_pc = exct[i].getHandlerPC();
+        int catch_type = exct[i].getCatchTypeIndex();
 
         if (start_pc <= bci && bci < end_pc) {
           BasicBlock excBB = getBasicBlockAt(handler_pc);
@@ -2151,7 +2153,7 @@
     _conflict       = false;
     _max_locals     = (int) method().getMaxLocals();
     _max_stack      = (int) method().getMaxStack();
-    _has_exceptions = (method().getExceptionTable().getLength() > 0);
+    _has_exceptions = (method().hasExceptionTable());
     _nof_refval_conflicts = 0;
     _init_vars      = new ArrayList(5);  // There are seldom more than 5 init_vars
     _report_result  = false;
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
index 87de970..acd9752 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/InstanceKlass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -50,9 +50,7 @@
   private static int INITVAL_INDEX_OFFSET;
   private static int LOW_OFFSET;
   private static int HIGH_OFFSET;
-  private static int GENERIC_SIGNATURE_INDEX_OFFSET;
   private static int FIELD_SLOTS;
-  public static int IMPLEMENTORS_LIMIT;
 
   // ClassState constants
   private static int CLASS_STATE_UNPARSABLE_BY_GC;
@@ -70,13 +68,6 @@
     methodOrdering       = new OopField(type.getOopField("_method_ordering"), Oop.getHeaderSize());
     localInterfaces      = new OopField(type.getOopField("_local_interfaces"), Oop.getHeaderSize());
     transitiveInterfaces = new OopField(type.getOopField("_transitive_interfaces"), Oop.getHeaderSize());
-    nofImplementors      = new CIntField(type.getCIntegerField("_nof_implementors"), Oop.getHeaderSize());
-    IMPLEMENTORS_LIMIT   = db.lookupIntConstant("instanceKlass::implementors_limit").intValue();
-    implementors         = new OopField[IMPLEMENTORS_LIMIT];
-    for (int i = 0; i < IMPLEMENTORS_LIMIT; i++) {
-      long arrayOffset = Oop.getHeaderSize() + (i * db.getAddressSize());
-      implementors[i]    = new OopField(type.getOopField("_implementors[0]"), arrayOffset);
-    }
     fields               = new OopField(type.getOopField("_fields"), Oop.getHeaderSize());
     javaFieldsCount      = new CIntField(type.getCIntegerField("_java_fields_count"), Oop.getHeaderSize());
     constants            = new OopField(type.getOopField("_constants"), Oop.getHeaderSize());
@@ -107,7 +98,6 @@
     INITVAL_INDEX_OFFSET           = db.lookupIntConstant("FieldInfo::initval_index_offset").intValue();
     LOW_OFFSET                     = db.lookupIntConstant("FieldInfo::low_offset").intValue();
     HIGH_OFFSET                    = db.lookupIntConstant("FieldInfo::high_offset").intValue();
-    GENERIC_SIGNATURE_INDEX_OFFSET = db.lookupIntConstant("FieldInfo::generic_signature_offset").intValue();
     FIELD_SLOTS                    = db.lookupIntConstant("FieldInfo::field_slots").intValue();
     // read ClassState constants
     CLASS_STATE_UNPARSABLE_BY_GC = db.lookupIntConstant("instanceKlass::unparsable_by_gc").intValue();
@@ -136,8 +126,6 @@
   private static OopField  methodOrdering;
   private static OopField  localInterfaces;
   private static OopField  transitiveInterfaces;
-  private static CIntField nofImplementors;
-  private static OopField[] implementors;
   private static OopField  fields;
   private static CIntField javaFieldsCount;
   private static OopField  constants;
@@ -289,7 +277,25 @@
   }
 
   public short getFieldGenericSignatureIndex(int index) {
-    return getFields().getShortAt(index * FIELD_SLOTS + GENERIC_SIGNATURE_INDEX_OFFSET);
+    int len = (int)getFields().getLength();
+    int allFieldsCount = getAllFieldsCount();
+    int generic_signature_slot = allFieldsCount * FIELD_SLOTS;
+    for (int i = 0; i < allFieldsCount; i++) {
+      short flags = getFieldAccessFlags(i);
+      AccessFlags access = new AccessFlags(flags);
+      if (i == index) {
+        if (access.fieldHasGenericSignature()) {
+          return getFields().getShortAt(generic_signature_slot);
+        } else {
+          return 0;
+        }
+      } else {
+        if (access.fieldHasGenericSignature()) {
+          generic_signature_slot ++;
+        }
+      }
+    }
+    return 0;
   }
 
   public Symbol getFieldGenericSignature(int index) {
@@ -317,18 +323,26 @@
   public TypeArray getMethodOrdering()      { return (TypeArray)    methodOrdering.getValue(this); }
   public ObjArray  getLocalInterfaces()     { return (ObjArray)     localInterfaces.getValue(this); }
   public ObjArray  getTransitiveInterfaces() { return (ObjArray)     transitiveInterfaces.getValue(this); }
-  public long      nofImplementors()        { return                nofImplementors.getValue(this); }
-  public Klass     getImplementor()         { return (Klass)        implementors[0].getValue(this); }
-  public Klass     getImplementor(int i)    { return (Klass)        implementors[i].getValue(this); }
   public TypeArray getFields()              { return (TypeArray)    fields.getValue(this); }
   public int       getJavaFieldsCount()     { return                (int) javaFieldsCount.getValue(this); }
-  public int       getAllFieldsCount()      { return                (int)getFields().getLength() / FIELD_SLOTS; }
+  public int       getAllFieldsCount()      {
+    int len = (int)getFields().getLength();
+    int allFieldsCount = 0;
+    for (; allFieldsCount*FIELD_SLOTS < len; allFieldsCount++) {
+      short flags = getFieldAccessFlags(allFieldsCount);
+      AccessFlags access = new AccessFlags(flags);
+      if (access.fieldHasGenericSignature()) {
+        len --;
+      }
+    }
+    return allFieldsCount;
+  }
   public ConstantPool getConstants()        { return (ConstantPool) constants.getValue(this); }
   public Oop       getClassLoader()         { return                classLoader.getValue(this); }
   public Oop       getProtectionDomain()    { return                protectionDomain.getValue(this); }
   public ObjArray  getSigners()             { return (ObjArray)     signers.getValue(this); }
   public Symbol    getSourceFileName()      { return getSymbol(sourceFileName); }
-  public Symbol    getSourceDebugExtension(){ return getSymbol(sourceDebugExtension); }
+  public String    getSourceDebugExtension(){ return                CStringUtilities.getString(sourceDebugExtension.getValue(getHandle())); }
   public TypeArray getInnerClasses()        { return (TypeArray)    innerClasses.getValue(this); }
   public long      getNonstaticFieldSize()  { return                nonstaticFieldSize.getValue(this); }
   public long      getStaticOopFieldCount() { return                staticOopFieldCount.getValue(this); }
@@ -359,6 +373,12 @@
     public static final int innerClassNextOffset = 4;
   };
 
+  public static interface EnclosingMethodAttributeOffset {
+    public static final int enclosing_method_class_index_offset = 0;
+    public static final int enclosing_method_method_index_offset = 1;
+    public static final int enclosing_method_attribute_size = 2;
+  };
+
   // refer to compute_modifier_flags in VM code.
   public long computeModifierFlags() {
     long access = getAccessFlags();
@@ -367,9 +387,14 @@
     int length = ( innerClassList == null)? 0 : (int) innerClassList.getLength();
     if (length > 0) {
        if (Assert.ASSERTS_ENABLED) {
-          Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0, "just checking");
+          Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
+                      length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
+                      "just checking");
        }
        for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
+          if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
+              break;
+          }
           int ioff = innerClassList.getShortAt(i +
                          InnerClassAttributeOffset.innerClassInnerClassInfoOffset);
           // 'ioff' can be zero.
@@ -419,9 +444,14 @@
     int length = ( innerClassList == null)? 0 : (int) innerClassList.getLength();
     if (length > 0) {
        if (Assert.ASSERTS_ENABLED) {
-         Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0, "just checking");
+         Assert.that(length % InnerClassAttributeOffset.innerClassNextOffset == 0 ||
+                     length % InnerClassAttributeOffset.innerClassNextOffset == EnclosingMethodAttributeOffset.enclosing_method_attribute_size,
+                     "just checking");
        }
        for (int i = 0; i < length; i += InnerClassAttributeOffset.innerClassNextOffset) {
+         if (i == length - EnclosingMethodAttributeOffset.enclosing_method_attribute_size) {
+             break;
+         }
          int ioff = innerClassList.getShortAt(i +
                         InnerClassAttributeOffset.innerClassInnerClassInfoOffset);
          // 'ioff' can be zero.
@@ -511,9 +541,6 @@
       visitor.doOop(methodOrdering, true);
       visitor.doOop(localInterfaces, true);
       visitor.doOop(transitiveInterfaces, true);
-      visitor.doCInt(nofImplementors, true);
-      for (int i = 0; i < IMPLEMENTORS_LIMIT; i++)
-        visitor.doOop(implementors[i], true);
       visitor.doOop(fields, true);
       visitor.doOop(constants, true);
       visitor.doOop(classLoader, true);
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
index d42115b..d8b3fad 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/oops/Method.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -48,7 +48,6 @@
   private static synchronized void initialize(TypeDataBase db) throws WrongTypeException {
     Type type                  = db.lookupType("methodOopDesc");
     constMethod                = new OopField(type.getOopField("_constMethod"), 0);
-    constants                  = new OopField(type.getOopField("_constants"), 0);
     methodData                 = new OopField(type.getOopField("_method_data"), 0);
     methodSize                 = new CIntField(type.getCIntegerField("_method_size"), 0);
     maxStack                   = new CIntField(type.getCIntegerField("_max_stack"), 0);
@@ -83,7 +82,6 @@
 
   // Fields
   private static OopField  constMethod;
-  private static OopField  constants;
   private static OopField  methodData;
   private static CIntField methodSize;
   private static CIntField maxStack;
@@ -125,9 +123,10 @@
 
   // Accessors for declared fields
   public ConstMethod  getConstMethod()                { return (ConstMethod)  constMethod.getValue(this);       }
-  public ConstantPool getConstants()                  { return (ConstantPool) constants.getValue(this);         }
+  public ConstantPool getConstants()                  {
+    return getConstMethod().getConstants();
+  }
   public MethodData   getMethodData()                 { return (MethodData) methodData.getValue(this);          }
-  public TypeArray    getExceptionTable()             { return getConstMethod().getExceptionTable();            }
   /** WARNING: this is in words, not useful in this system; use getObjectSize() instead */
   public long         getMethodSize()                 { return                methodSize.getValue(this);        }
   public long         getMaxStack()                   { return                maxStack.getValue(this);          }
@@ -281,7 +280,6 @@
     super.iterateFields(visitor, doVMFields);
     if (doVMFields) {
       visitor.doOop(constMethod, true);
-      visitor.doOop(constants, true);
       visitor.doCInt(methodSize, true);
       visitor.doCInt(maxStack, true);
       visitor.doCInt(maxLocals, true);
@@ -329,6 +327,14 @@
     return null;
   }
 
+  public boolean hasExceptionTable() {
+    return getConstMethod().hasExceptionTable();
+  }
+
+  public ExceptionTableElement[] getExceptionTable() {
+    return getConstMethod().getExceptionTable();
+  }
+
   public boolean hasCheckedExceptions() {
     return getConstMethod().hasCheckedExceptions();
   }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java
index 722496e..e17a75c 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/ClassConstants.java
@@ -153,6 +153,8 @@
     public static final long JVM_ACC_FIELD_ACCESS_WATCHED         = 0x00002000;
     // field modification is watched by JVMTI
     public static final long JVM_ACC_FIELD_MODIFICATION_WATCHED   = 0x00008000;
+    // field has generic signature
+    public static final long JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE  = 0x00000800;
 
     // flags accepted by set_field_flags
     public static final long JVM_ACC_FIELD_FLAGS = 0x00008000 | JVM_ACC_WRITTEN_FLAGS;
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java
index 70eace5..9f6285a 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Frame.java
@@ -147,12 +147,6 @@
     }
   }
 
-  public boolean isRicochetFrame() {
-    CodeBlob cb = VM.getVM().getCodeCache().findBlob(getPC());
-    RicochetBlob rcb = VM.getVM().ricochetBlob();
-    return (cb == rcb && rcb != null && rcb.returnsToBounceAddr(getPC()));
-  }
-
   public boolean isCompiledFrame() {
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(!VM.getVM().isCore(), "noncore builds only");
@@ -216,8 +210,7 @@
   public Frame realSender(RegisterMap map) {
     if (!VM.getVM().isCore()) {
       Frame result = sender(map);
-      while (result.isRuntimeFrame() ||
-             result.isRicochetFrame()) {
+      while (result.isRuntimeFrame()) {
         result = result.sender(map);
       }
       return result;
@@ -631,9 +624,6 @@
     if (Assert.ASSERTS_ENABLED) {
       Assert.that(cb != null, "sanity check");
     }
-    if (cb == VM.getVM().ricochetBlob()) {
-      oopsRicochetDo(oopVisitor, regMap);
-    }
     if (cb.getOopMaps() != null) {
       OopMapSet.oopsDo(this, cb, regMap, oopVisitor, VM.getVM().isDebugging());
 
@@ -650,10 +640,6 @@
     //    }
   }
 
-  private void oopsRicochetDo      (AddressVisitor oopVisitor, RegisterMap regMap) {
-    // XXX Empty for now
-  }
-
   // FIXME: implement the above routines, plus add
   // oops_interpreted_arguments_do and oops_compiled_arguments_do
 }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
index 67d929d..5a4c344 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/Threads.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -91,6 +91,16 @@
                 access = new LinuxAMD64JavaThreadPDAccess();
             } else if (cpu.equals("sparc")) {
                 access = new LinuxSPARCJavaThreadPDAccess();
+            } else {
+              try {
+                access = (JavaThreadPDAccess)
+                  Class.forName("sun.jvm.hotspot.runtime.linux_" +
+                     cpu.toLowerCase() + ".Linux" + cpu.toUpperCase() +
+                     "JavaThreadPDAccess").newInstance();
+              } catch (Exception e) {
+                throw new RuntimeException("OS/CPU combination " + os + "/" + cpu +
+                                           " not yet supported");
+              }
             }
         } else if (os.equals("bsd")) {
             if (cpu.equals("x86")) {
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
index 5a96a8e..a143472 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java
@@ -87,13 +87,13 @@
   private StubRoutines stubRoutines;
   private Bytes        bytes;
 
-  private RicochetBlob ricochetBlob;
-
   /** Flags indicating whether we are attached to a core, C1, or C2 build */
   private boolean      usingClientCompiler;
   private boolean      usingServerCompiler;
   /** Flag indicating whether UseTLAB is turned on */
   private boolean      useTLAB;
+  /** Flag indicating whether invokedynamic support is on */
+  private boolean      enableInvokeDynamic;
   /** alignment constants */
   private boolean      isLP64;
   private int          bytesPerLong;
@@ -319,6 +319,7 @@
     }
 
     useTLAB = (db.lookupIntConstant("UseTLAB").intValue() != 0);
+    enableInvokeDynamic = (db.lookupIntConstant("EnableInvokeDynamic").intValue() != 0);
 
     if (debugger != null) {
       isLP64 = debugger.getMachineDescription().isLP64();
@@ -554,6 +555,10 @@
     return useTLAB;
   }
 
+  public boolean getEnableInvokeDynamic() {
+    return enableInvokeDynamic;
+  }
+
   public TypeDataBase getTypeDataBase() {
     return db;
   }
@@ -628,18 +633,6 @@
     return stubRoutines;
   }
 
-  public RicochetBlob ricochetBlob() {
-    if (ricochetBlob == null) {
-      Type ricochetType  = db.lookupType("SharedRuntime");
-      AddressField ricochetBlobAddress = ricochetType.getAddressField("_ricochet_blob");
-      Address addr = ricochetBlobAddress.getValue();
-      if (addr != null) {
-        ricochetBlob = new RicochetBlob(addr);
-      }
-    }
-    return ricochetBlob;
-  }
-
   public VMRegImpl getVMRegImplInfo() {
     if (vmregImpl == null) {
       vmregImpl = new VMRegImpl();
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java
index c756ec8..8b1e356 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCFrame.java
@@ -571,8 +571,6 @@
     //        registers callee-saved, then we will have to copy over
     //        the RegisterMap update logic from the Intel code.
 
-    if (isRicochetFrame()) return senderForRicochetFrame(map);
-
     // The constructor of the sender must know whether this frame is interpreted so it can set the
     // sender's _interpreter_sp_adjustment field.
     if (VM.getVM().getInterpreter().contains(pc)) {
@@ -945,20 +943,6 @@
   }
 
 
-  private Frame senderForRicochetFrame(SPARCRegisterMap map) {
-    if (DEBUG) {
-      System.out.println("senderForRicochetFrame");
-    }
-    //RicochetFrame* f = RicochetFrame::from_frame(fr);
-    // Cf. is_interpreted_frame path of frame::sender
-    Address youngerSP = getSP();
-    Address sp        = getSenderSP();
-    map.makeIntegerRegsUnsaved();
-    map.shiftWindow(sp, youngerSP);
-    boolean thisFrameAdjustedStack = true;  // I5_savedSP is live in this RF
-    return new SPARCFrame(biasSP(sp), biasSP(youngerSP), thisFrameAdjustedStack);
-  }
-
   private Frame senderForEntryFrame(RegisterMap regMap) {
     SPARCRegisterMap map = (SPARCRegisterMap) regMap;
 
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCRicochetFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCRicochetFrame.java
deleted file mode 100644
index 57fa927..0000000
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/sparc/SPARCRicochetFrame.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.runtime.sparc;
-
-import java.util.*;
-import sun.jvm.hotspot.asm.sparc.SPARCRegister;
-import sun.jvm.hotspot.asm.sparc.SPARCRegisters;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-public class SPARCRicochetFrame {
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private SPARCFrame frame;
-
-  private static void initialize(TypeDataBase db) {
-    // Type type = db.lookupType("MethodHandles::RicochetFrame");
-
-  }
-
-  static SPARCRicochetFrame fromFrame(SPARCFrame f) {
-    return new SPARCRicochetFrame(f);
-  }
-
-  private SPARCRicochetFrame(SPARCFrame f) {
-    frame = f;
-  }
-
-  private Address registerValue(SPARCRegister reg) {
-    return frame.getSP().addOffsetTo(reg.spOffsetInSavedWindow()).getAddressAt(0);
-  }
-
-  public Address savedArgsBase() {
-    return registerValue(SPARCRegisters.L4);
-  }
-  public Address exactSenderSP() {
-    return registerValue(SPARCRegisters.I5);
-  }
-  public Address senderLink() {
-    return frame.getSenderSP();
-  }
-  public Address senderPC() {
-    return frame.getSenderPC();
-  }
-  public Address extendedSenderSP() {
-    return savedArgsBase();
-  }
-}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java
index 41ef832..af71570 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86Frame.java
@@ -269,7 +269,6 @@
 
     if (isEntryFrame())       return senderForEntryFrame(map);
     if (isInterpretedFrame()) return senderForInterpreterFrame(map);
-    if (isRicochetFrame())    return senderForRicochetFrame(map);
 
     if(cb == null) {
       cb = VM.getVM().getCodeCache().findBlob(getPC());
@@ -288,16 +287,6 @@
     return new X86Frame(getSenderSP(), getLink(), getSenderPC());
   }
 
-  private Frame senderForRicochetFrame(X86RegisterMap map) {
-    if (DEBUG) {
-      System.out.println("senderForRicochetFrame");
-    }
-    X86RicochetFrame f = X86RicochetFrame.fromFrame(this);
-    if (map.getUpdateMap())
-      updateMapWithSavedLink(map, f.senderLinkAddress());
-    return new X86Frame(f.extendedSenderSP(), f.exactSenderSP(), f.senderLink(), f.senderPC());
-  }
-
   private Frame senderForEntryFrame(X86RegisterMap map) {
     if (DEBUG) {
       System.out.println("senderForEntryFrame");
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86RicochetFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86RicochetFrame.java
deleted file mode 100644
index 5d73ac9..0000000
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/x86/X86RicochetFrame.java
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-package sun.jvm.hotspot.runtime.x86;
-
-import java.util.*;
-import sun.jvm.hotspot.debugger.*;
-import sun.jvm.hotspot.runtime.*;
-import sun.jvm.hotspot.types.*;
-
-public class X86RicochetFrame extends VMObject {
-  static {
-    VM.registerVMInitializedObserver(new Observer() {
-        public void update(Observable o, Object data) {
-          initialize(VM.getVM().getTypeDataBase());
-        }
-      });
-  }
-
-  private static void initialize(TypeDataBase db) {
-    Type type = db.lookupType("MethodHandles::RicochetFrame");
-
-    senderLinkField    = type.getAddressField("_sender_link");
-    savedArgsBaseField = type.getAddressField("_saved_args_base");
-    exactSenderSPField = type.getAddressField("_exact_sender_sp");
-    senderPCField      = type.getAddressField("_sender_pc");
-  }
-
-  private static AddressField senderLinkField;
-  private static AddressField savedArgsBaseField;
-  private static AddressField exactSenderSPField;
-  private static AddressField senderPCField;
-
-  static X86RicochetFrame fromFrame(X86Frame f) {
-    return new X86RicochetFrame(f.getFP().addOffsetTo(- senderLinkField.getOffset()));
-  }
-
-  private X86RicochetFrame(Address addr) {
-    super(addr);
-  }
-
-  public Address senderLink() {
-    return senderLinkField.getValue(addr);
-  }
-  public Address senderLinkAddress() {
-    return addr.addOffsetTo(senderLinkField.getOffset());
-  }
-  public Address savedArgsBase() {
-    return savedArgsBaseField.getValue(addr);
-  }
-  public Address extendedSenderSP() {
-    return savedArgsBase();
-  }
-  public Address exactSenderSP() {
-    return exactSenderSPField.getValue(addr);
-  }
-  public Address senderPC() {
-    return senderPCField.getValue(addr);
-  }
-}
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
index f4e3d7c..a71592d 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassWriter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -504,11 +504,14 @@
                             2           /* exp. table len.  */ +
                             2           /* code attr. count */;
 
-            TypeArray exceptionTable = m.getExceptionTable();
-            final int exceptionTableLen = (int) exceptionTable.getLength();
-            if (exceptionTableLen != 0) {
+            boolean hasExceptionTable = m.hasExceptionTable();
+            ExceptionTableElement[] exceptionTable = null;
+            int exceptionTableLen = 0;
+            if (hasExceptionTable) {
+                exceptionTable = m.getExceptionTable();
+                exceptionTableLen = exceptionTable.length;
                 if (DEBUG) debugMessage("\tmethod has exception table");
-                codeSize += (exceptionTableLen / 4) /* exception table is 4-tuple array */
+                codeSize += exceptionTableLen /* exception table is 4-tuple array */
                                          * (2 /* start_pc     */ +
                                             2 /* end_pc       */ +
                                             2 /* handler_pc   */ +
@@ -586,15 +589,15 @@
             dos.write(code);
 
             // write exception table size
-            dos.writeShort((short) (exceptionTableLen / 4));
-            if (DEBUG) debugMessage("\texception table length = " + (exceptionTableLen / 4));
+            dos.writeShort((short) exceptionTableLen);
+            if (DEBUG) debugMessage("\texception table length = " + exceptionTableLen);
 
             if (exceptionTableLen != 0) {
-                for (int e = 0; e < exceptionTableLen; e += 4) {
-                     dos.writeShort((short) exceptionTable.getIntAt(e));
-                     dos.writeShort((short) exceptionTable.getIntAt(e + 1));
-                     dos.writeShort((short) exceptionTable.getIntAt(e + 2));
-                     dos.writeShort((short) exceptionTable.getIntAt(e + 3));
+                for (int e = 0; e < exceptionTableLen; e++) {
+                     dos.writeShort((short) exceptionTable[e].getStartPC());
+                     dos.writeShort((short) exceptionTable[e].getEndPC());
+                     dos.writeShort((short) exceptionTable[e].getHandlerPC());
+                     dos.writeShort((short) exceptionTable[e].getCatchTypeIndex());
                 }
             }
 
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
index b8d5c8b..5e55c32 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -204,7 +204,13 @@
       } else if (cpu.equals("ia64")) {
          cpuHelper = new IA64Helper();
       } else {
+        try {
+          cpuHelper = (CPUHelper)Class.forName("sun.jvm.hotspot.asm." +
+             cpu.toLowerCase() + "." + cpu.toUpperCase() +
+             "Helper").newInstance();
+        } catch (Exception e) {
           throw new RuntimeException("cpu '" + cpu + "' is not yet supported!");
+        }
       }
    }
 
@@ -783,37 +789,39 @@
                        });
 
          // display exception table for this method
-         TypeArray exceptionTable = method.getExceptionTable();
-         // exception table is 4 tuple array of shorts
-         int numEntries = (int)exceptionTable.getLength() / 4;
-         if (numEntries != 0) {
-            buf.h4("Exception Table");
-            buf.beginTable(1);
-            buf.beginTag("tr");
-            buf.headerCell("start bci");
-            buf.headerCell("end bci");
-            buf.headerCell("handler bci");
-            buf.headerCell("catch type");
-            buf.endTag("tr");
-
-            for (int e = 0; e < numEntries; e += 4) {
+         boolean hasException = method.hasExceptionTable();
+         if (hasException) {
+            ExceptionTableElement[] exceptionTable = method.getExceptionTable();
+            int numEntries = exceptionTable.length;
+            if (numEntries != 0) {
+               buf.h4("Exception Table");
+               buf.beginTable(1);
                buf.beginTag("tr");
-               buf.cell(Integer.toString(exceptionTable.getIntAt(e)));
-               buf.cell(Integer.toString(exceptionTable.getIntAt(e + 1)));
-               buf.cell(Integer.toString(exceptionTable.getIntAt(e + 2)));
-               short cpIndex = (short) exceptionTable.getIntAt(e + 3);
-               ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
-               if (obj == null) {
-                  buf.cell("Any");
-               } else if (obj.isMetaData()) {
-                 buf.cell(obj.getSymbol().asString().replace('/', '.'));
-               } else {
-                 buf.cell(genKlassLink((InstanceKlass)obj.getOop()));
-               }
+               buf.headerCell("start bci");
+               buf.headerCell("end bci");
+               buf.headerCell("handler bci");
+               buf.headerCell("catch type");
                buf.endTag("tr");
-            }
 
-            buf.endTable();
+               for (int e = 0; e < numEntries; e ++) {
+                  buf.beginTag("tr");
+                  buf.cell(Integer.toString(exceptionTable[e].getStartPC()));
+                  buf.cell(Integer.toString(exceptionTable[e].getEndPC()));
+                  buf.cell(Integer.toString(exceptionTable[e].getHandlerPC()));
+                  short cpIndex = (short) exceptionTable[e].getCatchTypeIndex();
+                  ConstantPool.CPSlot obj = cpIndex == 0? null : cpool.getSlotAt(cpIndex);
+                  if (obj == null) {
+                     buf.cell("Any");
+                  } else if (obj.isMetaData()) {
+                     buf.cell(obj.getSymbol().asString().replace('/', '.'));
+                  } else {
+                     buf.cell(genKlassLink((InstanceKlass)obj.getOop()));
+                  }
+                  buf.endTag("tr");
+               }
+
+               buf.endTable();
+            }
          }
 
          // display constant pool hyperlink
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/AltPlatformInfo.java
similarity index 78%
rename from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
rename to hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/AltPlatformInfo.java
index 077886f..0b802c3 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/AltPlatformInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -22,14 +22,10 @@
  *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+package sun.jvm.hotspot.utilities;
 
-    public FileFormatException() {
-        super();
-    }
+public interface AltPlatformInfo {
+  // Additional cpu types can be tested via this interface
 
-    public FileFormatException(String s) {
-        super(s);
-    }
-}
+  public boolean knownCPU(String cpu);
+}
\ No newline at end of file
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/BasicHashtable.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/BasicHashtable.java
index bb296a5..0f4da3a 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/BasicHashtable.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/BasicHashtable.java
@@ -41,10 +41,10 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("BasicHashtable");
+    Type type = db.lookupType("BasicHashtable<mtInternal>");
     tableSizeField = type.getCIntegerField("_table_size");
     bucketsField   = type.getAddressField("_buckets");
-    bucketSize = db.lookupType("HashtableBucket").getSize();
+    bucketSize = db.lookupType("HashtableBucket<mtInternal>").getSize();
   }
 
   // Fields
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/BasicHashtableEntry.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/BasicHashtableEntry.java
index 192c1dd..0296dcb 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/BasicHashtableEntry.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/BasicHashtableEntry.java
@@ -41,7 +41,7 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("BasicHashtableEntry");
+    Type type = db.lookupType("BasicHashtableEntry<mtInternal>");
     hashField      = type.getCIntegerField("_hash");
     nextField      = type.getAddressField("_next");
   }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/Hashtable.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/Hashtable.java
index 3c2e0f9..70709f0 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/Hashtable.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/Hashtable.java
@@ -40,7 +40,7 @@
 
   private static synchronized void initialize(TypeDataBase db) {
     // just to confirm that type exists
-    Type type = db.lookupType("Hashtable<intptr_t>");
+    Type type = db.lookupType("IntptrHashtable");
   }
 
   // derived class may return Class<? extends HashtableEntry>
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableBucket.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableBucket.java
index 2e86b9a..44f78e4 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableBucket.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableBucket.java
@@ -39,7 +39,7 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("HashtableBucket");
+    Type type = db.lookupType("HashtableBucket<mtInternal>");
     entryField = type.getAddressField("_entry");
   }
 
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java
index 73932a4..38c5968 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/HashtableEntry.java
@@ -41,7 +41,7 @@
   }
 
   private static synchronized void initialize(TypeDataBase db) {
-    Type type = db.lookupType("HashtableEntry<intptr_t>");
+    Type type = db.lookupType("IntptrHashtableEntry");
     literalField   = type.getAddressField("_literal");
   }
 
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java
index d069db2..9a5dc14 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/PlatformInfo.java
@@ -64,6 +64,13 @@
     } else if (cpu.equals("ia64") || cpu.equals("amd64") || cpu.equals("x86_64")) {
       return cpu;
     } else {
+      try {
+        Class pic = Class.forName("sun.jvm.hotspot.utilities.PlatformInfoClosed");
+        AltPlatformInfo api = (AltPlatformInfo)pic.newInstance();
+        if (api.knownCPU(cpu)) {
+          return cpu;
+        }
+      } catch (Exception e) {}
       throw new UnsupportedPlatformException("CPU type " + cpu + " not yet supported");
     }
   }
diff --git a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFrame.java b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFrame.java
index 0efd244..cc3f216 100644
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFrame.java
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/JSJavaFrame.java
@@ -153,7 +153,8 @@
             List visibleVars = new ArrayList(0);
             for (int i = 0; i < localVars.length; i++) {
                 LocalVariableTableElement cur = localVars[i];
-                if (cur.getStartBCI() >= bci && cur.getLength() > 0) {
+                int startBCI = cur.getStartBCI();
+                if (startBCI <= bci && bci < startBCI + cur.getLength()) {
                     visibleVars.add(cur);
                 }
             }
diff --git a/hotspot/make/Makefile b/hotspot/make/Makefile
index f367de5..fc536c1 100644
--- a/hotspot/make/Makefile
+++ b/hotspot/make/Makefile
@@ -288,23 +288,25 @@
 ZERO_DIR=$(ZERO_BASE_DIR)/$(VM_SUBDIR)
 SHARK_DIR=$(SHARK_BASE_DIR)/$(VM_SUBDIR)
 
-# Misc files and generated files need to come from C1 or C2 area
-ifeq ($(ZERO_BUILD), true)
-ifeq ($(SHARK_BUILD), true)
-  MISC_DIR=$(SHARK_DIR)
-  GEN_DIR=$(SHARK_BASE_DIR)/generated
-else
-  MISC_DIR=$(ZERO_DIR)
-  GEN_DIR=$(ZERO_BASE_DIR)/generated
+ifeq ($(JVM_VARIANT_SERVER), true)
+    MISC_DIR=$(C2_DIR)
+    GEN_DIR=$(C2_BASE_DIR)/generated
 endif
-else
-ifeq ($(ARCH_DATA_MODEL), 32)
-  MISC_DIR=$(C1_DIR)
-  GEN_DIR=$(C1_BASE_DIR)/generated
-else
-  MISC_DIR=$(C2_DIR)
-  GEN_DIR=$(C2_BASE_DIR)/generated
+ifeq ($(JVM_VARIANT_CLIENT), true)
+    MISC_DIR=$(C1_DIR)
+    GEN_DIR=$(C1_BASE_DIR)/generated
 endif
+ifeq ($(JVM_VARIANT_KERNEL), true)
+    MISC_DIR=$(C2_DIR)
+    GEN_DIR=$(C2_BASE_DIR)/generated
+endif
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+    MISC_DIR=$(SHARK_DIR)
+    GEN_DIR=$(SHARK_BASE_DIR)/generated
+endif
+ifeq ($(JVM_VARIANT_ZERO), true)
+    MISC_DIR=$(ZERO_DIR)
+    GEN_DIR=$(ZERO_BASE_DIR)/generated
 endif
 
 # Bin files (windows)
@@ -357,66 +359,67 @@
 
 # Shared Library
 ifneq ($(OSNAME),windows)
-  ifeq ($(ZERO_BUILD), true)
-    ifeq ($(SHARK_BUILD), true)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-    else
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
+    ifeq ($(JVM_VARIANT_SERVER), true)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C2_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 		$(C2_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.debuginfo:       		$(C2_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/64/%.debuginfo:    		$(C2_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: 			$(C2_DIR)/%.diz
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.diz:       			$(C2_DIR)/%.diz
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/64/%.diz:    			$(C2_DIR)/%.diz
+		$(install-file)
     endif
-  else
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C2_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX):       $(C1_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C1_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(C2_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C2_DIR)/%.$(LIBRARY_SUFFIX)
-	$(install-file)
-
-# Debug info for shared library
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C1_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: $(C2_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.debuginfo:       $(C1_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.debuginfo:    $(C1_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.debuginfo:       $(C2_DIR)/%.debuginfo
-	$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.debuginfo:    $(C2_DIR)/%.debuginfo
-	$(install-file)
-
-# ZIP'ed debug info for shared library
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C1_DIR)/%.diz
-	$(install-file)
-$(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: $(C2_DIR)/%.diz
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/%.diz:       $(C1_DIR)/%.diz
-	$(install-file)
-$(EXPORT_CLIENT_DIR)/64/%.diz:    $(C1_DIR)/%.diz
-	$(install-file)
-$(EXPORT_SERVER_DIR)/%.diz:       $(C2_DIR)/%.diz
-	$(install-file)
-$(EXPORT_SERVER_DIR)/64/%.diz:    $(C2_DIR)/%.diz
-	$(install-file)
-  endif
+    ifeq ($(JVM_VARIANT_CLIENT), true)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/%.$(LIBRARY_SUFFIX):       $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/64/%.$(LIBRARY_SUFFIX):    $(C1_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.debuginfo: 		$(C1_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/%.debuginfo:       		$(C1_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/64/%.debuginfo:    		$(C1_DIR)/%.debuginfo
+		$(install-file)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.diz: 			$(C1_DIR)/%.diz
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/%.diz:       			$(C1_DIR)/%.diz
+		$(install-file)
+        $(EXPORT_CLIENT_DIR)/64/%.diz:    			$(C1_DIR)/%.diz
+		$(install-file)
+    endif
+    ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(SHARK_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+    endif
+    ifeq ($(JVM_VARIANT_ZERO), true)
+        $(EXPORT_JRE_LIB_ARCH_DIR)/%.$(LIBRARY_SUFFIX): $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+        $(EXPORT_SERVER_DIR)/%.$(LIBRARY_SUFFIX):       $(ZERO_DIR)/%.$(LIBRARY_SUFFIX)
+		$(install-file)
+    endif
 endif
 
 # Jar file (sa-jdi.jar)
 $(EXPORT_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
 	$(install-file)
 
+$(EXPORT_JRE_LIB_DIR)/%.jar: $(GEN_DIR)/%.jar
+	$(install-file)
+
 # Include files (jvmti.h, jvmticmlr.h, jni.h, $(JDK_INCLUDE_SUBDIR)/jni_md.h, jmm.h, jfr.h)
 $(EXPORT_INCLUDE_DIR)/%: $(GEN_DIR)/jvmtifiles/%
 	$(install-file)
@@ -486,18 +489,19 @@
 	 ($(CD) $(JDK_IMAGE_DIR) && $(TAR) -xf -)
 
 test_jdk:
-    ifeq ($(ARCH_DATA_MODEL), 32)
-      ifneq ($(ZERO_BUILD), true)
-	$(JDK_IMAGE_DIR)/bin/java -d32 -client -Xinternalversion
-	$(JDK_IMAGE_DIR)/bin/java -d32 -client -version
-      endif
-	$(JDK_IMAGE_DIR)/bin/java -d32 -server -Xinternalversion
-	$(JDK_IMAGE_DIR)/bin/java -d32 -server -version
-    endif
-    ifeq ($(ARCH_DATA_MODEL), 64)
-	$(JDK_IMAGE_DIR)/bin/java -d64 -server -Xinternalversion
-	$(JDK_IMAGE_DIR)/bin/java -d64 -server -version
-    endif
+  ifeq ($(JVM_VARIANT_CLIENT), true)
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -client -Xinternalversion
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -client -version
+  endif
+  ifeq ($(findstring true, $(JVM_VARIANT_SERVER)\
+		$(JVM_VARIANT_ZERO)$(JVM_VARIANT_ZEROSHARK)), true)
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -Xinternalversion
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -server -version
+  endif
+  ifeq ($(JVM_VARIANT_KERNEL), true)
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -Xinternalversion
+	$(JDK_IMAGE_DIR)/bin/java -d$(ARCH_DATA_MODEL) -kernel -version
+  endif
 
 copy_product_jdk::
 	$(RM) -r $(JDK_IMAGE_DIR)
diff --git a/hotspot/make/bsd/Makefile b/hotspot/make/bsd/Makefile
index 9660f4a..518c54f 100644
--- a/hotspot/make/bsd/Makefile
+++ b/hotspot/make/bsd/Makefile
@@ -188,7 +188,7 @@
 # in the build.sh script:
 TARGETS           = debug jvmg fastdebug optimized profiled product
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   SUBDIR_DOCS     = $(OSNAME)_$(VARIANTARCH)_docs
 else
   SUBDIR_DOCS     = $(OSNAME)_$(BUILDARCH)_docs
diff --git a/hotspot/make/bsd/makefiles/buildtree.make b/hotspot/make/bsd/makefiles/buildtree.make
index 960a382..ecd7368 100644
--- a/hotspot/make/bsd/makefiles/buildtree.make
+++ b/hotspot/make/bsd/makefiles/buildtree.make
@@ -58,6 +58,7 @@
 # needs to be set here since this Makefile doesn't include defs.make
 OS_VENDOR:=$(shell uname -s)
 
+-include $(SPEC)
 include $(GAMMADIR)/make/scm.make
 include $(GAMMADIR)/make/altsrc.make
 
@@ -68,7 +69,7 @@
 # For now, until the compiler is less wobbly:
 TESTFLAGS	= -Xbatch -showversion
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
 else
   ifdef USE_SUNCC
@@ -162,6 +163,13 @@
   endif
 endif
 
+# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
+ifndef OPENJDK
+  ifneq ($(call if-has-altsrc,$(HS_COMMON_SRC)/,true,false),true)
+    OPENJDK=true
+  endif
+endif
+
 BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HS_BUILD_VER) HOTSPOT_BUILD_VERSION=  JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
 
 BUILDTREE	= \
@@ -204,6 +212,7 @@
 	echo "SA_BUILD_VERSION = $(HS_BUILD_VER)"; \
 	echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \
 	echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \
+	echo "OPENJDK = $(OPENJDK)"; \
 	echo; \
 	echo "# Used for platform dispatching"; \
 	echo "TARGET_DEFINES  = -DTARGET_OS_FAMILY_\$$(Platform_os_family)"; \
@@ -247,6 +256,8 @@
 	    echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \
 	    echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \
 	echo; \
+	[ -n "$(SPEC)" ] && \
+	    echo "include $(SPEC)"; \
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(VARIANT).make"; \
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(COMPILER).make"; \
 	) > $@
diff --git a/hotspot/make/bsd/makefiles/defs.make b/hotspot/make/bsd/makefiles/defs.make
index 7048970b..1183981 100644
--- a/hotspot/make/bsd/makefiles/defs.make
+++ b/hotspot/make/bsd/makefiles/defs.make
@@ -38,7 +38,7 @@
 endif
 
 # zero
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   ifeq ($(ARCH_DATA_MODEL), 64)
     MAKE_ARGS      += LP64=1
   endif
@@ -124,6 +124,18 @@
   HS_ARCH          = ppc
 endif
 
+# On 32 bit bsd we build server and client, on 64 bit just server.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    JVM_VARIANTS:=client,server
+    JVM_VARIANT_CLIENT:=true
+    JVM_VARIANT_SERVER:=true
+  else
+    JVM_VARIANTS:=server
+    JVM_VARIANT_SERVER:=true
+  endif
+endif
+
 JDK_INCLUDE_SUBDIR=bsd
 
 # Library suffix
@@ -144,16 +156,16 @@
 EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
 EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
 
-ifndef BUILD_CLIENT_ONLY
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
+
+ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
 endif
 
-ifneq ($(ZERO_BUILD), true)
-  ifeq ($(ARCH_DATA_MODEL), 32)
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
-  endif
+ifeq ($(JVM_VARIANT_CLIENT),true)
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
 endif
 
 # Serviceability Binaries
diff --git a/hotspot/make/bsd/makefiles/dtrace.make b/hotspot/make/bsd/makefiles/dtrace.make
index 1f5d956..98ce02f 100644
--- a/hotspot/make/bsd/makefiles/dtrace.make
+++ b/hotspot/make/bsd/makefiles/dtrace.make
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2012, 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,21 +114,21 @@
 
 # $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
 $(JVMOFFS).h: $(GENOFFS)
-	$(QUIETLY) DYLD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp; touch $@; \
+	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -header > $@.tmp; touch $@; \
 	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
 	then rm -f $@; mv $@.tmp $@; \
 	else rm -f $@.tmp; \
 	fi
 
 $(JVMOFFS)Index.h: $(GENOFFS)
-	$(QUIETLY) DYLD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp; touch $@; \
+	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -index > $@.tmp; touch $@; \
 	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
 	then rm -f $@; mv $@.tmp $@; \
 	else rm -f $@.tmp; \
 	fi
 
 $(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
-	$(QUIETLY) DYLD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp; touch $@; \
+	$(QUIETLY) DYLD_LIBRARY_PATH=.:$(DYLD_LIBRARY_PATH) ./$(GENOFFS) -table > $@.tmp; touch $@; \
 	if [ `diff $@.tmp $@ > /dev/null 2>&1; echo $$?` -ne 0 ] ; \
 	then rm -f $@; mv $@.tmp $@; \
 	else rm -f $@.tmp; \
diff --git a/hotspot/make/bsd/makefiles/gcc.make b/hotspot/make/bsd/makefiles/gcc.make
index d7a6422..249628e 100644
--- a/hotspot/make/bsd/makefiles/gcc.make
+++ b/hotspot/make/bsd/makefiles/gcc.make
@@ -27,53 +27,57 @@
 #------------------------------------------------------------------------
 # CC, CXX & AS
 
-# When cross-compiling the ALT_COMPILER_PATH points
-# to the cross-compilation toolset
-ifdef CROSS_COMPILE_ARCH
- CXX = $(ALT_COMPILER_PATH)/g++
- CC  = $(ALT_COMPILER_PATH)/gcc
- HOSTCXX = g++
- HOSTCC  = gcc
-else ifneq ($(OS_VENDOR), Darwin)
- CXX = g++
- CC  = gcc
- HOSTCXX = $(CXX)
- HOSTCC  = $(CC)
+# If a SPEC is not set already, then use these defaults.
+ifeq ($(SPEC),)
+  # When cross-compiling the ALT_COMPILER_PATH points
+  # to the cross-compilation toolset
+  ifdef CROSS_COMPILE_ARCH
+    CXX = $(ALT_COMPILER_PATH)/g++
+    CC  = $(ALT_COMPILER_PATH)/gcc
+    HOSTCXX = g++
+    HOSTCC  = gcc
+  else ifneq ($(OS_VENDOR), Darwin)
+    CXX = g++
+    CC  = gcc
+    HOSTCXX = $(CXX)
+    HOSTCC  = $(CC)
+  endif
+
+  # i486 hotspot requires -mstackrealign on Darwin.
+  # llvm-gcc supports this in Xcode 3.2.6 and 4.0.
+  # gcc-4.0 supports this on earlier versions.
+  # Prefer llvm-gcc where available.
+  ifeq ($(OS_VENDOR), Darwin)
+    ifeq ($(origin CXX), default)
+      CXX = llvm-g++
+    endif
+    ifeq ($(origin CC), default)
+      CC  = llvm-gcc
+    endif
+
+    ifeq ($(ARCH), i486)
+      LLVM_SUPPORTS_STACKREALIGN := $(shell \
+       [ "0"`llvm-gcc -v 2>&1 | grep LLVM | sed -E "s/.*LLVM build ([0-9]+).*/\1/"` -gt "2333" ] \
+       && echo true || echo false)
+
+      ifeq ($(LLVM_SUPPORTS_STACKREALIGN), true)
+        CXX32 ?= llvm-g++
+        CC32  ?= llvm-gcc
+      else
+        CXX32 ?= g++-4.0
+        CC32  ?= gcc-4.0
+      endif
+      CXX = $(CXX32)
+      CC  = $(CC32)
+    endif
+
+    HOSTCXX = $(CXX)
+    HOSTCC  = $(CC)
+  endif
+
+  AS   = $(CC) -c -x assembler-with-cpp
 endif
 
-# i486 hotspot requires -mstackrealign on Darwin.
-# llvm-gcc supports this in Xcode 3.2.6 and 4.0.
-# gcc-4.0 supports this on earlier versions.
-# Prefer llvm-gcc where available.
-ifeq ($(OS_VENDOR), Darwin)
-  ifeq ($(origin CXX), default)
-   CXX = llvm-g++
-  endif
-  ifeq ($(origin CC), default)
-   CC  = llvm-gcc
-  endif
-
-  ifeq ($(ARCH), i486)
-  LLVM_SUPPORTS_STACKREALIGN := $(shell \
-   [ "0"`llvm-gcc -v 2>&1 | grep LLVM | sed -E "s/.*LLVM build ([0-9]+).*/\1/"` -gt "2333" ] \
-   && echo true || echo false)
-
-  ifeq ($(LLVM_SUPPORTS_STACKREALIGN), true)
-    CXX32 ?= llvm-g++
-    CC32  ?= llvm-gcc
-  else
-    CXX32 ?= g++-4.0
-    CC32  ?= gcc-4.0
-  endif
-  CXX = $(CXX32)
-  CC  = $(CC32)
-  endif
-
-  HOSTCXX = $(CXX)
-  HOSTCC  = $(CC)
-endif
-
-AS   = $(CC) -c -x assembler-with-cpp
 
 # -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
 # prints the numbers (e.g. "2.95", "3.2.1")
@@ -101,11 +105,12 @@
 VM_PICFLAG/AOUT   =
 VM_PICFLAG        = $(VM_PICFLAG/$(LINK_INTO))
 
-ifeq ($(ZERO_BUILD), true)
-CFLAGS += $(LIBFFI_CFLAGS)
+ifeq ($(JVM_VARIANT_ZERO), true)
+  CFLAGS += $(LIBFFI_CFLAGS)
 endif
-ifeq ($(SHARK_BUILD), true)
-CFLAGS += $(LLVM_CFLAGS)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+  CFLAGS += $(LIBFFI_CFLAGS)
+  CFLAGS += $(LLVM_CFLAGS)
 endif
 CFLAGS += $(VM_PICFLAG)
 CFLAGS += -fno-rtti
@@ -209,7 +214,7 @@
 
 # Flags for generating make dependency flags.
 ifneq ("${CC_VER_MAJOR}", "2")
-DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
+DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
 endif
 
 # -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
diff --git a/hotspot/make/bsd/makefiles/jvmg.make b/hotspot/make/bsd/makefiles/jvmg.make
index 8c56368..b5be296 100644
--- a/hotspot/make/bsd/makefiles/jvmg.make
+++ b/hotspot/make/bsd/makefiles/jvmg.make
@@ -27,7 +27,9 @@
 # Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
 DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
 DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
-CFLAGS += $(DEBUG_CFLAGS/BYFILE)
+
+# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
+CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
 
 # Set the environment variable HOTSPARC_GENERIC to "true"
 # to inhibit the effect of the previous line on CFLAGS.
diff --git a/hotspot/make/bsd/makefiles/sparcWorks.make b/hotspot/make/bsd/makefiles/sparcWorks.make
index 81de9c3..c87f504 100644
--- a/hotspot/make/bsd/makefiles/sparcWorks.make
+++ b/hotspot/make/bsd/makefiles/sparcWorks.make
@@ -25,12 +25,15 @@
 #------------------------------------------------------------------------
 # CC, CXX & AS
 
-CXX = CC
-CC  = cc
-AS  = $(CC) -c
+# If a SPEC is not set already, then use these defaults.
+ifeq ($(SPEC),)
+  CXX = CC
+  CC  = cc
+  AS  = $(CC) -c
 
-HOSTCXX = $(CXX)
-HOSTCC  = $(CC)
+  HOSTCXX = $(CXX)
+  HOSTCC  = $(CC)
+endif
 
 ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
 ARCHFLAG/i486    = -m32
diff --git a/hotspot/make/bsd/makefiles/universal.gmk b/hotspot/make/bsd/makefiles/universal.gmk
index 169b70d..0cc9275 100644
--- a/hotspot/make/bsd/makefiles/universal.gmk
+++ b/hotspot/make/bsd/makefiles/universal.gmk
@@ -110,4 +110,5 @@
 
 .PHONY:	universal_product universal_fastdebug universal_debug \
 	all_product_universal all_fastdebug_universal all_debug_universal \
-	universalize export_universal copy_universal
+	universalize export_universal copy_universal \
+	$(UNIVERSAL_LIPO_LIST) $(UNIVERSAL_COPY_LIST)
diff --git a/hotspot/make/bsd/makefiles/vm.make b/hotspot/make/bsd/makefiles/vm.make
index 0124422..f423408 100644
--- a/hotspot/make/bsd/makefiles/vm.make
+++ b/hotspot/make/bsd/makefiles/vm.make
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2012, 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,7 +42,7 @@
 -include $(DEP_DIR)/*.d
 
 # read machine-specific adjustments (%%% should do this via buildtree.make?)
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   include $(MAKEFILES_DIR)/zeroshark.make
 else
   include $(MAKEFILES_DIR)/$(BUILDARCH).make
@@ -271,12 +271,12 @@
 
   LIBS_VM                  += $(LIBS)
 endif
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(JVM_VARIANT_ZERO), true)
   LIBS_VM += $(LIBFFI_LIBS)
 endif
-ifeq ($(SHARK_BUILD), true)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+  LIBS_VM   += $(LIBFFI_LIBS) $(LLVM_LIBS)
   LFLAGS_VM += $(LLVM_LDFLAGS)
-  LIBS_VM   += $(LLVM_LIBS)
 endif
 
 
@@ -335,6 +335,9 @@
 # Serviceability agent
 include $(MAKEFILES_DIR)/saproc.make
 
+# Whitebox testing API
+include $(MAKEFILES_DIR)/wb.make
+
 #----------------------------------------------------------------------
 
 ifeq ($(OS_VENDOR), Darwin)
@@ -342,10 +345,10 @@
 	dsymutil $(LIBJVM)
 
 # no libjvm_db for macosx
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(BUILDLIBSAPROC) dtraceCheck $(LIBJVM).dSYM $(WB_JAR)
 	echo "Doing vm.make build:"
 else
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) $(WB_JAR)
 endif
 
 install: install_jvm install_jsig install_saproc
diff --git a/hotspot/make/bsd/makefiles/wb.make b/hotspot/make/bsd/makefiles/wb.make
new file mode 100644
index 0000000..8298d87
--- /dev/null
+++ b/hotspot/make/bsd/makefiles/wb.make
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2012, 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.
+#  
+#
+
+# Rules to build whitebox testing library, used by vm.make
+WB = wb
+
+WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
+
+WB_JAR = $(GENERATED)/$(WB).jar
+
+WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
+WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
+
+WB_JAVA_CLASSES  = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
+	$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
+
+$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
+	$(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
+
+$(WB_JAR): $(WB_JAVA_CLASSES)
+	$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
+
+$(WB_JAVA_CLASSDIR):
+	$(QUIETLY) mkdir -p $@
+
diff --git a/hotspot/make/defs.make b/hotspot/make/defs.make
index a0aa0e5..63c6be7 100644
--- a/hotspot/make/defs.make
+++ b/hotspot/make/defs.make
@@ -22,8 +22,21 @@
 #  
 #
 
+ifeq ($(HS_ALT_MAKE),)
+  ifneq ($(OPENJDK),true)
+    HS_ALT_MAKE=$(GAMMADIR)/make/closed
+  else
+    HS_ALT_MAKE=NO_SUCH_PATH
+  endif
+endif
+
 # The common definitions for hotspot builds.
 
+# Optionally include SPEC file generated by configure.
+ifneq ($(SPEC),)
+  include $(SPEC)
+endif
+
 # Default to verbose build logs (show all compile lines):
 MAKE_VERBOSE=y
 
@@ -50,6 +63,27 @@
 @$(RM) $@
 endef
 
+# Default values for JVM_VARIANT* variables if configure hasn't set
+# it already.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ZERO_BUILD), true)
+    ifeq ($(SHARK_BUILD), true)
+      JVM_VARIANTS:=zeroshark
+      JVM_VARIANT_ZEROSHARK:=true
+    else
+      JVM_VARIANTS:=zero
+      JVM_VARIANT_ZERO:=true
+    endif
+  else
+    # A default is needed
+    ifeq ($(BUILD_CLIENT_ONLY), true)
+      JVM_VARIANTS:=client
+      JVM_VARIANT_CLIENT:=true
+    endif
+    # Further defaults are platform and arch specific
+  endif
+endif
+
 # Directory paths and user name
 # Unless GAMMADIR is set on the command line, search upward from
 # the current directory for a parent directory containing "src/share/vm".
@@ -301,3 +335,4 @@
 ifndef JAVASE_EMBEDDED
 EXPORT_LIST += $(EXPORT_INCLUDE_DIR)/jfr.h
 endif
+
diff --git a/hotspot/make/hotspot_version b/hotspot/make/hotspot_version
index 3451145..2ded6dd 100644
--- a/hotspot/make/hotspot_version
+++ b/hotspot/make/hotspot_version
@@ -33,9 +33,9 @@
 # Don't put quotes (fail windows build).
 HOTSPOT_VM_COPYRIGHT=Copyright 2012
 
-HS_MAJOR_VER=23
-HS_MINOR_VER=6
-HS_BUILD_NUMBER=04
+HS_MAJOR_VER=24
+HS_MINOR_VER=0
+HS_BUILD_NUMBER=28
 
 JDK_MAJOR_VER=1
 JDK_MINOR_VER=7
diff --git a/hotspot/make/jprt.properties b/hotspot/make/jprt.properties
index 4b99e88..c101348 100644
--- a/hotspot/make/jprt.properties
+++ b/hotspot/make/jprt.properties
@@ -38,7 +38,7 @@
 
 # This tells jprt what default release we want to build
 
-jprt.hotspot.default.release=jdk7u6
+jprt.hotspot.default.release=jdk7u12
 
 jprt.tools.default.release=${jprt.submit.option.release?${jprt.submit.option.release}:${jprt.hotspot.default.release}}
 
@@ -54,77 +54,97 @@
 # Define the Solaris platforms we want for the various releases
 jprt.my.solaris.sparc.jdk8=solaris_sparc_5.10
 jprt.my.solaris.sparc.jdk7=solaris_sparc_5.10
-jprt.my.solaris.sparc.jdk7u6=${jprt.my.solaris.sparc.jdk7}
+jprt.my.solaris.sparc.jdk7u12=${jprt.my.solaris.sparc.jdk7}
 jprt.my.solaris.sparc=${jprt.my.solaris.sparc.${jprt.tools.default.release}}
 
 jprt.my.solaris.sparcv9.jdk8=solaris_sparcv9_5.10
 jprt.my.solaris.sparcv9.jdk7=solaris_sparcv9_5.10
-jprt.my.solaris.sparcv9.jdk7u6=${jprt.my.solaris.sparcv9.jdk7}
+jprt.my.solaris.sparcv9.jdk7u12=${jprt.my.solaris.sparcv9.jdk7}
 jprt.my.solaris.sparcv9=${jprt.my.solaris.sparcv9.${jprt.tools.default.release}}
 
 jprt.my.solaris.i586.jdk8=solaris_i586_5.10
 jprt.my.solaris.i586.jdk7=solaris_i586_5.10
-jprt.my.solaris.i586.jdk7u6=${jprt.my.solaris.i586.jdk7}
+jprt.my.solaris.i586.jdk7u12=${jprt.my.solaris.i586.jdk7}
 jprt.my.solaris.i586=${jprt.my.solaris.i586.${jprt.tools.default.release}}
 
 jprt.my.solaris.x64.jdk8=solaris_x64_5.10
 jprt.my.solaris.x64.jdk7=solaris_x64_5.10
-jprt.my.solaris.x64.jdk7u6=${jprt.my.solaris.x64.jdk7}
+jprt.my.solaris.x64.jdk7u12=${jprt.my.solaris.x64.jdk7}
 jprt.my.solaris.x64=${jprt.my.solaris.x64.${jprt.tools.default.release}}
 
 jprt.my.linux.i586.jdk8=linux_i586_2.6
 jprt.my.linux.i586.jdk7=linux_i586_2.6
-jprt.my.linux.i586.jdk7u6=${jprt.my.linux.i586.jdk7}
+jprt.my.linux.i586.jdk7u12=${jprt.my.linux.i586.jdk7}
 jprt.my.linux.i586=${jprt.my.linux.i586.${jprt.tools.default.release}}
 
 jprt.my.linux.x64.jdk8=linux_x64_2.6
 jprt.my.linux.x64.jdk7=linux_x64_2.6
-jprt.my.linux.x64.jdk7u6=${jprt.my.linux.x64.jdk7}
+jprt.my.linux.x64.jdk7u12=${jprt.my.linux.x64.jdk7}
 jprt.my.linux.x64=${jprt.my.linux.x64.${jprt.tools.default.release}}
 
 jprt.my.linux.ppc.jdk8=linux_ppc_2.6
 jprt.my.linux.ppc.jdk7=linux_ppc_2.6
-jprt.my.linux.ppc.jdk7u6=${jprt.my.linux.ppc.jdk7}
+jprt.my.linux.ppc.jdk7u12=${jprt.my.linux.ppc.jdk7}
 jprt.my.linux.ppc=${jprt.my.linux.ppc.${jprt.tools.default.release}}
 
 jprt.my.linux.ppcv2.jdk8=linux_ppcv2_2.6
 jprt.my.linux.ppcv2.jdk7=linux_ppcv2_2.6
-jprt.my.linux.ppcv2.jdk7u6=${jprt.my.linux.ppcv2.jdk7}
+jprt.my.linux.ppcv2.jdk7u12=${jprt.my.linux.ppcv2.jdk7}
 jprt.my.linux.ppcv2=${jprt.my.linux.ppcv2.${jprt.tools.default.release}}
 
 jprt.my.linux.ppcsflt.jdk8=linux_ppcsflt_2.6
 jprt.my.linux.ppcsflt.jdk7=linux_ppcsflt_2.6
-jprt.my.linux.ppcsflt.jdk7u6=${jprt.my.linux.ppcsflt.jdk7}
+jprt.my.linux.ppcsflt.jdk7u12=${jprt.my.linux.ppcsflt.jdk7}
 jprt.my.linux.ppcsflt=${jprt.my.linux.ppcsflt.${jprt.tools.default.release}}
 
 jprt.my.linux.armvfp.jdk8=linux_armvfp_2.6
 jprt.my.linux.armvfp.jdk7=linux_armvfp_2.6
-jprt.my.linux.armvfp.jdk7u6=${jprt.my.linux.armvfp.jdk7}
+jprt.my.linux.armvfp.jdk7u12=${jprt.my.linux.armvfp.jdk7}
 jprt.my.linux.armvfp=${jprt.my.linux.armvfp.${jprt.tools.default.release}}
 
+jprt.my.linux.armvfpsflt.jdk8=linux_armvfpsflt_2.6
+jprt.my.linux.armvfpsflt.jdk7=linux_armvfpsflt_2.6
+jprt.my.linux.armvfpsflt.jdk7u12=${jprt.my.linux.armvfpsflt.jdk7}
+jprt.my.linux.armvfpsflt=${jprt.my.linux.armvfpsflt.${jprt.tools.default.release}}
+
+jprt.my.linux.armvfphflt.jdk8=linux_armvfphflt_2.6
+jprt.my.linux.armvfphflt.jdk7=linux_armvfphflt_2.6
+jprt.my.linux.armvfphflt.jdk7u12=${jprt.my.linux.armvfphflt.jdk7}
+jprt.my.linux.armvfphflt=${jprt.my.linux.armvfphflt.${jprt.tools.default.release}}
+
 jprt.my.linux.armv6.jdk8=linux_armv6_2.6
 jprt.my.linux.armv6.jdk7=linux_armv6_2.6
-jprt.my.linux.armv6.jdk7u6=${jprt.my.linux.armv6.jdk7}
+jprt.my.linux.armv6.jdk7u12=${jprt.my.linux.armv6.jdk7}
 jprt.my.linux.armv6=${jprt.my.linux.armv6.${jprt.tools.default.release}}
 
+jprt.my.linux.armvs.jdk8=linux_armvs_2.6
+jprt.my.linux.armvs.jdk7=linux_armvs_2.6
+jprt.my.linux.armvs.jdk7u12=${jprt.my.linux.armvs.jdk7}
+jprt.my.linux.armvs=${jprt.my.linux.armvs.${jprt.tools.default.release}}
+
+jprt.my.linux.armvh.jdk8=linux_armvh_2.6
+jprt.my.linux.armvh.jdk7=linux_armvh_2.6
+jprt.my.linux.armvh.jdk7u12=${jprt.my.linux.armvh.jdk7}
+jprt.my.linux.armvh=${jprt.my.linux.armvh.${jprt.tools.default.release}}
+
 jprt.my.linux.armsflt.jdk8=linux_armsflt_2.6
 jprt.my.linux.armsflt.jdk7=linux_armsflt_2.6
-jprt.my.linux.armsflt.jdk7u6=${jprt.my.linux.armsflt.jdk7}
+jprt.my.linux.armsflt.jdk7u12=${jprt.my.linux.armsflt.jdk7}
 jprt.my.linux.armsflt=${jprt.my.linux.armsflt.${jprt.tools.default.release}}
 
 jprt.my.macosx.x64.jdk8=macosx_x64_10.7
 jprt.my.macosx.x64.jdk7=macosx_x64_10.7
-jprt.my.macosx.x64.jdk7u6=${jprt.my.macosx.x64.jdk7}
+jprt.my.macosx.x64.jdk7u12=${jprt.my.macosx.x64.jdk7}
 jprt.my.macosx.x64=${jprt.my.macosx.x64.${jprt.tools.default.release}}
 
 jprt.my.windows.i586.jdk8=windows_i586_5.1
 jprt.my.windows.i586.jdk7=windows_i586_5.1
-jprt.my.windows.i586.jdk7u6=${jprt.my.windows.i586.jdk7}
+jprt.my.windows.i586.jdk7u12=${jprt.my.windows.i586.jdk7}
 jprt.my.windows.i586=${jprt.my.windows.i586.${jprt.tools.default.release}}
 
 jprt.my.windows.x64.jdk8=windows_x64_5.2
 jprt.my.windows.x64.jdk7=windows_x64_5.2
-jprt.my.windows.x64.jdk7u6=${jprt.my.windows.x64.jdk7}
+jprt.my.windows.x64.jdk7u12=${jprt.my.windows.x64.jdk7}
 jprt.my.windows.x64=${jprt.my.windows.x64.${jprt.tools.default.release}}
 
 # Standard list of jprt build targets for this source tree
@@ -139,7 +159,9 @@
     ${jprt.my.macosx.x64}-{product|fastdebug|debug}, \
     ${jprt.my.windows.i586}-{product|fastdebug|debug}, \
     ${jprt.my.windows.x64}-{product|fastdebug|debug}, \
-    ${jprt.my.linux.armv6}-{product|fastdebug}
+    ${jprt.my.linux.armv6}-{product|fastdebug}, \
+    ${jprt.my.linux.armvs}-{product|fastdebug}, \
+    ${jprt.my.linux.armvh}-{product|fastdebug}
 
 jprt.build.targets.open= \
     ${jprt.my.solaris.i586}-{productOpen}, \
@@ -152,24 +174,16 @@
     ${jprt.my.linux.ppcv2}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.ppcsflt}-{productEmb|fastdebugEmb}, \
     ${jprt.my.linux.armvfp}-{productEmb|fastdebugEmb}, \
-    ${jprt.my.linux.armsflt}-{productEmb|fastdebugEmb}
+    ${jprt.my.linux.armsflt}-{productEmb|fastdebugEmb}, \
+    ${jprt.my.linux.armvfpsflt}-{productEmb|fastdebugEmb}, \
+    ${jprt.my.linux.armvfphflt}-{productEmb|fastdebugEmb}
 
 jprt.build.targets.all=${jprt.build.targets.standard}, \
     ${jprt.build.targets.embedded}, ${jprt.build.targets.open}
 
 jprt.build.targets.jdk8=${jprt.build.targets.all}
 jprt.build.targets.jdk7=${jprt.build.targets.all}
-jprt.build.targets.jdk7u6=${jprt.build.targets.all}
-jprt.build.targets.jdk7temp=${jprt.build.targets.all}
-jprt.build.targets.jdk7b107=${jprt.build.targets.all}
-jprt.build.targets.jdk6=${jprt.build.targets.standard}
-jprt.build.targets.jdk6perf=${jprt.build.targets.standard}
-jprt.build.targets.jdk6u10=${jprt.build.targets.standard}
-jprt.build.targets.jdk6u14=${jprt.build.targets.standard}
-jprt.build.targets.jdk6u18=${jprt.build.targets.standard}
-jprt.build.targets.jdk6u20=${jprt.build.targets.standard}
-jprt.build.targets.ejdk6=${jprt.build.targets.all}
-jprt.build.targets.ejdk7=${jprt.build.targets.all}
+jprt.build.targets.jdk7u12=${jprt.build.targets.all}
 jprt.build.targets=${jprt.build.targets.${jprt.tools.default.release}}
 
 # Subset lists of test targets for this source tree
@@ -462,7 +476,7 @@
 
 jprt.test.targets.jdk8=${jprt.test.targets.standard}
 jprt.test.targets.jdk7=${jprt.test.targets.standard}
-jprt.test.targets.jdk7u6=${jprt.test.targets.jdk7}
+jprt.test.targets.jdk7u12=${jprt.test.targets.jdk7}
 jprt.test.targets=${jprt.test.targets.${jprt.tools.default.release}}
 
 # The default test/Makefile targets that should be run
@@ -496,18 +510,33 @@
   ${jprt.my.macosx.x64}-fastdebug-c2-internalvmtests, \
   ${jprt.my.windows.i586}-fastdebug-c2-internalvmtests, \
   ${jprt.my.windows.x64}-fastdebug-c2-internalvmtests
-  
+
+jprt.make.rule.test.targets.standard.wbapi = \
+  ${jprt.my.solaris.sparc}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.solaris.sparcv9}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.solaris.i586}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.solaris.x64}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.linux.i586}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.linux.x64}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.windows.i586}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.windows.x64}-{product|fastdebug}-c2-wbapitest, \
+  ${jprt.my.solaris.sparc}-{product|fastdebug}-c1-wbapitest, \
+  ${jprt.my.solaris.i586}-{product|fastdebug}-c1-wbapitest, \
+  ${jprt.my.linux.i586}-{product|fastdebug}-c1-wbapitest, \
+  ${jprt.my.windows.i586}-{product|fastdebug}-c1-wbapitest
+
 jprt.make.rule.test.targets.standard = \
   ${jprt.make.rule.test.targets.standard.client}, \
   ${jprt.make.rule.test.targets.standard.server}, \
-  ${jprt.make.rule.test.targets.standard.internalvmtests}
+  ${jprt.make.rule.test.targets.standard.internalvmtests}, \
+  ${jprt.make.rule.test.targets.standard.wbapi}
 
 jprt.make.rule.test.targets.embedded = \
   ${jprt.make.rule.test.targets.standard.client}
 
 jprt.make.rule.test.targets.jdk8=${jprt.make.rule.test.targets.standard}
 jprt.make.rule.test.targets.jdk7=${jprt.make.rule.test.targets.standard}
-jprt.make.rule.test.targets.jdk7u6=${jprt.make.rule.test.targets.jdk7}
+jprt.make.rule.test.targets.jdk7u12=${jprt.make.rule.test.targets.jdk7}
 jprt.make.rule.test.targets=${jprt.make.rule.test.targets.${jprt.tools.default.release}}
 
 # 7155453: Work-around to prevent popups on OSX from blocking test completion
diff --git a/hotspot/make/linux/Makefile b/hotspot/make/linux/Makefile
index 0ae3f4c..ad49c93 100644
--- a/hotspot/make/linux/Makefile
+++ b/hotspot/make/linux/Makefile
@@ -188,7 +188,7 @@
 # in the build.sh script:
 TARGETS           = debug jvmg fastdebug optimized profiled product
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   SUBDIR_DOCS     = $(OSNAME)_$(VARIANTARCH)_docs
 else
   SUBDIR_DOCS     = $(OSNAME)_$(BUILDARCH)_docs
diff --git a/hotspot/make/linux/makefiles/adlc.make b/hotspot/make/linux/makefiles/adlc.make
index 16d3ca9..6befe8a 100644
--- a/hotspot/make/linux/makefiles/adlc.make
+++ b/hotspot/make/linux/makefiles/adlc.make
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2012, 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
@@ -133,8 +133,10 @@
 # Note that product files are updated via "mv", which is atomic.
 TEMPDIR := $(OUTDIR)/mktmp$(shell echo $$$$)
 
-# Debuggable by default
-CFLAGS += -g
+ifneq ($(DEBUG_BINARIES), true)
+  # Debuggable by default (unless already done by DEBUG_BINARIES)
+  CFLAGS += -g
+endif
 
 # Pass -D flags into ADLC.
 ADLCFLAGS += $(SYSDEFS)
diff --git a/hotspot/make/linux/makefiles/buildtree.make b/hotspot/make/linux/makefiles/buildtree.make
index 0581fac..7615897 100644
--- a/hotspot/make/linux/makefiles/buildtree.make
+++ b/hotspot/make/linux/makefiles/buildtree.make
@@ -55,6 +55,7 @@
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
 
+-include $(SPEC)
 include $(GAMMADIR)/make/scm.make
 include $(GAMMADIR)/make/altsrc.make
 
@@ -65,7 +66,7 @@
 # For now, until the compiler is less wobbly:
 TESTFLAGS	= -Xbatch -showversion
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   PLATFORM_FILE = $(shell dirname $(shell dirname $(shell pwd)))/platform_zero
 else
   ifdef USE_SUNCC
@@ -155,6 +156,13 @@
   endif
 endif
 
+# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
+ifndef OPENJDK
+  ifneq ($(call if-has-altsrc,$(HS_COMMON_SRC)/,true,false),true)
+    OPENJDK=true
+  endif
+endif
+
 BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HS_BUILD_VER) HOTSPOT_BUILD_VERSION=  JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION)
 
 BUILDTREE	= \
@@ -197,6 +205,7 @@
 	echo "SA_BUILD_VERSION = $(HS_BUILD_VER)"; \
 	echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \
 	echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \
+	echo "OPENJDK = $(OPENJDK)"; \
 	echo; \
 	echo "# Used for platform dispatching"; \
 	echo "TARGET_DEFINES  = -DTARGET_OS_FAMILY_\$$(Platform_os_family)"; \
@@ -250,6 +259,8 @@
 	    echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \
 	    echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \
 	echo; \
+	[ -n "$(SPEC)" ] && \
+	    echo "include $(SPEC)"; \
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(VARIANT).make"; \
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(COMPILER).make"; \
 	) > $@
diff --git a/hotspot/make/linux/makefiles/defs.make b/hotspot/make/linux/makefiles/defs.make
index db5a42c..906826a 100644
--- a/hotspot/make/linux/makefiles/defs.make
+++ b/hotspot/make/linux/makefiles/defs.make
@@ -38,7 +38,7 @@
 endif
 
 # zero
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   ifeq ($(ARCH_DATA_MODEL), 64)
     MAKE_ARGS      += LP64=1
   endif
@@ -114,6 +114,18 @@
   HS_ARCH          = ppc
 endif
 
+# On 32 bit linux we build server and client, on 64 bit just server.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    JVM_VARIANTS:=client,server
+    JVM_VARIANT_CLIENT:=true
+    JVM_VARIANT_SERVER:=true
+  else
+    JVM_VARIANTS:=server
+    JVM_VARIANT_SERVER:=true
+  endif
+endif
+
 # determine if HotSpot is being built in JDK6 or earlier version
 JDK6_OR_EARLIER=0
 ifeq "$(shell expr \( '$(JDK_MAJOR_VERSION)' != '' \& '$(JDK_MINOR_VERSION)' != '' \& '$(JDK_MICRO_VERSION)' != '' \))" "1"
@@ -152,68 +164,70 @@
   # overridden in some situations, e.g., a BUILD_FLAVOR != product
   # build.
 
-  ifeq ($(BUILD_FLAVOR), product)
-    FULL_DEBUG_SYMBOLS ?= 1
-    ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
-  else
-    # debug variants always get Full Debug Symbols (if available)
-    ENABLE_FULL_DEBUG_SYMBOLS = 1
-  endif
-  _JUNK_ := $(shell \
-    echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
-  # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
-
-  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-    # Default OBJCOPY comes from GNU Binutils on Linux:
-    DEF_OBJCOPY=/usr/bin/objcopy
-    ifdef CROSS_COMPILE_ARCH
-      # don't try to generate .debuginfo files when cross compiling
-      _JUNK_ := $(shell \
-        echo >&2 "INFO: cross compiling for ARCH $(CROSS_COMPILE_ARCH)," \
-          "skipping .debuginfo generation.")
-      OBJCOPY=
+  # Due to the multiple sub-make processes that occur this logic gets
+  # executed multiple times. We reduce the noise by at least checking that
+  # BUILD_FLAVOR has been set.
+  ifneq ($(BUILD_FLAVOR),)
+    ifeq ($(BUILD_FLAVOR), product)
+      FULL_DEBUG_SYMBOLS ?= 1
+      ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
     else
+      # debug variants always get Full Debug Symbols (if available)
+      ENABLE_FULL_DEBUG_SYMBOLS = 1
+    endif
+    _JUNK_ := $(shell \
+      echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
+    # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
+
+    ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+      # Default OBJCOPY comes from GNU Binutils on Linux
+      ifeq ($(CROSS_COMPILE_ARCH),)
+        DEF_OBJCOPY=/usr/bin/objcopy
+      else
+        # Assume objcopy is part of the cross-compilation toolset
+        ifneq ($(ALT_COMPILER_PATH),)
+          DEF_OBJCOPY=$(ALT_COMPILER_PATH)/objcopy
+        endif
+      endif
       OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
       ifneq ($(ALT_OBJCOPY),)
         _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
         OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
       endif
-    endif
-  else
-    OBJCOPY=
-  endif
 
-  ifeq ($(OBJCOPY),)
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
-    ENABLE_FULL_DEBUG_SYMBOLS=0
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
-  else
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
+      ifeq ($(OBJCOPY),)
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files. You may need to set ALT_OBJCOPY.")
+        ENABLE_FULL_DEBUG_SYMBOLS=0
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
+      else
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
 
-    # Library stripping policies for .debuginfo configs:
-    #   all_strip - strips everything from the library
-    #   min_strip - strips most stuff from the library; leaves minimum symbols
-    #   no_strip  - does not strip the library at all
-    #
-    # Oracle security policy requires "all_strip". A waiver was granted on
-    # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
-    #
-    # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
-    #
-    STRIP_POLICY ?= min_strip
+        # Library stripping policies for .debuginfo configs:
+        #   all_strip - strips everything from the library
+        #   min_strip - strips most stuff from the library; leaves minimum symbols
+        #   no_strip  - does not strip the library at all
+        #
+        # Oracle security policy requires "all_strip". A waiver was granted on
+        # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
+        #
+        # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
+        #
+        STRIP_POLICY ?= min_strip
 
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
 
-    ZIP_DEBUGINFO_FILES ?= 1
+        ZIP_DEBUGINFO_FILES ?= 1
 
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
-  endif
-endif
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
+      endif
+    endif # ENABLE_FULL_DEBUG_SYMBOLS=1
+  endif # BUILD_FLAVOR
+endif # JDK_6_OR_EARLIER
 
 JDK_INCLUDE_SUBDIR=linux
 
@@ -237,9 +251,11 @@
 EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
 EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
 
-ifndef BUILD_CLIENT_ONLY
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
+EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
+
+ifeq ($(findstring true, $(JVM_VARIANT_SERVER) $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
   ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
     ifeq ($(ZIP_DEBUGINFO_FILES),1)
       EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.diz
@@ -249,18 +265,16 @@
   endif
 endif
 
-ifneq ($(ZERO_BUILD), true)
-  ifeq ($(ARCH_DATA_MODEL), 32)
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
-    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
-    ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-      ifeq ($(ZIP_DEBUGINFO_FILES),1)
-        EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.diz
-      else
-        EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
-      endif
+ifeq ($(JVM_VARIANT_CLIENT),true)
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX)
+  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+    ifeq ($(ZIP_DEBUGINFO_FILES),1)
+      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.diz
+    else
+      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
     endif
-  endif
+  endif 
 endif
 
 # Serviceability Binaries
@@ -283,6 +297,8 @@
 ADD_SA_BINARIES/arm   = 
 ADD_SA_BINARIES/zero  = 
 
+-include $(HS_ALT_MAKE)/linux/makefiles/defs.make
+
 EXPORT_LIST += $(ADD_SA_BINARIES/$(HS_ARCH))
 
 
diff --git a/hotspot/make/linux/makefiles/dtrace.make b/hotspot/make/linux/makefiles/dtrace.make
index 785561c..b50eab1 100644
--- a/hotspot/make/linux/makefiles/dtrace.make
+++ b/hotspot/make/linux/makefiles/dtrace.make
@@ -1,5 +1,6 @@
 #
-# Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012 Red Hat, Inc.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -25,3 +26,40 @@
 # Linux does not build jvm_db
 LIBJVM_DB =
 
+# Only OPENJDK builds test and support SDT probes currently.
+ifndef OPENJDK
+REASON = "This JDK does not support SDT probes"
+else
+
+# We need a recent GCC for the default
+ifeq "$(shell expr \( $(CC_VER_MAJOR) \>= 4 \) \& \( $(CC_VER_MINOR) \>= 4 \) )" "0"
+REASON = "gcc version is too old"
+else
+
+# But it does have a SystemTap dtrace compatible sys/sdt.h
+ifneq ($(ALT_SDT_H),)
+  SDT_H_FILE = $(ALT_SDT_H)
+else
+  SDT_H_FILE = /usr/include/sys/sdt.h
+endif
+DTRACE_ENABLED = $(shell test -f $(SDT_H_FILE) && echo $(SDT_H_FILE))
+REASON = "$(SDT_H_FILE) not found"
+
+ifneq ($(DTRACE_ENABLED),)
+  CFLAGS += -DDTRACE_ENABLED
+endif
+
+endif
+endif
+
+# Phony target used in vm.make build target to check whether enabled.
+.PHONY: dtraceCheck
+ifeq ($(DTRACE_ENABLED),)
+dtraceCheck:
+	$(QUIETLY) echo "**NOTICE** Dtrace support disabled: $(REASON)"
+else
+dtraceCheck:
+endif
+
+# It doesn't support HAVE_DTRACE_H though.
+
diff --git a/hotspot/make/linux/makefiles/gcc.make b/hotspot/make/linux/makefiles/gcc.make
index 7ad7e43..9231daf 100644
--- a/hotspot/make/linux/makefiles/gcc.make
+++ b/hotspot/make/linux/makefiles/gcc.make
@@ -25,21 +25,26 @@
 #------------------------------------------------------------------------
 # CC, CXX & AS
 
-# When cross-compiling the ALT_COMPILER_PATH points
-# to the cross-compilation toolset
-ifdef CROSS_COMPILE_ARCH
-CXX = $(ALT_COMPILER_PATH)/g++
-CC  = $(ALT_COMPILER_PATH)/gcc
-HOSTCXX = g++
-HOSTCC  = gcc
-else
-CXX = g++
-CC  = gcc
-HOSTCXX = $(CXX)
-HOSTCC  = $(CC)
+# If a SPEC is not set already, then use these defaults.
+ifeq ($(SPEC),)
+  # When cross-compiling the ALT_COMPILER_PATH points
+  # to the cross-compilation toolset
+  ifdef CROSS_COMPILE_ARCH
+    CXX = $(ALT_COMPILER_PATH)/g++
+    CC  = $(ALT_COMPILER_PATH)/gcc
+    HOSTCXX = g++
+    HOSTCC  = gcc
+    STRIP = $(ALT_COMPILER_PATH)/strip
+  else
+    CXX = g++
+    CC  = gcc
+    HOSTCXX = $(CXX)
+    HOSTCC  = $(CC)
+    STRIP = strip
+  endif
+  AS  = $(CC) -c
 endif
 
-AS  = $(CC) -c
 
 # -dumpversion in gcc-2.91 shows "egcs-2.91.66". In later version, it only
 # prints the numbers (e.g. "2.95", "3.2.1")
@@ -67,10 +72,11 @@
 VM_PICFLAG/AOUT   =
 VM_PICFLAG        = $(VM_PICFLAG/$(LINK_INTO))
 
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(JVM_VARIANT_ZERO), true)
 CFLAGS += $(LIBFFI_CFLAGS)
 endif
-ifeq ($(SHARK_BUILD), true)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+CFLAGS += $(LIBFFI_CFLAGS)
 CFLAGS += $(LLVM_CFLAGS)
 endif
 CFLAGS += $(VM_PICFLAG)
@@ -160,7 +166,7 @@
 
 # Flags for generating make dependency flags.
 ifneq ("${CC_VER_MAJOR}", "2")
-DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
+DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
 endif
 
 # -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
@@ -209,45 +215,44 @@
 #------------------------------------------------------------------------
 # Debug flags
 
-# Use the stabs format for debugging information (this is the default
-# on gcc-2.91). It's good enough, has all the information about line
-# numbers and local variables, and libjvm_g.so is only about 16M.
-# Change this back to "-g" if you want the most expressive format.
-# (warning: that could easily inflate libjvm_g.so to 150M!)
-# Note: The Itanium gcc compiler crashes when using -gstabs.
-DEBUG_CFLAGS/ia64  = -g
-DEBUG_CFLAGS/amd64 = -g
-DEBUG_CFLAGS/arm   = -g
-DEBUG_CFLAGS/ppc   = -g
-DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
-ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
-DEBUG_CFLAGS += -gstabs
-endif
-
-ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-  FASTDEBUG_CFLAGS/ia64  = -g
-  FASTDEBUG_CFLAGS/amd64 = -g
-  FASTDEBUG_CFLAGS/arm   = -g
-  FASTDEBUG_CFLAGS/ppc   = -g
-  FASTDEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
-  ifeq ($(FASTDEBUG_CFLAGS/$(BUILDARCH)),)
-    FASTDEBUG_CFLAGS += -gstabs
-  endif
-
-  OPT_CFLAGS/ia64  = -g
-  OPT_CFLAGS/amd64 = -g
-  OPT_CFLAGS/arm   = -g
-  OPT_CFLAGS/ppc   = -g
-  OPT_CFLAGS += $(OPT_CFLAGS/$(BUILDARCH))
-  ifeq ($(OPT_CFLAGS/$(BUILDARCH)),)
-    OPT_CFLAGS += -gstabs
-  endif
-endif
-
-# DEBUG_BINARIES overrides everything, use full -g debug information
+# DEBUG_BINARIES uses full -g debug information for all configs
 ifeq ($(DEBUG_BINARIES), true)
-  DEBUG_CFLAGS = -g
-  CFLAGS += $(DEBUG_CFLAGS)
+  CFLAGS += -g
+else
+  # Use the stabs format for debugging information (this is the default
+  # on gcc-2.91). It's good enough, has all the information about line
+  # numbers and local variables, and libjvm_g.so is only about 16M.
+  # Change this back to "-g" if you want the most expressive format.
+  # (warning: that could easily inflate libjvm_g.so to 150M!)
+  # Note: The Itanium gcc compiler crashes when using -gstabs.
+  DEBUG_CFLAGS/ia64  = -g
+  DEBUG_CFLAGS/amd64 = -g
+  DEBUG_CFLAGS/arm   = -g
+  DEBUG_CFLAGS/ppc   = -g
+  DEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
+  ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),)
+    DEBUG_CFLAGS += -gstabs
+  endif
+  
+  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+    FASTDEBUG_CFLAGS/ia64  = -g
+    FASTDEBUG_CFLAGS/amd64 = -g
+    FASTDEBUG_CFLAGS/arm   = -g
+    FASTDEBUG_CFLAGS/ppc   = -g
+    FASTDEBUG_CFLAGS += $(DEBUG_CFLAGS/$(BUILDARCH))
+    ifeq ($(FASTDEBUG_CFLAGS/$(BUILDARCH)),)
+      FASTDEBUG_CFLAGS += -gstabs
+    endif
+  
+    OPT_CFLAGS/ia64  = -g
+    OPT_CFLAGS/amd64 = -g
+    OPT_CFLAGS/arm   = -g
+    OPT_CFLAGS/ppc   = -g
+    OPT_CFLAGS += $(OPT_CFLAGS/$(BUILDARCH))
+    ifeq ($(OPT_CFLAGS/$(BUILDARCH)),)
+      OPT_CFLAGS += -gstabs
+    endif
+  endif
 endif
 
 # If we are building HEADLESS, pass on to VM
@@ -261,9 +266,3 @@
 ifdef MINIMIZE_RAM_USAGE
 CFLAGS += -DMINIMIZE_RAM_USAGE
 endif
-
-ifdef CROSS_COMPILE_ARCH
-  STRIP = $(ALT_COMPILER_PATH)/strip
-else
-  STRIP = strip
-endif
diff --git a/hotspot/make/linux/makefiles/jvmg.make b/hotspot/make/linux/makefiles/jvmg.make
index db10608..3c0ae3a 100644
--- a/hotspot/make/linux/makefiles/jvmg.make
+++ b/hotspot/make/linux/makefiles/jvmg.make
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,9 @@
 # Compiler specific DEBUG_CFLAGS are passed in from gcc.make, sparcWorks.make
 DEBUG_CFLAGS/DEFAULT= $(DEBUG_CFLAGS)
 DEBUG_CFLAGS/BYFILE = $(DEBUG_CFLAGS/$@)$(DEBUG_CFLAGS/DEFAULT$(DEBUG_CFLAGS/$@))
-CFLAGS += $(DEBUG_CFLAGS/BYFILE)
+
+# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
+CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
 
 # Set the environment variable HOTSPARC_GENERIC to "true"
 # to inhibit the effect of the previous line on CFLAGS.
diff --git a/hotspot/make/linux/makefiles/sa.make b/hotspot/make/linux/makefiles/sa.make
index ede5761..f39e736 100644
--- a/hotspot/make/linux/makefiles/sa.make
+++ b/hotspot/make/linux/makefiles/sa.make
@@ -30,10 +30,16 @@
 
 include $(GAMMADIR)/make/linux/makefiles/rules.make
 
+include $(GAMMADIR)/make/defs.make
+include $(GAMMADIR)/make/altsrc.make
+
 AGENT_DIR = $(GAMMADIR)/agent
 
 include $(GAMMADIR)/make/sa.files
 
+-include $(HS_ALT_MAKE)/linux/makefiles/sa.make
+
+
 TOPDIR    = $(shell echo `pwd`)
 GENERATED = $(TOPDIR)/../generated
 
@@ -52,17 +58,15 @@
 SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties
 
 # if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium, PowerPC, ARM or zero.
+# also, we don't build SA on Itanium or zero.
 
 all: 
 	if [ -d $(AGENT_DIR) -a "$(SRCARCH)" != "ia64" \
-             -a "$(SRCARCH)" != "arm" \
-             -a "$(SRCARCH)" != "ppc" \
              -a "$(SRCARCH)" != "zero" ] ; then \
 	   $(MAKE) -f sa.make $(GENERATED)/sa-jdi.jar; \
 	fi
 
-$(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
+$(GENERATED)/sa-jdi.jar:: $(AGENT_FILES)
 	$(QUIETLY) echo "Making $@"
 	$(QUIETLY) if [ "$(BOOT_JAVA_HOME)" = "" ]; then \
 	  echo "ALT_BOOTDIR, BOOTDIR or JAVA_HOME needs to be defined to build SA"; \
@@ -111,3 +115,5 @@
 	rm -rf $(SA_CLASSDIR)
 	rm -rf $(GENERATED)/sa-jdi.jar
 	rm -rf $(AGENT_FILES_LIST)
+
+-include $(HS_ALT_MAKE)/linux/makefiles/sa-rules.make
diff --git a/hotspot/make/linux/makefiles/saproc.make b/hotspot/make/linux/makefiles/saproc.make
index 09beebd..af0767a 100644
--- a/hotspot/make/linux/makefiles/saproc.make
+++ b/hotspot/make/linux/makefiles/saproc.make
@@ -21,6 +21,8 @@
 # questions.
 #  
 #
+include $(GAMMADIR)/make/defs.make
+include $(GAMMADIR)/make/altsrc.make
 
 # Rules to build serviceability agent library, used by vm.make
 
@@ -48,6 +50,8 @@
              $(SASRCDIR)/ps_core.c                    \
              $(SASRCDIR)/LinuxDebuggerLocal.c
 
+-include $(HS_ALT_MAKE)/linux/makefiles/saproc.make
+
 SAMAPFILE = $(SASRCDIR)/mapfile
 
 DEST_SAPROC           = $(JDK_LIBDIR)/$(LIBSAPROC)
@@ -60,15 +64,19 @@
 endif
 
 # if $(AGENT_DIR) does not exist, we don't build SA
-# also, we don't build SA on Itanium, PPC, ARM or zero.
+# also, we don't build SA on Itanium or zero.
 
 ifneq ($(wildcard $(AGENT_DIR)),)
-ifneq ($(filter-out ia64 arm ppc zero,$(SRCARCH)),)
+ifneq ($(filter-out ia64 zero,$(SRCARCH)),)
   BUILDLIBSAPROC = $(LIBSAPROC)
 endif
 endif
 
-
+ifneq ($(ALT_SASRCDIR),)
+ALT_SAINCDIR=-I$(ALT_SASRCDIR)
+else
+ALT_SAINCDIR=
+endif
 SA_LFLAGS = $(MAPFLAG:FILENAME=$(SAMAPFILE)) $(LDFLAGS_HASH_STYLE)
 
 $(LIBSAPROC): $(SASRCFILES) $(SAMAPFILE)
@@ -84,6 +92,7 @@
 	           -I$(GENERATED)                                       \
 	           -I$(BOOT_JAVA_HOME)/include                          \
 	           -I$(BOOT_JAVA_HOME)/include/$(Platform_os_family)    \
+			   $(ALT_SAINCDIR) 										\
 	           $(SASRCFILES)                                        \
 	           $(SA_LFLAGS)                                         \
 	           $(SA_DEBUG_CFLAGS)                                   \
diff --git a/hotspot/make/linux/makefiles/sparcWorks.make b/hotspot/make/linux/makefiles/sparcWorks.make
index 81de9c3..c87f504 100644
--- a/hotspot/make/linux/makefiles/sparcWorks.make
+++ b/hotspot/make/linux/makefiles/sparcWorks.make
@@ -25,12 +25,15 @@
 #------------------------------------------------------------------------
 # CC, CXX & AS
 
-CXX = CC
-CC  = cc
-AS  = $(CC) -c
+# If a SPEC is not set already, then use these defaults.
+ifeq ($(SPEC),)
+  CXX = CC
+  CC  = cc
+  AS  = $(CC) -c
 
-HOSTCXX = $(CXX)
-HOSTCC  = $(CC)
+  HOSTCXX = $(CXX)
+  HOSTCC  = $(CC)
+endif
 
 ARCHFLAG = $(ARCHFLAG/$(BUILDARCH))
 ARCHFLAG/i486    = -m32
diff --git a/hotspot/make/linux/makefiles/vm.make b/hotspot/make/linux/makefiles/vm.make
index 3beebde..5d39cbd 100644
--- a/hotspot/make/linux/makefiles/vm.make
+++ b/hotspot/make/linux/makefiles/vm.make
@@ -42,7 +42,7 @@
 -include $(DEP_DIR)/*.d
 
 # read machine-specific adjustments (%%% should do this via buildtree.make?)
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(findstring true, $(JVM_VARIANT_ZERO) $(JVM_VARIANT_ZEROSHARK)), true)
   include $(MAKEFILES_DIR)/zeroshark.make
 else
   include $(MAKEFILES_DIR)/$(BUILDARCH).make
@@ -242,7 +242,7 @@
 vm.def: $(Res_Files) $(Obj_Files)
 	sh $(GAMMADIR)/make/linux/makefiles/build_vm_def.sh *.o > $@
 
-ifeq ($(SHARK_BUILD), true)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
   STATIC_CXX = false
 else
   ifeq ($(ZERO_LIBARCH), ppc64)
@@ -274,12 +274,12 @@
 
   LIBS_VM                  += $(LIBS)
 endif
-ifeq ($(ZERO_BUILD), true)
+ifeq ($(JVM_VARIANT_ZERO), true)
   LIBS_VM += $(LIBFFI_LIBS)
 endif
-ifeq ($(SHARK_BUILD), true)
+ifeq ($(JVM_VARIANT_ZEROSHARK), true)
+  LIBS_VM   += $(LIBFFI_LIBS) $(LLVM_LIBS)
   LFLAGS_VM += $(LLVM_LDFLAGS)
-  LIBS_VM   += $(LLVM_LIBS)
 endif
 
 LINK_VM = $(LINK_LIB.CC)
@@ -336,24 +336,23 @@
 	      fi                                                        \
             fi 								\
 	}
-ifeq ($(CROSS_COMPILE_ARCH),)
-  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+
+ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
 	$(QUIETLY) $(OBJCOPY) --only-keep-debug $@ $(LIBJVM_DEBUGINFO)
 	$(QUIETLY) $(OBJCOPY) --add-gnu-debuglink=$(LIBJVM_DEBUGINFO) $@
-    ifeq ($(STRIP_POLICY),all_strip)
+  ifeq ($(STRIP_POLICY),all_strip)
 	$(QUIETLY) $(STRIP) $@
-    else
-      ifeq ($(STRIP_POLICY),min_strip)
+  else
+    ifeq ($(STRIP_POLICY),min_strip)
 	$(QUIETLY) $(STRIP) -g $@
-      # implied else here is no stripping at all
-      endif
+    # implied else here is no stripping at all
     endif
+  endif
 	$(QUIETLY) [ -f $(LIBJVM_G_DEBUGINFO) ] || ln -s $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
-    ifeq ($(ZIP_DEBUGINFO_FILES),1)
+  ifeq ($(ZIP_DEBUGINFO_FILES),1)
 	$(ZIPEXE) -q -y $(LIBJVM_DIZ) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
 	$(RM) $(LIBJVM_DEBUGINFO) $(LIBJVM_G_DEBUGINFO)
 	[ -f $(LIBJVM_G_DIZ) ] || { ln -s $(LIBJVM_DIZ) $(LIBJVM_G_DIZ); }
-    endif
   endif
 endif
 
@@ -382,9 +381,12 @@
 # Serviceability agent
 include $(MAKEFILES_DIR)/saproc.make
 
+# Whitebox testing API
+include $(MAKEFILES_DIR)/wb.make
+
 #----------------------------------------------------------------------
 
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC)
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
 
 install: install_jvm install_jsig install_saproc
 
diff --git a/hotspot/make/linux/makefiles/wb.make b/hotspot/make/linux/makefiles/wb.make
new file mode 100644
index 0000000..8298d87
--- /dev/null
+++ b/hotspot/make/linux/makefiles/wb.make
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2012, 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.
+#  
+#
+
+# Rules to build whitebox testing library, used by vm.make
+WB = wb
+
+WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
+
+WB_JAR = $(GENERATED)/$(WB).jar
+
+WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
+WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
+
+WB_JAVA_CLASSES  = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
+	$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
+
+$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
+	$(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
+
+$(WB_JAR): $(WB_JAVA_CLASSES)
+	$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
+
+$(WB_JAVA_CLASSDIR):
+	$(QUIETLY) mkdir -p $@
+
diff --git a/hotspot/make/pic.make b/hotspot/make/pic.make
index 79b2ea2..0e61ad9 100644
--- a/hotspot/make/pic.make
+++ b/hotspot/make/pic.make
@@ -32,7 +32,7 @@
   ifndef LP64
     PARTIAL_NONPIC=1
   endif
-  PIC_ARCH = ppc
+  PIC_ARCH = ppc arm
   ifneq ("$(filter $(PIC_ARCH),$(BUILDARCH))","")
     PARTIAL_NONPIC=0
   endif
diff --git a/hotspot/make/solaris/makefiles/buildtree.make b/hotspot/make/solaris/makefiles/buildtree.make
index 808de3b..3bca3dc 100644
--- a/hotspot/make/solaris/makefiles/buildtree.make
+++ b/hotspot/make/solaris/makefiles/buildtree.make
@@ -55,6 +55,7 @@
 # The makefiles are split this way so that "make foo" will run faster by not
 # having to read the dependency files for the vm.
 
+-include $(SPEC)
 include $(GAMMADIR)/make/scm.make
 include $(GAMMADIR)/make/altsrc.make
 
@@ -147,6 +148,13 @@
   endif
 endif
 
+# if hotspot-only build and/or OPENJDK isn't passed down, need to set OPENJDK
+ifndef OPENJDK
+  ifneq ($(call if-has-altsrc,$(HS_COMMON_SRC)/,true,false),true)
+    OPENJDK=true
+  endif
+endif
+
 BUILDTREE_VARS += HOTSPOT_RELEASE_VERSION=$(HS_BUILD_VER) HOTSPOT_BUILD_VERSION= JRE_RELEASE_VERSION=$(JRE_RELEASE_VERSION) 
 
 BUILDTREE	= \
@@ -189,6 +197,7 @@
 	echo "SA_BUILD_VERSION = $(HS_BUILD_VER)"; \
 	echo "HOTSPOT_BUILD_USER = $(HOTSPOT_BUILD_USER)"; \
 	echo "HOTSPOT_VM_DISTRO = $(HOTSPOT_VM_DISTRO)"; \
+	echo "OPENJDK = $(OPENJDK)"; \
 	echo "$(LP64_SETTING/$(DATA_MODE))"; \
 	echo; \
 	echo "# Used for platform dispatching"; \
@@ -243,6 +252,8 @@
 	    echo "HOTSPOT_EXTRA_SYSDEFS\$$(HOTSPOT_EXTRA_SYSDEFS) = $(HOTSPOT_EXTRA_SYSDEFS)" && \
 	    echo "SYSDEFS += \$$(HOTSPOT_EXTRA_SYSDEFS)"; \
 	echo; \
+	[ -n "$(SPEC)" ] && \
+	    echo "include $(SPEC)"; \
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(VARIANT).make"; \
 	echo "include \$$(GAMMADIR)/make/$(OS_FAMILY)/makefiles/$(COMPILER).make"; \
 	) > $@
diff --git a/hotspot/make/solaris/makefiles/defs.make b/hotspot/make/solaris/makefiles/defs.make
index 7c79113..896798f 100644
--- a/hotspot/make/solaris/makefiles/defs.make
+++ b/hotspot/make/solaris/makefiles/defs.make
@@ -59,6 +59,18 @@
   endif
 endif
 
+# On 32 bit solaris we build server and client, on 64 bit just server.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    JVM_VARIANTS:=client,server
+    JVM_VARIANT_CLIENT:=true
+    JVM_VARIANT_SERVER:=true
+  else
+    JVM_VARIANTS:=server
+    JVM_VARIANT_SERVER:=true
+  endif
+endif
+
 # determine if HotSpot is being built in JDK6 or earlier version
 JDK6_OR_EARLIER=0
 ifeq "$(shell expr \( '$(JDK_MAJOR_VERSION)' != '' \& '$(JDK_MINOR_VERSION)' != '' \& '$(JDK_MICRO_VERSION)' != '' \))" "1"
@@ -97,60 +109,63 @@
   # overridden in some situations, e.g., a BUILD_FLAVOR != product
   # build.
 
-  ifeq ($(BUILD_FLAVOR), product)
-    FULL_DEBUG_SYMBOLS ?= 1
-    ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
-  else
-    # debug variants always get Full Debug Symbols (if available)
-    ENABLE_FULL_DEBUG_SYMBOLS = 1
-  endif
-  _JUNK_ := $(shell \
-    echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
-  # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
-
-  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-    # Default OBJCOPY comes from the SUNWbinutils package:
-    DEF_OBJCOPY=/usr/sfw/bin/gobjcopy
-    OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
-    ifneq ($(ALT_OBJCOPY),)
-      _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
-      OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
+  # Due to the multiple sub-make processes that occur this logic gets
+  # executed multiple times. We reduce the noise by at least checking that
+  # BUILD_FLAVOR has been set.
+  ifneq ($(BUILD_FLAVOR),)
+    ifeq ($(BUILD_FLAVOR), product)
+      FULL_DEBUG_SYMBOLS ?= 1
+      ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
+    else
+      # debug variants always get Full Debug Symbols (if available)
+      ENABLE_FULL_DEBUG_SYMBOLS = 1
     endif
-  else
-    OBJCOPY=
-  endif
-
-  ifeq ($(OBJCOPY),)
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
-    ENABLE_FULL_DEBUG_SYMBOLS=0
     _JUNK_ := $(shell \
       echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
-  else
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
+    # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
 
-    # Library stripping policies for .debuginfo configs:
-    #   all_strip - strips everything from the library
-    #   min_strip - strips most stuff from the library; leaves minimum symbols
-    #   no_strip  - does not strip the library at all
-    #
-    # Oracle security policy requires "all_strip". A waiver was granted on
-    # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
-    #
-    # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
-    #
-    STRIP_POLICY ?= min_strip
+    ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+      # Default OBJCOPY comes from the SUNWbinutils package:
+      DEF_OBJCOPY=/usr/sfw/bin/gobjcopy
+      OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
+      ifneq ($(ALT_OBJCOPY),)
+        _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
+        OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
+      endif
 
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
+      ifeq ($(OBJCOPY),)
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
+        ENABLE_FULL_DEBUG_SYMBOLS=0
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
+      else
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: $(OBJCOPY) cmd found so will create .debuginfo files.")
 
-    ZIP_DEBUGINFO_FILES ?= 1
+        # Library stripping policies for .debuginfo configs:
+        #   all_strip - strips everything from the library
+        #   min_strip - strips most stuff from the library; leaves minimum symbols
+        #   no_strip  - does not strip the library at all
+        #
+        # Oracle security policy requires "all_strip". A waiver was granted on
+        # 2011.09.01 that permits using "min_strip" in the Java JDK and Java JRE.
+        #
+        # Currently, STRIP_POLICY is only used when Full Debug Symbols is enabled.
+        #
+        STRIP_POLICY ?= min_strip
 
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
-  endif
-endif
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: STRIP_POLICY=$(STRIP_POLICY)")
+
+        ZIP_DEBUGINFO_FILES ?= 1
+
+        _JUNK_ := $(shell \
+          echo >&2 "INFO: ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)")
+      endif
+    endif # ENABLE_FULL_DEBUG_SYMBOLS=1
+  endif # BUILD_FLAVOR
+endif # JDK_6_OR_EARLIER
 
 JDK_INCLUDE_SUBDIR=solaris
 
@@ -172,58 +187,65 @@
   endif
 endif
 
+EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
+
 EXPORT_SERVER_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/server
 EXPORT_CLIENT_DIR = $(EXPORT_JRE_LIB_ARCH_DIR)/client
 
-ifneq ($(BUILD_CLIENT_ONLY),true)
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
+ifeq ($(JVM_VARIANT_SERVER),true)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.$(LIBRARY_SUFFIX)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.$(LIBRARY_SUFFIX)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
+  ifeq ($(ARCH_DATA_MODEL),32)
+    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
+    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
+  endif
   ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
     ifeq ($(ZIP_DEBUGINFO_FILES),1)
       EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.diz
       EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.diz
       EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.diz
+      ifeq ($(ARCH_DATA_MODEL),32)
+        EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.diz
+        EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.diz
+      endif
     else
       EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm.debuginfo
       EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_db.debuginfo
       EXPORT_LIST += $(EXPORT_SERVER_DIR)/libjvm_dtrace.debuginfo
+      ifeq ($(ARCH_DATA_MODEL),32)
+        EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.debuginfo
+        EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.debuginfo
+      endif
     endif
   endif
 endif
-ifeq ($(ARCH_DATA_MODEL), 32)
+ifeq ($(JVM_VARIANT_CLIENT),true)
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.$(LIBRARY_SUFFIX) 
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.$(LIBRARY_SUFFIX) 
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.$(LIBRARY_SUFFIX)
-  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
-  EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
+  ifeq ($(ARCH_DATA_MODEL),32)
+    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
+    EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
+  endif
   ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
     ifeq ($(ZIP_DEBUGINFO_FILES),1)
       EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.diz
       EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.diz
       EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.diz
-      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.diz
-      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.diz
+      ifeq ($(ARCH_DATA_MODEL),32)
+        EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.diz
+        EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.diz
+      endif
     else
       EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm.debuginfo
       EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_db.debuginfo
       EXPORT_LIST += $(EXPORT_CLIENT_DIR)/libjvm_dtrace.debuginfo
-      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.debuginfo
-      EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo
-    endif
-  endif
-  ifneq ($(BUILD_CLIENT_ONLY), true)
-    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.$(LIBRARY_SUFFIX)
-    EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.$(LIBRARY_SUFFIX)
-    ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-      ifeq ($(ZIP_DEBUGINFO_FILES),1)
-        EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.diz
-        EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.diz
-      else
-        EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_db.debuginfo
-        EXPORT_LIST += $(EXPORT_SERVER_DIR)/64/libjvm_dtrace.debuginfo
+      ifeq ($(ARCH_DATA_MODEL),32)
+        EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_db.debuginfo
+        EXPORT_LIST += $(EXPORT_CLIENT_DIR)/64/libjvm_dtrace.debuginfo
       endif
     endif
   endif
diff --git a/hotspot/make/solaris/makefiles/dtrace.make b/hotspot/make/solaris/makefiles/dtrace.make
index 48bc98d..1473a0f 100644
--- a/hotspot/make/solaris/makefiles/dtrace.make
+++ b/hotspot/make/solaris/makefiles/dtrace.make
@@ -206,15 +206,15 @@
 
 # $@.tmp is created first to avoid an empty $(JVMOFFS).h if an error occurs.
 $(JVMOFFS).h: $(GENOFFS)
-	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -header > $@.tmp
+	$(QUIETLY) LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ./$(GENOFFS) -header > $@.tmp
 	$(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
 
 $(JVMOFFS)Index.h: $(GENOFFS)
-	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -index > $@.tmp
+	$(QUIETLY) LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ./$(GENOFFS) -index > $@.tmp
 	$(QUIETLY)  $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
 
 $(JVMOFFS).cpp: $(GENOFFS) $(JVMOFFS).h $(JVMOFFS)Index.h
-	$(QUIETLY) LD_LIBRARY_PATH=. ./$(GENOFFS) -table > $@.tmp
+	$(QUIETLY) LD_LIBRARY_PATH=.:$(LD_LIBRARY_PATH) ./$(GENOFFS) -table > $@.tmp
 	$(QUIETLY) $(CONDITIONALLY_UPDATE_JVMOFFS_TARGET)
 
 $(JVMOFFS.o): $(JVMOFFS).h $(JVMOFFS).cpp 
diff --git a/hotspot/make/solaris/makefiles/fastdebug.make b/hotspot/make/solaris/makefiles/fastdebug.make
index 2841055..08834f0 100644
--- a/hotspot/make/solaris/makefiles/fastdebug.make
+++ b/hotspot/make/solaris/makefiles/fastdebug.make
@@ -36,6 +36,11 @@
 ifeq ("${Platform_compiler}", "sparcWorks")
 OPT_CFLAGS/SLOWER = -xO2
 
+ifeq ($(COMPILER_REV_NUMERIC), 510)
+# CC 5.10 has bug XXXXX with -xO4
+OPT_CFLAGS/jvmtiClassFileReconstituter.o = $(OPT_CFLAGS/SLOWER)
+endif # COMPILER_REV_NUMERIC == 510
+
 ifeq ($(COMPILER_REV_NUMERIC), 509)
 # To avoid jvm98 crash
 OPT_CFLAGS/instanceKlass.o = $(OPT_CFLAGS/SLOWER)
diff --git a/hotspot/make/solaris/makefiles/gcc.make b/hotspot/make/solaris/makefiles/gcc.make
index d4c54ab..be26f6d 100644
--- a/hotspot/make/solaris/makefiles/gcc.make
+++ b/hotspot/make/solaris/makefiles/gcc.make
@@ -25,9 +25,13 @@
 #------------------------------------------------------------------------
 # CC, CXX & AS
 
-CXX = g++
-CC  = gcc
-AS  = $(CC) -c
+# If a SPEC is not set already, then use these defaults.
+ifeq ($(SPEC),)
+  CXX = g++
+  CC  = gcc
+  AS  = $(CC) -c
+  MCS = /usr/ccs/bin/mcs
+endif
 
 Compiler = gcc
 
@@ -137,7 +141,7 @@
 
 # Flags for generating make dependency flags.
 ifneq ("${CC_VER_MAJOR}", "2")
-DEPFLAGS = -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
+DEPFLAGS = -fpch-deps -MMD -MP -MF $(DEP_DIR)/$(@:%=%.d)
 endif
 
 # -DDONT_USE_PRECOMPILED_HEADER will exclude all includes in precompiled.hpp.
@@ -193,5 +197,3 @@
 ifeq ($(DEBUG_CFLAGS/$(BUILDARCH)),) 
 DEBUG_CFLAGS += -gstabs 
 endif 
-
-MCS = /usr/ccs/bin/mcs
diff --git a/hotspot/make/solaris/makefiles/jvmg.make b/hotspot/make/solaris/makefiles/jvmg.make
index 8e1db86..821c0a1 100644
--- a/hotspot/make/solaris/makefiles/jvmg.make
+++ b/hotspot/make/solaris/makefiles/jvmg.make
@@ -37,7 +37,8 @@
 endif
 endif
 
-CFLAGS += $(DEBUG_CFLAGS/BYFILE)
+# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
+CFLAGS += $(DEBUG_CFLAGS/BYFILE) -D_NMT_NOINLINE_
 
 # Set the environment variable HOTSPARC_GENERIC to "true"
 # to inhibit the effect of the previous line on CFLAGS.
diff --git a/hotspot/make/solaris/makefiles/optimized.make b/hotspot/make/solaris/makefiles/optimized.make
index 6919578..83fd01c 100644
--- a/hotspot/make/solaris/makefiles/optimized.make
+++ b/hotspot/make/solaris/makefiles/optimized.make
@@ -32,6 +32,11 @@
 # (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
 ifeq ("${Platform_compiler}", "sparcWorks")
 
+ifeq ($(COMPILER_REV_NUMERIC), 510)
+# CC 5.10 has bug XXXXX with -xO4
+OPT_CFLAGS/jvmtiClassFileReconstituter.o = $(OPT_CFLAGS/O2)
+endif # COMPILER_REV_NUMERIC == 510
+
 ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
 # dtrace cannot handle tail call optimization (6672627, 6693876)
 OPT_CFLAGS/jni.o = $(OPT_CFLAGS/DEFAULT) $(OPT_CCFLAGS/NO_TAIL_CALL_OPT)
diff --git a/hotspot/make/solaris/makefiles/product.make b/hotspot/make/solaris/makefiles/product.make
index 8746d51..2aeae30 100644
--- a/hotspot/make/solaris/makefiles/product.make
+++ b/hotspot/make/solaris/makefiles/product.make
@@ -40,6 +40,11 @@
 # (OPT_CFLAGS/SLOWER is also available, to alter compilation of buggy files)
 ifeq ("${Platform_compiler}", "sparcWorks")
 
+ifeq ($(COMPILER_REV_NUMERIC), 510)
+# CC 5.10 has bug XXXXX with -xO4
+OPT_CFLAGS/jvmtiClassFileReconstituter.o = $(OPT_CFLAGS/O2)
+endif # COMPILER_REV_NUMERIC == 510
+
 ifeq ($(shell expr $(COMPILER_REV_NUMERIC) \>= 509), 1)
 # dtrace cannot handle tail call optimization (6672627, 6693876)
 OPT_CFLAGS/jni.o = $(OPT_CFLAGS/DEFAULT) $(OPT_CCFLAGS/NO_TAIL_CALL_OPT)
diff --git a/hotspot/make/solaris/makefiles/sparcWorks.make b/hotspot/make/solaris/makefiles/sparcWorks.make
index 6fb4f54..bcf0295 100644
--- a/hotspot/make/solaris/makefiles/sparcWorks.make
+++ b/hotspot/make/solaris/makefiles/sparcWorks.make
@@ -22,18 +22,22 @@
 #  
 #
 
-# Compiler-specific flags for sparcworks.
+# If a SPEC is not set already, then use these defaults.
+ifeq ($(SPEC),)
+  # Compiler-specific flags for sparcworks.
+  CC	= cc
+  CXX	= CC
 
-# tell make which C and C++ compilers to use
-CC	= cc
-CXX	= CC
+  # Note that this 'as' is an older version of the Sun Studio 'fbe', and will
+  #   use the older style options. The 'fbe' options will match 'cc' and 'CC'.
+  AS	= /usr/ccs/bin/as
 
-# Note that this 'as' is an older version of the Sun Studio 'fbe', and will
-#   use the older style options. The 'fbe' options will match 'cc' and 'CC'.
-AS	= /usr/ccs/bin/as
+  NM    = /usr/ccs/bin/nm
+  NAWK  = /bin/nawk
 
-NM	= /usr/ccs/bin/nm
-NAWK    = /bin/nawk
+  MCS	= /usr/ccs/bin/mcs
+  STRIP	= /usr/ccs/bin/strip
+endif
 
 REORDER_FLAG = -xF
 
@@ -557,9 +561,6 @@
 #LINK_INTO = LIBJVM
 endif
 
-MCS	= /usr/ccs/bin/mcs
-STRIP	= /usr/ccs/bin/strip
-
 # Solaris platforms collect lots of redundant file-ident lines,
 # to the point of wasting a significant percentage of file space.
 # (The text is stored in ELF .comment sections, contributed by
diff --git a/hotspot/make/solaris/makefiles/vm.make b/hotspot/make/solaris/makefiles/vm.make
index 4fc8d32..833bfb9 100644
--- a/hotspot/make/solaris/makefiles/vm.make
+++ b/hotspot/make/solaris/makefiles/vm.make
@@ -348,9 +348,12 @@
 # Serviceability agent
 include $(MAKEFILES_DIR)/saproc.make
 
+# Whitebox testing API
+include $(MAKEFILES_DIR)/wb.make
+
 #----------------------------------------------------------------------
 
-build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck
+build: $(LIBJVM) $(LAUNCHER) $(LIBJSIG) $(LIBJVM_DB) $(LIBJVM_DTRACE) $(BUILDLIBSAPROC) dtraceCheck $(WB_JAR)
 
 install: install_jvm install_jsig install_saproc
 
diff --git a/hotspot/make/solaris/makefiles/wb.make b/hotspot/make/solaris/makefiles/wb.make
new file mode 100644
index 0000000..a4a24dd
--- /dev/null
+++ b/hotspot/make/solaris/makefiles/wb.make
@@ -0,0 +1,46 @@
+#
+# Copyright (c) 2012, 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.
+#
+
+# Rules to build whitebox testing library, used by vm.make
+
+WB = wb
+
+WBSRCDIR = $(GAMMADIR)/src/share/tools/whitebox
+
+WB_JAR = $(GENERATED)/$(WB).jar
+
+WB_JAVA_SRCS = $(shell find $(WBSRCDIR) -name '*.java')
+WB_JAVA_CLASSDIR = $(GENERATED)/wb/classes
+
+WB_JAVA_CLASSES  = $(patsubst $(WBSRCDIR)/%,$(WB_JAVA_CLASSDIR)/%, \
+	$(patsubst %.java,%.class,$(WB_JAVA_SRCS)))
+
+$(WB_JAVA_CLASSDIR)/%.class: $(WBSRCDIR)/%.java $(WB_JAVA_CLASSDIR)
+	$(REMOTE) $(COMPILE.JAVAC) -sourcepath $(WBSRCDIR) -nowarn -d $(WB_JAVA_CLASSDIR) $<
+
+$(WB_JAR): $(WB_JAVA_CLASSES)
+	$(QUIETLY) $(REMOTE) $(RUN.JAR) cf $@ -C $(WB_JAVA_CLASSDIR)/ .
+
+$(WB_JAVA_CLASSDIR):
+	$(QUIETLY) mkdir -p $@
+
diff --git a/hotspot/make/windows/build.make b/hotspot/make/windows/build.make
index 90d2e5e..c215d59 100644
--- a/hotspot/make/windows/build.make
+++ b/hotspot/make/windows/build.make
@@ -297,6 +297,10 @@
 	@ echo BUILDARCH=$(BUILDARCH)         			>> $@
 	@ echo Platform_arch=$(Platform_arch)        		>> $@
 	@ echo Platform_arch_model=$(Platform_arch_model)	>> $@
+	@ echo CXX=$(CXX)					>> $@
+	@ echo LD=$(LD)						>> $@
+	@ echo MT=$(MT)						>> $@
+	@ echo RC=$(RC)						>> $@
 	@ sh $(WorkSpace)/make/windows/get_msc_ver.sh		>> $@
 	@ if "$(ENABLE_FULL_DEBUG_SYMBOLS)" NEQ "" echo ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS) >> $@
 	@ if "$(ZIP_DEBUGINFO_FILES)" NEQ "" echo ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES) >> $@
diff --git a/hotspot/make/windows/create_obj_files.sh b/hotspot/make/windows/create_obj_files.sh
index 6190338..78333bf 100644
--- a/hotspot/make/windows/create_obj_files.sh
+++ b/hotspot/make/windows/create_obj_files.sh
@@ -80,6 +80,8 @@
   BASE_PATHS="${BASE_PATHS} ${ALTSRC}/share/vm/jfr"
 fi
 
+BASE_PATHS="${BASE_PATHS} ${COMMONSRC}/share/vm/prims/wbtestmethods"
+
 CORE_PATHS="${BASE_PATHS}"
 # shared is already in BASE_PATHS. Should add vm/memory but that one is also in BASE_PATHS.
 if [ -d "${ALTSRC}/share/vm/gc_implementation" ]; then
diff --git a/hotspot/make/windows/makefiles/compile.make b/hotspot/make/windows/makefiles/compile.make
index 19baea3..38c0bd5 100644
--- a/hotspot/make/windows/makefiles/compile.make
+++ b/hotspot/make/windows/makefiles/compile.make
@@ -23,7 +23,9 @@
 #
 
 # Generic compiler settings
+!if "x$(CXX)" == "x"
 CXX=cl.exe
+!endif
 
 # CXX Flags: (these vary slightly from VC6->VS2003->VS2005 compilers)
 #   /nologo   Supress copyright message at every cl.exe startup
@@ -185,8 +187,10 @@
 LD_FLAGS = /manifest $(LD_FLAGS) $(BUFFEROVERFLOWLIB)
 # Manifest Tool - used in VS2005 and later to adjust manifests stored
 # as resources inside build artifacts.
+!if "x$(MT)" == "x"
 MT=mt.exe
 !endif
+!endif
 
 !if "$(COMPILER_NAME)" == "VS2008"
 PRODUCT_OPT_OPTION   = /O2 /Oy-
@@ -196,8 +200,10 @@
 LD_FLAGS = /manifest $(LD_FLAGS)
 # Manifest Tool - used in VS2005 and later to adjust manifests stored
 # as resources inside build artifacts.
+!if "x$(MT)" == "x"
 MT=mt.exe
 !endif
+!endif
 
 !if "$(COMPILER_NAME)" == "VS2010"
 PRODUCT_OPT_OPTION   = /O2 /Oy-
@@ -207,7 +213,9 @@
 LD_FLAGS = /manifest $(LD_FLAGS)
 # Manifest Tool - used in VS2005 and later to adjust manifests stored
 # as resources inside build artifacts.
+!if "x$(MT)" == "x"
 MT=mt.exe
+!endif
 !if "$(BUILDARCH)" == "i486"
 LD_FLAGS = /SAFESEH $(LD_FLAGS)
 !endif
@@ -227,7 +235,9 @@
 !endif
 
 # Generic linker settings
+!if "x$(LD)" == "x"
 LD=link.exe
+!endif
 LD_FLAGS= $(LD_FLAGS) kernel32.lib user32.lib gdi32.lib winspool.lib \
  comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib \
  uuid.lib Wsock32.lib winmm.lib /nologo /machine:$(MACHINE) /opt:REF \
@@ -242,7 +252,9 @@
 !endif
 
 # Resource compiler settings
+!if "x$(RC)" == "x"
 RC=rc.exe
+!endif
 RC_FLAGS=/D "HS_VER=$(HS_VER)" \
 	 /D "HS_DOTVER=$(HS_DOTVER)" \
 	 /D "HS_BUILD_ID=$(HS_BUILD_ID)" \
diff --git a/hotspot/make/windows/makefiles/debug.make b/hotspot/make/windows/makefiles/debug.make
index 97b5c06..36a12dc 100644
--- a/hotspot/make/windows/makefiles/debug.make
+++ b/hotspot/make/windows/makefiles/debug.make
@@ -33,12 +33,13 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
 
 !include ../local.make
 !include compile.make
 
-CXX_FLAGS=$(CXX_FLAGS) $(DEBUG_OPT_OPTION)
+# _NMT_NOINLINE_ informs NMT that no inlining by Compiler
+CXX_FLAGS=$(CXX_FLAGS) $(DEBUG_OPT_OPTION) /D "_NMT_NOINLINE_"
 
 !include $(WorkSpace)/make/windows/makefiles/vm.make
 !include local.make
@@ -71,3 +72,4 @@
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
 !include $(WorkSpace)/make/windows/makefiles/launcher.make
+!include $(WorkSpace)/make/windows/makefiles/wb.make
diff --git a/hotspot/make/windows/makefiles/defs.make b/hotspot/make/windows/makefiles/defs.make
index e922ce2..381d589b 100644
--- a/hotspot/make/windows/makefiles/defs.make
+++ b/hotspot/make/windows/makefiles/defs.make
@@ -131,26 +131,45 @@
 # overridden in some situations, e.g., a BUILD_FLAVOR != product
 # build.
 
-ifeq ($(BUILD_FLAVOR), product)
-  FULL_DEBUG_SYMBOLS ?= 1
-  ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
-else
-  # debug variants always get Full Debug Symbols (if available)
-  ENABLE_FULL_DEBUG_SYMBOLS = 1
-endif
-_JUNK_ := $(shell \
-  echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
-MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)
+# Due to the multiple sub-make processes that occur this logic gets
+# executed multiple times. We reduce the noise by at least checking that
+# BUILD_FLAVOR has been set.
+ifneq ($(BUILD_FLAVOR),)
+  ifeq ($(BUILD_FLAVOR), product)
+    FULL_DEBUG_SYMBOLS ?= 1
+    ENABLE_FULL_DEBUG_SYMBOLS = $(FULL_DEBUG_SYMBOLS)
+  else
+    # debug variants always get Full Debug Symbols (if available)
+    ENABLE_FULL_DEBUG_SYMBOLS = 1
+  endif
+  _JUNK_ := $(shell \
+    echo >&2 "INFO: ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)")
+  MAKE_ARGS += ENABLE_FULL_DEBUG_SYMBOLS=$(ENABLE_FULL_DEBUG_SYMBOLS)
 
-ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-  ZIP_DEBUGINFO_FILES ?= 1
-else
-  ZIP_DEBUGINFO_FILES=0
+  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+    ZIP_DEBUGINFO_FILES ?= 1
+  else
+    ZIP_DEBUGINFO_FILES=0
+  endif
+  MAKE_ARGS += ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)
 endif
-MAKE_ARGS += ZIP_DEBUGINFO_FILES=$(ZIP_DEBUGINFO_FILES)
+
 MAKE_ARGS += RM="$(RM)"
 MAKE_ARGS += ZIPEXE=$(ZIPEXE)
 
+# On 32 bit windows we build server, client and kernel, on 64 bit just server.
+ifeq ($(JVM_VARIANTS),)
+  ifeq ($(ARCH_DATA_MODEL), 32)
+    JVM_VARIANTS:=client,server,kernel
+    JVM_VARIANT_CLIENT:=true
+    JVM_VARIANT_SERVER:=true
+    JVM_VARIANT_KERNEL:=true
+  else
+    JVM_VARIANTS:=server
+    JVM_VARIANT_SERVER:=true
+  endif
+endif
+
 JDK_INCLUDE_SUBDIR=win32
 
 # Library suffix
@@ -175,14 +194,22 @@
   MAKE_ARGS += JDK_BUILD_NUMBER=$(COOKED_BUILD_NUMBER)
 endif
 
-NMAKE= MAKEFLAGS= MFLAGS= nmake /NOLOGO
+NMAKE= MAKEFLAGS= MFLAGS= nmake -NOLOGO
+ifndef SYSTEM_UNAME
+  SYSTEM_UNAME := $(shell uname)
+  export SYSTEM_UNAME
+endif
 
 # Check for CYGWIN
-ifneq (,$(findstring CYGWIN,$(shell uname)))
+ifneq (,$(findstring CYGWIN,$(SYSTEM_UNAME)))
   USING_CYGWIN=true
 else
   USING_CYGWIN=false
 endif
+# Check for MinGW
+ifneq (,$(findstring MINGW,$(SYSTEM_UNAME)))
+  USING_MINGW=true
+endif
 # FIXUP: The subdirectory for a debug build is NOT the same on all platforms
 VM_DEBUG=debug
 
@@ -195,11 +222,16 @@
   ABS_BOOTDIR     := $(subst /,\\,$(shell /bin/cygpath -m -a "$(BOOTDIR)"))
   ABS_GAMMADIR    := $(subst /,\\,$(shell /bin/cygpath -m -a "$(GAMMADIR)"))
   ABS_OS_MAKEFILE := $(shell /bin/cygpath -m -a "$(HS_MAKE_DIR)/$(OSNAME)")/build.make
-else
-  ABS_OUTPUTDIR   := $(subst /,\\,$(shell $(CD) $(OUTPUTDIR);$(PWD)))
-  ABS_BOOTDIR     := $(subst /,\\,$(shell $(CD) $(BOOTDIR);$(PWD)))
-  ABS_GAMMADIR    := $(subst /,\\,$(shell $(CD) $(GAMMADIR);$(PWD)))
-  ABS_OS_MAKEFILE := $(subst /,\\,$(shell $(CD) $(HS_MAKE_DIR)/$(OSNAME);$(PWD))/build.make)
+else ifeq ($(USING_MINGW), true)
+    ABS_OUTPUTDIR   := $(shell $(CD) $(OUTPUTDIR);$(PWD))
+    ABS_BOOTDIR     := $(shell $(CD) $(BOOTDIR);$(PWD))
+    ABS_GAMMADIR    := $(shell $(CD) $(GAMMADIR);$(PWD))
+    ABS_OS_MAKEFILE := $(shell $(CD) $(HS_MAKE_DIR)/$(OSNAME);$(PWD))/build.make
+  else
+    ABS_OUTPUTDIR   := $(subst /,\\,$(shell $(CD) $(OUTPUTDIR);$(PWD)))
+    ABS_BOOTDIR     := $(subst /,\\,$(shell $(CD) $(BOOTDIR);$(PWD)))
+    ABS_GAMMADIR    := $(subst /,\\,$(shell $(CD) $(GAMMADIR);$(PWD)))
+    ABS_OS_MAKEFILE := $(subst /,\\,$(shell $(CD) $(HS_MAKE_DIR)/$(OSNAME);$(PWD))/build.make)
 endif
 
 # Disable building SA on windows until we are sure
@@ -221,18 +253,20 @@
 EXPORT_CLIENT_DIR = $(EXPORT_JRE_BIN_DIR)/client
 EXPORT_KERNEL_DIR = $(EXPORT_JRE_BIN_DIR)/kernel
 
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
-EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.$(LIBRARY_SUFFIX)
-ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-  ifeq ($(ZIP_DEBUGINFO_FILES),1)
-    EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.diz
-  else
-    EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
-    EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
+ifeq ($(JVM_VARIANT_SERVER),true)
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/Xusage.txt
+  EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.$(LIBRARY_SUFFIX)
+  ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
+    ifeq ($(ZIP_DEBUGINFO_FILES),1)
+      EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.diz
+    else
+      EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.pdb
+      EXPORT_LIST += $(EXPORT_SERVER_DIR)/jvm.map
+    endif
   endif
+  EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
 endif
-EXPORT_LIST += $(EXPORT_LIB_DIR)/jvm.lib
-ifeq ($(ARCH_DATA_MODEL), 32)
+ifeq ($(JVM_VARIANT_CLIENT),true)
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/Xusage.txt
   EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.$(LIBRARY_SUFFIX)
   ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
@@ -243,7 +277,8 @@
       EXPORT_LIST += $(EXPORT_CLIENT_DIR)/jvm.map
     endif
   endif
-  # kernel vm
+endif
+ifeq ($(JVM_VARIANT_KERNEL),true)
   EXPORT_LIST += $(EXPORT_KERNEL_DIR)/Xusage.txt
   EXPORT_LIST += $(EXPORT_KERNEL_DIR)/jvm.$(LIBRARY_SUFFIX)
   ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
@@ -256,6 +291,8 @@
   endif
 endif
 
+EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/wb.jar
+
 ifeq ($(BUILD_WIN_SA), 1)
   EXPORT_LIST += $(EXPORT_JRE_BIN_DIR)/sawindbg.$(LIBRARY_SUFFIX)
   ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
@@ -270,3 +307,19 @@
   # Must pass this down to nmake.
   MAKE_ARGS += BUILD_WIN_SA=1
 endif
+
+# Propagate compiler and tools paths from configure to nmake. 
+# Need to make sure they contain \\ and not /.
+ifneq ($(SPEC),)
+  ifeq ($(USING_CYGWIN), true)
+    MAKE_ARGS += CXX="$(subst /,\\,$(shell /bin/cygpath -s -m -a $(CXX)))"
+    MAKE_ARGS += LD="$(subst /,\\,$(shell /bin/cygpath -s -m -a $(LD)))"
+    MAKE_ARGS += RC="$(subst /,\\,$(shell /bin/cygpath -s -m -a $(RC)))"
+    MAKE_ARGS += MT="$(subst /,\\,$(shell /bin/cygpath -s -m -a $(MT)))"
+  else
+    MAKE_ARGS += CXX="$(subst /,\\,$(CXX))"
+    MAKE_ARGS += LD="$(subst /,\\,$(LD))"
+    MAKE_ARGS += RC="$(subst /,\\,$(RC))"
+    MAKE_ARGS += MT="$(subst /,\\,$(MT))"
+  endif
+endif
diff --git a/hotspot/make/windows/makefiles/fastdebug.make b/hotspot/make/windows/makefiles/fastdebug.make
index 0fc2329..f6347bc 100644
--- a/hotspot/make/windows/makefiles/fastdebug.make
+++ b/hotspot/make/windows/makefiles/fastdebug.make
@@ -33,7 +33,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
 
 !include ../local.make
 !include compile.make
@@ -71,3 +71,4 @@
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
 !include $(WorkSpace)/make/windows/makefiles/launcher.make
+!include $(WorkSpace)/make/windows/makefiles/wb.make
diff --git a/hotspot/make/windows/makefiles/product.make b/hotspot/make/windows/makefiles/product.make
index 2b21d1c..ada9c72 100644
--- a/hotspot/make/windows/makefiles/product.make
+++ b/hotspot/make/windows/makefiles/product.make
@@ -32,7 +32,7 @@
 BUILD_PCH_FILE=_build_pch_file.obj
 !endif
 
-default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA
+default:: $(BUILD_PCH_FILE) $(AOUT) launcher checkAndBuildSA wb
 
 !include ../local.make
 !include compile.make
@@ -82,3 +82,4 @@
 !include $(WorkSpace)/make/windows/makefiles/shared.make
 !include $(WorkSpace)/make/windows/makefiles/sa.make
 !include $(WorkSpace)/make/windows/makefiles/launcher.make
+!include $(WorkSpace)/make/windows/makefiles/wb.make
diff --git a/hotspot/make/windows/makefiles/projectcreator.make b/hotspot/make/windows/makefiles/projectcreator.make
index 0c110f9..2af47d48 100644
--- a/hotspot/make/windows/makefiles/projectcreator.make
+++ b/hotspot/make/windows/makefiles/projectcreator.make
@@ -29,12 +29,11 @@
 # HOTSPOTRELEASEBINDEST, or HOTSPOTDEBUGBINDEST environment variables.
 
 ProjectCreatorSources=\
-        $(WorkSpace)\src\share\tools\ProjectCreator\DirectoryTree.java \
-        $(WorkSpace)\src\share\tools\ProjectCreator\DirectoryTreeNode.java \
-        $(WorkSpace)\src\share\tools\ProjectCreator\FileFormatException.java \
         $(WorkSpace)\src\share\tools\ProjectCreator\ProjectCreator.java \
+        $(WorkSpace)\src\share\tools\ProjectCreator\FileTreeCreator.java \
+        $(WorkSpace)\src\share\tools\ProjectCreator\FileTreeCreatorVC7.java \
+        $(WorkSpace)\src\share\tools\ProjectCreator\FileTreeCreatorVC10.java \
         $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatform.java \
-        $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC6.java \
         $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC7.java \
         $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC8.java \
         $(WorkSpace)\src\share\tools\ProjectCreator\WinGammaPlatformVC9.java \
@@ -51,15 +50,30 @@
         -relativeInclude src\closed\cpu\$(Platform_arch)\vm \
         -relativeInclude src\share\vm \
         -relativeInclude src\share\vm\precompiled \
+        -relativeInclude src\share\vm\prims\wbtestmethods \
         -relativeInclude src\share\vm\prims \
         -relativeInclude src\os\windows\vm \
         -relativeInclude src\os_cpu\windows_$(Platform_arch)\vm \
         -relativeInclude src\cpu\$(Platform_arch)\vm \
         -absoluteInclude $(HOTSPOTBUILDSPACE)/%f/generated \
-        -ignorePath $(HOTSPOTBUILDSPACE)/%f/generated \
-        -ignorePath src\share\vm\adlc \
-        -ignorePath src\share\vm\shark \
-        -ignorePath posix
+        -relativeSrcInclude src \
+        -absoluteSrcInclude $(HOTSPOTBUILDSPACE) \
+        -ignorePath $(HOTSPOTBUILDSPACE) \
+        -ignorePath launcher \
+        -ignorePath share\vm\adlc \
+        -ignorePath share\vm\shark \
+        -ignorePath share\tools \
+        -ignorePath solaris \
+        -ignorePath posix \
+        -ignorePath sparc \
+        -ignorePath linux \
+        -ignorePath bsd \
+        -ignorePath osx \
+        -ignorePath arm \
+        -ignorePath ppc \
+        -ignorePath zero \
+        -hidePath .hg
+	
 
 # This is referenced externally by both the IDE and batch builds
 ProjectCreatorOptions=
@@ -83,6 +97,7 @@
         $(ProjectCreatorIDEOptions) \
         -sourceBase $(HOTSPOTWORKSPACE) \
         -buildBase $(HOTSPOTBUILDSPACE)\%f\%b \
+        -buildSpace $(HOTSPOTBUILDSPACE) \
         -startAt src \
         -compiler $(VcVersion) \
         -projectFileName $(HOTSPOTBUILDSPACE)\$(ProjectFile) \
@@ -102,6 +117,7 @@
         -define TARGET_OS_ARCH_windows_x86 \
         -define TARGET_OS_FAMILY_windows \
         -define TARGET_COMPILER_visCPP \
+        -define INCLUDE_TRACE \
        $(ProjectCreatorIncludesPRIVATE)
 
 # Add in build-specific options
@@ -124,9 +140,13 @@
 !endif
 
 ProjectCreatorIDEOptionsIgnoreCompiler1=\
+ -ignorePath_TARGET compiler1 \
+ -ignorePath_TARGET tiered \
  -ignorePath_TARGET c1_
 
 ProjectCreatorIDEOptionsIgnoreCompiler2=\
+ -ignorePath_TARGET compiler2 \
+ -ignorePath_TARGET tiered \
  -ignorePath_TARGET src/share/vm/opto \
  -ignorePath_TARGET src/share/vm/libadt \
  -ignorePath_TARGET adfiles \
@@ -208,6 +228,7 @@
 ##################################################
 ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
  -define_compiler1 COMPILER1 \
+ -ignorePath_compiler1 core \
 $(ProjectCreatorIDEOptionsIgnoreCompiler2:TARGET=compiler1)
 
 ##################################################
@@ -216,18 +237,19 @@
 #NOTE! This list must be kept in sync with GENERATED_NAMES in adlc.make.
 ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
  -define_compiler2 COMPILER2 \
+ -ignorePath_compiler2 core \
  -additionalFile_compiler2 $(Platform_arch_model).ad \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model).cpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model).hpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_clone.cpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_expand.cpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_format.cpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_gen.cpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_misc.cpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_peephole.cpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles ad_$(Platform_arch_model)_pipeline.cpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles adGlobals_$(Platform_arch_model).hpp \
- -additionalGeneratedFile_compiler2 $(HOTSPOTBUILDSPACE)/%f/generated/adfiles dfa_$(Platform_arch_model).cpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model).cpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model).hpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model)_clone.cpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model)_expand.cpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model)_format.cpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model)_gen.cpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model)_misc.cpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model)_peephole.cpp \
+ -additionalFile_compiler2 ad_$(Platform_arch_model)_pipeline.cpp \
+ -additionalFile_compiler2 adGlobals_$(Platform_arch_model).hpp \
+ -additionalFile_compiler2 dfa_$(Platform_arch_model).cpp \
  $(ProjectCreatorIDEOptionsIgnoreCompiler1:TARGET=compiler2)
 
 # Add in the jvmti (JSR-163) options
@@ -236,8 +258,8 @@
 #       code merge was done correctly (@see jvmti.make and jvmtiEnvFill.java).
 #       If so, they would then check it in as a new version of jvmtiEnv.cpp.
 ProjectCreatorIDEOptions=$(ProjectCreatorIDEOptions) \
- -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles jvmtiEnv.hpp \
- -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles jvmtiEnter.cpp \
- -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles jvmtiEnterTrace.cpp \
- -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles jvmti.h \
- -additionalGeneratedFile $(HOTSPOTBUILDSPACE)/%f/generated/jvmtifiles bytecodeInterpreterWithChecks.cpp
+ -additionalFile jvmtiEnv.hpp \
+ -additionalFile jvmtiEnter.cpp \
+ -additionalFile jvmtiEnterTrace.cpp \
+ -additionalFile jvmti.h \
+ -additionalFile bytecodeInterpreterWithChecks.cpp
diff --git a/hotspot/make/windows/makefiles/rules.make b/hotspot/make/windows/makefiles/rules.make
index 14bc0d5..3e8d854 100644
--- a/hotspot/make/windows/makefiles/rules.make
+++ b/hotspot/make/windows/makefiles/rules.make
@@ -23,14 +23,15 @@
 #
 
 # These are the commands used externally to compile and run.
-
+# The \ are used here for traditional Windows apps and " quoted to get
+# past the Unix-like shell:
 !ifdef BootStrapDir
-RUN_JAVA=$(BootStrapDir)\bin\java
-RUN_JAVAP=$(BootStrapDir)\bin\javap
-RUN_JAVAH=$(BootStrapDir)\bin\javah
-RUN_JAR=$(BootStrapDir)\bin\jar
-COMPILE_JAVAC=$(BootStrapDir)\bin\javac $(BOOTSTRAP_JAVAC_FLAGS)
-COMPILE_RMIC=$(BootStrapDir)\bin\rmic
+RUN_JAVA="$(BootStrapDir)\bin\java"
+RUN_JAVAP="$(BootStrapDir)\bin\javap"
+RUN_JAVAH="$(BootStrapDir)\bin\javah"
+RUN_JAR="$(BootStrapDir)\bin\jar"
+COMPILE_JAVAC="$(BootStrapDir)\bin\javac" $(BOOTSTRAP_JAVAC_FLAGS)
+COMPILE_RMIC="$(BootStrapDir)\bin\rmic"
 BOOT_JAVA_HOME=$(BootStrapDir)
 !else
 RUN_JAVA=java
diff --git a/hotspot/make/windows/makefiles/sa.make b/hotspot/make/windows/makefiles/sa.make
index 9d52c58..9391ce8 100644
--- a/hotspot/make/windows/makefiles/sa.make
+++ b/hotspot/make/windows/makefiles/sa.make
@@ -36,37 +36,37 @@
 !include $(WorkSpace)/make/windows/makefiles/rules.make
 !include $(WorkSpace)/make/sa.files
 
-GENERATED = ..\generated
+GENERATED = ../generated
 
 # tools.jar is needed by the JDI - SA binding
-SA_CLASSPATH = $(BOOT_JAVA_HOME)\lib\tools.jar
+SA_CLASSPATH = $(BOOT_JAVA_HOME)/lib/tools.jar
 
-SA_CLASSDIR = $(GENERATED)\saclasses
+SA_CLASSDIR = $(GENERATED)/saclasses
 
 SA_BUILD_VERSION_PROP = sun.jvm.hotspot.runtime.VM.saBuildVersion=$(SA_BUILD_VERSION)
 
-SA_PROPERTIES = $(SA_CLASSDIR)\sa.properties
+SA_PROPERTIES = $(SA_CLASSDIR)/sa.properties
 
-default::  $(GENERATED)\sa-jdi.jar
+default::  $(GENERATED)/sa-jdi.jar
 
 # Remove the space between $(SA_BUILD_VERSION_PROP) and > below as it adds a white space
 # at the end of SA version string and causes a version mismatch with the target VM version.
 
-$(GENERATED)\sa-jdi.jar: $(AGENT_FILES:/=\)
-	@if not exist $(SA_CLASSDIR) mkdir $(SA_CLASSDIR)
-	@echo ...Building sa-jdi.jar
+$(GENERATED)/sa-jdi.jar: $(AGENT_FILES)
+	$(QUIETLY) mkdir -p $(SA_CLASSDIR)
+	@echo ...Building sa-jdi.jar into $(SA_CLASSDIR)
 	@echo ...$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -d $(SA_CLASSDIR) ....
-	@$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES:/=\)
+	@$(COMPILE_JAVAC) -classpath $(SA_CLASSPATH) -sourcepath $(AGENT_SRC_DIR) -d $(SA_CLASSDIR) $(AGENT_FILES)
 	$(COMPILE_RMIC) -classpath $(SA_CLASSDIR) -d $(SA_CLASSDIR) sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer
 	$(QUIETLY) echo $(SA_BUILD_VERSION_PROP)> $(SA_PROPERTIES)
 	$(QUIETLY) rm -f $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql/sa.js
 	$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/utilities/soql/sa.js $(SA_CLASSDIR)/sun/jvm/hotspot/utilities/soql
 	$(QUIETLY) rm -rf $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
-	$(QUIETLY) mkdir $(SA_CLASSDIR)\sun\jvm\hotspot\ui\resources
+	$(QUIETLY) mkdir $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
 	$(QUIETLY) cp $(AGENT_SRC_DIR)/sun/jvm/hotspot/ui/resources/*.png $(SA_CLASSDIR)/sun/jvm/hotspot/ui/resources
 	$(QUIETLY) cp -r $(AGENT_SRC_DIR)/images/* $(SA_CLASSDIR)
 	$(RUN_JAR) cf $@ -C $(SA_CLASSDIR) .
-	$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR:/=\) META-INF\services\com.sun.jdi.connect.Connector
+	$(RUN_JAR) uf $@ -C $(AGENT_SRC_DIR) META-INF/services/com.sun.jdi.connect.Connector
 	$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal
 	$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.x86.X86ThreadContext 
 	$(RUN_JAVAH) -classpath $(SA_CLASSDIR) -jni sun.jvm.hotspot.debugger.ia64.IA64ThreadContext 
@@ -85,27 +85,27 @@
 # will be useful to have the assertion checks in place
 
 !if "$(BUILDARCH)" == "ia64"
-SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 $(GX_OPTION) /Od /D "WIN32" /D "WIN64" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -c
 !elseif "$(BUILDARCH)" == "amd64"
-SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 $(GX_OPTION) /Od /D "WIN32" /D "WIN64" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 $(GX_OPTION) -Od -D "WIN32" -D "WIN64" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -c
 !if "$(COMPILER_NAME)" == "VS2005"
 # On amd64, VS2005 compiler requires bufferoverflowU.lib on the link command line, 
 # otherwise we get missing __security_check_cookie externals at link time. 
 SA_LD_FLAGS = bufferoverflowU.lib
 !endif
 !else
-SA_CFLAGS = /nologo $(MS_RUNTIME_OPTION) /W3 /Gm $(GX_OPTION) /Od /D "WIN32" /D "_WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+SA_CFLAGS = -nologo $(MS_RUNTIME_OPTION) -W3 -Gm $(GX_OPTION) -Od -D "WIN32" -D "_WINDOWS" -D "_DEBUG" -D "_CONSOLE" -D "_MBCS" -YX -FD -GZ -c
 !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
-SA_CFLAGS = $(SA_CFLAGS) /ZI
+SA_CFLAGS = $(SA_CFLAGS) -ZI
 !endif
 !endif
 !if "$(MT)" != ""
-SA_LD_FLAGS = /manifest $(SA_LD_FLAGS)
+SA_LD_FLAGS = -manifest $(SA_LD_FLAGS)
 !endif
 SASRCFILE = $(AGENT_DIR)/src/os/win32/windbg/sawindbg.cpp
-SA_LFLAGS = $(SA_LD_FLAGS) /nologo /subsystem:console /machine:$(MACHINE)
+SA_LFLAGS = $(SA_LD_FLAGS) -nologo -subsystem:console -machine:$(MACHINE)
 !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
-SA_LFLAGS = $(SA_LFLAGS) /map /debug
+SA_LFLAGS = $(SA_LFLAGS) -map -debug
 !endif
 
 # Note that we do not keep sawindbj.obj around as it would then
@@ -117,15 +117,15 @@
 $(SAWINDBG): $(SASRCFILE)
 	set INCLUDE=$(SA_INCLUDE)$(INCLUDE)
 	$(CXX) @<<
-	  /I"$(BootStrapDir)/include" /I"$(BootStrapDir)/include/win32" 
-	  /I"$(GENERATED)" $(SA_CFLAGS)
+	  -I"$(BootStrapDir)/include" -I"$(BootStrapDir)/include/win32" 
+	  -I"$(GENERATED)" $(SA_CFLAGS)
 	  $(SASRCFILE)
-	  /out:$*.obj
+	  -out:$*.obj
 <<
 	set LIB=$(SA_LIB)$(LIB)
-	$(LD) /out:$@ /DLL $*.obj dbgeng.lib $(SA_LFLAGS)
+	$(LD) -out:$@ -DLL $*.obj dbgeng.lib $(SA_LFLAGS)
 !if "$(MT)" != ""
-	$(MT) /manifest $(@F).manifest /outputresource:$(@F);#2
+	$(MT) -manifest $(@F).manifest -outputresource:$(@F);#2
 !endif
 !if "$(ENABLE_FULL_DEBUG_SYMBOLS)" == "1"
 !if "$(ZIP_DEBUGINFO_FILES)" == "1"
@@ -136,6 +136,6 @@
 	-@rm -f $*.obj
 
 cleanall :
-	rm -rf $(GENERATED:\=/)/saclasses
-	rm -rf $(GENERATED:\=/)/sa-jdi.jar
+	rm -rf $(GENERATED)/saclasses
+	rm -rf $(GENERATED)/sa-jdi.jar
 !endif
diff --git a/hotspot/make/windows/makefiles/shared.make b/hotspot/make/windows/makefiles/shared.make
index cf01423..b525cf7 100644
--- a/hotspot/make/windows/makefiles/shared.make
+++ b/hotspot/make/windows/makefiles/shared.make
@@ -36,11 +36,12 @@
 
 
 !ifdef SUBDIRS
+# \ is used below because $(MAKE) is nmake here, which expects Windows paths
 $(SUBDIRS): FORCE
 	@if not exist $@ mkdir $@
-	@if not exist $@\local.make echo # Empty > $@\local.make
-	@echo nmake $(ACTION) in $(DIR)\$@
-	cd $@ && $(MAKE) /NOLOGO /f $(WorkSpace)\make\windows\makefiles\$@.make $(ACTION) DIR=$(DIR)\$@ BUILD_FLAVOR=$(BUILD_FLAVOR)
+	@if not exist $@/local.make echo # Empty > $@/local.make
+	@echo nmake $(ACTION) in $(DIR)/$@
+	cd $@ && $(MAKE) -NOLOGO -f $(WorkSpace)\make\windows\makefiles\$@.make $(ACTION) DIR=$(DIR)\$@ BUILD_FLAVOR=$(BUILD_FLAVOR)
 !endif
 
 # Creates the needed directory
diff --git a/hotspot/make/windows/makefiles/vm.make b/hotspot/make/windows/makefiles/vm.make
index d3e226c..ee878fe 100644
--- a/hotspot/make/windows/makefiles/vm.make
+++ b/hotspot/make/windows/makefiles/vm.make
@@ -172,6 +172,7 @@
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/memory
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/oops
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/prims
+VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/prims/wbtestmethods
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/runtime
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/services
 VM_PATH=$(VM_PATH);$(WorkSpace)/src/share/vm/trace
@@ -269,6 +270,9 @@
 {$(COMMONSRC)\share\vm\prims}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
+{$(COMMONSRC)\share\vm\prims\wbtestmethods}.cpp.obj::
+        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
 {$(COMMONSRC)\share\vm\runtime}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
@@ -349,6 +353,9 @@
 {$(ALTSRC)\share\vm\prims}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
+{$(ALTSRC)\share\vm\prims\wbtestmethods}.cpp.obj::
+        $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
+
 {$(ALTSRC)\share\vm\runtime}.cpp.obj::
         $(CXX) $(CXX_FLAGS) $(CXX_USE_PCH) /c $<
 
diff --git a/hotspot/make/windows/makefiles/wb.make b/hotspot/make/windows/makefiles/wb.make
new file mode 100644
index 0000000..76b4318
--- /dev/null
+++ b/hotspot/make/windows/makefiles/wb.make
@@ -0,0 +1,54 @@
+#
+# Copyright (c) 2012, 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.
+#  
+#
+
+# This makefile is used to build the whitebox testing lib
+# and compile the tests which use it
+
+!include $(WorkSpace)/make/windows/makefiles/rules.make
+
+WBSRCDIR = $(WorkSpace)/src/share/tools/whitebox
+
+# turn GENERATED into a windows path to get sane dependencies
+WB_CLASSES=$(GENERATED:/=\)\wb\classes
+WB_JAR=$(GENERATED:/=\)\wb.jar
+
+# call recursive make to do wildcard expansion
+.SUFFIXES : .java .class
+wb_java_srcs: $(WorkSpace)\src\share\tools\whitebox\sun\hotspot\*.java $(WB_CLASSES)
+	$(MAKE) -f $(WorkSpace)\make\windows\makefiles\$(BUILD_FLAVOR).make $(**:.java=.class)
+
+
+{$(WorkSpace)\src\share\tools\whitebox\sun\hotspot}.java.class::
+	$(COMPILE_JAVAC) -sourcepath $(WBSRCDIR) -d $(WB_CLASSES) $<
+
+$(WB_JAR): wb_java_srcs
+	$(RUN_JAR) cf $@ -C $(WB_CLASSES) .
+
+# turn $@ to a unix path because mkdir in PATH is cygwin/mks mkdir
+$(WB_CLASSES):
+	mkdir -p $(@:\=/)
+
+# main target to build wb
+wb: $(WB_JAR)
+
diff --git a/hotspot/make/windows/projectfiles/common/Makefile b/hotspot/make/windows/projectfiles/common/Makefile
index 3e7d159..1b037a1 100644
--- a/hotspot/make/windows/projectfiles/common/Makefile
+++ b/hotspot/make/windows/projectfiles/common/Makefile
@@ -108,7 +108,7 @@
       -define              HOTSPOT_VM_DISTRO=\\\"$(HOTSPOT_VM_DISTRO)\\\"
 
 $(HOTSPOTBUILDSPACE)/$(ProjectFile): $(HOTSPOTBUILDSPACE)/classes/ProjectCreator.class
-	@$(RUN_JAVA) -Djava.class.path=$(HOTSPOTBUILDSPACE)/classes ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
+	@$(RUN_JAVA) -Djava.class.path="$(HOTSPOTBUILDSPACE)/classes" ProjectCreator WinGammaPlatform$(VcVersion) $(ProjectCreatorIDEOptions)
 
 clean:
 	@rm -rf $(HOTSPOTBUILDSPACE)/classes
diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp
index 71c8e07..8a4431e 100644
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.cpp
@@ -44,8 +44,10 @@
 
 #ifdef PRODUCT
 #define BLOCK_COMMENT(str) /* nothing */
+#define STOP(error) stop(error)
 #else
 #define BLOCK_COMMENT(str) block_comment(str)
+#define STOP(error) block_comment(error); stop(error)
 #endif
 
 // Convert the raw encoding form into the form expected by the
@@ -723,24 +725,6 @@
 }
 
 
-// Convert to C varargs format
-void MacroAssembler::set_varargs( Argument inArg, Register d ) {
-  // spill register-resident args to their memory slots
-  // (SPARC calling convention requires callers to have already preallocated these)
-  // Note that the inArg might in fact be an outgoing argument,
-  // if a leaf routine or stub does some tricky argument shuffling.
-  // This routine must work even though one of the saved arguments
-  // is in the d register (e.g., set_varargs(Argument(0, false), O0)).
-  for (Argument savePtr = inArg;
-       savePtr.is_register();
-       savePtr = savePtr.successor()) {
-    st_ptr(savePtr.as_register(), savePtr.address_in_frame());
-  }
-  // return the address of the first memory slot
-  Address a = inArg.address_in_frame();
-  add(a.base(), a.disp(), d);
-}
-
 // Conditional breakpoint (for assertion checks in assembly code)
 void MacroAssembler::breakpoint_trap(Condition c, CC cc) {
   trap(c, cc, G0, ST_RESERVED_FOR_USER_0);
@@ -992,7 +976,7 @@
   save_frame(0);                // to avoid clobbering O0
   ld_ptr(pc_addr, L0);
   br_null_short(L0, Assembler::pt, PcOk);
-  stop("last_Java_pc not zeroed before leaving Java");
+  STOP("last_Java_pc not zeroed before leaving Java");
   bind(PcOk);
 
   // Verify that flags was zeroed on return to Java
@@ -1001,7 +985,7 @@
   tst(L0);
   br(Assembler::zero, false, Assembler::pt, FlagsOk);
   delayed() -> restore();
-  stop("flags not zeroed before leaving Java");
+  STOP("flags not zeroed before leaving Java");
   bind(FlagsOk);
 #endif /* ASSERT */
   //
@@ -1021,7 +1005,7 @@
   andcc(last_java_sp, 0x01, G0);
   br(Assembler::notZero, false, Assembler::pt, StackOk);
   delayed()->nop();
-  stop("Stack Not Biased in set_last_Java_frame");
+  STOP("Stack Not Biased in set_last_Java_frame");
   bind(StackOk);
 #endif // ASSERT
   assert( last_java_sp != G4_scratch, "bad register usage in set_last_Java_frame");
@@ -1650,23 +1634,28 @@
 
 
 void RegistersForDebugging::print(outputStream* s) {
+  FlagSetting fs(Debugging, true);
   int j;
-  for ( j = 0;  j < 8;  ++j )
-    if ( j != 6 ) s->print_cr("i%d = 0x%.16lx", j, i[j]);
-    else          s->print_cr( "fp = 0x%.16lx",    i[j]);
+  for (j = 0; j < 8; ++j) {
+    if (j != 6) { s->print("i%d = ", j); os::print_location(s, i[j]); }
+    else        { s->print( "fp = "   ); os::print_location(s, i[j]); }
+  }
   s->cr();
 
-  for ( j = 0;  j < 8;  ++j )
-    s->print_cr("l%d = 0x%.16lx", j, l[j]);
+  for (j = 0;  j < 8;  ++j) {
+    s->print("l%d = ", j); os::print_location(s, l[j]);
+  }
   s->cr();
 
-  for ( j = 0;  j < 8;  ++j )
-    if ( j != 6 ) s->print_cr("o%d = 0x%.16lx", j, o[j]);
-    else          s->print_cr( "sp = 0x%.16lx",    o[j]);
+  for (j = 0; j < 8; ++j) {
+    if (j != 6) { s->print("o%d = ", j); os::print_location(s, o[j]); }
+    else        { s->print( "sp = "   ); os::print_location(s, o[j]); }
+  }
   s->cr();
 
-  for ( j = 0;  j < 8;  ++j )
-    s->print_cr("g%d = 0x%.16lx", j, g[j]);
+  for (j = 0; j < 8; ++j) {
+    s->print("g%d = ", j); os::print_location(s, g[j]);
+  }
   s->cr();
 
   // print out floats with compression
@@ -2020,8 +2009,8 @@
   char* b = new char[1024];
   sprintf(b, "untested: %s", what);
 
-  if ( ShowMessageBoxOnError )   stop(b);
-  else                           warn(b);
+  if (ShowMessageBoxOnError) { STOP(b); }
+  else                       { warn(b); }
 }
 
 
@@ -2923,6 +2912,20 @@
   assert(itable_index.is_constant() || itable_index.as_register() == method_result,
          "caller must use same register for non-constant itable index as for method");
 
+  Label L_no_such_interface_restore;
+  bool did_save = false;
+  if (scan_temp == noreg || sethi_temp == noreg) {
+    Register recv_2 = recv_klass->is_global() ? recv_klass : L0;
+    Register intf_2 = intf_klass->is_global() ? intf_klass : L1;
+    assert(method_result->is_global(), "must be able to return value");
+    scan_temp  = L2;
+    sethi_temp = L3;
+    save_frame_and_mov(0, recv_klass, recv_2, intf_klass, intf_2);
+    recv_klass = recv_2;
+    intf_klass = intf_2;
+    did_save = true;
+  }
+
   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
   int vtable_base = instanceKlass::vtable_start_offset() * wordSize;
   int scan_step   = itableOffsetEntry::size() * wordSize;
@@ -2961,7 +2964,7 @@
   //     result = (klass + scan->offset() + itable_index);
   //   }
   // }
-  Label search, found_method;
+  Label L_search, L_found_method;
 
   for (int peel = 1; peel >= 0; peel--) {
     // %%%% Could load both offset and interface in one ldx, if they were
@@ -2971,23 +2974,23 @@
     // Check that this entry is non-null.  A null entry means that
     // the receiver class doesn't implement the interface, and wasn't the
     // same as when the caller was compiled.
-    bpr(Assembler::rc_z, false, Assembler::pn, method_result, L_no_such_interface);
+    bpr(Assembler::rc_z, false, Assembler::pn, method_result, did_save ? L_no_such_interface_restore : L_no_such_interface);
     delayed()->cmp(method_result, intf_klass);
 
     if (peel) {
-      brx(Assembler::equal,    false, Assembler::pt, found_method);
+      brx(Assembler::equal,    false, Assembler::pt, L_found_method);
     } else {
-      brx(Assembler::notEqual, false, Assembler::pn, search);
+      brx(Assembler::notEqual, false, Assembler::pn, L_search);
       // (invert the test to fall through to found_method...)
     }
     delayed()->add(scan_temp, scan_step, scan_temp);
 
     if (!peel)  break;
 
-    bind(search);
+    bind(L_search);
   }
 
-  bind(found_method);
+  bind(L_found_method);
 
   // Got a hit.
   int ito_offset = itableOffsetEntry::offset_offset_in_bytes();
@@ -2995,6 +2998,40 @@
   ito_offset -= scan_step;
   lduw(scan_temp, ito_offset, scan_temp);
   ld_ptr(recv_klass, scan_temp, method_result);
+
+  if (did_save) {
+    Label L_done;
+    ba(L_done);
+    delayed()->restore();
+
+    bind(L_no_such_interface_restore);
+    ba(L_no_such_interface);
+    delayed()->restore();
+
+    bind(L_done);
+  }
+}
+
+
+// virtual method calling
+void MacroAssembler::lookup_virtual_method(Register recv_klass,
+                                           RegisterOrConstant vtable_index,
+                                           Register method_result) {
+  assert_different_registers(recv_klass, method_result, vtable_index.register_or_noreg());
+  Register sethi_temp = method_result;
+  const int base = (instanceKlass::vtable_start_offset() * wordSize +
+                    // method pointer offset within the vtable entry:
+                    vtableEntry::method_offset_in_bytes());
+  RegisterOrConstant vtable_offset = vtable_index;
+  // Each of the following three lines potentially generates an instruction.
+  // But the total number of address formation instructions will always be
+  // at most two, and will often be zero.  In any case, it will be optimal.
+  // If vtable_index is a register, we will have (sll_ptr N,x; inc_ptr B,x; ld_ptr k,x).
+  // If vtable_index is a constant, we will have at most (set B+X<<N,t; ld_ptr k,t).
+  vtable_offset = regcon_sll_ptr(vtable_index, exact_log2(vtableEntry::size() * wordSize), vtable_offset);
+  vtable_offset = regcon_inc_ptr(vtable_offset, base, vtable_offset, sethi_temp);
+  Address vtable_entry_addr(recv_klass, ensure_simm13_or_reg(vtable_offset, sethi_temp));
+  ld_ptr(vtable_entry_addr, method_result);
 }
 
 
@@ -3003,21 +3040,33 @@
                                          Register temp_reg,
                                          Register temp2_reg,
                                          Label& L_success) {
-  Label L_failure, L_pop_to_failure;
-  check_klass_subtype_fast_path(sub_klass, super_klass,
-                                temp_reg, temp2_reg,
-                                &L_success, &L_failure, NULL);
   Register sub_2 = sub_klass;
   Register sup_2 = super_klass;
   if (!sub_2->is_global())  sub_2 = L0;
   if (!sup_2->is_global())  sup_2 = L1;
+  bool did_save = false;
+  if (temp_reg == noreg || temp2_reg == noreg) {
+    temp_reg = L2;
+    temp2_reg = L3;
+    save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2);
+    sub_klass = sub_2;
+    super_klass = sup_2;
+    did_save = true;
+  }
+  Label L_failure, L_pop_to_failure, L_pop_to_success;
+  check_klass_subtype_fast_path(sub_klass, super_klass,
+                                temp_reg, temp2_reg,
+                                (did_save ? &L_pop_to_success : &L_success),
+                                (did_save ? &L_pop_to_failure : &L_failure), NULL);
 
-  save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2);
+  if (!did_save)
+    save_frame_and_mov(0, sub_klass, sub_2, super_klass, sup_2);
   check_klass_subtype_slow_path(sub_2, sup_2,
                                 L2, L3, L4, L5,
                                 NULL, &L_pop_to_failure);
 
   // on success:
+  bind(L_pop_to_success);
   restore();
   ba_short(L_success);
 
@@ -3234,54 +3283,6 @@
 }
 
 
-void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
-                                              Register temp_reg,
-                                              Label& wrong_method_type) {
-  assert_different_registers(mtype_reg, mh_reg, temp_reg);
-  // compare method type against that of the receiver
-  RegisterOrConstant mhtype_offset = delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg);
-  load_heap_oop(mh_reg, mhtype_offset, temp_reg);
-  cmp_and_brx_short(temp_reg, mtype_reg, Assembler::notEqual, Assembler::pn, wrong_method_type);
-}
-
-
-// A method handle has a "vmslots" field which gives the size of its
-// argument list in JVM stack slots.  This field is either located directly
-// in every method handle, or else is indirectly accessed through the
-// method handle's MethodType.  This macro hides the distinction.
-void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
-                                                Register temp_reg) {
-  assert_different_registers(vmslots_reg, mh_reg, temp_reg);
-  // load mh.type.form.vmslots
-  Register temp2_reg = vmslots_reg;
-  load_heap_oop(Address(mh_reg,    delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)),      temp2_reg);
-  load_heap_oop(Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)),        temp2_reg);
-  ld(           Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)), vmslots_reg);
-}
-
-
-void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg, bool emit_delayed_nop) {
-  assert(mh_reg == G3_method_handle, "caller must put MH object in G3");
-  assert_different_registers(mh_reg, temp_reg);
-
-  // pick out the interpreted side of the handler
-  // NOTE: vmentry is not an oop!
-  ld_ptr(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes, temp_reg), temp_reg);
-
-  // off we go...
-  ld_ptr(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes(), temp_reg);
-  jmp(temp_reg, 0);
-
-  // for the various stubs which take control at this point,
-  // see MethodHandles::generate_method_handle_stub
-
-  // Some callers can fill the delay slot.
-  if (emit_delayed_nop) {
-    delayed()->nop();
-  }
-}
-
-
 RegisterOrConstant MacroAssembler::argument_offset(RegisterOrConstant arg_slot,
                                                    Register temp_reg,
                                                    int extra_slot_offset) {
@@ -3914,7 +3915,7 @@
     ld_ptr(G2_thread, in_bytes(JavaThread::tlab_start_offset()), t2);
     or3(t1, t2, t3);
     cmp_and_br_short(t1, t2, Assembler::greaterEqual, Assembler::pn, next);
-    stop("assert(top >= start)");
+    STOP("assert(top >= start)");
     should_not_reach_here();
 
     bind(next);
@@ -3922,13 +3923,13 @@
     ld_ptr(G2_thread, in_bytes(JavaThread::tlab_end_offset()), t2);
     or3(t3, t2, t3);
     cmp_and_br_short(t1, t2, Assembler::lessEqual, Assembler::pn, next2);
-    stop("assert(top <= end)");
+    STOP("assert(top <= end)");
     should_not_reach_here();
 
     bind(next2);
     and3(t3, MinObjAlignmentInBytesMask, t3);
     cmp_and_br_short(t3, 0, Assembler::lessEqual, Assembler::pn, ok);
-    stop("assert(aligned)");
+    STOP("assert(aligned)");
     should_not_reach_here();
 
     bind(ok);
@@ -3976,7 +3977,7 @@
       btst(MinObjAlignmentInBytesMask, obj);
       br(Assembler::zero, false, Assembler::pt, L);
       delayed()->nop();
-      stop("eden top is not properly aligned");
+      STOP("eden top is not properly aligned");
       bind(L);
     }
 #endif // ASSERT
@@ -4013,7 +4014,7 @@
       btst(MinObjAlignmentInBytesMask, top_addr);
       br(Assembler::zero, false, Assembler::pt, L);
       delayed()->nop();
-      stop("eden top is not properly aligned");
+      STOP("eden top is not properly aligned");
       bind(L);
     }
 #endif // ASSERT
@@ -4066,7 +4067,7 @@
     btst(MinObjAlignmentInBytesMask, free);
     br(Assembler::zero, false, Assembler::pt, L);
     delayed()->nop();
-    stop("updated TLAB free is not properly aligned");
+    STOP("updated TLAB free is not properly aligned");
     bind(L);
   }
 #endif // ASSERT
@@ -4164,7 +4165,7 @@
     ld_ptr(G2_thread, in_bytes(JavaThread::tlab_size_offset()), t2);
     sll_ptr(t2, LogHeapWordSize, t2);
     cmp_and_br_short(t1, t2, Assembler::equal, Assembler::pt, ok);
-    stop("assert(t1 == tlab_size)");
+    STOP("assert(t1 == tlab_size)");
     should_not_reach_here();
 
     bind(ok);
diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
index 04f8a98..6a3c4c5 100644
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.hpp
@@ -2221,7 +2221,7 @@
   // traps as per trap.h (SPARC ABI?)
 
   void breakpoint_trap();
-  void breakpoint_trap(Condition c, CC cc = icc);
+  void breakpoint_trap(Condition c, CC cc);
   void flush_windows_trap();
   void clean_windows_trap();
   void get_psr_trap();
@@ -2412,9 +2412,6 @@
   static void test();
 #endif
 
-  // convert an incoming arglist to varargs format; put the pointer in d
-  void set_varargs( Argument a, Register d );
-
   int total_frame_size_in_bytes(int extraWords);
 
   // used when extraWords known statically
@@ -2538,6 +2535,11 @@
                                Register temp_reg, Register temp2_reg,
                                Label& no_such_interface);
 
+  // virtual method calling
+  void lookup_virtual_method(Register recv_klass,
+                             RegisterOrConstant vtable_index,
+                             Register method_result);
+
   // Test sub_klass against super_klass, with fast and slow paths.
 
   // The fast path produces a tri-state answer: yes / no / maybe-slow.
@@ -2577,12 +2579,6 @@
                            Label& L_success);
 
   // method handles (JSR 292)
-  void check_method_handle_type(Register mtype_reg, Register mh_reg,
-                                Register temp_reg,
-                                Label& wrong_method_type);
-  void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
-                                  Register temp_reg);
-  void jump_to_method_handle_entry(Register mh_reg, Register temp_reg, bool emit_delayed_nop = true);
   // offset relative to Gargs of argument at tos[arg_slot].
   // (arg_slot == 0 means the last argument, not the first).
   RegisterOrConstant argument_offset(RegisterOrConstant arg_slot,
@@ -2590,7 +2586,7 @@
                                      int extra_slot_offset = 0);
   // Address of Gargs and argument_offset.
   Address            argument_address(RegisterOrConstant arg_slot,
-                                      Register temp_reg,
+                                      Register temp_reg = noreg,
                                       int extra_slot_offset = 0);
 
   // Stack overflow checking
diff --git a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp
index fce5c37..26e8861 100644
--- a/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp
+++ b/hotspot/src/cpu/sparc/vm/assembler_sparc.inline.hpp
@@ -347,7 +347,11 @@
 inline void Assembler::swap(    Register s1, Register s2, Register d) { v9_dep();  emit_long( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | rs2(s2) ); }
 inline void Assembler::swap(    Register s1, int simm13a, Register d) { v9_dep();  emit_data( op(ldst_op) | rd(d) | op3(swap_op3) | rs1(s1) | immed(true) | simm(simm13a, 13)); }
 
-inline void Assembler::swap(    Address& a, Register d, int offset ) { relocate(a.rspec(offset)); swap(  a.base(), a.disp() + offset, d ); }
+inline void Assembler::swap(    Address& a, Register d, int offset ) {
+  relocate(a.rspec(offset));
+  if (a.has_index()) { assert(offset == 0, ""); swap( a.base(), a.index(), d         ); }
+  else               {                          swap( a.base(), a.disp() + offset, d ); }
+}
 
 
 // Use the right loads/stores for the platform
diff --git a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
index c38b82b..b284a3e 100644
--- a/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/c1_CodeStubs_sparc.cpp
@@ -435,85 +435,6 @@
 
 }
 
-void G1UnsafeGetObjSATBBarrierStub::emit_code(LIR_Assembler* ce) {
-  // At this point we know that offset == referent_offset.
-  //
-  // So we might have to emit:
-  //   if (src == null) goto continuation.
-  //
-  // and we definitely have to emit:
-  //   if (klass(src).reference_type == REF_NONE) goto continuation
-  //   if (!marking_active) goto continuation
-  //   if (pre_val == null) goto continuation
-  //   call pre_barrier(pre_val)
-  //   goto continuation
-  //
-  __ bind(_entry);
-
-  assert(src()->is_register(), "sanity");
-  Register src_reg = src()->as_register();
-
-  if (gen_src_check()) {
-    // The original src operand was not a constant.
-    // Generate src == null?
-    if (__ is_in_wdisp16_range(_continuation)) {
-      __ br_null(src_reg, /*annul*/false, Assembler::pt, _continuation);
-    } else {
-      __ cmp(src_reg, G0);
-      __ brx(Assembler::equal, false, Assembler::pt, _continuation);
-    }
-    __ delayed()->nop();
-  }
-
-  // Generate src->_klass->_reference_type() == REF_NONE)?
-  assert(tmp()->is_register(), "sanity");
-  Register tmp_reg = tmp()->as_register();
-
-  __ load_klass(src_reg, tmp_reg);
-
-  Address ref_type_adr(tmp_reg, instanceKlass::reference_type_offset());
-  __ ldub(ref_type_adr, tmp_reg);
-
-  // _reference_type field is of type ReferenceType (enum)
-  assert(REF_NONE == 0, "check this code");
-  __ cmp_zero_and_br(Assembler::equal, tmp_reg, _continuation, /*annul*/false, Assembler::pt);
-  __ delayed()->nop();
-
-  // Is marking active?
-  assert(thread()->is_register(), "precondition");
-  Register thread_reg = thread()->as_pointer_register();
-
-  Address in_progress(thread_reg, in_bytes(JavaThread::satb_mark_queue_offset() +
-                                       PtrQueue::byte_offset_of_active()));
-
-  if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
-    __ ld(in_progress, tmp_reg);
-  } else {
-    assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
-    __ ldsb(in_progress, tmp_reg);
-  }
-
-  __ cmp_zero_and_br(Assembler::equal, tmp_reg, _continuation, /*annul*/false, Assembler::pt);
-  __ delayed()->nop();
-
-  // val == null?
-  assert(val()->is_register(), "Precondition.");
-  Register val_reg = val()->as_register();
-
-  if (__ is_in_wdisp16_range(_continuation)) {
-    __ br_null(val_reg, /*annul*/false, Assembler::pt, _continuation);
-  } else {
-    __ cmp(val_reg, G0);
-    __ brx(Assembler::equal, false, Assembler::pt, _continuation);
-  }
-  __ delayed()->nop();
-
-  __ call(Runtime1::entry_for(Runtime1::Runtime1::g1_pre_barrier_slow_id));
-  __ delayed()->mov(val_reg, G4);
-  __ br(Assembler::always, false, Assembler::pt, _continuation);
-  __ delayed()->nop();
-}
-
 jbyte* G1PostBarrierStub::_byte_map_base = NULL;
 
 jbyte* G1PostBarrierStub::byte_map_base_slow() {
diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
index b2587e4..f48e29d 100644
--- a/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRAssembler_sparc.cpp
@@ -1284,7 +1284,13 @@
 
 Address LIR_Assembler::as_Address(LIR_Address* addr) {
   Register reg = addr->base()->as_register();
-  return Address(reg, addr->disp());
+  LIR_Opr index = addr->index();
+  if (index->is_illegal()) {
+    return Address(reg, addr->disp());
+  } else {
+    assert (addr->disp() == 0, "unsupported address mode");
+    return Address(reg, index->as_pointer_register());
+  }
 }
 
 
@@ -2956,6 +2962,7 @@
 void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
   ciMethod* method = op->profiled_method();
   int bci          = op->profiled_bci();
+  ciMethod* callee = op->profiled_callee();
 
   // Update counter for all call types
   ciMethodData* md = method->method_data_or_null();
@@ -2984,9 +2991,11 @@
 
   Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()) - mdo_offset_bias);
   Bytecodes::Code bc = method->java_code_at_bci(bci);
+  const bool callee_is_static = callee->is_loaded() && callee->is_static();
   // Perform additional virtual call profiling for invokevirtual and
   // invokeinterface bytecodes
   if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
+      !callee_is_static &&  // required for optimized MH invokes
       C1ProfileVirtualCalls) {
     assert(op->recv()->is_single_cpu(), "recv must be allocated");
     Register recv = op->recv()->as_register();
@@ -3403,7 +3412,28 @@
   }
 }
 
+void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) {
+  LIR_Address* addr = src->as_address_ptr();
 
+  assert(data == dest, "swap uses only 2 operands");
+  assert (code == lir_xchg, "no xadd on sparc");
 
+  if (data->type() == T_INT) {
+    __ swap(as_Address(addr), data->as_register());
+  } else if (data->is_oop()) {
+    Register obj = data->as_register();
+    Register narrow = tmp->as_register();
+#ifdef _LP64
+    assert(UseCompressedOops, "swap is 32bit only");
+    __ encode_heap_oop(obj, narrow);
+    __ swap(as_Address(addr), narrow);
+    __ decode_heap_oop(narrow, obj);
+#else
+    __ swap(as_Address(addr), obj);
+#endif
+  } else {
+    ShouldNotReachHere();
+  }
+}
 
 #undef __
diff --git a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
index f07d267..f50dae8 100644
--- a/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/c1_LIRGenerator_sparc.cpp
@@ -644,30 +644,6 @@
 }
 
 
-void LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
-  assert(x->number_of_arguments() == 3, "wrong type");
-  LIRItem obj       (x->argument_at(0), this);  // AtomicLong object
-  LIRItem cmp_value (x->argument_at(1), this);  // value to compare with field
-  LIRItem new_value (x->argument_at(2), this);  // replace field with new_value if it matches cmp_value
-
-  obj.load_item();
-  cmp_value.load_item();
-  new_value.load_item();
-
-  // generate compare-and-swap and produce zero condition if swap occurs
-  int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
-  LIR_Opr addr = FrameMap::O7_opr;
-  __ add(obj.result(), LIR_OprFact::intConst(value_offset), addr);
-  LIR_Opr t1 = FrameMap::G1_opr;  // temp for 64-bit value
-  LIR_Opr t2 = FrameMap::G3_opr;  // temp for 64-bit value
-  __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);
-
-  // 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, T_LONG);
-}
-
-
 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
   assert(x->number_of_arguments() == 4, "wrong type");
   LIRItem obj   (x->argument_at(0), this);  // object
@@ -738,7 +714,8 @@
     case vmIntrinsics::_dlog: // fall through
     case vmIntrinsics::_dsin: // fall through
     case vmIntrinsics::_dtan: // fall through
-    case vmIntrinsics::_dcos: {
+    case vmIntrinsics::_dcos: // fall through
+    case vmIntrinsics::_dexp: {
       assert(x->number_of_arguments() == 1, "wrong type");
 
       address runtime_entry = NULL;
@@ -758,12 +735,23 @@
       case vmIntrinsics::_dlog10:
         runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dlog10);
         break;
+      case vmIntrinsics::_dexp:
+        runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dexp);
+        break;
       default:
         ShouldNotReachHere();
       }
 
       LIR_Opr result = call_runtime(x->argument_at(0), runtime_entry, x->type(), NULL);
       set_result(x, result);
+      break;
+    }
+    case vmIntrinsics::_dpow: {
+      assert(x->number_of_arguments() == 2, "wrong type");
+      address runtime_entry = CAST_FROM_FN_PTR(address, SharedRuntime::dpow);
+      LIR_Opr result = call_runtime(x->argument_at(0), x->argument_at(1), runtime_entry, x->type(), NULL);
+      set_result(x, result);
+      break;
     }
   }
 }
@@ -1215,3 +1203,58 @@
     __ load(addr, dst);
   }
 }
+
+void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
+  BasicType type = x->basic_type();
+  LIRItem src(x->object(), this);
+  LIRItem off(x->offset(), this);
+  LIRItem value(x->value(), this);
+
+  src.load_item();
+  value.load_item();
+  off.load_nonconstant();
+
+  LIR_Opr dst = rlock_result(x, type);
+  LIR_Opr data = value.result();
+  bool is_obj = (type == T_ARRAY || type == T_OBJECT);
+  LIR_Opr offset = off.result();
+
+  if (data != dst) {
+    __ move(data, dst);
+    data = dst;
+  }
+
+  assert (!x->is_add() && (type == T_INT || (is_obj LP64_ONLY(&& UseCompressedOops))), "unexpected type");
+  LIR_Address* addr;
+  if (offset->is_constant()) {
+
+#ifdef _LP64
+    jlong l = offset->as_jlong();
+    assert((jlong)((jint)l) == l, "offset too large for constant");
+    jint c = (jint)l;
+#else
+    jint c = offset->as_jint();
+#endif
+    addr = new LIR_Address(src.result(), c, type);
+  } else {
+    addr = new LIR_Address(src.result(), offset, type);
+  }
+
+  LIR_Opr tmp = LIR_OprFact::illegalOpr;
+  LIR_Opr ptr = LIR_OprFact::illegalOpr;
+
+  if (is_obj) {
+    // Do the pre-write barrier, if any.
+    // barriers on sparc don't work with a base + index address
+    tmp = FrameMap::G3_opr;
+    ptr = new_pointer_register();
+    __ add(src.result(), off.result(), ptr);
+    pre_barrier(ptr, LIR_OprFact::illegalOpr /* pre_val */,
+                true /* do_load */, false /* patch */, NULL);
+  }
+  __ xchg(LIR_OprFact::address(addr), data, dst, tmp);
+  if (is_obj) {
+    // Seems to be a precise address
+    post_barrier(ptr, data);
+  }
+}
diff --git a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
index f402d62..240b382 100644
--- a/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/cppInterpreter_sparc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, 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
@@ -490,7 +490,8 @@
                       ConstantPoolCacheEntry::size()) * BytesPerWord), G1_scratch);
 
     // get constant pool cache
-    __ ld_ptr(G5_method, in_bytes(methodOopDesc::constants_offset()), G3_scratch);
+    __ ld_ptr(G5_method, in_bytes(methodOopDesc::const_offset()), G3_scratch);
+    __ ld_ptr(G3_scratch, in_bytes(constMethodOopDesc::constants_offset()), G3_scratch);
     __ ld_ptr(G3_scratch, constantPoolOopDesc::cache_offset_in_bytes(), G3_scratch);
 
     // get specific constant pool cache entry
@@ -514,9 +515,9 @@
     // Need to differentiate between igetfield, agetfield, bgetfield etc.
     // because they are different sizes.
     // Get the type from the constant pool cache
-    __ srl(G1_scratch, ConstantPoolCacheEntry::tosBits, G1_scratch);
-    // Make sure we don't need to mask G1_scratch for tosBits after the above shift
-    ConstantPoolCacheEntry::verify_tosBits();
+    __ srl(G1_scratch, ConstantPoolCacheEntry::tos_state_shift, G1_scratch);
+    // Make sure we don't need to mask G1_scratch after the above shift
+    ConstantPoolCacheEntry::verify_tos_state_shift();
     __ cmp(G1_scratch, atos );
     __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
     __ delayed()->ld_ptr(Otos_i, G3_scratch, Otos_i);
@@ -768,7 +769,8 @@
     // for static methods insert the mirror argument
     const int mirror_offset = in_bytes(Klass::java_mirror_offset());
 
-    __ ld_ptr(Address(G5_method, 0, in_bytes(methodOopDesc:: constants_offset())), O1);
+    __ ld_ptr(Address(G5_method, 0, in_bytes(methodOopDesc:: const_offset())), O1);
+    __ ld_ptr(Address(O1, 0, in_bytes(constMethodOopDesc::constants_offset())), O1);
     __ ld_ptr(Address(O1, 0, constantPoolOopDesc::pool_holder_offset_in_bytes()), O1);
     __ ld_ptr(O1, mirror_offset, O1);
     // where the mirror handle body is allocated:
@@ -1047,7 +1049,7 @@
   assert_different_registers(state, prev_state);
   assert_different_registers(prev_state, G3_scratch);
   const Register Gtmp = G3_scratch;
-  const Address constants         (G5_method, 0, in_bytes(methodOopDesc::constants_offset()));
+  const Address constMethod       (G5_method, 0, in_bytes(methodOopDesc::const_offset()));
   const Address access_flags      (G5_method, 0, in_bytes(methodOopDesc::access_flags_offset()));
   const Address size_of_parameters(G5_method, 0, in_bytes(methodOopDesc::size_of_parameters_offset()));
   const Address max_stack         (G5_method, 0, in_bytes(methodOopDesc::max_stack_offset()));
@@ -1155,7 +1157,8 @@
   __ set((int) BytecodeInterpreter::method_entry, O1);
   __ st(O1, XXX_STATE(_msg));
 
-  __ ld_ptr(constants, O3);
+  __ ld_ptr(constMethod, O3);
+  __ ld_ptr(O3, in_bytes(constMethodOopDesc::constants_offset()), O3);
   __ ld_ptr(O3, constantPoolOopDesc::cache_offset_in_bytes(), O2);
   __ st_ptr(O2, XXX_STATE(_constants));
 
@@ -1178,7 +1181,8 @@
     __ ld_ptr(XXX_STATE(_locals), O1);
     __ br( Assembler::zero, true, Assembler::pt, got_obj);
     __ delayed()->ld_ptr(O1, 0, O1);                  // get receiver for not-static case
-    __ ld_ptr(constants, O1);
+    __ ld_ptr(constMethod, O1);
+    __ ld_ptr( O1, in_bytes(constMethodOopDesc::constants_offset()), O1);
     __ ld_ptr( O1, constantPoolOopDesc::pool_holder_offset_in_bytes(), O1);
     // lock the mirror, not the klassOop
     __ ld_ptr( O1, mirror_offset, O1);
@@ -1187,7 +1191,7 @@
 
   #ifdef ASSERT
     __ tst(O1);
-    __ breakpoint_trap(Assembler::zero);
+    __ breakpoint_trap(Assembler::zero, Assembler::ptr_cc);
   #endif // ASSERT
 
     const int entry_size            = frame::interpreter_frame_monitor_size() * wordSize;
@@ -1536,7 +1540,7 @@
   const Register Gtmp1 = G3_scratch;
   // const Register Lmirror = L1;     // native mirror (native calls only)
 
-  const Address constants         (G5_method, 0, in_bytes(methodOopDesc::constants_offset()));
+  const Address constMethod       (G5_method, 0, in_bytes(methodOopDesc::const_offset()));
   const Address access_flags      (G5_method, 0, in_bytes(methodOopDesc::access_flags_offset()));
   const Address size_of_parameters(G5_method, 0, in_bytes(methodOopDesc::size_of_parameters_offset()));
   const Address max_stack         (G5_method, 0, in_bytes(methodOopDesc::max_stack_offset()));
diff --git a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp
index 1acc457..d56d0d4 100644
--- a/hotspot/src/cpu/sparc/vm/frame_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/frame_sparc.cpp
@@ -514,7 +514,6 @@
   // interpreted but its pc is in the code cache (for c1 -> osr_frame_return_id stub), so it must be
   // explicitly recognized.
 
-  if (is_ricochet_frame())    return sender_for_ricochet_frame(map);
 
   bool frame_is_interpreted = is_interpreted_frame();
   if (frame_is_interpreted) {
@@ -821,9 +820,7 @@
     values.describe(frame_no, sp() + w, err_msg("register save area word %d", w), 1);
   }
 
-  if (is_ricochet_frame()) {
-    MethodHandles::RicochetFrame::describe(this, values, frame_no);
-  } else if (is_interpreted_frame()) {
+  if (is_interpreted_frame()) {
     DESCRIBE_FP_OFFSET(interpreter_frame_d_scratch_fp);
     DESCRIBE_FP_OFFSET(interpreter_frame_l_scratch_fp);
     DESCRIBE_FP_OFFSET(interpreter_frame_padding);
diff --git a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
index dca0441..ee330c6 100644
--- a/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/globals_sparc.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,4 +75,43 @@
 
 // GC Ergo Flags
 define_pd_global(intx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
+
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
+                                                                            \
+  product(intx, UseVIS, 99,                                                 \
+          "Highest supported VIS instructions set on Sparc")                \
+                                                                            \
+  product(bool, UseCBCond, false,                                           \
+          "Use compare and branch instruction on SPARC")                    \
+                                                                            \
+  product(bool, UseBlockZeroing, false,                                     \
+          "Use special cpu instructions for block zeroing")                 \
+                                                                            \
+  product(intx, BlockZeroingLowLimit, 2048,                                 \
+          "Minimum size in bytes when block zeroing will be used")          \
+                                                                            \
+  product(bool, UseBlockCopy, false,                                        \
+          "Use special cpu instructions for block copy")                    \
+                                                                            \
+  product(intx, BlockCopyLowLimit, 2048,                                    \
+          "Minimum size in bytes when block copy will be used")             \
+                                                                            \
+  develop(bool, UseV8InstrsOnly, false,                                     \
+          "Use SPARC-V8 Compliant instruction subset")                      \
+                                                                            \
+  product(bool, UseNiagaraInstrs, false,                                    \
+          "Use Niagara-efficient instruction subset")                       \
+                                                                            \
+  develop(bool, UseCASForSwap, false,                                       \
+          "Do not use swap instructions, but only CAS (in a loop) on SPARC")\
+                                                                            \
+  product(uintx,  ArraycopySrcPrefetchDistance, 0,                          \
+          "Distance to prefetch source array in arracopy")                  \
+                                                                            \
+  product(uintx,  ArraycopyDstPrefetchDistance, 0,                          \
+          "Distance to prefetch destination array in arracopy")             \
+                                                                            \
+  develop(intx, V8AtomicOperationUnderLockSpinCount,    50,                 \
+          "Number of times to spin wait on a v8 atomic operation lock")     \
+
 #endif // CPU_SPARC_VM_GLOBALS_SPARC_HPP
diff --git a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
index 8e3b919..63f1eb2 100644
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -505,7 +505,7 @@
 void InterpreterMacroAssembler::load_receiver(Register param_count,
                                               Register recv) {
   sll(param_count, Interpreter::logStackElementSize, param_count);
-  ld_ptr(Lesp, param_count, recv);                      // gets receiver Oop
+  ld_ptr(Lesp, param_count, recv);  // gets receiver oop
 }
 
 void InterpreterMacroAssembler::empty_expression_stack() {
@@ -767,8 +767,12 @@
   get_cache_and_index_at_bcp(cache, temp, bcp_offset, index_size);
   ld_ptr(cache, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset(), bytecode);
   const int shift_count = (1 + byte_no) * BitsPerByte;
-  srl( bytecode, shift_count, bytecode);
-  and3(bytecode,        0xFF, bytecode);
+  assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) ||
+         (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift),
+         "correct shift count");
+  srl(bytecode, shift_count, bytecode);
+  assert(ConstantPoolCacheEntry::bytecode_1_mask == ConstantPoolCacheEntry::bytecode_2_mask, "common mask");
+  and3(bytecode, ConstantPoolCacheEntry::bytecode_1_mask, bytecode);
 }
 
 
@@ -934,8 +938,14 @@
 }
 
 
+void InterpreterMacroAssembler::get_const(Register Rdst) {
+  ld_ptr(Lmethod, in_bytes(methodOopDesc::const_offset()), Rdst);
+}
+
+
 void InterpreterMacroAssembler::get_constant_pool(Register Rdst) {
-  ld_ptr(Lmethod, in_bytes(methodOopDesc::constants_offset()), Rdst);
+  get_const(Rdst);
+  ld_ptr(Rdst, in_bytes(constMethodOopDesc::constants_offset()), Rdst);
 }
 
 
@@ -1369,12 +1379,17 @@
   AddressLiteral profile_limit((address) &InvocationCounter::InterpreterProfileLimit);
   sethi(profile_limit, Rtmp);
   ld(Rtmp, profile_limit.low10(), Rtmp);
-  cmp_and_br_short(invocation_count, Rtmp, Assembler::lessUnsigned, Assembler::pn, profile_continue);
+  cmp(invocation_count, Rtmp);
+  // Use long branches because call_VM() code and following code generated by
+  // test_backedge_count_for_osr() is large in debug VM.
+  br(Assembler::lessUnsigned, false, Assembler::pn, profile_continue);
+  delayed()->nop();
 
   // Build it now.
   call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
   set_method_data_pointer_for_bcp();
-  ba_short(profile_continue);
+  ba(profile_continue);
+  delayed()->nop();
   bind(done);
 }
 
diff --git a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp
index 8e05e9a..4732bf0a 100644
--- a/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/interp_masm_sparc.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -205,6 +205,7 @@
   void index_check(Register array, Register index, int index_shift, Register tmp, Register res);
   void index_check_without_pop(Register array, Register index, int index_shift, Register tmp, Register res);
 
+  void get_const(Register Rdst);
   void get_constant_pool(Register Rdst);
   void get_constant_pool_cache(Register Rdst);
   void get_cpool_and_tags(Register Rcpool, Register Rtags);
diff --git a/hotspot/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp b/hotspot/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp
index 2cca1e5..2f9fac8 100644
--- a/hotspot/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/interpreterGenerator_sparc.hpp
@@ -32,7 +32,6 @@
   address generate_normal_entry(bool synchronized);
   address generate_native_entry(bool synchronized);
   address generate_abstract_entry(void);
-  address generate_method_handle_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
   address generate_empty_entry(void);
   address generate_accessor_entry(void);
diff --git a/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp
index 5471ebc..cdd493a 100644
--- a/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/interpreter_sparc.cpp
@@ -255,17 +255,6 @@
 }
 
 
-// Method handle invoker
-// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
-address InterpreterGenerator::generate_method_handle_entry(void) {
-  if (!EnableInvokeDynamic) {
-    return generate_abstract_entry();
-  }
-
-  return MethodHandles::generate_method_handle_interpreter_entry(_masm);
-}
-
-
 //----------------------------------------------------------------------------------------------------
 // Entry points & stack frame layout
 //
@@ -395,7 +384,7 @@
     case Interpreter::empty                  : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry();        break;
     case Interpreter::accessor               : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry();     break;
     case Interpreter::abstract               : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry();     break;
-    case Interpreter::method_handle          : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break;
+
     case Interpreter::java_lang_math_sin     :                                                                             break;
     case Interpreter::java_lang_math_cos     :                                                                             break;
     case Interpreter::java_lang_math_tan     :                                                                             break;
@@ -403,9 +392,13 @@
     case Interpreter::java_lang_math_abs     :                                                                             break;
     case Interpreter::java_lang_math_log     :                                                                             break;
     case Interpreter::java_lang_math_log10   :                                                                             break;
+    case Interpreter::java_lang_math_pow     :                                                                             break;
+    case Interpreter::java_lang_math_exp     :                                                                             break;
     case Interpreter::java_lang_ref_reference_get
                                              : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
-    default                                  : ShouldNotReachHere();                                                       break;
+    default:
+      fatal(err_msg("unexpected method kind: %d", kind));
+      break;
   }
 
   if (entry_point) return entry_point;
diff --git a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp
index 7c0d86c..9cf61ab 100644
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.cpp
@@ -31,452 +31,37 @@
 
 #ifdef PRODUCT
 #define BLOCK_COMMENT(str) /* nothing */
+#define STOP(error) stop(error)
 #else
 #define BLOCK_COMMENT(str) __ block_comment(str)
+#define STOP(error) block_comment(error); __ stop(error)
 #endif
 
 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
 
-address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
-                                                address interpreted_entry) {
-  // Just before the actual machine code entry point, allocate space
-  // for a MethodHandleEntry::Data record, so that we can manage everything
-  // from one base pointer.
-  __ align(wordSize);
-  address target = __ pc() + sizeof(Data);
-  while (__ pc() < target) {
-    __ nop();
-    __ align(wordSize);
-  }
-
-  MethodHandleEntry* me = (MethodHandleEntry*) __ pc();
-  me->set_end_address(__ pc());         // set a temporary end_address
-  me->set_from_interpreted_entry(interpreted_entry);
-  me->set_type_checking_entry(NULL);
-
-  return (address) me;
+// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
+static RegisterOrConstant constant(int value) {
+  return RegisterOrConstant(value);
 }
 
-MethodHandleEntry* MethodHandleEntry::finish_compiled_entry(MacroAssembler* _masm,
-                                                address start_addr) {
-  MethodHandleEntry* me = (MethodHandleEntry*) start_addr;
-  assert(me->end_address() == start_addr, "valid ME");
-
-  // Fill in the real end_address:
-  __ align(wordSize);
-  me->set_end_address(__ pc());
-
-  return me;
-}
-
-// stack walking support
-
-frame MethodHandles::ricochet_frame_sender(const frame& fr, RegisterMap *map) {
-  //RicochetFrame* f = RicochetFrame::from_frame(fr);
-  // Cf. is_interpreted_frame path of frame::sender
-  intptr_t* younger_sp = fr.sp();
-  intptr_t* sp         = fr.sender_sp();
-  map->make_integer_regs_unsaved();
-  map->shift_window(sp, younger_sp);
-  bool this_frame_adjusted_stack = true;  // I5_savedSP is live in this RF
-  return frame(sp, younger_sp, this_frame_adjusted_stack);
-}
-
-void MethodHandles::ricochet_frame_oops_do(const frame& fr, OopClosure* blk, const RegisterMap* reg_map) {
-  ResourceMark rm;
-  RicochetFrame* f = RicochetFrame::from_frame(fr);
-
-  // pick up the argument type descriptor:
-  Thread* thread = Thread::current();
-  Handle cookie(thread, f->compute_saved_args_layout(true, true));
-
-  // process fixed part
-  blk->do_oop((oop*)f->saved_target_addr());
-  blk->do_oop((oop*)f->saved_args_layout_addr());
-
-  // process variable arguments:
-  if (cookie.is_null())  return;  // no arguments to describe
-
-  // the cookie is actually the invokeExact method for my target
-  // his argument signature is what I'm interested in
-  assert(cookie->is_method(), "");
-  methodHandle invoker(thread, methodOop(cookie()));
-  assert(invoker->name() == vmSymbols::invokeExact_name(), "must be this kind of method");
-  assert(!invoker->is_static(), "must have MH argument");
-  int slot_count = invoker->size_of_parameters();
-  assert(slot_count >= 1, "must include 'this'");
-  intptr_t* base = f->saved_args_base();
-  intptr_t* retval = NULL;
-  if (f->has_return_value_slot())
-    retval = f->return_value_slot_addr();
-  int slot_num = slot_count - 1;
-  intptr_t* loc = &base[slot_num];
-  //blk->do_oop((oop*) loc);   // original target, which is irrelevant
-  int arg_num = 0;
-  for (SignatureStream ss(invoker->signature()); !ss.is_done(); ss.next()) {
-    if (ss.at_return_type())  continue;
-    BasicType ptype = ss.type();
-    if (ptype == T_ARRAY)  ptype = T_OBJECT; // fold all refs to T_OBJECT
-    assert(ptype >= T_BOOLEAN && ptype <= T_OBJECT, "not array or void");
-    slot_num -= type2size[ptype];
-    loc = &base[slot_num];
-    bool is_oop = (ptype == T_OBJECT && loc != retval);
-    if (is_oop)  blk->do_oop((oop*)loc);
-    arg_num += 1;
-  }
-  assert(slot_num == 0, "must have processed all the arguments");
-}
-
-// Ricochet Frames
-const Register MethodHandles::RicochetFrame::L1_continuation      = L1;
-const Register MethodHandles::RicochetFrame::L2_saved_target      = L2;
-const Register MethodHandles::RicochetFrame::L3_saved_args_layout = L3;
-const Register MethodHandles::RicochetFrame::L4_saved_args_base   = L4; // cf. Gargs = G4
-const Register MethodHandles::RicochetFrame::L5_conversion        = L5;
-#ifdef ASSERT
-const Register MethodHandles::RicochetFrame::L0_magic_number_1    = L0;
-#endif //ASSERT
-
-oop MethodHandles::RicochetFrame::compute_saved_args_layout(bool read_cache, bool write_cache) {
-  if (read_cache) {
-    oop cookie = saved_args_layout();
-    if (cookie != NULL)  return cookie;
-  }
-  oop target = saved_target();
-  oop mtype  = java_lang_invoke_MethodHandle::type(target);
-  oop mtform = java_lang_invoke_MethodType::form(mtype);
-  oop cookie = java_lang_invoke_MethodTypeForm::vmlayout(mtform);
-  if (write_cache)  {
-    (*saved_args_layout_addr()) = cookie;
-  }
-  return cookie;
-}
-
-void MethodHandles::RicochetFrame::generate_ricochet_blob(MacroAssembler* _masm,
-                                                          // output params:
-                                                          int* bounce_offset,
-                                                          int* exception_offset,
-                                                          int* frame_size_in_words) {
-  (*frame_size_in_words) = RicochetFrame::frame_size_in_bytes() / wordSize;
-
-  address start = __ pc();
-
-#ifdef ASSERT
-  __ illtrap(0); __ illtrap(0); __ illtrap(0);
-  // here's a hint of something special:
-  __ set(MAGIC_NUMBER_1, G0);
-  __ set(MAGIC_NUMBER_2, G0);
-#endif //ASSERT
-  __ illtrap(0);  // not reached
-
-  // Return values are in registers.
-  // L1_continuation contains a cleanup continuation we must return
-  // to.
-
-  (*bounce_offset) = __ pc() - start;
-  BLOCK_COMMENT("ricochet_blob.bounce");
-
-  if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
-  trace_method_handle(_masm, "return/ricochet_blob.bounce");
-
-  __ JMP(L1_continuation, 0);
-  __ delayed()->nop();
-  __ illtrap(0);
-
-  DEBUG_ONLY(__ set(MAGIC_NUMBER_2, G0));
-
-  (*exception_offset) = __ pc() - start;
-  BLOCK_COMMENT("ricochet_blob.exception");
-
-  // compare this to Interpreter::rethrow_exception_entry, which is parallel code
-  // for example, see TemplateInterpreterGenerator::generate_throw_exception
-  // Live registers in:
-  //   Oexception  (O0): exception
-  //   Oissuing_pc (O1): return address/pc that threw exception (ignored, always equal to bounce addr)
-  __ verify_oop(Oexception);
-
-  // Take down the frame.
-
-  // Cf. InterpreterMacroAssembler::remove_activation.
-  leave_ricochet_frame(_masm, /*recv_reg=*/ noreg, I5_savedSP, I7);
-
-  // We are done with this activation frame; find out where to go next.
-  // The continuation point will be an exception handler, which expects
-  // the following registers set up:
-  //
-  // Oexception: exception
-  // Oissuing_pc: the local call that threw exception
-  // Other On: garbage
-  // In/Ln:  the contents of the caller's register window
-  //
-  // We do the required restore at the last possible moment, because we
-  // need to preserve some state across a runtime call.
-  // (Remember that the caller activation is unknown--it might not be
-  // interpreted, so things like Lscratch are useless in the caller.)
-  __ mov(Oexception,  Oexception ->after_save());  // get exception in I0 so it will be on O0 after restore
-  __ add(I7, frame::pc_return_offset, Oissuing_pc->after_save());  // likewise set I1 to a value local to the caller
-  __ call_VM_leaf(L7_thread_cache,
-                  CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address),
-                  G2_thread, Oissuing_pc->after_save());
-
-  // The caller's SP was adjusted upon method entry to accomodate
-  // the callee's non-argument locals. Undo that adjustment.
-  __ JMP(O0, 0);                         // return exception handler in caller
-  __ delayed()->restore(I5_savedSP, G0, SP);
-
-  // (same old exception object is already in Oexception; see above)
-  // Note that an "issuing PC" is actually the next PC after the call
-}
-
-void MethodHandles::RicochetFrame::enter_ricochet_frame(MacroAssembler* _masm,
-                                                        Register recv_reg,
-                                                        Register argv_reg,
-                                                        address return_handler) {
-  // does not include the __ save()
-  assert(argv_reg == Gargs, "");
-  Address G3_mh_vmtarget(   recv_reg, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes());
-  Address G3_amh_conversion(recv_reg, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes());
-
-  // Create the RicochetFrame.
-  // Unlike on x86 we can store all required information in local
-  // registers.
-  BLOCK_COMMENT("push RicochetFrame {");
-  __ set(ExternalAddress(return_handler),          L1_continuation);
-  __ load_heap_oop(G3_mh_vmtarget,                 L2_saved_target);
-  __ mov(G0,                                       L3_saved_args_layout);
-  __ mov(Gargs,                                    L4_saved_args_base);
-  __ lduw(G3_amh_conversion,                       L5_conversion);  // 32-bit field
-  // I5, I6, I7 are already set up
-  DEBUG_ONLY(__ set((int32_t) MAGIC_NUMBER_1,      L0_magic_number_1));
-  BLOCK_COMMENT("} RicochetFrame");
-}
-
-void MethodHandles::RicochetFrame::leave_ricochet_frame(MacroAssembler* _masm,
-                                                        Register recv_reg,
-                                                        Register new_sp_reg,
-                                                        Register sender_pc_reg) {
-  assert(new_sp_reg == I5_savedSP, "exact_sender_sp already in place");
-  assert(sender_pc_reg == I7, "in a fixed place");
-  // does not include the __ ret() & __ restore()
-  assert_different_registers(recv_reg, new_sp_reg, sender_pc_reg);
-  // Take down the frame.
-  // Cf. InterpreterMacroAssembler::remove_activation.
-  BLOCK_COMMENT("end_ricochet_frame {");
-  if (recv_reg->is_valid())
-    __ mov(L2_saved_target, recv_reg);
-  BLOCK_COMMENT("} end_ricochet_frame");
-}
-
-// Emit code to verify that FP is pointing at a valid ricochet frame.
-#ifndef PRODUCT
-enum {
-  ARG_LIMIT = 255, SLOP = 45,
-  // use this parameter for checking for garbage stack movements:
-  UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
-  // the slop defends against false alarms due to fencepost errors
-};
-#endif
-
-#ifdef ASSERT
-void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
-  // The stack should look like this:
-  //    ... keep1 | dest=42 | keep2 | magic | handler | magic | recursive args | [RF]
-  // Check various invariants.
-
-  Register O7_temp = O7, O5_temp = O5;
-
-  Label L_ok_1, L_ok_2, L_ok_3, L_ok_4;
-  BLOCK_COMMENT("verify_clean {");
-  // Magic numbers must check out:
-  __ set((int32_t) MAGIC_NUMBER_1, O7_temp);
-  __ cmp_and_br_short(O7_temp, L0_magic_number_1, Assembler::equal, Assembler::pt, L_ok_1);
-  __ stop("damaged ricochet frame: MAGIC_NUMBER_1 not found");
-
-  __ BIND(L_ok_1);
-
-  // Arguments pointer must look reasonable:
-#ifdef _LP64
-  Register FP_temp = O5_temp;
-  __ add(FP, STACK_BIAS, FP_temp);
-#else
-  Register FP_temp = FP;
-#endif
-  __ cmp_and_brx_short(L4_saved_args_base, FP_temp, Assembler::greaterEqualUnsigned, Assembler::pt, L_ok_2);
-  __ stop("damaged ricochet frame: L4 < FP");
-
-  __ BIND(L_ok_2);
-  // Disable until we decide on it's fate
-  // __ sub(L4_saved_args_base, UNREASONABLE_STACK_MOVE * Interpreter::stackElementSize, O7_temp);
-  // __ cmp(O7_temp, FP_temp);
-  // __ br(Assembler::lessEqualUnsigned, false, Assembler::pt, L_ok_3);
-  // __ delayed()->nop();
-  // __ stop("damaged ricochet frame: (L4 - UNREASONABLE_STACK_MOVE) > FP");
-
-  __ BIND(L_ok_3);
-  extract_conversion_dest_type(_masm, L5_conversion, O7_temp);
-  __ cmp_and_br_short(O7_temp, T_VOID, Assembler::equal, Assembler::pt, L_ok_4);
-  extract_conversion_vminfo(_masm, L5_conversion, O5_temp);
-  __ ld_ptr(L4_saved_args_base, __ argument_offset(O5_temp, O5_temp), O7_temp);
-  assert(Assembler::is_simm13(RETURN_VALUE_PLACEHOLDER), "must be simm13");
-  __ cmp_and_brx_short(O7_temp, (int32_t) RETURN_VALUE_PLACEHOLDER, Assembler::equal, Assembler::pt, L_ok_4);
-  __ stop("damaged ricochet frame: RETURN_VALUE_PLACEHOLDER not found");
-  __ BIND(L_ok_4);
-  BLOCK_COMMENT("} verify_clean");
-}
-#endif //ASSERT
-
 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg) {
   if (VerifyMethodHandles)
     verify_klass(_masm, klass_reg, SystemDictionaryHandles::Class_klass(), temp_reg, temp2_reg,
-                 "AMH argument is a Class");
+                 "MH argument is a Class");
   __ load_heap_oop(Address(klass_reg, java_lang_Class::klass_offset_in_bytes()), klass_reg);
 }
 
-void MethodHandles::load_conversion_vminfo(MacroAssembler* _masm, Address conversion_field_addr, Register reg) {
-  assert(CONV_VMINFO_SHIFT == 0, "preshifted");
-  assert(CONV_VMINFO_MASK == right_n_bits(BitsPerByte), "else change type of following load");
-  __ ldub(conversion_field_addr.plus_disp(BytesPerInt - 1), reg);
-}
-
-void MethodHandles::extract_conversion_vminfo(MacroAssembler* _masm, Register conversion_field_reg, Register reg) {
-  assert(CONV_VMINFO_SHIFT == 0, "preshifted");
-  __ and3(conversion_field_reg, CONV_VMINFO_MASK, reg);
-}
-
-void MethodHandles::extract_conversion_dest_type(MacroAssembler* _masm, Register conversion_field_reg, Register reg) {
-  __ srl(conversion_field_reg, CONV_DEST_TYPE_SHIFT, reg);
-  __ and3(reg, 0x0F, reg);
-}
-
-void MethodHandles::load_stack_move(MacroAssembler* _masm,
-                                    Address G3_amh_conversion,
-                                    Register stack_move_reg) {
-  BLOCK_COMMENT("load_stack_move {");
-  __ ldsw(G3_amh_conversion, stack_move_reg);
-  __ sra(stack_move_reg, CONV_STACK_MOVE_SHIFT, stack_move_reg);
 #ifdef ASSERT
-  if (VerifyMethodHandles) {
-    Label L_ok, L_bad;
-    int32_t stack_move_limit = 0x0800;  // extra-large
-    __ cmp_and_br_short(stack_move_reg, stack_move_limit, Assembler::greaterEqual, Assembler::pn, L_bad);
-    __ cmp(stack_move_reg, -stack_move_limit);
-    __ br(Assembler::greater, false, Assembler::pt, L_ok);
-    __ delayed()->nop();
-    __ BIND(L_bad);
-    __ stop("load_stack_move of garbage value");
-    __ BIND(L_ok);
-  }
-#endif
-  BLOCK_COMMENT("} load_stack_move");
+static int check_nonzero(const char* xname, int x) {
+  assert(x != 0, err_msg("%s should be nonzero", xname));
+  return x;
 }
+#define NONZERO(x) check_nonzero(#x, x)
+#else //ASSERT
+#define NONZERO(x) (x)
+#endif //ASSERT
 
 #ifdef ASSERT
-void MethodHandles::RicochetFrame::verify() const {
-  assert(magic_number_1() == MAGIC_NUMBER_1, "");
-  if (!Universe::heap()->is_gc_active()) {
-    if (saved_args_layout() != NULL) {
-      assert(saved_args_layout()->is_method(), "must be valid oop");
-    }
-    if (saved_target() != NULL) {
-      assert(java_lang_invoke_MethodHandle::is_instance(saved_target()), "checking frame value");
-    }
-  }
-  int conv_op = adapter_conversion_op(conversion());
-  assert(conv_op == java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS ||
-         conv_op == java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS ||
-         conv_op == java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF,
-         "must be a sane conversion");
-  if (has_return_value_slot()) {
-    assert(*return_value_slot_addr() == RETURN_VALUE_PLACEHOLDER, "");
-  }
-}
-
-void MethodHandles::verify_argslot(MacroAssembler* _masm, Register argslot_reg, Register temp_reg, const char* error_message) {
-  // Verify that argslot lies within (Gargs, FP].
-  Label L_ok, L_bad;
-  BLOCK_COMMENT("verify_argslot {");
-  __ cmp_and_brx_short(Gargs, argslot_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad);
-  __ add(FP, STACK_BIAS, temp_reg);  // STACK_BIAS is zero on !_LP64
-  __ cmp_and_brx_short(argslot_reg, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok);
-  __ BIND(L_bad);
-  __ stop(error_message);
-  __ BIND(L_ok);
-  BLOCK_COMMENT("} verify_argslot");
-}
-
-void MethodHandles::verify_argslots(MacroAssembler* _masm,
-                                    RegisterOrConstant arg_slots,
-                                    Register arg_slot_base_reg,
-                                    Register temp_reg,
-                                    Register temp2_reg,
-                                    bool negate_argslots,
-                                    const char* error_message) {
-  // Verify that [argslot..argslot+size) lies within (Gargs, FP).
-  Label L_ok, L_bad;
-  BLOCK_COMMENT("verify_argslots {");
-  if (negate_argslots) {
-    if (arg_slots.is_constant()) {
-      arg_slots = -1 * arg_slots.as_constant();
-    } else {
-      __ neg(arg_slots.as_register(), temp_reg);
-      arg_slots = temp_reg;
-    }
-  }
-  __ add(arg_slot_base_reg, __ argument_offset(arg_slots, temp_reg), temp_reg);
-  __ add(FP, STACK_BIAS, temp2_reg);  // STACK_BIAS is zero on !_LP64
-  __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::greaterUnsigned, Assembler::pn, L_bad);
-  // Gargs points to the first word so adjust by BytesPerWord
-  __ add(arg_slot_base_reg, BytesPerWord, temp_reg);
-  __ cmp_and_brx_short(Gargs, temp_reg, Assembler::lessEqualUnsigned, Assembler::pt, L_ok);
-  __ BIND(L_bad);
-  __ stop(error_message);
-  __ BIND(L_ok);
-  BLOCK_COMMENT("} verify_argslots");
-}
-
-// Make sure that arg_slots has the same sign as the given direction.
-// If (and only if) arg_slots is a assembly-time constant, also allow it to be zero.
-void MethodHandles::verify_stack_move(MacroAssembler* _masm,
-                                      RegisterOrConstant arg_slots, int direction) {
-  enum { UNREASONABLE_STACK_MOVE = 256 * 4 };  // limit of 255 arguments
-  bool allow_zero = arg_slots.is_constant();
-  if (direction == 0) { direction = +1; allow_zero = true; }
-  assert(stack_move_unit() == -1, "else add extra checks here");
-  if (arg_slots.is_register()) {
-    Label L_ok, L_bad;
-    BLOCK_COMMENT("verify_stack_move {");
-    // __ btst(-stack_move_unit() - 1, arg_slots.as_register());  // no need
-    // __ br(Assembler::notZero, false, Assembler::pn, L_bad);
-    // __ delayed()->nop();
-    __ cmp(arg_slots.as_register(), (int32_t) NULL_WORD);
-    if (direction > 0) {
-      __ br(allow_zero ? Assembler::less : Assembler::lessEqual, false, Assembler::pn, L_bad);
-      __ delayed()->nop();
-      __ cmp(arg_slots.as_register(), (int32_t) UNREASONABLE_STACK_MOVE);
-      __ br(Assembler::less, false, Assembler::pn, L_ok);
-      __ delayed()->nop();
-    } else {
-      __ br(allow_zero ? Assembler::greater : Assembler::greaterEqual, false, Assembler::pn, L_bad);
-      __ delayed()->nop();
-      __ cmp(arg_slots.as_register(), (int32_t) -UNREASONABLE_STACK_MOVE);
-      __ br(Assembler::greater, false, Assembler::pn, L_ok);
-      __ delayed()->nop();
-    }
-    __ BIND(L_bad);
-    if (direction > 0)
-      __ stop("assert arg_slots > 0");
-    else
-      __ stop("assert arg_slots < 0");
-    __ BIND(L_ok);
-    BLOCK_COMMENT("} verify_stack_move");
-  } else {
-    intptr_t size = arg_slots.as_constant();
-    if (direction < 0)  size = -size;
-    assert(size >= 0, "correct direction of constant move");
-    assert(size < UNREASONABLE_STACK_MOVE, "reasonable size of constant move");
-  }
-}
-
 void MethodHandles::verify_klass(MacroAssembler* _masm,
                                  Register obj_reg, KlassHandle klass,
                                  Register temp_reg, Register temp2_reg,
@@ -485,6 +70,14 @@
   assert(klass_addr >= SystemDictionaryHandles::Object_klass().raw_value() &&
          klass_addr <= SystemDictionaryHandles::Long_klass().raw_value(),
          "must be one of the SystemDictionaryHandles");
+  bool did_save = false;
+  if (temp_reg == noreg || temp2_reg == noreg) {
+    temp_reg = L1;
+    temp2_reg = L2;
+    __ save_frame_and_mov(0, obj_reg, L0);
+    obj_reg = L0;
+    did_save = true;
+  }
   Label L_ok, L_bad;
   BLOCK_COMMENT("verify_klass {");
   __ verify_oop(obj_reg);
@@ -499,548 +92,387 @@
   __ ld_ptr(Address(temp2_reg, 0), temp2_reg);
   __ cmp_and_brx_short(temp_reg, temp2_reg, Assembler::equal, Assembler::pt, L_ok);
   __ BIND(L_bad);
-  __ stop(error_message);
+  if (did_save)  __ restore();
+  __ STOP(error_message);
   __ BIND(L_ok);
+  if (did_save)  __ restore();
   BLOCK_COMMENT("} verify_klass");
 }
+
+void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {
+  Label L;
+  BLOCK_COMMENT("verify_ref_kind {");
+  __ lduw(Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes())), temp);
+  __ srl( temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT, temp);
+  __ and3(temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,  temp);
+  __ cmp_and_br_short(temp, ref_kind, Assembler::equal, Assembler::pt, L);
+  { char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal);
+    jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind);
+    if (ref_kind == JVM_REF_invokeVirtual ||
+        ref_kind == JVM_REF_invokeSpecial)
+      // could do this for all ref_kinds, but would explode assembly code size
+      trace_method_handle(_masm, buf);
+    __ STOP(buf);
+  }
+  BLOCK_COMMENT("} verify_ref_kind");
+  __ bind(L);
+}
+
 #endif // ASSERT
 
-
-void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp) {
+void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register target, Register temp,
+                                            bool for_compiler_entry) {
   assert(method == G5_method, "interpreter calling convention");
+  assert_different_registers(method, target, temp);
   __ verify_oop(method);
-  __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_interpreted_offset()), target);
-  if (JvmtiExport::can_post_interpreter_events()) {
+
+  if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
+    Label run_compiled_code;
     // JVMTI events, such as single-stepping, are implemented partly by avoiding running
     // compiled code in threads for which the event is enabled.  Check here for
     // interp_only_mode if these events CAN be enabled.
     __ verify_thread();
-    Label skip_compiled_code;
-
     const Address interp_only(G2_thread, JavaThread::interp_only_mode_offset());
     __ ld(interp_only, temp);
-    __ tst(temp);
-    __ br(Assembler::notZero, true, Assembler::pn, skip_compiled_code);
-    __ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
-    __ bind(skip_compiled_code);
+    __ cmp_and_br_short(temp, 0, Assembler::zero, Assembler::pt, run_compiled_code);
+    __ ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), target);
+    __ jmp(target, 0);
+    __ delayed()->nop();
+    __ BIND(run_compiled_code);
+    // Note: we could fill some delay slots here, but
+    // it doesn't matter, since this is interpreter code.
   }
+
+  const ByteSize entry_offset = for_compiler_entry ? methodOopDesc::from_compiled_offset() :
+                                                     methodOopDesc::from_interpreted_offset();
+  __ ld_ptr(G5_method, in_bytes(entry_offset), target);
   __ jmp(target, 0);
   __ delayed()->nop();
 }
 
+void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
+                                        Register recv, Register method_temp,
+                                        Register temp2, Register temp3,
+                                        bool for_compiler_entry) {
+  BLOCK_COMMENT("jump_to_lambda_form {");
+  // This is the initial entry point of a lazy method handle.
+  // After type checking, it picks up the invoker from the LambdaForm.
+  assert_different_registers(recv, method_temp, temp2);  // temp3 is only passed on
+  assert(method_temp == G5_method, "required register for loading method");
+
+  //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
+
+  // Load the invoker, as MH -> MH.form -> LF.vmentry
+  __ verify_oop(recv);
+  __ load_heap_oop(Address(recv,        NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())),   method_temp);
+  __ verify_oop(method_temp);
+  __ load_heap_oop(Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())),  method_temp);
+  __ verify_oop(method_temp);
+  // the following assumes that a methodOop is normally compressed in the vmtarget field:
+  __ load_heap_oop(Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())), method_temp);
+  __ verify_oop(method_temp);
+
+  if (VerifyMethodHandles && !for_compiler_entry) {
+    // make sure recv is already on stack
+    __ load_sized_value(Address(method_temp, methodOopDesc::size_of_parameters_offset()),
+                        temp2,
+                        sizeof(u2), /*is_signed*/ false);
+    // assert(sizeof(u2) == sizeof(methodOopDesc::_size_of_parameters), "");
+    Label L;
+    __ ld_ptr(__ argument_address(temp2, temp2, -1), temp2);
+    __ cmp_and_br_short(temp2, recv, Assembler::equal, Assembler::pt, L);
+    __ STOP("receiver not on stack");
+    __ BIND(L);
+  }
+
+  jump_from_method_handle(_masm, method_temp, temp2, temp3, for_compiler_entry);
+  BLOCK_COMMENT("} jump_to_lambda_form");
+}
+
 
 // Code generation
-address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) {
-  // I5_savedSP/O5_savedSP: sender SP (must preserve)
-  // G4 (Gargs): incoming argument list (must preserve)
-  // G5_method:  invoke methodOop
-  // G3_method_handle: receiver method handle (must load from sp[MethodTypeForm.vmslots])
-  // O0, O1, O2, O3, O4: garbage temps, blown away
-  Register O0_mtype   = O0;
-  Register O1_scratch = O1;
-  Register O2_scratch = O2;
-  Register O3_scratch = O3;
-  Register O4_argslot = O4;
-  Register O4_argbase = O4;
+address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm,
+                                                                vmIntrinsics::ID iid) {
+  const bool not_for_compiler_entry = false;  // this is the interpreter entry
+  assert(is_signature_polymorphic(iid), "expected invoke iid");
+  if (iid == vmIntrinsics::_invokeGeneric ||
+      iid == vmIntrinsics::_compiledLambdaForm) {
+    // Perhaps surprisingly, the symbolic references visible to Java are not directly used.
+    // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod.
+    // They all allow an appendix argument.
+    __ should_not_reach_here();           // empty stubs make SG sick
+    return NULL;
+  }
 
-  // emit WrongMethodType path first, to enable back-branch from main path
-  Label wrong_method_type;
-  __ bind(wrong_method_type);
-  Label invoke_generic_slow_path;
-  assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");;
-  __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch);
-  __ cmp(O1_scratch, (int) vmIntrinsics::_invokeExact);
-  __ brx(Assembler::notEqual, false, Assembler::pt, invoke_generic_slow_path);
-  __ delayed()->nop();
-  __ mov(O0_mtype, G5_method_type);  // required by throw_WrongMethodType
-  __ mov(G3_method_handle, G3_method_handle);  // already in this register
-  // O0 will be filled in with JavaThread in stub
-  __ jump_to(AddressLiteral(StubRoutines::throw_WrongMethodTypeException_entry()), O3_scratch);
-  __ delayed()->nop();
+  // I5_savedSP/O5_savedSP: sender SP (must preserve; see prepare_to_jump_from_interpreted)
+  // G5_method:  methodOop
+  // G4 (Gargs): incoming argument list (must preserve)
+  // O0: used as temp to hold mh or receiver
+  // O1, O4: garbage temps, blown away
+  Register O1_scratch    = O1;
+  Register O4_param_size = O4;   // size of parameters
 
   // here's where control starts out:
   __ align(CodeEntryAlignment);
   address entry_point = __ pc();
 
-  // fetch the MethodType from the method handle
-  // FIXME: Interpreter should transmit pre-popped stack pointer, to locate base of arg list.
-  // This would simplify several touchy bits of code.
-  // See 6984712: JSR 292 method handle calls need a clean argument base pointer
-  {
-    Register tem = G5_method;
-    for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
-      __ ld_ptr(Address(tem, *pchase), O0_mtype);
-      tem = O0_mtype;          // in case there is another indirection
-    }
-  }
-
-  // given the MethodType, find out where the MH argument is buried
-  __ load_heap_oop(Address(O0_mtype,   __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes,        O1_scratch)), O4_argslot);
-  __ ldsw(         Address(O4_argslot, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, O1_scratch)), O4_argslot);
-  __ add(__ argument_address(O4_argslot, O4_argslot, 1), O4_argbase);
-  // Note: argument_address uses its input as a scratch register!
-  Address mh_receiver_slot_addr(O4_argbase, -Interpreter::stackElementSize);
-  __ ld_ptr(mh_receiver_slot_addr, G3_method_handle);
-
-  trace_method_handle(_masm, "invokeExact");
-
-  __ check_method_handle_type(O0_mtype, G3_method_handle, O1_scratch, wrong_method_type);
-
-  // Nobody uses the MH receiver slot after this.  Make sure.
-  DEBUG_ONLY(__ set((int32_t) 0x999999, O1_scratch); __ st_ptr(O1_scratch, mh_receiver_slot_addr));
-
-  __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-
-  // for invokeGeneric (only), apply argument and result conversions on the fly
-  __ bind(invoke_generic_slow_path);
-#ifdef ASSERT
   if (VerifyMethodHandles) {
     Label L;
+    BLOCK_COMMENT("verify_intrinsic_id {");
     __ ldub(Address(G5_method, methodOopDesc::intrinsic_id_offset_in_bytes()), O1_scratch);
-    __ cmp(O1_scratch, (int) vmIntrinsics::_invokeGeneric);
-    __ brx(Assembler::equal, false, Assembler::pt, L);
-    __ delayed()->nop();
-    __ stop("bad methodOop::intrinsic_id");
+    __ cmp_and_br_short(O1_scratch, (int) iid, Assembler::equal, Assembler::pt, L);
+    if (iid == vmIntrinsics::_linkToVirtual ||
+        iid == vmIntrinsics::_linkToSpecial) {
+      // could do this for all kinds, but would explode assembly code size
+      trace_method_handle(_masm, "bad methodOop::intrinsic_id");
+    }
+    __ STOP("bad methodOop::intrinsic_id");
     __ bind(L);
+    BLOCK_COMMENT("} verify_intrinsic_id");
   }
-#endif //ASSERT
 
-  // make room on the stack for another pointer:
-  insert_arg_slots(_masm, 2 * stack_move_unit(), O4_argbase, O1_scratch, O2_scratch, O3_scratch);
-  // load up an adapter from the calling type (Java weaves this)
-  Register O2_form    = O2_scratch;
-  Register O3_adapter = O3_scratch;
-  __ load_heap_oop(Address(O0_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes,               O1_scratch)), O2_form);
-  __ load_heap_oop(Address(O2_form,  __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, O1_scratch)), O3_adapter);
-  __ verify_oop(O3_adapter);
-  __ st_ptr(O3_adapter, Address(O4_argbase, 1 * Interpreter::stackElementSize));
-  // As a trusted first argument, pass the type being called, so the adapter knows
-  // the actual types of the arguments and return values.
-  // (Generic invokers are shared among form-families of method-type.)
-  __ st_ptr(O0_mtype,   Address(O4_argbase, 0 * Interpreter::stackElementSize));
-  // FIXME: assert that O3_adapter is of the right method-type.
-  __ mov(O3_adapter, G3_method_handle);
-  trace_method_handle(_masm, "invokeGeneric");
-  __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
+  // First task:  Find out how big the argument list is.
+  Address O4_first_arg_addr;
+  int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
+  assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
+  if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
+    __ load_sized_value(Address(G5_method, methodOopDesc::size_of_parameters_offset()),
+                        O4_param_size,
+                        sizeof(u2), /*is_signed*/ false);
+    // assert(sizeof(u2) == sizeof(methodOopDesc::_size_of_parameters), "");
+    O4_first_arg_addr = __ argument_address(O4_param_size, O4_param_size, -1);
+  } else {
+    DEBUG_ONLY(O4_param_size = noreg);
+  }
+
+  Register O0_mh = noreg;
+  if (!is_signature_polymorphic_static(iid)) {
+    __ ld_ptr(O4_first_arg_addr, O0_mh = O0);
+    DEBUG_ONLY(O4_param_size = noreg);
+  }
+
+  // O4_first_arg_addr is live!
+
+  if (TraceMethodHandles) {
+    if (O0_mh != noreg)
+      __ mov(O0_mh, G3_method_handle);  // make stub happy
+    trace_method_handle_interpreter_entry(_masm, iid);
+  }
+
+  if (iid == vmIntrinsics::_invokeBasic) {
+    generate_method_handle_dispatch(_masm, iid, O0_mh, noreg, not_for_compiler_entry);
+
+  } else {
+    // Adjust argument list by popping the trailing MemberName argument.
+    Register O0_recv = noreg;
+    if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
+      // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack.
+      __ ld_ptr(O4_first_arg_addr, O0_recv = O0);
+      DEBUG_ONLY(O4_param_size = noreg);
+    }
+    Register G5_member = G5_method;  // MemberName ptr; incoming method ptr is dead now
+    __ ld_ptr(__ argument_address(constant(0)), G5_member);
+    __ add(Gargs, Interpreter::stackElementSize, Gargs);
+    generate_method_handle_dispatch(_masm, iid, O0_recv, G5_member, not_for_compiler_entry);
+  }
 
   return entry_point;
 }
 
-// Workaround for C++ overloading nastiness on '0' for RegisterOrConstant.
-static RegisterOrConstant constant(int value) {
-  return RegisterOrConstant(value);
-}
-
-static void load_vmargslot(MacroAssembler* _masm, Address vmargslot_addr, Register result) {
-  __ ldsw(vmargslot_addr, result);
-}
-
-static RegisterOrConstant adjust_SP_and_Gargs_down_by_slots(MacroAssembler* _masm,
-                                                            RegisterOrConstant arg_slots,
-                                                            Register temp_reg, Register temp2_reg) {
-  // Keep the stack pointer 2*wordSize aligned.
-  const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1);
-  if (arg_slots.is_constant()) {
-    const int        offset = arg_slots.as_constant() << LogBytesPerWord;
-    const int masked_offset = round_to(offset, 2 * BytesPerWord);
-    const int masked_offset2 = (offset + 1*BytesPerWord) & ~TwoWordAlignmentMask;
-    assert(masked_offset == masked_offset2, "must agree");
-    __ sub(Gargs,        offset, Gargs);
-    __ sub(SP,    masked_offset, SP   );
-    return offset;
+void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
+                                                    vmIntrinsics::ID iid,
+                                                    Register receiver_reg,
+                                                    Register member_reg,
+                                                    bool for_compiler_entry) {
+  assert(is_signature_polymorphic(iid), "expected invoke iid");
+  Register temp1 = (for_compiler_entry ? G1_scratch : O1);
+  Register temp2 = (for_compiler_entry ? G3_scratch : O2);
+  Register temp3 = (for_compiler_entry ? G4_scratch : O3);
+  Register temp4 = (for_compiler_entry ? noreg      : O4);
+  if (for_compiler_entry) {
+    assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : O0), "only valid assignment");
+    assert_different_registers(temp1, O0, O1, O2, O3, O4, O5);
+    assert_different_registers(temp2, O0, O1, O2, O3, O4, O5);
+    assert_different_registers(temp3, O0, O1, O2, O3, O4, O5);
+    assert_different_registers(temp4, O0, O1, O2, O3, O4, O5);
   } else {
-#ifdef ASSERT
+    assert_different_registers(temp1, temp2, temp3, temp4, O5_savedSP);  // don't trash lastSP
+  }
+  if (receiver_reg != noreg)  assert_different_registers(temp1, temp2, temp3, temp4, receiver_reg);
+  if (member_reg   != noreg)  assert_different_registers(temp1, temp2, temp3, temp4, member_reg);
+
+  if (iid == vmIntrinsics::_invokeBasic) {
+    // indirect through MH.form.vmentry.vmtarget
+    jump_to_lambda_form(_masm, receiver_reg, G5_method, temp1, temp2, for_compiler_entry);
+
+  } else {
+    // The method is a member invoker used by direct method handles.
+    if (VerifyMethodHandles) {
+      // make sure the trailing argument really is a MemberName (caller responsibility)
+      verify_klass(_masm, member_reg, SystemDictionaryHandles::MemberName_klass(),
+                   temp1, temp2,
+                   "MemberName required for invokeVirtual etc.");
+    }
+
+    Address member_clazz(    member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
+    Address member_vmindex(  member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
+    Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()));
+
+    Register temp1_recv_klass = temp1;
+    if (iid != vmIntrinsics::_linkToStatic) {
+      __ verify_oop(receiver_reg);
+      if (iid == vmIntrinsics::_linkToSpecial) {
+        // Don't actually load the klass; just null-check the receiver.
+        __ null_check(receiver_reg);
+      } else {
+        // load receiver klass itself
+        __ null_check(receiver_reg, oopDesc::klass_offset_in_bytes());
+        __ load_klass(receiver_reg, temp1_recv_klass);
+        __ verify_oop(temp1_recv_klass);
+      }
+      BLOCK_COMMENT("check_receiver {");
+      // The receiver for the MemberName must be in receiver_reg.
+      // Check the receiver against the MemberName.clazz
+      if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) {
+        // Did not load it above...
+        __ load_klass(receiver_reg, temp1_recv_klass);
+        __ verify_oop(temp1_recv_klass);
+      }
+      if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
+        Label L_ok;
+        Register temp2_defc = temp2;
+        __ load_heap_oop(member_clazz, temp2_defc);
+        load_klass_from_Class(_masm, temp2_defc, temp3, temp4);
+        __ verify_oop(temp2_defc);
+        __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, temp4, L_ok);
+        // If we get here, the type check failed!
+        __ STOP("receiver class disagrees with MemberName.clazz");
+        __ bind(L_ok);
+      }
+      BLOCK_COMMENT("} check_receiver");
+    }
+    if (iid == vmIntrinsics::_linkToSpecial ||
+        iid == vmIntrinsics::_linkToStatic) {
+      DEBUG_ONLY(temp1_recv_klass = noreg);  // these guys didn't load the recv_klass
+    }
+
+    // Live registers at this point:
+    //  member_reg - MemberName that was the trailing argument
+    //  temp1_recv_klass - klass of stacked receiver, if needed
+    //  O5_savedSP - interpreter linkage (if interpreted)
+    //  O0..O5 - compiler arguments (if compiled)
+
+    Label L_incompatible_class_change_error;
+    switch (iid) {
+    case vmIntrinsics::_linkToSpecial:
+      if (VerifyMethodHandles) {
+        verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp2);
+      }
+      __ load_heap_oop(member_vmtarget, G5_method);
+      break;
+
+    case vmIntrinsics::_linkToStatic:
+      if (VerifyMethodHandles) {
+        verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp2);
+      }
+      __ load_heap_oop(member_vmtarget, G5_method);
+      break;
+
+    case vmIntrinsics::_linkToVirtual:
     {
-      Label L_ok;
-      __ cmp_and_br_short(arg_slots.as_register(), 0, Assembler::greaterEqual, Assembler::pt, L_ok);
-      __ stop("negative arg_slots");
-      __ bind(L_ok);
+      // same as TemplateTable::invokevirtual,
+      // minus the CP setup and profiling:
+
+      if (VerifyMethodHandles) {
+        verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp2);
+      }
+
+      // pick out the vtable index from the MemberName, and then we can discard it:
+      Register temp2_index = temp2;
+      __ ld_ptr(member_vmindex, temp2_index);
+
+      if (VerifyMethodHandles) {
+        Label L_index_ok;
+        __ cmp_and_br_short(temp2_index, (int) 0, Assembler::greaterEqual, Assembler::pn, L_index_ok);
+        __ STOP("no virtual index");
+        __ BIND(L_index_ok);
+      }
+
+      // Note:  The verifier invariants allow us to ignore MemberName.clazz and vmtarget
+      // at this point.  And VerifyMethodHandles has already checked clazz, if needed.
+
+      // get target methodOop & entry point
+      __ lookup_virtual_method(temp1_recv_klass, temp2_index, G5_method);
+      break;
     }
-#endif
-    __ sll_ptr(arg_slots.as_register(), LogBytesPerWord, temp_reg);
-    __ add( temp_reg,  1*BytesPerWord,       temp2_reg);
-    __ andn(temp2_reg, TwoWordAlignmentMask, temp2_reg);
-    __ sub(Gargs, temp_reg,  Gargs);
-    __ sub(SP,    temp2_reg, SP   );
-    return temp_reg;
-  }
-}
 
-static RegisterOrConstant adjust_SP_and_Gargs_up_by_slots(MacroAssembler* _masm,
-                                                          RegisterOrConstant arg_slots,
-                                                          Register temp_reg, Register temp2_reg) {
-  // Keep the stack pointer 2*wordSize aligned.
-  const int TwoWordAlignmentMask = right_n_bits(LogBytesPerWord + 1);
-  if (arg_slots.is_constant()) {
-    const int        offset = arg_slots.as_constant() << LogBytesPerWord;
-    const int masked_offset = offset & ~TwoWordAlignmentMask;
-    __ add(Gargs,        offset, Gargs);
-    __ add(SP,    masked_offset, SP   );
-    return offset;
-  } else {
-    __ sll_ptr(arg_slots.as_register(), LogBytesPerWord, temp_reg);
-    __ andn(temp_reg, TwoWordAlignmentMask, temp2_reg);
-    __ add(Gargs, temp_reg,  Gargs);
-    __ add(SP,    temp2_reg, SP   );
-    return temp_reg;
-  }
-}
+    case vmIntrinsics::_linkToInterface:
+    {
+      // same as TemplateTable::invokeinterface
+      // (minus the CP setup and profiling, with different argument motion)
+      if (VerifyMethodHandles) {
+        verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp2);
+      }
 
-// Helper to insert argument slots into the stack.
-// arg_slots must be a multiple of stack_move_unit() and < 0
-// argslot_reg is decremented to point to the new (shifted) location of the argslot
-// But, temp_reg ends up holding the original value of argslot_reg.
-void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
-                                     RegisterOrConstant arg_slots,
-                                     Register argslot_reg,
-                                     Register temp_reg, Register temp2_reg, Register temp3_reg) {
-  // allow constant zero
-  if (arg_slots.is_constant() && arg_slots.as_constant() == 0)
-    return;
+      Register temp2_intf = temp2;
+      __ load_heap_oop(member_clazz, temp2_intf);
+      load_klass_from_Class(_masm, temp2_intf, temp3, temp4);
+      __ verify_oop(temp2_intf);
 
-  // We have to insert at least one word, so bang the stack.
-  if (UseStackBanging) {
-    // Save G3_method_handle since bang_stack_with_offset uses it as a temp register
-    __ mov(G3_method_handle, temp_reg);
-    int frame_size = (arg_slots.is_constant() ? -1 * arg_slots.as_constant() * wordSize : 0);
-    if (frame_size <= 0)
-      frame_size = 256 * Interpreter::stackElementSize;  // conservative
-    __ generate_stack_overflow_check(frame_size);
-    __ mov(temp_reg, G3_method_handle);
-  }
+      Register G5_index = G5_method;
+      __ ld_ptr(member_vmindex, G5_index);
+      if (VerifyMethodHandles) {
+        Label L;
+        __ cmp_and_br_short(G5_index, 0, Assembler::greaterEqual, Assembler::pt, L);
+        __ STOP("invalid vtable index for MH.invokeInterface");
+        __ bind(L);
+      }
 
-  assert_different_registers(argslot_reg, temp_reg, temp2_reg, temp3_reg,
-                             (!arg_slots.is_register() ? Gargs : arg_slots.as_register()));
-
-  BLOCK_COMMENT("insert_arg_slots {");
-  if (VerifyMethodHandles)
-    verify_argslot(_masm, argslot_reg, temp_reg, "insertion point must fall within current frame");
-  if (VerifyMethodHandles)
-    verify_stack_move(_masm, arg_slots, -1);
-
-  // Make space on the stack for the inserted argument(s).
-  // Then pull down everything shallower than argslot_reg.
-  // The stacked return address gets pulled down with everything else.
-  // That is, copy [sp, argslot) downward by -size words.  In pseudo-code:
-  //   sp -= size;
-  //   for (temp = sp + size; temp < argslot; temp++)
-  //     temp[-size] = temp[0]
-  //   argslot -= size;
-
-  // offset is temp3_reg in case of arg_slots being a register.
-  RegisterOrConstant offset = adjust_SP_and_Gargs_up_by_slots(_masm, arg_slots, temp3_reg, temp_reg);
-  __ sub(Gargs, offset, temp_reg);  // source pointer for copy
-
-  {
-    Label loop;
-    __ BIND(loop);
-    // pull one word down each time through the loop
-    __ ld_ptr(           Address(temp_reg, 0     ), temp2_reg);
-    __ st_ptr(temp2_reg, Address(temp_reg, offset)           );
-    __ add(temp_reg, wordSize, temp_reg);
-    __ cmp_and_brx_short(temp_reg, argslot_reg, Assembler::lessUnsigned, Assembler::pt, loop);
-  }
-
-  // Now move the argslot down, to point to the opened-up space.
-  __ add(argslot_reg, offset, argslot_reg);
-  BLOCK_COMMENT("} insert_arg_slots");
-}
-
-
-// Helper to remove argument slots from the stack.
-// arg_slots must be a multiple of stack_move_unit() and > 0
-void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
-                                     RegisterOrConstant arg_slots,
-                                     Register argslot_reg,
-                                     Register temp_reg, Register temp2_reg, Register temp3_reg) {
-  // allow constant zero
-  if (arg_slots.is_constant() && arg_slots.as_constant() == 0)
-    return;
-  assert_different_registers(argslot_reg, temp_reg, temp2_reg, temp3_reg,
-                             (!arg_slots.is_register() ? Gargs : arg_slots.as_register()));
-
-  BLOCK_COMMENT("remove_arg_slots {");
-  if (VerifyMethodHandles)
-    verify_argslots(_masm, arg_slots, argslot_reg, temp_reg, temp2_reg, false,
-                    "deleted argument(s) must fall within current frame");
-  if (VerifyMethodHandles)
-    verify_stack_move(_masm, arg_slots, +1);
-
-  // Pull up everything shallower than argslot.
-  // Then remove the excess space on the stack.
-  // The stacked return address gets pulled up with everything else.
-  // That is, copy [sp, argslot) upward by size words.  In pseudo-code:
-  //   for (temp = argslot-1; temp >= sp; --temp)
-  //     temp[size] = temp[0]
-  //   argslot += size;
-  //   sp += size;
-
-  RegisterOrConstant offset = __ regcon_sll_ptr(arg_slots, LogBytesPerWord, temp3_reg);
-  __ sub(argslot_reg, wordSize, temp_reg);  // source pointer for copy
-
-  {
-    Label L_loop;
-    __ BIND(L_loop);
-    // pull one word up each time through the loop
-    __ ld_ptr(           Address(temp_reg, 0     ), temp2_reg);
-    __ st_ptr(temp2_reg, Address(temp_reg, offset)           );
-    __ sub(temp_reg, wordSize, temp_reg);
-    __ cmp_and_brx_short(temp_reg, Gargs, Assembler::greaterEqualUnsigned, Assembler::pt, L_loop);
-  }
-
-  // And adjust the argslot address to point at the deletion point.
-  __ add(argslot_reg, offset, argslot_reg);
-
-  // We don't need the offset at this point anymore, just adjust SP and Gargs.
-  (void) adjust_SP_and_Gargs_up_by_slots(_masm, arg_slots, temp3_reg, temp_reg);
-
-  BLOCK_COMMENT("} remove_arg_slots");
-}
-
-// Helper to copy argument slots to the top of the stack.
-// The sequence starts with argslot_reg and is counted by slot_count
-// slot_count must be a multiple of stack_move_unit() and >= 0
-// This function blows the temps but does not change argslot_reg.
-void MethodHandles::push_arg_slots(MacroAssembler* _masm,
-                                   Register argslot_reg,
-                                   RegisterOrConstant slot_count,
-                                   Register temp_reg, Register temp2_reg) {
-  // allow constant zero
-  if (slot_count.is_constant() && slot_count.as_constant() == 0)
-    return;
-  assert_different_registers(argslot_reg, temp_reg, temp2_reg,
-                             (!slot_count.is_register() ? Gargs : slot_count.as_register()),
-                             SP);
-  assert(Interpreter::stackElementSize == wordSize, "else change this code");
-
-  BLOCK_COMMENT("push_arg_slots {");
-  if (VerifyMethodHandles)
-    verify_stack_move(_masm, slot_count, 0);
-
-  RegisterOrConstant offset = adjust_SP_and_Gargs_down_by_slots(_masm, slot_count, temp2_reg, temp_reg);
-
-  if (slot_count.is_constant()) {
-    for (int i = slot_count.as_constant() - 1; i >= 0; i--) {
-      __ ld_ptr(          Address(argslot_reg, i * wordSize), temp_reg);
-      __ st_ptr(temp_reg, Address(Gargs,       i * wordSize));
+      // given intf, index, and recv klass, dispatch to the implementation method
+      __ lookup_interface_method(temp1_recv_klass, temp2_intf,
+                                 // note: next two args must be the same:
+                                 G5_index, G5_method,
+                                 temp3, temp4,
+                                 L_incompatible_class_change_error);
+      break;
     }
-  } else {
-    Label L_plural, L_loop, L_break;
-    // Emit code to dynamically check for the common cases, zero and one slot.
-    __ cmp(slot_count.as_register(), (int32_t) 1);
-    __ br(Assembler::greater, false, Assembler::pn, L_plural);
-    __ delayed()->nop();
-    __ br(Assembler::less, false, Assembler::pn, L_break);
-    __ delayed()->nop();
-    __ ld_ptr(          Address(argslot_reg, 0), temp_reg);
-    __ st_ptr(temp_reg, Address(Gargs,       0));
-    __ ba_short(L_break);
-    __ BIND(L_plural);
 
-    // Loop for 2 or more:
-    //   top = &argslot[slot_count]
-    //   while (top > argslot)  *(--Gargs) = *(--top)
-    Register top_reg = temp_reg;
-    __ add(argslot_reg, offset, top_reg);
-    __ add(Gargs,       offset, Gargs  );  // move back up again so we can go down
-    __ BIND(L_loop);
-    __ sub(top_reg, wordSize, top_reg);
-    __ sub(Gargs,   wordSize, Gargs  );
-    __ ld_ptr(           Address(top_reg, 0), temp2_reg);
-    __ st_ptr(temp2_reg, Address(Gargs,   0));
-    __ cmp_and_brx_short(top_reg, argslot_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
-    __ BIND(L_break);
-  }
-  BLOCK_COMMENT("} push_arg_slots");
-}
+    default:
+      fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+      break;
+    }
 
-// in-place movement; no change to Gargs
-// blows temp_reg, temp2_reg
-void MethodHandles::move_arg_slots_up(MacroAssembler* _masm,
-                                      Register bottom_reg,  // invariant
-                                      Address  top_addr,    // can use temp_reg
-                                      RegisterOrConstant positive_distance_in_slots,  // destroyed if register
-                                      Register temp_reg, Register temp2_reg) {
-  assert_different_registers(bottom_reg,
-                             temp_reg, temp2_reg,
-                             positive_distance_in_slots.register_or_noreg());
-  BLOCK_COMMENT("move_arg_slots_up {");
-  Label L_loop, L_break;
-  Register top_reg = temp_reg;
-  if (!top_addr.is_same_address(Address(top_reg, 0))) {
-    __ add(top_addr, top_reg);
-  }
-  // Detect empty (or broken) loop:
-#ifdef ASSERT
-  if (VerifyMethodHandles) {
-    // Verify that &bottom < &top (non-empty interval)
-    Label L_ok, L_bad;
-    if (positive_distance_in_slots.is_register()) {
-      __ cmp(positive_distance_in_slots.as_register(), (int32_t) 0);
-      __ br(Assembler::lessEqual, false, Assembler::pn, L_bad);
+    // Live at this point:
+    //   G5_method
+    //   O5_savedSP (if interpreted)
+
+    // After figuring out which concrete method to call, jump into it.
+    // Note that this works in the interpreter with no data motion.
+    // But the compiled version will require that rcx_recv be shifted out.
+    __ verify_oop(G5_method);
+    jump_from_method_handle(_masm, G5_method, temp1, temp2, for_compiler_entry);
+
+    if (iid == vmIntrinsics::_linkToInterface) {
+      __ BIND(L_incompatible_class_change_error);
+      AddressLiteral icce(StubRoutines::throw_IncompatibleClassChangeError_entry());
+      __ jump_to(icce, temp1);
       __ delayed()->nop();
     }
-    __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
-    __ BIND(L_bad);
-    __ stop("valid bounds (copy up)");
-    __ BIND(L_ok);
   }
-#endif
-  __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
-  // work top down to bottom, copying contiguous data upwards
-  // In pseudo-code:
-  //   while (--top >= bottom) *(top + distance) = *(top + 0);
-  RegisterOrConstant offset = __ argument_offset(positive_distance_in_slots, positive_distance_in_slots.register_or_noreg());
-  __ BIND(L_loop);
-  __ sub(top_reg, wordSize, top_reg);
-  __ ld_ptr(           Address(top_reg, 0     ), temp2_reg);
-  __ st_ptr(temp2_reg, Address(top_reg, offset)           );
-  __ cmp_and_brx_short(top_reg, bottom_reg, Assembler::greaterUnsigned, Assembler::pt, L_loop);
-  assert(Interpreter::stackElementSize == wordSize, "else change loop");
-  __ BIND(L_break);
-  BLOCK_COMMENT("} move_arg_slots_up");
-}
-
-// in-place movement; no change to rsp
-// blows temp_reg, temp2_reg
-void MethodHandles::move_arg_slots_down(MacroAssembler* _masm,
-                                        Address  bottom_addr,  // can use temp_reg
-                                        Register top_reg,      // invariant
-                                        RegisterOrConstant negative_distance_in_slots,  // destroyed if register
-                                        Register temp_reg, Register temp2_reg) {
-  assert_different_registers(top_reg,
-                             negative_distance_in_slots.register_or_noreg(),
-                             temp_reg, temp2_reg);
-  BLOCK_COMMENT("move_arg_slots_down {");
-  Label L_loop, L_break;
-  Register bottom_reg = temp_reg;
-  if (!bottom_addr.is_same_address(Address(bottom_reg, 0))) {
-    __ add(bottom_addr, bottom_reg);
-  }
-  // Detect empty (or broken) loop:
-#ifdef ASSERT
-  assert(!negative_distance_in_slots.is_constant() || negative_distance_in_slots.as_constant() < 0, "");
-  if (VerifyMethodHandles) {
-    // Verify that &bottom < &top (non-empty interval)
-    Label L_ok, L_bad;
-    if (negative_distance_in_slots.is_register()) {
-      __ cmp(negative_distance_in_slots.as_register(), (int32_t) 0);
-      __ br(Assembler::greaterEqual, false, Assembler::pn, L_bad);
-      __ delayed()->nop();
-    }
-    __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
-    __ BIND(L_bad);
-    __ stop("valid bounds (copy down)");
-    __ BIND(L_ok);
-  }
-#endif
-  __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::greaterEqualUnsigned, Assembler::pn, L_break);
-  // work bottom up to top, copying contiguous data downwards
-  // In pseudo-code:
-  //   while (bottom < top) *(bottom - distance) = *(bottom + 0), bottom++;
-  RegisterOrConstant offset = __ argument_offset(negative_distance_in_slots, negative_distance_in_slots.register_or_noreg());
-  __ BIND(L_loop);
-  __ ld_ptr(           Address(bottom_reg, 0     ), temp2_reg);
-  __ st_ptr(temp2_reg, Address(bottom_reg, offset)           );
-  __ add(bottom_reg, wordSize, bottom_reg);
-  __ cmp_and_brx_short(bottom_reg, top_reg, Assembler::lessUnsigned, Assembler::pt, L_loop);
-  assert(Interpreter::stackElementSize == wordSize, "else change loop");
-  __ BIND(L_break);
-  BLOCK_COMMENT("} move_arg_slots_down");
-}
-
-// Copy from a field or array element to a stacked argument slot.
-// is_element (ignored) says whether caller is loading an array element instead of an instance field.
-void MethodHandles::move_typed_arg(MacroAssembler* _masm,
-                                   BasicType type, bool is_element,
-                                   Address value_src, Address slot_dest,
-                                   Register temp_reg) {
-  assert(!slot_dest.uses(temp_reg), "must be different register");
-  BLOCK_COMMENT(!is_element ? "move_typed_arg {" : "move_typed_arg { (array element)");
-  if (type == T_OBJECT || type == T_ARRAY) {
-    __ load_heap_oop(value_src, temp_reg);
-    __ verify_oop(temp_reg);
-    __ st_ptr(temp_reg, slot_dest);
-  } else if (type != T_VOID) {
-    int  arg_size      = type2aelembytes(type);
-    bool arg_is_signed = is_signed_subword_type(type);
-    int  slot_size     = is_subword_type(type) ? type2aelembytes(T_INT) : arg_size;  // store int sub-words as int
-    __ load_sized_value( value_src, temp_reg, arg_size, arg_is_signed);
-    __ store_sized_value(temp_reg, slot_dest, slot_size              );
-  }
-  BLOCK_COMMENT("} move_typed_arg");
-}
-
-// Cf. TemplateInterpreterGenerator::generate_return_entry_for and
-// InterpreterMacroAssembler::save_return_value
-void MethodHandles::move_return_value(MacroAssembler* _masm, BasicType type,
-                                      Address return_slot) {
-  BLOCK_COMMENT("move_return_value {");
-  // Look at the type and pull the value out of the corresponding register.
-  if (type == T_VOID) {
-    // nothing to do
-  } else if (type == T_OBJECT) {
-    __ verify_oop(O0);
-    __ st_ptr(O0, return_slot);
-  } else if (type == T_INT || is_subword_type(type)) {
-    int type_size = type2aelembytes(T_INT);
-    __ store_sized_value(O0, return_slot, type_size);
-  } else if (type == T_LONG) {
-    // store the value by parts
-    // Note: We assume longs are continguous (if misaligned) on the interpreter stack.
-#if !defined(_LP64) && defined(COMPILER2)
-    __ stx(G1, return_slot);
-#else
-  #ifdef _LP64
-    __ stx(O0, return_slot);
-  #else
-    if (return_slot.has_disp()) {
-      // The displacement is a constant
-      __ st(O0, return_slot);
-      __ st(O1, return_slot.plus_disp(Interpreter::stackElementSize));
-    } else {
-      __ std(O0, return_slot);
-    }
-  #endif
-#endif
-  } else if (type == T_FLOAT) {
-    __ stf(FloatRegisterImpl::S, Ftos_f, return_slot);
-  } else if (type == T_DOUBLE) {
-    __ stf(FloatRegisterImpl::D, Ftos_f, return_slot);
-  } else {
-    ShouldNotReachHere();
-  }
-  BLOCK_COMMENT("} move_return_value");
 }
 
 #ifndef PRODUCT
-void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no)  {
-    RicochetFrame* rf = new RicochetFrame(*fr);
-
-    // ricochet slots (kept in registers for sparc)
-    values.describe(frame_no, rf->register_addr(I5_savedSP), err_msg("exact_sender_sp reg for #%d", frame_no));
-    values.describe(frame_no, rf->register_addr(L5_conversion), err_msg("conversion reg for #%d", frame_no));
-    values.describe(frame_no, rf->register_addr(L4_saved_args_base), err_msg("saved_args_base reg for #%d", frame_no));
-    values.describe(frame_no, rf->register_addr(L3_saved_args_layout), err_msg("saved_args_layout reg for #%d", frame_no));
-    values.describe(frame_no, rf->register_addr(L2_saved_target), err_msg("saved_target reg for #%d", frame_no));
-    values.describe(frame_no, rf->register_addr(L1_continuation), err_msg("continuation reg for #%d", frame_no));
-
-    // relevant ricochet targets (in caller frame)
-    values.describe(-1, rf->saved_args_base(),  err_msg("*saved_args_base for #%d", frame_no));
-    values.describe(-1, (intptr_t *)(STACK_BIAS+(uintptr_t)rf->exact_sender_sp()),  err_msg("*exact_sender_sp+STACK_BIAS for #%d", frame_no));
-}
-#endif // ASSERT
-
-#ifndef PRODUCT
-extern "C" void print_method_handle(oop mh);
 void trace_method_handle_stub(const char* adaptername,
                               oopDesc* mh,
                               intptr_t* saved_sp,
                               intptr_t* args,
                               intptr_t* tracing_fp) {
-  bool has_mh = (strstr(adaptername, "return/") == NULL);  // return adapters don't have mh
-
-  tty->print_cr("MH %s mh="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT, adaptername, (intptr_t) mh, saved_sp, args);
+  bool has_mh = (strstr(adaptername, "/static") == NULL &&
+                 strstr(adaptername, "linkTo") == NULL);    // static linkers don't have MH
+  const char* mh_reg_name = has_mh ? "G3_mh" : "G3";
+  tty->print_cr("MH %s %s="INTPTR_FORMAT " saved_sp=" INTPTR_FORMAT " args=" INTPTR_FORMAT,
+                adaptername, mh_reg_name,
+                (intptr_t) mh, saved_sp, args);
 
   if (Verbose) {
     // dumping last frame with frame::describe
@@ -1101,6 +533,7 @@
 
     // mark saved_sp, if seems valid (may not be valid for some adapters)
     intptr_t *unbiased_sp = (intptr_t *)(STACK_BIAS+(uintptr_t)saved_sp);
+    const int ARG_LIMIT = 255, SLOP = 45, UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP);
     if ((unbiased_sp >= dump_sp - UNREASONABLE_STACK_MOVE) && (unbiased_sp < dump_fp)) {
       values.describe(-1, unbiased_sp, "*saved_sp+STACK_BIAS");
     }
@@ -1108,10 +541,13 @@
     // Note: the unextended_sp may not be correct
     tty->print_cr("  stack layout:");
     values.print(p);
-  }
-
-  if (has_mh) {
-    print_method_handle(mh);
+    if (has_mh && mh->is_oop()) {
+      mh->print();
+      if (java_lang_invoke_MethodHandle::is_instance(mh)) {
+        if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0)
+          java_lang_invoke_MethodHandle::form(mh)->print();
+      }
+    }
   }
 }
 
@@ -1154,1280 +590,3 @@
   BLOCK_COMMENT("} trace_method_handle");
 }
 #endif // PRODUCT
-
-// which conversion op types are implemented here?
-int MethodHandles::adapter_conversion_ops_supported_mask() {
-  return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
-          // OP_PRIM_TO_REF is below...
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
-          // OP_COLLECT_ARGS is below...
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS)
-         |(
-           java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 :
-           ((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF)
-           |(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS)
-           |(1<<java_lang_invoke_AdapterMethodHandle::OP_FOLD_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) {
-  MethodHandles::EntryKind ek_orig = ek_original_kind(ek);
-
-  // 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)
-
-  const Register O0_scratch = O0;
-  const Register O1_scratch = O1;
-  const Register O2_scratch = O2;
-  const Register O3_scratch = O3;
-  const Register O4_scratch = O4;
-  const Register G5_scratch = G5;
-
-  // Often used names:
-  const Register O0_argslot = O0;
-
-  // Argument registers for _raise_exception:
-  const Register O0_code     = O0;
-  const Register O1_actual   = O1;
-  const Register O2_required = O2;
-
-  guarantee(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
-
-  // Some handy addresses:
-  Address G3_mh_vmtarget(   G3_method_handle, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes());
-
-  Address G3_dmh_vmindex(   G3_method_handle, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes());
-
-  Address G3_bmh_vmargslot( G3_method_handle, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes());
-  Address G3_bmh_argument(  G3_method_handle, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes());
-
-  Address G3_amh_vmargslot( G3_method_handle, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes());
-  Address G3_amh_argument ( G3_method_handle, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes());
-  Address G3_amh_conversion(G3_method_handle, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes());
-
-  const int java_mirror_offset = in_bytes(Klass::java_mirror_offset());
-
-  if (have_entry(ek)) {
-    __ nop();  // empty stubs make SG sick
-    return;
-  }
-
-  address interp_entry = __ pc();
-
-  trace_method_handle(_masm, entry_name(ek));
-
-  BLOCK_COMMENT(err_msg("Entry %s {", entry_name(ek)));
-
-  switch ((int) ek) {
-  case _raise_exception:
-    {
-      // Not a real MH entry, but rather shared code for raising an
-      // exception.  For sharing purposes the arguments are passed into registers
-      // and then placed in the intepreter calling convention here.
-      assert(raise_exception_method(), "must be set");
-      assert(raise_exception_method()->from_compiled_entry(), "method must be linked");
-
-      __ set(AddressLiteral((address) &_raise_exception_method), G5_method);
-      __ ld_ptr(Address(G5_method, 0), G5_method);
-
-      const int jobject_oop_offset = 0;
-      __ ld_ptr(Address(G5_method, jobject_oop_offset), G5_method);
-
-      adjust_SP_and_Gargs_down_by_slots(_masm, 3, noreg, noreg);
-
-      __ st    (O0_code,     __ argument_address(constant(2), noreg, 0));
-      __ st_ptr(O1_actual,   __ argument_address(constant(1), noreg, 0));
-      __ st_ptr(O2_required, __ argument_address(constant(0), noreg, 0));
-      jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
-    }
-    break;
-
-  case _invokestatic_mh:
-  case _invokespecial_mh:
-    {
-      __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
-      // Same as TemplateTable::invokestatic or invokespecial,
-      // minus the CP setup and profiling:
-      if (ek == _invokespecial_mh) {
-        // Must load & check the first argument before entering the target method.
-        __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch);
-        __ ld_ptr(__ argument_address(O0_argslot, O0_argslot, -1), G3_method_handle);
-        __ null_check(G3_method_handle);
-        __ verify_oop(G3_method_handle);
-      }
-      jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
-    }
-    break;
-
-  case _invokevirtual_mh:
-    {
-      // Same as TemplateTable::invokevirtual,
-      // minus the CP setup and profiling:
-
-      // Pick out the vtable index and receiver offset from the MH,
-      // and then we can discard it:
-      Register O2_index = O2_scratch;
-      __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch);
-      __ ldsw(G3_dmh_vmindex, O2_index);
-      // Note:  The verifier allows us to ignore G3_mh_vmtarget.
-      __ ld_ptr(__ argument_address(O0_argslot, O0_argslot, -1), G3_method_handle);
-      __ null_check(G3_method_handle, oopDesc::klass_offset_in_bytes());
-
-      // Get receiver klass:
-      Register O0_klass = O0_argslot;
-      __ load_klass(G3_method_handle, O0_klass);
-      __ verify_oop(O0_klass);
-
-      // Get target methodOop & entry point:
-      const int base = instanceKlass::vtable_start_offset() * wordSize;
-      assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
-
-      __ sll_ptr(O2_index, LogBytesPerWord, O2_index);
-      __ add(O0_klass, O2_index, O0_klass);
-      Address vtable_entry_addr(O0_klass, base + vtableEntry::method_offset_in_bytes());
-      __ ld_ptr(vtable_entry_addr, G5_method);
-
-      jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
-    }
-    break;
-
-  case _invokeinterface_mh:
-    {
-      // Same as TemplateTable::invokeinterface,
-      // minus the CP setup and profiling:
-      __ load_method_handle_vmslots(O0_argslot, G3_method_handle, O1_scratch);
-      Register O1_intf  = O1_scratch;
-      Register G5_index = G5_scratch;
-      __ load_heap_oop(G3_mh_vmtarget, O1_intf);
-      __ ldsw(G3_dmh_vmindex, G5_index);
-      __ ld_ptr(__ argument_address(O0_argslot, O0_argslot, -1), G3_method_handle);
-      __ null_check(G3_method_handle, oopDesc::klass_offset_in_bytes());
-
-      // Get receiver klass:
-      Register O0_klass = O0_argslot;
-      __ load_klass(G3_method_handle, O0_klass);
-      __ verify_oop(O0_klass);
-
-      // Get interface:
-      Label no_such_interface;
-      __ verify_oop(O1_intf);
-      __ lookup_interface_method(O0_klass, O1_intf,
-                                 // Note: next two args must be the same:
-                                 G5_index, G5_method,
-                                 O2_scratch,
-                                 O3_scratch,
-                                 no_such_interface);
-
-      jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
-
-      __ bind(no_such_interface);
-      // Throw an exception.
-      // For historical reasons, it will be IncompatibleClassChangeError.
-      __ unimplemented("not tested yet");
-      __ 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;
-
-  case _bound_ref_mh:
-  case _bound_int_mh:
-  case _bound_long_mh:
-  case _bound_ref_direct_mh:
-  case _bound_int_direct_mh:
-  case _bound_long_direct_mh:
-    {
-      const bool direct_to_method = (ek >= _bound_ref_direct_mh);
-      BasicType arg_type  = ek_bound_mh_arg_type(ek);
-      int       arg_slots = type2size[arg_type];
-
-      // Make room for the new argument:
-      load_vmargslot(_masm, G3_bmh_vmargslot, O0_argslot);
-      __ add(__ argument_address(O0_argslot, O0_argslot), O0_argslot);
-
-      insert_arg_slots(_masm, arg_slots * stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch);
-
-      // Store bound argument into the new stack slot:
-      __ load_heap_oop(G3_bmh_argument, O1_scratch);
-      if (arg_type == T_OBJECT) {
-        __ st_ptr(O1_scratch, Address(O0_argslot, 0));
-      } else {
-        Address prim_value_addr(O1_scratch, java_lang_boxing_object::value_offset_in_bytes(arg_type));
-        move_typed_arg(_masm, arg_type, false,
-                       prim_value_addr,
-                       Address(O0_argslot, 0),
-                      O2_scratch);  // must be an even register for !_LP64 long moves (uses O2/O3)
-      }
-
-      if (direct_to_method) {
-        __ load_heap_oop(G3_mh_vmtarget, G5_method);  // target is a methodOop
-        jump_from_method_handle(_masm, G5_method, O1_scratch, O2_scratch);
-      } else {
-        __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);  // target is a methodOop
-        __ verify_oop(G3_method_handle);
-        __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-      }
-    }
-    break;
-
-  case _adapter_opt_profiling:
-    if (java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes() != 0) {
-      Address G3_mh_vmcount(G3_method_handle, java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes());
-      __ ld(G3_mh_vmcount, O1_scratch);
-      __ add(O1_scratch, 1, O1_scratch);
-      __ st(O1_scratch, G3_mh_vmcount);
-    }
-    // fall through
-
-  case _adapter_retype_only:
-  case _adapter_retype_raw:
-    // Immediately jump to the next MH layer:
-    __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
-    __ verify_oop(G3_method_handle);
-    __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-    // This is OK when all parameter types widen.
-    // It is also OK when a return type narrows.
-    break;
-
-  case _adapter_check_cast:
-    {
-      // Check a reference argument before jumping to the next layer of MH:
-      load_vmargslot(_masm, G3_amh_vmargslot, O0_argslot);
-      Address vmarg = __ argument_address(O0_argslot, O0_argslot);
-
-      // What class are we casting to?
-      Register O1_klass = O1_scratch;  // Interesting AMH data.
-      __ load_heap_oop(G3_amh_argument, O1_klass);  // This is a Class object!
-      load_klass_from_Class(_masm, O1_klass, O2_scratch, O3_scratch);
-
-      Label L_done;
-      __ ld_ptr(vmarg, O2_scratch);
-      __ br_null_short(O2_scratch, Assembler::pn, L_done);  // No cast if null.
-      __ load_klass(O2_scratch, O2_scratch);
-
-      // Live at this point:
-      // - O0_argslot      :  argslot index in vmarg; may be required in the failing path
-      // - O1_klass        :  klass required by the target method
-      // - O2_scratch      :  argument klass to test
-      // - G3_method_handle:  adapter method handle
-      __ check_klass_subtype(O2_scratch, O1_klass, O3_scratch, O4_scratch, L_done);
-
-      // If we get here, the type check failed!
-      __ 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(L_done);
-      // Get the new MH:
-      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
-      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-    }
-    break;
-
-  case _adapter_prim_to_prim:
-  case _adapter_ref_to_prim:
-    // Handled completely by optimized cases.
-    __ stop("init_AdapterMethodHandle should not issue this");
-    break;
-
-  case _adapter_opt_i2i:        // optimized subcase of adapt_prim_to_prim
-//case _adapter_opt_f2i:        // optimized subcase of adapt_prim_to_prim
-  case _adapter_opt_l2i:        // optimized subcase of adapt_prim_to_prim
-  case _adapter_opt_unboxi:     // optimized subcase of adapt_ref_to_prim
-    {
-      // Perform an in-place conversion to int or an int subword.
-      load_vmargslot(_masm, G3_amh_vmargslot, O0_argslot);
-      Address value;
-      Address vmarg;
-      bool value_left_justified = false;
-
-      switch (ek) {
-      case _adapter_opt_i2i:
-        value = vmarg = __ argument_address(O0_argslot, O0_argslot);
-        break;
-      case _adapter_opt_l2i:
-        {
-          // just delete the extra slot
-#ifdef _LP64
-          // In V9, longs are given 2 64-bit slots in the interpreter, but the
-          // data is passed in only 1 slot.
-          // Keep the second slot.
-          __ add(__ argument_address(O0_argslot, O0_argslot, -1), O0_argslot);
-          remove_arg_slots(_masm, -stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch);
-          value = Address(O0_argslot, 4);  // Get least-significant 32-bit of 64-bit value.
-          vmarg = Address(O0_argslot, Interpreter::stackElementSize);
-#else
-          // Keep the first slot.
-          __ add(__ argument_address(O0_argslot, O0_argslot), O0_argslot);
-          remove_arg_slots(_masm, -stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch);
-          value = Address(O0_argslot, 0);
-          vmarg = value;
-#endif
-        }
-        break;
-      case _adapter_opt_unboxi:
-        {
-          vmarg = __ argument_address(O0_argslot, O0_argslot);
-          // Load the value up from the heap.
-          __ ld_ptr(vmarg, O1_scratch);
-          int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
-#ifdef ASSERT
-          for (int bt = T_BOOLEAN; bt < T_INT; bt++) {
-            if (is_subword_type(BasicType(bt)))
-              assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(BasicType(bt)), "");
-          }
-#endif
-          __ null_check(O1_scratch, value_offset);
-          value = Address(O1_scratch, value_offset);
-#ifdef _BIG_ENDIAN
-          // Values stored in objects are packed.
-          value_left_justified = true;
-#endif
-        }
-        break;
-      default:
-        ShouldNotReachHere();
-      }
-
-      // This check is required on _BIG_ENDIAN
-      Register G5_vminfo = G5_scratch;
-      __ ldsw(G3_amh_conversion, G5_vminfo);
-      assert(CONV_VMINFO_SHIFT == 0, "preshifted");
-
-      // Original 32-bit vmdata word must be of this form:
-      // | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
-      __ lduw(value, O1_scratch);
-      if (!value_left_justified)
-        __ sll(O1_scratch, G5_vminfo, O1_scratch);
-      Label zero_extend, done;
-      __ btst(CONV_VMINFO_SIGN_FLAG, G5_vminfo);
-      __ br(Assembler::zero, false, Assembler::pn, zero_extend);
-      __ delayed()->nop();
-
-      // this path is taken for int->byte, int->short
-      __ sra(O1_scratch, G5_vminfo, O1_scratch);
-      __ ba_short(done);
-
-      __ bind(zero_extend);
-      // this is taken for int->char
-      __ srl(O1_scratch, G5_vminfo, O1_scratch);
-
-      __ bind(done);
-      __ st(O1_scratch, vmarg);
-
-      // Get the new MH:
-      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
-      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-    }
-    break;
-
-  case _adapter_opt_i2l:        // optimized subcase of adapt_prim_to_prim
-  case _adapter_opt_unboxl:     // optimized subcase of adapt_ref_to_prim
-    {
-      // Perform an in-place int-to-long or ref-to-long conversion.
-      load_vmargslot(_masm, G3_amh_vmargslot, O0_argslot);
-
-      // On big-endian machine we duplicate the slot and store the MSW
-      // in the first slot.
-      __ add(__ argument_address(O0_argslot, O0_argslot, 1), O0_argslot);
-
-      insert_arg_slots(_masm, stack_move_unit(), O0_argslot, O1_scratch, O2_scratch, O3_scratch);
-
-      Address arg_lsw(O0_argslot, 0);
-      Address arg_msw(O0_argslot, -Interpreter::stackElementSize);
-
-      switch (ek) {
-      case _adapter_opt_i2l:
-        {
-#ifdef _LP64
-          __ ldsw(arg_lsw, O2_scratch);                 // Load LSW sign-extended
-#else
-          __ ldsw(arg_lsw, O3_scratch);                 // Load LSW sign-extended
-          __ srlx(O3_scratch, BitsPerInt, O2_scratch);  // Move MSW value to lower 32-bits for std
-#endif
-          __ st_long(O2_scratch, arg_msw);              // Uses O2/O3 on !_LP64
-        }
-        break;
-      case _adapter_opt_unboxl:
-        {
-          // Load the value up from the heap.
-          __ ld_ptr(arg_lsw, O1_scratch);
-          int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_LONG);
-          assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE), "");
-          __ null_check(O1_scratch, value_offset);
-          __ ld_long(Address(O1_scratch, value_offset), O2_scratch);  // Uses O2/O3 on !_LP64
-          __ st_long(O2_scratch, arg_msw);
-        }
-        break;
-      default:
-        ShouldNotReachHere();
-      }
-
-      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
-      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-    }
-    break;
-
-  case _adapter_opt_f2d:        // optimized subcase of adapt_prim_to_prim
-  case _adapter_opt_d2f:        // optimized subcase of adapt_prim_to_prim
-    {
-      // perform an in-place floating primitive conversion
-      __ unimplemented(entry_name(ek));
-    }
-    break;
-
-  case _adapter_prim_to_ref:
-    __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
-    break;
-
-  case _adapter_swap_args:
-  case _adapter_rot_args:
-    // handled completely by optimized cases
-    __ stop("init_AdapterMethodHandle should not issue this");
-    break;
-
-  case _adapter_opt_swap_1:
-  case _adapter_opt_swap_2:
-  case _adapter_opt_rot_1_up:
-  case _adapter_opt_rot_1_down:
-  case _adapter_opt_rot_2_up:
-  case _adapter_opt_rot_2_down:
-    {
-      int swap_slots = ek_adapter_opt_swap_slots(ek);
-      int rotate     = ek_adapter_opt_swap_mode(ek);
-
-      // 'argslot' is the position of the first argument to swap.
-      load_vmargslot(_masm, G3_amh_vmargslot, O0_argslot);
-      __ add(__ argument_address(O0_argslot, O0_argslot), O0_argslot);
-      if (VerifyMethodHandles)
-        verify_argslot(_masm, O0_argslot, O2_scratch, "swap point must fall within current frame");
-
-      // 'vminfo' is the second.
-      Register O1_destslot = O1_scratch;
-      load_conversion_vminfo(_masm, G3_amh_conversion, O1_destslot);
-      __ add(__ argument_address(O1_destslot, O1_destslot), O1_destslot);
-      if (VerifyMethodHandles)
-        verify_argslot(_masm, O1_destslot, O2_scratch, "swap point must fall within current frame");
-
-      assert(Interpreter::stackElementSize == wordSize, "else rethink use of wordSize here");
-      if (!rotate) {
-        // simple swap
-        for (int i = 0; i < swap_slots; i++) {
-          __ ld_ptr(            Address(O0_argslot,  i * wordSize), O2_scratch);
-          __ ld_ptr(            Address(O1_destslot, i * wordSize), O3_scratch);
-          __ st_ptr(O3_scratch, Address(O0_argslot,  i * wordSize));
-          __ st_ptr(O2_scratch, Address(O1_destslot, i * wordSize));
-        }
-      } else {
-        // A rotate is actually pair of moves, with an "odd slot" (or pair)
-        // changing place with a series of other slots.
-        // First, push the "odd slot", which is going to get overwritten
-        switch (swap_slots) {
-        case 2 :  __ ld_ptr(Address(O0_argslot, 1 * wordSize), O4_scratch); // fall-thru
-        case 1 :  __ ld_ptr(Address(O0_argslot, 0 * wordSize), O3_scratch); break;
-        default:  ShouldNotReachHere();
-        }
-        if (rotate > 0) {
-          // Here is rotate > 0:
-          // (low mem)                                          (high mem)
-          //     | dest:     more_slots...     | arg: odd_slot :arg+1 |
-          // =>
-          //     | dest: odd_slot | dest+1: more_slots...      :arg+1 |
-          // work argslot down to destslot, copying contiguous data upwards
-          // pseudo-code:
-          //   argslot  = src_addr - swap_bytes
-          //   destslot = dest_addr
-          //   while (argslot >= destslot) *(argslot + swap_bytes) = *(argslot + 0), argslot--;
-          move_arg_slots_up(_masm,
-                            O1_destslot,
-                            Address(O0_argslot, 0),
-                            swap_slots,
-                            O0_argslot, O2_scratch);
-        } else {
-          // Here is the other direction, rotate < 0:
-          // (low mem)                                          (high mem)
-          //     | arg: odd_slot | arg+1: more_slots...       :dest+1 |
-          // =>
-          //     | arg:    more_slots...     | dest: odd_slot :dest+1 |
-          // work argslot up to destslot, copying contiguous data downwards
-          // pseudo-code:
-          //   argslot  = src_addr + swap_bytes
-          //   destslot = dest_addr
-          //   while (argslot <= destslot) *(argslot - swap_bytes) = *(argslot + 0), argslot++;
-          // dest_slot denotes an exclusive upper limit
-          int limit_bias = OP_ROT_ARGS_DOWN_LIMIT_BIAS;
-          if (limit_bias != 0)
-            __ add(O1_destslot, - limit_bias * wordSize, O1_destslot);
-          move_arg_slots_down(_masm,
-                              Address(O0_argslot, swap_slots * wordSize),
-                              O1_destslot,
-                              -swap_slots,
-                              O0_argslot, O2_scratch);
-
-          __ sub(O1_destslot, swap_slots * wordSize, O1_destslot);
-        }
-        // pop the original first chunk into the destination slot, now free
-        switch (swap_slots) {
-        case 2 :  __ st_ptr(O4_scratch, Address(O1_destslot, 1 * wordSize)); // fall-thru
-        case 1 :  __ st_ptr(O3_scratch, Address(O1_destslot, 0 * wordSize)); break;
-        default:  ShouldNotReachHere();
-        }
-      }
-
-      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
-      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-    }
-    break;
-
-  case _adapter_dup_args:
-    {
-      // 'argslot' is the position of the first argument to duplicate.
-      load_vmargslot(_masm, G3_amh_vmargslot, O0_argslot);
-      __ add(__ argument_address(O0_argslot, O0_argslot), O0_argslot);
-
-      // 'stack_move' is negative number of words to duplicate.
-      Register O1_stack_move = O1_scratch;
-      load_stack_move(_masm, G3_amh_conversion, O1_stack_move);
-
-      if (VerifyMethodHandles) {
-        verify_argslots(_masm, O1_stack_move, O0_argslot, O2_scratch, O3_scratch, true,
-                        "copied argument(s) must fall within current frame");
-      }
-
-      if (UseStackBanging) {
-        // Save G3_method_handle since bang_stack_with_offset uses it as a temp register
-        __ mov(G3_method_handle, O3_scratch);
-         // Bang the stack before pushing args.
-        int frame_size = 256 * Interpreter::stackElementSize;  // conservative
-        __ generate_stack_overflow_check(frame_size + sizeof(RicochetFrame));
-        __ mov(O3_scratch, G3_method_handle);
-      }
-      // insert location is always the bottom of the argument list:
-      __ neg(O1_stack_move);
-      push_arg_slots(_masm, O0_argslot, O1_stack_move, O2_scratch, O3_scratch);
-
-      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
-      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-    }
-    break;
-
-  case _adapter_drop_args:
-    {
-      // 'argslot' is the position of the first argument to nuke.
-      load_vmargslot(_masm, G3_amh_vmargslot, O0_argslot);
-      __ add(__ argument_address(O0_argslot, O0_argslot), O0_argslot);
-
-      // 'stack_move' is number of words to drop.
-      Register O1_stack_move = O1_scratch;
-      load_stack_move(_masm, G3_amh_conversion, O1_stack_move);
-
-      remove_arg_slots(_masm, O1_stack_move, O0_argslot, O2_scratch, O3_scratch, O4_scratch);
-
-      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
-      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-    }
-    break;
-
-  case _adapter_collect_args:
-  case _adapter_fold_args:
-  case _adapter_spread_args:
-    // Handled completely by optimized cases.
-    __ stop("init_AdapterMethodHandle should not issue this");
-    break;
-
-  case _adapter_opt_collect_ref:
-  case _adapter_opt_collect_int:
-  case _adapter_opt_collect_long:
-  case _adapter_opt_collect_float:
-  case _adapter_opt_collect_double:
-  case _adapter_opt_collect_void:
-  case _adapter_opt_collect_0_ref:
-  case _adapter_opt_collect_1_ref:
-  case _adapter_opt_collect_2_ref:
-  case _adapter_opt_collect_3_ref:
-  case _adapter_opt_collect_4_ref:
-  case _adapter_opt_collect_5_ref:
-  case _adapter_opt_filter_S0_ref:
-  case _adapter_opt_filter_S1_ref:
-  case _adapter_opt_filter_S2_ref:
-  case _adapter_opt_filter_S3_ref:
-  case _adapter_opt_filter_S4_ref:
-  case _adapter_opt_filter_S5_ref:
-  case _adapter_opt_collect_2_S0_ref:
-  case _adapter_opt_collect_2_S1_ref:
-  case _adapter_opt_collect_2_S2_ref:
-  case _adapter_opt_collect_2_S3_ref:
-  case _adapter_opt_collect_2_S4_ref:
-  case _adapter_opt_collect_2_S5_ref:
-  case _adapter_opt_fold_ref:
-  case _adapter_opt_fold_int:
-  case _adapter_opt_fold_long:
-  case _adapter_opt_fold_float:
-  case _adapter_opt_fold_double:
-  case _adapter_opt_fold_void:
-  case _adapter_opt_fold_1_ref:
-  case _adapter_opt_fold_2_ref:
-  case _adapter_opt_fold_3_ref:
-  case _adapter_opt_fold_4_ref:
-  case _adapter_opt_fold_5_ref:
-    {
-      // Given a fresh incoming stack frame, build a new ricochet frame.
-      // On entry, TOS points at a return PC, and FP is the callers frame ptr.
-      // RSI/R13 has the caller's exact stack pointer, which we must also preserve.
-      // RCX contains an AdapterMethodHandle of the indicated kind.
-
-      // Relevant AMH fields:
-      // amh.vmargslot:
-      //   points to the trailing edge of the arguments
-      //   to filter, collect, or fold.  For a boxing operation,
-      //   it points just after the single primitive value.
-      // amh.argument:
-      //   recursively called MH, on |collect| arguments
-      // amh.vmtarget:
-      //   final destination MH, on return value, etc.
-      // amh.conversion.dest:
-      //   tells what is the type of the return value
-      //   (not needed here, since dest is also derived from ek)
-      // amh.conversion.vminfo:
-      //   points to the trailing edge of the return value
-      //   when the vmtarget is to be called; this is
-      //   equal to vmargslot + (retained ? |collect| : 0)
-
-      // Pass 0 or more argument slots to the recursive target.
-      int collect_count_constant = ek_adapter_opt_collect_count(ek);
-
-      // The collected arguments are copied from the saved argument list:
-      int collect_slot_constant = ek_adapter_opt_collect_slot(ek);
-
-      assert(ek_orig == _adapter_collect_args ||
-             ek_orig == _adapter_fold_args, "");
-      bool retain_original_args = (ek_orig == _adapter_fold_args);
-
-      // The return value is replaced (or inserted) at the 'vminfo' argslot.
-      // Sometimes we can compute this statically.
-      int dest_slot_constant = -1;
-      if (!retain_original_args)
-        dest_slot_constant = collect_slot_constant;
-      else if (collect_slot_constant >= 0 && collect_count_constant >= 0)
-        // We are preserving all the arguments, and the return value is prepended,
-        // so the return slot is to the left (above) the |collect| sequence.
-        dest_slot_constant = collect_slot_constant + collect_count_constant;
-
-      // Replace all those slots by the result of the recursive call.
-      // The result type can be one of ref, int, long, float, double, void.
-      // In the case of void, nothing is pushed on the stack after return.
-      BasicType dest = ek_adapter_opt_collect_type(ek);
-      assert(dest == type2wfield[dest], "dest is a stack slot type");
-      int dest_count = type2size[dest];
-      assert(dest_count == 1 || dest_count == 2 || (dest_count == 0 && dest == T_VOID), "dest has a size");
-
-      // Choose a return continuation.
-      EntryKind ek_ret = _adapter_opt_return_any;
-      if (dest != T_CONFLICT && OptimizeMethodHandles) {
-        switch (dest) {
-        case T_INT    : ek_ret = _adapter_opt_return_int;     break;
-        case T_LONG   : ek_ret = _adapter_opt_return_long;    break;
-        case T_FLOAT  : ek_ret = _adapter_opt_return_float;   break;
-        case T_DOUBLE : ek_ret = _adapter_opt_return_double;  break;
-        case T_OBJECT : ek_ret = _adapter_opt_return_ref;     break;
-        case T_VOID   : ek_ret = _adapter_opt_return_void;    break;
-        default       : ShouldNotReachHere();
-        }
-        if (dest == T_OBJECT && dest_slot_constant >= 0) {
-          EntryKind ek_try = EntryKind(_adapter_opt_return_S0_ref + dest_slot_constant);
-          if (ek_try <= _adapter_opt_return_LAST &&
-              ek_adapter_opt_return_slot(ek_try) == dest_slot_constant) {
-            ek_ret = ek_try;
-          }
-        }
-        assert(ek_adapter_opt_return_type(ek_ret) == dest, "");
-      }
-
-      // Already pushed:  ... keep1 | collect | keep2 |
-
-      // Push a few extra argument words, if we need them to store the return value.
-      {
-        int extra_slots = 0;
-        if (retain_original_args) {
-          extra_slots = dest_count;
-        } else if (collect_count_constant == -1) {
-          extra_slots = dest_count;  // collect_count might be zero; be generous
-        } else if (dest_count > collect_count_constant) {
-          extra_slots = (dest_count - collect_count_constant);
-        } else {
-          // else we know we have enough dead space in |collect| to repurpose for return values
-        }
-        if (extra_slots != 0) {
-          __ sub(SP, round_to(extra_slots, 2) * Interpreter::stackElementSize, SP);
-        }
-      }
-
-      // Set up Ricochet Frame.
-      __ mov(SP, O5_savedSP);  // record SP for the callee
-
-      // One extra (empty) slot for outgoing target MH (see Gargs computation below).
-      __ save_frame(2);  // Note: we need to add 2 slots since frame::memory_parameter_word_sp_offset is 23.
-
-      // Note: Gargs is live throughout the following, until we make our recursive call.
-      // And the RF saves a copy in L4_saved_args_base.
-
-      RicochetFrame::enter_ricochet_frame(_masm, G3_method_handle, Gargs,
-                                          entry(ek_ret)->from_interpreted_entry());
-
-      // Compute argument base:
-      // Set up Gargs for current frame, extra (empty) slot is for outgoing target MH (space reserved by save_frame above).
-      __ add(FP, STACK_BIAS - (1 * Interpreter::stackElementSize), Gargs);
-
-      // Now pushed:  ... keep1 | collect | keep2 | extra | [RF]
-
-#ifdef ASSERT
-      if (VerifyMethodHandles && dest != T_CONFLICT) {
-        BLOCK_COMMENT("verify AMH.conv.dest {");
-        extract_conversion_dest_type(_masm, RicochetFrame::L5_conversion, O1_scratch);
-        Label L_dest_ok;
-        __ cmp(O1_scratch, (int) dest);
-        __ br(Assembler::equal, false, Assembler::pt, L_dest_ok);
-        __ delayed()->nop();
-        if (dest == T_INT) {
-          for (int bt = T_BOOLEAN; bt < T_INT; bt++) {
-            if (is_subword_type(BasicType(bt))) {
-              __ cmp(O1_scratch, (int) bt);
-              __ br(Assembler::equal, false, Assembler::pt, L_dest_ok);
-              __ delayed()->nop();
-            }
-          }
-        }
-        __ stop("bad dest in AMH.conv");
-        __ BIND(L_dest_ok);
-        BLOCK_COMMENT("} verify AMH.conv.dest");
-      }
-#endif //ASSERT
-
-      // Find out where the original copy of the recursive argument sequence begins.
-      Register O0_coll = O0_scratch;
-      {
-        RegisterOrConstant collect_slot = collect_slot_constant;
-        if (collect_slot_constant == -1) {
-          load_vmargslot(_masm, G3_amh_vmargslot, O1_scratch);
-          collect_slot = O1_scratch;
-        }
-        // collect_slot might be 0, but we need the move anyway.
-        __ add(RicochetFrame::L4_saved_args_base, __ argument_offset(collect_slot, collect_slot.register_or_noreg()), O0_coll);
-        // O0_coll now points at the trailing edge of |collect| and leading edge of |keep2|
-      }
-
-      // Replace the old AMH with the recursive MH.  (No going back now.)
-      // In the case of a boxing call, the recursive call is to a 'boxer' method,
-      // such as Integer.valueOf or Long.valueOf.  In the case of a filter
-      // or collect call, it will take one or more arguments, transform them,
-      // and return some result, to store back into argument_base[vminfo].
-      __ load_heap_oop(G3_amh_argument, G3_method_handle);
-      if (VerifyMethodHandles)  verify_method_handle(_masm, G3_method_handle, O1_scratch, O2_scratch);
-
-      // Calculate |collect|, the number of arguments we are collecting.
-      Register O1_collect_count = O1_scratch;
-      RegisterOrConstant collect_count;
-      if (collect_count_constant < 0) {
-        __ load_method_handle_vmslots(O1_collect_count, G3_method_handle, O2_scratch);
-        collect_count = O1_collect_count;
-      } else {
-        collect_count = collect_count_constant;
-#ifdef ASSERT
-        if (VerifyMethodHandles) {
-          BLOCK_COMMENT("verify collect_count_constant {");
-          __ load_method_handle_vmslots(O3_scratch, G3_method_handle, O2_scratch);
-          Label L_count_ok;
-          __ cmp_and_br_short(O3_scratch, collect_count_constant, Assembler::equal, Assembler::pt, L_count_ok);
-          __ stop("bad vminfo in AMH.conv");
-          __ BIND(L_count_ok);
-          BLOCK_COMMENT("} verify collect_count_constant");
-        }
-#endif //ASSERT
-      }
-
-      // copy |collect| slots directly to TOS:
-      push_arg_slots(_masm, O0_coll, collect_count, O2_scratch, O3_scratch);
-      // Now pushed:  ... keep1 | collect | keep2 | RF... | collect |
-      // O0_coll still points at the trailing edge of |collect| and leading edge of |keep2|
-
-      // If necessary, adjust the saved arguments to make room for the eventual return value.
-      // Normal adjustment:  ... keep1 | +dest+ | -collect- | keep2 | RF... | collect |
-      // If retaining args:  ... keep1 | +dest+ |  collect  | keep2 | RF... | collect |
-      // In the non-retaining case, this might move keep2 either up or down.
-      // We don't have to copy the whole | RF... collect | complex,
-      // but we must adjust RF.saved_args_base.
-      // Also, from now on, we will forget about the original copy of |collect|.
-      // If we are retaining it, we will treat it as part of |keep2|.
-      // For clarity we will define |keep3| = |collect|keep2| or |keep2|.
-
-      BLOCK_COMMENT("adjust trailing arguments {");
-      // Compare the sizes of |+dest+| and |-collect-|, which are opposed opening and closing movements.
-      int                open_count  = dest_count;
-      RegisterOrConstant close_count = collect_count_constant;
-      Register O1_close_count = O1_collect_count;
-      if (retain_original_args) {
-        close_count = constant(0);
-      } else if (collect_count_constant == -1) {
-        close_count = O1_collect_count;
-      }
-
-      // How many slots need moving?  This is simply dest_slot (0 => no |keep3|).
-      RegisterOrConstant keep3_count;
-      Register O2_keep3_count = O2_scratch;
-      if (dest_slot_constant < 0) {
-        extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O2_keep3_count);
-        keep3_count = O2_keep3_count;
-      } else  {
-        keep3_count = dest_slot_constant;
-#ifdef ASSERT
-        if (VerifyMethodHandles && dest_slot_constant < 0) {
-          BLOCK_COMMENT("verify dest_slot_constant {");
-          extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O3_scratch);
-          Label L_vminfo_ok;
-          __ cmp_and_br_short(O3_scratch, dest_slot_constant, Assembler::equal, Assembler::pt, L_vminfo_ok);
-          __ stop("bad vminfo in AMH.conv");
-          __ BIND(L_vminfo_ok);
-          BLOCK_COMMENT("} verify dest_slot_constant");
-        }
-#endif //ASSERT
-      }
-
-      // tasks remaining:
-      bool move_keep3 = (!keep3_count.is_constant() || keep3_count.as_constant() != 0);
-      bool stomp_dest = (NOT_DEBUG(dest == T_OBJECT) DEBUG_ONLY(dest_count != 0));
-      bool fix_arg_base = (!close_count.is_constant() || open_count != close_count.as_constant());
-
-      // Old and new argument locations (based at slot 0).
-      // Net shift (&new_argv - &old_argv) is (close_count - open_count).
-      bool zero_open_count = (open_count == 0);  // remember this bit of info
-      if (move_keep3 && fix_arg_base) {
-        // It will be easier to have everything in one register:
-        if (close_count.is_register()) {
-          // Deduct open_count from close_count register to get a clean +/- value.
-          __ sub(close_count.as_register(), open_count, close_count.as_register());
-        } else {
-          close_count = close_count.as_constant() - open_count;
-        }
-        open_count = 0;
-      }
-      Register L4_old_argv = RicochetFrame::L4_saved_args_base;
-      Register O3_new_argv = O3_scratch;
-      if (fix_arg_base) {
-        __ add(L4_old_argv, __ argument_offset(close_count, O4_scratch), O3_new_argv,
-               -(open_count * Interpreter::stackElementSize));
-      }
-
-      // First decide if any actual data are to be moved.
-      // We can skip if (a) |keep3| is empty, or (b) the argument list size didn't change.
-      // (As it happens, all movements involve an argument list size change.)
-
-      // If there are variable parameters, use dynamic checks to skip around the whole mess.
-      Label L_done;
-      if (keep3_count.is_register()) {
-        __ cmp_and_br_short(keep3_count.as_register(), 0, Assembler::equal, Assembler::pn, L_done);
-      }
-      if (close_count.is_register()) {
-        __ cmp_and_br_short(close_count.as_register(), open_count, Assembler::equal, Assembler::pn, L_done);
-      }
-
-      if (move_keep3 && fix_arg_base) {
-        bool emit_move_down = false, emit_move_up = false, emit_guard = false;
-        if (!close_count.is_constant()) {
-          emit_move_down = emit_guard = !zero_open_count;
-          emit_move_up   = true;
-        } else if (open_count != close_count.as_constant()) {
-          emit_move_down = (open_count > close_count.as_constant());
-          emit_move_up   = !emit_move_down;
-        }
-        Label L_move_up;
-        if (emit_guard) {
-          __ cmp(close_count.as_register(), open_count);
-          __ br(Assembler::greater, false, Assembler::pn, L_move_up);
-          __ delayed()->nop();
-        }
-
-        if (emit_move_down) {
-          // Move arguments down if |+dest+| > |-collect-|
-          // (This is rare, except when arguments are retained.)
-          // This opens space for the return value.
-          if (keep3_count.is_constant()) {
-            for (int i = 0; i < keep3_count.as_constant(); i++) {
-              __ ld_ptr(            Address(L4_old_argv, i * Interpreter::stackElementSize), O4_scratch);
-              __ st_ptr(O4_scratch, Address(O3_new_argv, i * Interpreter::stackElementSize)            );
-            }
-          } else {
-            // Live: O1_close_count, O2_keep3_count, O3_new_argv
-            Register argv_top = O0_scratch;
-            __ add(L4_old_argv, __ argument_offset(keep3_count, O4_scratch), argv_top);
-            move_arg_slots_down(_masm,
-                                Address(L4_old_argv, 0),  // beginning of old argv
-                                argv_top,                 // end of old argv
-                                close_count,              // distance to move down (must be negative)
-                                O4_scratch, G5_scratch);
-          }
-        }
-
-        if (emit_guard) {
-          __ ba_short(L_done);  // assumes emit_move_up is true also
-          __ BIND(L_move_up);
-        }
-
-        if (emit_move_up) {
-          // Move arguments up if |+dest+| < |-collect-|
-          // (This is usual, except when |keep3| is empty.)
-          // This closes up the space occupied by the now-deleted collect values.
-          if (keep3_count.is_constant()) {
-            for (int i = keep3_count.as_constant() - 1; i >= 0; i--) {
-              __ ld_ptr(            Address(L4_old_argv, i * Interpreter::stackElementSize), O4_scratch);
-              __ st_ptr(O4_scratch, Address(O3_new_argv, i * Interpreter::stackElementSize)            );
-            }
-          } else {
-            Address argv_top(L4_old_argv, __ argument_offset(keep3_count, O4_scratch));
-            // Live: O1_close_count, O2_keep3_count, O3_new_argv
-            move_arg_slots_up(_masm,
-                              L4_old_argv,  // beginning of old argv
-                              argv_top,     // end of old argv
-                              close_count,  // distance to move up (must be positive)
-                              O4_scratch, G5_scratch);
-          }
-        }
-      }
-      __ BIND(L_done);
-
-      if (fix_arg_base) {
-        // adjust RF.saved_args_base
-        __ mov(O3_new_argv, RicochetFrame::L4_saved_args_base);
-      }
-
-      if (stomp_dest) {
-        // Stomp the return slot, so it doesn't hold garbage.
-        // This isn't strictly necessary, but it may help detect bugs.
-        __ set(RicochetFrame::RETURN_VALUE_PLACEHOLDER, O4_scratch);
-        __ st_ptr(O4_scratch, Address(RicochetFrame::L4_saved_args_base,
-                                      __ argument_offset(keep3_count, keep3_count.register_or_noreg())));  // uses O2_keep3_count
-      }
-      BLOCK_COMMENT("} adjust trailing arguments");
-
-      BLOCK_COMMENT("do_recursive_call");
-      __ mov(SP, O5_savedSP);  // record SP for the callee
-      __ set(ExternalAddress(SharedRuntime::ricochet_blob()->bounce_addr() - frame::pc_return_offset), O7);
-      // The globally unique bounce address has two purposes:
-      // 1. It helps the JVM recognize this frame (frame::is_ricochet_frame).
-      // 2. When returned to, it cuts back the stack and redirects control flow
-      //    to the return handler.
-      // The return handler will further cut back the stack when it takes
-      // down the RF.  Perhaps there is a way to streamline this further.
-
-      if (UseStackBanging) {
-        // Save G3_method_handle since bang_stack_with_offset uses it as a temp register
-        __ mov(G3_method_handle, O4_scratch);
-        // Bang the stack before recursive call.
-        // Even if slots == 0, we are inside a RicochetFrame.
-        int frame_size = collect_count.is_constant() ? collect_count.as_constant() * wordSize : -1;
-        if (frame_size < 0) {
-          frame_size = 256 * Interpreter::stackElementSize;  // conservative
-        }
-        __ generate_stack_overflow_check(frame_size + sizeof(RicochetFrame));
-        __ mov(O4_scratch, G3_method_handle);
-      }
-      // State during recursive call:
-      // ... keep1 | dest | dest=42 | keep3 | RF... | collect | bounce_pc |
-      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-    }
-    break;
-
-  case _adapter_opt_return_ref:
-  case _adapter_opt_return_int:
-  case _adapter_opt_return_long:
-  case _adapter_opt_return_float:
-  case _adapter_opt_return_double:
-  case _adapter_opt_return_void:
-  case _adapter_opt_return_S0_ref:
-  case _adapter_opt_return_S1_ref:
-  case _adapter_opt_return_S2_ref:
-  case _adapter_opt_return_S3_ref:
-  case _adapter_opt_return_S4_ref:
-  case _adapter_opt_return_S5_ref:
-    {
-      BasicType dest_type_constant = ek_adapter_opt_return_type(ek);
-      int       dest_slot_constant = ek_adapter_opt_return_slot(ek);
-
-      if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
-
-      if (dest_slot_constant == -1) {
-        // The current stub is a general handler for this dest_type.
-        // It can be called from _adapter_opt_return_any below.
-        // Stash the address in a little table.
-        assert((dest_type_constant & CONV_TYPE_MASK) == dest_type_constant, "oob");
-        address return_handler = __ pc();
-        _adapter_return_handlers[dest_type_constant] = return_handler;
-        if (dest_type_constant == T_INT) {
-          // do the subword types too
-          for (int bt = T_BOOLEAN; bt < T_INT; bt++) {
-            if (is_subword_type(BasicType(bt)) &&
-                _adapter_return_handlers[bt] == NULL) {
-              _adapter_return_handlers[bt] = return_handler;
-            }
-          }
-        }
-      }
-
-      // On entry to this continuation handler, make Gargs live again.
-      __ mov(RicochetFrame::L4_saved_args_base, Gargs);
-
-      Register O7_temp   = O7;
-      Register O5_vminfo = O5;
-
-      RegisterOrConstant dest_slot = dest_slot_constant;
-      if (dest_slot_constant == -1) {
-        extract_conversion_vminfo(_masm, RicochetFrame::L5_conversion, O5_vminfo);
-        dest_slot = O5_vminfo;
-      }
-      // Store the result back into the argslot.
-      // This code uses the interpreter calling sequence, in which the return value
-      // is usually left in the TOS register, as defined by InterpreterMacroAssembler::pop.
-      // There are certain irregularities with floating point values, which can be seen
-      // in TemplateInterpreterGenerator::generate_return_entry_for.
-      move_return_value(_masm, dest_type_constant, __ argument_address(dest_slot, O7_temp));
-
-      RicochetFrame::leave_ricochet_frame(_masm, G3_method_handle, I5_savedSP, I7);
-
-      // Load the final target and go.
-      if (VerifyMethodHandles)  verify_method_handle(_masm, G3_method_handle, O0_scratch, O1_scratch);
-      __ restore(I5_savedSP, G0, SP);
-      __ jump_to_method_handle_entry(G3_method_handle, O0_scratch);
-      __ illtrap(0);
-    }
-    break;
-
-  case _adapter_opt_return_any:
-    {
-      Register O7_temp      = O7;
-      Register O5_dest_type = O5;
-
-      if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
-      extract_conversion_dest_type(_masm, RicochetFrame::L5_conversion, O5_dest_type);
-      __ set(ExternalAddress((address) &_adapter_return_handlers[0]), O7_temp);
-      __ sll_ptr(O5_dest_type, LogBytesPerWord, O5_dest_type);
-      __ ld_ptr(O7_temp, O5_dest_type, O7_temp);
-
-#ifdef ASSERT
-      { Label L_ok;
-        __ br_notnull_short(O7_temp, Assembler::pt, L_ok);
-        __ stop("bad method handle return");
-        __ BIND(L_ok);
-      }
-#endif //ASSERT
-      __ JMP(O7_temp, 0);
-      __ delayed()->nop();
-    }
-    break;
-
-  case _adapter_opt_spread_0:
-  case _adapter_opt_spread_1_ref:
-  case _adapter_opt_spread_2_ref:
-  case _adapter_opt_spread_3_ref:
-  case _adapter_opt_spread_4_ref:
-  case _adapter_opt_spread_5_ref:
-  case _adapter_opt_spread_ref:
-  case _adapter_opt_spread_byte:
-  case _adapter_opt_spread_char:
-  case _adapter_opt_spread_short:
-  case _adapter_opt_spread_int:
-  case _adapter_opt_spread_long:
-  case _adapter_opt_spread_float:
-  case _adapter_opt_spread_double:
-    {
-      // spread an array out into a group of arguments
-      int  length_constant    = ek_adapter_opt_spread_count(ek);
-      bool length_can_be_zero = (length_constant == 0);
-      if (length_constant < 0) {
-        // some adapters with variable length must handle the zero case
-        if (!OptimizeMethodHandles ||
-            ek_adapter_opt_spread_type(ek) != T_OBJECT)
-          length_can_be_zero = true;
-      }
-
-      // find the address of the array argument
-      load_vmargslot(_masm, G3_amh_vmargslot, O0_argslot);
-      __ add(__ argument_address(O0_argslot, O0_argslot), O0_argslot);
-
-      // O0_argslot points both to the array and to the first output arg
-      Address vmarg = Address(O0_argslot, 0);
-
-      // Get the array value.
-      Register  O1_array       = O1_scratch;
-      Register  O2_array_klass = O2_scratch;
-      BasicType elem_type      = ek_adapter_opt_spread_type(ek);
-      int       elem_slots     = type2size[elem_type];  // 1 or 2
-      int       array_slots    = 1;  // array is always a T_OBJECT
-      int       length_offset  = arrayOopDesc::length_offset_in_bytes();
-      int       elem0_offset   = arrayOopDesc::base_offset_in_bytes(elem_type);
-      __ ld_ptr(vmarg, O1_array);
-
-      Label L_array_is_empty, L_insert_arg_space, L_copy_args, L_args_done;
-      if (length_can_be_zero) {
-        // handle the null pointer case, if zero is allowed
-        Label L_skip;
-        if (length_constant < 0) {
-          load_conversion_vminfo(_masm, G3_amh_conversion, O3_scratch);
-          __ cmp_zero_and_br(Assembler::notZero, O3_scratch, L_skip);
-          __ delayed()->nop(); // to avoid back-to-back cbcond instructions
-        }
-        __ br_null_short(O1_array, Assembler::pn, L_array_is_empty);
-        __ BIND(L_skip);
-      }
-      __ null_check(O1_array, oopDesc::klass_offset_in_bytes());
-      __ load_klass(O1_array, O2_array_klass);
-
-      // Check the array type.
-      Register O3_klass = O3_scratch;
-      __ load_heap_oop(G3_amh_argument, O3_klass);  // this is a Class object!
-      load_klass_from_Class(_masm, O3_klass, O4_scratch, G5_scratch);
-
-      Label L_ok_array_klass, L_bad_array_klass, L_bad_array_length;
-      __ check_klass_subtype(O2_array_klass, O3_klass, O4_scratch, G5_scratch, L_ok_array_klass);
-      // If we get here, the type check failed!
-      __ ba_short(L_bad_array_klass);
-      __ BIND(L_ok_array_klass);
-
-      // Check length.
-      if (length_constant >= 0) {
-        __ ldsw(Address(O1_array, length_offset), O4_scratch);
-        __ cmp(O4_scratch, length_constant);
-      } else {
-        Register O3_vminfo = O3_scratch;
-        load_conversion_vminfo(_masm, G3_amh_conversion, O3_vminfo);
-        __ ldsw(Address(O1_array, length_offset), O4_scratch);
-        __ cmp(O3_vminfo, O4_scratch);
-      }
-      __ br(Assembler::notEqual, false, Assembler::pn, L_bad_array_length);
-      __ delayed()->nop();
-
-      Register O2_argslot_limit = O2_scratch;
-
-      // Array length checks out.  Now insert any required stack slots.
-      if (length_constant == -1) {
-        // Form a pointer to the end of the affected region.
-        __ add(O0_argslot, Interpreter::stackElementSize, O2_argslot_limit);
-        // 'stack_move' is negative number of words to insert
-        // This number already accounts for elem_slots.
-        Register O3_stack_move = O3_scratch;
-        load_stack_move(_masm, G3_amh_conversion, O3_stack_move);
-        __ cmp(O3_stack_move, 0);
-        assert(stack_move_unit() < 0, "else change this comparison");
-        __ br(Assembler::less, false, Assembler::pn, L_insert_arg_space);
-        __ delayed()->nop();
-        __ br(Assembler::equal, false, Assembler::pn, L_copy_args);
-        __ delayed()->nop();
-        // single argument case, with no array movement
-        __ BIND(L_array_is_empty);
-        remove_arg_slots(_masm, -stack_move_unit() * array_slots,
-                         O0_argslot, O1_scratch, O2_scratch, O3_scratch);
-        __ ba_short(L_args_done);  // no spreading to do
-        __ BIND(L_insert_arg_space);
-        // come here in the usual case, stack_move < 0 (2 or more spread arguments)
-        // Live: O1_array, O2_argslot_limit, O3_stack_move
-        insert_arg_slots(_masm, O3_stack_move,
-                         O0_argslot, O4_scratch, G5_scratch, O1_scratch);
-        // reload from rdx_argslot_limit since rax_argslot is now decremented
-        __ ld_ptr(Address(O2_argslot_limit, -Interpreter::stackElementSize), O1_array);
-      } else if (length_constant >= 1) {
-        int new_slots = (length_constant * elem_slots) - array_slots;
-        insert_arg_slots(_masm, new_slots * stack_move_unit(),
-                         O0_argslot, O2_scratch, O3_scratch, O4_scratch);
-      } else if (length_constant == 0) {
-        __ BIND(L_array_is_empty);
-        remove_arg_slots(_masm, -stack_move_unit() * array_slots,
-                         O0_argslot, O1_scratch, O2_scratch, O3_scratch);
-      } else {
-        ShouldNotReachHere();
-      }
-
-      // Copy from the array to the new slots.
-      // Note: Stack change code preserves integrity of O0_argslot pointer.
-      // So even after slot insertions, O0_argslot still points to first argument.
-      // Beware:  Arguments that are shallow on the stack are deep in the array,
-      // and vice versa.  So a downward-growing stack (the usual) has to be copied
-      // elementwise in reverse order from the source array.
-      __ BIND(L_copy_args);
-      if (length_constant == -1) {
-        // [O0_argslot, O2_argslot_limit) is the area we are inserting into.
-        // Array element [0] goes at O0_argslot_limit[-wordSize].
-        Register O1_source = O1_array;
-        __ add(Address(O1_array, elem0_offset), O1_source);
-        Register O4_fill_ptr = O4_scratch;
-        __ mov(O2_argslot_limit, O4_fill_ptr);
-        Label L_loop;
-        __ BIND(L_loop);
-        __ add(O4_fill_ptr, -Interpreter::stackElementSize * elem_slots, O4_fill_ptr);
-        move_typed_arg(_masm, elem_type, true,
-                       Address(O1_source, 0), Address(O4_fill_ptr, 0),
-                       O2_scratch);  // must be an even register for !_LP64 long moves (uses O2/O3)
-        __ add(O1_source, type2aelembytes(elem_type), O1_source);
-        __ cmp_and_brx_short(O4_fill_ptr, O0_argslot, Assembler::greaterUnsigned, Assembler::pt, L_loop);
-      } else if (length_constant == 0) {
-        // nothing to copy
-      } else {
-        int elem_offset = elem0_offset;
-        int slot_offset = length_constant * Interpreter::stackElementSize;
-        for (int index = 0; index < length_constant; index++) {
-          slot_offset -= Interpreter::stackElementSize * elem_slots;  // fill backward
-          move_typed_arg(_masm, elem_type, true,
-                         Address(O1_array, elem_offset), Address(O0_argslot, slot_offset),
-                         O2_scratch);  // must be an even register for !_LP64 long moves (uses O2/O3)
-          elem_offset += type2aelembytes(elem_type);
-        }
-      }
-      __ BIND(L_args_done);
-
-      // Arguments are spread.  Move to next method handle.
-      __ load_heap_oop(G3_mh_vmtarget, G3_method_handle);
-      __ jump_to_method_handle_entry(G3_method_handle, O1_scratch);
-
-      __ BIND(L_bad_array_klass);
-      assert(!vmarg.uses(O2_required), "must be different registers");
-      __ load_heap_oop(Address(O2_array_klass, java_mirror_offset), O2_required);  // required class
-      __ ld_ptr(       vmarg,                                       O1_actual);    // bad object
-      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
-      __ delayed()->mov(Bytecodes::_aaload,                         O0_code);      // who is complaining?
-
-      __ bind(L_bad_array_length);
-      assert(!vmarg.uses(O2_required), "must be different registers");
-      __ mov(   G3_method_handle,                O2_required);  // required class
-      __ ld_ptr(vmarg,                           O1_actual);    // bad object
-      __ jump_to(AddressLiteral(from_interpreted_entry(_raise_exception)), O3_scratch);
-      __ delayed()->mov(Bytecodes::_arraylength, O0_code);      // who is complaining?
-    }
-    break;
-
-  default:
-    DEBUG_ONLY(tty->print_cr("bad ek=%d (%s)", (int)ek, entry_name(ek)));
-    ShouldNotReachHere();
-  }
-  BLOCK_COMMENT(err_msg("} Entry %s", entry_name(ek)));
-
-  address me_cookie = MethodHandleEntry::start_compiled_entry(_masm, interp_entry);
-  __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
-
-  init_entry(ek, MethodHandleEntry::finish_compiled_entry(_masm, me_cookie));
-}
diff --git a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp
index 7382b9c..acc4436 100644
--- a/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/methodHandles_sparc.hpp
@@ -30,186 +30,9 @@
   adapter_code_size = NOT_LP64(23000 DEBUG_ONLY(+ 40000)) LP64_ONLY(35000 DEBUG_ONLY(+ 50000))
 };
 
-public:
-
-class RicochetFrame : public ResourceObj {
-  friend class MethodHandles;
-
- private:
-  /*
-    RF field            x86                 SPARC
-    sender_pc           *(rsp+0)            I7-0x8
-    sender_link         rbp                 I6+BIAS
-    exact_sender_sp     rsi/r13             I5_savedSP
-    conversion          *(rcx+&amh_conv)    L5_conv
-    saved_args_base     rax                 L4_sab (cf. Gargs = G4)
-    saved_args_layout   #NULL               L3_sal
-    saved_target        *(rcx+&mh_vmtgt)    L2_stgt
-    continuation        #STUB_CON           L1_cont
-   */
-  static const Register L1_continuation     ;  // what to do when control gets back here
-  static const Register L2_saved_target     ;  // target method handle to invoke on saved_args
-  static const Register L3_saved_args_layout;  // caching point for MethodTypeForm.vmlayout cookie
-  static const Register L4_saved_args_base  ;  // base of pushed arguments (slot 0, arg N) (-3)
-  static const Register L5_conversion       ;  // misc. information from original AdapterMethodHandle (-2)
-
-  frame _fr;
-
-  RicochetFrame(const frame& fr) : _fr(fr) { }
-
-  intptr_t* register_addr(Register reg) const  {
-    assert((_fr.sp() + reg->sp_offset_in_saved_window()) == _fr.register_addr(reg), "must agree");
-    return _fr.register_addr(reg);
-  }
-  intptr_t  register_value(Register reg) const { return *register_addr(reg); }
-
- public:
-  intptr_t* continuation() const        { return (intptr_t*) register_value(L1_continuation); }
-  oop       saved_target() const        { return (oop)       register_value(L2_saved_target); }
-  oop       saved_args_layout() const   { return (oop)       register_value(L3_saved_args_layout); }
-  intptr_t* saved_args_base() const     { return (intptr_t*) register_value(L4_saved_args_base); }
-  intptr_t  conversion() const          { return             register_value(L5_conversion); }
-  intptr_t* exact_sender_sp() const     { return (intptr_t*) register_value(I5_savedSP); }
-  intptr_t* sender_link() const         { return _fr.sender_sp(); }  // XXX
-  address   sender_pc() const           { return _fr.sender_pc(); }
-
-  // This value is not used for much, but it apparently must be nonzero.
-  static int frame_size_in_bytes()              { return wordSize * 4; }
-
-  intptr_t* extended_sender_sp() const  { return saved_args_base(); }
-
-  intptr_t  return_value_slot_number() const {
-    return adapter_conversion_vminfo(conversion());
-  }
-  BasicType return_value_type() const {
-    return adapter_conversion_dest_type(conversion());
-  }
-  bool has_return_value_slot() const {
-    return return_value_type() != T_VOID;
-  }
-  intptr_t* return_value_slot_addr() const {
-    assert(has_return_value_slot(), "");
-    return saved_arg_slot_addr(return_value_slot_number());
-  }
-  intptr_t* saved_target_slot_addr() const {
-    return saved_arg_slot_addr(saved_args_length());
-  }
-  intptr_t* saved_arg_slot_addr(int slot) const {
-    assert(slot >= 0, "");
-    return (intptr_t*)( (address)saved_args_base() + (slot * Interpreter::stackElementSize) );
-  }
-
-  jint      saved_args_length() const;
-  jint      saved_arg_offset(int arg) const;
-
-  // GC interface
-  oop*  saved_target_addr()                     { return (oop*)register_addr(L2_saved_target); }
-  oop*  saved_args_layout_addr()                { return (oop*)register_addr(L3_saved_args_layout); }
-
-  oop  compute_saved_args_layout(bool read_cache, bool write_cache);
-
-#ifdef ASSERT
-  // The magic number is supposed to help find ricochet frames within the bytes of stack dumps.
-  enum { MAGIC_NUMBER_1 = 0xFEED03E, MAGIC_NUMBER_2 = 0xBEEF03E };
-  static const Register L0_magic_number_1   ;  // cookie for debugging, at start of RSA
-  static Address magic_number_2_addr()  { return Address(L4_saved_args_base, -wordSize); }
-  intptr_t magic_number_1() const       { return register_value(L0_magic_number_1); }
-  intptr_t magic_number_2() const       { return saved_args_base()[-1]; }
-#endif //ASSERT
-
- public:
-  enum { RETURN_VALUE_PLACEHOLDER = (NOT_DEBUG(0) DEBUG_ONLY(42)) };
-
-  void verify() const NOT_DEBUG_RETURN; // check for MAGIC_NUMBER, etc.
-
-  static void generate_ricochet_blob(MacroAssembler* _masm,
-                                     // output params:
-                                     int* bounce_offset,
-                                     int* exception_offset,
-                                     int* frame_size_in_words);
-
-  static void enter_ricochet_frame(MacroAssembler* _masm,
-                                   Register recv_reg,
-                                   Register argv_reg,
-                                   address return_handler);
-
-  static void leave_ricochet_frame(MacroAssembler* _masm,
-                                   Register recv_reg,
-                                   Register new_sp_reg,
-                                   Register sender_pc_reg);
-
-  static RicochetFrame* from_frame(const frame& fr) {
-    RicochetFrame* rf = new RicochetFrame(fr);
-    rf->verify();
-    return rf;
-  }
-
-  static void verify_clean(MacroAssembler* _masm) NOT_DEBUG_RETURN;
-
-  static void describe(const frame* fr, FrameValues& values, int frame_no) PRODUCT_RETURN;
-};
-
 // Additional helper methods for MethodHandles code generation:
 public:
   static void load_klass_from_Class(MacroAssembler* _masm, Register klass_reg, Register temp_reg, Register temp2_reg);
-  static void load_conversion_vminfo(MacroAssembler* _masm, Address conversion_field_addr, Register reg);
-  static void extract_conversion_vminfo(MacroAssembler* _masm, Register conversion_field_reg, Register reg);
-  static void extract_conversion_dest_type(MacroAssembler* _masm, Register conversion_field_reg, Register reg);
-
-  static void load_stack_move(MacroAssembler* _masm,
-                              Address G3_amh_conversion,
-                              Register G5_stack_move);
-
-  static void insert_arg_slots(MacroAssembler* _masm,
-                               RegisterOrConstant arg_slots,
-                               Register argslot_reg,
-                               Register temp_reg, Register temp2_reg, Register temp3_reg);
-
-  static void remove_arg_slots(MacroAssembler* _masm,
-                               RegisterOrConstant arg_slots,
-                               Register argslot_reg,
-                               Register temp_reg, Register temp2_reg, Register temp3_reg);
-
-  static void push_arg_slots(MacroAssembler* _masm,
-                             Register argslot_reg,
-                             RegisterOrConstant slot_count,
-                             Register temp_reg, Register temp2_reg);
-
-  static void move_arg_slots_up(MacroAssembler* _masm,
-                                Register bottom_reg,  // invariant
-                                Address  top_addr,    // can use temp_reg
-                                RegisterOrConstant positive_distance_in_slots,
-                                Register temp_reg, Register temp2_reg);
-
-  static void move_arg_slots_down(MacroAssembler* _masm,
-                                  Address  bottom_addr,  // can use temp_reg
-                                  Register top_reg,      // invariant
-                                  RegisterOrConstant negative_distance_in_slots,
-                                  Register temp_reg, Register temp2_reg);
-
-  static void move_typed_arg(MacroAssembler* _masm,
-                             BasicType type, bool is_element,
-                             Address value_src, Address slot_dest,
-                             Register temp_reg);
-
-  static void move_return_value(MacroAssembler* _masm, BasicType type,
-                                Address return_slot);
-
-  static void verify_argslot(MacroAssembler* _masm, Register argslot_reg,
-                             Register temp_reg,
-                             const char* error_message) NOT_DEBUG_RETURN;
-
-  static void verify_argslots(MacroAssembler* _masm,
-                              RegisterOrConstant argslot_count,
-                              Register argslot_reg,
-                              Register temp_reg,
-                              Register temp2_reg,
-                              bool negate_argslot,
-                              const char* error_message) NOT_DEBUG_RETURN;
-
-  static void verify_stack_move(MacroAssembler* _masm,
-                                RegisterOrConstant arg_slots,
-                                int direction) NOT_DEBUG_RETURN;
 
   static void verify_klass(MacroAssembler* _masm,
                            Register obj_reg, KlassHandle klass,
@@ -223,8 +46,15 @@
                  "reference is a MH");
   }
 
+  static void verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) NOT_DEBUG_RETURN;
+
   // Similar to InterpreterMacroAssembler::jump_from_interpreted.
   // Takes care of special dispatch from single stepping too.
-  static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp, Register temp2);
+  static void jump_from_method_handle(MacroAssembler* _masm, Register method,
+                                      Register temp, Register temp2,
+                                      bool for_compiler_entry);
 
-  static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
+  static void jump_to_lambda_form(MacroAssembler* _masm,
+                                  Register recv, Register method_temp,
+                                  Register temp2, Register temp3,
+                                  bool for_compiler_entry);
diff --git a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
index f82066e..17b5377 100644
--- a/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/sharedRuntime_sparc.cpp
@@ -313,6 +313,14 @@
 
 }
 
+// Is vector's size (in bytes) bigger than a size saved by default?
+// 8 bytes FP registers are saved by default on SPARC.
+bool SharedRuntime::is_wide_vector(int size) {
+  // Note, MaxVectorSize == 8 on SPARC.
+  assert(size <= 8, err_msg_res("%d bytes vectors are not supported", size));
+  return size > 8;
+}
+
 // The java_calling_convention describes stack locations as ideal slots on
 // a frame with no abi restrictions. Since we must observe abi restrictions
 // (like the placement of the register window) the slots must be biased by
@@ -364,9 +372,9 @@
 // ---------------------------------------------------------------------------
 // The compiled Java calling convention.  The Java convention always passes
 // 64-bit values in adjacent aligned locations (either registers or stack),
-// floats in float registers and doubles in aligned float pairs.  Values are
-// packed in the registers.  There is no backing varargs store for values in
-// registers.  In the 32-bit build, longs are passed in G1 and G4 (cannot be
+// floats in float registers and doubles in aligned float pairs.  There is
+// no backing varargs store for values in registers.
+// In the 32-bit build, longs are passed on the stack (cannot be
 // passed in I's, because longs in I's get their heads chopped off at
 // interrupt).
 int SharedRuntime::java_calling_convention(const BasicType *sig_bt,
@@ -375,77 +383,13 @@
                                            int is_outgoing) {
   assert(F31->as_VMReg()->is_reg(), "overlapping stack/register numbers");
 
-  // Convention is to pack the first 6 int/oop args into the first 6 registers
-  // (I0-I5), extras spill to the stack.  Then pack the first 8 float args
-  // into F0-F7, extras spill to the stack.  Then pad all register sets to
-  // align.  Then put longs and doubles into the same registers as they fit,
-  // else spill to the stack.
   const int int_reg_max = SPARC_ARGS_IN_REGS_NUM;
   const int flt_reg_max = 8;
-  //
-  // Where 32-bit 1-reg longs start being passed
-  // In tiered we must pass on stack because c1 can't use a "pair" in a single reg.
-  // So make it look like we've filled all the G regs that c2 wants to use.
-  Register g_reg = TieredCompilation ? noreg : G1;
 
-  // Count int/oop and float args.  See how many stack slots we'll need and
-  // where the longs & doubles will go.
-  int int_reg_cnt   = 0;
-  int flt_reg_cnt   = 0;
-  // int stk_reg_pairs = frame::register_save_words*(wordSize>>2);
-  // int stk_reg_pairs = SharedRuntime::out_preserve_stack_slots();
-  int stk_reg_pairs = 0;
-  for (int i = 0; i < total_args_passed; i++) {
-    switch (sig_bt[i]) {
-    case T_LONG:                // LP64, longs compete with int args
-      assert(sig_bt[i+1] == T_VOID, "");
-#ifdef _LP64
-      if (int_reg_cnt < int_reg_max) int_reg_cnt++;
-#endif
-      break;
-    case T_OBJECT:
-    case T_ARRAY:
-    case T_ADDRESS: // Used, e.g., in slow-path locking for the lock's stack address
-      if (int_reg_cnt < int_reg_max) int_reg_cnt++;
-#ifndef _LP64
-      else                            stk_reg_pairs++;
-#endif
-      break;
-    case T_INT:
-    case T_SHORT:
-    case T_CHAR:
-    case T_BYTE:
-    case T_BOOLEAN:
-      if (int_reg_cnt < int_reg_max) int_reg_cnt++;
-      else                            stk_reg_pairs++;
-      break;
-    case T_FLOAT:
-      if (flt_reg_cnt < flt_reg_max) flt_reg_cnt++;
-      else                            stk_reg_pairs++;
-      break;
-    case T_DOUBLE:
-      assert(sig_bt[i+1] == T_VOID, "");
-      break;
-    case T_VOID:
-      break;
-    default:
-      ShouldNotReachHere();
-    }
-  }
-
-  // This is where the longs/doubles start on the stack.
-  stk_reg_pairs = (stk_reg_pairs+1) & ~1; // Round
-
-  int int_reg_pairs = (int_reg_cnt+1) & ~1; // 32-bit 2-reg longs only
-  int flt_reg_pairs = (flt_reg_cnt+1) & ~1;
-
-  // int stk_reg = frame::register_save_words*(wordSize>>2);
-  // int stk_reg = SharedRuntime::out_preserve_stack_slots();
-  int stk_reg = 0;
   int int_reg = 0;
   int flt_reg = 0;
+  int slot = 0;
 
-  // Now do the signature layout
   for (int i = 0; i < total_args_passed; i++) {
     switch (sig_bt[i]) {
     case T_INT:
@@ -462,11 +406,14 @@
         Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++);
         regs[i].set1(r->as_VMReg());
       } else {
-        regs[i].set1(VMRegImpl::stack2reg(stk_reg++));
+        regs[i].set1(VMRegImpl::stack2reg(slot++));
       }
       break;
 
 #ifdef _LP64
+    case T_LONG:
+      assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half");
+      // fall-through
     case T_OBJECT:
     case T_ARRAY:
     case T_ADDRESS: // Used, e.g., in slow-path locking for the lock's stack address
@@ -474,87 +421,57 @@
         Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++);
         regs[i].set2(r->as_VMReg());
       } else {
-        regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
-        stk_reg_pairs += 2;
+        slot = round_to(slot, 2);  // align
+        regs[i].set2(VMRegImpl::stack2reg(slot));
+        slot += 2;
       }
       break;
-#endif // _LP64
-
+#else
     case T_LONG:
       assert(sig_bt[i+1] == T_VOID, "expecting VOID in other half");
-#ifdef _LP64
-        if (int_reg < int_reg_max) {
-          Register r = is_outgoing ? as_oRegister(int_reg++) : as_iRegister(int_reg++);
-          regs[i].set2(r->as_VMReg());
-        } else {
-          regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
-          stk_reg_pairs += 2;
-        }
-#else
-#ifdef COMPILER2
-        // For 32-bit build, can't pass longs in O-regs because they become
-        // I-regs and get trashed.  Use G-regs instead.  G1 and G4 are almost
-        // spare and available.  This convention isn't used by the Sparc ABI or
-        // anywhere else. If we're tiered then we don't use G-regs because c1
-        // can't deal with them as a "pair". (Tiered makes this code think g's are filled)
-        // G0: zero
-        // G1: 1st Long arg
-        // G2: global allocated to TLS
-        // G3: used in inline cache check
-        // G4: 2nd Long arg
-        // G5: used in inline cache check
-        // G6: used by OS
-        // G7: used by OS
-
-        if (g_reg == G1) {
-          regs[i].set2(G1->as_VMReg()); // This long arg in G1
-          g_reg = G4;                  // Where the next arg goes
-        } else if (g_reg == G4) {
-          regs[i].set2(G4->as_VMReg()); // The 2nd long arg in G4
-          g_reg = noreg;               // No more longs in registers
-        } else {
-          regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
-          stk_reg_pairs += 2;
-        }
-#else // COMPILER2
-        if (int_reg_pairs + 1 < int_reg_max) {
-          if (is_outgoing) {
-            regs[i].set_pair(as_oRegister(int_reg_pairs + 1)->as_VMReg(), as_oRegister(int_reg_pairs)->as_VMReg());
-          } else {
-            regs[i].set_pair(as_iRegister(int_reg_pairs + 1)->as_VMReg(), as_iRegister(int_reg_pairs)->as_VMReg());
-          }
-          int_reg_pairs += 2;
-        } else {
-          regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
-          stk_reg_pairs += 2;
-        }
-#endif // COMPILER2
-#endif // _LP64
+      // On 32-bit SPARC put longs always on the stack to keep the pressure off
+      // integer argument registers.  They should be used for oops.
+      slot = round_to(slot, 2);  // align
+      regs[i].set2(VMRegImpl::stack2reg(slot));
+      slot += 2;
+#endif
       break;
 
     case T_FLOAT:
-      if (flt_reg < flt_reg_max) regs[i].set1(as_FloatRegister(flt_reg++)->as_VMReg());
-      else                       regs[i].set1(    VMRegImpl::stack2reg(stk_reg++));
-      break;
-    case T_DOUBLE:
-      assert(sig_bt[i+1] == T_VOID, "expecting half");
-      if (flt_reg_pairs + 1 < flt_reg_max) {
-        regs[i].set2(as_FloatRegister(flt_reg_pairs)->as_VMReg());
-        flt_reg_pairs += 2;
+      if (flt_reg < flt_reg_max) {
+        FloatRegister r = as_FloatRegister(flt_reg++);
+        regs[i].set1(r->as_VMReg());
       } else {
-        regs[i].set2(VMRegImpl::stack2reg(stk_reg_pairs));
-        stk_reg_pairs += 2;
+        regs[i].set1(VMRegImpl::stack2reg(slot++));
       }
       break;
-    case T_VOID: regs[i].set_bad();  break; // Halves of longs & doubles
+
+    case T_DOUBLE:
+      assert(sig_bt[i+1] == T_VOID, "expecting half");
+      if (round_to(flt_reg, 2) + 1 < flt_reg_max) {
+        flt_reg = round_to(flt_reg, 2);  // align
+        FloatRegister r = as_FloatRegister(flt_reg);
+        regs[i].set2(r->as_VMReg());
+        flt_reg += 2;
+      } else {
+        slot = round_to(slot, 2);  // align
+        regs[i].set2(VMRegImpl::stack2reg(slot));
+        slot += 2;
+      }
+      break;
+
+    case T_VOID:
+      regs[i].set_bad();   // Halves of longs & doubles
+      break;
+
     default:
-      ShouldNotReachHere();
+      fatal(err_msg_res("unknown basic type %d", sig_bt[i]));
+      break;
     }
   }
 
   // retun the amount of stack space these arguments will need.
-  return stk_reg_pairs;
-
+  return slot;
 }
 
 // Helper class mostly to avoid passing masm everywhere, and handle
@@ -611,8 +528,7 @@
   Label L;
   __ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch);
   __ br_null(G3_scratch, false, Assembler::pt, L);
-  // Schedule the branch target address early.
-  __ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch);
+  __ delayed()->nop();
   // Call into the VM to patch the caller, then jump to compiled callee
   __ save_frame(4);     // Args in compiled layout; do not blow them
 
@@ -655,7 +571,6 @@
   __ ldx(FP, -8 + STACK_BIAS, G1);
   __ ldx(FP, -16 + STACK_BIAS, G4);
   __ mov(L5, G5_method);
-  __ ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch);
 #endif /* _LP64 */
 
   __ restore();      // Restore args
@@ -736,7 +651,7 @@
                             int comp_args_on_stack, // VMRegStackSlots
                             const BasicType *sig_bt,
                             const VMRegPair *regs,
-                            Label& skip_fixup) {
+                            Label& L_skip_fixup) {
 
   // Before we get into the guts of the C2I adapter, see if we should be here
   // at all.  We've come from compiled code and are attempting to jump to the
@@ -757,7 +672,7 @@
 
   patch_callers_callsite();
 
-  __ bind(skip_fixup);
+  __ bind(L_skip_fixup);
 
   // Since all args are passed on the stack, total_args_passed*wordSize is the
   // space we need.  Add in varargs area needed by the interpreter. Round up
@@ -767,46 +682,18 @@
                  (frame::varargs_offset - frame::register_save_words)*wordSize;
   const int extraspace = round_to(arg_size + varargs_area, 2*wordSize);
 
-  int bias = STACK_BIAS;
+  const int bias = STACK_BIAS;
   const int interp_arg_offset = frame::varargs_offset*wordSize +
                         (total_args_passed-1)*Interpreter::stackElementSize;
 
-  Register base = SP;
+  const Register base = SP;
 
-#ifdef _LP64
-  // In the 64bit build because of wider slots and STACKBIAS we can run
-  // out of bits in the displacement to do loads and stores.  Use g3 as
-  // temporary displacement.
-  if (!Assembler::is_simm13(extraspace)) {
-    __ set(extraspace, G3_scratch);
-    __ sub(SP, G3_scratch, SP);
-  } else {
-    __ sub(SP, extraspace, SP);
-  }
+  // Make some extra space on the stack.
+  __ sub(SP, __ ensure_simm13_or_reg(extraspace, G3_scratch), SP);
   set_Rdisp(G3_scratch);
-#else
-  __ sub(SP, extraspace, SP);
-#endif // _LP64
 
-  // First write G1 (if used) to where ever it must go
-  for (int i=0; i<total_args_passed; i++) {
-    const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize) + bias;
-    VMReg r_1 = regs[i].first();
-    VMReg r_2 = regs[i].second();
-    if (r_1 == G1_scratch->as_VMReg()) {
-      if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) {
-        store_c2i_object(G1_scratch, base, st_off);
-      } else if (sig_bt[i] == T_LONG) {
-        assert(!TieredCompilation, "should not use register args for longs");
-        store_c2i_long(G1_scratch, base, st_off, false);
-      } else {
-        store_c2i_int(G1_scratch, base, st_off);
-      }
-    }
-  }
-
-  // Now write the args into the outgoing interpreter space
-  for (int i=0; i<total_args_passed; i++) {
+  // Write the args into the outgoing interpreter space.
+  for (int i = 0; i < total_args_passed; i++) {
     const int st_off = interp_arg_offset - (i*Interpreter::stackElementSize) + bias;
     VMReg r_1 = regs[i].first();
     VMReg r_2 = regs[i].second();
@@ -814,23 +701,9 @@
       assert(!r_2->is_valid(), "");
       continue;
     }
-    // Skip G1 if found as we did it first in order to free it up
-    if (r_1 == G1_scratch->as_VMReg()) {
-      continue;
-    }
-#ifdef ASSERT
-    bool G1_forced = false;
-#endif // ASSERT
     if (r_1->is_stack()) {        // Pretend stack targets are loaded into G1
-#ifdef _LP64
-      Register ld_off = Rdisp;
-      __ set(reg2offset(r_1) + extraspace + bias, ld_off);
-#else
-      int ld_off = reg2offset(r_1) + extraspace + bias;
-#endif // _LP64
-#ifdef ASSERT
-      G1_forced = true;
-#endif // ASSERT
+      RegisterOrConstant ld_off = reg2offset(r_1) + extraspace + bias;
+      ld_off = __ ensure_simm13_or_reg(ld_off, Rdisp);
       r_1 = G1_scratch->as_VMReg();// as part of the load/store shuffle
       if (!r_2->is_valid()) __ ld (base, ld_off, G1_scratch);
       else                  __ ldx(base, ld_off, G1_scratch);
@@ -841,11 +714,6 @@
       if (sig_bt[i] == T_OBJECT || sig_bt[i] == T_ARRAY) {
         store_c2i_object(r, base, st_off);
       } else if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) {
-#ifndef _LP64
-        if (TieredCompilation) {
-          assert(G1_forced || sig_bt[i] != T_LONG, "should not use register args for longs");
-        }
-#endif // _LP64
         store_c2i_long(r, base, st_off, r_2->is_stack());
       } else {
         store_c2i_int(r, base, st_off);
@@ -861,19 +729,12 @@
     }
   }
 
-#ifdef _LP64
-  // Need to reload G3_scratch, used for temporary displacements.
+  // Load the interpreter entry point.
   __ ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch);
 
   // Pass O5_savedSP as an argument to the interpreter.
   // The interpreter will restore SP to this value before returning.
-  __ set(extraspace, G1);
-  __ add(SP, G1, O5_savedSP);
-#else
-  // Pass O5_savedSP as an argument to the interpreter.
-  // The interpreter will restore SP to this value before returning.
-  __ add(SP, extraspace, O5_savedSP);
-#endif // _LP64
+  __ add(SP, __ ensure_simm13_or_reg(extraspace, G1), O5_savedSP);
 
   __ mov((frame::varargs_offset)*wordSize -
          1*Interpreter::stackElementSize+bias+BytesPerWord, G1);
@@ -886,6 +747,20 @@
   __ delayed()->add(SP, G1, Gargs);
 }
 
+static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg, Register temp2_reg,
+                        address code_start, address code_end,
+                        Label& L_ok) {
+  Label L_fail;
+  __ set(ExternalAddress(code_start), temp_reg);
+  __ set(pointer_delta(code_end, code_start, 1), temp2_reg);
+  __ cmp(pc_reg, temp_reg);
+  __ brx(Assembler::lessEqualUnsigned, false, Assembler::pn, L_fail);
+  __ delayed()->add(temp_reg, temp2_reg, temp_reg);
+  __ cmp(pc_reg, temp_reg);
+  __ cmp_and_brx_short(pc_reg, temp_reg, Assembler::lessUnsigned, Assembler::pt, L_ok);
+  __ bind(L_fail);
+}
+
 void AdapterGenerator::gen_i2c_adapter(
                             int total_args_passed,
                             // VMReg max_arg,
@@ -907,6 +782,51 @@
   // This removes all sorts of headaches on the x86 side and also eliminates
   // the possibility of having c2i -> i2c -> c2i -> ... endless transitions.
 
+  // More detail:
+  // Adapters can be frameless because they do not require the caller
+  // to perform additional cleanup work, such as correcting the stack pointer.
+  // An i2c adapter is frameless because the *caller* frame, which is interpreted,
+  // routinely repairs its own stack pointer (from interpreter_frame_last_sp),
+  // even if a callee has modified the stack pointer.
+  // A c2i adapter is frameless because the *callee* frame, which is interpreted,
+  // routinely repairs its caller's stack pointer (from sender_sp, which is set
+  // up via the senderSP register).
+  // In other words, if *either* the caller or callee is interpreted, we can
+  // get the stack pointer repaired after a call.
+  // This is why c2i and i2c adapters cannot be indefinitely composed.
+  // In particular, if a c2i adapter were to somehow call an i2c adapter,
+  // both caller and callee would be compiled methods, and neither would
+  // clean up the stack pointer changes performed by the two adapters.
+  // If this happens, control eventually transfers back to the compiled
+  // caller, but with an uncorrected stack, causing delayed havoc.
+
+  if (VerifyAdapterCalls &&
+      (Interpreter::code() != NULL || StubRoutines::code1() != NULL)) {
+    // So, let's test for cascading c2i/i2c adapters right now.
+    //  assert(Interpreter::contains($return_addr) ||
+    //         StubRoutines::contains($return_addr),
+    //         "i2c adapter must return to an interpreter frame");
+    __ block_comment("verify_i2c { ");
+    Label L_ok;
+    if (Interpreter::code() != NULL)
+      range_check(masm, O7, O0, O1,
+                  Interpreter::code()->code_start(), Interpreter::code()->code_end(),
+                  L_ok);
+    if (StubRoutines::code1() != NULL)
+      range_check(masm, O7, O0, O1,
+                  StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(),
+                  L_ok);
+    if (StubRoutines::code2() != NULL)
+      range_check(masm, O7, O0, O1,
+                  StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(),
+                  L_ok);
+    const char* msg = "i2c adapter must return to an interpreter frame";
+    __ block_comment(msg);
+    __ stop(msg);
+    __ bind(L_ok);
+    __ block_comment("} verify_i2ce ");
+  }
+
   // As you can see from the list of inputs & outputs there are not a lot
   // of temp registers to work with: mostly G1, G3 & G4.
 
@@ -922,7 +842,6 @@
 
   // Outputs:
   // G2_thread      - TLS
-  // G1, G4         - Outgoing long args in 32-bit build
   // O0-O5          - Outgoing args in compiled layout
   // O6             - Adjusted or restored SP
   // O7             - Valid return address
@@ -967,10 +886,10 @@
   // +--------------+ <--- start of outgoing args
   // |  pad, align  |   |
   // +--------------+   |
-  // | ints, floats |   |---Outgoing stack args, packed low.
-  // +--------------+   |   First few args in registers.
-  // :   doubles    :   |
-  // |   longs      |   |
+  // | ints, longs, |   |
+  // |    floats,   |   |---Outgoing stack args.
+  // :    doubles   :   |   First few args in registers.
+  // |              |   |
   // +--------------+ <--- SP' + 16*wordsize
   // |              |
   // :    window    :
@@ -984,7 +903,6 @@
   // Cut-out for having no stack args.  Since up to 6 args are passed
   // in registers, we will commonly have no stack args.
   if (comp_args_on_stack > 0) {
-
     // Convert VMReg stack slots to words.
     int comp_words_on_stack = round_to(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord;
     // Round up to miminum stack alignment, in wordSize
@@ -995,13 +913,9 @@
     __ sub(SP, (comp_words_on_stack)*wordSize, SP);
   }
 
-  // Will jump to the compiled code just as if compiled code was doing it.
-  // Pre-load the register-jump target early, to schedule it better.
-  __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3);
-
   // Now generate the shuffle code.  Pick up all register args and move the
   // rest through G1_scratch.
-  for (int i=0; i<total_args_passed; i++) {
+  for (int i = 0; i < total_args_passed; i++) {
     if (sig_bt[i] == T_VOID) {
       // Longs and doubles are passed in native word order, but misaligned
       // in the 32-bit build.
@@ -1039,14 +953,13 @@
               next_arg_slot(ld_off) : arg_slot(ld_off);
         __ ldx(Gargs, slot, r);
 #else
-        // Need to load a 64-bit value into G1/G4, but G1/G4 is being used in the
-        // stack shuffle.  Load the first 2 longs into G1/G4 later.
+        fatal("longs should be on stack");
 #endif
       }
     } else {
       assert(r_1->is_FloatRegister(), "");
       if (!r_2->is_valid()) {
-        __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_1->as_FloatRegister());
+        __ ldf(FloatRegisterImpl::S, Gargs,      arg_slot(ld_off), r_1->as_FloatRegister());
       } else {
 #ifdef _LP64
         // In V9, doubles are given 2 64-bit slots in the interpreter, but the
@@ -1055,11 +968,11 @@
         // spare float register.
         RegisterOrConstant slot = (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) ?
               next_arg_slot(ld_off) : arg_slot(ld_off);
-        __ ldf(FloatRegisterImpl::D, Gargs, slot, r_1->as_FloatRegister());
+        __ ldf(FloatRegisterImpl::D, Gargs,                  slot, r_1->as_FloatRegister());
 #else
         // Need to marshal 64-bit value from misaligned Lesp loads
         __ ldf(FloatRegisterImpl::S, Gargs, next_arg_slot(ld_off), r_1->as_FloatRegister());
-        __ ldf(FloatRegisterImpl::S, Gargs, arg_slot(ld_off), r_2->as_FloatRegister());
+        __ ldf(FloatRegisterImpl::S, Gargs,      arg_slot(ld_off), r_2->as_FloatRegister());
 #endif
       }
     }
@@ -1075,76 +988,35 @@
       else                  __ stf(FloatRegisterImpl::D, r_1->as_FloatRegister(), SP, slot);
     }
   }
-  bool made_space = false;
-#ifndef _LP64
-  // May need to pick up a few long args in G1/G4
-  bool g4_crushed = false;
-  bool g3_crushed = false;
-  for (int i=0; i<total_args_passed; i++) {
-    if (regs[i].first()->is_Register() && regs[i].second()->is_valid()) {
-      // Load in argument order going down
-      int ld_off = (total_args_passed-i)*Interpreter::stackElementSize;
-      // Need to marshal 64-bit value from misaligned Lesp loads
-      Register r = regs[i].first()->as_Register()->after_restore();
-      if (r == G1 || r == G4) {
-        assert(!g4_crushed, "ordering problem");
-        if (r == G4){
-          g4_crushed = true;
-          __ lduw(Gargs, arg_slot(ld_off)     , G3_scratch); // Load lo bits
-          __ ld  (Gargs, next_arg_slot(ld_off), r);          // Load hi bits
-        } else {
-          // better schedule this way
-          __ ld  (Gargs, next_arg_slot(ld_off), r);          // Load hi bits
-          __ lduw(Gargs, arg_slot(ld_off)     , G3_scratch); // Load lo bits
-        }
-        g3_crushed = true;
-        __ sllx(r, 32, r);
-        __ or3(G3_scratch, r, r);
-      } else {
-        assert(r->is_out(), "longs passed in two O registers");
-        __ ld  (Gargs, arg_slot(ld_off)     , r->successor()); // Load lo bits
-        __ ld  (Gargs, next_arg_slot(ld_off), r);              // Load hi bits
-      }
-    }
-  }
-#endif
 
   // Jump to the compiled code just as if compiled code was doing it.
-  //
-#ifndef _LP64
-    if (g3_crushed) {
-      // Rats load was wasted, at least it is in cache...
-      __ ld_ptr(G5_method, methodOopDesc::from_compiled_offset(), G3);
-    }
-#endif /* _LP64 */
+  __ ld_ptr(G5_method, in_bytes(methodOopDesc::from_compiled_offset()), G3);
 
-    // 6243940 We might end up in handle_wrong_method if
-    // the callee is deoptimized as we race thru here. If that
-    // happens we don't want to take a safepoint because the
-    // caller frame will look interpreted and arguments are now
-    // "compiled" so it is much better to make this transition
-    // invisible to the stack walking code. Unfortunately if
-    // we try and find the callee by normal means a safepoint
-    // is possible. So we stash the desired callee in the thread
-    // and the vm will find there should this case occur.
-    Address callee_target_addr(G2_thread, JavaThread::callee_target_offset());
-    __ st_ptr(G5_method, callee_target_addr);
+  // 6243940 We might end up in handle_wrong_method if
+  // the callee is deoptimized as we race thru here. If that
+  // happens we don't want to take a safepoint because the
+  // caller frame will look interpreted and arguments are now
+  // "compiled" so it is much better to make this transition
+  // invisible to the stack walking code. Unfortunately if
+  // we try and find the callee by normal means a safepoint
+  // is possible. So we stash the desired callee in the thread
+  // and the vm will find there should this case occur.
+  Address callee_target_addr(G2_thread, JavaThread::callee_target_offset());
+  __ st_ptr(G5_method, callee_target_addr);
 
-    if (StressNonEntrant) {
-      // Open a big window for deopt failure
-      __ save_frame(0);
-      __ mov(G0, L0);
-      Label loop;
-      __ bind(loop);
-      __ sub(L0, 1, L0);
-      __ br_null_short(L0, Assembler::pt, loop);
+  if (StressNonEntrant) {
+    // Open a big window for deopt failure
+    __ save_frame(0);
+    __ mov(G0, L0);
+    Label loop;
+    __ bind(loop);
+    __ sub(L0, 1, L0);
+    __ br_null_short(L0, Assembler::pt, loop);
+    __ restore();
+  }
 
-      __ restore();
-    }
-
-
-    __ jmpl(G3, 0, G0);
-    __ delayed()->nop();
+  __ jmpl(G3, 0, G0);
+  __ delayed()->nop();
 }
 
 // ---------------------------------------------------------------
@@ -1172,13 +1044,9 @@
   // compiled code, which relys solely on SP and not FP, get sick).
 
   address c2i_unverified_entry = __ pc();
-  Label skip_fixup;
+  Label L_skip_fixup;
   {
-#if !defined(_LP64) && defined(COMPILER2)
-    Register R_temp   = L0;   // another scratch register
-#else
-    Register R_temp   = G1;   // another scratch register
-#endif
+    Register R_temp = G1;  // another scratch register
 
     AddressLiteral ic_miss(SharedRuntime::get_ic_miss_stub());
 
@@ -1187,17 +1055,9 @@
     __ load_klass(O0, G3_scratch);
     __ verify_oop(G3_scratch);
 
-#if !defined(_LP64) && defined(COMPILER2)
-    __ save(SP, -frame::register_save_words*wordSize, SP);
     __ ld_ptr(G5_method, compiledICHolderOopDesc::holder_klass_offset(), R_temp);
     __ verify_oop(R_temp);
     __ cmp(G3_scratch, R_temp);
-    __ restore();
-#else
-    __ ld_ptr(G5_method, compiledICHolderOopDesc::holder_klass_offset(), R_temp);
-    __ verify_oop(R_temp);
-    __ cmp(G3_scratch, R_temp);
-#endif
 
     Label ok, ok2;
     __ brx(Assembler::equal, false, Assembler::pt, ok);
@@ -1211,8 +1071,8 @@
     // the call site corrected.
     __ ld_ptr(G5_method, in_bytes(methodOopDesc::code_offset()), G3_scratch);
     __ bind(ok2);
-    __ br_null(G3_scratch, false, Assembler::pt, skip_fixup);
-    __ delayed()->ld_ptr(G5_method, in_bytes(methodOopDesc::interpreter_entry_offset()), G3_scratch);
+    __ br_null(G3_scratch, false, Assembler::pt, L_skip_fixup);
+    __ delayed()->nop();
     __ jump_to(ic_miss, G3_scratch);
     __ delayed()->nop();
 
@@ -1220,7 +1080,7 @@
 
   address c2i_entry = __ pc();
 
-  agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, skip_fixup);
+  agen.gen_c2i_adapter(total_args_passed, comp_args_on_stack, sig_bt, regs, L_skip_fixup);
 
   __ flush();
   return AdapterHandlerLibrary::new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
@@ -1937,20 +1797,149 @@
   __ bind(done);
 }
 
+static void verify_oop_args(MacroAssembler* masm,
+                            methodHandle method,
+                            const BasicType* sig_bt,
+                            const VMRegPair* regs) {
+  Register temp_reg = G5_method;  // not part of any compiled calling seq
+  if (VerifyOops) {
+    for (int i = 0; i < method->size_of_parameters(); i++) {
+      if (sig_bt[i] == T_OBJECT ||
+          sig_bt[i] == T_ARRAY) {
+        VMReg r = regs[i].first();
+        assert(r->is_valid(), "bad oop arg");
+        if (r->is_stack()) {
+          RegisterOrConstant ld_off = reg2offset(r) + STACK_BIAS;
+          ld_off = __ ensure_simm13_or_reg(ld_off, temp_reg);
+          __ ld_ptr(SP, ld_off, temp_reg);
+          __ verify_oop(temp_reg);
+        } else {
+          __ verify_oop(r->as_Register());
+        }
+      }
+    }
+  }
+}
+
+static void gen_special_dispatch(MacroAssembler* masm,
+                                 methodHandle method,
+                                 const BasicType* sig_bt,
+                                 const VMRegPair* regs) {
+  verify_oop_args(masm, method, sig_bt, regs);
+  vmIntrinsics::ID iid = method->intrinsic_id();
+
+  // Now write the args into the outgoing interpreter space
+  bool     has_receiver   = false;
+  Register receiver_reg   = noreg;
+  int      member_arg_pos = -1;
+  Register member_reg     = noreg;
+  int      ref_kind       = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid);
+  if (ref_kind != 0) {
+    member_arg_pos = method->size_of_parameters() - 1;  // trailing MemberName argument
+    member_reg = G5_method;  // known to be free at this point
+    has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind);
+  } else if (iid == vmIntrinsics::_invokeBasic) {
+    has_receiver = true;
+  } else {
+    fatal(err_msg_res("unexpected intrinsic id %d", iid));
+  }
+
+  if (member_reg != noreg) {
+    // Load the member_arg into register, if necessary.
+    SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs);
+    VMReg r = regs[member_arg_pos].first();
+    if (r->is_stack()) {
+      RegisterOrConstant ld_off = reg2offset(r) + STACK_BIAS;
+      ld_off = __ ensure_simm13_or_reg(ld_off, member_reg);
+      __ ld_ptr(SP, ld_off, member_reg);
+    } else {
+      // no data motion is needed
+      member_reg = r->as_Register();
+    }
+  }
+
+  if (has_receiver) {
+    // Make sure the receiver is loaded into a register.
+    assert(method->size_of_parameters() > 0, "oob");
+    assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object");
+    VMReg r = regs[0].first();
+    assert(r->is_valid(), "bad receiver arg");
+    if (r->is_stack()) {
+      // Porting note:  This assumes that compiled calling conventions always
+      // pass the receiver oop in a register.  If this is not true on some
+      // platform, pick a temp and load the receiver from stack.
+      fatal("receiver always in a register");
+      receiver_reg = G3_scratch;  // known to be free at this point
+      RegisterOrConstant ld_off = reg2offset(r) + STACK_BIAS;
+      ld_off = __ ensure_simm13_or_reg(ld_off, member_reg);
+      __ ld_ptr(SP, ld_off, receiver_reg);
+    } else {
+      // no data motion is needed
+      receiver_reg = r->as_Register();
+    }
+  }
+
+  // Figure out which address we are really jumping to:
+  MethodHandles::generate_method_handle_dispatch(masm, iid,
+                                                 receiver_reg, member_reg, /*for_compiler_entry:*/ true);
+}
+
 // ---------------------------------------------------------------------------
 // Generate a native wrapper for a given method.  The method takes arguments
 // in the Java compiled code convention, marshals them to the native
 // convention (handlizes oops, etc), transitions to native, makes the call,
 // returns to java state (possibly blocking), unhandlizes any result and
 // returns.
-nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
+//
+// Critical native functions are a shorthand for the use of
+// GetPrimtiveArrayCritical and disallow the use of any other JNI
+// functions.  The wrapper is expected to unpack the arguments before
+// passing them to the callee and perform checks before and after the
+// native call to ensure that they GC_locker
+// lock_critical/unlock_critical semantics are followed.  Some other
+// parts of JNI setup are skipped like the tear down of the JNI handle
+// block and the check for pending exceptions it's impossible for them
+// to be thrown.
+//
+// They are roughly structured like this:
+//    if (GC_locker::needs_gc())
+//      SharedRuntime::block_for_jni_critical();
+//    tranistion to thread_in_native
+//    unpack arrray arguments and call native entry point
+//    check for safepoint in progress
+//    check if any thread suspend flags are set
+//      call into JVM and possible unlock the JNI critical
+//      if a GC was suppressed while in the critical native.
+//    transition back to thread_in_Java
+//    return to caller
+//
+nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
                                                 methodHandle method,
                                                 int compile_id,
-                                                int total_in_args,
-                                                int comp_args_on_stack, // in VMRegStackSlots
-                                                BasicType *in_sig_bt,
-                                                VMRegPair *in_regs,
+                                                BasicType* in_sig_bt,
+                                                VMRegPair* in_regs,
                                                 BasicType ret_type) {
+  if (method->is_method_handle_intrinsic()) {
+    vmIntrinsics::ID iid = method->intrinsic_id();
+    intptr_t start = (intptr_t)__ pc();
+    int vep_offset = ((intptr_t)__ pc()) - start;
+    gen_special_dispatch(masm,
+                         method,
+                         in_sig_bt,
+                         in_regs);
+    int frame_complete = ((intptr_t)__ pc()) - start;  // not complete, period
+    __ flush();
+    int stack_slots = SharedRuntime::out_preserve_stack_slots();  // no out slots at all, actually
+    return nmethod::new_native_nmethod(method,
+                                       compile_id,
+                                       masm->code(),
+                                       vep_offset,
+                                       frame_complete,
+                                       stack_slots / VMRegImpl::slots_per_word,
+                                       in_ByteSize(-1),
+                                       in_ByteSize(-1),
+                                       (OopMapSet*)NULL);
+  }
   bool is_critical_native = true;
   address native_func = method->critical_native_function();
   if (native_func == NULL) {
@@ -2037,6 +2026,7 @@
   // we convert the java signature to a C signature by inserting
   // the hidden arguments as arg[0] and possibly arg[1] (static method)
 
+  const int total_in_args = method->size_of_parameters();
   int total_c_args = total_in_args;
   int total_save_slots = 6 * VMRegImpl::slots_per_word;
   if (!is_critical_native) {
@@ -3325,7 +3315,7 @@
   // make sure that the frames are aligned properly
 #ifndef _LP64
   __ btst(wordSize*2-1, SP);
-  __ breakpoint_trap(Assembler::notZero);
+  __ breakpoint_trap(Assembler::notZero, Assembler::ptr_cc);
 #endif
   #endif
 
@@ -3407,7 +3397,7 @@
 #ifdef ASSERT
   // make sure that there is at least one entry in the array
   __ tst(O4array_size);
-  __ breakpoint_trap(Assembler::zero);
+  __ breakpoint_trap(Assembler::zero, Assembler::icc);
 #endif
 
   // Now push the new interpreter frames
@@ -3753,7 +3743,7 @@
 // the 64-bit %o's, then do a save, then fixup the caller's SP (our FP).
 // Tricky, tricky, tricky...
 
-SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) {
+SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) {
   assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
 
   // allocate space for the code
@@ -3771,6 +3761,7 @@
 
   int start = __ offset();
 
+  bool cause_return = (poll_type == POLL_AT_RETURN);
   // If this causes a return before the processing, then do a "restore"
   if (cause_return) {
     __ restore();
diff --git a/hotspot/src/cpu/sparc/vm/sparc.ad b/hotspot/src/cpu/sparc/vm/sparc.ad
index 3063b2d..4933608 100644
--- a/hotspot/src/cpu/sparc/vm/sparc.ad
+++ b/hotspot/src/cpu/sparc/vm/sparc.ad
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1998, 2012, 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
@@ -678,18 +678,26 @@
 
 static inline jdouble replicate_immI(int con, int count, int width) {
   // Load a constant replicated "count" times with width "width"
+  assert(count*width == 8 && width <= 4, "sanity");
   int bit_width = width * 8;
-  jlong elt_val = con;
-  elt_val &= (((jlong) 1) << bit_width) - 1;  // mask off sign bits
-  jlong val = elt_val;
+  jlong val = con;
+  val &= (((jlong) 1) << bit_width) - 1;  // mask off sign bits
   for (int i = 0; i < count - 1; i++) {
-    val <<= bit_width;
-    val |= elt_val;
+    val |= (val << bit_width);
   }
   jdouble dval = *((jdouble*) &val);  // coerce to double type
   return dval;
 }
 
+static inline jdouble replicate_immF(float con) {
+  // Replicate float con 2 times and pack into vector.
+  int val = *((int*)&con);
+  jlong lval = val;
+  lval = (lval << 32) | (lval & 0xFFFFFFFFl);
+  jdouble dval = *((jdouble*) &lval);  // coerce to double type
+  return dval;
+}
+
 // Standard Sparc opcode form2 field breakdown
 static inline void emit2_19(CodeBuffer &cbuf, int f30, int f29, int f25, int f22, int f20, int f19, int f0 ) {
   f0 &= (1<<19)-1;     // Mask displacement to 19 bits
@@ -791,6 +799,7 @@
     case Assembler::stdf_op3: st_op = Op_StoreD; break;
 
     case Assembler::ldsb_op3: ld_op = Op_LoadB; break;
+    case Assembler::ldub_op3: ld_op = Op_LoadUB; break;
     case Assembler::lduh_op3: ld_op = Op_LoadUS; break;
     case Assembler::ldsh_op3: ld_op = Op_LoadS; break;
     case Assembler::ldx_op3:  // may become LoadP or stay LoadI
@@ -799,7 +808,6 @@
     case Assembler::ldd_op3:  ld_op = Op_LoadL; break;
     case Assembler::ldf_op3:  ld_op = Op_LoadF; break;
     case Assembler::lddf_op3: ld_op = Op_LoadD; break;
-    case Assembler::ldub_op3: ld_op = Op_LoadB; break;
     case Assembler::prefetch_op3: ld_op = Op_LoadI; break;
 
     default: ShouldNotReachHere();
@@ -827,7 +835,6 @@
       // a Load
       // inputs are (0:control, 1:memory, 2:address)
       if (!(n->ideal_Opcode()==ld_op)       && // Following are special cases
-          !(n->ideal_Opcode()==Op_LoadLLocked && ld_op==Op_LoadI) &&
           !(n->ideal_Opcode()==Op_LoadPLocked && ld_op==Op_LoadP) &&
           !(n->ideal_Opcode()==Op_LoadI     && ld_op==Op_LoadF) &&
           !(n->ideal_Opcode()==Op_LoadF     && ld_op==Op_LoadI) &&
@@ -841,10 +848,7 @@
           !(n->ideal_Opcode()==Op_PrefetchRead  && ld_op==Op_LoadI) &&
           !(n->ideal_Opcode()==Op_PrefetchWrite && ld_op==Op_LoadI) &&
           !(n->ideal_Opcode()==Op_PrefetchAllocation && ld_op==Op_LoadI) &&
-          !(n->ideal_Opcode()==Op_Load2I    && ld_op==Op_LoadD) &&
-          !(n->ideal_Opcode()==Op_Load4C    && ld_op==Op_LoadD) &&
-          !(n->ideal_Opcode()==Op_Load4S    && ld_op==Op_LoadD) &&
-          !(n->ideal_Opcode()==Op_Load8B    && ld_op==Op_LoadD) &&
+          !(n->ideal_Opcode()==Op_LoadVector && ld_op==Op_LoadD) &&
           !(n->rule() == loadUB_rule)) {
         verify_oops_warning(n, n->ideal_Opcode(), ld_op);
       }
@@ -856,9 +860,7 @@
           !(n->ideal_Opcode()==Op_StoreI && st_op==Op_StoreF) &&
           !(n->ideal_Opcode()==Op_StoreF && st_op==Op_StoreI) &&
           !(n->ideal_Opcode()==Op_StoreL && st_op==Op_StoreI) &&
-          !(n->ideal_Opcode()==Op_Store2I && st_op==Op_StoreD) &&
-          !(n->ideal_Opcode()==Op_Store4C && st_op==Op_StoreD) &&
-          !(n->ideal_Opcode()==Op_Store8B && st_op==Op_StoreD) &&
+          !(n->ideal_Opcode()==Op_StoreVector && st_op==Op_StoreD) &&
           !(n->ideal_Opcode()==Op_StoreD && st_op==Op_StoreI && n->rule() == storeD0_rule)) {
         verify_oops_warning(n, n->ideal_Opcode(), st_op);
       }
@@ -1832,8 +1834,16 @@
   case Op_CountLeadingZerosL:
   case Op_CountTrailingZerosI:
   case Op_CountTrailingZerosL:
+  case Op_PopCountI:
+  case Op_PopCountL:
     if (!UsePopCountInstruction)
       return false;
+  case Op_CompareAndSwapL:
+#ifdef _LP64
+  case Op_CompareAndSwapP:
+#endif
+    if (!VM_Version::supports_cx8())
+      return false;
     break;
   }
 
@@ -1848,16 +1858,50 @@
 address last_rethrow = NULL;  // debugging aid for Rethrow encoding
 #endif
 
+// Map Types to machine register types
+const int Matcher::base2reg[Type::lastype] = {
+  Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN,
+  Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */
+  0, Op_RegD, 0, 0, /* Vectors */
+  Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */
+  0, 0/*abio*/,
+  Op_RegP /* Return address */, 0, /* the memories */
+  Op_RegF, Op_RegF, Op_RegF, Op_RegD, Op_RegD, Op_RegD,
+  0  /*bottom*/
+};
+
 // Vector width in bytes
-const uint Matcher::vector_width_in_bytes(void) {
+const int Matcher::vector_width_in_bytes(BasicType bt) {
+  assert(MaxVectorSize == 8, "");
   return 8;
 }
 
 // Vector ideal reg
-const uint Matcher::vector_ideal_reg(void) {
+const int Matcher::vector_ideal_reg(int size) {
+  assert(MaxVectorSize == 8, "");
   return Op_RegD;
 }
 
+const int Matcher::vector_shift_count_ideal_reg(int size) {
+  fatal("vector shift is not supported");
+  return Node::NotAMachineReg;
+}
+
+// Limits on vector size (number of elements) loaded into vector.
+const int Matcher::max_vector_size(const BasicType bt) {
+  assert(is_java_primitive(bt), "only primitive type vectors");
+  return vector_width_in_bytes(bt)/type2aelembytes(bt);
+}
+
+const int Matcher::min_vector_size(const BasicType bt) {
+  return max_vector_size(bt); // Same as max.
+}
+
+// SPARC doesn't support misaligned vectors store/load.
+const bool Matcher::misaligned_vectors_ok() {
+  return false;
+}
+
 // USII supports fxtof through the whole range of number, USIII doesn't
 const bool Matcher::convL2FSupported(void) {
   return VM_Version::has_fast_fxtof();
@@ -3124,50 +3168,6 @@
     __ membar( Assembler::Membar_mask_bits(Assembler::StoreLoad) );
   %}
 
-  enc_class enc_repl8b( iRegI src, iRegL dst ) %{
-    MacroAssembler _masm(&cbuf);
-    Register src_reg = reg_to_register_object($src$$reg);
-    Register dst_reg = reg_to_register_object($dst$$reg);
-    __ sllx(src_reg, 56, dst_reg);
-    __ srlx(dst_reg,  8, O7);
-    __ or3 (dst_reg, O7, dst_reg);
-    __ srlx(dst_reg, 16, O7);
-    __ or3 (dst_reg, O7, dst_reg);
-    __ srlx(dst_reg, 32, O7);
-    __ or3 (dst_reg, O7, dst_reg);
-  %}
-
-  enc_class enc_repl4b( iRegI src, iRegL dst ) %{
-    MacroAssembler _masm(&cbuf);
-    Register src_reg = reg_to_register_object($src$$reg);
-    Register dst_reg = reg_to_register_object($dst$$reg);
-    __ sll(src_reg, 24, dst_reg);
-    __ srl(dst_reg,  8, O7);
-    __ or3(dst_reg, O7, dst_reg);
-    __ srl(dst_reg, 16, O7);
-    __ or3(dst_reg, O7, dst_reg);
-  %}
-
-  enc_class enc_repl4s( iRegI src, iRegL dst ) %{
-    MacroAssembler _masm(&cbuf);
-    Register src_reg = reg_to_register_object($src$$reg);
-    Register dst_reg = reg_to_register_object($dst$$reg);
-    __ sllx(src_reg, 48, dst_reg);
-    __ srlx(dst_reg, 16, O7);
-    __ or3 (dst_reg, O7, dst_reg);
-    __ srlx(dst_reg, 32, O7);
-    __ or3 (dst_reg, O7, dst_reg);
-  %}
-
-  enc_class enc_repl2i( iRegI src, iRegL dst ) %{
-    MacroAssembler _masm(&cbuf);
-    Register src_reg = reg_to_register_object($src$$reg);
-    Register dst_reg = reg_to_register_object($dst$$reg);
-    __ sllx(src_reg, 32, dst_reg);
-    __ srlx(dst_reg, 32, O7);
-    __ or3 (dst_reg, O7, dst_reg);
-  %}
-
 %}
 
 //----------FRAME--------------------------------------------------------------
@@ -5891,8 +5891,8 @@
 %}
 
 // Load Unsigned Integer into a Long Register
-instruct loadUI2L(iRegL dst, memory mem) %{
-  match(Set dst (LoadUI2L mem));
+instruct loadUI2L(iRegL dst, memory mem, immL_32bits mask) %{
+  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
   ins_cost(MEMORY_REF_COST);
 
   size(4);
@@ -5931,50 +5931,6 @@
   ins_pipe(iload_mem);
 %}
 
-// Load Aligned Packed Byte into a Double Register
-instruct loadA8B(regD dst, memory mem) %{
-  match(Set dst (Load8B mem));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "LDDF   $mem,$dst\t! packed8B" %}
-  opcode(Assembler::lddf_op3);
-  ins_encode(simple_form3_mem_reg( mem, dst ) );
-  ins_pipe(floadD_mem);
-%}
-
-// Load Aligned Packed Char into a Double Register
-instruct loadA4C(regD dst, memory mem) %{
-  match(Set dst (Load4C mem));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "LDDF   $mem,$dst\t! packed4C" %}
-  opcode(Assembler::lddf_op3);
-  ins_encode(simple_form3_mem_reg( mem, dst ) );
-  ins_pipe(floadD_mem);
-%}
-
-// Load Aligned Packed Short into a Double Register
-instruct loadA4S(regD dst, memory mem) %{
-  match(Set dst (Load4S mem));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "LDDF   $mem,$dst\t! packed4S" %}
-  opcode(Assembler::lddf_op3);
-  ins_encode(simple_form3_mem_reg( mem, dst ) );
-  ins_pipe(floadD_mem);
-%}
-
-// Load Aligned Packed Int into a Double Register
-instruct loadA2I(regD dst, memory mem) %{
-  match(Set dst (Load2I mem));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "LDDF   $mem,$dst\t! packed2I" %}
-  opcode(Assembler::lddf_op3);
-  ins_encode(simple_form3_mem_reg( mem, dst ) );
-  ins_pipe(floadD_mem);
-%}
-
 // Load Range
 instruct loadRange(iRegI dst, memory mem) %{
   match(Set dst (LoadRange mem));
@@ -6598,17 +6554,6 @@
   ins_pipe(fstoreF_mem_zero);
 %}
 
-// Store Aligned Packed Bytes in Double register to memory
-instruct storeA8B(memory mem, regD src) %{
-  match(Set mem (Store8B mem src));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "STDF   $src,$mem\t! packed8B" %}
-  opcode(Assembler::stdf_op3);
-  ins_encode(simple_form3_mem_reg( mem, src ) );
-  ins_pipe(fstoreD_mem_reg);
-%}
-
 // Convert oop pointer into compressed form
 instruct encodeHeapOop(iRegN dst, iRegP src) %{
   predicate(n->bottom_type()->make_ptr()->ptr() != TypePtr::NotNull);
@@ -6653,62 +6598,6 @@
 %}
 
 
-// Store Zero into Aligned Packed Bytes
-instruct storeA8B0(memory mem, immI0 zero) %{
-  match(Set mem (Store8B mem zero));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "STX    $zero,$mem\t! packed8B" %}
-  opcode(Assembler::stx_op3);
-  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
-  ins_pipe(fstoreD_mem_zero);
-%}
-
-// Store Aligned Packed Chars/Shorts in Double register to memory
-instruct storeA4C(memory mem, regD src) %{
-  match(Set mem (Store4C mem src));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "STDF   $src,$mem\t! packed4C" %}
-  opcode(Assembler::stdf_op3);
-  ins_encode(simple_form3_mem_reg( mem, src ) );
-  ins_pipe(fstoreD_mem_reg);
-%}
-
-// Store Zero into Aligned Packed Chars/Shorts
-instruct storeA4C0(memory mem, immI0 zero) %{
-  match(Set mem (Store4C mem (Replicate4C zero)));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "STX    $zero,$mem\t! packed4C" %}
-  opcode(Assembler::stx_op3);
-  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
-  ins_pipe(fstoreD_mem_zero);
-%}
-
-// Store Aligned Packed Ints in Double register to memory
-instruct storeA2I(memory mem, regD src) %{
-  match(Set mem (Store2I mem src));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "STDF   $src,$mem\t! packed2I" %}
-  opcode(Assembler::stdf_op3);
-  ins_encode(simple_form3_mem_reg( mem, src ) );
-  ins_pipe(fstoreD_mem_reg);
-%}
-
-// Store Zero into Aligned Packed Ints
-instruct storeA2I0(memory mem, immI0 zero) %{
-  match(Set mem (Store2I mem zero));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "STX    $zero,$mem\t! packed2I" %}
-  opcode(Assembler::stx_op3);
-  ins_encode(simple_form3_mem_reg( mem, R_G0 ) );
-  ins_pipe(fstoreD_mem_zero);
-%}
-
-
 //----------MemBar Instructions-----------------------------------------------
 // Memory barrier flavors
 
@@ -7304,17 +7193,6 @@
   ins_pipe(iload_mem);
 %}
 
-// LoadL-locked.  Same as a regular long load when used with a compare-swap
-instruct loadLLocked(iRegL dst, memory mem) %{
-  match(Set dst (LoadLLocked mem));
-  ins_cost(MEMORY_REF_COST);
-  size(4);
-  format %{ "LDX    $mem,$dst\t! long" %}
-  opcode(Assembler::ldx_op3);
-  ins_encode(simple_form3_mem_reg( mem, dst ) );
-  ins_pipe(iload_mem);
-%}
-
 instruct storePConditional( iRegP heap_top_ptr, iRegP oldval, g3RegP newval, flagsRegP pcc ) %{
   match(Set pcc (StorePConditional heap_top_ptr (Binary oldval newval)));
   effect( KILL newval );
@@ -7347,6 +7225,7 @@
 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 
 instruct compareAndSwapL_bool(iRegP mem_ptr, iRegL oldval, iRegL newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
+  predicate(VM_Version::supports_cx8());
   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
   effect( USE mem_ptr, KILL ccr, KILL tmp1);
   format %{
@@ -7378,6 +7257,9 @@
 %}
 
 instruct compareAndSwapP_bool(iRegP mem_ptr, iRegP oldval, iRegP newval, iRegI res, o7RegI tmp1, flagsReg ccr ) %{
+#ifdef _LP64
+  predicate(VM_Version::supports_cx8());
+#endif
   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
   effect( USE mem_ptr, KILL ccr, KILL tmp1);
   format %{
@@ -7412,6 +7294,38 @@
   ins_pipe( long_memory_op );
 %}
 
+instruct xchgI( memory mem, iRegI newval) %{
+  match(Set newval (GetAndSetI mem newval));
+  format %{ "SWAP  [$mem],$newval" %}
+  size(4);
+  ins_encode %{
+    __ swap($mem$$Address, $newval$$Register);
+  %}
+  ins_pipe( long_memory_op );
+%}
+
+#ifndef _LP64
+instruct xchgP( memory mem, iRegP newval) %{
+  match(Set newval (GetAndSetP mem newval));
+  format %{ "SWAP  [$mem],$newval" %}
+  size(4);
+  ins_encode %{
+    __ swap($mem$$Address, $newval$$Register);
+  %}
+  ins_pipe( long_memory_op );
+%}
+#endif
+
+instruct xchgN( memory mem, iRegN newval) %{
+  match(Set newval (GetAndSetN mem newval));
+  format %{ "SWAP  [$mem],$newval" %}
+  size(4);
+  ins_encode %{
+    __ swap($mem$$Address, $newval$$Register);
+  %}
+  ins_pipe( long_memory_op );
+%}
+
 //---------------------
 // Subtraction Instructions
 // Register Subtraction
@@ -8890,150 +8804,6 @@
   ins_pipe(ialu_reg_imm);
 %}
 
-// Replicate scalar to packed byte values in Double register
-instruct Repl8B_reg_helper(iRegL dst, iRegI src) %{
-  effect(DEF dst, USE src);
-  format %{ "SLLX  $src,56,$dst\n\t"
-            "SRLX  $dst, 8,O7\n\t"
-            "OR    $dst,O7,$dst\n\t"
-            "SRLX  $dst,16,O7\n\t"
-            "OR    $dst,O7,$dst\n\t"
-            "SRLX  $dst,32,O7\n\t"
-            "OR    $dst,O7,$dst\t! replicate8B" %}
-  ins_encode( enc_repl8b(src, dst));
-  ins_pipe(ialu_reg);
-%}
-
-// Replicate scalar to packed byte values in Double register
-instruct Repl8B_reg(stackSlotD dst, iRegI src) %{
-  match(Set dst (Replicate8B src));
-  expand %{
-    iRegL tmp;
-    Repl8B_reg_helper(tmp, src);
-    regL_to_stkD(dst, tmp);
-  %}
-%}
-
-// Replicate scalar constant to packed byte values in Double register
-instruct Repl8B_immI(regD dst, immI13 con, o7RegI tmp) %{
-  match(Set dst (Replicate8B con));
-  effect(KILL tmp);
-  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl8B($con)" %}
-  ins_encode %{
-    // XXX This is a quick fix for 6833573.
-    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), $dst$$FloatRegister);
-    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 8, 1)), $tmp$$Register);
-    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
-  %}
-  ins_pipe(loadConFD);
-%}
-
-// Replicate scalar to packed char values into stack slot
-instruct Repl4C_reg_helper(iRegL dst, iRegI src) %{
-  effect(DEF dst, USE src);
-  format %{ "SLLX  $src,48,$dst\n\t"
-            "SRLX  $dst,16,O7\n\t"
-            "OR    $dst,O7,$dst\n\t"
-            "SRLX  $dst,32,O7\n\t"
-            "OR    $dst,O7,$dst\t! replicate4C" %}
-  ins_encode( enc_repl4s(src, dst) );
-  ins_pipe(ialu_reg);
-%}
-
-// Replicate scalar to packed char values into stack slot
-instruct Repl4C_reg(stackSlotD dst, iRegI src) %{
-  match(Set dst (Replicate4C src));
-  expand %{
-    iRegL tmp;
-    Repl4C_reg_helper(tmp, src);
-    regL_to_stkD(dst, tmp);
-  %}
-%}
-
-// Replicate scalar constant to packed char values in Double register
-instruct Repl4C_immI(regD dst, immI con, o7RegI tmp) %{
-  match(Set dst (Replicate4C con));
-  effect(KILL tmp);
-  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4C($con)" %}
-  ins_encode %{
-    // XXX This is a quick fix for 6833573.
-    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
-    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register);
-    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
-  %}
-  ins_pipe(loadConFD);
-%}
-
-// Replicate scalar to packed short values into stack slot
-instruct Repl4S_reg_helper(iRegL dst, iRegI src) %{
-  effect(DEF dst, USE src);
-  format %{ "SLLX  $src,48,$dst\n\t"
-            "SRLX  $dst,16,O7\n\t"
-            "OR    $dst,O7,$dst\n\t"
-            "SRLX  $dst,32,O7\n\t"
-            "OR    $dst,O7,$dst\t! replicate4S" %}
-  ins_encode( enc_repl4s(src, dst) );
-  ins_pipe(ialu_reg);
-%}
-
-// Replicate scalar to packed short values into stack slot
-instruct Repl4S_reg(stackSlotD dst, iRegI src) %{
-  match(Set dst (Replicate4S src));
-  expand %{
-    iRegL tmp;
-    Repl4S_reg_helper(tmp, src);
-    regL_to_stkD(dst, tmp);
-  %}
-%}
-
-// Replicate scalar constant to packed short values in Double register
-instruct Repl4S_immI(regD dst, immI con, o7RegI tmp) %{
-  match(Set dst (Replicate4S con));
-  effect(KILL tmp);
-  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4S($con)" %}
-  ins_encode %{
-    // XXX This is a quick fix for 6833573.
-    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
-    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register);
-    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
-  %}
-  ins_pipe(loadConFD);
-%}
-
-// Replicate scalar to packed int values in Double register
-instruct Repl2I_reg_helper(iRegL dst, iRegI src) %{
-  effect(DEF dst, USE src);
-  format %{ "SLLX  $src,32,$dst\n\t"
-            "SRLX  $dst,32,O7\n\t"
-            "OR    $dst,O7,$dst\t! replicate2I" %}
-  ins_encode( enc_repl2i(src, dst));
-  ins_pipe(ialu_reg);
-%}
-
-// Replicate scalar to packed int values in Double register
-instruct Repl2I_reg(stackSlotD dst, iRegI src) %{
-  match(Set dst (Replicate2I src));
-  expand %{
-    iRegL tmp;
-    Repl2I_reg_helper(tmp, src);
-    regL_to_stkD(dst, tmp);
-  %}
-%}
-
-// Replicate scalar zero constant to packed int values in Double register
-instruct Repl2I_immI(regD dst, immI con, o7RegI tmp) %{
-  match(Set dst (Replicate2I con));
-  effect(KILL tmp);
-  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2I($con)" %}
-  ins_encode %{
-    // XXX This is a quick fix for 6833573.
-    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), $dst$$FloatRegister);
-    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 2, 4)), $tmp$$Register);
-    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
-  %}
-  ins_pipe(loadConFD);
-%}
-
 //----------Control Flow Instructions------------------------------------------
 // Compare Instructions
 // Compare Integers
@@ -10752,6 +10522,308 @@
   ins_pipe(istore_mem_reg);
 %}
 
+// ====================VECTOR INSTRUCTIONS=====================================
+
+// Load Aligned Packed values into a Double Register
+instruct loadV8(regD dst, memory mem) %{
+  predicate(n->as_LoadVector()->memory_size() == 8);
+  match(Set dst (LoadVector mem));
+  ins_cost(MEMORY_REF_COST);
+  size(4);
+  format %{ "LDDF   $mem,$dst\t! load vector (8 bytes)" %}
+  ins_encode %{
+    __ ldf(FloatRegisterImpl::D, $mem$$Address, as_DoubleFloatRegister($dst$$reg));
+  %}
+  ins_pipe(floadD_mem);
+%}
+
+// Store Vector in Double register to memory
+instruct storeV8(memory mem, regD src) %{
+  predicate(n->as_StoreVector()->memory_size() == 8);
+  match(Set mem (StoreVector mem src));
+  ins_cost(MEMORY_REF_COST);
+  size(4);
+  format %{ "STDF   $src,$mem\t! store vector (8 bytes)" %}
+  ins_encode %{
+    __ stf(FloatRegisterImpl::D, as_DoubleFloatRegister($src$$reg), $mem$$Address);
+  %}
+  ins_pipe(fstoreD_mem_reg);
+%}
+
+// Store Zero into vector in memory
+instruct storeV8B_zero(memory mem, immI0 zero) %{
+  predicate(n->as_StoreVector()->memory_size() == 8);
+  match(Set mem (StoreVector mem (ReplicateB zero)));
+  ins_cost(MEMORY_REF_COST);
+  size(4);
+  format %{ "STX    $zero,$mem\t! store zero vector (8 bytes)" %}
+  ins_encode %{
+    __ stx(G0, $mem$$Address);
+  %}
+  ins_pipe(fstoreD_mem_zero);
+%}
+
+instruct storeV4S_zero(memory mem, immI0 zero) %{
+  predicate(n->as_StoreVector()->memory_size() == 8);
+  match(Set mem (StoreVector mem (ReplicateS zero)));
+  ins_cost(MEMORY_REF_COST);
+  size(4);
+  format %{ "STX    $zero,$mem\t! store zero vector (4 shorts)" %}
+  ins_encode %{
+    __ stx(G0, $mem$$Address);
+  %}
+  ins_pipe(fstoreD_mem_zero);
+%}
+
+instruct storeV2I_zero(memory mem, immI0 zero) %{
+  predicate(n->as_StoreVector()->memory_size() == 8);
+  match(Set mem (StoreVector mem (ReplicateI zero)));
+  ins_cost(MEMORY_REF_COST);
+  size(4);
+  format %{ "STX    $zero,$mem\t! store zero vector (2 ints)" %}
+  ins_encode %{
+    __ stx(G0, $mem$$Address);
+  %}
+  ins_pipe(fstoreD_mem_zero);
+%}
+
+instruct storeV2F_zero(memory mem, immF0 zero) %{
+  predicate(n->as_StoreVector()->memory_size() == 8);
+  match(Set mem (StoreVector mem (ReplicateF zero)));
+  ins_cost(MEMORY_REF_COST);
+  size(4);
+  format %{ "STX    $zero,$mem\t! store zero vector (2 floats)" %}
+  ins_encode %{
+    __ stx(G0, $mem$$Address);
+  %}
+  ins_pipe(fstoreD_mem_zero);
+%}
+
+// Replicate scalar to packed byte values into Double register
+instruct Repl8B_reg(regD dst, iRegI src, iRegL tmp, o7RegL tmp2) %{
+  predicate(n->as_Vector()->length() == 8 && UseVIS >= 3);
+  match(Set dst (ReplicateB src));
+  effect(DEF dst, USE src, TEMP tmp, KILL tmp2);
+  format %{ "SLLX  $src,56,$tmp\n\t"
+            "SRLX  $tmp, 8,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\n\t"
+            "SRLX  $tmp,16,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\n\t"
+            "SRLX  $tmp,32,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\t! replicate8B\n\t"
+            "MOVXTOD $tmp,$dst\t! MoveL2D" %}
+  ins_encode %{
+    Register Rsrc = $src$$Register;
+    Register Rtmp = $tmp$$Register;
+    Register Rtmp2 = $tmp2$$Register;
+    __ sllx(Rsrc,    56, Rtmp);
+    __ srlx(Rtmp,     8, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ srlx(Rtmp,    16, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ srlx(Rtmp,    32, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ movxtod(Rtmp, as_DoubleFloatRegister($dst$$reg));
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+// Replicate scalar to packed byte values into Double stack
+instruct Repl8B_stk(stackSlotD dst, iRegI src, iRegL tmp, o7RegL tmp2) %{
+  predicate(n->as_Vector()->length() == 8 && UseVIS < 3);
+  match(Set dst (ReplicateB src));
+  effect(DEF dst, USE src, TEMP tmp, KILL tmp2);
+  format %{ "SLLX  $src,56,$tmp\n\t"
+            "SRLX  $tmp, 8,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\n\t"
+            "SRLX  $tmp,16,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\n\t"
+            "SRLX  $tmp,32,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\t! replicate8B\n\t"
+            "STX   $tmp,$dst\t! regL to stkD" %}
+  ins_encode %{
+    Register Rsrc = $src$$Register;
+    Register Rtmp = $tmp$$Register;
+    Register Rtmp2 = $tmp2$$Register;
+    __ sllx(Rsrc,    56, Rtmp);
+    __ srlx(Rtmp,     8, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ srlx(Rtmp,    16, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ srlx(Rtmp,    32, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ set ($dst$$disp + STACK_BIAS, Rtmp2);
+    __ stx (Rtmp, Rtmp2, $dst$$base$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+// Replicate scalar constant to packed byte values in Double register
+instruct Repl8B_immI(regD dst, immI13 con, o7RegI tmp) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateB con));
+  effect(KILL tmp);
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl8B($con)" %}
+  ins_encode %{
+    // XXX This is a quick fix for 6833573.
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 8, 1)), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 8, 1)), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
+  %}
+  ins_pipe(loadConFD);
+%}
+
+// Replicate scalar to packed char/short values into Double register
+instruct Repl4S_reg(regD dst, iRegI src, iRegL tmp, o7RegL tmp2) %{
+  predicate(n->as_Vector()->length() == 4 && UseVIS >= 3);
+  match(Set dst (ReplicateS src));
+  effect(DEF dst, USE src, TEMP tmp, KILL tmp2);
+  format %{ "SLLX  $src,48,$tmp\n\t"
+            "SRLX  $tmp,16,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\n\t"
+            "SRLX  $tmp,32,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\t! replicate4S\n\t"
+            "MOVXTOD $tmp,$dst\t! MoveL2D" %}
+  ins_encode %{
+    Register Rsrc = $src$$Register;
+    Register Rtmp = $tmp$$Register;
+    Register Rtmp2 = $tmp2$$Register;
+    __ sllx(Rsrc,    48, Rtmp);
+    __ srlx(Rtmp,    16, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ srlx(Rtmp,    32, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ movxtod(Rtmp, as_DoubleFloatRegister($dst$$reg));
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+// Replicate scalar to packed char/short values into Double stack
+instruct Repl4S_stk(stackSlotD dst, iRegI src, iRegL tmp, o7RegL tmp2) %{
+  predicate(n->as_Vector()->length() == 4 && UseVIS < 3);
+  match(Set dst (ReplicateS src));
+  effect(DEF dst, USE src, TEMP tmp, KILL tmp2);
+  format %{ "SLLX  $src,48,$tmp\n\t"
+            "SRLX  $tmp,16,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\n\t"
+            "SRLX  $tmp,32,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\t! replicate4S\n\t"
+            "STX   $tmp,$dst\t! regL to stkD" %}
+  ins_encode %{
+    Register Rsrc = $src$$Register;
+    Register Rtmp = $tmp$$Register;
+    Register Rtmp2 = $tmp2$$Register;
+    __ sllx(Rsrc,    48, Rtmp);
+    __ srlx(Rtmp,    16, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ srlx(Rtmp,    32, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ set ($dst$$disp + STACK_BIAS, Rtmp2);
+    __ stx (Rtmp, Rtmp2, $dst$$base$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+// Replicate scalar constant to packed char/short values in Double register
+instruct Repl4S_immI(regD dst, immI con, o7RegI tmp) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateS con));
+  effect(KILL tmp);
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl4S($con)" %}
+  ins_encode %{
+    // XXX This is a quick fix for 6833573.
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 4, 2)), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 4, 2)), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
+  %}
+  ins_pipe(loadConFD);
+%}
+
+// Replicate scalar to packed int values into Double register
+instruct Repl2I_reg(regD dst, iRegI src, iRegL tmp, o7RegL tmp2) %{
+  predicate(n->as_Vector()->length() == 2 && UseVIS >= 3);
+  match(Set dst (ReplicateI src));
+  effect(DEF dst, USE src, TEMP tmp, KILL tmp2);
+  format %{ "SLLX  $src,32,$tmp\n\t"
+            "SRLX  $tmp,32,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\t! replicate2I\n\t"
+            "MOVXTOD $tmp,$dst\t! MoveL2D" %}
+  ins_encode %{
+    Register Rsrc = $src$$Register;
+    Register Rtmp = $tmp$$Register;
+    Register Rtmp2 = $tmp2$$Register;
+    __ sllx(Rsrc,    32, Rtmp);
+    __ srlx(Rtmp,    32, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ movxtod(Rtmp, as_DoubleFloatRegister($dst$$reg));
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+// Replicate scalar to packed int values into Double stack
+instruct Repl2I_stk(stackSlotD dst, iRegI src, iRegL tmp, o7RegL tmp2) %{
+  predicate(n->as_Vector()->length() == 2 && UseVIS < 3);
+  match(Set dst (ReplicateI src));
+  effect(DEF dst, USE src, TEMP tmp, KILL tmp2);
+  format %{ "SLLX  $src,32,$tmp\n\t"
+            "SRLX  $tmp,32,$tmp2\n\t"
+            "OR    $tmp,$tmp2,$tmp\t! replicate2I\n\t"
+            "STX   $tmp,$dst\t! regL to stkD" %}
+  ins_encode %{
+    Register Rsrc = $src$$Register;
+    Register Rtmp = $tmp$$Register;
+    Register Rtmp2 = $tmp2$$Register;
+    __ sllx(Rsrc,    32, Rtmp);
+    __ srlx(Rtmp,    32, Rtmp2);
+    __ or3 (Rtmp, Rtmp2, Rtmp);
+    __ set ($dst$$disp + STACK_BIAS, Rtmp2);
+    __ stx (Rtmp, Rtmp2, $dst$$base$$Register);
+  %}
+  ins_pipe(ialu_reg);
+%}
+
+// Replicate scalar zero constant to packed int values in Double register
+instruct Repl2I_immI(regD dst, immI con, o7RegI tmp) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateI con));
+  effect(KILL tmp);
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2I($con)" %}
+  ins_encode %{
+    // XXX This is a quick fix for 6833573.
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immI($con$$constant, 2, 4)), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immI($con$$constant, 2, 4)), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
+  %}
+  ins_pipe(loadConFD);
+%}
+
+// Replicate scalar to packed float values into Double stack
+instruct Repl2F_stk(stackSlotD dst, regF src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateF src));
+  ins_cost(MEMORY_REF_COST*2);
+  format %{ "STF    $src,$dst.hi\t! packed2F\n\t"
+            "STF    $src,$dst.lo" %}
+  opcode(Assembler::stf_op3);
+  ins_encode(simple_form3_mem_reg(dst, src), form3_mem_plus_4_reg(dst, src));
+  ins_pipe(fstoreF_stk_reg);
+%}
+
+// Replicate scalar zero constant to packed float values in Double register
+instruct Repl2F_immF(regD dst, immF con, o7RegI tmp) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateF con));
+  effect(KILL tmp);
+  format %{ "LDDF   [$constanttablebase + $constantoffset],$dst\t! load from constant table: Repl2F($con)" %}
+  ins_encode %{
+    // XXX This is a quick fix for 6833573.
+    //__ ldf(FloatRegisterImpl::D, $constanttablebase, $constantoffset(replicate_immF($con$$constant)), $dst$$FloatRegister);
+    RegisterOrConstant con_offset = __ ensure_simm13_or_reg($constantoffset(replicate_immF($con$$constant)), $tmp$$Register);
+    __ ldf(FloatRegisterImpl::D, $constanttablebase, con_offset, as_DoubleFloatRegister($dst$$reg));
+  %}
+  ins_pipe(loadConFD);
+%}
+
 //----------PEEPHOLE RULES-----------------------------------------------------
 // These must follow all instruction definitions as they use the names
 // defined in the instructions definitions.
diff --git a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
index 0e076db..c1851b9 100644
--- a/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/stubGenerator_sparc.cpp
@@ -3404,14 +3404,6 @@
     StubRoutines::_atomic_add_ptr_entry      = StubRoutines::_atomic_add_entry;
 #endif  // COMPILER2 !=> _LP64
 
-    // Build this early so it's available for the interpreter.  The
-    // stub expects the required and actual type to already be in O1
-    // and O2 respectively.
-    StubRoutines::_throw_WrongMethodTypeException_entry =
-      generate_throw_exception("WrongMethodTypeException throw_exception",
-                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException),
-                               G5_method_type, G3_method_handle);
-
     // Build this early so it's available for the interpreter.
     StubRoutines::_throw_StackOverflowError_entry          = generate_throw_exception("StackOverflowError throw_exception",           CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
   }
diff --git a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
index ceb6a59..0dcf764 100644
--- a/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/templateInterpreter_sparc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -371,7 +371,8 @@
     __ br( Assembler::zero, true, Assembler::pt, done);
     __ delayed()->ld_ptr(Llocals, Interpreter::local_offset_in_bytes(0), O0); // get receiver for not-static case
 
-    __ ld_ptr( Lmethod, in_bytes(methodOopDesc::constants_offset()), O0);
+    __ ld_ptr( Lmethod, in_bytes(methodOopDesc::const_offset()), O0);
+    __ ld_ptr( O0, in_bytes(constMethodOopDesc::constants_offset()), O0);
     __ ld_ptr( O0, constantPoolOopDesc::pool_holder_offset_in_bytes(), O0);
 
     // lock the mirror, not the klassOop
@@ -379,7 +380,7 @@
 
 #ifdef ASSERT
     __ tst(O0);
-    __ breakpoint_trap(Assembler::zero);
+    __ breakpoint_trap(Assembler::zero, Assembler::ptr_cc);
 #endif // ASSERT
 
     __ bind(done);
@@ -433,7 +434,7 @@
 
   // the frame is greater than one page in size, so check against
   // the bottom of the stack
-  __ cmp_and_brx_short(SP, Rscratch, Assembler::greater, Assembler::pt, after_frame_check);
+  __ cmp_and_brx_short(SP, Rscratch, Assembler::greaterUnsigned, Assembler::pt, after_frame_check);
 
   // the stack will overflow, throw an exception
 
@@ -670,7 +671,8 @@
                       ConstantPoolCacheEntry::size()) * BytesPerWord), G1_scratch);
 
     // get constant pool cache
-    __ ld_ptr(G5_method, methodOopDesc::constants_offset(), G3_scratch);
+    __ ld_ptr(G5_method, methodOopDesc::const_offset(), G3_scratch);
+    __ ld_ptr(G3_scratch, constMethodOopDesc::constants_offset(), G3_scratch);
     __ ld_ptr(G3_scratch, constantPoolOopDesc::cache_offset_in_bytes(), G3_scratch);
 
     // get specific constant pool cache entry
@@ -692,9 +694,9 @@
     // Need to differentiate between igetfield, agetfield, bgetfield etc.
     // because they are different sizes.
     // Get the type from the constant pool cache
-    __ srl(G1_scratch, ConstantPoolCacheEntry::tosBits, G1_scratch);
-    // Make sure we don't need to mask G1_scratch for tosBits after the above shift
-    ConstantPoolCacheEntry::verify_tosBits();
+    __ srl(G1_scratch, ConstantPoolCacheEntry::tos_state_shift, G1_scratch);
+    // Make sure we don't need to mask G1_scratch after the above shift
+    ConstantPoolCacheEntry::verify_tos_state_shift();
     __ cmp(G1_scratch, atos );
     __ br(Assembler::equal, true, Assembler::pt, xreturn_path);
     __ delayed()->ld_ptr(Otos_i, G3_scratch, Otos_i);
@@ -993,7 +995,8 @@
     // for static methods insert the mirror argument
     const int mirror_offset = in_bytes(Klass::java_mirror_offset());
 
-    __ ld_ptr(Lmethod, methodOopDesc:: constants_offset(), O1);
+    __ ld_ptr(Lmethod, methodOopDesc:: const_offset(), O1);
+    __ ld_ptr(O1, constMethodOopDesc::constants_offset(), O1);
     __ ld_ptr(O1, constantPoolOopDesc::pool_holder_offset_in_bytes(), O1);
     __ ld_ptr(O1, mirror_offset, O1);
 #ifdef ASSERT
@@ -1659,7 +1662,7 @@
       int computed_sp_adjustment = (delta > 0) ? round_to(delta, WordsPerLong) : 0;
       *interpreter_frame->register_addr(I5_savedSP)    = (intptr_t) (fp + computed_sp_adjustment) - STACK_BIAS;
     } else {
-      assert(caller->is_compiled_frame() || caller->is_entry_frame() || caller->is_ricochet_frame(), "only possible cases");
+      assert(caller->is_compiled_frame() || caller->is_entry_frame(), "only possible cases");
       // Don't have Lesp available; lay out locals block in the caller
       // adjacent to the register window save area.
       //
@@ -2050,7 +2053,7 @@
   AddressLiteral stop_at(&StopInterpreterAt);
   __ load_ptr_contents(stop_at, G4_scratch);
   __ cmp(G3_scratch, G4_scratch);
-  __ breakpoint_trap(Assembler::equal);
+  __ breakpoint_trap(Assembler::equal, Assembler::icc);
 }
 #endif // not PRODUCT
 #endif // !CC_INTERP
diff --git a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
index af6829b..016799e 100644
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.cpp
@@ -378,7 +378,7 @@
   Register Rcache = G3_scratch;
   Register Rscratch = G4_scratch;
 
-  resolve_cache_and_index(f1_oop, Otos_i, Rcache, Rscratch, wide ? sizeof(u2) : sizeof(u1));
+  resolve_cache_and_index(f12_oop, Otos_i, Rcache, Rscratch, wide ? sizeof(u2) : sizeof(u1));
 
   __ verify_oop(Otos_i);
 
@@ -2093,10 +2093,12 @@
   // Depends on cpCacheOop layout!
   Label resolved;
 
-  if (byte_no == f1_oop) {
-    // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
-    // This kind of CP cache entry does not need to match the flags byte, because
+  if (byte_no == f12_oop) {
+    // We are resolved if the f1 field contains a non-null object (CallSite, MethodType, etc.)
+    // This kind of CP cache entry does not need to match bytecode_1 or bytecode_2, because
     // there is a 1-1 relation between bytecode type and CP entry type.
+    // The caller will also load a methodOop from f2.
+    assert(result != noreg, "");
     assert_different_registers(result, Rcache);
     __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
     __ ld_ptr(Rcache, constantPoolCacheOopDesc::base_offset() +
@@ -2123,10 +2125,13 @@
     case Bytecodes::_invokespecial  : // fall through
     case Bytecodes::_invokestatic   : // fall through
     case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;
+    case Bytecodes::_invokehandle   : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);  break;
     case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);  break;
     case Bytecodes::_fast_aldc      : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
     case Bytecodes::_fast_aldc_w    : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
-    default                         : ShouldNotReachHere();                                 break;
+    default:
+      fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
+      break;
   }
   // first time invocation - must resolve first
   __ call_VM(noreg, entry, O1);
@@ -2139,48 +2144,54 @@
 }
 
 void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
-                                               Register Rmethod,
-                                               Register Ritable_index,
-                                               Register Rflags,
+                                               Register method,
+                                               Register itable_index,
+                                               Register flags,
                                                bool is_invokevirtual,
                                                bool is_invokevfinal,
                                                bool is_invokedynamic) {
   // Uses both G3_scratch and G4_scratch
-  Register Rcache = G3_scratch;
-  Register Rscratch = G4_scratch;
-  assert_different_registers(Rcache, Rmethod, Ritable_index);
-
-  ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset();
+  Register cache = G3_scratch;
+  Register index = G4_scratch;
+  assert_different_registers(cache, method, itable_index);
 
   // determine constant pool cache field offsets
+  assert(is_invokevirtual == (byte_no == f2_byte), "is_invokevirtual flag redundant");
   const int method_offset = in_bytes(
-    cp_base_offset +
-      (is_invokevirtual
+      constantPoolCacheOopDesc::base_offset() +
+      ((byte_no == f2_byte)
        ? ConstantPoolCacheEntry::f2_offset()
        : ConstantPoolCacheEntry::f1_offset()
       )
     );
-  const int flags_offset = in_bytes(cp_base_offset +
+  const int flags_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
                                     ConstantPoolCacheEntry::flags_offset());
   // access constant pool cache fields
-  const int index_offset = in_bytes(cp_base_offset +
+  const int index_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
                                     ConstantPoolCacheEntry::f2_offset());
 
   if (is_invokevfinal) {
-    __ get_cache_and_index_at_bcp(Rcache, Rscratch, 1);
-    __ ld_ptr(Rcache, method_offset, Rmethod);
-  } else if (byte_no == f1_oop) {
-    // Resolved f1_oop goes directly into 'method' register.
-    resolve_cache_and_index(byte_no, Rmethod, Rcache, Rscratch, sizeof(u4));
+    __ get_cache_and_index_at_bcp(cache, index, 1);
+    __ ld_ptr(Address(cache, method_offset), method);
+  } else if (byte_no == f12_oop) {
+    // Resolved f1_oop (CallSite, MethodType, etc.) goes into 'itable_index'.
+    // Resolved f2_oop (methodOop invoker) will go into 'method' (at index_offset).
+    // See ConstantPoolCacheEntry::set_dynamic_call and set_method_handle.
+    size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
+    resolve_cache_and_index(byte_no, itable_index, cache, index, index_size);
+    __ ld_ptr(Address(cache, index_offset), method);
+    itable_index = noreg;  // hack to disable load below
   } else {
-    resolve_cache_and_index(byte_no, noreg, Rcache, Rscratch, sizeof(u2));
-    __ ld_ptr(Rcache, method_offset, Rmethod);
+    resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
+    __ ld_ptr(Address(cache, method_offset), method);
   }
 
-  if (Ritable_index != noreg) {
-    __ ld_ptr(Rcache, index_offset, Ritable_index);
+  if (itable_index != noreg) {
+    // pick up itable index from f2 also:
+    assert(byte_no == f1_byte, "already picked up f1");
+    __ ld_ptr(Address(cache, index_offset), itable_index);
   }
-  __ ld_ptr(Rcache, flags_offset, Rflags);
+  __ ld_ptr(Address(cache, flags_offset), flags);
 }
 
 // The Rcache register must be set before call
@@ -2272,7 +2283,7 @@
 
   if (__ membar_has_effect(membar_bits)) {
     // Get volatile flag
-    __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch);
+    __ set((1 << ConstantPoolCacheEntry::is_volatile_shift), Lscratch);
     __ and3(Rflags, Lscratch, Lscratch);
   }
 
@@ -2280,9 +2291,9 @@
 
   // compute field type
   Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj;
-  __ srl(Rflags, ConstantPoolCacheEntry::tosBits, Rflags);
-  // Make sure we don't need to mask Rflags for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
+  __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
+  // Make sure we don't need to mask Rflags after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
 
   // Check atos before itos for getstatic, more likely (in Queens at least)
   __ cmp(Rflags, atos);
@@ -2445,7 +2456,7 @@
   if (__ membar_has_effect(membar_bits)) {
     // Get volatile flag
     __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::f2_offset(), Rflags);
-    __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch);
+    __ set((1 << ConstantPoolCacheEntry::is_volatile_shift), Lscratch);
   }
 
   switch (bytecode()) {
@@ -2569,9 +2580,9 @@
       Label two_word, valsizeknown;
       __ ld_ptr(G1_scratch, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), Rflags);
       __ mov(Lesp, G4_scratch);
-      __ srl(Rflags, ConstantPoolCacheEntry::tosBits, Rflags);
-      // Make sure we don't need to mask Rflags for tosBits after the above shift
-      ConstantPoolCacheEntry::verify_tosBits();
+      __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
+      // Make sure we don't need to mask Rflags after the above shift
+      ConstantPoolCacheEntry::verify_tos_state_shift();
       __ cmp(Rflags, ltos);
       __ br(Assembler::equal, false, Assembler::pt, two_word);
       __ delayed()->cmp(Rflags, dtos);
@@ -2625,7 +2636,7 @@
 
   Label notVolatile, checkVolatile, exit;
   if (__ membar_has_effect(read_bits) || __ membar_has_effect(write_bits)) {
-    __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch);
+    __ set((1 << ConstantPoolCacheEntry::is_volatile_shift), Lscratch);
     __ and3(Rflags, Lscratch, Lscratch);
 
     if (__ membar_has_effect(read_bits)) {
@@ -2635,9 +2646,9 @@
     }
   }
 
-  __ srl(Rflags, ConstantPoolCacheEntry::tosBits, Rflags);
-  // Make sure we don't need to mask Rflags for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
+  __ srl(Rflags, ConstantPoolCacheEntry::tos_state_shift, Rflags);
+  // Make sure we don't need to mask Rflags after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
 
   // compute field type
   Label notInt, notShort, notChar, notObj, notByte, notLong, notFloat;
@@ -2833,7 +2844,7 @@
   Label notVolatile, checkVolatile, exit;
   if (__ membar_has_effect(read_bits) || __ membar_has_effect(write_bits)) {
     __ ld_ptr(Rcache, cp_base_offset + ConstantPoolCacheEntry::flags_offset(), Rflags);
-    __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch);
+    __ set((1 << ConstantPoolCacheEntry::is_volatile_shift), Lscratch);
     __ and3(Rflags, Lscratch, Lscratch);
     if (__ membar_has_effect(read_bits)) {
       __ cmp_and_br_short(Lscratch, 0, Assembler::equal, Assembler::pt, notVolatile);
@@ -2916,7 +2927,7 @@
 
     // Test volatile
     Label notVolatile;
-    __ set((1 << ConstantPoolCacheEntry::volatileField), Lscratch);
+    __ set((1 << ConstantPoolCacheEntry::is_volatile_shift), Lscratch);
     __ btst(Rflags, Lscratch);
     __ br(Assembler::zero, false, Assembler::pt, notVolatile);
     __ delayed()->nop();
@@ -2936,27 +2947,82 @@
   ShouldNotReachHere();
 }
 
+
+void TemplateTable::prepare_invoke(int byte_no,
+                                   Register method,  // linked method (or i-klass)
+                                   Register ra,      // return address
+                                   Register index,   // itable index, MethodType, etc.
+                                   Register recv,    // if caller wants to see it
+                                   Register flags    // if caller wants to test it
+                                   ) {
+  // determine flags
+  const Bytecodes::Code code = bytecode();
+  const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
+  const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
+  const bool is_invokehandle     = code == Bytecodes::_invokehandle;
+  const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
+  const bool is_invokespecial    = code == Bytecodes::_invokespecial;
+  const bool load_receiver       = (recv != noreg);
+  assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), "");
+  assert(recv  == noreg || recv  == O0, "");
+  assert(flags == noreg || flags == O1, "");
+
+  // setup registers & access constant pool cache
+  if (recv  == noreg)  recv  = O0;
+  if (flags == noreg)  flags = O1;
+  const Register temp = O2;
+  assert_different_registers(method, ra, index, recv, flags, temp);
+
+  load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
+
+  __ mov(SP, O5_savedSP);  // record SP that we wanted the callee to restore
+
+  // maybe push appendix to arguments
+  if (is_invokedynamic || is_invokehandle) {
+    Label L_no_push;
+    __ verify_oop(index);
+    __ set((1 << ConstantPoolCacheEntry::has_appendix_shift), temp);
+    __ btst(flags, temp);
+    __ br(Assembler::zero, false, Assembler::pt, L_no_push);
+    __ delayed()->nop();
+    // Push the appendix as a trailing parameter.
+    // This must be done before we get the receiver,
+    // since the parameter_size includes it.
+    __ push_ptr(index);  // push appendix (MethodType, CallSite, etc.)
+    __ bind(L_no_push);
+  }
+
+  // load receiver if needed (after appendix is pushed so parameter size is correct)
+  if (load_receiver) {
+    __ and3(flags, ConstantPoolCacheEntry::parameter_size_mask, temp);  // get parameter size
+    __ load_receiver(temp, recv);  //  __ argument_address uses Gargs but we need Lesp
+    __ verify_oop(recv);
+  }
+
+  // compute return type
+  __ srl(flags, ConstantPoolCacheEntry::tos_state_shift, ra);
+  // Make sure we don't need to mask flags after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
+  // load return address
+  {
+    const address table_addr = (is_invokeinterface || is_invokedynamic) ?
+        (address)Interpreter::return_5_addrs_by_index_table() :
+        (address)Interpreter::return_3_addrs_by_index_table();
+    AddressLiteral table(table_addr);
+    __ set(table, temp);
+    __ sll(ra, LogBytesPerWord, ra);
+    __ ld_ptr(Address(temp, ra), ra);
+  }
+}
+
+
 void TemplateTable::generate_vtable_call(Register Rrecv, Register Rindex, Register Rret) {
   Register Rtemp = G4_scratch;
   Register Rcall = Rindex;
   assert_different_registers(Rcall, G5_method, Gargs, Rret);
 
   // get target methodOop & entry point
-  const int base = instanceKlass::vtable_start_offset() * wordSize;
-  if (vtableEntry::size() % 3 == 0) {
-    // scale the vtable index by 12:
-    int one_third = vtableEntry::size() / 3;
-    __ sll(Rindex, exact_log2(one_third * 1 * wordSize), Rtemp);
-    __ sll(Rindex, exact_log2(one_third * 2 * wordSize), Rindex);
-    __ add(Rindex, Rtemp, Rindex);
-  } else {
-    // scale the vtable index by 8:
-    __ sll(Rindex, exact_log2(vtableEntry::size() * wordSize), Rindex);
-  }
-
-  __ add(Rrecv, Rindex, Rrecv);
-  __ ld_ptr(Rrecv, base + vtableEntry::method_offset_in_bytes(), G5_method);
-
+  __ lookup_virtual_method(Rrecv, Rindex, G5_method);
   __ call_from_interpreter(Rcall, Gargs, Rret);
 }
 
@@ -2965,16 +3031,16 @@
   assert(byte_no == f2_byte, "use this argument");
 
   Register Rscratch = G3_scratch;
-  Register Rtemp = G4_scratch;
-  Register Rret = Lscratch;
-  Register Rrecv = G5_method;
+  Register Rtemp    = G4_scratch;
+  Register Rret     = Lscratch;
+  Register O0_recv  = O0;
   Label notFinal;
 
   load_invoke_cp_cache_entry(byte_no, G5_method, noreg, Rret, true, false, false);
   __ mov(SP, O5_savedSP); // record SP that we wanted the callee to restore
 
   // Check for vfinal
-  __ set((1 << ConstantPoolCacheEntry::vfinalMethod), G4_scratch);
+  __ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), G4_scratch);
   __ btst(Rret, G4_scratch);
   __ br(Assembler::zero, false, Assembler::pt, notFinal);
   __ delayed()->and3(Rret, 0xFF, G4_scratch);      // gets number of parameters
@@ -2986,27 +3052,27 @@
   __ bind(notFinal);
 
   __ mov(G5_method, Rscratch);  // better scratch register
-  __ load_receiver(G4_scratch, O0);  // gets receiverOop
-  // receiver is in O0
-  __ verify_oop(O0);
+  __ load_receiver(G4_scratch, O0_recv);  // gets receiverOop
+  // receiver is in O0_recv
+  __ verify_oop(O0_recv);
 
   // get return address
   AddressLiteral table(Interpreter::return_3_addrs_by_index_table());
   __ set(table, Rtemp);
-  __ srl(Rret, ConstantPoolCacheEntry::tosBits, Rret);          // get return type
-  // Make sure we don't need to mask Rret for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
+  __ srl(Rret, ConstantPoolCacheEntry::tos_state_shift, Rret);          // get return type
+  // Make sure we don't need to mask Rret after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
   __ sll(Rret,  LogBytesPerWord, Rret);
   __ ld_ptr(Rtemp, Rret, Rret);         // get return address
 
   // get receiver klass
-  __ null_check(O0, oopDesc::klass_offset_in_bytes());
-  __ load_klass(O0, Rrecv);
-  __ verify_oop(Rrecv);
+  __ null_check(O0_recv, oopDesc::klass_offset_in_bytes());
+  __ load_klass(O0_recv, O0_recv);
+  __ verify_oop(O0_recv);
 
-  __ profile_virtual_call(Rrecv, O4);
+  __ profile_virtual_call(O0_recv, O4);
 
-  generate_vtable_call(Rrecv, Rscratch, Rret);
+  generate_vtable_call(O0_recv, Rscratch, Rret);
 }
 
 void TemplateTable::fast_invokevfinal(int byte_no) {
@@ -3036,9 +3102,9 @@
   // get return address
   AddressLiteral table(Interpreter::return_3_addrs_by_index_table());
   __ set(table, Rtemp);
-  __ srl(Rret, ConstantPoolCacheEntry::tosBits, Rret);          // get return type
-  // Make sure we don't need to mask Rret for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
+  __ srl(Rret, ConstantPoolCacheEntry::tos_state_shift, Rret);          // get return type
+  // Make sure we don't need to mask Rret after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
   __ sll(Rret,  LogBytesPerWord, Rret);
   __ ld_ptr(Rtemp, Rret, Rret);         // get return address
 
@@ -3047,65 +3113,37 @@
   __ call_from_interpreter(Rscratch, Gargs, Rret);
 }
 
+
 void TemplateTable::invokespecial(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
 
-  Register Rscratch = G3_scratch;
-  Register Rtemp = G4_scratch;
-  Register Rret = Lscratch;
+  const Register Rret     = Lscratch;
+  const Register O0_recv  = O0;
+  const Register Rscratch = G3_scratch;
 
-  load_invoke_cp_cache_entry(byte_no, G5_method, noreg, Rret, /*virtual*/ false, false, false);
-  __ mov(SP, O5_savedSP); // record SP that we wanted the callee to restore
-
-  __ verify_oop(G5_method);
-
-  __ lduh(G5_method, in_bytes(methodOopDesc::size_of_parameters_offset()), G4_scratch);
-  __ load_receiver(G4_scratch, O0);
-
-  // receiver NULL check
-  __ null_check(O0);
-
-  __ profile_call(O4);
-
-  // get return address
-  AddressLiteral table(Interpreter::return_3_addrs_by_index_table());
-  __ set(table, Rtemp);
-  __ srl(Rret, ConstantPoolCacheEntry::tosBits, Rret);          // get return type
-  // Make sure we don't need to mask Rret for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
-  __ sll(Rret,  LogBytesPerWord, Rret);
-  __ ld_ptr(Rtemp, Rret, Rret);         // get return address
+  prepare_invoke(byte_no, G5_method, Rret, noreg, O0_recv);  // get receiver also for null check
+  __ null_check(O0_recv);
 
   // do the call
+  __ verify_oop(G5_method);
+  __ profile_call(O4);
   __ call_from_interpreter(Rscratch, Gargs, Rret);
 }
 
+
 void TemplateTable::invokestatic(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
 
-  Register Rscratch = G3_scratch;
-  Register Rtemp = G4_scratch;
-  Register Rret = Lscratch;
+  const Register Rret     = Lscratch;
+  const Register Rscratch = G3_scratch;
 
-  load_invoke_cp_cache_entry(byte_no, G5_method, noreg, Rret, /*virtual*/ false, false, false);
-  __ mov(SP, O5_savedSP); // record SP that we wanted the callee to restore
-
-  __ verify_oop(G5_method);
-
-  __ profile_call(O4);
-
-  // get return address
-  AddressLiteral table(Interpreter::return_3_addrs_by_index_table());
-  __ set(table, Rtemp);
-  __ srl(Rret, ConstantPoolCacheEntry::tosBits, Rret);          // get return type
-  // Make sure we don't need to mask Rret for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
-  __ sll(Rret,  LogBytesPerWord, Rret);
-  __ ld_ptr(Rtemp, Rret, Rret);         // get return address
+  prepare_invoke(byte_no, G5_method, Rret);  // get f1 methodOop
 
   // do the call
+  __ verify_oop(G5_method);
+  __ profile_call(O4);
   __ call_from_interpreter(Rscratch, Gargs, Rret);
 }
 
@@ -3122,7 +3160,7 @@
   Label notFinal;
 
   // Check for vfinal
-  __ set((1 << ConstantPoolCacheEntry::vfinalMethod), Rscratch);
+  __ set((1 << ConstantPoolCacheEntry::is_vfinal_shift), Rscratch);
   __ btst(Rflags, Rscratch);
   __ br(Assembler::zero, false, Assembler::pt, notFinal);
   __ delayed()->nop();
@@ -3144,53 +3182,37 @@
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
 
-  Register Rscratch = G4_scratch;
-  Register Rret = G3_scratch;
-  Register Rindex = Lscratch;
-  Register Rinterface = G1_scratch;
-  Register RklassOop = G5_method;
-  Register Rflags = O1;
+  const Register Rinterface  = G1_scratch;
+  const Register Rret        = G3_scratch;
+  const Register Rindex      = Lscratch;
+  const Register O0_recv     = O0;
+  const Register O1_flags    = O1;
+  const Register O2_klassOop = O2;
+  const Register Rscratch    = G4_scratch;
   assert_different_registers(Rscratch, G5_method);
 
-  load_invoke_cp_cache_entry(byte_no, Rinterface, Rindex, Rflags, /*virtual*/ false, false, false);
-  __ mov(SP, O5_savedSP); // record SP that we wanted the callee to restore
-
-  // get receiver
-  __ and3(Rflags, 0xFF, Rscratch);       // gets number of parameters
-  __ load_receiver(Rscratch, O0);
-  __ verify_oop(O0);
-
-  __ mov(Rflags, Rret);
-
-  // get return address
-  AddressLiteral table(Interpreter::return_5_addrs_by_index_table());
-  __ set(table, Rscratch);
-  __ srl(Rret, ConstantPoolCacheEntry::tosBits, Rret);          // get return type
-  // Make sure we don't need to mask Rret for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
-  __ sll(Rret,  LogBytesPerWord, Rret);
-  __ ld_ptr(Rscratch, Rret, Rret);      // get return address
+  prepare_invoke(byte_no, Rinterface, Rret, Rindex, O0_recv, O1_flags);
 
   // get receiver klass
-  __ null_check(O0, oopDesc::klass_offset_in_bytes());
-  __ load_klass(O0, RklassOop);
-  __ verify_oop(RklassOop);
+  __ null_check(O0_recv, oopDesc::klass_offset_in_bytes());
+  __ load_klass(O0_recv, O2_klassOop);
+  __ verify_oop(O2_klassOop);
 
   // Special case of invokeinterface called for virtual method of
   // java.lang.Object.  See cpCacheOop.cpp for details.
   // This code isn't produced by javac, but could be produced by
   // another compliant java compiler.
   Label notMethod;
-  __ set((1 << ConstantPoolCacheEntry::methodInterface), Rscratch);
-  __ btst(Rflags, Rscratch);
+  __ set((1 << ConstantPoolCacheEntry::is_forced_virtual_shift), Rscratch);
+  __ btst(O1_flags, Rscratch);
   __ br(Assembler::zero, false, Assembler::pt, notMethod);
   __ delayed()->nop();
 
-  invokeinterface_object_method(RklassOop, Rinterface, Rret, Rflags);
+  invokeinterface_object_method(O2_klassOop, Rinterface, Rret, O1_flags);
 
   __ bind(notMethod);
 
-  __ profile_virtual_call(RklassOop, O4);
+  __ profile_virtual_call(O2_klassOop, O4);
 
   //
   // find entry point to call
@@ -3199,9 +3221,9 @@
   // compute start of first itableOffsetEntry (which is at end of vtable)
   const int base = instanceKlass::vtable_start_offset() * wordSize;
   Label search;
-  Register Rtemp = Rflags;
+  Register Rtemp = O1_flags;
 
-  __ ld(RklassOop, instanceKlass::vtable_length_offset() * wordSize, Rtemp);
+  __ ld(O2_klassOop, instanceKlass::vtable_length_offset() * wordSize, Rtemp);
   if (align_object_offset(1) > 1) {
     __ round_to(Rtemp, align_object_offset(1));
   }
@@ -3212,7 +3234,7 @@
     __ set(base, Rscratch);
     __ add(Rscratch, Rtemp, Rtemp);
   }
-  __ add(RklassOop, Rtemp, Rscratch);
+  __ add(O2_klassOop, Rtemp, Rscratch);
 
   __ bind(search);
 
@@ -3244,7 +3266,7 @@
   assert(itableMethodEntry::method_offset_in_bytes() == 0, "adjust instruction below");
   __ sll(Rindex, exact_log2(itableMethodEntry::size() * wordSize), Rindex);       // Rindex *= 8;
   __ add(Rscratch, Rindex, Rscratch);
-  __ ld_ptr(RklassOop, Rscratch, G5_method);
+  __ ld_ptr(O2_klassOop, Rscratch, G5_method);
 
   // Check for abstract method error.
   {
@@ -3260,13 +3282,42 @@
 
   __ verify_oop(G5_method);
   __ call_from_interpreter(Rcall, Gargs, Rret);
+}
 
+
+void TemplateTable::invokehandle(int byte_no) {
+  transition(vtos, vtos);
+  assert(byte_no == f12_oop, "use this argument");
+
+  if (!EnableInvokeDynamic) {
+    // rewriter does not generate this bytecode
+    __ should_not_reach_here();
+    return;
+  }
+
+  const Register Rret       = Lscratch;
+  const Register G4_mtype   = G4_scratch;  // f1
+  const Register O0_recv    = O0;
+  const Register Rscratch   = G3_scratch;
+
+  prepare_invoke(byte_no, G5_method, Rret, G4_mtype, O0_recv);
+  __ null_check(O0_recv);
+
+  // G4: MethodType object (from f1)
+  // G5: MH.linkToCallSite method (from f2)
+
+  // Note:  G4_mtype is already pushed (if necessary) by prepare_invoke
+
+  // do the call
+  __ verify_oop(G5_method);
+  __ profile_final_call(O4);  // FIXME: profile the LambdaForm also
+  __ call_from_interpreter(Rscratch, Gargs, Rret);
 }
 
 
 void TemplateTable::invokedynamic(int byte_no) {
   transition(vtos, vtos);
-  assert(byte_no == f1_oop, "use this argument");
+  assert(byte_no == f12_oop, "use this argument");
 
   if (!EnableInvokeDynamic) {
     // We should not encounter this bytecode if !EnableInvokeDynamic.
@@ -3279,42 +3330,24 @@
     return;
   }
 
-  // G5: CallSite object (f1)
-  // XX: unused (f2)
-  // XX: flags (unused)
+  const Register Rret        = Lscratch;
+  const Register G4_callsite = G4_scratch;
+  const Register Rscratch    = G3_scratch;
 
-  Register G5_callsite = G5_method;
-  Register Rscratch    = G3_scratch;
-  Register Rtemp       = G1_scratch;
-  Register Rret        = Lscratch;
+  prepare_invoke(byte_no, G5_method, Rret, G4_callsite);
 
-  load_invoke_cp_cache_entry(byte_no, G5_callsite, noreg, Rret,
-                             /*virtual*/ false, /*vfinal*/ false, /*indy*/ true);
-  __ mov(SP, O5_savedSP);  // record SP that we wanted the callee to restore
+  // G4: CallSite object (from f1)
+  // G5: MH.linkToCallSite method (from f2)
 
+  // Note:  G4_callsite is already pushed by prepare_invoke
+
+  // %%% should make a type profile for any invokedynamic that takes a ref argument
   // profile this call
   __ profile_call(O4);
 
-  // get return address
-  AddressLiteral table(Interpreter::return_5_addrs_by_index_table());
-  __ set(table, Rtemp);
-  __ srl(Rret, ConstantPoolCacheEntry::tosBits, Rret);  // get return type
-  // Make sure we don't need to mask Rret for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
-  __ sll(Rret, LogBytesPerWord, Rret);
-  __ ld_ptr(Rtemp, Rret, Rret);  // get return address
-
-  __ verify_oop(G5_callsite);
-  __ load_heap_oop(G5_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, Rscratch), G3_method_handle);
-  __ null_check(G3_method_handle);
-  __ verify_oop(G3_method_handle);
-
-  // Adjust Rret first so Llast_SP can be same as Rret
-  __ add(Rret, -frame::pc_return_offset, O7);
-  __ add(Lesp, BytesPerWord, Gargs);  // setup parameter pointer
-  __ jump_to_method_handle_entry(G3_method_handle, Rtemp, /* emit_delayed_nop */ false);
-  // Record SP so we can remove any stack space allocated by adapter transition
-  __ delayed()->mov(SP, Llast_SP);
+  // do the call
+  __ verify_oop(G5_method);
+  __ call_from_interpreter(Rscratch, Gargs, Rret);
 }
 
 
diff --git a/hotspot/src/cpu/sparc/vm/templateTable_sparc.hpp b/hotspot/src/cpu/sparc/vm/templateTable_sparc.hpp
index 35c8ca1..b202a80 100644
--- a/hotspot/src/cpu/sparc/vm/templateTable_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/templateTable_sparc.hpp
@@ -25,6 +25,13 @@
 #ifndef CPU_SPARC_VM_TEMPLATETABLE_SPARC_HPP
 #define CPU_SPARC_VM_TEMPLATETABLE_SPARC_HPP
 
+  static void prepare_invoke(int byte_no,
+                             Register method,         // linked method (or i-klass)
+                             Register ra,             // return address
+                             Register index = noreg,  // itable index, MethodType, etc.
+                             Register recv  = noreg,  // if caller wants to see it
+                             Register flags = noreg   // if caller wants to test it
+                             );
   // helper function
   static void invokevfinal_helper(Register Rcache, Register Rret);
   static void invokeinterface_object_method(Register RklassOop, Register Rcall,
diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
index 1d49662..07eadd5 100644
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -96,6 +96,7 @@
   UseSSE = 0; // Only on x86 and x64
 
   _supports_cx8 = has_v9();
+  _supports_atomic_getset4 = true; // swap instruction
 
   if (is_niagara()) {
     // Indirect branch is the same cost as direct
@@ -106,10 +107,10 @@
     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) {
+    // When using CMS or G1, 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 || UseG1GC)) {
       FLAG_SET_DEFAULT(UseMemSetInBOT, false);
     }
 #ifdef _LP64
@@ -217,6 +218,8 @@
   // Currently not supported anywhere.
   FLAG_SET_DEFAULT(UseFPUForSpilling, false);
 
+  MaxVectorSize = 8;
+
   assert((InteriorEntryAlignment % relocInfo::addr_unit()) == 0, "alignment is not a multiple of NOP size");
 #endif
 
@@ -336,7 +339,11 @@
 
 unsigned int VM_Version::calc_parallel_worker_threads() {
   unsigned int result;
-  if (is_niagara_plus()) {
+  if (is_M_series()) {
+    // for now, use same gc thread calculation for M-series as for niagara-plus
+    // in future, we may want to tweak parameters for nof_parallel_worker_thread
+    result = nof_parallel_worker_threads(5, 16, 8);
+  } else if (is_niagara_plus()) {
     result = nof_parallel_worker_threads(5, 16, 8);
   } else {
     result = nof_parallel_worker_threads(5, 8, 8);
diff --git a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp
index db3343b..d602fd0 100644
--- a/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp
+++ b/hotspot/src/cpu/sparc/vm/vm_version_sparc.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,10 +44,11 @@
     fmaf_instructions    = 10,
     fmau_instructions    = 11,
     vis3_instructions    = 12,
-    sparc64_family       = 13,
-    T_family             = 14,
-    T1_model             = 15,
-    cbcond_instructions  = 16
+    cbcond_instructions  = 13,
+    sparc64_family       = 14,
+    M_family             = 15,
+    T_family             = 16,
+    T1_model             = 17
   };
 
   enum Feature_Flag_Set {
@@ -67,10 +68,11 @@
     fmaf_instructions_m     = 1 << fmaf_instructions,
     fmau_instructions_m     = 1 << fmau_instructions,
     vis3_instructions_m     = 1 << vis3_instructions,
+    cbcond_instructions_m   = 1 << cbcond_instructions,
     sparc64_family_m        = 1 << sparc64_family,
+    M_family_m              = 1 << M_family,
     T_family_m              = 1 << T_family,
     T1_model_m              = 1 << T1_model,
-    cbcond_instructions_m   = 1 << cbcond_instructions,
 
     generic_v8_m        = v8_instructions_m | hardware_mul32_m | hardware_div32_m | hardware_fsmuld_m,
     generic_v9_m        = generic_v8_m | v9_instructions_m,
@@ -89,6 +91,7 @@
   static int  platform_features(int features);
 
   // Returns true if the platform is in the niagara line (T series)
+  static bool is_M_family(int features) { return (features & M_family_m) != 0; }
   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; } )
@@ -121,6 +124,8 @@
   // 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); }
+
+  static bool is_M_series()             { return is_M_family(_features); }
   static bool is_T4()                   { return is_T_family(_features) && has_cbcond(); }
 
   // Fujitsu SPARC64
diff --git a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
index 17ef156..039988a 100644
--- a/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
+++ b/hotspot/src/cpu/sparc/vm/vtableStubs_sparc.cpp
@@ -70,7 +70,6 @@
   __ load_klass(O0, G3_scratch);
 
   // set methodOop (in case of interpreted method), and destination address
-  int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
 #ifndef PRODUCT
   if (DebugVtables) {
     Label L;
@@ -82,13 +81,8 @@
     __ bind(L);
   }
 #endif
-  int v_off = entry_offset*wordSize + vtableEntry::method_offset_in_bytes();
-  if (Assembler::is_simm13(v_off)) {
-    __ ld_ptr(G3, v_off, G5_method);
-  } else {
-    __ set(v_off,G5);
-    __ ld_ptr(G3, G5, G5_method);
-  }
+
+  __ lookup_virtual_method(G3_scratch, vtable_index, G5_method);
 
 #ifndef PRODUCT
   if (DebugVtables) {
diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.cpp b/hotspot/src/cpu/x86/vm/assembler_x86.cpp
index 7c7cb3d..5a36aa8 100644
--- a/hotspot/src/cpu/x86/vm/assembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.cpp
@@ -41,6 +41,15 @@
 #include "gc_implementation/g1/heapRegion.hpp"
 #endif
 
+#ifdef PRODUCT
+#define BLOCK_COMMENT(str) /* nothing */
+#define STOP(error) stop(error)
+#else
+#define BLOCK_COMMENT(str) block_comment(str)
+#define STOP(error) block_comment(error); stop(error)
+#endif
+
+#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
 // Implementation of AddressLiteral
 
 AddressLiteral::AddressLiteral(address target, relocInfo::relocType rtype) {
@@ -990,34 +999,85 @@
 
 void Assembler::addsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x58);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x58, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::addsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x58);
-  emit_operand(dst, src);
+  emit_simd_arith(0x58, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::addss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x58);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x58, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::addss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
+  emit_simd_arith(0x58, dst, src, VEX_SIMD_F3);
+}
+
+void Assembler::aesdec(XMMRegister dst, Address src) {
+  assert(VM_Version::supports_aes(), "");
   InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x58);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0xde);
   emit_operand(dst, src);
 }
 
+void Assembler::aesdec(XMMRegister dst, XMMRegister src) {
+  assert(VM_Version::supports_aes(), "");
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0xde);
+  emit_byte(0xC0 | encode);
+}
+
+void Assembler::aesdeclast(XMMRegister dst, Address src) {
+  assert(VM_Version::supports_aes(), "");
+  InstructionMark im(this);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0xdf);
+  emit_operand(dst, src);
+}
+
+void Assembler::aesdeclast(XMMRegister dst, XMMRegister src) {
+  assert(VM_Version::supports_aes(), "");
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0xdf);
+  emit_byte(0xC0 | encode);
+}
+
+void Assembler::aesenc(XMMRegister dst, Address src) {
+  assert(VM_Version::supports_aes(), "");
+  InstructionMark im(this);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0xdc);
+  emit_operand(dst, src);
+}
+
+void Assembler::aesenc(XMMRegister dst, XMMRegister src) {
+  assert(VM_Version::supports_aes(), "");
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0xdc);
+  emit_byte(0xC0 | encode);
+}
+
+void Assembler::aesenclast(XMMRegister dst, Address src) {
+  assert(VM_Version::supports_aes(), "");
+  InstructionMark im(this);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0xdd);
+  emit_operand(dst, src);
+}
+
+void Assembler::aesenclast(XMMRegister dst, XMMRegister src) {
+  assert(VM_Version::supports_aes(), "");
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0xdd);
+  emit_byte(0xC0 | encode);
+}
+
+
 void Assembler::andl(Address dst, int32_t imm32) {
   InstructionMark im(this);
   prefix(dst);
@@ -1043,36 +1103,6 @@
   emit_arith(0x23, 0xC0, dst, src);
 }
 
-void Assembler::andpd(XMMRegister dst, Address src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x54);
-  emit_operand(dst, src);
-}
-
-void Assembler::andpd(XMMRegister dst, XMMRegister src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x54);
-  emit_byte(0xC0 | encode);
-}
-
-void Assembler::andps(XMMRegister dst, Address src) {
-  NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_NONE);
-  emit_byte(0x54);
-  emit_operand(dst, src);
-}
-
-void Assembler::andps(XMMRegister dst, XMMRegister src) {
-  NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE);
-  emit_byte(0x54);
-  emit_byte(0xC0 | encode);
-}
-
 void Assembler::bsfl(Register dst, Register src) {
   int encode = prefix_and_encode(dst->encoding(), src->encoding());
   emit_byte(0x0F);
@@ -1237,61 +1267,42 @@
   // NOTE: dbx seems to decode this as comiss even though the
   // 0x66 is there. Strangly ucomisd comes out correct
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_66);
-  emit_byte(0x2F);
-  emit_operand(dst, src);
+  emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::comisd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66);
-  emit_byte(0x2F);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::comiss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_NONE);
-  emit_byte(0x2F);
-  emit_operand(dst, src);
+  emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_NONE);
 }
 
 void Assembler::comiss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_NONE);
-  emit_byte(0x2F);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x2F, dst, src, VEX_SIMD_NONE);
 }
 
 void Assembler::cvtdq2pd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F3);
-  emit_byte(0xE6);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0xE6, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::cvtdq2ps(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_NONE);
-  emit_byte(0x5B);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x5B, dst, src, VEX_SIMD_NONE);
 }
 
 void Assembler::cvtsd2ss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x5A);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x5A, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::cvtsd2ss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x5A);
-  emit_operand(dst, src);
+  emit_simd_arith(0x5A, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::cvtsi2sdl(XMMRegister dst, Register src) {
@@ -1303,10 +1314,7 @@
 
 void Assembler::cvtsi2sdl(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x2A);
-  emit_operand(dst, src);
+  emit_simd_arith(0x2A, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::cvtsi2ssl(XMMRegister dst, Register src) {
@@ -1318,25 +1326,17 @@
 
 void Assembler::cvtsi2ssl(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x2A);
-  emit_operand(dst, src);
+  emit_simd_arith(0x2A, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::cvtss2sd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x5A);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x5A, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::cvtss2sd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x5A);
-  emit_operand(dst, src);
+  emit_simd_arith(0x5A, dst, src, VEX_SIMD_F3);
 }
 
 
@@ -1364,32 +1364,22 @@
 
 void Assembler::divsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x5E);
-  emit_operand(dst, src);
+  emit_simd_arith(0x5E, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::divsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x5E);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x5E, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::divss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x5E);
-  emit_operand(dst, src);
+  emit_simd_arith(0x5E, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::divss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x5E);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x5E, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::emms() {
@@ -1625,15 +1615,18 @@
 
 void Assembler::movapd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66);
-  emit_byte(0x28);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x28, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::movaps(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_NONE);
-  emit_byte(0x28);
+  emit_simd_arith_nonds(0x28, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::movlhps(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse(), ""));
+  int encode = simd_prefix_and_encode(dst, src, src, VEX_SIMD_NONE);
+  emit_byte(0x16);
   emit_byte(0xC0 | encode);
 }
 
@@ -1686,26 +1679,27 @@
   emit_operand(dst, src);
 }
 
+void Assembler::movdl(Address dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  InstructionMark im(this);
+  simd_prefix(dst, src, VEX_SIMD_66);
+  emit_byte(0x7E);
+  emit_operand(src, dst);
+}
+
 void Assembler::movdqa(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66);
-  emit_byte(0x6F);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::movdqu(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_F3);
-  emit_byte(0x6F);
-  emit_operand(dst, src);
+  emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::movdqu(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F3);
-  emit_byte(0x6F);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x6F, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::movdqu(Address dst, XMMRegister src) {
@@ -1716,6 +1710,35 @@
   emit_operand(src, dst);
 }
 
+// Move Unaligned 256bit Vector
+void Assembler::vmovdqu(XMMRegister dst, XMMRegister src) {
+  assert(UseAVX, "");
+  bool vector256 = true;
+  int encode = vex_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_F3, vector256);
+  emit_byte(0x6F);
+  emit_byte(0xC0 | encode);
+}
+
+void Assembler::vmovdqu(XMMRegister dst, Address src) {
+  assert(UseAVX, "");
+  InstructionMark im(this);
+  bool vector256 = true;
+  vex_prefix(dst, xnoreg, src, VEX_SIMD_F3, vector256);
+  emit_byte(0x6F);
+  emit_operand(dst, src);
+}
+
+void Assembler::vmovdqu(Address dst, XMMRegister src) {
+  assert(UseAVX, "");
+  InstructionMark im(this);
+  bool vector256 = true;
+  // swap src<->dst for encoding
+  assert(src != xnoreg, "sanity");
+  vex_prefix(src, xnoreg, dst, VEX_SIMD_F3, vector256);
+  emit_byte(0x7F);
+  emit_operand(src, dst);
+}
+
 // Uses zero extension on 64bit
 
 void Assembler::movl(Register dst, int32_t imm32) {
@@ -1757,10 +1780,7 @@
 // The selection is done in MacroAssembler::movdbl() and movflt().
 void Assembler::movlpd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x12);
-  emit_operand(dst, src);
+  emit_simd_arith(0x12, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::movq( MMXRegister dst, Address src ) {
@@ -1817,17 +1837,12 @@
 
 void Assembler::movsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x10);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x10, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::movsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_F2);
-  emit_byte(0x10);
-  emit_operand(dst, src);
+  emit_simd_arith_nonds(0x10, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::movsd(Address dst, XMMRegister src) {
@@ -1840,17 +1855,12 @@
 
 void Assembler::movss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x10);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x10, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::movss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_F3);
-  emit_byte(0x10);
-  emit_operand(dst, src);
+  emit_simd_arith_nonds(0x10, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::movss(Address dst, XMMRegister src) {
@@ -1948,32 +1958,22 @@
 
 void Assembler::mulsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x59);
-  emit_operand(dst, src);
+  emit_simd_arith(0x59, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::mulsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x59);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x59, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::mulss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x59);
-  emit_operand(dst, src);
+  emit_simd_arith(0x59, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::mulss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x59);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x59, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::negl(Register dst) {
@@ -2262,17 +2262,12 @@
 void Assembler::packuswb(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x67);
-  emit_operand(dst, src);
+  emit_simd_arith(0x67, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::packuswb(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x67);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x67, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::pcmpestri(XMMRegister dst, Address src, int imm8) {
@@ -2286,7 +2281,7 @@
 
 void Assembler::pcmpestri(XMMRegister dst, XMMRegister src, int imm8) {
   assert(VM_Version::supports_sse4_2(), "");
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_3A);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_3A);
   emit_byte(0x61);
   emit_byte(0xC0 | encode);
   emit_byte(imm8);
@@ -2302,7 +2297,7 @@
 
 void Assembler::pmovzxbw(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_sse4_1(), "");
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
   emit_byte(0x30);
   emit_byte(0xC0 | encode);
 }
@@ -2403,28 +2398,26 @@
   a_byte(p);
 }
 
-void Assembler::por(XMMRegister dst, XMMRegister src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0xEB);
+void Assembler::pshufb(XMMRegister dst, XMMRegister src) {
+  assert(VM_Version::supports_ssse3(), "");
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0x00);
   emit_byte(0xC0 | encode);
 }
 
-void Assembler::por(XMMRegister dst, Address src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+void Assembler::pshufb(XMMRegister dst, Address src) {
+  assert(VM_Version::supports_ssse3(), "");
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
   InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0xEB);
+  simd_prefix(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0x00);
   emit_operand(dst, src);
 }
 
 void Assembler::pshufd(XMMRegister dst, XMMRegister src, int mode) {
   assert(isByte(mode), "invalid value");
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66);
-  emit_byte(0x70);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_66);
   emit_byte(mode & 0xFF);
 
 }
@@ -2443,9 +2436,7 @@
 void Assembler::pshuflw(XMMRegister dst, XMMRegister src, int mode) {
   assert(isByte(mode), "invalid value");
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_F2);
-  emit_byte(0x70);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x70, dst, src, VEX_SIMD_F2);
   emit_byte(mode & 0xFF);
 }
 
@@ -2460,18 +2451,6 @@
   emit_byte(mode & 0xFF);
 }
 
-void Assembler::psrlq(XMMRegister dst, int shift) {
-  // Shift 64 bit value logically right by specified number of bits.
-  // HMM Table D-1 says sse2 or mmx.
-  // Do not confuse it with psrldq SSE2 instruction which
-  // shifts 128 bit value in xmm register by number of bytes.
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
-  emit_byte(0x73);
-  emit_byte(0xC0 | encode);
-  emit_byte(shift);
-}
-
 void Assembler::psrldq(XMMRegister dst, int shift) {
   // Shift 128 bit value in xmm register by number of bytes.
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
@@ -2492,7 +2471,7 @@
 
 void Assembler::ptest(XMMRegister dst, XMMRegister src) {
   assert(VM_Version::supports_sse4_1(), "");
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
   emit_byte(0x17);
   emit_byte(0xC0 | encode);
 }
@@ -2500,33 +2479,28 @@
 void Assembler::punpcklbw(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x60);
-  emit_operand(dst, src);
+  emit_simd_arith(0x60, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::punpcklbw(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x60);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x60, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::punpckldq(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
   assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x62);
-  emit_operand(dst, src);
+  emit_simd_arith(0x62, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::punpckldq(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x62);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x62, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::punpcklqdq(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x6C, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::push(int32_t imm32) {
@@ -2556,22 +2530,6 @@
 }
 #endif
 
-void Assembler::pxor(XMMRegister dst, Address src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  assert((UseAVX > 0), "SSE mode requires address alignment 16 bytes");
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0xEF);
-  emit_operand(dst, src);
-}
-
-void Assembler::pxor(XMMRegister dst, XMMRegister src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0xEF);
-  emit_byte(0xC0 | encode);
-}
-
 void Assembler::rcll(Register dst, int imm8) {
   assert(isShiftCount(imm8), "illegal shift count");
   int encode = prefix_and_encode(dst->encoding());
@@ -2730,32 +2688,22 @@
 
 void Assembler::sqrtsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x51);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x51, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::sqrtsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x51);
-  emit_operand(dst, src);
+  emit_simd_arith(0x51, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::sqrtss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x51);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x51, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::sqrtss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x51);
-  emit_operand(dst, src);
+  emit_simd_arith(0x51, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::stmxcsr( Address dst) {
@@ -2805,32 +2753,22 @@
 
 void Assembler::subsd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x5C);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x5C, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::subsd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F2);
-  emit_byte(0x5C);
-  emit_operand(dst, src);
+  emit_simd_arith(0x5C, dst, src, VEX_SIMD_F2);
 }
 
 void Assembler::subss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x5C);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith(0x5C, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::subss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_F3);
-  emit_byte(0x5C);
-  emit_operand(dst, src);
+  emit_simd_arith(0x5C, dst, src, VEX_SIMD_F3);
 }
 
 void Assembler::testb(Register dst, int imm8) {
@@ -2868,32 +2806,22 @@
 
 void Assembler::ucomisd(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_66);
-  emit_byte(0x2E);
-  emit_operand(dst, src);
+  emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::ucomisd(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_66);
-  emit_byte(0x2E);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_66);
 }
 
 void Assembler::ucomiss(XMMRegister dst, Address src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, src, VEX_SIMD_NONE);
-  emit_byte(0x2E);
-  emit_operand(dst, src);
+  emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_NONE);
 }
 
 void Assembler::ucomiss(XMMRegister dst, XMMRegister src) {
   NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, src, VEX_SIMD_NONE);
-  emit_byte(0x2E);
-  emit_byte(0xC0 | encode);
+  emit_simd_arith_nonds(0x2E, dst, src, VEX_SIMD_NONE);
 }
 
 
@@ -2935,189 +2863,795 @@
   emit_arith(0x33, 0xC0, dst, src);
 }
 
-void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x57);
-  emit_byte(0xC0 | encode);
-}
 
-void Assembler::xorpd(XMMRegister dst, Address src) {
-  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_66);
-  emit_byte(0x57);
-  emit_operand(dst, src);
-}
-
-
-void Assembler::xorps(XMMRegister dst, XMMRegister src) {
-  NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_NONE);
-  emit_byte(0x57);
-  emit_byte(0xC0 | encode);
-}
-
-void Assembler::xorps(XMMRegister dst, Address src) {
-  NOT_LP64(assert(VM_Version::supports_sse(), ""));
-  InstructionMark im(this);
-  simd_prefix(dst, dst, src, VEX_SIMD_NONE);
-  emit_byte(0x57);
-  emit_operand(dst, src);
-}
-
-// AVX 3-operands non destructive source instructions (encoded with VEX prefix)
+// AVX 3-operands scalar float-point arithmetic instructions
 
 void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_F2);
-  emit_byte(0x58);
-  emit_operand(dst, src);
+  emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_F2, /* vector256 */ false);
 }
 
 void Assembler::vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F2);
-  emit_byte(0x58);
-  emit_byte(0xC0 | encode);
+  emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_F2, /* vector256 */ false);
 }
 
 void Assembler::vaddss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_F3);
-  emit_byte(0x58);
-  emit_operand(dst, src);
+  emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_F3, /* vector256 */ false);
 }
 
 void Assembler::vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F3);
-  emit_byte(0x58);
-  emit_byte(0xC0 | encode);
-}
-
-void Assembler::vandpd(XMMRegister dst, XMMRegister nds, Address src) {
-  assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_66); // 128-bit vector
-  emit_byte(0x54);
-  emit_operand(dst, src);
-}
-
-void Assembler::vandps(XMMRegister dst, XMMRegister nds, Address src) {
-  assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_NONE); // 128-bit vector
-  emit_byte(0x54);
-  emit_operand(dst, src);
+  emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_F3, /* vector256 */ false);
 }
 
 void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_F2);
-  emit_byte(0x5E);
-  emit_operand(dst, src);
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_F2, /* vector256 */ false);
 }
 
 void Assembler::vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F2);
-  emit_byte(0x5E);
-  emit_byte(0xC0 | encode);
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_F2, /* vector256 */ false);
 }
 
 void Assembler::vdivss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_F3);
-  emit_byte(0x5E);
-  emit_operand(dst, src);
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_F3, /* vector256 */ false);
 }
 
 void Assembler::vdivss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F3);
-  emit_byte(0x5E);
-  emit_byte(0xC0 | encode);
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_F3, /* vector256 */ false);
 }
 
 void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_F2);
-  emit_byte(0x59);
-  emit_operand(dst, src);
+  emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_F2, /* vector256 */ false);
 }
 
 void Assembler::vmulsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F2);
-  emit_byte(0x59);
-  emit_byte(0xC0 | encode);
+  emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_F2, /* vector256 */ false);
 }
 
 void Assembler::vmulss(XMMRegister dst, XMMRegister nds, Address src) {
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_F3);
-  emit_byte(0x59);
-  emit_operand(dst, src);
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_F3, /* vector256 */ false);
 }
 
 void Assembler::vmulss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F3);
-  emit_byte(0x59);
-  emit_byte(0xC0 | encode);
+  emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_F3, /* vector256 */ false);
 }
 
-
 void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_F2);
-  emit_byte(0x5C);
-  emit_operand(dst, src);
+  emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_F2, /* vector256 */ false);
 }
 
 void Assembler::vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F2);
-  emit_byte(0x5C);
-  emit_byte(0xC0 | encode);
+  emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_F2, /* vector256 */ false);
 }
 
 void Assembler::vsubss(XMMRegister dst, XMMRegister nds, Address src) {
   assert(VM_Version::supports_avx(), "");
-  InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_F3);
-  emit_byte(0x5C);
-  emit_operand(dst, src);
+  emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_F3, /* vector256 */ false);
 }
 
 void Assembler::vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src) {
   assert(VM_Version::supports_avx(), "");
-  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_F3);
-  emit_byte(0x5C);
+  emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_F3, /* vector256 */ false);
+}
+
+//====================VECTOR ARITHMETIC=====================================
+
+// Float-point vector arithmetic
+
+void Assembler::addpd(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x58, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::addps(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x58, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::vaddpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vaddps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::vaddpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vaddps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x58, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::subpd(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x5C, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::subps(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x5C, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::vsubpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vsubps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::vsubpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vsubps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x5C, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::mulpd(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x59, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::mulps(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x59, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::vmulpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vmulps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::vmulpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vmulps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x59, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::divpd(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x5E, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::divps(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x5E, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::vdivpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vdivps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::vdivpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vdivps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x5E, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::andpd(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x54, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::andps(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse(), ""));
+  emit_simd_arith(0x54, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::andps(XMMRegister dst, Address src) {
+  NOT_LP64(assert(VM_Version::supports_sse(), ""));
+  emit_simd_arith(0x54, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::andpd(XMMRegister dst, Address src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x54, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::vandpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vandps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x54, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x57, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::xorps(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse(), ""));
+  emit_simd_arith(0x57, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::xorpd(XMMRegister dst, Address src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0x57, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::xorps(XMMRegister dst, Address src) {
+  NOT_LP64(assert(VM_Version::supports_sse(), ""));
+  emit_simd_arith(0x57, dst, src, VEX_SIMD_NONE);
+}
+
+void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx(), "");
+  emit_vex_arith(0x57, dst, nds, src, VEX_SIMD_NONE, vector256);
+}
+
+
+// Integer vector arithmetic
+void Assembler::paddb(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xFC, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::paddw(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xFD, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::paddd(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xFE, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::paddq(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xD4, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::vpaddb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFC, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFD, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFE, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xD4, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpaddb(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFC, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpaddw(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFD, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpaddd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFE, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpaddq(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xD4, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::psubb(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xF8, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::psubw(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xF9, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::psubd(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xFA, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::psubq(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xFB, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xF8, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsubw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xF9, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFA, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsubq(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFB, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsubb(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xF8, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsubw(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xF9, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsubd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFA, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsubq(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xFB, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::pmullw(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xD5, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::pmulld(XMMRegister dst, XMMRegister src) {
+  assert(VM_Version::supports_sse4_1(), "");
+  int encode = simd_prefix_and_encode(dst, dst, src, VEX_SIMD_66, VEX_OPCODE_0F_38);
+  emit_byte(0x40);
   emit_byte(0xC0 | encode);
 }
 
-void Assembler::vxorpd(XMMRegister dst, XMMRegister nds, Address src) {
-  assert(VM_Version::supports_avx(), "");
+void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_38);
+  emit_byte(0x40);
+  emit_byte(0xC0 | encode);
+}
+
+void Assembler::vpmullw(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xD5, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpmulld(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
   InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_66); // 128-bit vector
-  emit_byte(0x57);
+  int dst_enc = dst->encoding();
+  int nds_enc = nds->is_valid() ? nds->encoding() : 0;
+  vex_prefix(src, nds_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_38, false, vector256);
+  emit_byte(0x40);
   emit_operand(dst, src);
 }
 
-void Assembler::vxorps(XMMRegister dst, XMMRegister nds, Address src) {
+// Shift packed integers left by specified number of bits.
+void Assembler::psllw(XMMRegister dst, int shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  // XMM6 is for /6 encoding: 66 0F 71 /6 ib
+  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
+  emit_byte(0x71);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::pslld(XMMRegister dst, int shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  // XMM6 is for /6 encoding: 66 0F 72 /6 ib
+  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
+  emit_byte(0x72);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::psllq(XMMRegister dst, int shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  // XMM6 is for /6 encoding: 66 0F 73 /6 ib
+  int encode = simd_prefix_and_encode(xmm6, dst, dst, VEX_SIMD_66);
+  emit_byte(0x73);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::psllw(XMMRegister dst, XMMRegister shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xF1, dst, shift, VEX_SIMD_66);
+}
+
+void Assembler::pslld(XMMRegister dst, XMMRegister shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xF2, dst, shift, VEX_SIMD_66);
+}
+
+void Assembler::psllq(XMMRegister dst, XMMRegister shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xF3, dst, shift, VEX_SIMD_66);
+}
+
+void Assembler::vpsllw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  // XMM6 is for /6 encoding: 66 0F 71 /6 ib
+  emit_vex_arith(0x71, xmm6, dst, src, VEX_SIMD_66, vector256);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::vpslld(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  // XMM6 is for /6 encoding: 66 0F 72 /6 ib
+  emit_vex_arith(0x72, xmm6, dst, src, VEX_SIMD_66, vector256);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::vpsllq(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  // XMM6 is for /6 encoding: 66 0F 73 /6 ib
+  emit_vex_arith(0x73, xmm6, dst, src, VEX_SIMD_66, vector256);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::vpsllw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xF1, dst, src, shift, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpslld(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xF2, dst, src, shift, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsllq(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xF3, dst, src, shift, VEX_SIMD_66, vector256);
+}
+
+// Shift packed integers logically right by specified number of bits.
+void Assembler::psrlw(XMMRegister dst, int shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  // XMM2 is for /2 encoding: 66 0F 71 /2 ib
+  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
+  emit_byte(0x71);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::psrld(XMMRegister dst, int shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  // XMM2 is for /2 encoding: 66 0F 72 /2 ib
+  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
+  emit_byte(0x72);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::psrlq(XMMRegister dst, int shift) {
+  // Do not confuse it with psrldq SSE2 instruction which
+  // shifts 128 bit value in xmm register by number of bytes.
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  // XMM2 is for /2 encoding: 66 0F 73 /2 ib
+  int encode = simd_prefix_and_encode(xmm2, dst, dst, VEX_SIMD_66);
+  emit_byte(0x73);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::psrlw(XMMRegister dst, XMMRegister shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xD1, dst, shift, VEX_SIMD_66);
+}
+
+void Assembler::psrld(XMMRegister dst, XMMRegister shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xD2, dst, shift, VEX_SIMD_66);
+}
+
+void Assembler::psrlq(XMMRegister dst, XMMRegister shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xD3, dst, shift, VEX_SIMD_66);
+}
+
+void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  // XMM2 is for /2 encoding: 66 0F 73 /2 ib
+  emit_vex_arith(0x71, xmm2, dst, src, VEX_SIMD_66, vector256);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::vpsrld(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  // XMM2 is for /2 encoding: 66 0F 73 /2 ib
+  emit_vex_arith(0x72, xmm2, dst, src, VEX_SIMD_66, vector256);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  // XMM2 is for /2 encoding: 66 0F 73 /2 ib
+  emit_vex_arith(0x73, xmm2, dst, src, VEX_SIMD_66, vector256);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::vpsrlw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xD1, dst, src, shift, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsrld(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xD2, dst, src, shift, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xD3, dst, src, shift, VEX_SIMD_66, vector256);
+}
+
+// Shift packed integers arithmetically right by specified number of bits.
+void Assembler::psraw(XMMRegister dst, int shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  // XMM4 is for /4 encoding: 66 0F 71 /4 ib
+  int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66);
+  emit_byte(0x71);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::psrad(XMMRegister dst, int shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  // XMM4 is for /4 encoding: 66 0F 72 /4 ib
+  int encode = simd_prefix_and_encode(xmm4, dst, dst, VEX_SIMD_66);
+  emit_byte(0x72);
+  emit_byte(0xC0 | encode);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::psraw(XMMRegister dst, XMMRegister shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xE1, dst, shift, VEX_SIMD_66);
+}
+
+void Assembler::psrad(XMMRegister dst, XMMRegister shift) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xE2, dst, shift, VEX_SIMD_66);
+}
+
+void Assembler::vpsraw(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  // XMM4 is for /4 encoding: 66 0F 71 /4 ib
+  emit_vex_arith(0x71, xmm4, dst, src, VEX_SIMD_66, vector256);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::vpsrad(XMMRegister dst, XMMRegister src, int shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  // XMM4 is for /4 encoding: 66 0F 71 /4 ib
+  emit_vex_arith(0x72, xmm4, dst, src, VEX_SIMD_66, vector256);
+  emit_byte(shift & 0xFF);
+}
+
+void Assembler::vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xE1, dst, src, shift, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpsrad(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xE2, dst, src, shift, VEX_SIMD_66, vector256);
+}
+
+
+// AND packed integers
+void Assembler::pand(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xDB, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xDB, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpand(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xDB, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::por(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xEB, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::vpor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xEB, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpor(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xEB, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::pxor(XMMRegister dst, XMMRegister src) {
+  NOT_LP64(assert(VM_Version::supports_sse2(), ""));
+  emit_simd_arith(0xEF, dst, src, VEX_SIMD_66);
+}
+
+void Assembler::vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xEF, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+void Assembler::vpxor(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+  assert(VM_Version::supports_avx() && !vector256 || VM_Version::supports_avx2(), "256 bit integer vectors requires AVX2");
+  emit_vex_arith(0xEF, dst, nds, src, VEX_SIMD_66, vector256);
+}
+
+
+void Assembler::vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
+  assert(VM_Version::supports_avx(), "");
+  bool vector256 = true;
+  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_3A);
+  emit_byte(0x18);
+  emit_byte(0xC0 | encode);
+  // 0x00 - insert into lower 128 bits
+  // 0x01 - insert into upper 128 bits
+  emit_byte(0x01);
+}
+
+void Assembler::vinsertf128h(XMMRegister dst, Address src) {
   assert(VM_Version::supports_avx(), "");
   InstructionMark im(this);
-  vex_prefix(dst, nds, src, VEX_SIMD_NONE); // 128-bit vector
-  emit_byte(0x57);
+  bool vector256 = true;
+  assert(dst != xnoreg, "sanity");
+  int dst_enc = dst->encoding();
+  // swap src<->dst for encoding
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
+  emit_byte(0x18);
   emit_operand(dst, src);
+  // 0x01 - insert into upper 128 bits
+  emit_byte(0x01);
+}
+
+void Assembler::vextractf128h(Address dst, XMMRegister src) {
+  assert(VM_Version::supports_avx(), "");
+  InstructionMark im(this);
+  bool vector256 = true;
+  assert(src != xnoreg, "sanity");
+  int src_enc = src->encoding();
+  vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
+  emit_byte(0x19);
+  emit_operand(src, dst);
+  // 0x01 - extract from upper 128 bits
+  emit_byte(0x01);
+}
+
+void Assembler::vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
+  assert(VM_Version::supports_avx2(), "");
+  bool vector256 = true;
+  int encode = vex_prefix_and_encode(dst, nds, src, VEX_SIMD_66, vector256, VEX_OPCODE_0F_3A);
+  emit_byte(0x38);
+  emit_byte(0xC0 | encode);
+  // 0x00 - insert into lower 128 bits
+  // 0x01 - insert into upper 128 bits
+  emit_byte(0x01);
+}
+
+void Assembler::vinserti128h(XMMRegister dst, Address src) {
+  assert(VM_Version::supports_avx2(), "");
+  InstructionMark im(this);
+  bool vector256 = true;
+  assert(dst != xnoreg, "sanity");
+  int dst_enc = dst->encoding();
+  // swap src<->dst for encoding
+  vex_prefix(src, dst_enc, dst_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
+  emit_byte(0x38);
+  emit_operand(dst, src);
+  // 0x01 - insert into upper 128 bits
+  emit_byte(0x01);
+}
+
+void Assembler::vextracti128h(Address dst, XMMRegister src) {
+  assert(VM_Version::supports_avx2(), "");
+  InstructionMark im(this);
+  bool vector256 = true;
+  assert(src != xnoreg, "sanity");
+  int src_enc = src->encoding();
+  vex_prefix(dst, 0, src_enc, VEX_SIMD_66, VEX_OPCODE_0F_3A, false, vector256);
+  emit_byte(0x39);
+  emit_operand(src, dst);
+  // 0x01 - extract from upper 128 bits
+  emit_byte(0x01);
+}
+
+void Assembler::vzeroupper() {
+  assert(VM_Version::supports_avx(), "");
+  (void)vex_prefix_and_encode(xmm0, xmm0, xmm0, VEX_SIMD_NONE);
+  emit_byte(0x77);
 }
 
 
@@ -3578,6 +4112,21 @@
   emit_byte(0xF1);
 }
 
+void Assembler::frndint() {
+  emit_byte(0xD9);
+  emit_byte(0xFC);
+}
+
+void Assembler::f2xm1() {
+  emit_byte(0xD9);
+  emit_byte(0xF0);
+}
+
+void Assembler::fldl2e() {
+  emit_byte(0xD9);
+  emit_byte(0xEA);
+}
+
 // SSE SIMD prefix byte values corresponding to VexSimdPrefix encoding.
 static int simd_pre[4] = { 0, 0x66, 0xF3, 0xF2 };
 // SSE opcode second byte values (first is 0x0F) corresponding to VexOpcode encoding.
@@ -3681,6 +4230,49 @@
   }
 }
 
+void Assembler::emit_simd_arith(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre) {
+  InstructionMark im(this);
+  simd_prefix(dst, dst, src, pre);
+  emit_byte(opcode);
+  emit_operand(dst, src);
+}
+
+void Assembler::emit_simd_arith(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre) {
+  int encode = simd_prefix_and_encode(dst, dst, src, pre);
+  emit_byte(opcode);
+  emit_byte(0xC0 | encode);
+}
+
+// Versions with no second source register (non-destructive source).
+void Assembler::emit_simd_arith_nonds(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre) {
+  InstructionMark im(this);
+  simd_prefix(dst, xnoreg, src, pre);
+  emit_byte(opcode);
+  emit_operand(dst, src);
+}
+
+void Assembler::emit_simd_arith_nonds(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre) {
+  int encode = simd_prefix_and_encode(dst, xnoreg, src, pre);
+  emit_byte(opcode);
+  emit_byte(0xC0 | encode);
+}
+
+// 3-operands AVX instructions
+void Assembler::emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
+                               Address src, VexSimdPrefix pre, bool vector256) {
+  InstructionMark im(this);
+  vex_prefix(dst, nds, src, pre, vector256);
+  emit_byte(opcode);
+  emit_operand(dst, src);
+}
+
+void Assembler::emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
+                               XMMRegister src, VexSimdPrefix pre, bool vector256) {
+  int encode = vex_prefix_and_encode(dst, nds, src, pre, vector256);
+  emit_byte(opcode);
+  emit_byte(0xC0 | encode);
+}
+
 #ifndef _LP64
 
 void Assembler::incl(Register dst) {
@@ -5393,23 +5985,7 @@
     // To see where a verify_oop failed, get $ebx+40/X for this frame.
     // This is the value of eip which points to where verify_oop will return.
     if (os::message_box(msg, "Execution stopped, print registers?")) {
-      ttyLocker ttyl;
-      tty->print_cr("eip = 0x%08x", eip);
-#ifndef PRODUCT
-      if ((WizardMode || Verbose) && PrintMiscellaneous) {
-        tty->cr();
-        findpc(eip);
-        tty->cr();
-      }
-#endif
-      tty->print_cr("rax = 0x%08x", rax);
-      tty->print_cr("rbx = 0x%08x", rbx);
-      tty->print_cr("rcx = 0x%08x", rcx);
-      tty->print_cr("rdx = 0x%08x", rdx);
-      tty->print_cr("rdi = 0x%08x", rdi);
-      tty->print_cr("rsi = 0x%08x", rsi);
-      tty->print_cr("rbp = 0x%08x", rbp);
-      tty->print_cr("rsp = 0x%08x", rsp);
+      print_state32(rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax, eip);
       BREAKPOINT;
       assert(false, "start up GDB");
     }
@@ -5421,12 +5997,53 @@
   ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
 }
 
+void MacroAssembler::print_state32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip) {
+  ttyLocker ttyl;
+  FlagSetting fs(Debugging, true);
+  tty->print_cr("eip = 0x%08x", eip);
+#ifndef PRODUCT
+  if ((WizardMode || Verbose) && PrintMiscellaneous) {
+    tty->cr();
+    findpc(eip);
+    tty->cr();
+  }
+#endif
+#define PRINT_REG(rax) \
+  { tty->print("%s = ", #rax); os::print_location(tty, rax); }
+  PRINT_REG(rax);
+  PRINT_REG(rbx);
+  PRINT_REG(rcx);
+  PRINT_REG(rdx);
+  PRINT_REG(rdi);
+  PRINT_REG(rsi);
+  PRINT_REG(rbp);
+  PRINT_REG(rsp);
+#undef PRINT_REG
+  // Print some words near top of staack.
+  int* dump_sp = (int*) rsp;
+  for (int col1 = 0; col1 < 8; col1++) {
+    tty->print("(rsp+0x%03x) 0x%08x: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (intptr_t)dump_sp);
+    os::print_location(tty, *dump_sp++);
+  }
+  for (int row = 0; row < 16; row++) {
+    tty->print("(rsp+0x%03x) 0x%08x: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (intptr_t)dump_sp);
+    for (int col = 0; col < 8; col++) {
+      tty->print(" 0x%08x", *dump_sp++);
+    }
+    tty->cr();
+  }
+  // Print some instructions around pc:
+  Disassembler::decode((address)eip-64, (address)eip);
+  tty->print_cr("--------");
+  Disassembler::decode((address)eip, (address)eip+32);
+}
+
 void MacroAssembler::stop(const char* msg) {
   ExternalAddress message((address)msg);
   // push address of message
   pushptr(message.addr());
   { Label L; call(L, relocInfo::none); bind(L); }     // push eip
-  pusha();                                           // push registers
+  pusha();                                            // push registers
   call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::debug32)));
   hlt();
 }
@@ -5443,6 +6060,18 @@
   pop_CPU_state();
 }
 
+void MacroAssembler::print_state() {
+  { Label L; call(L, relocInfo::none); bind(L); }     // push eip
+  pusha();                                            // push registers
+
+  push_CPU_state();
+  call(RuntimeAddress(CAST_FROM_FN_PTR(address, MacroAssembler::print_state32)));
+  pop_CPU_state();
+
+  popa();
+  addl(rsp, wordSize);
+}
+
 #else // _LP64
 
 // 64 bit versions
@@ -5908,14 +6537,33 @@
 }
 
 void MacroAssembler::warn(const char* msg) {
-  push(rsp);
+  push(rbp);
+  movq(rbp, rsp);
   andq(rsp, -16);     // align stack as required by push_CPU_state and call
-
   push_CPU_state();   // keeps alignment at 16 bytes
   lea(c_rarg0, ExternalAddress((address) msg));
   call_VM_leaf(CAST_FROM_FN_PTR(address, warning), c_rarg0);
   pop_CPU_state();
-  pop(rsp);
+  mov(rsp, rbp);
+  pop(rbp);
+}
+
+void MacroAssembler::print_state() {
+  address rip = pc();
+  pusha();            // get regs on stack
+  push(rbp);
+  movq(rbp, rsp);
+  andq(rsp, -16);     // align stack as required by push_CPU_state and call
+  push_CPU_state();   // keeps alignment at 16 bytes
+
+  lea(c_rarg0, InternalAddress(rip));
+  lea(c_rarg1, Address(rbp, wordSize)); // pass pointer to regs array
+  call_VM_leaf(CAST_FROM_FN_PTR(address, MacroAssembler::print_state64), c_rarg0, c_rarg1);
+
+  pop_CPU_state();
+  mov(rsp, rbp);
+  pop(rbp);
+  popa();
 }
 
 #ifndef PRODUCT
@@ -5924,7 +6572,7 @@
 
 void MacroAssembler::debug64(char* msg, int64_t pc, int64_t regs[]) {
   // In order to get locks to work, we need to fake a in_VM state
-  if (ShowMessageBoxOnError ) {
+  if (ShowMessageBoxOnError) {
     JavaThread* thread = JavaThread::current();
     JavaThreadState saved_state = thread->thread_state();
     thread->set_thread_state(_thread_in_vm);
@@ -5938,30 +6586,9 @@
     // XXX correct this offset for amd64
     // This is the value of eip which points to where verify_oop will return.
     if (os::message_box(msg, "Execution stopped, print registers?")) {
-      ttyLocker ttyl;
-      tty->print_cr("rip = 0x%016lx", pc);
-#ifndef PRODUCT
-      tty->cr();
-      findpc(pc);
-      tty->cr();
-#endif
-      tty->print_cr("rax = 0x%016lx", regs[15]);
-      tty->print_cr("rbx = 0x%016lx", regs[12]);
-      tty->print_cr("rcx = 0x%016lx", regs[14]);
-      tty->print_cr("rdx = 0x%016lx", regs[13]);
-      tty->print_cr("rdi = 0x%016lx", regs[8]);
-      tty->print_cr("rsi = 0x%016lx", regs[9]);
-      tty->print_cr("rbp = 0x%016lx", regs[10]);
-      tty->print_cr("rsp = 0x%016lx", regs[11]);
-      tty->print_cr("r8  = 0x%016lx", regs[7]);
-      tty->print_cr("r9  = 0x%016lx", regs[6]);
-      tty->print_cr("r10 = 0x%016lx", regs[5]);
-      tty->print_cr("r11 = 0x%016lx", regs[4]);
-      tty->print_cr("r12 = 0x%016lx", regs[3]);
-      tty->print_cr("r13 = 0x%016lx", regs[2]);
-      tty->print_cr("r14 = 0x%016lx", regs[1]);
-      tty->print_cr("r15 = 0x%016lx", regs[0]);
+      print_state64(pc, regs);
       BREAKPOINT;
+      assert(false, "start up GDB");
     }
     ThreadStateTransition::transition(thread, _thread_in_vm, saved_state);
   } else {
@@ -5972,6 +6599,54 @@
   }
 }
 
+void MacroAssembler::print_state64(int64_t pc, int64_t regs[]) {
+  ttyLocker ttyl;
+  FlagSetting fs(Debugging, true);
+  tty->print_cr("rip = 0x%016lx", pc);
+#ifndef PRODUCT
+  tty->cr();
+  findpc(pc);
+  tty->cr();
+#endif
+#define PRINT_REG(rax, value) \
+  { tty->print("%s = ", #rax); os::print_location(tty, value); }
+  PRINT_REG(rax, regs[15]);
+  PRINT_REG(rbx, regs[12]);
+  PRINT_REG(rcx, regs[14]);
+  PRINT_REG(rdx, regs[13]);
+  PRINT_REG(rdi, regs[8]);
+  PRINT_REG(rsi, regs[9]);
+  PRINT_REG(rbp, regs[10]);
+  PRINT_REG(rsp, regs[11]);
+  PRINT_REG(r8 , regs[7]);
+  PRINT_REG(r9 , regs[6]);
+  PRINT_REG(r10, regs[5]);
+  PRINT_REG(r11, regs[4]);
+  PRINT_REG(r12, regs[3]);
+  PRINT_REG(r13, regs[2]);
+  PRINT_REG(r14, regs[1]);
+  PRINT_REG(r15, regs[0]);
+#undef PRINT_REG
+  // Print some words near top of staack.
+  int64_t* rsp = (int64_t*) regs[11];
+  int64_t* dump_sp = rsp;
+  for (int col1 = 0; col1 < 8; col1++) {
+    tty->print("(rsp+0x%03x) 0x%016lx: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (int64_t)dump_sp);
+    os::print_location(tty, *dump_sp++);
+  }
+  for (int row = 0; row < 25; row++) {
+    tty->print("(rsp+0x%03x) 0x%016lx: ", (int)((intptr_t)dump_sp - (intptr_t)rsp), (int64_t)dump_sp);
+    for (int col = 0; col < 4; col++) {
+      tty->print(" 0x%016lx", *dump_sp++);
+    }
+    tty->cr();
+  }
+  // Print some instructions around pc:
+  Disassembler::decode((address)pc-64, (address)pc);
+  tty->print_cr("--------");
+  Disassembler::decode((address)pc, (address)pc+32);
+}
+
 #endif // _LP64
 
 // Now versions that are common to 32/64 bit
@@ -6341,7 +7016,7 @@
       get_thread(rax);
       cmpptr(java_thread, rax);
       jcc(Assembler::equal, L);
-      stop("MacroAssembler::call_VM_base: rdi not callee saved?");
+      STOP("MacroAssembler::call_VM_base: rdi not callee saved?");
       bind(L);
     }
     pop(rax);
@@ -6868,6 +7543,264 @@
   Assembler::fldcw(as_Address(src));
 }
 
+void MacroAssembler::pow_exp_core_encoding() {
+  // kills rax, rcx, rdx
+  subptr(rsp,sizeof(jdouble));
+  // computes 2^X. Stack: X ...
+  // f2xm1 computes 2^X-1 but only operates on -1<=X<=1. Get int(X) and
+  // keep it on the thread's stack to compute 2^int(X) later
+  // then compute 2^(X-int(X)) as (2^(X-int(X)-1+1)
+  // final result is obtained with: 2^X = 2^int(X) * 2^(X-int(X))
+  fld_s(0);                 // Stack: X X ...
+  frndint();                // Stack: int(X) X ...
+  fsuba(1);                 // Stack: int(X) X-int(X) ...
+  fistp_s(Address(rsp,0));  // move int(X) as integer to thread's stack. Stack: X-int(X) ...
+  f2xm1();                  // Stack: 2^(X-int(X))-1 ...
+  fld1();                   // Stack: 1 2^(X-int(X))-1 ...
+  faddp(1);                 // Stack: 2^(X-int(X))
+  // computes 2^(int(X)): add exponent bias (1023) to int(X), then
+  // shift int(X)+1023 to exponent position.
+  // Exponent is limited to 11 bits if int(X)+1023 does not fit in 11
+  // bits, set result to NaN. 0x000 and 0x7FF are reserved exponent
+  // values so detect them and set result to NaN.
+  movl(rax,Address(rsp,0));
+  movl(rcx, -2048); // 11 bit mask and valid NaN binary encoding
+  addl(rax, 1023);
+  movl(rdx,rax);
+  shll(rax,20);
+  // Check that 0 < int(X)+1023 < 2047. Otherwise set rax to NaN.
+  addl(rdx,1);
+  // Check that 1 < int(X)+1023+1 < 2048
+  // in 3 steps:
+  // 1- (int(X)+1023+1)&-2048 == 0 => 0 <= int(X)+1023+1 < 2048
+  // 2- (int(X)+1023+1)&-2048 != 0
+  // 3- (int(X)+1023+1)&-2048 != 1
+  // Do 2- first because addl just updated the flags.
+  cmov32(Assembler::equal,rax,rcx);
+  cmpl(rdx,1);
+  cmov32(Assembler::equal,rax,rcx);
+  testl(rdx,rcx);
+  cmov32(Assembler::notEqual,rax,rcx);
+  movl(Address(rsp,4),rax);
+  movl(Address(rsp,0),0);
+  fmul_d(Address(rsp,0));   // Stack: 2^X ...
+  addptr(rsp,sizeof(jdouble));
+}
+
+void MacroAssembler::increase_precision() {
+  subptr(rsp, BytesPerWord);
+  fnstcw(Address(rsp, 0));
+  movl(rax, Address(rsp, 0));
+  orl(rax, 0x300);
+  push(rax);
+  fldcw(Address(rsp, 0));
+  pop(rax);
+}
+
+void MacroAssembler::restore_precision() {
+  fldcw(Address(rsp, 0));
+  addptr(rsp, BytesPerWord);
+}
+
+void MacroAssembler::fast_pow() {
+  // computes X^Y = 2^(Y * log2(X))
+  // if fast computation is not possible, result is NaN. Requires
+  // fallback from user of this macro.
+  // increase precision for intermediate steps of the computation
+  increase_precision();
+  fyl2x();                 // Stack: (Y*log2(X)) ...
+  pow_exp_core_encoding(); // Stack: exp(X) ...
+  restore_precision();
+}
+
+void MacroAssembler::fast_exp() {
+  // computes exp(X) = 2^(X * log2(e))
+  // if fast computation is not possible, result is NaN. Requires
+  // fallback from user of this macro.
+  // increase precision for intermediate steps of the computation
+  increase_precision();
+  fldl2e();                // Stack: log2(e) X ...
+  fmulp(1);                // Stack: (X*log2(e)) ...
+  pow_exp_core_encoding(); // Stack: exp(X) ...
+  restore_precision();
+}
+
+void MacroAssembler::pow_or_exp(bool is_exp, int num_fpu_regs_in_use) {
+  // kills rax, rcx, rdx
+  // pow and exp needs 2 extra registers on the fpu stack.
+  Label slow_case, done;
+  Register tmp = noreg;
+  if (!VM_Version::supports_cmov()) {
+    // fcmp needs a temporary so preserve rdx,
+    tmp = rdx;
+  }
+  Register tmp2 = rax;
+  Register tmp3 = rcx;
+
+  if (is_exp) {
+    // Stack: X
+    fld_s(0);                   // duplicate argument for runtime call. Stack: X X
+    fast_exp();                 // Stack: exp(X) X
+    fcmp(tmp, 0, false, false); // Stack: exp(X) X
+    // exp(X) not equal to itself: exp(X) is NaN go to slow case.
+    jcc(Assembler::parity, slow_case);
+    // get rid of duplicate argument. Stack: exp(X)
+    if (num_fpu_regs_in_use > 0) {
+      fxch();
+      fpop();
+    } else {
+      ffree(1);
+    }
+    jmp(done);
+  } else {
+    // Stack: X Y
+    Label x_negative, y_odd;
+
+    fldz();                     // Stack: 0 X Y
+    fcmp(tmp, 1, true, false);  // Stack: X Y
+    jcc(Assembler::above, x_negative);
+
+    // X >= 0
+
+    fld_s(1);                   // duplicate arguments for runtime call. Stack: Y X Y
+    fld_s(1);                   // Stack: X Y X Y
+    fast_pow();                 // Stack: X^Y X Y
+    fcmp(tmp, 0, false, false); // Stack: X^Y X Y
+    // X^Y not equal to itself: X^Y is NaN go to slow case.
+    jcc(Assembler::parity, slow_case);
+    // get rid of duplicate arguments. Stack: X^Y
+    if (num_fpu_regs_in_use > 0) {
+      fxch(); fpop();
+      fxch(); fpop();
+    } else {
+      ffree(2);
+      ffree(1);
+    }
+    jmp(done);
+
+    // X <= 0
+    bind(x_negative);
+
+    fld_s(1);                   // Stack: Y X Y
+    frndint();                  // Stack: int(Y) X Y
+    fcmp(tmp, 2, false, false); // Stack: int(Y) X Y
+    jcc(Assembler::notEqual, slow_case);
+
+    subptr(rsp, 8);
+
+    // For X^Y, when X < 0, Y has to be an integer and the final
+    // result depends on whether it's odd or even. We just checked
+    // that int(Y) == Y.  We move int(Y) to gp registers as a 64 bit
+    // integer to test its parity. If int(Y) is huge and doesn't fit
+    // in the 64 bit integer range, the integer indefinite value will
+    // end up in the gp registers. Huge numbers are all even, the
+    // integer indefinite number is even so it's fine.
+
+#ifdef ASSERT
+    // Let's check we don't end up with an integer indefinite number
+    // when not expected. First test for huge numbers: check whether
+    // int(Y)+1 == int(Y) which is true for very large numbers and
+    // those are all even. A 64 bit integer is guaranteed to not
+    // overflow for numbers where y+1 != y (when precision is set to
+    // double precision).
+    Label y_not_huge;
+
+    fld1();                     // Stack: 1 int(Y) X Y
+    fadd(1);                    // Stack: 1+int(Y) int(Y) X Y
+
+#ifdef _LP64
+    // trip to memory to force the precision down from double extended
+    // precision
+    fstp_d(Address(rsp, 0));
+    fld_d(Address(rsp, 0));
+#endif
+
+    fcmp(tmp, 1, true, false);  // Stack: int(Y) X Y
+#endif
+
+    // move int(Y) as 64 bit integer to thread's stack
+    fistp_d(Address(rsp,0));    // Stack: X Y
+
+#ifdef ASSERT
+    jcc(Assembler::notEqual, y_not_huge);
+
+    // Y is huge so we know it's even. It may not fit in a 64 bit
+    // integer and we don't want the debug code below to see the
+    // integer indefinite value so overwrite int(Y) on the thread's
+    // stack with 0.
+    movl(Address(rsp, 0), 0);
+    movl(Address(rsp, 4), 0);
+
+    bind(y_not_huge);
+#endif
+
+    fld_s(1);                   // duplicate arguments for runtime call. Stack: Y X Y
+    fld_s(1);                   // Stack: X Y X Y
+    fabs();                     // Stack: abs(X) Y X Y
+    fast_pow();                 // Stack: abs(X)^Y X Y
+    fcmp(tmp, 0, false, false); // Stack: abs(X)^Y X Y
+    // abs(X)^Y not equal to itself: abs(X)^Y is NaN go to slow case.
+
+    pop(tmp2);
+    NOT_LP64(pop(tmp3));
+    jcc(Assembler::parity, slow_case);
+
+#ifdef ASSERT
+    // Check that int(Y) is not integer indefinite value (int
+    // overflow). Shouldn't happen because for values that would
+    // overflow, 1+int(Y)==Y which was tested earlier.
+#ifndef _LP64
+    {
+      Label integer;
+      testl(tmp2, tmp2);
+      jcc(Assembler::notZero, integer);
+      cmpl(tmp3, 0x80000000);
+      jcc(Assembler::notZero, integer);
+      STOP("integer indefinite value shouldn't be seen here");
+      bind(integer);
+    }
+#else
+    {
+      Label integer;
+      mov(tmp3, tmp2); // preserve tmp2 for parity check below
+      shlq(tmp3, 1);
+      jcc(Assembler::carryClear, integer);
+      jcc(Assembler::notZero, integer);
+      STOP("integer indefinite value shouldn't be seen here");
+      bind(integer);
+    }
+#endif
+#endif
+
+    // get rid of duplicate arguments. Stack: X^Y
+    if (num_fpu_regs_in_use > 0) {
+      fxch(); fpop();
+      fxch(); fpop();
+    } else {
+      ffree(2);
+      ffree(1);
+    }
+
+    testl(tmp2, 1);
+    jcc(Assembler::zero, done); // X <= 0, Y even: X^Y = abs(X)^Y
+    // X <= 0, Y even: X^Y = -abs(X)^Y
+
+    fchs();                     // Stack: -abs(X)^Y Y
+    jmp(done);
+  }
+
+  // slow case: runtime call
+  bind(slow_case);
+
+  fpop();                       // pop incorrect result or int(Y)
+
+  fp_runtime_fallback(is_exp ? CAST_FROM_FN_PTR(address, SharedRuntime::dexp) : CAST_FROM_FN_PTR(address, SharedRuntime::dpow),
+                      is_exp ? 1 : 2, num_fpu_regs_in_use);
+
+  // Come here with result in F-TOS
+  bind(done);
+}
+
 void MacroAssembler::fpop() {
   ffree();
   fincstp();
@@ -7132,6 +8065,24 @@
   movb(as_Address(dst), src);
 }
 
+void MacroAssembler::movdl(XMMRegister dst, AddressLiteral src) {
+  if (reachable(src)) {
+    movdl(dst, as_Address(src));
+  } else {
+    lea(rscratch1, src);
+    movdl(dst, Address(rscratch1, 0));
+  }
+}
+
+void MacroAssembler::movq(XMMRegister dst, AddressLiteral src) {
+  if (reachable(src)) {
+    movq(dst, as_Address(src));
+  } else {
+    lea(rscratch1, src);
+    movq(dst, Address(rscratch1, 0));
+  }
+}
+
 void MacroAssembler::movdbl(XMMRegister dst, AddressLiteral src) {
   if (reachable(src)) {
     if (UseXmmLoadAndClearUpper) {
@@ -7175,6 +8126,15 @@
   LP64_ONLY(movq(dst, src)) NOT_LP64(movl(dst, src));
 }
 
+void MacroAssembler::movdqu(XMMRegister dst, AddressLiteral src) {
+  if (reachable(src)) {
+    Assembler::movdqu(dst, as_Address(src));
+  } else {
+    lea(rscratch1, src);
+    Assembler::movdqu(dst, Address(rscratch1, 0));
+  }
+}
+
 void MacroAssembler::movsd(XMMRegister dst, AddressLiteral src) {
   if (reachable(src)) {
     Assembler::movsd(dst, as_Address(src));
@@ -7465,6 +8425,17 @@
   }
 }
 
+void MacroAssembler::pshufb(XMMRegister dst, AddressLiteral src) {
+  // Used in sign-bit flipping with aligned address.
+  assert((UseAVX > 0) || (((intptr_t)src.target() & 15) == 0), "SSE mode requires address alignment 16 bytes");
+  if (reachable(src)) {
+    Assembler::pshufb(dst, as_Address(src));
+  } else {
+    lea(rscratch1, src);
+    Assembler::pshufb(dst, Address(rscratch1, 0));
+  }
+}
+
 // AVX 3-operands instructions
 
 void MacroAssembler::vaddsd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
@@ -7485,21 +8456,21 @@
   }
 }
 
-void MacroAssembler::vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
+void MacroAssembler::vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256) {
   if (reachable(src)) {
-    vandpd(dst, nds, as_Address(src));
+    vandpd(dst, nds, as_Address(src), vector256);
   } else {
     lea(rscratch1, src);
-    vandpd(dst, nds, Address(rscratch1, 0));
+    vandpd(dst, nds, Address(rscratch1, 0), vector256);
   }
 }
 
-void MacroAssembler::vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
+void MacroAssembler::vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256) {
   if (reachable(src)) {
-    vandps(dst, nds, as_Address(src));
+    vandps(dst, nds, as_Address(src), vector256);
   } else {
     lea(rscratch1, src);
-    vandps(dst, nds, Address(rscratch1, 0));
+    vandps(dst, nds, Address(rscratch1, 0), vector256);
   }
 }
 
@@ -7557,21 +8528,21 @@
   }
 }
 
-void MacroAssembler::vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
+void MacroAssembler::vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256) {
   if (reachable(src)) {
-    vxorpd(dst, nds, as_Address(src));
+    vxorpd(dst, nds, as_Address(src), vector256);
   } else {
     lea(rscratch1, src);
-    vxorpd(dst, nds, Address(rscratch1, 0));
+    vxorpd(dst, nds, Address(rscratch1, 0), vector256);
   }
 }
 
-void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src) {
+void MacroAssembler::vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256) {
   if (reachable(src)) {
-    vxorps(dst, nds, as_Address(src));
+    vxorps(dst, nds, as_Address(src), vector256);
   } else {
     lea(rscratch1, src);
-    vxorps(dst, nds, Address(rscratch1, 0));
+    vxorps(dst, nds, Address(rscratch1, 0), vector256);
   }
 }
 
@@ -7997,7 +8968,7 @@
     shlptr(tsize, LogHeapWordSize);
     cmpptr(t1, tsize);
     jcc(Assembler::equal, ok);
-    stop("assert(t1 != tlab size)");
+    STOP("assert(t1 != tlab size)");
     should_not_reach_here();
 
     bind(ok);
@@ -8045,6 +9016,193 @@
 #endif
 }
 
+void MacroAssembler::fp_runtime_fallback(address runtime_entry, int nb_args, int num_fpu_regs_in_use) {
+  pusha();
+
+  // if we are coming from c1, xmm registers may be live
+  int off = 0;
+  if (UseSSE == 1)  {
+    subptr(rsp, sizeof(jdouble)*8);
+    movflt(Address(rsp,off++*sizeof(jdouble)),xmm0);
+    movflt(Address(rsp,off++*sizeof(jdouble)),xmm1);
+    movflt(Address(rsp,off++*sizeof(jdouble)),xmm2);
+    movflt(Address(rsp,off++*sizeof(jdouble)),xmm3);
+    movflt(Address(rsp,off++*sizeof(jdouble)),xmm4);
+    movflt(Address(rsp,off++*sizeof(jdouble)),xmm5);
+    movflt(Address(rsp,off++*sizeof(jdouble)),xmm6);
+    movflt(Address(rsp,off++*sizeof(jdouble)),xmm7);
+  } else if (UseSSE >= 2)  {
+#ifdef COMPILER2
+    if (MaxVectorSize > 16) {
+      assert(UseAVX > 0, "256bit vectors are supported only with AVX");
+      // Save upper half of YMM registes
+      subptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8));
+      vextractf128h(Address(rsp,  0),xmm0);
+      vextractf128h(Address(rsp, 16),xmm1);
+      vextractf128h(Address(rsp, 32),xmm2);
+      vextractf128h(Address(rsp, 48),xmm3);
+      vextractf128h(Address(rsp, 64),xmm4);
+      vextractf128h(Address(rsp, 80),xmm5);
+      vextractf128h(Address(rsp, 96),xmm6);
+      vextractf128h(Address(rsp,112),xmm7);
+#ifdef _LP64
+      vextractf128h(Address(rsp,128),xmm8);
+      vextractf128h(Address(rsp,144),xmm9);
+      vextractf128h(Address(rsp,160),xmm10);
+      vextractf128h(Address(rsp,176),xmm11);
+      vextractf128h(Address(rsp,192),xmm12);
+      vextractf128h(Address(rsp,208),xmm13);
+      vextractf128h(Address(rsp,224),xmm14);
+      vextractf128h(Address(rsp,240),xmm15);
+#endif
+    }
+#endif
+    // Save whole 128bit (16 bytes) XMM regiters
+    subptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8));
+    movdqu(Address(rsp,off++*16),xmm0);
+    movdqu(Address(rsp,off++*16),xmm1);
+    movdqu(Address(rsp,off++*16),xmm2);
+    movdqu(Address(rsp,off++*16),xmm3);
+    movdqu(Address(rsp,off++*16),xmm4);
+    movdqu(Address(rsp,off++*16),xmm5);
+    movdqu(Address(rsp,off++*16),xmm6);
+    movdqu(Address(rsp,off++*16),xmm7);
+#ifdef _LP64
+    movdqu(Address(rsp,off++*16),xmm8);
+    movdqu(Address(rsp,off++*16),xmm9);
+    movdqu(Address(rsp,off++*16),xmm10);
+    movdqu(Address(rsp,off++*16),xmm11);
+    movdqu(Address(rsp,off++*16),xmm12);
+    movdqu(Address(rsp,off++*16),xmm13);
+    movdqu(Address(rsp,off++*16),xmm14);
+    movdqu(Address(rsp,off++*16),xmm15);
+#endif
+  }
+
+  // Preserve registers across runtime call
+  int incoming_argument_and_return_value_offset = -1;
+  if (num_fpu_regs_in_use > 1) {
+    // Must preserve all other FPU regs (could alternatively convert
+    // SharedRuntime::dsin, dcos etc. into assembly routines known not to trash
+    // FPU state, but can not trust C compiler)
+    NEEDS_CLEANUP;
+    // NOTE that in this case we also push the incoming argument(s) to
+    // the stack and restore it later; we also use this stack slot to
+    // hold the return value from dsin, dcos etc.
+    for (int i = 0; i < num_fpu_regs_in_use; i++) {
+      subptr(rsp, sizeof(jdouble));
+      fstp_d(Address(rsp, 0));
+    }
+    incoming_argument_and_return_value_offset = sizeof(jdouble)*(num_fpu_regs_in_use-1);
+    for (int i = nb_args-1; i >= 0; i--) {
+      fld_d(Address(rsp, incoming_argument_and_return_value_offset-i*sizeof(jdouble)));
+    }
+  }
+
+  subptr(rsp, nb_args*sizeof(jdouble));
+  for (int i = 0; i < nb_args; i++) {
+    fstp_d(Address(rsp, i*sizeof(jdouble)));
+  }
+
+#ifdef _LP64
+  if (nb_args > 0) {
+    movdbl(xmm0, Address(rsp, 0));
+  }
+  if (nb_args > 1) {
+    movdbl(xmm1, Address(rsp, sizeof(jdouble)));
+  }
+  assert(nb_args <= 2, "unsupported number of args");
+#endif // _LP64
+
+  // NOTE: we must not use call_VM_leaf here because that requires a
+  // complete interpreter frame in debug mode -- same bug as 4387334
+  // MacroAssembler::call_VM_leaf_base is perfectly safe and will
+  // do proper 64bit abi
+
+  NEEDS_CLEANUP;
+  // Need to add stack banging before this runtime call if it needs to
+  // be taken; however, there is no generic stack banging routine at
+  // the MacroAssembler level
+
+  MacroAssembler::call_VM_leaf_base(runtime_entry, 0);
+
+#ifdef _LP64
+  movsd(Address(rsp, 0), xmm0);
+  fld_d(Address(rsp, 0));
+#endif // _LP64
+  addptr(rsp, sizeof(jdouble) * nb_args);
+  if (num_fpu_regs_in_use > 1) {
+    // Must save return value to stack and then restore entire FPU
+    // stack except incoming arguments
+    fstp_d(Address(rsp, incoming_argument_and_return_value_offset));
+    for (int i = 0; i < num_fpu_regs_in_use - nb_args; i++) {
+      fld_d(Address(rsp, 0));
+      addptr(rsp, sizeof(jdouble));
+    }
+    fld_d(Address(rsp, (nb_args-1)*sizeof(jdouble)));
+    addptr(rsp, sizeof(jdouble) * nb_args);
+  }
+
+  off = 0;
+  if (UseSSE == 1)  {
+    movflt(xmm0, Address(rsp,off++*sizeof(jdouble)));
+    movflt(xmm1, Address(rsp,off++*sizeof(jdouble)));
+    movflt(xmm2, Address(rsp,off++*sizeof(jdouble)));
+    movflt(xmm3, Address(rsp,off++*sizeof(jdouble)));
+    movflt(xmm4, Address(rsp,off++*sizeof(jdouble)));
+    movflt(xmm5, Address(rsp,off++*sizeof(jdouble)));
+    movflt(xmm6, Address(rsp,off++*sizeof(jdouble)));
+    movflt(xmm7, Address(rsp,off++*sizeof(jdouble)));
+    addptr(rsp, sizeof(jdouble)*8);
+  } else if (UseSSE >= 2)  {
+    // Restore whole 128bit (16 bytes) XMM regiters
+    movdqu(xmm0, Address(rsp,off++*16));
+    movdqu(xmm1, Address(rsp,off++*16));
+    movdqu(xmm2, Address(rsp,off++*16));
+    movdqu(xmm3, Address(rsp,off++*16));
+    movdqu(xmm4, Address(rsp,off++*16));
+    movdqu(xmm5, Address(rsp,off++*16));
+    movdqu(xmm6, Address(rsp,off++*16));
+    movdqu(xmm7, Address(rsp,off++*16));
+#ifdef _LP64
+    movdqu(xmm8, Address(rsp,off++*16));
+    movdqu(xmm9, Address(rsp,off++*16));
+    movdqu(xmm10, Address(rsp,off++*16));
+    movdqu(xmm11, Address(rsp,off++*16));
+    movdqu(xmm12, Address(rsp,off++*16));
+    movdqu(xmm13, Address(rsp,off++*16));
+    movdqu(xmm14, Address(rsp,off++*16));
+    movdqu(xmm15, Address(rsp,off++*16));
+#endif
+    addptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8));
+#ifdef COMPILER2
+    if (MaxVectorSize > 16) {
+      // Restore upper half of YMM registes.
+      vinsertf128h(xmm0, Address(rsp,  0));
+      vinsertf128h(xmm1, Address(rsp, 16));
+      vinsertf128h(xmm2, Address(rsp, 32));
+      vinsertf128h(xmm3, Address(rsp, 48));
+      vinsertf128h(xmm4, Address(rsp, 64));
+      vinsertf128h(xmm5, Address(rsp, 80));
+      vinsertf128h(xmm6, Address(rsp, 96));
+      vinsertf128h(xmm7, Address(rsp,112));
+#ifdef _LP64
+      vinsertf128h(xmm8, Address(rsp,128));
+      vinsertf128h(xmm9, Address(rsp,144));
+      vinsertf128h(xmm10, Address(rsp,160));
+      vinsertf128h(xmm11, Address(rsp,176));
+      vinsertf128h(xmm12, Address(rsp,192));
+      vinsertf128h(xmm13, Address(rsp,208));
+      vinsertf128h(xmm14, Address(rsp,224));
+      vinsertf128h(xmm15, Address(rsp,240));
+#endif
+      addptr(rsp, 16 * LP64_ONLY(16) NOT_LP64(8));
+    }
+#endif
+  }
+  popa();
+}
+
 static const double     pi_4 =  0.7853981633974483;
 
 void MacroAssembler::trigfunc(char trig, int num_fpu_regs_in_use) {
@@ -8092,73 +9250,27 @@
 
   // slow case: runtime call
   bind(slow_case);
-  // Preserve registers across runtime call
-  pusha();
-  int incoming_argument_and_return_value_offset = -1;
-  if (num_fpu_regs_in_use > 1) {
-    // Must preserve all other FPU regs (could alternatively convert
-    // SharedRuntime::dsin and dcos into assembly routines known not to trash
-    // FPU state, but can not trust C compiler)
-    NEEDS_CLEANUP;
-    // NOTE that in this case we also push the incoming argument to
-    // the stack and restore it later; we also use this stack slot to
-    // hold the return value from dsin or dcos.
-    for (int i = 0; i < num_fpu_regs_in_use; i++) {
-      subptr(rsp, sizeof(jdouble));
-      fstp_d(Address(rsp, 0));
-    }
-    incoming_argument_and_return_value_offset = sizeof(jdouble)*(num_fpu_regs_in_use-1);
-    fld_d(Address(rsp, incoming_argument_and_return_value_offset));
-  }
-  subptr(rsp, sizeof(jdouble));
-  fstp_d(Address(rsp, 0));
-#ifdef _LP64
-  movdbl(xmm0, Address(rsp, 0));
-#endif // _LP64
 
-  // NOTE: we must not use call_VM_leaf here because that requires a
-  // complete interpreter frame in debug mode -- same bug as 4387334
-  // MacroAssembler::call_VM_leaf_base is perfectly safe and will
-  // do proper 64bit abi
-
-  NEEDS_CLEANUP;
-  // Need to add stack banging before this runtime call if it needs to
-  // be taken; however, there is no generic stack banging routine at
-  // the MacroAssembler level
   switch(trig) {
   case 's':
     {
-      MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), 0);
+      fp_runtime_fallback(CAST_FROM_FN_PTR(address, SharedRuntime::dsin), 1, num_fpu_regs_in_use);
     }
     break;
   case 'c':
     {
-      MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), 0);
+      fp_runtime_fallback(CAST_FROM_FN_PTR(address, SharedRuntime::dcos), 1, num_fpu_regs_in_use);
     }
     break;
   case 't':
     {
-      MacroAssembler::call_VM_leaf_base(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), 0);
+      fp_runtime_fallback(CAST_FROM_FN_PTR(address, SharedRuntime::dtan), 1, num_fpu_regs_in_use);
     }
     break;
   default:
     assert(false, "bad intrinsic");
     break;
   }
-#ifdef _LP64
-    movsd(Address(rsp, 0), xmm0);
-    fld_d(Address(rsp, 0));
-#endif // _LP64
-  addptr(rsp, sizeof(jdouble));
-  if (num_fpu_regs_in_use > 1) {
-    // Must save return value to stack and then restore entire FPU stack
-    fstp_d(Address(rsp, incoming_argument_and_return_value_offset));
-    for (int i = 0; i < num_fpu_regs_in_use; i++) {
-      fld_d(Address(rsp, 0));
-      addptr(rsp, sizeof(jdouble));
-    }
-  }
-  popa();
 
   // Come here with result in F-TOS
   bind(done);
@@ -8244,6 +9356,19 @@
 }
 
 
+// virtual method calling
+void MacroAssembler::lookup_virtual_method(Register recv_klass,
+                                           RegisterOrConstant vtable_index,
+                                           Register method_result) {
+  const int base = instanceKlass::vtable_start_offset() * wordSize;
+  assert(vtableEntry::size() * wordSize == wordSize, "else adjust the scaling in the code below");
+  Address vtable_entry_addr(recv_klass,
+                            vtable_index, Address::times_ptr,
+                            base + vtableEntry::method_offset_in_bytes());
+  movptr(method_result, vtable_entry_addr);
+}
+
+
 void MacroAssembler::check_klass_subtype(Register sub_klass,
                            Register super_klass,
                            Register temp_reg,
@@ -8493,6 +9618,7 @@
   // Pass register number to verify_oop_subroutine
   char* b = new char[strlen(s) + 50];
   sprintf(b, "verify_oop: %s: %s", reg->name(), s);
+  BLOCK_COMMENT("verify_oop {");
 #ifdef _LP64
   push(rscratch1);                    // save r10, trashed by movptr()
 #endif
@@ -8507,6 +9633,7 @@
   movptr(rax, ExternalAddress(StubRoutines::verify_oop_subroutine_entry_address()));
   call(rax);
   // Caller pops the arguments (oop, message) and restores rax, r10
+  BLOCK_COMMENT("} verify_oop");
 }
 
 
@@ -8527,7 +9654,7 @@
       jcc(Assembler::notZero, L);
       char* buf = new char[40];
       sprintf(buf, "DelayedValue="INTPTR_FORMAT, delayed_value_addr[1]);
-      stop(buf);
+      STOP(buf);
     } else {
       jccb(Assembler::notZero, L);
       hlt();
@@ -8543,60 +9670,6 @@
 }
 
 
-// registers on entry:
-//  - rax ('check' register): required MethodType
-//  - rcx: method handle
-//  - rdx, rsi, or ?: killable temp
-void MacroAssembler::check_method_handle_type(Register mtype_reg, Register mh_reg,
-                                              Register temp_reg,
-                                              Label& wrong_method_type) {
-  Address type_addr(mh_reg, delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg));
-  // compare method type against that of the receiver
-  if (UseCompressedOops) {
-    load_heap_oop(temp_reg, type_addr);
-    cmpptr(mtype_reg, temp_reg);
-  } else {
-    cmpptr(mtype_reg, type_addr);
-  }
-  jcc(Assembler::notEqual, wrong_method_type);
-}
-
-
-// A method handle has a "vmslots" field which gives the size of its
-// argument list in JVM stack slots.  This field is either located directly
-// in every method handle, or else is indirectly accessed through the
-// method handle's MethodType.  This macro hides the distinction.
-void MacroAssembler::load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
-                                                Register temp_reg) {
-  assert_different_registers(vmslots_reg, mh_reg, temp_reg);
-  // load mh.type.form.vmslots
-  Register temp2_reg = vmslots_reg;
-  load_heap_oop(temp2_reg, Address(mh_reg,    delayed_value(java_lang_invoke_MethodHandle::type_offset_in_bytes, temp_reg)));
-  load_heap_oop(temp2_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, temp_reg)));
-  movl(vmslots_reg, Address(temp2_reg, delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, temp_reg)));
-}
-
-
-// registers on entry:
-//  - rcx: method handle
-//  - rdx: killable temp (interpreted only)
-//  - rax: killable temp (compiled only)
-void MacroAssembler::jump_to_method_handle_entry(Register mh_reg, Register temp_reg) {
-  assert(mh_reg == rcx, "caller must put MH object in rcx");
-  assert_different_registers(mh_reg, temp_reg);
-
-  // pick out the interpreted side of the handler
-  // NOTE: vmentry is not an oop!
-  movptr(temp_reg, Address(mh_reg, delayed_value(java_lang_invoke_MethodHandle::vmentry_offset_in_bytes, temp_reg)));
-
-  // off we go...
-  jmp(Address(temp_reg, MethodHandleEntry::from_interpreted_entry_offset_in_bytes()));
-
-  // for the various stubs which take control at this point,
-  // see MethodHandles::generate_method_handle_stub
-}
-
-
 Address MacroAssembler::argument_address(RegisterOrConstant arg_slot,
                                          int extra_slot_offset) {
   // cf. TemplateTable::prepare_invoke(), if (load_receiver).
@@ -8669,14 +9742,14 @@
     movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())));
     cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_start_offset())));
     jcc(Assembler::aboveEqual, next);
-    stop("assert(top >= start)");
+    STOP("assert(top >= start)");
     should_not_reach_here();
 
     bind(next);
     movptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_end_offset())));
     cmpptr(t1, Address(thread_reg, in_bytes(JavaThread::tlab_top_offset())));
     jcc(Assembler::aboveEqual, ok);
-    stop("assert(top <= end)");
+    STOP("assert(top <= end)");
     should_not_reach_here();
 
     bind(ok);
@@ -9109,6 +10182,25 @@
     movptr(dst, src);
 }
 
+void MacroAssembler::cmp_heap_oop(Register src1, Address src2, Register tmp) {
+  assert_different_registers(src1, tmp);
+#ifdef _LP64
+  if (UseCompressedOops) {
+    bool did_push = false;
+    if (tmp == noreg) {
+      tmp = rax;
+      push(tmp);
+      did_push = true;
+      assert(!src2.uses(rsp), "can't push");
+    }
+    load_heap_oop(tmp, src2);
+    cmpptr(src1, tmp);
+    if (did_push)  pop(tmp);
+  } else
+#endif
+    cmpptr(src1, src2);
+}
+
 // Used for storing NULLs.
 void MacroAssembler::store_heap_oop_null(Address dst) {
 #ifdef _LP64
@@ -9139,7 +10231,7 @@
     push(rscratch1); // cmpptr trashes rscratch1
     cmpptr(r12_heapbase, ExternalAddress((address)Universe::narrow_oop_base_addr()));
     jcc(Assembler::equal, ok);
-    stop(msg);
+    STOP(msg);
     bind(ok);
     pop(rscratch1);
   }
@@ -9172,7 +10264,7 @@
     Label ok;
     testq(r, r);
     jcc(Assembler::notEqual, ok);
-    stop("null oop passed to encode_heap_oop_not_null");
+    STOP("null oop passed to encode_heap_oop_not_null");
     bind(ok);
   }
 #endif
@@ -9193,7 +10285,7 @@
     Label ok;
     testq(src, src);
     jcc(Assembler::notEqual, ok);
-    stop("null oop passed to encode_heap_oop_not_null2");
+    STOP("null oop passed to encode_heap_oop_not_null2");
     bind(ok);
   }
 #endif
@@ -9384,7 +10476,7 @@
     cmpptr(rax, StackAlignmentInBytes-wordSize);
     pop(rax);
     jcc(Assembler::equal, L);
-    stop("Stack is not properly aligned!");
+    STOP("Stack is not properly aligned!");
     bind(L);
   }
 #endif
@@ -10058,13 +11150,6 @@
   bind(DONE);
 }
 
-#ifdef PRODUCT
-#define BLOCK_COMMENT(str) /* nothing */
-#else
-#define BLOCK_COMMENT(str) block_comment(str)
-#endif
-
-#define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
 void MacroAssembler::generate_fill(BasicType t, bool aligned,
                                    Register to, Register value, Register count,
                                    Register rtmp, XMMRegister xtmp) {
diff --git a/hotspot/src/cpu/x86/vm/assembler_x86.hpp b/hotspot/src/cpu/x86/vm/assembler_x86.hpp
index 4a72da8..e4ec81a 100644
--- a/hotspot/src/cpu/x86/vm/assembler_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/assembler_x86.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -591,8 +591,9 @@
 
   void vex_prefix(XMMRegister dst, XMMRegister nds, Address src,
                   VexSimdPrefix pre, bool vector256 = false) {
-     vex_prefix(src, nds->encoding(), dst->encoding(),
-                pre, VEX_OPCODE_0F, false, vector256);
+    int dst_enc = dst->encoding();
+    int nds_enc = nds->is_valid() ? nds->encoding() : 0;
+    vex_prefix(src, nds_enc, dst_enc, pre, VEX_OPCODE_0F, false, vector256);
   }
 
   int  vex_prefix_and_encode(int dst_enc, int nds_enc, int src_enc,
@@ -600,9 +601,12 @@
                              bool vex_w, bool vector256);
 
   int  vex_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
-                             VexSimdPrefix pre, bool vector256 = false) {
-     return vex_prefix_and_encode(dst->encoding(), nds->encoding(), src->encoding(),
-                                  pre, VEX_OPCODE_0F, false, vector256);
+                             VexSimdPrefix pre, bool vector256 = false,
+                             VexOpcode opc = VEX_OPCODE_0F) {
+    int src_enc = src->encoding();
+    int dst_enc = dst->encoding();
+    int nds_enc = nds->is_valid() ? nds->encoding() : 0;
+    return vex_prefix_and_encode(dst_enc, nds_enc, src_enc, pre, opc, false, vector256);
   }
 
   void simd_prefix(XMMRegister xreg, XMMRegister nds, Address adr,
@@ -613,6 +617,7 @@
                    VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F) {
     simd_prefix(dst, xnoreg, src, pre, opc);
   }
+
   void simd_prefix(Address dst, XMMRegister src, VexSimdPrefix pre) {
     simd_prefix(src, dst, pre);
   }
@@ -622,16 +627,10 @@
     simd_prefix(dst, nds, src, pre, VEX_OPCODE_0F, rex_w);
   }
 
-
   int simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, XMMRegister src,
                              VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F,
                              bool rex_w = false, bool vector256 = false);
 
-  int simd_prefix_and_encode(XMMRegister dst, XMMRegister src,
-                             VexSimdPrefix pre, VexOpcode opc = VEX_OPCODE_0F) {
-    return simd_prefix_and_encode(dst, xnoreg, src, pre, opc);
-  }
-
   // Move/convert 32-bit integer value.
   int simd_prefix_and_encode(XMMRegister dst, XMMRegister nds, Register src,
                              VexSimdPrefix pre) {
@@ -673,6 +672,15 @@
   void emit_arith(int op1, int op2, Register dst, jobject obj);
   void emit_arith(int op1, int op2, Register dst, Register src);
 
+  void emit_simd_arith(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre);
+  void emit_simd_arith(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre);
+  void emit_simd_arith_nonds(int opcode, XMMRegister dst, Address src, VexSimdPrefix pre);
+  void emit_simd_arith_nonds(int opcode, XMMRegister dst, XMMRegister src, VexSimdPrefix pre);
+  void emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
+                      Address src, VexSimdPrefix pre, bool vector256);
+  void emit_vex_arith(int opcode, XMMRegister dst, XMMRegister nds,
+                      XMMRegister src, VexSimdPrefix pre, bool vector256);
+
   void emit_operand(Register reg,
                     Register base, Register index, Address::ScaleFactor scale,
                     int disp,
@@ -877,6 +885,17 @@
   void addss(XMMRegister dst, Address src);
   void addss(XMMRegister dst, XMMRegister src);
 
+  // AES instructions
+  void aesdec(XMMRegister dst, Address src);
+  void aesdec(XMMRegister dst, XMMRegister src);
+  void aesdeclast(XMMRegister dst, Address src);
+  void aesdeclast(XMMRegister dst, XMMRegister src);
+  void aesenc(XMMRegister dst, Address src);
+  void aesenc(XMMRegister dst, XMMRegister src);
+  void aesenclast(XMMRegister dst, Address src);
+  void aesenclast(XMMRegister dst, XMMRegister src);
+
+
   void andl(Address  dst, int32_t imm32);
   void andl(Register dst, int32_t imm32);
   void andl(Register dst, Address src);
@@ -887,12 +906,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, XMMRegister src);
-
-  // Bitwise Logical AND of Packed Single-Precision Floating-Point Values
-  void andps(XMMRegister dst, XMMRegister src);
-
   void bsfl(Register dst, Register src);
   void bsrl(Register dst, Register src);
 
@@ -1148,6 +1161,9 @@
   void fxsave(Address dst);
 
   void fyl2x();
+  void frndint();
+  void f2xm1();
+  void fldl2e();
 
   void hlt();
 
@@ -1258,6 +1274,7 @@
   void movdl(XMMRegister dst, Register src);
   void movdl(Register dst, XMMRegister src);
   void movdl(XMMRegister dst, Address src);
+  void movdl(Address dst, XMMRegister src);
 
   // Move Double Quadword
   void movdq(XMMRegister dst, Register src);
@@ -1271,6 +1288,14 @@
   void movdqu(XMMRegister dst, Address src);
   void movdqu(XMMRegister dst, XMMRegister src);
 
+  // Move Unaligned 256bit Vector
+  void vmovdqu(Address dst, XMMRegister src);
+  void vmovdqu(XMMRegister dst, Address src);
+  void vmovdqu(XMMRegister dst, XMMRegister src);
+
+  // Move lower 64bit to high 64bit in 128bit register
+  void movlhps(XMMRegister dst, XMMRegister src);
+
   void movl(Register dst, int32_t imm32);
   void movl(Address dst, int32_t imm32);
   void movl(Register dst, Register src);
@@ -1420,9 +1445,9 @@
   void prefetcht2(Address src);
   void prefetchw(Address src);
 
-  // POR - Bitwise logical OR
-  void por(XMMRegister dst, XMMRegister src);
-  void por(XMMRegister dst, Address src);
+  // Shuffle Bytes
+  void pshufb(XMMRegister dst, XMMRegister src);
+  void pshufb(XMMRegister dst, Address src);
 
   // Shuffle Packed Doublewords
   void pshufd(XMMRegister dst, XMMRegister src, int mode);
@@ -1432,9 +1457,6 @@
   void pshuflw(XMMRegister dst, XMMRegister src, int mode);
   void pshuflw(XMMRegister dst, Address src,     int mode);
 
-  // Shift Right by bits Logical Quadword Immediate
-  void psrlq(XMMRegister dst, int shift);
-
   // Shift Right by bytes Logical DoubleQuadword Immediate
   void psrldq(XMMRegister dst, int shift);
 
@@ -1450,16 +1472,15 @@
   void punpckldq(XMMRegister dst, XMMRegister src);
   void punpckldq(XMMRegister dst, Address src);
 
+  // Interleave Low Quadwords
+  void punpcklqdq(XMMRegister dst, XMMRegister src);
+
 #ifndef _LP64 // no 32bit push/pop on amd64
   void pushl(Address src);
 #endif
 
   void pushq(Address src);
 
-  // Xor Packed Byte Integer Values
-  void pxor(XMMRegister dst, Address src);
-  void pxor(XMMRegister dst, XMMRegister src);
-
   void rcll(Register dst, int imm8);
 
   void rclq(Register dst, int imm8);
@@ -1582,21 +1603,14 @@
   void xorq(Register dst, Address src);
   void xorq(Register dst, Register src);
 
-  // Bitwise Logical XOR of Packed Double-Precision Floating-Point Values
-  void xorpd(XMMRegister dst, XMMRegister src);
-
-  // Bitwise Logical XOR of Packed Single-Precision Floating-Point Values
-  void xorps(XMMRegister dst, XMMRegister src);
-
   void set_byte_if_not_zero(Register dst); // sets reg to 1 if not zero, otherwise 0
 
-  // AVX 3-operands instructions (encoded with VEX prefix)
+  // AVX 3-operands scalar instructions (encoded with VEX prefix)
+
   void vaddsd(XMMRegister dst, XMMRegister nds, Address src);
   void vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
   void vaddss(XMMRegister dst, XMMRegister nds, Address src);
   void vaddss(XMMRegister dst, XMMRegister nds, XMMRegister src);
-  void vandpd(XMMRegister dst, XMMRegister nds, Address src);
-  void vandps(XMMRegister dst, XMMRegister nds, Address src);
   void vdivsd(XMMRegister dst, XMMRegister nds, Address src);
   void vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
   void vdivss(XMMRegister dst, XMMRegister nds, Address src);
@@ -1609,10 +1623,164 @@
   void vsubsd(XMMRegister dst, XMMRegister nds, XMMRegister src);
   void vsubss(XMMRegister dst, XMMRegister nds, Address src);
   void vsubss(XMMRegister dst, XMMRegister nds, XMMRegister src);
-  void vxorpd(XMMRegister dst, XMMRegister nds, Address src);
-  void vxorps(XMMRegister dst, XMMRegister nds, Address src);
 
 
+  //====================VECTOR ARITHMETIC=====================================
+
+  // Add Packed Floating-Point Values
+  void addpd(XMMRegister dst, XMMRegister src);
+  void addps(XMMRegister dst, XMMRegister src);
+  void vaddpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vaddps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vaddpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vaddps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Subtract Packed Floating-Point Values
+  void subpd(XMMRegister dst, XMMRegister src);
+  void subps(XMMRegister dst, XMMRegister src);
+  void vsubpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vsubps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vsubpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vsubps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Multiply Packed Floating-Point Values
+  void mulpd(XMMRegister dst, XMMRegister src);
+  void mulps(XMMRegister dst, XMMRegister src);
+  void vmulpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vmulps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vmulpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vmulps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Divide Packed Floating-Point Values
+  void divpd(XMMRegister dst, XMMRegister src);
+  void divps(XMMRegister dst, XMMRegister src);
+  void vdivpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vdivps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vdivpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vdivps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Bitwise Logical AND of Packed Floating-Point Values
+  void andpd(XMMRegister dst, XMMRegister src);
+  void andps(XMMRegister dst, XMMRegister src);
+  void vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vandpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vandps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Bitwise Logical XOR of Packed Floating-Point Values
+  void xorpd(XMMRegister dst, XMMRegister src);
+  void xorps(XMMRegister dst, XMMRegister src);
+  void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vxorpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vxorps(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Add packed integers
+  void paddb(XMMRegister dst, XMMRegister src);
+  void paddw(XMMRegister dst, XMMRegister src);
+  void paddd(XMMRegister dst, XMMRegister src);
+  void paddq(XMMRegister dst, XMMRegister src);
+  void vpaddb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpaddw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpaddd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpaddq(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpaddb(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vpaddw(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vpaddd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vpaddq(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Sub packed integers
+  void psubb(XMMRegister dst, XMMRegister src);
+  void psubw(XMMRegister dst, XMMRegister src);
+  void psubd(XMMRegister dst, XMMRegister src);
+  void psubq(XMMRegister dst, XMMRegister src);
+  void vpsubb(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpsubw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpsubd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpsubq(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpsubb(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vpsubw(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vpsubd(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vpsubq(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Multiply packed integers (only shorts and ints)
+  void pmullw(XMMRegister dst, XMMRegister src);
+  void pmulld(XMMRegister dst, XMMRegister src);
+  void vpmullw(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpmulld(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpmullw(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+  void vpmulld(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Shift left packed integers
+  void psllw(XMMRegister dst, int shift);
+  void pslld(XMMRegister dst, int shift);
+  void psllq(XMMRegister dst, int shift);
+  void psllw(XMMRegister dst, XMMRegister shift);
+  void pslld(XMMRegister dst, XMMRegister shift);
+  void psllq(XMMRegister dst, XMMRegister shift);
+  void vpsllw(XMMRegister dst, XMMRegister src, int shift, bool vector256);
+  void vpslld(XMMRegister dst, XMMRegister src, int shift, bool vector256);
+  void vpsllq(XMMRegister dst, XMMRegister src, int shift, bool vector256);
+  void vpsllw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
+  void vpslld(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
+  void vpsllq(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
+
+  // Logical shift right packed integers
+  void psrlw(XMMRegister dst, int shift);
+  void psrld(XMMRegister dst, int shift);
+  void psrlq(XMMRegister dst, int shift);
+  void psrlw(XMMRegister dst, XMMRegister shift);
+  void psrld(XMMRegister dst, XMMRegister shift);
+  void psrlq(XMMRegister dst, XMMRegister shift);
+  void vpsrlw(XMMRegister dst, XMMRegister src, int shift, bool vector256);
+  void vpsrld(XMMRegister dst, XMMRegister src, int shift, bool vector256);
+  void vpsrlq(XMMRegister dst, XMMRegister src, int shift, bool vector256);
+  void vpsrlw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
+  void vpsrld(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
+  void vpsrlq(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
+
+  // Arithmetic shift right packed integers (only shorts and ints, no instructions for longs)
+  void psraw(XMMRegister dst, int shift);
+  void psrad(XMMRegister dst, int shift);
+  void psraw(XMMRegister dst, XMMRegister shift);
+  void psrad(XMMRegister dst, XMMRegister shift);
+  void vpsraw(XMMRegister dst, XMMRegister src, int shift, bool vector256);
+  void vpsrad(XMMRegister dst, XMMRegister src, int shift, bool vector256);
+  void vpsraw(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
+  void vpsrad(XMMRegister dst, XMMRegister src, XMMRegister shift, bool vector256);
+
+  // And packed integers
+  void pand(XMMRegister dst, XMMRegister src);
+  void vpand(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpand(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Or packed integers
+  void por(XMMRegister dst, XMMRegister src);
+  void vpor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpor(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Xor packed integers
+  void pxor(XMMRegister dst, XMMRegister src);
+  void vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256);
+  void vpxor(XMMRegister dst, XMMRegister nds, Address src, bool vector256);
+
+  // Copy low 128bit into high 128bit of YMM registers.
+  void vinsertf128h(XMMRegister dst, XMMRegister nds, XMMRegister src);
+  void vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src);
+
+  // Load/store high 128bit of YMM registers which does not destroy other half.
+  void vinsertf128h(XMMRegister dst, Address src);
+  void vinserti128h(XMMRegister dst, Address src);
+  void vextractf128h(Address dst, XMMRegister src);
+  void vextracti128h(Address dst, XMMRegister src);
+
+  // AVX instruction which is used to clear upper 128 bits of YMM registers and
+  // to avoid transaction penalty between AVX and SSE states. There is no
+  // penalty if legacy SSE instructions are encoded using VEX prefix because
+  // they always clear upper 128 bits. It should be used before calling
+  // runtime code and native libraries.
+  void vzeroupper();
+
  protected:
   // Next instructions require address alignment 16 bytes SSE mode.
   // They should be called only from corresponding MacroAssembler instructions.
@@ -1908,6 +2076,7 @@
   void load_heap_oop(Register dst, Address src);
   void load_heap_oop_not_null(Register dst, Address src);
   void store_heap_oop(Address dst, Register src);
+  void cmp_heap_oop(Register src1, Address src2, Register tmp = noreg);
 
   // Used for storing NULL. All other oop constants should be
   // stored using routines that take a jobject.
@@ -2085,6 +2254,11 @@
                                Register scan_temp,
                                Label& no_such_interface);
 
+  // virtual method calling
+  void lookup_virtual_method(Register recv_klass,
+                             RegisterOrConstant vtable_index,
+                             Register method_result);
+
   // Test sub_klass against super_klass, with fast and slow paths.
 
   // The fast path produces a tri-state answer: yes / no / maybe-slow.
@@ -2120,15 +2294,8 @@
                            Label& L_success);
 
   // method handles (JSR 292)
-  void check_method_handle_type(Register mtype_reg, Register mh_reg,
-                                Register temp_reg,
-                                Label& wrong_method_type);
-  void load_method_handle_vmslots(Register vmslots_reg, Register mh_reg,
-                                  Register temp_reg);
-  void jump_to_method_handle_entry(Register mh_reg, Register temp_reg);
   Address argument_address(RegisterOrConstant arg_slot, int extra_slot_offset = 0);
 
-
   //----
   void set_word_if_not_zero(Register reg); // sets reg to 1 if not zero, otherwise 0
 
@@ -2147,8 +2314,13 @@
   // prints msg and continues
   void warn(const char* msg);
 
+  // dumps registers and other state
+  void print_state();
+
   static void debug32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip, char* msg);
   static void debug64(char* msg, int64_t pc, int64_t regs[]);
+  static void print_state32(int rdi, int rsi, int rbp, int rsp, int rbx, int rdx, int rcx, int rax, int eip);
+  static void print_state64(int64_t pc, int64_t regs[]);
 
   void os_breakpoint();
 
@@ -2387,7 +2559,30 @@
   void ldmxcsr(Address src) { Assembler::ldmxcsr(src); }
   void ldmxcsr(AddressLiteral src);
 
+  // compute pow(x,y) and exp(x) with x86 instructions. Don't cover
+  // all corner cases and may result in NaN and require fallback to a
+  // runtime call.
+  void fast_pow();
+  void fast_exp();
+  void increase_precision();
+  void restore_precision();
+
+  // computes exp(x). Fallback to runtime call included.
+  void exp_with_fallback(int num_fpu_regs_in_use) { pow_or_exp(true, num_fpu_regs_in_use); }
+  // computes pow(x,y). Fallback to runtime call included.
+  void pow_with_fallback(int num_fpu_regs_in_use) { pow_or_exp(false, num_fpu_regs_in_use); }
+
 private:
+
+  // call runtime as a fallback for trig functions and pow/exp.
+  void fp_runtime_fallback(address runtime_entry, int nb_args, int num_fpu_regs_in_use);
+
+  // computes 2^(Ylog2X); Ylog2X in ST(0)
+  void pow_exp_core_encoding();
+
+  // computes pow(x,y) or exp(x). Fallback to runtime call included.
+  void pow_or_exp(bool is_exp, int num_fpu_regs_in_use);
+
   // these are private because users should be doing movflt/movdbl
 
   void movss(Address dst, XMMRegister src)     { Assembler::movss(dst, src); }
@@ -2416,6 +2611,12 @@
   void divss(XMMRegister dst, Address src)        { Assembler::divss(dst, src); }
   void divss(XMMRegister dst, AddressLiteral src);
 
+  // Move Unaligned Double Quadword
+  void movdqu(Address     dst, XMMRegister src)   { Assembler::movdqu(dst, src); }
+  void movdqu(XMMRegister dst, Address src)       { Assembler::movdqu(dst, src); }
+  void movdqu(XMMRegister dst, XMMRegister src)   { Assembler::movdqu(dst, src); }
+  void movdqu(XMMRegister dst, AddressLiteral 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); }
@@ -2463,6 +2664,10 @@
   void xorps(XMMRegister dst, Address src)     { Assembler::xorps(dst, src); }
   void xorps(XMMRegister dst, AddressLiteral src);
 
+  // Shuffle Bytes
+  void pshufb(XMMRegister dst, XMMRegister src) { Assembler::pshufb(dst, src); }
+  void pshufb(XMMRegister dst, Address src)     { Assembler::pshufb(dst, src); }
+  void pshufb(XMMRegister dst, AddressLiteral src);
   // AVX 3-operands instructions
 
   void vaddsd(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vaddsd(dst, nds, src); }
@@ -2473,11 +2678,13 @@
   void vaddss(XMMRegister dst, XMMRegister nds, Address src)     { Assembler::vaddss(dst, nds, src); }
   void vaddss(XMMRegister dst, XMMRegister nds, AddressLiteral src);
 
-  void vandpd(XMMRegister dst, XMMRegister nds, Address src)     { Assembler::vandpd(dst, nds, src); }
-  void vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
+  void vandpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) { Assembler::vandpd(dst, nds, src, vector256); }
+  void vandpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256)     { Assembler::vandpd(dst, nds, src, vector256); }
+  void vandpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256);
 
-  void vandps(XMMRegister dst, XMMRegister nds, Address src)     { Assembler::vandps(dst, nds, src); }
-  void vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src);
+  void vandps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) { Assembler::vandps(dst, nds, src, vector256); }
+  void vandps(XMMRegister dst, XMMRegister nds, Address src, bool vector256)     { Assembler::vandps(dst, nds, src, vector256); }
+  void vandps(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256);
 
   void vdivsd(XMMRegister dst, XMMRegister nds, XMMRegister src) { Assembler::vdivsd(dst, nds, src); }
   void vdivsd(XMMRegister dst, XMMRegister nds, Address src)     { Assembler::vdivsd(dst, nds, src); }
@@ -2503,12 +2710,36 @@
   void vsubss(XMMRegister dst, XMMRegister nds, Address src)     { Assembler::vsubss(dst, nds, src); }
   void vsubss(XMMRegister dst, XMMRegister nds, AddressLiteral src);
 
-  void vxorpd(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vxorpd(dst, nds, src); }
-  void vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src);
+  // AVX Vector instructions
 
-  void vxorps(XMMRegister dst, XMMRegister nds, Address src) { Assembler::vxorps(dst, nds, src); }
-  void vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src);
+  void vxorpd(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) { Assembler::vxorpd(dst, nds, src, vector256); }
+  void vxorpd(XMMRegister dst, XMMRegister nds, Address src, bool vector256) { Assembler::vxorpd(dst, nds, src, vector256); }
+  void vxorpd(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256);
 
+  void vxorps(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) { Assembler::vxorps(dst, nds, src, vector256); }
+  void vxorps(XMMRegister dst, XMMRegister nds, Address src, bool vector256) { Assembler::vxorps(dst, nds, src, vector256); }
+  void vxorps(XMMRegister dst, XMMRegister nds, AddressLiteral src, bool vector256);
+
+  void vpxor(XMMRegister dst, XMMRegister nds, XMMRegister src, bool vector256) {
+    if (UseAVX > 1 || !vector256) // vpxor 256 bit is available only in AVX2
+      Assembler::vpxor(dst, nds, src, vector256);
+    else
+      Assembler::vxorpd(dst, nds, src, vector256);
+  }
+  void vpxor(XMMRegister dst, XMMRegister nds, Address src, bool vector256) {
+    if (UseAVX > 1 || !vector256) // vpxor 256 bit is available only in AVX2
+      Assembler::vpxor(dst, nds, src, vector256);
+    else
+      Assembler::vxorpd(dst, nds, src, vector256);
+  }
+
+  // Move packed integer values from low 128 bit to hign 128 bit in 256 bit vector.
+  void vinserti128h(XMMRegister dst, XMMRegister nds, XMMRegister src) {
+    if (UseAVX > 1) // vinserti128h is available only in AVX2
+      Assembler::vinserti128h(dst, nds, src);
+    else
+      Assembler::vinsertf128h(dst, nds, src);
+  }
 
   // Data
 
@@ -2561,6 +2792,13 @@
   // to avoid hiding movb
   void movbyte(ArrayAddress dst, int src);
 
+  // Import other mov() methods from the parent class or else
+  // they will be hidden by the following overriding declaration.
+  using Assembler::movdl;
+  using Assembler::movq;
+  void movdl(XMMRegister dst, AddressLiteral src);
+  void movq(XMMRegister dst, AddressLiteral src);
+
   // Can push value or effective address
   void pushptr(AddressLiteral src);
 
diff --git a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
index 24b879a..618a37c 100644
--- a/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_CodeStubs_x86.cpp
@@ -488,68 +488,6 @@
 
 }
 
-void G1UnsafeGetObjSATBBarrierStub::emit_code(LIR_Assembler* ce) {
-  // At this point we know that offset == referent_offset.
-  //
-  // So we might have to emit:
-  //   if (src == null) goto continuation.
-  //
-  // and we definitely have to emit:
-  //   if (klass(src).reference_type == REF_NONE) goto continuation
-  //   if (!marking_active) goto continuation
-  //   if (pre_val == null) goto continuation
-  //   call pre_barrier(pre_val)
-  //   goto continuation
-  //
-  __ bind(_entry);
-
-  assert(src()->is_register(), "sanity");
-  Register src_reg = src()->as_register();
-
-  if (gen_src_check()) {
-    // The original src operand was not a constant.
-    // Generate src == null?
-    __ cmpptr(src_reg, (int32_t) NULL_WORD);
-    __ jcc(Assembler::equal, _continuation);
-  }
-
-  // Generate src->_klass->_reference_type == REF_NONE)?
-  assert(tmp()->is_register(), "sanity");
-  Register tmp_reg = tmp()->as_register();
-
-  __ load_klass(tmp_reg, src_reg);
-
-  Address ref_type_adr(tmp_reg, instanceKlass::reference_type_offset());
-  __ cmpb(ref_type_adr, REF_NONE);
-  __ jcc(Assembler::equal, _continuation);
-
-  // Is marking active?
-  assert(thread()->is_register(), "precondition");
-  Register thread_reg = thread()->as_pointer_register();
-
-  Address in_progress(thread_reg, in_bytes(JavaThread::satb_mark_queue_offset() +
-                                       PtrQueue::byte_offset_of_active()));
-
-  if (in_bytes(PtrQueue::byte_width_of_active()) == 4) {
-    __ cmpl(in_progress, 0);
-  } else {
-    assert(in_bytes(PtrQueue::byte_width_of_active()) == 1, "Assumption");
-    __ cmpb(in_progress, 0);
-  }
-  __ jcc(Assembler::equal, _continuation);
-
-  // val == null?
-  assert(val()->is_register(), "Precondition.");
-  Register val_reg = val()->as_register();
-
-  __ cmpptr(val_reg, (int32_t) NULL_WORD);
-  __ jcc(Assembler::equal, _continuation);
-
-  ce->store_parameter(val()->as_register(), 0);
-  __ call(RuntimeAddress(Runtime1::entry_for(Runtime1::g1_pre_barrier_slow_id)));
-  __ jmp(_continuation);
-}
-
 jbyte* G1PostBarrierStub::_byte_map_base = NULL;
 
 jbyte* G1PostBarrierStub::byte_map_base_slow() {
diff --git a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
index dcb38ab..435ce7f 100644
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp
@@ -2446,6 +2446,12 @@
         // Should consider not saving rbx, if not necessary
         __ trigfunc('t', op->as_Op2()->fpu_stack_size());
         break;
+      case lir_exp :
+        __ exp_with_fallback(op->as_Op2()->fpu_stack_size());
+        break;
+      case lir_pow :
+        __ pow_with_fallback(op->as_Op2()->fpu_stack_size());
+        break;
       default      : ShouldNotReachHere();
     }
   } else {
@@ -3502,6 +3508,7 @@
 void LIR_Assembler::emit_profile_call(LIR_OpProfileCall* op) {
   ciMethod* method = op->profiled_method();
   int bci          = op->profiled_bci();
+  ciMethod* callee = op->profiled_callee();
 
   // Update counter for all call types
   ciMethodData* md = method->method_data_or_null();
@@ -3513,9 +3520,11 @@
   __ movoop(mdo, md->constant_encoding());
   Address counter_addr(mdo, md->byte_offset_of_slot(data, CounterData::count_offset()));
   Bytecodes::Code bc = method->java_code_at_bci(bci);
+  const bool callee_is_static = callee->is_loaded() && callee->is_static();
   // Perform additional virtual call profiling for invokevirtual and
   // invokeinterface bytecodes
   if ((bc == Bytecodes::_invokevirtual || bc == Bytecodes::_invokeinterface) &&
+      !callee_is_static &&  // required for optimized MH invokes
       C1ProfileVirtualCalls) {
     assert(op->recv()->is_single_cpu(), "recv must be allocated");
     Register recv = op->recv()->as_register();
@@ -3760,5 +3769,49 @@
   // do nothing for now
 }
 
+void LIR_Assembler::atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp) {
+  assert(data == dest, "xchg/xadd uses only 2 operands");
+
+  if (data->type() == T_INT) {
+    if (code == lir_xadd) {
+      if (os::is_MP()) {
+        __ lock();
+      }
+      __ xaddl(as_Address(src->as_address_ptr()), data->as_register());
+    } else {
+      __ xchgl(data->as_register(), as_Address(src->as_address_ptr()));
+    }
+  } else if (data->is_oop()) {
+    assert (code == lir_xchg, "xadd for oops");
+    Register obj = data->as_register();
+#ifdef _LP64
+    if (UseCompressedOops) {
+      __ encode_heap_oop(obj);
+      __ xchgl(obj, as_Address(src->as_address_ptr()));
+      __ decode_heap_oop(obj);
+    } else {
+      __ xchgptr(obj, as_Address(src->as_address_ptr()));
+    }
+#else
+    __ xchgl(obj, as_Address(src->as_address_ptr()));
+#endif
+  } else if (data->type() == T_LONG) {
+#ifdef _LP64
+    assert(data->as_register_lo() == data->as_register_hi(), "should be a single register");
+    if (code == lir_xadd) {
+      if (os::is_MP()) {
+        __ lock();
+      }
+      __ xaddq(as_Address(src->as_address_ptr()), data->as_register_lo());
+    } else {
+      __ xchgq(data->as_register_lo(), as_Address(src->as_address_ptr()));
+    }
+#else
+    ShouldNotReachHere();
+#endif
+  } else {
+    ShouldNotReachHere();
+  }
+}
 
 #undef __
diff --git a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
index c872742..734cdb1 100644
--- a/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_LIRGenerator_x86.cpp
@@ -718,35 +718,6 @@
 }
 
 
-void LIRGenerator::do_AttemptUpdate(Intrinsic* x) {
-  assert(x->number_of_arguments() == 3, "wrong type");
-  LIRItem obj       (x->argument_at(0), this);  // AtomicLong object
-  LIRItem cmp_value (x->argument_at(1), this);  // value to compare with field
-  LIRItem new_value (x->argument_at(2), this);  // replace field with new_value if it matches cmp_value
-
-  // compare value must be in rdx,eax (hi,lo); may be destroyed by cmpxchg8 instruction
-  cmp_value.load_item_force(FrameMap::long0_opr);
-
-  // new value must be in rcx,ebx (hi,lo)
-  new_value.load_item_force(FrameMap::long1_opr);
-
-  // object pointer register is overwritten with field address
-  obj.load_item();
-
-  // generate compare-and-swap; produces zero condition if swap occurs
-  int value_offset = sun_misc_AtomicLongCSImpl::value_offset();
-  LIR_Opr addr = new_pointer_register();
-  __ leal(LIR_OprFact::address(new LIR_Address(obj.result(), value_offset, T_LONG)), addr);
-  LIR_Opr t1 = LIR_OprFact::illegalOpr;  // no temp needed
-  LIR_Opr t2 = LIR_OprFact::illegalOpr;  // no temp needed
-  __ cas_long(addr, cmp_value.result(), new_value.result(), t1, t2);
-
-  // 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, T_LONG);
-}
-
-
 void LIRGenerator::do_CompareAndSwap(Intrinsic* x, ValueType* type) {
   assert(x->number_of_arguments() == 4, "wrong type");
   LIRItem obj   (x->argument_at(0), this);  // object
@@ -782,9 +753,24 @@
   LIR_Opr addr = new_pointer_register();
   LIR_Address* a;
   if(offset.result()->is_constant()) {
+#ifdef _LP64
+    jlong c = offset.result()->as_jlong();
+    if ((jlong)((jint)c) == c) {
+      a = new LIR_Address(obj.result(),
+                          (jint)c,
+                          as_BasicType(type));
+    } else {
+      LIR_Opr tmp = new_register(T_LONG);
+      __ move(offset.result(), tmp);
+      a = new LIR_Address(obj.result(),
+                          tmp,
+                          as_BasicType(type));
+    }
+#else
     a = new LIR_Address(obj.result(),
-                        NOT_LP64(offset.result()->as_constant_ptr()->as_jint()) LP64_ONLY((int)offset.result()->as_constant_ptr()->as_jlong()),
+                        offset.result()->as_jint(),
                         as_BasicType(type));
+#endif
   } else {
     a = new LIR_Address(obj.result(),
                         offset.result(),
@@ -823,7 +809,7 @@
 
 
 void LIRGenerator::do_MathIntrinsic(Intrinsic* x) {
-  assert(x->number_of_arguments() == 1, "wrong type");
+  assert(x->number_of_arguments() == 1 || (x->number_of_arguments() == 2 && x->id() == vmIntrinsics::_dpow), "wrong type");
   LIRItem value(x->argument_at(0), this);
 
   bool use_fpu = false;
@@ -834,6 +820,8 @@
       case vmIntrinsics::_dtan:
       case vmIntrinsics::_dlog:
       case vmIntrinsics::_dlog10:
+      case vmIntrinsics::_dexp:
+      case vmIntrinsics::_dpow:
         use_fpu = true;
     }
   } else {
@@ -843,20 +831,37 @@
   value.load_item();
 
   LIR_Opr calc_input = value.result();
+  LIR_Opr calc_input2 = NULL;
+  if (x->id() == vmIntrinsics::_dpow) {
+    LIRItem extra_arg(x->argument_at(1), this);
+    if (UseSSE < 2) {
+      extra_arg.set_destroys_register();
+    }
+    extra_arg.load_item();
+    calc_input2 = extra_arg.result();
+  }
   LIR_Opr calc_result = rlock_result(x);
 
-  // sin and cos need two free fpu stack slots, so register two temporary operands
+  // sin, cos, pow and exp need two free fpu stack slots, so register
+  // two temporary operands
   LIR_Opr tmp1 = FrameMap::caller_save_fpu_reg_at(0);
   LIR_Opr tmp2 = FrameMap::caller_save_fpu_reg_at(1);
 
   if (use_fpu) {
     LIR_Opr tmp = FrameMap::fpu0_double_opr;
+    int tmp_start = 1;
+    if (calc_input2 != NULL) {
+      __ move(calc_input2, tmp);
+      tmp_start = 2;
+      calc_input2 = tmp;
+    }
     __ move(calc_input, tmp);
 
     calc_input = tmp;
     calc_result = tmp;
-    tmp1 = FrameMap::caller_save_fpu_reg_at(1);
-    tmp2 = FrameMap::caller_save_fpu_reg_at(2);
+
+    tmp1 = FrameMap::caller_save_fpu_reg_at(tmp_start);
+    tmp2 = FrameMap::caller_save_fpu_reg_at(tmp_start + 1);
   }
 
   switch(x->id()) {
@@ -867,6 +872,8 @@
     case vmIntrinsics::_dtan:   __ tan  (calc_input, calc_result, tmp1, tmp2);              break;
     case vmIntrinsics::_dlog:   __ log  (calc_input, calc_result, tmp1);                    break;
     case vmIntrinsics::_dlog10: __ log10(calc_input, calc_result, tmp1);                    break;
+    case vmIntrinsics::_dexp:   __ exp  (calc_input, calc_result,              tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break;
+    case vmIntrinsics::_dpow:   __ pow  (calc_input, calc_input2, calc_result, tmp1, tmp2, FrameMap::rax_opr, FrameMap::rcx_opr, FrameMap::rdx_opr); break;
     default:                    ShouldNotReachHere();
   }
 
@@ -1353,3 +1360,57 @@
     }
   }
 }
+
+void LIRGenerator::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
+  BasicType type = x->basic_type();
+  LIRItem src(x->object(), this);
+  LIRItem off(x->offset(), this);
+  LIRItem value(x->value(), this);
+
+  src.load_item();
+  value.load_item();
+  off.load_nonconstant();
+
+  LIR_Opr dst = rlock_result(x, type);
+  LIR_Opr data = value.result();
+  bool is_obj = (type == T_ARRAY || type == T_OBJECT);
+  LIR_Opr offset = off.result();
+
+  assert (type == T_INT || (!x->is_add() && is_obj) LP64_ONLY( || type == T_LONG ), "unexpected type");
+  LIR_Address* addr;
+  if (offset->is_constant()) {
+#ifdef _LP64
+    jlong c = offset->as_jlong();
+    if ((jlong)((jint)c) == c) {
+      addr = new LIR_Address(src.result(), (jint)c, type);
+    } else {
+      LIR_Opr tmp = new_register(T_LONG);
+      __ move(offset, tmp);
+      addr = new LIR_Address(src.result(), tmp, type);
+    }
+#else
+    addr = new LIR_Address(src.result(), offset->as_jint(), type);
+#endif
+  } else {
+    addr = new LIR_Address(src.result(), offset, type);
+  }
+
+  if (data != dst) {
+    __ move(data, dst);
+    data = dst;
+  }
+  if (x->is_add()) {
+    __ xadd(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr);
+  } else {
+    if (is_obj) {
+      // Do the pre-write barrier, if any.
+      pre_barrier(LIR_OprFact::address(addr), LIR_OprFact::illegalOpr /* pre_val */,
+                  true /* do_load */, false /* patch */, NULL);
+    }
+    __ xchg(LIR_OprFact::address(addr), data, dst, LIR_OprFact::illegalOpr);
+    if (is_obj) {
+      // Seems to be a precise address
+      post_barrier(LIR_OprFact::address(addr), data);
+    }
+  }
+}
diff --git a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp
index 0c19851..77859b9 100644
--- a/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_LinearScan_x86.cpp
@@ -690,8 +690,8 @@
 
     case lir_mul_strictfp:
     case lir_div_strictfp: {
-      assert(op2->tmp_opr()->is_fpu_register(), "strict operations need temporary fpu stack slot");
-      insert_free_if_dead(op2->tmp_opr());
+      assert(op2->tmp1_opr()->is_fpu_register(), "strict operations need temporary fpu stack slot");
+      insert_free_if_dead(op2->tmp1_opr());
       assert(sim()->stack_size() <= 7, "at least one stack slot must be free");
       // fall-through: continue with the normal handling of lir_mul and lir_div
     }
@@ -787,16 +787,17 @@
 
     case lir_log:
     case lir_log10: {
-      // log and log10 needs one temporary fpu stack slot, so there is ontemporary
-      // registers stored in temp of the operation.
-      // the stack allocator must guarantee that the stack slots are really free,
-      // otherwise there might be a stack overflow.
+      // log and log10 need one temporary fpu stack slot, so
+      // there is one temporary registers stored in temp of the
+      // operation. the stack allocator must guarantee that the stack
+      // slots are really free, otherwise there might be a stack
+      // overflow.
       assert(right->is_illegal(), "must be");
       assert(left->is_fpu_register(), "must be");
       assert(res->is_fpu_register(), "must be");
-      assert(op2->tmp_opr()->is_fpu_register(), "must be");
+      assert(op2->tmp1_opr()->is_fpu_register(), "must be");
 
-      insert_free_if_dead(op2->tmp_opr());
+      insert_free_if_dead(op2->tmp1_opr());
       insert_free_if_dead(res, left);
       insert_exchange(left);
       do_rename(left, res);
@@ -812,8 +813,9 @@
 
     case lir_tan:
     case lir_sin:
-    case lir_cos: {
-      // sin and cos need two temporary fpu stack slots, so there are two temporary
+    case lir_cos:
+    case lir_exp: {
+      // sin, cos and exp need two temporary fpu stack slots, so there are two temporary
       // registers (stored in right and temp of the operation).
       // the stack allocator must guarantee that the stack slots are really free,
       // otherwise there might be a stack overflow.
@@ -821,11 +823,11 @@
       assert(res->is_fpu_register(), "must be");
       // assert(left->is_last_use(), "old value gets destroyed");
       assert(right->is_fpu_register(), "right is used as the first temporary register");
-      assert(op2->tmp_opr()->is_fpu_register(), "temp is used as the second temporary register");
-      assert(fpu_num(left) != fpu_num(right) && fpu_num(right) != fpu_num(op2->tmp_opr()) && fpu_num(op2->tmp_opr()) != fpu_num(res), "need distinct temp registers");
+      assert(op2->tmp1_opr()->is_fpu_register(), "temp is used as the second temporary register");
+      assert(fpu_num(left) != fpu_num(right) && fpu_num(right) != fpu_num(op2->tmp1_opr()) && fpu_num(op2->tmp1_opr()) != fpu_num(res), "need distinct temp registers");
 
       insert_free_if_dead(right);
-      insert_free_if_dead(op2->tmp_opr());
+      insert_free_if_dead(op2->tmp1_opr());
 
       insert_free_if_dead(res, left);
       insert_exchange(left);
@@ -839,6 +841,53 @@
       break;
     }
 
+    case lir_pow: {
+      // pow needs two temporary fpu stack slots, so there are two temporary
+      // registers (stored in tmp1 and tmp2 of the operation).
+      // the stack allocator must guarantee that the stack slots are really free,
+      // otherwise there might be a stack overflow.
+      assert(left->is_fpu_register(), "must be");
+      assert(right->is_fpu_register(), "must be");
+      assert(res->is_fpu_register(), "must be");
+
+      assert(op2->tmp1_opr()->is_fpu_register(), "tmp1 is the first temporary register");
+      assert(op2->tmp2_opr()->is_fpu_register(), "tmp2 is the second temporary register");
+      assert(fpu_num(left) != fpu_num(right) && fpu_num(left) != fpu_num(op2->tmp1_opr()) && fpu_num(left) != fpu_num(op2->tmp2_opr()) && fpu_num(left) != fpu_num(res), "need distinct temp registers");
+      assert(fpu_num(right) != fpu_num(op2->tmp1_opr()) && fpu_num(right) != fpu_num(op2->tmp2_opr()) && fpu_num(right) != fpu_num(res), "need distinct temp registers");
+      assert(fpu_num(op2->tmp1_opr()) != fpu_num(op2->tmp2_opr()) && fpu_num(op2->tmp1_opr()) != fpu_num(res), "need distinct temp registers");
+      assert(fpu_num(op2->tmp2_opr()) != fpu_num(res), "need distinct temp registers");
+
+      insert_free_if_dead(op2->tmp1_opr());
+      insert_free_if_dead(op2->tmp2_opr());
+
+      // Must bring both operands to top of stack with following operand ordering:
+      // * fpu stack before pow: ... right left
+      // * fpu stack after pow:  ... left
+
+      insert_free_if_dead(res, right);
+
+      if (tos_offset(right) != 1) {
+        insert_exchange(right);
+        insert_exchange(1);
+      }
+      insert_exchange(left);
+      assert(tos_offset(right) == 1, "check");
+      assert(tos_offset(left) == 0, "check");
+
+      new_left = to_fpu_stack_top(left);
+      new_right = to_fpu_stack(right);
+
+      op2->set_fpu_stack_size(sim()->stack_size());
+      assert(sim()->stack_size() <= 6, "at least two stack slots must be free");
+
+      sim()->pop();
+
+      do_rename(right, res);
+
+      new_res = to_fpu_stack_top(res);
+      break;
+    }
+
     default: {
       assert(false, "missed a fpu-operation");
     }
diff --git a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
index 5f2cf38..30df608 100644
--- a/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/c1_Runtime1_x86.cpp
@@ -47,6 +47,12 @@
   assert(!(oop_result1->is_valid() || oop_result2->is_valid()) || oop_result1 != oop_result2, "registers must be different");
   assert(oop_result1 != thread && oop_result2 != thread, "registers must be different");
   assert(args_size >= 0, "illegal args_size");
+  bool align_stack = false;
+#ifdef _LP64
+  // At a method handle call, the stack may not be properly aligned
+  // when returning with an exception.
+  align_stack = (stub_id() == Runtime1::handle_exception_from_callee_id);
+#endif
 
 #ifdef _LP64
   mov(c_rarg0, thread);
@@ -59,11 +65,21 @@
   push(thread);
 #endif // _LP64
 
-  set_last_Java_frame(thread, noreg, rbp, NULL);
+  int call_offset;
+  if (!align_stack) {
+    set_last_Java_frame(thread, noreg, rbp, NULL);
+  } else {
+    address the_pc = pc();
+    call_offset = offset();
+    set_last_Java_frame(thread, noreg, rbp, the_pc);
+    andptr(rsp, -(StackAlignmentInBytes));    // Align stack
+  }
 
   // do the call
   call(RuntimeAddress(entry));
-  int call_offset = offset();
+  if (!align_stack) {
+    call_offset = offset();
+  }
   // verify callee-saved register
 #ifdef ASSERT
   guarantee(thread != rax, "change this code");
@@ -78,7 +94,7 @@
   }
   pop(rax);
 #endif
-  reset_last_Java_frame(thread, true, false);
+  reset_last_Java_frame(thread, true, align_stack);
 
   // discard thread and arguments
   NOT_LP64(addptr(rsp, num_rt_args()*BytesPerWord));
diff --git a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp
index b9a5c22..f400522 100644
--- a/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/cppInterpreter_x86.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, 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
@@ -481,7 +481,8 @@
   __ xorptr(rdx, rdx);
   __ movptr(STATE(_oop_temp), rdx);                     // state->_oop_temp = NULL (only really needed for native)
   __ movptr(STATE(_mdx), rdx);                          // state->_mdx = NULL
-  __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset()));
+  __ movptr(rdx, Address(rbx, methodOopDesc::const_offset()));
+  __ movptr(rdx, Address(rdx, constMethodOopDesc::constants_offset()));
   __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes()));
   __ movptr(STATE(_constants), rdx);                    // state->_constants = constants()
 
@@ -516,7 +517,8 @@
     __ testl(rax, JVM_ACC_STATIC);
     __ movptr(rax, Address(locals, 0));                   // get receiver (assume this is frequent case)
     __ jcc(Assembler::zero, done);
-    __ movptr(rax, Address(rbx, methodOopDesc::constants_offset()));
+    __ movptr(rax, Address(rbx, methodOopDesc::const_offset()));
+    __ movptr(rax, Address(rax, constMethodOopDesc::constants_offset()));
     __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes()));
     __ movptr(rax, Address(rax, mirror_offset));
     __ bind(done);
@@ -769,7 +771,8 @@
     __ testl(rax, JVM_ACC_STATIC);
     __ movptr(rax, Address(rdi, 0));                                    // get receiver (assume this is frequent case)
     __ jcc(Assembler::zero, done);
-    __ movptr(rax, Address(rbx, methodOopDesc::constants_offset()));
+    __ movptr(rax, Address(rbx, methodOopDesc::const_offset()));
+    __ movptr(rax, Address(rax, constMethodOopDesc::constants_offset()));
     __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes()));
     __ movptr(rax, Address(rax, mirror_offset));
     __ bind(done);
@@ -821,9 +824,9 @@
     __ testptr(rax, rax);
     __ jcc(Assembler::zero, slow_path);
 
-    __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset()));
     // read first instruction word and extract bytecode @ 1 and index @ 2
     __ movptr(rdx, Address(rbx, methodOopDesc::const_offset()));
+    __ movptr(rdi, Address(rdx, constMethodOopDesc::constants_offset()));
     __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset()));
     // Shift codes right to get the index on the right.
     // The bytecode fetched looks like <index><0xb4><0x2a>
@@ -868,9 +871,9 @@
     // Need to differentiate between igetfield, agetfield, bgetfield etc.
     // because they are different sizes.
     // Use the type from the constant pool cache
-    __ shrl(rdx, ConstantPoolCacheEntry::tosBits);
-    // Make sure we don't need to mask rdx for tosBits after the above shift
-    ConstantPoolCacheEntry::verify_tosBits();
+    __ shrl(rdx, ConstantPoolCacheEntry::tos_state_shift);
+    // Make sure we don't need to mask rdx after the above shift
+    ConstantPoolCacheEntry::verify_tos_state_shift();
 #ifdef _LP64
     Label notObj;
     __ cmpl(rdx, atos);
@@ -1185,7 +1188,8 @@
     __ testl(t, JVM_ACC_STATIC);
     __ jcc(Assembler::zero, L);
     // get mirror
-    __ movptr(t, Address(method, methodOopDesc:: constants_offset()));
+    __ movptr(t, Address(method, methodOopDesc:: const_offset()));
+    __ movptr(t, Address(t, constMethodOopDesc::constants_offset()));
     __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes()));
     __ movptr(t, Address(t, mirror_offset));
     // copy mirror into activation object
diff --git a/hotspot/src/cpu/x86/vm/frame_x86.cpp b/hotspot/src/cpu/x86/vm/frame_x86.cpp
index 4e87936..d9b21d7 100644
--- a/hotspot/src/cpu/x86/vm/frame_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/frame_x86.cpp
@@ -439,7 +439,6 @@
 // frame::sender_for_compiled_frame
 frame frame::sender_for_compiled_frame(RegisterMap* map) const {
   assert(map != NULL, "map must be set");
-  assert(!is_ricochet_frame(), "caller must handle this");
 
   // frame owned by optimizing compiler
   assert(_cb->frame_size() >= 0, "must have non-zero frame size");
@@ -483,7 +482,6 @@
   if (is_entry_frame())       return sender_for_entry_frame(map);
   if (is_interpreted_frame()) return sender_for_interpreter_frame(map);
   assert(_cb == CodeCache::find_blob(pc()),"Must be the same");
-  if (is_ricochet_frame())    return sender_for_ricochet_frame(map);
 
   if (_cb != NULL) {
     return sender_for_compiled_frame(map);
@@ -658,9 +656,7 @@
   values.describe(frame_no, fp() + frame::name##_offset, #name)
 
 void frame::describe_pd(FrameValues& values, int frame_no) {
-  if (is_ricochet_frame()) {
-    MethodHandles::RicochetFrame::describe(this, values, frame_no);
-  } else if (is_interpreted_frame()) {
+  if (is_interpreted_frame()) {
     DESCRIBE_FP_OFFSET(interpreter_frame_sender_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_last_sp);
     DESCRIBE_FP_OFFSET(interpreter_frame_method);
@@ -682,12 +678,7 @@
   if (_cb != NULL) {
     // use the frame size if valid
     int size = _cb->frame_size();
-    if ((size > 0) &&
-        (! is_ricochet_frame())) {
-      // Work-around: ricochet explicitly excluded because frame size is not
-      // constant for the ricochet blob but its frame_size could not, for
-      // some reasons, be declared as <= 0. This potentially confusing
-      // size declaration should be fixed as another CR.
+    if (size > 0) {
       return unextended_sp() + size;
     }
   }
diff --git a/hotspot/src/cpu/x86/vm/globals_x86.hpp b/hotspot/src/cpu/x86/vm/globals_x86.hpp
index 1d0ef81d..8d1cdfa 100644
--- a/hotspot/src/cpu/x86/vm/globals_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/globals_x86.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,4 +78,53 @@
 
 // GC Ergo Flags
 define_pd_global(intx, CMSYoungGenPerWorker, 64*M);  // default max size of CMS young gen, per GC worker thread
+
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct) \
+                                                                            \
+  develop(bool, IEEEPrecision, true,                                        \
+          "Enables IEEE precision (for INTEL only)")                        \
+                                                                            \
+  product(intx, FenceInstruction, 0,                                        \
+          "(Unsafe,Unstable) Experimental")                                 \
+                                                                            \
+  product(intx,  ReadPrefetchInstr, 0,                                      \
+          "Prefetch instruction to prefetch ahead")                         \
+                                                                            \
+  product(bool, UseStoreImmI16, true,                                       \
+          "Use store immediate 16-bits value instruction on x86")           \
+                                                                            \
+  product(intx, UseAVX, 99,                                                 \
+          "Highest supported AVX instructions set on x86/x64")              \
+                                                                            \
+  diagnostic(bool, UseIncDec, true,                                         \
+          "Use INC, DEC instructions on x86")                               \
+                                                                            \
+  product(bool, UseNewLongLShift, false,                                    \
+          "Use optimized bitwise shift left")                               \
+                                                                            \
+  product(bool, UseAddressNop, false,                                       \
+          "Use '0F 1F [addr]' NOP instructions on x86 cpus")                \
+                                                                            \
+  product(bool, UseXmmLoadAndClearUpper, true,                              \
+          "Load low part of XMM register and clear upper part")             \
+                                                                            \
+  product(bool, UseXmmRegToRegMoveAll, false,                               \
+          "Copy all XMM register bits when moving value between registers") \
+                                                                            \
+  product(bool, UseXmmI2D, false,                                           \
+          "Use SSE2 CVTDQ2PD instruction to convert Integer to Double")     \
+                                                                            \
+  product(bool, UseXmmI2F, false,                                           \
+          "Use SSE2 CVTDQ2PS instruction to convert Integer to Float")      \
+                                                                            \
+  product(bool, UseUnalignedLoadStores, false,                              \
+          "Use SSE2 MOVDQU instruction for Arraycopy")                      \
+                                                                            \
+  /* assembler */                                                           \
+  product(bool, Use486InstrsOnly, false,                                    \
+          "Use 80486 Compliant instruction subset")                         \
+                                                                            \
+  product(bool, UseCountLeadingZerosInstruction, false,                     \
+          "Use count leading zeros instruction")                            \
+
 #endif // CPU_X86_VM_GLOBALS_X86_HPP
diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
index f06d54e..b0ebcfd 100644
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.cpp
@@ -253,8 +253,12 @@
   get_cache_and_index_at_bcp(cache, index, bcp_offset, index_size);
   movptr(bytecode, Address(cache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
   const int shift_count = (1 + byte_no) * BitsPerByte;
+  assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) ||
+         (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift),
+         "correct shift count");
   shrptr(bytecode, shift_count);
-  andptr(bytecode, 0xFF);
+  assert(ConstantPoolCacheEntry::bytecode_1_mask == ConstantPoolCacheEntry::bytecode_2_mask, "common mask");
+  andptr(bytecode, ConstantPoolCacheEntry::bytecode_1_mask);
 }
 
 
diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp
index 97f1da4..4583257 100644
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_32.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -77,7 +77,8 @@
 
   // Helpers for runtime call arguments/results
   void get_method(Register reg)                            { movptr(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize)); }
-  void get_constant_pool(Register reg)                     { get_method(reg); movptr(reg, Address(reg, methodOopDesc::constants_offset())); }
+  void get_const(Register reg)                             { get_method(reg); movptr(reg, Address(reg, methodOopDesc::const_offset())); }
+  void get_constant_pool(Register reg)                     { get_const(reg); movptr(reg, Address(reg, constMethodOopDesc::constants_offset())); }
   void get_constant_pool_cache(Register reg)               { get_constant_pool(reg); movptr(reg, Address(reg, constantPoolOopDesc::cache_offset_in_bytes())); }
   void get_cpool_and_tags(Register cpool, Register tags)   { get_constant_pool(cpool); movptr(tags, Address(cpool, constantPoolOopDesc::tags_offset_in_bytes()));
   }
diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
index e418436..2790c2a 100644
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.cpp
@@ -256,8 +256,12 @@
   // little-endian machines allow us that.
   movl(bytecode, Address(cache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::indices_offset()));
   const int shift_count = (1 + byte_no) * BitsPerByte;
+  assert((byte_no == TemplateTable::f1_byte && shift_count == ConstantPoolCacheEntry::bytecode_1_shift) ||
+         (byte_no == TemplateTable::f2_byte && shift_count == ConstantPoolCacheEntry::bytecode_2_shift),
+         "correct shift count");
   shrl(bytecode, shift_count);
-  andl(bytecode, 0xFF);
+  assert(ConstantPoolCacheEntry::bytecode_1_mask == ConstantPoolCacheEntry::bytecode_2_mask, "common mask");
+  andl(bytecode, ConstantPoolCacheEntry::bytecode_1_mask);
 }
 
 
diff --git a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp
index cb17e01..8486c34 100644
--- a/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp
+++ b/hotspot/src/cpu/x86/vm/interp_masm_x86_64.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -84,9 +84,14 @@
     movptr(reg, Address(rbp, frame::interpreter_frame_method_offset * wordSize));
   }
 
-  void get_constant_pool(Register reg) {
+  void get_const(Register reg) {
     get_method(reg);
-    movptr(reg, Address(reg, methodOopDesc::constants_offset()));
+    movptr(reg, Address(reg, methodOopDesc::const_offset()));
+  }
+
+  void get_constant_pool(Register reg) {
+    get_const(reg);
+    movptr(reg, Address(reg, constMethodOopDesc::constants_offset()));
   }
 
   void get_constant_pool_cache(Register reg) {
diff --git a/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp b/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp
index 3004865..9a05821 100644
--- a/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/interpreterGenerator_x86.hpp
@@ -35,7 +35,6 @@
   address generate_normal_entry(bool synchronized);
   address generate_native_entry(bool synchronized);
   address generate_abstract_entry(void);
-  address generate_method_handle_entry(void);
   address generate_math_entry(AbstractInterpreter::MethodKind kind);
   address generate_empty_entry(void);
   address generate_accessor_entry(void);
diff --git a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp
index 43a5a18..ddc4e61 100644
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_32.cpp
@@ -181,6 +181,19 @@
         __ push_fTOS();
         __ pop_fTOS();
         break;
+    case Interpreter::java_lang_math_pow:
+      __ fld_d(Address(rsp, 3*wordSize)); // second argument
+      __ pow_with_fallback(0);
+      // Store to stack to convert 80bit precision back to 64bits
+      __ push_fTOS();
+      __ pop_fTOS();
+      break;
+    case Interpreter::java_lang_math_exp:
+      __ exp_with_fallback(0);
+      // Store to stack to convert 80bit precision back to 64bits
+      __ push_fTOS();
+      __ pop_fTOS();
+      break;
     default                              :
         ShouldNotReachHere();
   }
@@ -230,18 +243,6 @@
 }
 
 
-// Method handle invoker
-// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
-address InterpreterGenerator::generate_method_handle_entry(void) {
-  if (!EnableInvokeDynamic) {
-    return generate_abstract_entry();
-  }
-
-  address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm);
-
-  return entry_point;
-}
-
 void Deoptimization::unwind_callee_save_values(frame* f, vframeArray* vframe_array) {
 
   // This code is sort of the equivalent of C2IAdapter::setup_stack_frame back in
diff --git a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp
index 1c124c2..e86c13c 100644
--- a/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/interpreter_x86_64.cpp
@@ -271,6 +271,14 @@
       case Interpreter::java_lang_math_log10:
           __ flog10();
           break;
+      case Interpreter::java_lang_math_pow:
+          __ fld_d(Address(rsp, 3*wordSize)); // second argument (one
+                                              // empty stack slot)
+          __ pow_with_fallback(0);
+          break;
+      case Interpreter::java_lang_math_exp:
+          __ exp_with_fallback(0);
+           break;
       default                              :
           ShouldNotReachHere();
     }
@@ -317,19 +325,6 @@
 }
 
 
-// Method handle invoker
-// Dispatch a method of the form java.lang.invoke.MethodHandles::invoke(...)
-address InterpreterGenerator::generate_method_handle_entry(void) {
-  if (!EnableInvokeDynamic) {
-    return generate_abstract_entry();
-  }
-
-  address entry_point = MethodHandles::generate_method_handle_interpreter_entry(_masm);
-
-  return entry_point;
-}
-
-
 // Empty method, generate a very fast return.
 
 address InterpreterGenerator::generate_empty_entry(void) {
diff --git a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp
index 29bffcf..130c053 100644
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.cpp
@@ -32,8 +32,10 @@
 
 #ifdef PRODUCT
 #define BLOCK_COMMENT(str) /* nothing */
+#define STOP(error) stop(error)
 #else
 #define BLOCK_COMMENT(str) __ block_comment(str)
+#define STOP(error) block_comment(error); __ stop(error)
 #endif
 
 #define BIND(label) bind(label); BLOCK_COMMENT(#label ":")
@@ -43,483 +45,24 @@
   return RegisterOrConstant(value);
 }
 
-address MethodHandleEntry::start_compiled_entry(MacroAssembler* _masm,
-                                                address interpreted_entry) {
-  // Just before the actual machine code entry point, allocate space
-  // for a MethodHandleEntry::Data record, so that we can manage everything
-  // from one base pointer.
-  __ align(wordSize);
-  address target = __ pc() + sizeof(Data);
-  while (__ pc() < target) {
-    __ nop();
-    __ align(wordSize);
-  }
-
-  MethodHandleEntry* me = (MethodHandleEntry*) __ pc();
-  me->set_end_address(__ pc());         // set a temporary end_address
-  me->set_from_interpreted_entry(interpreted_entry);
-  me->set_type_checking_entry(NULL);
-
-  return (address) me;
-}
-
-MethodHandleEntry* MethodHandleEntry::finish_compiled_entry(MacroAssembler* _masm,
-                                                address start_addr) {
-  MethodHandleEntry* me = (MethodHandleEntry*) start_addr;
-  assert(me->end_address() == start_addr, "valid ME");
-
-  // Fill in the real end_address:
-  __ align(wordSize);
-  me->set_end_address(__ pc());
-
-  return me;
-}
-
-// stack walking support
-
-frame MethodHandles::ricochet_frame_sender(const frame& fr, RegisterMap *map) {
-  RicochetFrame* f = RicochetFrame::from_frame(fr);
-  if (map->update_map())
-    frame::update_map_with_saved_link(map, &f->_sender_link);
-  return frame(f->extended_sender_sp(), f->exact_sender_sp(), f->sender_link(), f->sender_pc());
-}
-
-void MethodHandles::ricochet_frame_oops_do(const frame& fr, OopClosure* blk, const RegisterMap* reg_map) {
-  RicochetFrame* f = RicochetFrame::from_frame(fr);
-
-  // pick up the argument type descriptor:
-  Thread* thread = Thread::current();
-  Handle cookie(thread, f->compute_saved_args_layout(true, true));
-
-  // process fixed part
-  blk->do_oop((oop*)f->saved_target_addr());
-  blk->do_oop((oop*)f->saved_args_layout_addr());
-
-  // process variable arguments:
-  if (cookie.is_null())  return;  // no arguments to describe
-
-  // the cookie is actually the invokeExact method for my target
-  // his argument signature is what I'm interested in
-  assert(cookie->is_method(), "");
-  methodHandle invoker(thread, methodOop(cookie()));
-  assert(invoker->name() == vmSymbols::invokeExact_name(), "must be this kind of method");
-  assert(!invoker->is_static(), "must have MH argument");
-  int slot_count = invoker->size_of_parameters();
-  assert(slot_count >= 1, "must include 'this'");
-  intptr_t* base = f->saved_args_base();
-  intptr_t* retval = NULL;
-  if (f->has_return_value_slot())
-    retval = f->return_value_slot_addr();
-  int slot_num = slot_count;
-  intptr_t* loc = &base[slot_num -= 1];
-  //blk->do_oop((oop*) loc);   // original target, which is irrelevant
-  int arg_num = 0;
-  for (SignatureStream ss(invoker->signature()); !ss.is_done(); ss.next()) {
-    if (ss.at_return_type())  continue;
-    BasicType ptype = ss.type();
-    if (ptype == T_ARRAY)  ptype = T_OBJECT; // fold all refs to T_OBJECT
-    assert(ptype >= T_BOOLEAN && ptype <= T_OBJECT, "not array or void");
-    loc = &base[slot_num -= type2size[ptype]];
-    bool is_oop = (ptype == T_OBJECT && loc != retval);
-    if (is_oop)  blk->do_oop((oop*)loc);
-    arg_num += 1;
-  }
-  assert(slot_num == 0, "must have processed all the arguments");
-}
-
-oop MethodHandles::RicochetFrame::compute_saved_args_layout(bool read_cache, bool write_cache) {
-  oop cookie = NULL;
-  if (read_cache) {
-    cookie = saved_args_layout();
-    if (cookie != NULL)  return cookie;
-  }
-  oop target = saved_target();
-  oop mtype  = java_lang_invoke_MethodHandle::type(target);
-  oop mtform = java_lang_invoke_MethodType::form(mtype);
-  cookie = java_lang_invoke_MethodTypeForm::vmlayout(mtform);
-  if (write_cache)  {
-    (*saved_args_layout_addr()) = cookie;
-  }
-  return cookie;
-}
-
-void MethodHandles::RicochetFrame::generate_ricochet_blob(MacroAssembler* _masm,
-                                                          // output params:
-                                                          int* bounce_offset,
-                                                          int* exception_offset,
-                                                          int* frame_size_in_words) {
-  (*frame_size_in_words) = RicochetFrame::frame_size_in_bytes() / wordSize;
-
-  address start = __ pc();
-
-#ifdef ASSERT
-  __ hlt(); __ hlt(); __ hlt();
-  // here's a hint of something special:
-  __ push(MAGIC_NUMBER_1);
-  __ push(MAGIC_NUMBER_2);
-#endif //ASSERT
-  __ hlt();  // not reached
-
-  // A return PC has just been popped from the stack.
-  // Return values are in registers.
-  // The ebp points into the RicochetFrame, which contains
-  // a cleanup continuation we must return to.
-
-  (*bounce_offset) = __ pc() - start;
-  BLOCK_COMMENT("ricochet_blob.bounce");
-
-  if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
-  trace_method_handle(_masm, "return/ricochet_blob.bounce");
-
-  __ jmp(frame_address(continuation_offset_in_bytes()));
-  __ hlt();
-  DEBUG_ONLY(__ push(MAGIC_NUMBER_2));
-
-  (*exception_offset) = __ pc() - start;
-  BLOCK_COMMENT("ricochet_blob.exception");
-
-  // compare this to Interpreter::rethrow_exception_entry, which is parallel code
-  // for example, see TemplateInterpreterGenerator::generate_throw_exception
-  // Live registers in:
-  //   rax: exception
-  //   rdx: return address/pc that threw exception (ignored, always equal to bounce addr)
-  __ verify_oop(rax);
-
-  // no need to empty_FPU_stack or reinit_heapbase, since caller frame will do the same if needed
-
-  // Take down the frame.
-
-  // Cf. InterpreterMacroAssembler::remove_activation.
-  leave_ricochet_frame(_masm, /*rcx_recv=*/ noreg,
-                       saved_last_sp_register(),
-                       /*sender_pc_reg=*/ rdx);
-
-  // In between activations - previous activation type unknown yet
-  // compute continuation point - the continuation point expects the
-  // following registers set up:
-  //
-  // rax: exception
-  // rdx: return address/pc that threw exception
-  // rsp: expression stack of caller
-  // rbp: ebp of caller
-  __ push(rax);                                  // save exception
-  __ push(rdx);                                  // save return address
-  Register thread_reg = LP64_ONLY(r15_thread) NOT_LP64(rdi);
-  NOT_LP64(__ get_thread(thread_reg));
-  __ call_VM_leaf(CAST_FROM_FN_PTR(address,
-                                   SharedRuntime::exception_handler_for_return_address),
-                  thread_reg, rdx);
-  __ mov(rbx, rax);                              // save exception handler
-  __ pop(rdx);                                   // restore return address
-  __ pop(rax);                                   // restore exception
-  __ jmp(rbx);                                   // jump to exception
-                                                 // handler of caller
-}
-
-void MethodHandles::RicochetFrame::enter_ricochet_frame(MacroAssembler* _masm,
-                                                        Register rcx_recv,
-                                                        Register rax_argv,
-                                                        address return_handler,
-                                                        Register rbx_temp) {
-  const Register saved_last_sp = saved_last_sp_register();
-  Address rcx_mh_vmtarget(    rcx_recv, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes() );
-  Address rcx_amh_conversion( rcx_recv, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes() );
-
-  // Push the RicochetFrame a word at a time.
-  // This creates something similar to an interpreter frame.
-  // Cf. TemplateInterpreterGenerator::generate_fixed_frame.
-  BLOCK_COMMENT("push RicochetFrame {");
-  DEBUG_ONLY(int rfo = (int) sizeof(RicochetFrame));
-  assert((rfo -= wordSize) == RicochetFrame::sender_pc_offset_in_bytes(), "");
-#define RF_FIELD(push_value, name)                                      \
-  { push_value;                                                         \
-    assert((rfo -= wordSize) == RicochetFrame::name##_offset_in_bytes(), ""); }
-  RF_FIELD(__ push(rbp),                   sender_link);
-  RF_FIELD(__ push(saved_last_sp),         exact_sender_sp);  // rsi/r13
-  RF_FIELD(__ pushptr(rcx_amh_conversion), conversion);
-  RF_FIELD(__ push(rax_argv),              saved_args_base);   // can be updated if args are shifted
-  RF_FIELD(__ push((int32_t) NULL_WORD),   saved_args_layout); // cache for GC layout cookie
-  if (UseCompressedOops) {
-    __ load_heap_oop(rbx_temp, rcx_mh_vmtarget);
-    RF_FIELD(__ push(rbx_temp),            saved_target);
-  } else {
-    RF_FIELD(__ pushptr(rcx_mh_vmtarget),  saved_target);
-  }
-  __ lea(rbx_temp, ExternalAddress(return_handler));
-  RF_FIELD(__ push(rbx_temp),              continuation);
-#undef RF_FIELD
-  assert(rfo == 0, "fully initialized the RicochetFrame");
-  // compute new frame pointer:
-  __ lea(rbp, Address(rsp, RicochetFrame::sender_link_offset_in_bytes()));
-  // Push guard word #1 in debug mode.
-  DEBUG_ONLY(__ push((int32_t) RicochetFrame::MAGIC_NUMBER_1));
-  // For debugging, leave behind an indication of which stub built this frame.
-  DEBUG_ONLY({ Label L; __ call(L, relocInfo::none); __ bind(L); });
-  BLOCK_COMMENT("} RicochetFrame");
-}
-
-void MethodHandles::RicochetFrame::leave_ricochet_frame(MacroAssembler* _masm,
-                                                        Register rcx_recv,
-                                                        Register new_sp_reg,
-                                                        Register sender_pc_reg) {
-  assert_different_registers(rcx_recv, new_sp_reg, sender_pc_reg);
-  const Register saved_last_sp = saved_last_sp_register();
-  // Take down the frame.
-  // Cf. InterpreterMacroAssembler::remove_activation.
-  BLOCK_COMMENT("end_ricochet_frame {");
-  // TO DO: If (exact_sender_sp - extended_sender_sp) > THRESH, compact the frame down.
-  // This will keep stack in bounds even with unlimited tailcalls, each with an adapter.
-  if (rcx_recv->is_valid())
-    __ movptr(rcx_recv,    RicochetFrame::frame_address(RicochetFrame::saved_target_offset_in_bytes()));
-  __ movptr(sender_pc_reg, RicochetFrame::frame_address(RicochetFrame::sender_pc_offset_in_bytes()));
-  __ movptr(saved_last_sp, RicochetFrame::frame_address(RicochetFrame::exact_sender_sp_offset_in_bytes()));
-  __ movptr(rbp,           RicochetFrame::frame_address(RicochetFrame::sender_link_offset_in_bytes()));
-  __ mov(rsp, new_sp_reg);
-  BLOCK_COMMENT("} end_ricochet_frame");
-}
-
-// Emit code to verify that RBP is pointing at a valid ricochet frame.
-#ifndef PRODUCT
-enum {
-  ARG_LIMIT = 255, SLOP = 4,
-  // use this parameter for checking for garbage stack movements:
-  UNREASONABLE_STACK_MOVE = (ARG_LIMIT + SLOP)
-  // the slop defends against false alarms due to fencepost errors
-};
-#endif
-
-#ifdef ASSERT
-void MethodHandles::RicochetFrame::verify_clean(MacroAssembler* _masm) {
-  // The stack should look like this:
-  //    ... keep1 | dest=42 | keep2 | RF | magic | handler | magic | recursive args |
-  // Check various invariants.
-  verify_offsets();
-
-  Register rdi_temp = rdi;
-  Register rcx_temp = rcx;
-  { __ push(rdi_temp); __ push(rcx_temp); }
-#define UNPUSH_TEMPS \
-  { __ pop(rcx_temp);  __ pop(rdi_temp); }
-
-  Address magic_number_1_addr  = RicochetFrame::frame_address(RicochetFrame::magic_number_1_offset_in_bytes());
-  Address magic_number_2_addr  = RicochetFrame::frame_address(RicochetFrame::magic_number_2_offset_in_bytes());
-  Address continuation_addr    = RicochetFrame::frame_address(RicochetFrame::continuation_offset_in_bytes());
-  Address conversion_addr      = RicochetFrame::frame_address(RicochetFrame::conversion_offset_in_bytes());
-  Address saved_args_base_addr = RicochetFrame::frame_address(RicochetFrame::saved_args_base_offset_in_bytes());
-
-  Label L_bad, L_ok;
-  BLOCK_COMMENT("verify_clean {");
-  // Magic numbers must check out:
-  __ cmpptr(magic_number_1_addr, (int32_t) MAGIC_NUMBER_1);
-  __ jcc(Assembler::notEqual, L_bad);
-  __ cmpptr(magic_number_2_addr, (int32_t) MAGIC_NUMBER_2);
-  __ jcc(Assembler::notEqual, L_bad);
-
-  // Arguments pointer must look reasonable:
-  __ movptr(rcx_temp, saved_args_base_addr);
-  __ cmpptr(rcx_temp, rbp);
-  __ jcc(Assembler::below, L_bad);
-  __ subptr(rcx_temp, UNREASONABLE_STACK_MOVE * Interpreter::stackElementSize);
-  __ cmpptr(rcx_temp, rbp);
-  __ jcc(Assembler::above, L_bad);
-
-  load_conversion_dest_type(_masm, rdi_temp, conversion_addr);
-  __ cmpl(rdi_temp, T_VOID);
-  __ jcc(Assembler::equal, L_ok);
-  __ movptr(rcx_temp, saved_args_base_addr);
-  load_conversion_vminfo(_masm, rdi_temp, conversion_addr);
-  __ cmpptr(Address(rcx_temp, rdi_temp, Interpreter::stackElementScale()),
-            (int32_t) RETURN_VALUE_PLACEHOLDER);
-  __ jcc(Assembler::equal, L_ok);
-  __ BIND(L_bad);
-  UNPUSH_TEMPS;
-  __ stop("damaged ricochet frame");
-  __ BIND(L_ok);
-  UNPUSH_TEMPS;
-  BLOCK_COMMENT("} verify_clean");
-
-#undef UNPUSH_TEMPS
-
-}
-#endif //ASSERT
-
 void MethodHandles::load_klass_from_Class(MacroAssembler* _masm, Register klass_reg) {
   if (VerifyMethodHandles)
     verify_klass(_masm, klass_reg, SystemDictionaryHandles::Class_klass(),
-                 "AMH argument is a Class");
+                 "MH argument is a Class");
   __ load_heap_oop(klass_reg, Address(klass_reg, java_lang_Class::klass_offset_in_bytes()));
 }
 
-void MethodHandles::load_conversion_vminfo(MacroAssembler* _masm, Register reg, Address conversion_field_addr) {
-  int bits   = BitsPerByte;
-  int offset = (CONV_VMINFO_SHIFT / bits);
-  int shift  = (CONV_VMINFO_SHIFT % bits);
-  __ load_unsigned_byte(reg, conversion_field_addr.plus_disp(offset));
-  assert(CONV_VMINFO_MASK == right_n_bits(bits - shift), "else change type of previous load");
-  assert(shift == 0, "no shift needed");
-}
-
-void MethodHandles::load_conversion_dest_type(MacroAssembler* _masm, Register reg, Address conversion_field_addr) {
-  int bits   = BitsPerByte;
-  int offset = (CONV_DEST_TYPE_SHIFT / bits);
-  int shift  = (CONV_DEST_TYPE_SHIFT % bits);
-  __ load_unsigned_byte(reg, conversion_field_addr.plus_disp(offset));
-  assert(CONV_TYPE_MASK == right_n_bits(bits - shift), "else change type of previous load");
-  __ shrl(reg, shift);
-  DEBUG_ONLY(int conv_type_bits = (int) exact_log2(CONV_TYPE_MASK+1));
-  assert((shift + conv_type_bits) == bits, "left justified in byte");
-}
-
-void MethodHandles::load_stack_move(MacroAssembler* _masm,
-                                    Register rdi_stack_move,
-                                    Register rcx_amh,
-                                    bool might_be_negative) {
-  BLOCK_COMMENT("load_stack_move {");
-  Address rcx_amh_conversion(rcx_amh, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes());
-  __ movl(rdi_stack_move, rcx_amh_conversion);
-  __ sarl(rdi_stack_move, CONV_STACK_MOVE_SHIFT);
-#ifdef _LP64
-  if (might_be_negative) {
-    // clean high bits of stack motion register (was loaded as an int)
-    __ movslq(rdi_stack_move, rdi_stack_move);
-  }
-#endif //_LP64
 #ifdef ASSERT
-  if (VerifyMethodHandles) {
-    Label L_ok, L_bad;
-    int32_t stack_move_limit = 0x4000;  // extra-large
-    __ cmpptr(rdi_stack_move, stack_move_limit);
-    __ jcc(Assembler::greaterEqual, L_bad);
-    __ cmpptr(rdi_stack_move, -stack_move_limit);
-    __ jcc(Assembler::greater, L_ok);
-    __ bind(L_bad);
-    __ stop("load_stack_move of garbage value");
-    __ BIND(L_ok);
-  }
-#endif
-  BLOCK_COMMENT("} load_stack_move");
+static int check_nonzero(const char* xname, int x) {
+  assert(x != 0, err_msg("%s should be nonzero", xname));
+  return x;
 }
+#define NONZERO(x) check_nonzero(#x, x)
+#else //ASSERT
+#define NONZERO(x) (x)
+#endif //ASSERT
 
 #ifdef ASSERT
-void MethodHandles::RicochetFrame::verify_offsets() {
-  // Check compatibility of this struct with the more generally used offsets of class frame:
-  int ebp_off = sender_link_offset_in_bytes();  // offset from struct base to local rbp value
-  assert(ebp_off + wordSize*frame::interpreter_frame_method_offset      == saved_args_base_offset_in_bytes(), "");
-  assert(ebp_off + wordSize*frame::interpreter_frame_last_sp_offset     == conversion_offset_in_bytes(), "");
-  assert(ebp_off + wordSize*frame::interpreter_frame_sender_sp_offset   == exact_sender_sp_offset_in_bytes(), "");
-  // These last two have to be exact:
-  assert(ebp_off + wordSize*frame::link_offset                          == sender_link_offset_in_bytes(), "");
-  assert(ebp_off + wordSize*frame::return_addr_offset                   == sender_pc_offset_in_bytes(), "");
-}
-
-void MethodHandles::RicochetFrame::verify() const {
-  verify_offsets();
-  assert(magic_number_1() == MAGIC_NUMBER_1, err_msg(PTR_FORMAT " == " PTR_FORMAT, magic_number_1(), MAGIC_NUMBER_1));
-  assert(magic_number_2() == MAGIC_NUMBER_2, err_msg(PTR_FORMAT " == " PTR_FORMAT, magic_number_2(), MAGIC_NUMBER_2));
-  if (!Universe::heap()->is_gc_active()) {
-    if (saved_args_layout() != NULL) {
-      assert(saved_args_layout()->is_method(), "must be valid oop");
-    }
-    if (saved_target() != NULL) {
-      assert(java_lang_invoke_MethodHandle::is_instance(saved_target()), "checking frame value");
-    }
-  }
-  int conv_op = adapter_conversion_op(conversion());
-  assert(conv_op == java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS ||
-         conv_op == java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS ||
-         conv_op == java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF,
-         "must be a sane conversion");
-  if (has_return_value_slot()) {
-    assert(*return_value_slot_addr() == RETURN_VALUE_PLACEHOLDER, "");
-  }
-}
-#endif //PRODUCT
-
-#ifdef ASSERT
-void MethodHandles::verify_argslot(MacroAssembler* _masm,
-                                   Register argslot_reg,
-                                   const char* error_message) {
-  // Verify that argslot lies within (rsp, rbp].
-  Label L_ok, L_bad;
-  BLOCK_COMMENT("verify_argslot {");
-  __ cmpptr(argslot_reg, rbp);
-  __ jccb(Assembler::above, L_bad);
-  __ cmpptr(rsp, argslot_reg);
-  __ jccb(Assembler::below, L_ok);
-  __ bind(L_bad);
-  __ stop(error_message);
-  __ BIND(L_ok);
-  BLOCK_COMMENT("} verify_argslot");
-}
-
-void MethodHandles::verify_argslots(MacroAssembler* _masm,
-                                    RegisterOrConstant arg_slots,
-                                    Register arg_slot_base_reg,
-                                    bool negate_argslots,
-                                    const char* error_message) {
-  // Verify that [argslot..argslot+size) lies within (rsp, rbp).
-  Label L_ok, L_bad;
-  Register rdi_temp = rdi;
-  BLOCK_COMMENT("verify_argslots {");
-  __ push(rdi_temp);
-  if (negate_argslots) {
-    if (arg_slots.is_constant()) {
-      arg_slots = -1 * arg_slots.as_constant();
-    } else {
-      __ movptr(rdi_temp, arg_slots);
-      __ negptr(rdi_temp);
-      arg_slots = rdi_temp;
-    }
-  }
-  __ lea(rdi_temp, Address(arg_slot_base_reg, arg_slots, Interpreter::stackElementScale()));
-  __ cmpptr(rdi_temp, rbp);
-  __ pop(rdi_temp);
-  __ jcc(Assembler::above, L_bad);
-  __ cmpptr(rsp, arg_slot_base_reg);
-  __ jcc(Assembler::below, L_ok);
-  __ bind(L_bad);
-  __ stop(error_message);
-  __ BIND(L_ok);
-  BLOCK_COMMENT("} verify_argslots");
-}
-
-// Make sure that arg_slots has the same sign as the given direction.
-// If (and only if) arg_slots is a assembly-time constant, also allow it to be zero.
-void MethodHandles::verify_stack_move(MacroAssembler* _masm,
-                                      RegisterOrConstant arg_slots, int direction) {
-  bool allow_zero = arg_slots.is_constant();
-  if (direction == 0) { direction = +1; allow_zero = true; }
-  assert(stack_move_unit() == -1, "else add extra checks here");
-  if (arg_slots.is_register()) {
-    Label L_ok, L_bad;
-    BLOCK_COMMENT("verify_stack_move {");
-    // testl(arg_slots.as_register(), -stack_move_unit() - 1);  // no need
-    // jcc(Assembler::notZero, L_bad);
-    __ cmpptr(arg_slots.as_register(), (int32_t) NULL_WORD);
-    if (direction > 0) {
-      __ jcc(allow_zero ? Assembler::less : Assembler::lessEqual, L_bad);
-      __ cmpptr(arg_slots.as_register(), (int32_t) UNREASONABLE_STACK_MOVE);
-      __ jcc(Assembler::less, L_ok);
-    } else {
-      __ jcc(allow_zero ? Assembler::greater : Assembler::greaterEqual, L_bad);
-      __ cmpptr(arg_slots.as_register(), (int32_t) -UNREASONABLE_STACK_MOVE);
-      __ jcc(Assembler::greater, L_ok);
-    }
-    __ bind(L_bad);
-    if (direction > 0)
-      __ stop("assert arg_slots > 0");
-    else
-      __ stop("assert arg_slots < 0");
-    __ BIND(L_ok);
-    BLOCK_COMMENT("} verify_stack_move");
-  } else {
-    intptr_t size = arg_slots.as_constant();
-    if (direction < 0)  size = -size;
-    assert(size >= 0, "correct direction of constant move");
-    assert(size < UNREASONABLE_STACK_MOVE, "reasonable size of constant move");
-  }
-}
-
 void MethodHandles::verify_klass(MacroAssembler* _masm,
                                  Register obj, KlassHandle klass,
                                  const char* error_message) {
@@ -528,12 +71,15 @@
          klass_addr <= SystemDictionaryHandles::Long_klass().raw_value(),
          "must be one of the SystemDictionaryHandles");
   Register temp = rdi;
+  Register temp2 = noreg;
+  LP64_ONLY(temp2 = rscratch1);  // used by MacroAssembler::cmpptr
   Label L_ok, L_bad;
   BLOCK_COMMENT("verify_klass {");
   __ verify_oop(obj);
   __ testptr(obj, obj);
   __ jcc(Assembler::zero, L_bad);
-  __ push(temp);
+  __ push(temp); if (temp2 != noreg)  __ push(temp2);
+#define UNPUSH { if (temp2 != noreg)  __ pop(temp2);  __ pop(temp); }
   __ load_klass(temp, obj);
   __ cmpptr(temp, ExternalAddress((address) klass_addr));
   __ jcc(Assembler::equal, L_ok);
@@ -541,17 +87,42 @@
   __ movptr(temp, Address(temp, super_check_offset));
   __ cmpptr(temp, ExternalAddress((address) klass_addr));
   __ jcc(Assembler::equal, L_ok);
-  __ pop(temp);
+  UNPUSH;
   __ bind(L_bad);
-  __ stop(error_message);
+  __ STOP(error_message);
   __ BIND(L_ok);
-  __ pop(temp);
+  UNPUSH;
   BLOCK_COMMENT("} verify_klass");
 }
+
+void MethodHandles::verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) {
+  Label L;
+  BLOCK_COMMENT("verify_ref_kind {");
+  __ movl(temp, Address(member_reg, NONZERO(java_lang_invoke_MemberName::flags_offset_in_bytes())));
+  __ shrl(temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT);
+  __ andl(temp, java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK);
+  __ cmpl(temp, ref_kind);
+  __ jcc(Assembler::equal, L);
+  { char* buf = NEW_C_HEAP_ARRAY(char, 100, mtInternal);
+    jio_snprintf(buf, 100, "verify_ref_kind expected %x", ref_kind);
+    if (ref_kind == JVM_REF_invokeVirtual ||
+        ref_kind == JVM_REF_invokeSpecial)
+      // could do this for all ref_kinds, but would explode assembly code size
+      trace_method_handle(_masm, buf);
+    __ STOP(buf);
+  }
+  BLOCK_COMMENT("} verify_ref_kind");
+  __ bind(L);
+}
+
 #endif //ASSERT
 
-void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp) {
-  if (JvmtiExport::can_post_interpreter_events()) {
+void MethodHandles::jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
+                                            bool for_compiler_entry) {
+  assert(method == rbx, "interpreter calling convention");
+  __ verify_oop(method);
+
+  if (!for_compiler_entry && JvmtiExport::can_post_interpreter_events()) {
     Label run_compiled_code;
     // JVMTI events, such as single-stepping, are implemented partly by avoiding running
     // compiled code in threads for which the event is enabled.  Check here for
@@ -567,470 +138,349 @@
     __ cmpb(Address(rthread, JavaThread::interp_only_mode_offset()), 0);
     __ jccb(Assembler::zero, run_compiled_code);
     __ jmp(Address(method, methodOopDesc::interpreter_entry_offset()));
-    __ bind(run_compiled_code);
+    __ BIND(run_compiled_code);
   }
-  __ jmp(Address(method, methodOopDesc::from_interpreted_offset()));
+
+  const ByteSize entry_offset = for_compiler_entry ? methodOopDesc::from_compiled_offset() :
+                                                     methodOopDesc::from_interpreted_offset();
+  __ jmp(Address(method, entry_offset));
 }
 
+void MethodHandles::jump_to_lambda_form(MacroAssembler* _masm,
+                                        Register recv, Register method_temp,
+                                        Register temp2,
+                                        bool for_compiler_entry) {
+  BLOCK_COMMENT("jump_to_lambda_form {");
+  // This is the initial entry point of a lazy method handle.
+  // After type checking, it picks up the invoker from the LambdaForm.
+  assert_different_registers(recv, method_temp, temp2);
+  assert(recv != noreg, "required register");
+  assert(method_temp == rbx, "required register for loading method");
+
+  //NOT_PRODUCT({ FlagSetting fs(TraceMethodHandles, true); trace_method_handle(_masm, "LZMH"); });
+
+  // Load the invoker, as MH -> MH.form -> LF.vmentry
+  __ verify_oop(recv);
+  __ load_heap_oop(method_temp, Address(recv, NONZERO(java_lang_invoke_MethodHandle::form_offset_in_bytes())));
+  __ verify_oop(method_temp);
+  __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_LambdaForm::vmentry_offset_in_bytes())));
+  __ verify_oop(method_temp);
+  // the following assumes that a methodOop is normally compressed in the vmtarget field:
+  __ load_heap_oop(method_temp, Address(method_temp, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes())));
+  __ verify_oop(method_temp);
+
+  if (VerifyMethodHandles && !for_compiler_entry) {
+    // make sure recv is already on stack
+    __ load_sized_value(temp2,
+                        Address(method_temp, methodOopDesc::size_of_parameters_offset()),
+                        sizeof(u2), /*is_signed*/ false);
+    // assert(sizeof(u2) == sizeof(methodOopDesc::_size_of_parameters), "");
+    Label L;
+    __ cmpptr(recv, __ argument_address(temp2, -1));
+    __ jcc(Assembler::equal, L);
+    __ movptr(rax, __ argument_address(temp2, -1));
+    __ STOP("receiver not on stack");
+    __ BIND(L);
+  }
+
+  jump_from_method_handle(_masm, method_temp, temp2, for_compiler_entry);
+  BLOCK_COMMENT("} jump_to_lambda_form");
+}
+
+
 // Code generation
-address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm) {
-  // rbx: methodOop
-  // rcx: receiver method handle (must load from sp[MethodTypeForm.vmslots])
+address MethodHandles::generate_method_handle_interpreter_entry(MacroAssembler* _masm,
+                                                                vmIntrinsics::ID iid) {
+  const bool not_for_compiler_entry = false;  // this is the interpreter entry
+  assert(is_signature_polymorphic(iid), "expected invoke iid");
+  if (iid == vmIntrinsics::_invokeGeneric ||
+      iid == vmIntrinsics::_compiledLambdaForm) {
+    // Perhaps surprisingly, the symbolic references visible to Java are not directly used.
+    // They are linked to Java-generated adapters via MethodHandleNatives.linkMethod.
+    // They all allow an appendix argument.
+    __ hlt();           // empty stubs make SG sick
+    return NULL;
+  }
+
   // rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
-  // rdx, rdi: garbage temp, blown away
-
-  Register rbx_method = rbx;
-  Register rcx_recv   = rcx;
-  Register rax_mtype  = rax;
-  Register rdx_temp   = rdx;
-  Register rdi_temp   = rdi;
-
-  // emit WrongMethodType path first, to enable jccb back-branch from main path
-  Label wrong_method_type;
-  __ bind(wrong_method_type);
-  Label invoke_generic_slow_path, invoke_exact_error_path;
-  assert(methodOopDesc::intrinsic_id_size_in_bytes() == sizeof(u1), "");;
-  __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeExact);
-  __ jcc(Assembler::notEqual, invoke_generic_slow_path);
-  __ jmp(invoke_exact_error_path);
+  // rbx: methodOop
+  // rdx: argument locator (parameter slot count, added to rsp)
+  // rcx: used as temp to hold mh or receiver
+  // rax, rdi: garbage temps, blown away
+  Register rdx_argp   = rdx;   // argument list ptr, live on error paths
+  Register rax_temp   = rax;
+  Register rcx_mh     = rcx;   // MH receiver; dies quickly and is recycled
+  Register rbx_method = rbx;   // eventual target of this invocation
 
   // here's where control starts out:
   __ align(CodeEntryAlignment);
   address entry_point = __ pc();
 
-  // fetch the MethodType from the method handle into rax (the 'check' register)
-  // FIXME: Interpreter should transmit pre-popped stack pointer, to locate base of arg list.
-  // This would simplify several touchy bits of code.
-  // See 6984712: JSR 292 method handle calls need a clean argument base pointer
-  {
-    Register tem = rbx_method;
-    for (jint* pchase = methodOopDesc::method_type_offsets_chain(); (*pchase) != -1; pchase++) {
-      __ movptr(rax_mtype, Address(tem, *pchase));
-      tem = rax_mtype;          // in case there is another indirection
-    }
-  }
-
-  // given the MethodType, find out where the MH argument is buried
-  __ load_heap_oop(rdx_temp, Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes, rdi_temp)));
-  Register rdx_vmslots = rdx_temp;
-  __ movl(rdx_vmslots, Address(rdx_temp, __ delayed_value(java_lang_invoke_MethodTypeForm::vmslots_offset_in_bytes, rdi_temp)));
-  Address mh_receiver_slot_addr = __ argument_address(rdx_vmslots);
-  __ movptr(rcx_recv, mh_receiver_slot_addr);
-
-  trace_method_handle(_masm, "invokeExact");
-
-  __ check_method_handle_type(rax_mtype, rcx_recv, rdi_temp, wrong_method_type);
-
-  // Nobody uses the MH receiver slot after this.  Make sure.
-  DEBUG_ONLY(__ movptr(mh_receiver_slot_addr, (int32_t)0x999999));
-
-  __ jump_to_method_handle_entry(rcx_recv, rdi_temp);
-
-  // error path for invokeExact (only)
-  __ bind(invoke_exact_error_path);
-  // ensure that the top of stack is properly aligned.
-  __ mov(rdi, rsp);
-  __ andptr(rsp, -StackAlignmentInBytes); // Align the stack for the ABI
-  __ pushptr(Address(rdi, 0));  // Pick up the return address
-
-  // Stub wants expected type in rax and the actual type in rcx
-  __ jump(ExternalAddress(StubRoutines::throw_WrongMethodTypeException_entry()));
-
-  // for invokeGeneric (only), apply argument and result conversions on the fly
-  __ bind(invoke_generic_slow_path);
-#ifdef ASSERT
   if (VerifyMethodHandles) {
     Label L;
-    __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) vmIntrinsics::_invokeGeneric);
+    BLOCK_COMMENT("verify_intrinsic_id {");
+    __ cmpb(Address(rbx_method, methodOopDesc::intrinsic_id_offset_in_bytes()), (int) iid);
     __ jcc(Assembler::equal, L);
-    __ stop("bad methodOop::intrinsic_id");
+    if (iid == vmIntrinsics::_linkToVirtual ||
+        iid == vmIntrinsics::_linkToSpecial) {
+      // could do this for all kinds, but would explode assembly code size
+      trace_method_handle(_masm, "bad methodOop::intrinsic_id");
+    }
+    __ STOP("bad methodOop::intrinsic_id");
     __ bind(L);
+    BLOCK_COMMENT("} verify_intrinsic_id");
   }
-#endif //ASSERT
-  Register rbx_temp = rbx_method;  // don't need it now
 
-  // make room on the stack for another pointer:
-  Register rcx_argslot = rcx_recv;
-  __ lea(rcx_argslot, __ argument_address(rdx_vmslots, 1));
-  insert_arg_slots(_masm, 2 * stack_move_unit(),
-                   rcx_argslot, rbx_temp, rdx_temp);
+  // First task:  Find out how big the argument list is.
+  Address rdx_first_arg_addr;
+  int ref_kind = signature_polymorphic_intrinsic_ref_kind(iid);
+  assert(ref_kind != 0 || iid == vmIntrinsics::_invokeBasic, "must be _invokeBasic or a linkTo intrinsic");
+  if (ref_kind == 0 || MethodHandles::ref_kind_has_receiver(ref_kind)) {
+    __ load_sized_value(rdx_argp,
+                        Address(rbx_method, methodOopDesc::size_of_parameters_offset()),
+                        sizeof(u2), /*is_signed*/ false);
+    // assert(sizeof(u2) == sizeof(methodOopDesc::_size_of_parameters), "");
+    rdx_first_arg_addr = __ argument_address(rdx_argp, -1);
+  } else {
+    DEBUG_ONLY(rdx_argp = noreg);
+  }
 
-  // load up an adapter from the calling type (Java weaves this)
-  Register rdx_adapter = rdx_temp;
-  __ load_heap_oop(rdx_temp,    Address(rax_mtype, __ delayed_value(java_lang_invoke_MethodType::form_offset_in_bytes,               rdi_temp)));
-  __ load_heap_oop(rdx_adapter, Address(rdx_temp,  __ delayed_value(java_lang_invoke_MethodTypeForm::genericInvoker_offset_in_bytes, rdi_temp)));
-  __ verify_oop(rdx_adapter);
-  __ movptr(Address(rcx_argslot, 1 * Interpreter::stackElementSize), rdx_adapter);
-  // As a trusted first argument, pass the type being called, so the adapter knows
-  // the actual types of the arguments and return values.
-  // (Generic invokers are shared among form-families of method-type.)
-  __ movptr(Address(rcx_argslot, 0 * Interpreter::stackElementSize), rax_mtype);
-  // FIXME: assert that rdx_adapter is of the right method-type.
-  __ mov(rcx, rdx_adapter);
-  trace_method_handle(_masm, "invokeGeneric");
-  __ jump_to_method_handle_entry(rcx, rdi_temp);
+  if (!is_signature_polymorphic_static(iid)) {
+    __ movptr(rcx_mh, rdx_first_arg_addr);
+    DEBUG_ONLY(rdx_argp = noreg);
+  }
+
+  // rdx_first_arg_addr is live!
+
+  trace_method_handle_interpreter_entry(_masm, iid);
+
+  if (iid == vmIntrinsics::_invokeBasic) {
+    generate_method_handle_dispatch(_masm, iid, rcx_mh, noreg, not_for_compiler_entry);
+
+  } else {
+    // Adjust argument list by popping the trailing MemberName argument.
+    Register rcx_recv = noreg;
+    if (MethodHandles::ref_kind_has_receiver(ref_kind)) {
+      // Load the receiver (not the MH; the actual MemberName's receiver) up from the interpreter stack.
+      __ movptr(rcx_recv = rcx, rdx_first_arg_addr);
+    }
+    DEBUG_ONLY(rdx_argp = noreg);
+    Register rbx_member = rbx_method;  // MemberName ptr; incoming method ptr is dead now
+    __ pop(rax_temp);           // return address
+    __ pop(rbx_member);         // extract last argument
+    __ push(rax_temp);          // re-push return address
+    generate_method_handle_dispatch(_masm, iid, rcx_recv, rbx_member, not_for_compiler_entry);
+  }
 
   return entry_point;
 }
 
-// Helper to insert argument slots into the stack.
-// arg_slots must be a multiple of stack_move_unit() and < 0
-// rax_argslot is decremented to point to the new (shifted) location of the argslot
-// But, rdx_temp ends up holding the original value of rax_argslot.
-void MethodHandles::insert_arg_slots(MacroAssembler* _masm,
-                                     RegisterOrConstant arg_slots,
-                                     Register rax_argslot,
-                                     Register rbx_temp, Register rdx_temp) {
-  // allow constant zero
-  if (arg_slots.is_constant() && arg_slots.as_constant() == 0)
-    return;
-  assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
-                             (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
-  if (VerifyMethodHandles)
-    verify_argslot(_masm, rax_argslot, "insertion point must fall within current frame");
-  if (VerifyMethodHandles)
-    verify_stack_move(_masm, arg_slots, -1);
-
-  // We have to insert at least one word, so bang the stack.
-  if (UseStackBanging) {
-    int frame_size = (arg_slots.is_constant() ? -1 * arg_slots.as_constant() * wordSize : 0);
-    if (frame_size <= 0)
-      frame_size = 256 * Interpreter::stackElementSize;  // conservative
-    __ generate_stack_overflow_check(frame_size);
+void MethodHandles::generate_method_handle_dispatch(MacroAssembler* _masm,
+                                                    vmIntrinsics::ID iid,
+                                                    Register receiver_reg,
+                                                    Register member_reg,
+                                                    bool for_compiler_entry) {
+  assert(is_signature_polymorphic(iid), "expected invoke iid");
+  Register rbx_method = rbx;   // eventual target of this invocation
+  // temps used in this code are not used in *either* compiled or interpreted calling sequences
+#ifdef _LP64
+  Register temp1 = rscratch1;
+  Register temp2 = rscratch2;
+  Register temp3 = rax;
+  if (for_compiler_entry) {
+    assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : j_rarg0), "only valid assignment");
+    assert_different_registers(temp1,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5);
+    assert_different_registers(temp2,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5);
+    assert_different_registers(temp3,        j_rarg0, j_rarg1, j_rarg2, j_rarg3, j_rarg4, j_rarg5);
   }
-
-  // Make space on the stack for the inserted argument(s).
-  // Then pull down everything shallower than rax_argslot.
-  // The stacked return address gets pulled down with everything else.
-  // That is, copy [rsp, argslot) downward by -size words.  In pseudo-code:
-  //   rsp -= size;
-  //   for (rdx = rsp + size; rdx < argslot; rdx++)
-  //     rdx[-size] = rdx[0]
-  //   argslot -= size;
-  BLOCK_COMMENT("insert_arg_slots {");
-  __ mov(rdx_temp, rsp);                        // source pointer for copy
-  __ lea(rsp, Address(rsp, arg_slots, Interpreter::stackElementScale()));
-  {
-    Label loop;
-    __ BIND(loop);
-    // pull one word down each time through the loop
-    __ movptr(rbx_temp, Address(rdx_temp, 0));
-    __ movptr(Address(rdx_temp, arg_slots, Interpreter::stackElementScale()), rbx_temp);
-    __ addptr(rdx_temp, wordSize);
-    __ cmpptr(rdx_temp, rax_argslot);
-    __ jcc(Assembler::below, loop);
-  }
-
-  // Now move the argslot down, to point to the opened-up space.
-  __ lea(rax_argslot, Address(rax_argslot, arg_slots, Interpreter::stackElementScale()));
-  BLOCK_COMMENT("} insert_arg_slots");
-}
-
-// Helper to remove argument slots from the stack.
-// arg_slots must be a multiple of stack_move_unit() and > 0
-void MethodHandles::remove_arg_slots(MacroAssembler* _masm,
-                                     RegisterOrConstant arg_slots,
-                                     Register rax_argslot,
-                                     Register rbx_temp, Register rdx_temp) {
-  // allow constant zero
-  if (arg_slots.is_constant() && arg_slots.as_constant() == 0)
-    return;
-  assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
-                             (!arg_slots.is_register() ? rsp : arg_slots.as_register()));
-  if (VerifyMethodHandles)
-    verify_argslots(_masm, arg_slots, rax_argslot, false,
-                    "deleted argument(s) must fall within current frame");
-  if (VerifyMethodHandles)
-    verify_stack_move(_masm, arg_slots, +1);
-
-  BLOCK_COMMENT("remove_arg_slots {");
-  // Pull up everything shallower than rax_argslot.
-  // Then remove the excess space on the stack.
-  // The stacked return address gets pulled up with everything else.
-  // That is, copy [rsp, argslot) upward by size words.  In pseudo-code:
-  //   for (rdx = argslot-1; rdx >= rsp; --rdx)
-  //     rdx[size] = rdx[0]
-  //   argslot += size;
-  //   rsp += size;
-  __ lea(rdx_temp, Address(rax_argslot, -wordSize)); // source pointer for copy
-  {
-    Label loop;
-    __ BIND(loop);
-    // pull one word up each time through the loop
-    __ movptr(rbx_temp, Address(rdx_temp, 0));
-    __ movptr(Address(rdx_temp, arg_slots, Interpreter::stackElementScale()), rbx_temp);
-    __ addptr(rdx_temp, -wordSize);
-    __ cmpptr(rdx_temp, rsp);
-    __ jcc(Assembler::aboveEqual, loop);
-  }
-
-  // Now move the argslot up, to point to the just-copied block.
-  __ lea(rsp, Address(rsp, arg_slots, Interpreter::stackElementScale()));
-  // And adjust the argslot address to point at the deletion point.
-  __ lea(rax_argslot, Address(rax_argslot, arg_slots, Interpreter::stackElementScale()));
-  BLOCK_COMMENT("} remove_arg_slots");
-}
-
-// Helper to copy argument slots to the top of the stack.
-// The sequence starts with rax_argslot and is counted by slot_count
-// slot_count must be a multiple of stack_move_unit() and >= 0
-// This function blows the temps but does not change rax_argslot.
-void MethodHandles::push_arg_slots(MacroAssembler* _masm,
-                                   Register rax_argslot,
-                                   RegisterOrConstant slot_count,
-                                   int skip_words_count,
-                                   Register rbx_temp, Register rdx_temp) {
-  assert_different_registers(rax_argslot, rbx_temp, rdx_temp,
-                             (!slot_count.is_register() ? rbp : slot_count.as_register()),
-                             rsp);
-  assert(Interpreter::stackElementSize == wordSize, "else change this code");
-
-  if (VerifyMethodHandles)
-    verify_stack_move(_masm, slot_count, 0);
-
-  // allow constant zero
-  if (slot_count.is_constant() && slot_count.as_constant() == 0)
-    return;
-
-  BLOCK_COMMENT("push_arg_slots {");
-
-  Register rbx_top = rbx_temp;
-
-  // There is at most 1 word to carry down with the TOS.
-  switch (skip_words_count) {
-  case 1: __ pop(rdx_temp); break;
-  case 0:                   break;
-  default: ShouldNotReachHere();
-  }
-
-  if (slot_count.is_constant()) {
-    for (int i = slot_count.as_constant() - 1; i >= 0; i--) {
-      __ pushptr(Address(rax_argslot, i * wordSize));
-    }
-  } else {
-    Label L_plural, L_loop, L_break;
-    // Emit code to dynamically check for the common cases, zero and one slot.
-    __ cmpl(slot_count.as_register(), (int32_t) 1);
-    __ jccb(Assembler::greater, L_plural);
-    __ jccb(Assembler::less, L_break);
-    __ pushptr(Address(rax_argslot, 0));
-    __ jmpb(L_break);
-    __ BIND(L_plural);
-
-    // Loop for 2 or more:
-    //   rbx = &rax[slot_count]
-    //   while (rbx > rax)  *(--rsp) = *(--rbx)
-    __ lea(rbx_top, Address(rax_argslot, slot_count, Address::times_ptr));
-    __ BIND(L_loop);
-    __ subptr(rbx_top, wordSize);
-    __ pushptr(Address(rbx_top, 0));
-    __ cmpptr(rbx_top, rax_argslot);
-    __ jcc(Assembler::above, L_loop);
-    __ bind(L_break);
-  }
-  switch (skip_words_count) {
-  case 1: __ push(rdx_temp); break;
-  case 0:                    break;
-  default: ShouldNotReachHere();
-  }
-  BLOCK_COMMENT("} push_arg_slots");
-}
-
-// in-place movement; no change to rsp
-// blows rax_temp, rdx_temp
-void MethodHandles::move_arg_slots_up(MacroAssembler* _masm,
-                                      Register rbx_bottom,  // invariant
-                                      Address  top_addr,     // can use rax_temp
-                                      RegisterOrConstant positive_distance_in_slots,
-                                      Register rax_temp, Register rdx_temp) {
-  BLOCK_COMMENT("move_arg_slots_up {");
-  assert_different_registers(rbx_bottom,
-                             rax_temp, rdx_temp,
-                             positive_distance_in_slots.register_or_noreg());
-  Label L_loop, L_break;
-  Register rax_top = rax_temp;
-  if (!top_addr.is_same_address(Address(rax_top, 0)))
-    __ lea(rax_top, top_addr);
-  // Detect empty (or broken) loop:
-#ifdef ASSERT
-  if (VerifyMethodHandles) {
-    // Verify that &bottom < &top (non-empty interval)
-    Label L_ok, L_bad;
-    if (positive_distance_in_slots.is_register()) {
-      __ cmpptr(positive_distance_in_slots.as_register(), (int32_t) 0);
-      __ jcc(Assembler::lessEqual, L_bad);
-    }
-    __ cmpptr(rbx_bottom, rax_top);
-    __ jcc(Assembler::below, L_ok);
-    __ bind(L_bad);
-    __ stop("valid bounds (copy up)");
-    __ BIND(L_ok);
+#else
+  Register temp1 = (for_compiler_entry ? rsi : rdx);
+  Register temp2 = rdi;
+  Register temp3 = rax;
+  if (for_compiler_entry) {
+    assert(receiver_reg == (iid == vmIntrinsics::_linkToStatic ? noreg : rcx), "only valid assignment");
+    assert_different_registers(temp1,        rcx, rdx);
+    assert_different_registers(temp2,        rcx, rdx);
+    assert_different_registers(temp3,        rcx, rdx);
   }
 #endif
-  __ cmpptr(rbx_bottom, rax_top);
-  __ jccb(Assembler::aboveEqual, L_break);
-  // work rax down to rbx, copying contiguous data upwards
-  // In pseudo-code:
-  //   [rbx, rax) = &[bottom, top)
-  //   while (--rax >= rbx) *(rax + distance) = *(rax + 0), rax--;
-  __ BIND(L_loop);
-  __ subptr(rax_top, wordSize);
-  __ movptr(rdx_temp, Address(rax_top, 0));
-  __ movptr(          Address(rax_top, positive_distance_in_slots, Address::times_ptr), rdx_temp);
-  __ cmpptr(rax_top, rbx_bottom);
-  __ jcc(Assembler::above, L_loop);
-  assert(Interpreter::stackElementSize == wordSize, "else change loop");
-  __ bind(L_break);
-  BLOCK_COMMENT("} move_arg_slots_up");
-}
-
-// in-place movement; no change to rsp
-// blows rax_temp, rdx_temp
-void MethodHandles::move_arg_slots_down(MacroAssembler* _masm,
-                                        Address  bottom_addr,  // can use rax_temp
-                                        Register rbx_top,      // invariant
-                                        RegisterOrConstant negative_distance_in_slots,
-                                        Register rax_temp, Register rdx_temp) {
-  BLOCK_COMMENT("move_arg_slots_down {");
-  assert_different_registers(rbx_top,
-                             negative_distance_in_slots.register_or_noreg(),
-                             rax_temp, rdx_temp);
-  Label L_loop, L_break;
-  Register rax_bottom = rax_temp;
-  if (!bottom_addr.is_same_address(Address(rax_bottom, 0)))
-    __ lea(rax_bottom, bottom_addr);
-  // Detect empty (or broken) loop:
-#ifdef ASSERT
-  assert(!negative_distance_in_slots.is_constant() || negative_distance_in_slots.as_constant() < 0, "");
-  if (VerifyMethodHandles) {
-    // Verify that &bottom < &top (non-empty interval)
-    Label L_ok, L_bad;
-    if (negative_distance_in_slots.is_register()) {
-      __ cmpptr(negative_distance_in_slots.as_register(), (int32_t) 0);
-      __ jcc(Assembler::greaterEqual, L_bad);
-    }
-    __ cmpptr(rax_bottom, rbx_top);
-    __ jcc(Assembler::below, L_ok);
-    __ bind(L_bad);
-    __ stop("valid bounds (copy down)");
-    __ BIND(L_ok);
+  else {
+    assert_different_registers(temp1, temp2, temp3, saved_last_sp_register());  // don't trash lastSP
   }
-#endif
-  __ cmpptr(rax_bottom, rbx_top);
-  __ jccb(Assembler::aboveEqual, L_break);
-  // work rax up to rbx, copying contiguous data downwards
-  // In pseudo-code:
-  //   [rax, rbx) = &[bottom, top)
-  //   while (rax < rbx) *(rax - distance) = *(rax + 0), rax++;
-  __ BIND(L_loop);
-  __ movptr(rdx_temp, Address(rax_bottom, 0));
-  __ movptr(          Address(rax_bottom, negative_distance_in_slots, Address::times_ptr), rdx_temp);
-  __ addptr(rax_bottom, wordSize);
-  __ cmpptr(rax_bottom, rbx_top);
-  __ jcc(Assembler::below, L_loop);
-  assert(Interpreter::stackElementSize == wordSize, "else change loop");
-  __ bind(L_break);
-  BLOCK_COMMENT("} move_arg_slots_down");
-}
+  assert_different_registers(temp1, temp2, temp3, receiver_reg);
+  assert_different_registers(temp1, temp2, temp3, member_reg);
 
-// Copy from a field or array element to a stacked argument slot.
-// is_element (ignored) says whether caller is loading an array element instead of an instance field.
-void MethodHandles::move_typed_arg(MacroAssembler* _masm,
-                                   BasicType type, bool is_element,
-                                   Address slot_dest, Address value_src,
-                                   Register rbx_temp, Register rdx_temp) {
-  BLOCK_COMMENT(!is_element ? "move_typed_arg {" : "move_typed_arg { (array element)");
-  if (type == T_OBJECT || type == T_ARRAY) {
-    __ load_heap_oop(rbx_temp, value_src);
-    __ movptr(slot_dest, rbx_temp);
-  } else if (type != T_VOID) {
-    int  arg_size      = type2aelembytes(type);
-    bool arg_is_signed = is_signed_subword_type(type);
-    int  slot_size     = (arg_size > wordSize) ? arg_size : wordSize;
-    __ load_sized_value(  rdx_temp,  value_src, arg_size, arg_is_signed, rbx_temp);
-    __ store_sized_value( slot_dest, rdx_temp,  slot_size,               rbx_temp);
-  }
-  BLOCK_COMMENT("} move_typed_arg");
-}
+  if (iid == vmIntrinsics::_invokeBasic) {
+    // indirect through MH.form.vmentry.vmtarget
+    jump_to_lambda_form(_masm, receiver_reg, rbx_method, temp1, for_compiler_entry);
 
-void MethodHandles::move_return_value(MacroAssembler* _masm, BasicType type,
-                                      Address return_slot) {
-  BLOCK_COMMENT("move_return_value {");
-  // Old versions of the JVM must clean the FPU stack after every return.
-#ifndef _LP64
-#ifdef COMPILER2
-  // The FPU stack is clean if UseSSE >= 2 but must be cleaned in other cases
-  if ((type == T_FLOAT && UseSSE < 1) || (type == T_DOUBLE && UseSSE < 2)) {
-    for (int i = 1; i < 8; i++) {
-        __ ffree(i);
-    }
-  } else if (UseSSE < 2) {
-    __ empty_FPU_stack();
-  }
-#endif //COMPILER2
-#endif //!_LP64
-
-  // Look at the type and pull the value out of the corresponding register.
-  if (type == T_VOID) {
-    // nothing to do
-  } else if (type == T_OBJECT) {
-    __ movptr(return_slot, rax);
-  } else if (type == T_INT || is_subword_type(type)) {
-    // write the whole word, even if only 32 bits is significant
-    __ movptr(return_slot, rax);
-  } else if (type == T_LONG) {
-    // store the value by parts
-    // Note: We assume longs are continguous (if misaligned) on the interpreter stack.
-    __ store_sized_value(return_slot, rax, BytesPerLong, rdx);
-  } else if (NOT_LP64((type == T_FLOAT  && UseSSE < 1) ||
-                      (type == T_DOUBLE && UseSSE < 2) ||)
-             false) {
-    // Use old x86 FPU registers:
-    if (type == T_FLOAT)
-      __ fstp_s(return_slot);
-    else
-      __ fstp_d(return_slot);
-  } else if (type == T_FLOAT) {
-    __ movflt(return_slot, xmm0);
-  } else if (type == T_DOUBLE) {
-    __ movdbl(return_slot, xmm0);
   } else {
-    ShouldNotReachHere();
+    // The method is a member invoker used by direct method handles.
+    if (VerifyMethodHandles) {
+      // make sure the trailing argument really is a MemberName (caller responsibility)
+      verify_klass(_masm, member_reg, SystemDictionaryHandles::MemberName_klass(),
+                   "MemberName required for invokeVirtual etc.");
+    }
+
+    Address member_clazz(    member_reg, NONZERO(java_lang_invoke_MemberName::clazz_offset_in_bytes()));
+    Address member_vmindex(  member_reg, NONZERO(java_lang_invoke_MemberName::vmindex_offset_in_bytes()));
+    Address member_vmtarget( member_reg, NONZERO(java_lang_invoke_MemberName::vmtarget_offset_in_bytes()));
+
+    Register temp1_recv_klass = temp1;
+    if (iid != vmIntrinsics::_linkToStatic) {
+      __ verify_oop(receiver_reg);
+      if (iid == vmIntrinsics::_linkToSpecial) {
+        // Don't actually load the klass; just null-check the receiver.
+        __ null_check(receiver_reg);
+      } else {
+        // load receiver klass itself
+        __ null_check(receiver_reg, oopDesc::klass_offset_in_bytes());
+        __ load_klass(temp1_recv_klass, receiver_reg);
+        __ verify_oop(temp1_recv_klass);
+      }
+      BLOCK_COMMENT("check_receiver {");
+      // The receiver for the MemberName must be in receiver_reg.
+      // Check the receiver against the MemberName.clazz
+      if (VerifyMethodHandles && iid == vmIntrinsics::_linkToSpecial) {
+        // Did not load it above...
+        __ load_klass(temp1_recv_klass, receiver_reg);
+        __ verify_oop(temp1_recv_klass);
+      }
+      if (VerifyMethodHandles && iid != vmIntrinsics::_linkToInterface) {
+        Label L_ok;
+        Register temp2_defc = temp2;
+        __ load_heap_oop(temp2_defc, member_clazz);
+        load_klass_from_Class(_masm, temp2_defc);
+        __ verify_oop(temp2_defc);
+        __ check_klass_subtype(temp1_recv_klass, temp2_defc, temp3, L_ok);
+        // If we get here, the type check failed!
+        __ STOP("receiver class disagrees with MemberName.clazz");
+        __ bind(L_ok);
+      }
+      BLOCK_COMMENT("} check_receiver");
+    }
+    if (iid == vmIntrinsics::_linkToSpecial ||
+        iid == vmIntrinsics::_linkToStatic) {
+      DEBUG_ONLY(temp1_recv_klass = noreg);  // these guys didn't load the recv_klass
+    }
+
+    // Live registers at this point:
+    //  member_reg - MemberName that was the trailing argument
+    //  temp1_recv_klass - klass of stacked receiver, if needed
+    //  rsi/r13 - interpreter linkage (if interpreted)
+    //  rcx, rdx, rsi, rdi, r8, r8 - compiler arguments (if compiled)
+
+    Label L_incompatible_class_change_error;
+    switch (iid) {
+    case vmIntrinsics::_linkToSpecial:
+      if (VerifyMethodHandles) {
+        verify_ref_kind(_masm, JVM_REF_invokeSpecial, member_reg, temp3);
+      }
+      __ load_heap_oop(rbx_method, member_vmtarget);
+      break;
+
+    case vmIntrinsics::_linkToStatic:
+      if (VerifyMethodHandles) {
+        verify_ref_kind(_masm, JVM_REF_invokeStatic, member_reg, temp3);
+      }
+      __ load_heap_oop(rbx_method, member_vmtarget);
+      break;
+
+    case vmIntrinsics::_linkToVirtual:
+    {
+      // same as TemplateTable::invokevirtual,
+      // minus the CP setup and profiling:
+
+      if (VerifyMethodHandles) {
+        verify_ref_kind(_masm, JVM_REF_invokeVirtual, member_reg, temp3);
+      }
+
+      // pick out the vtable index from the MemberName, and then we can discard it:
+      Register temp2_index = temp2;
+      __ movptr(temp2_index, member_vmindex);
+
+      if (VerifyMethodHandles) {
+        Label L_index_ok;
+        __ cmpl(temp2_index, 0);
+        __ jcc(Assembler::greaterEqual, L_index_ok);
+        __ STOP("no virtual index");
+        __ BIND(L_index_ok);
+      }
+
+      // Note:  The verifier invariants allow us to ignore MemberName.clazz and vmtarget
+      // at this point.  And VerifyMethodHandles has already checked clazz, if needed.
+
+      // get target methodOop & entry point
+      __ lookup_virtual_method(temp1_recv_klass, temp2_index, rbx_method);
+      break;
+    }
+
+    case vmIntrinsics::_linkToInterface:
+    {
+      // same as TemplateTable::invokeinterface
+      // (minus the CP setup and profiling, with different argument motion)
+      if (VerifyMethodHandles) {
+        verify_ref_kind(_masm, JVM_REF_invokeInterface, member_reg, temp3);
+      }
+
+      Register temp3_intf = temp3;
+      __ load_heap_oop(temp3_intf, member_clazz);
+      load_klass_from_Class(_masm, temp3_intf);
+      __ verify_oop(temp3_intf);
+
+      Register rbx_index = rbx_method;
+      __ movptr(rbx_index, member_vmindex);
+      if (VerifyMethodHandles) {
+        Label L;
+        __ cmpl(rbx_index, 0);
+        __ jcc(Assembler::greaterEqual, L);
+        __ STOP("invalid vtable index for MH.invokeInterface");
+        __ bind(L);
+      }
+
+      // given intf, index, and recv klass, dispatch to the implementation method
+      __ lookup_interface_method(temp1_recv_klass, temp3_intf,
+                                 // note: next two args must be the same:
+                                 rbx_index, rbx_method,
+                                 temp2,
+                                 L_incompatible_class_change_error);
+      break;
+    }
+
+    default:
+      fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+      break;
+    }
+
+    // Live at this point:
+    //   rbx_method
+    //   rsi/r13 (if interpreted)
+
+    // After figuring out which concrete method to call, jump into it.
+    // Note that this works in the interpreter with no data motion.
+    // But the compiled version will require that rcx_recv be shifted out.
+    __ verify_oop(rbx_method);
+    jump_from_method_handle(_masm, rbx_method, temp1, for_compiler_entry);
+
+    if (iid == vmIntrinsics::_linkToInterface) {
+      __ bind(L_incompatible_class_change_error);
+      __ jump(RuntimeAddress(StubRoutines::throw_IncompatibleClassChangeError_entry()));
+    }
   }
-  BLOCK_COMMENT("} move_return_value");
 }
 
 #ifndef PRODUCT
-#define DESCRIBE_RICOCHET_OFFSET(rf, name) \
-  values.describe(frame_no, (intptr_t *) (((uintptr_t)rf) + MethodHandles::RicochetFrame::name##_offset_in_bytes()), #name)
-
-void MethodHandles::RicochetFrame::describe(const frame* fr, FrameValues& values, int frame_no)  {
-    address bp = (address) fr->fp();
-    RicochetFrame* rf = (RicochetFrame*)(bp - sender_link_offset_in_bytes());
-
-    // ricochet slots
-    DESCRIBE_RICOCHET_OFFSET(rf, exact_sender_sp);
-    DESCRIBE_RICOCHET_OFFSET(rf, conversion);
-    DESCRIBE_RICOCHET_OFFSET(rf, saved_args_base);
-    DESCRIBE_RICOCHET_OFFSET(rf, saved_args_layout);
-    DESCRIBE_RICOCHET_OFFSET(rf, saved_target);
-    DESCRIBE_RICOCHET_OFFSET(rf, continuation);
-
-    // relevant ricochet targets (in caller frame)
-    values.describe(-1, rf->saved_args_base(),  err_msg("*saved_args_base for #%d", frame_no));
-}
-#endif // ASSERT
-
-#ifndef PRODUCT
-extern "C" void print_method_handle(oop mh);
 void trace_method_handle_stub(const char* adaptername,
                               oop mh,
                               intptr_t* saved_regs,
                               intptr_t* entry_sp) {
   // called as a leaf from native code: do not block the JVM!
-  bool has_mh = (strstr(adaptername, "return/") == NULL);  // return adapters don't have rcx_mh
+  bool has_mh = (strstr(adaptername, "/static") == NULL &&
+                 strstr(adaptername, "linkTo") == NULL);    // static linkers don't have MH
   const char* mh_reg_name = has_mh ? "rcx_mh" : "rcx";
-  tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT, adaptername, mh_reg_name, mh, entry_sp);
+  tty->print_cr("MH %s %s="PTR_FORMAT" sp="PTR_FORMAT,
+                adaptername, mh_reg_name,
+                mh, entry_sp);
 
   if (Verbose) {
     tty->print_cr("Registers:");
@@ -1094,12 +544,18 @@
         values.describe(-1, dump_fp, "fp for #1 <not parsed, cannot trust pc>");
         values.describe(-1, dump_sp, "sp for #1");
       }
+      values.describe(-1, entry_sp, "raw top of stack");
 
       tty->print_cr("Stack layout:");
       values.print(p);
     }
-    if (has_mh)
-      print_method_handle(mh);
+    if (has_mh && mh->is_oop()) {
+      mh->print();
+      if (java_lang_invoke_MethodHandle::is_instance(mh)) {
+        if (java_lang_invoke_MethodHandle::form_offset_in_bytes() != 0)
+          java_lang_invoke_MethodHandle::form(mh)->print();
+      }
+    }
   }
 }
 
@@ -1167,1387 +623,3 @@
 }
 #endif //PRODUCT
 
-// which conversion op types are implemented here?
-int MethodHandles::adapter_conversion_ops_supported_mask() {
-  return ((1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM)
-          //OP_PRIM_TO_REF is below...
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS)
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS)
-          //OP_COLLECT_ARGS is below...
-         |(1<<java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS)
-         |(
-           java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() <= 0 ? 0 :
-           ((1<<java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF)
-           |(1<<java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS)
-           |(1<<java_lang_invoke_AdapterMethodHandle::OP_FOLD_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) {
-  MethodHandles::EntryKind ek_orig = ek_original_kind(ek);
-
-  // 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)
-  // - rcx: receiver method handle
-  // - rax: method handle type (only used by the check_mtype entry point)
-  // - rsi/r13: sender SP (must preserve; see prepare_to_jump_from_interpreted)
-  // - rdx: garbage temp, can blow away
-
-  const Register rcx_recv    = rcx;
-  const Register rax_argslot = rax;
-  const Register rbx_temp    = rbx;
-  const Register rdx_temp    = rdx;
-  const Register rdi_temp    = rdi;
-
-  // This guy is set up by prepare_to_jump_from_interpreted (from interpreted calls)
-  // and gen_c2i_adapter (from compiled calls):
-  const Register saved_last_sp = saved_last_sp_register();
-
-  // 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_lang_invoke_MethodHandle::vmentry_offset_in_bytes() != 0, "must have offsets");
-
-  // some handy addresses
-  Address rcx_mh_vmtarget(    rcx_recv, java_lang_invoke_MethodHandle::vmtarget_offset_in_bytes() );
-  Address rcx_dmh_vmindex(    rcx_recv, java_lang_invoke_DirectMethodHandle::vmindex_offset_in_bytes() );
-
-  Address rcx_bmh_vmargslot(  rcx_recv, java_lang_invoke_BoundMethodHandle::vmargslot_offset_in_bytes() );
-  Address rcx_bmh_argument(   rcx_recv, java_lang_invoke_BoundMethodHandle::argument_offset_in_bytes() );
-
-  Address rcx_amh_vmargslot(  rcx_recv, java_lang_invoke_AdapterMethodHandle::vmargslot_offset_in_bytes() );
-  Address rcx_amh_argument(   rcx_recv, java_lang_invoke_AdapterMethodHandle::argument_offset_in_bytes() );
-  Address rcx_amh_conversion( rcx_recv, java_lang_invoke_AdapterMethodHandle::conversion_offset_in_bytes() );
-  Address vmarg;                // __ argument_address(vmargslot)
-
-  const int java_mirror_offset = in_bytes(Klass::java_mirror_offset());
-
-  if (have_entry(ek)) {
-    __ nop();                   // empty stubs make SG sick
-    return;
-  }
-
-#ifdef ASSERT
-  __ push((int32_t) 0xEEEEEEEE);
-  __ push((int32_t) (intptr_t) entry_name(ek));
-  LP64_ONLY(__ push((int32_t) high((intptr_t) entry_name(ek))));
-  __ push((int32_t) 0x33333333);
-#endif //ASSERT
-
-  address interp_entry = __ pc();
-
-  trace_method_handle(_masm, entry_name(ek));
-
-  BLOCK_COMMENT(err_msg("Entry %s {", entry_name(ek)));
-
-  switch ((int) ek) {
-  case _raise_exception:
-    {
-      // Not a real MH entry, but rather shared code for raising an
-      // exception.  Since we use the compiled entry, arguments are
-      // expected in compiler argument registers.
-      assert(raise_exception_method(), "must be set");
-      assert(raise_exception_method()->from_compiled_entry(), "method must be linked");
-
-      const Register rax_pc = rax;
-      __ pop(rax_pc);  // caller PC
-      __ mov(rsp, saved_last_sp);  // cut the stack back to where the caller started
-
-      Register rbx_method = rbx_temp;
-      __ movptr(rbx_method, ExternalAddress((address) &_raise_exception_method));
-
-      const int jobject_oop_offset = 0;
-      __ movptr(rbx_method, Address(rbx_method, jobject_oop_offset));  // dereference the jobject
-
-      __ movptr(saved_last_sp, rsp);
-      __ subptr(rsp, 3 * wordSize);
-      __ push(rax_pc);         // restore caller PC
-
-      __ movl  (__ argument_address(constant(2)), rarg0_code);
-      __ movptr(__ argument_address(constant(1)), rarg1_actual);
-      __ movptr(__ argument_address(constant(0)), rarg2_required);
-      jump_from_method_handle(_masm, rbx_method, rax);
-    }
-    break;
-
-  case _invokestatic_mh:
-  case _invokespecial_mh:
-    {
-      Register rbx_method = rbx_temp;
-      __ load_heap_oop(rbx_method, rcx_mh_vmtarget); // target is a methodOop
-      __ verify_oop(rbx_method);
-      // same as TemplateTable::invokestatic or invokespecial,
-      // minus the CP setup and profiling:
-      if (ek == _invokespecial_mh) {
-        // Must load & check the first argument before entering the target method.
-        __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
-        __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
-        __ null_check(rcx_recv);
-        __ verify_oop(rcx_recv);
-      }
-      jump_from_method_handle(_masm, rbx_method, rax);
-    }
-    break;
-
-  case _invokevirtual_mh:
-    {
-      // same as TemplateTable::invokevirtual,
-      // minus the CP setup and profiling:
-
-      // pick out the vtable index and receiver offset from the MH,
-      // and then we can discard it:
-      __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
-      Register rbx_index = rbx_temp;
-      __ movl(rbx_index, rcx_dmh_vmindex);
-      // Note:  The verifier allows us to ignore rcx_mh_vmtarget.
-      __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
-      __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes());
-
-      // get receiver klass
-      Register rax_klass = rax_argslot;
-      __ load_klass(rax_klass, rcx_recv);
-      __ verify_oop(rax_klass);
-
-      // get target methodOop & entry point
-      const int base = instanceKlass::vtable_start_offset() * wordSize;
-      assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
-      Address vtable_entry_addr(rax_klass,
-                                rbx_index, Address::times_ptr,
-                                base + vtableEntry::method_offset_in_bytes());
-      Register rbx_method = rbx_temp;
-      __ movptr(rbx_method, vtable_entry_addr);
-
-      __ verify_oop(rbx_method);
-      jump_from_method_handle(_masm, rbx_method, rax);
-    }
-    break;
-
-  case _invokeinterface_mh:
-    {
-      // same as TemplateTable::invokeinterface,
-      // minus the CP setup and profiling:
-
-      // pick out the interface and itable index from the MH.
-      __ load_method_handle_vmslots(rax_argslot, rcx_recv, rdx_temp);
-      Register rdx_intf  = rdx_temp;
-      Register rbx_index = rbx_temp;
-      __ load_heap_oop(rdx_intf, rcx_mh_vmtarget);
-      __ movl(rbx_index, rcx_dmh_vmindex);
-      __ movptr(rcx_recv, __ argument_address(rax_argslot, -1));
-      __ null_check(rcx_recv, oopDesc::klass_offset_in_bytes());
-
-      // get receiver klass
-      Register rax_klass = rax_argslot;
-      __ load_klass(rax_klass, rcx_recv);
-      __ verify_oop(rax_klass);
-
-      Register rbx_method = rbx_index;
-
-      // get interface klass
-      Label no_such_interface;
-      __ verify_oop(rdx_intf);
-      __ lookup_interface_method(rax_klass, rdx_intf,
-                                 // note: next two args must be the same:
-                                 rbx_index, rbx_method,
-                                 rdi_temp,
-                                 no_such_interface);
-
-      __ verify_oop(rbx_method);
-      jump_from_method_handle(_masm, rbx_method, rax);
-      __ hlt();
-
-      __ bind(no_such_interface);
-      // Throw an exception.
-      // For historical reasons, it will be IncompatibleClassChangeError.
-      __ 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;
-
-  case _bound_ref_mh:
-  case _bound_int_mh:
-  case _bound_long_mh:
-  case _bound_ref_direct_mh:
-  case _bound_int_direct_mh:
-  case _bound_long_direct_mh:
-    {
-      const bool direct_to_method = (ek >= _bound_ref_direct_mh);
-      BasicType arg_type  = ek_bound_mh_arg_type(ek);
-      int       arg_slots = type2size[arg_type];
-
-      // make room for the new argument:
-      __ movl(rax_argslot, rcx_bmh_vmargslot);
-      __ lea(rax_argslot, __ argument_address(rax_argslot));
-
-      insert_arg_slots(_masm, arg_slots * stack_move_unit(), rax_argslot, rbx_temp, rdx_temp);
-
-      // store bound argument into the new stack slot:
-      __ load_heap_oop(rbx_temp, rcx_bmh_argument);
-      if (arg_type == T_OBJECT) {
-        __ movptr(Address(rax_argslot, 0), rbx_temp);
-      } else {
-        Address prim_value_addr(rbx_temp, java_lang_boxing_object::value_offset_in_bytes(arg_type));
-        move_typed_arg(_masm, arg_type, false,
-                       Address(rax_argslot, 0),
-                       prim_value_addr,
-                       rbx_temp, rdx_temp);
-      }
-
-      if (direct_to_method) {
-        Register rbx_method = rbx_temp;
-        __ load_heap_oop(rbx_method, rcx_mh_vmtarget);
-        __ verify_oop(rbx_method);
-        jump_from_method_handle(_masm, rbx_method, rax);
-      } else {
-        __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-        __ verify_oop(rcx_recv);
-        __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-      }
-    }
-    break;
-
-  case _adapter_opt_profiling:
-    if (java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes() != 0) {
-      Address rcx_mh_vmcount(rcx_recv, java_lang_invoke_CountingMethodHandle::vmcount_offset_in_bytes());
-      __ incrementl(rcx_mh_vmcount);
-    }
-    // fall through
-
-  case _adapter_retype_only:
-  case _adapter_retype_raw:
-    // immediately jump to the next MH layer:
-    __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-    __ verify_oop(rcx_recv);
-    __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    // This is OK when all parameter types widen.
-    // It is also OK when a return type narrows.
-    break;
-
-  case _adapter_check_cast:
-    {
-      // temps:
-      Register rbx_klass = rbx_temp; // interesting AMH data
-
-      // check a reference argument before jumping to the next layer of MH:
-      __ movl(rax_argslot, rcx_amh_vmargslot);
-      vmarg = __ argument_address(rax_argslot);
-
-      // What class are we casting to?
-      __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object!
-      load_klass_from_Class(_masm, rbx_klass);
-
-      Label done;
-      __ movptr(rdx_temp, vmarg);
-      __ testptr(rdx_temp, rdx_temp);
-      __ jcc(Assembler::zero, done);         // no cast if null
-      __ load_klass(rdx_temp, rdx_temp);
-
-      // live at this point:
-      // - rbx_klass:  klass required by the target method
-      // - rdx_temp:   argument klass to test
-      // - rcx_recv:   adapter method handle
-      __ check_klass_subtype(rdx_temp, rbx_klass, rax_argslot, done);
-
-      // If we get here, the type check failed!
-      // Call the wrong_method_type stub, passing the failing argument type in rax.
-      Register rax_mtype = rax_argslot;
-      __ movl(rax_argslot, rcx_amh_vmargslot);  // reload argslot field
-      __ movptr(rdx_temp, vmarg);
-
-      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);
-      // get the new MH:
-      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    }
-    break;
-
-  case _adapter_prim_to_prim:
-  case _adapter_ref_to_prim:
-  case _adapter_prim_to_ref:
-    // handled completely by optimized cases
-    __ stop("init_AdapterMethodHandle should not issue this");
-    break;
-
-  case _adapter_opt_i2i:        // optimized subcase of adapt_prim_to_prim
-//case _adapter_opt_f2i:        // optimized subcase of adapt_prim_to_prim
-  case _adapter_opt_l2i:        // optimized subcase of adapt_prim_to_prim
-  case _adapter_opt_unboxi:     // optimized subcase of adapt_ref_to_prim
-    {
-      // perform an in-place conversion to int or an int subword
-      __ movl(rax_argslot, rcx_amh_vmargslot);
-      vmarg = __ argument_address(rax_argslot);
-
-      switch (ek) {
-      case _adapter_opt_i2i:
-        __ movl(rdx_temp, vmarg);
-        break;
-      case _adapter_opt_l2i:
-        {
-          // just delete the extra slot; on a little-endian machine we keep the first
-          __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
-          remove_arg_slots(_masm, -stack_move_unit(),
-                           rax_argslot, rbx_temp, rdx_temp);
-          vmarg = Address(rax_argslot, -Interpreter::stackElementSize);
-          __ movl(rdx_temp, vmarg);
-        }
-        break;
-      case _adapter_opt_unboxi:
-        {
-          // Load the value up from the heap.
-          __ movptr(rdx_temp, vmarg);
-          int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
-#ifdef ASSERT
-          for (int bt = T_BOOLEAN; bt < T_INT; bt++) {
-            if (is_subword_type(BasicType(bt)))
-              assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(BasicType(bt)), "");
-          }
-#endif
-          __ null_check(rdx_temp, value_offset);
-          __ movl(rdx_temp, Address(rdx_temp, value_offset));
-          // We load this as a word.  Because we are little-endian,
-          // the low bits will be correct, but the high bits may need cleaning.
-          // The vminfo will guide us to clean those bits.
-        }
-        break;
-      default:
-        ShouldNotReachHere();
-      }
-
-      // Do the requested conversion and store the value.
-      Register rbx_vminfo = rbx_temp;
-      load_conversion_vminfo(_masm, rbx_vminfo, rcx_amh_conversion);
-
-      // get the new MH:
-      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-      // (now we are done with the old MH)
-
-      // original 32-bit vmdata word must be of this form:
-      //    | MBZ:6 | signBitCount:8 | srcDstTypes:8 | conversionOp:8 |
-      __ xchgptr(rcx, rbx_vminfo);                // free rcx for shifts
-      __ shll(rdx_temp /*, rcx*/);
-      Label zero_extend, done;
-      __ testl(rcx, CONV_VMINFO_SIGN_FLAG);
-      __ jccb(Assembler::zero, zero_extend);
-
-      // this path is taken for int->byte, int->short
-      __ sarl(rdx_temp /*, rcx*/);
-      __ jmpb(done);
-
-      __ bind(zero_extend);
-      // this is taken for int->char
-      __ shrl(rdx_temp /*, rcx*/);
-
-      __ bind(done);
-      __ movl(vmarg, rdx_temp);  // Store the value.
-      __ xchgptr(rcx, rbx_vminfo);                // restore rcx_recv
-
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    }
-    break;
-
-  case _adapter_opt_i2l:        // optimized subcase of adapt_prim_to_prim
-  case _adapter_opt_unboxl:     // optimized subcase of adapt_ref_to_prim
-    {
-      // perform an in-place int-to-long or ref-to-long conversion
-      __ movl(rax_argslot, rcx_amh_vmargslot);
-
-      // on a little-endian machine we keep the first slot and add another after
-      __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
-      insert_arg_slots(_masm, stack_move_unit(),
-                       rax_argslot, rbx_temp, rdx_temp);
-      Address vmarg1(rax_argslot, -Interpreter::stackElementSize);
-      Address vmarg2 = vmarg1.plus_disp(Interpreter::stackElementSize);
-
-      switch (ek) {
-      case _adapter_opt_i2l:
-        {
-#ifdef _LP64
-          __ movslq(rdx_temp, vmarg1);  // Load sign-extended
-          __ movq(vmarg1, rdx_temp);    // Store into first slot
-#else
-          __ movl(rdx_temp, vmarg1);
-          __ sarl(rdx_temp, BitsPerInt - 1);  // __ extend_sign()
-          __ movl(vmarg2, rdx_temp); // store second word
-#endif
-        }
-        break;
-      case _adapter_opt_unboxl:
-        {
-          // Load the value up from the heap.
-          __ movptr(rdx_temp, vmarg1);
-          int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_LONG);
-          assert(value_offset == java_lang_boxing_object::value_offset_in_bytes(T_DOUBLE), "");
-          __ null_check(rdx_temp, value_offset);
-#ifdef _LP64
-          __ movq(rbx_temp, Address(rdx_temp, value_offset));
-          __ movq(vmarg1, rbx_temp);
-#else
-          __ movl(rbx_temp, Address(rdx_temp, value_offset + 0*BytesPerInt));
-          __ movl(rdx_temp, Address(rdx_temp, value_offset + 1*BytesPerInt));
-          __ movl(vmarg1, rbx_temp);
-          __ movl(vmarg2, rdx_temp);
-#endif
-        }
-        break;
-      default:
-        ShouldNotReachHere();
-      }
-
-      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    }
-    break;
-
-  case _adapter_opt_f2d:        // optimized subcase of adapt_prim_to_prim
-  case _adapter_opt_d2f:        // optimized subcase of adapt_prim_to_prim
-    {
-      // perform an in-place floating primitive conversion
-      __ movl(rax_argslot, rcx_amh_vmargslot);
-      __ lea(rax_argslot, __ argument_address(rax_argslot, 1));
-      if (ek == _adapter_opt_f2d) {
-        insert_arg_slots(_masm, stack_move_unit(),
-                         rax_argslot, rbx_temp, rdx_temp);
-      }
-      Address vmarg(rax_argslot, -Interpreter::stackElementSize);
-
-#ifdef _LP64
-      if (ek == _adapter_opt_f2d) {
-        __ movflt(xmm0, vmarg);
-        __ cvtss2sd(xmm0, xmm0);
-        __ movdbl(vmarg, xmm0);
-      } else {
-        __ movdbl(xmm0, vmarg);
-        __ cvtsd2ss(xmm0, xmm0);
-        __ movflt(vmarg, xmm0);
-      }
-#else //_LP64
-      if (ek == _adapter_opt_f2d) {
-        __ fld_s(vmarg);        // load float to ST0
-        __ fstp_d(vmarg);       // store double
-      } else {
-        __ fld_d(vmarg);        // load double to ST0
-        __ fstp_s(vmarg);       // store single
-      }
-#endif //_LP64
-
-      if (ek == _adapter_opt_d2f) {
-        remove_arg_slots(_masm, -stack_move_unit(),
-                         rax_argslot, rbx_temp, rdx_temp);
-      }
-
-      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    }
-    break;
-
-  case _adapter_swap_args:
-  case _adapter_rot_args:
-    // handled completely by optimized cases
-    __ stop("init_AdapterMethodHandle should not issue this");
-    break;
-
-  case _adapter_opt_swap_1:
-  case _adapter_opt_swap_2:
-  case _adapter_opt_rot_1_up:
-  case _adapter_opt_rot_1_down:
-  case _adapter_opt_rot_2_up:
-  case _adapter_opt_rot_2_down:
-    {
-      int swap_slots = ek_adapter_opt_swap_slots(ek);
-      int rotate     = ek_adapter_opt_swap_mode(ek);
-
-      // 'argslot' is the position of the first argument to swap
-      __ movl(rax_argslot, rcx_amh_vmargslot);
-      __ lea(rax_argslot, __ argument_address(rax_argslot));
-
-      // 'vminfo' is the second
-      Register rbx_destslot = rbx_temp;
-      load_conversion_vminfo(_masm, rbx_destslot, rcx_amh_conversion);
-      __ lea(rbx_destslot, __ argument_address(rbx_destslot));
-      if (VerifyMethodHandles)
-        verify_argslot(_masm, rbx_destslot, "swap point must fall within current frame");
-
-      assert(Interpreter::stackElementSize == wordSize, "else rethink use of wordSize here");
-      if (!rotate) {
-        // simple swap
-        for (int i = 0; i < swap_slots; i++) {
-          __ movptr(rdi_temp, Address(rax_argslot,  i * wordSize));
-          __ movptr(rdx_temp, Address(rbx_destslot, i * wordSize));
-          __ movptr(Address(rax_argslot,  i * wordSize), rdx_temp);
-          __ movptr(Address(rbx_destslot, i * wordSize), rdi_temp);
-        }
-      } else {
-        // A rotate is actually pair of moves, with an "odd slot" (or pair)
-        // changing place with a series of other slots.
-        // First, push the "odd slot", which is going to get overwritten
-        for (int i = swap_slots - 1; i >= 0; i--) {
-          // handle one with rdi_temp instead of a push:
-          if (i == 0)  __ movptr(rdi_temp, Address(rax_argslot, i * wordSize));
-          else         __ pushptr(         Address(rax_argslot, i * wordSize));
-        }
-        if (rotate > 0) {
-          // Here is rotate > 0:
-          // (low mem)                                          (high mem)
-          //     | dest:     more_slots...     | arg: odd_slot :arg+1 |
-          // =>
-          //     | dest: odd_slot | dest+1: more_slots...      :arg+1 |
-          // work argslot down to destslot, copying contiguous data upwards
-          // pseudo-code:
-          //   rax = src_addr - swap_bytes
-          //   rbx = dest_addr
-          //   while (rax >= rbx) *(rax + swap_bytes) = *(rax + 0), rax--;
-          move_arg_slots_up(_masm,
-                            rbx_destslot,
-                            Address(rax_argslot, 0),
-                            swap_slots,
-                            rax_argslot, rdx_temp);
-        } else {
-          // Here is the other direction, rotate < 0:
-          // (low mem)                                          (high mem)
-          //     | arg: odd_slot | arg+1: more_slots...       :dest+1 |
-          // =>
-          //     | arg:    more_slots...     | dest: odd_slot :dest+1 |
-          // work argslot up to destslot, copying contiguous data downwards
-          // pseudo-code:
-          //   rax = src_addr + swap_bytes
-          //   rbx = dest_addr
-          //   while (rax <= rbx) *(rax - swap_bytes) = *(rax + 0), rax++;
-          // dest_slot denotes an exclusive upper limit
-          int limit_bias = OP_ROT_ARGS_DOWN_LIMIT_BIAS;
-          if (limit_bias != 0)
-            __ addptr(rbx_destslot, - limit_bias * wordSize);
-          move_arg_slots_down(_masm,
-                              Address(rax_argslot, swap_slots * wordSize),
-                              rbx_destslot,
-                              -swap_slots,
-                              rax_argslot, rdx_temp);
-          __ subptr(rbx_destslot, swap_slots * wordSize);
-        }
-        // pop the original first chunk into the destination slot, now free
-        for (int i = 0; i < swap_slots; i++) {
-          if (i == 0)  __ movptr(Address(rbx_destslot, i * wordSize), rdi_temp);
-          else         __ popptr(Address(rbx_destslot, i * wordSize));
-        }
-      }
-
-      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    }
-    break;
-
-  case _adapter_dup_args:
-    {
-      // 'argslot' is the position of the first argument to duplicate
-      __ movl(rax_argslot, rcx_amh_vmargslot);
-      __ lea(rax_argslot, __ argument_address(rax_argslot));
-
-      // 'stack_move' is negative number of words to duplicate
-      Register rdi_stack_move = rdi_temp;
-      load_stack_move(_masm, rdi_stack_move, rcx_recv, true);
-
-      if (VerifyMethodHandles) {
-        verify_argslots(_masm, rdi_stack_move, rax_argslot, true,
-                        "copied argument(s) must fall within current frame");
-      }
-
-      if (UseStackBanging) {
-        // Bang the stack before pushing args.
-        int frame_size = 256 * Interpreter::stackElementSize;  // conservative
-        __ generate_stack_overflow_check(frame_size + sizeof(RicochetFrame));
-      }
-      // insert location is always the bottom of the argument list:
-      Address insert_location = __ argument_address(constant(0));
-      int pre_arg_words = insert_location.disp() / wordSize;   // return PC is pushed
-      assert(insert_location.base() == rsp, "");
-
-      __ negl(rdi_stack_move);
-      push_arg_slots(_masm, rax_argslot, rdi_stack_move,
-                     pre_arg_words, rbx_temp, rdx_temp);
-
-      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    }
-    break;
-
-  case _adapter_drop_args:
-    {
-      // 'argslot' is the position of the first argument to nuke
-      __ movl(rax_argslot, rcx_amh_vmargslot);
-      __ lea(rax_argslot, __ argument_address(rax_argslot));
-
-      // (must do previous push after argslot address is taken)
-
-      // 'stack_move' is number of words to drop
-      Register rdi_stack_move = rdi_temp;
-      load_stack_move(_masm, rdi_stack_move, rcx_recv, false);
-      remove_arg_slots(_masm, rdi_stack_move,
-                       rax_argslot, rbx_temp, rdx_temp);
-
-      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-    }
-    break;
-
-  case _adapter_collect_args:
-  case _adapter_fold_args:
-  case _adapter_spread_args:
-    // handled completely by optimized cases
-    __ stop("init_AdapterMethodHandle should not issue this");
-    break;
-
-  case _adapter_opt_collect_ref:
-  case _adapter_opt_collect_int:
-  case _adapter_opt_collect_long:
-  case _adapter_opt_collect_float:
-  case _adapter_opt_collect_double:
-  case _adapter_opt_collect_void:
-  case _adapter_opt_collect_0_ref:
-  case _adapter_opt_collect_1_ref:
-  case _adapter_opt_collect_2_ref:
-  case _adapter_opt_collect_3_ref:
-  case _adapter_opt_collect_4_ref:
-  case _adapter_opt_collect_5_ref:
-  case _adapter_opt_filter_S0_ref:
-  case _adapter_opt_filter_S1_ref:
-  case _adapter_opt_filter_S2_ref:
-  case _adapter_opt_filter_S3_ref:
-  case _adapter_opt_filter_S4_ref:
-  case _adapter_opt_filter_S5_ref:
-  case _adapter_opt_collect_2_S0_ref:
-  case _adapter_opt_collect_2_S1_ref:
-  case _adapter_opt_collect_2_S2_ref:
-  case _adapter_opt_collect_2_S3_ref:
-  case _adapter_opt_collect_2_S4_ref:
-  case _adapter_opt_collect_2_S5_ref:
-  case _adapter_opt_fold_ref:
-  case _adapter_opt_fold_int:
-  case _adapter_opt_fold_long:
-  case _adapter_opt_fold_float:
-  case _adapter_opt_fold_double:
-  case _adapter_opt_fold_void:
-  case _adapter_opt_fold_1_ref:
-  case _adapter_opt_fold_2_ref:
-  case _adapter_opt_fold_3_ref:
-  case _adapter_opt_fold_4_ref:
-  case _adapter_opt_fold_5_ref:
-    {
-      // Given a fresh incoming stack frame, build a new ricochet frame.
-      // On entry, TOS points at a return PC, and RBP is the callers frame ptr.
-      // RSI/R13 has the caller's exact stack pointer, which we must also preserve.
-      // RCX contains an AdapterMethodHandle of the indicated kind.
-
-      // Relevant AMH fields:
-      // amh.vmargslot:
-      //   points to the trailing edge of the arguments
-      //   to filter, collect, or fold.  For a boxing operation,
-      //   it points just after the single primitive value.
-      // amh.argument:
-      //   recursively called MH, on |collect| arguments
-      // amh.vmtarget:
-      //   final destination MH, on return value, etc.
-      // amh.conversion.dest:
-      //   tells what is the type of the return value
-      //   (not needed here, since dest is also derived from ek)
-      // amh.conversion.vminfo:
-      //   points to the trailing edge of the return value
-      //   when the vmtarget is to be called; this is
-      //   equal to vmargslot + (retained ? |collect| : 0)
-
-      // Pass 0 or more argument slots to the recursive target.
-      int collect_count_constant = ek_adapter_opt_collect_count(ek);
-
-      // The collected arguments are copied from the saved argument list:
-      int collect_slot_constant = ek_adapter_opt_collect_slot(ek);
-
-      assert(ek_orig == _adapter_collect_args ||
-             ek_orig == _adapter_fold_args, "");
-      bool retain_original_args = (ek_orig == _adapter_fold_args);
-
-      // The return value is replaced (or inserted) at the 'vminfo' argslot.
-      // Sometimes we can compute this statically.
-      int dest_slot_constant = -1;
-      if (!retain_original_args)
-        dest_slot_constant = collect_slot_constant;
-      else if (collect_slot_constant >= 0 && collect_count_constant >= 0)
-        // We are preserving all the arguments, and the return value is prepended,
-        // so the return slot is to the left (above) the |collect| sequence.
-        dest_slot_constant = collect_slot_constant + collect_count_constant;
-
-      // Replace all those slots by the result of the recursive call.
-      // The result type can be one of ref, int, long, float, double, void.
-      // In the case of void, nothing is pushed on the stack after return.
-      BasicType dest = ek_adapter_opt_collect_type(ek);
-      assert(dest == type2wfield[dest], "dest is a stack slot type");
-      int dest_count = type2size[dest];
-      assert(dest_count == 1 || dest_count == 2 || (dest_count == 0 && dest == T_VOID), "dest has a size");
-
-      // Choose a return continuation.
-      EntryKind ek_ret = _adapter_opt_return_any;
-      if (dest != T_CONFLICT && OptimizeMethodHandles) {
-        switch (dest) {
-        case T_INT    : ek_ret = _adapter_opt_return_int;     break;
-        case T_LONG   : ek_ret = _adapter_opt_return_long;    break;
-        case T_FLOAT  : ek_ret = _adapter_opt_return_float;   break;
-        case T_DOUBLE : ek_ret = _adapter_opt_return_double;  break;
-        case T_OBJECT : ek_ret = _adapter_opt_return_ref;     break;
-        case T_VOID   : ek_ret = _adapter_opt_return_void;    break;
-        default       : ShouldNotReachHere();
-        }
-        if (dest == T_OBJECT && dest_slot_constant >= 0) {
-          EntryKind ek_try = EntryKind(_adapter_opt_return_S0_ref + dest_slot_constant);
-          if (ek_try <= _adapter_opt_return_LAST &&
-              ek_adapter_opt_return_slot(ek_try) == dest_slot_constant) {
-            ek_ret = ek_try;
-          }
-        }
-        assert(ek_adapter_opt_return_type(ek_ret) == dest, "");
-      }
-
-      // Already pushed:  ... keep1 | collect | keep2 | sender_pc |
-      // push(sender_pc);
-
-      // Compute argument base:
-      Register rax_argv = rax_argslot;
-      __ lea(rax_argv, __ argument_address(constant(0)));
-
-      // Push a few extra argument words, if we need them to store the return value.
-      {
-        int extra_slots = 0;
-        if (retain_original_args) {
-          extra_slots = dest_count;
-        } else if (collect_count_constant == -1) {
-          extra_slots = dest_count;  // collect_count might be zero; be generous
-        } else if (dest_count > collect_count_constant) {
-          extra_slots = (dest_count - collect_count_constant);
-        } else {
-          // else we know we have enough dead space in |collect| to repurpose for return values
-        }
-        DEBUG_ONLY(extra_slots += 1);
-        if (extra_slots > 0) {
-          __ pop(rbx_temp);   // return value
-          __ subptr(rsp, (extra_slots * Interpreter::stackElementSize));
-          // Push guard word #2 in debug mode.
-          DEBUG_ONLY(__ movptr(Address(rsp, 0), (int32_t) RicochetFrame::MAGIC_NUMBER_2));
-          __ push(rbx_temp);
-        }
-      }
-
-      RicochetFrame::enter_ricochet_frame(_masm, rcx_recv, rax_argv,
-                                          entry(ek_ret)->from_interpreted_entry(), rbx_temp);
-
-      // Now pushed:  ... keep1 | collect | keep2 | RF |
-      // some handy frame slots:
-      Address exact_sender_sp_addr = RicochetFrame::frame_address(RicochetFrame::exact_sender_sp_offset_in_bytes());
-      Address conversion_addr      = RicochetFrame::frame_address(RicochetFrame::conversion_offset_in_bytes());
-      Address saved_args_base_addr = RicochetFrame::frame_address(RicochetFrame::saved_args_base_offset_in_bytes());
-
-#ifdef ASSERT
-      if (VerifyMethodHandles && dest != T_CONFLICT) {
-        BLOCK_COMMENT("verify AMH.conv.dest");
-        load_conversion_dest_type(_masm, rbx_temp, conversion_addr);
-        Label L_dest_ok;
-        __ cmpl(rbx_temp, (int) dest);
-        __ jcc(Assembler::equal, L_dest_ok);
-        if (dest == T_INT) {
-          for (int bt = T_BOOLEAN; bt < T_INT; bt++) {
-            if (is_subword_type(BasicType(bt))) {
-              __ cmpl(rbx_temp, (int) bt);
-              __ jcc(Assembler::equal, L_dest_ok);
-            }
-          }
-        }
-        __ stop("bad dest in AMH.conv");
-        __ BIND(L_dest_ok);
-      }
-#endif //ASSERT
-
-      // Find out where the original copy of the recursive argument sequence begins.
-      Register rax_coll = rax_argv;
-      {
-        RegisterOrConstant collect_slot = collect_slot_constant;
-        if (collect_slot_constant == -1) {
-          __ movl(rdi_temp, rcx_amh_vmargslot);
-          collect_slot = rdi_temp;
-        }
-        if (collect_slot_constant != 0)
-          __ lea(rax_coll, Address(rax_argv, collect_slot, Interpreter::stackElementScale()));
-        // rax_coll now points at the trailing edge of |collect| and leading edge of |keep2|
-      }
-
-      // Replace the old AMH with the recursive MH.  (No going back now.)
-      // In the case of a boxing call, the recursive call is to a 'boxer' method,
-      // such as Integer.valueOf or Long.valueOf.  In the case of a filter
-      // or collect call, it will take one or more arguments, transform them,
-      // and return some result, to store back into argument_base[vminfo].
-      __ load_heap_oop(rcx_recv, rcx_amh_argument);
-      if (VerifyMethodHandles)  verify_method_handle(_masm, rcx_recv);
-
-      // Push a space for the recursively called MH first:
-      __ push((int32_t)NULL_WORD);
-
-      // Calculate |collect|, the number of arguments we are collecting.
-      Register rdi_collect_count = rdi_temp;
-      RegisterOrConstant collect_count;
-      if (collect_count_constant >= 0) {
-        collect_count = collect_count_constant;
-      } else {
-        __ load_method_handle_vmslots(rdi_collect_count, rcx_recv, rdx_temp);
-        collect_count = rdi_collect_count;
-      }
-#ifdef ASSERT
-      if (VerifyMethodHandles && collect_count_constant >= 0) {
-        __ load_method_handle_vmslots(rbx_temp, rcx_recv, rdx_temp);
-        Label L_count_ok;
-        __ cmpl(rbx_temp, collect_count_constant);
-        __ jcc(Assembler::equal, L_count_ok);
-        __ stop("bad vminfo in AMH.conv");
-        __ BIND(L_count_ok);
-      }
-#endif //ASSERT
-
-      // copy |collect| slots directly to TOS:
-      push_arg_slots(_masm, rax_coll, collect_count, 0, rbx_temp, rdx_temp);
-      // Now pushed:  ... keep1 | collect | keep2 | RF... | collect |
-      // rax_coll still points at the trailing edge of |collect| and leading edge of |keep2|
-
-      // If necessary, adjust the saved arguments to make room for the eventual return value.
-      // Normal adjustment:  ... keep1 | +dest+ | -collect- | keep2 | RF... | collect |
-      // If retaining args:  ... keep1 | +dest+ |  collect  | keep2 | RF... | collect |
-      // In the non-retaining case, this might move keep2 either up or down.
-      // We don't have to copy the whole | RF... collect | complex,
-      // but we must adjust RF.saved_args_base.
-      // Also, from now on, we will forget about the original copy of |collect|.
-      // If we are retaining it, we will treat it as part of |keep2|.
-      // For clarity we will define |keep3| = |collect|keep2| or |keep2|.
-
-      BLOCK_COMMENT("adjust trailing arguments {");
-      // Compare the sizes of |+dest+| and |-collect-|, which are opposed opening and closing movements.
-      int                open_count  = dest_count;
-      RegisterOrConstant close_count = collect_count_constant;
-      Register rdi_close_count = rdi_collect_count;
-      if (retain_original_args) {
-        close_count = constant(0);
-      } else if (collect_count_constant == -1) {
-        close_count = rdi_collect_count;
-      }
-
-      // How many slots need moving?  This is simply dest_slot (0 => no |keep3|).
-      RegisterOrConstant keep3_count;
-      Register rsi_keep3_count = rsi;  // can repair from RF.exact_sender_sp
-      if (dest_slot_constant >= 0) {
-        keep3_count = dest_slot_constant;
-      } else  {
-        load_conversion_vminfo(_masm, rsi_keep3_count, conversion_addr);
-        keep3_count = rsi_keep3_count;
-      }
-#ifdef ASSERT
-      if (VerifyMethodHandles && dest_slot_constant >= 0) {
-        load_conversion_vminfo(_masm, rbx_temp, conversion_addr);
-        Label L_vminfo_ok;
-        __ cmpl(rbx_temp, dest_slot_constant);
-        __ jcc(Assembler::equal, L_vminfo_ok);
-        __ stop("bad vminfo in AMH.conv");
-        __ BIND(L_vminfo_ok);
-      }
-#endif //ASSERT
-
-      // tasks remaining:
-      bool move_keep3 = (!keep3_count.is_constant() || keep3_count.as_constant() != 0);
-      bool stomp_dest = (NOT_DEBUG(dest == T_OBJECT) DEBUG_ONLY(dest_count != 0));
-      bool fix_arg_base = (!close_count.is_constant() || open_count != close_count.as_constant());
-
-      if (stomp_dest | fix_arg_base) {
-        // we will probably need an updated rax_argv value
-        if (collect_slot_constant >= 0) {
-          // rax_coll already holds the leading edge of |keep2|, so tweak it
-          assert(rax_coll == rax_argv, "elided a move");
-          if (collect_slot_constant != 0)
-            __ subptr(rax_argv, collect_slot_constant * Interpreter::stackElementSize);
-        } else {
-          // Just reload from RF.saved_args_base.
-          __ movptr(rax_argv, saved_args_base_addr);
-        }
-      }
-
-      // Old and new argument locations (based at slot 0).
-      // Net shift (&new_argv - &old_argv) is (close_count - open_count).
-      bool zero_open_count = (open_count == 0);  // remember this bit of info
-      if (move_keep3 && fix_arg_base) {
-        // It will be easier to have everything in one register:
-        if (close_count.is_register()) {
-          // Deduct open_count from close_count register to get a clean +/- value.
-          __ subptr(close_count.as_register(), open_count);
-        } else {
-          close_count = close_count.as_constant() - open_count;
-        }
-        open_count = 0;
-      }
-      Address old_argv(rax_argv, 0);
-      Address new_argv(rax_argv, close_count,  Interpreter::stackElementScale(),
-                                - open_count * Interpreter::stackElementSize);
-
-      // First decide if any actual data are to be moved.
-      // We can skip if (a) |keep3| is empty, or (b) the argument list size didn't change.
-      // (As it happens, all movements involve an argument list size change.)
-
-      // If there are variable parameters, use dynamic checks to skip around the whole mess.
-      Label L_done;
-      if (!keep3_count.is_constant()) {
-        __ testl(keep3_count.as_register(), keep3_count.as_register());
-        __ jcc(Assembler::zero, L_done);
-      }
-      if (!close_count.is_constant()) {
-        __ cmpl(close_count.as_register(), open_count);
-        __ jcc(Assembler::equal, L_done);
-      }
-
-      if (move_keep3 && fix_arg_base) {
-        bool emit_move_down = false, emit_move_up = false, emit_guard = false;
-        if (!close_count.is_constant()) {
-          emit_move_down = emit_guard = !zero_open_count;
-          emit_move_up   = true;
-        } else if (open_count != close_count.as_constant()) {
-          emit_move_down = (open_count > close_count.as_constant());
-          emit_move_up   = !emit_move_down;
-        }
-        Label L_move_up;
-        if (emit_guard) {
-          __ cmpl(close_count.as_register(), open_count);
-          __ jcc(Assembler::greater, L_move_up);
-        }
-
-        if (emit_move_down) {
-          // Move arguments down if |+dest+| > |-collect-|
-          // (This is rare, except when arguments are retained.)
-          // This opens space for the return value.
-          if (keep3_count.is_constant()) {
-            for (int i = 0; i < keep3_count.as_constant(); i++) {
-              __ movptr(rdx_temp, old_argv.plus_disp(i * Interpreter::stackElementSize));
-              __ movptr(          new_argv.plus_disp(i * Interpreter::stackElementSize), rdx_temp);
-            }
-          } else {
-            Register rbx_argv_top = rbx_temp;
-            __ lea(rbx_argv_top, old_argv.plus_disp(keep3_count, Interpreter::stackElementScale()));
-            move_arg_slots_down(_masm,
-                                old_argv,     // beginning of old argv
-                                rbx_argv_top, // end of old argv
-                                close_count,  // distance to move down (must be negative)
-                                rax_argv, rdx_temp);
-            // Used argv as an iteration variable; reload from RF.saved_args_base.
-            __ movptr(rax_argv, saved_args_base_addr);
-          }
-        }
-
-        if (emit_guard) {
-          __ jmp(L_done);  // assumes emit_move_up is true also
-          __ BIND(L_move_up);
-        }
-
-        if (emit_move_up) {
-
-          // Move arguments up if |+dest+| < |-collect-|
-          // (This is usual, except when |keep3| is empty.)
-          // This closes up the space occupied by the now-deleted collect values.
-          if (keep3_count.is_constant()) {
-            for (int i = keep3_count.as_constant() - 1; i >= 0; i--) {
-              __ movptr(rdx_temp, old_argv.plus_disp(i * Interpreter::stackElementSize));
-              __ movptr(          new_argv.plus_disp(i * Interpreter::stackElementSize), rdx_temp);
-            }
-          } else {
-            Address argv_top = old_argv.plus_disp(keep3_count, Interpreter::stackElementScale());
-            move_arg_slots_up(_masm,
-                              rax_argv,     // beginning of old argv
-                              argv_top,     // end of old argv
-                              close_count,  // distance to move up (must be positive)
-                              rbx_temp, rdx_temp);
-          }
-        }
-      }
-      __ BIND(L_done);
-
-      if (fix_arg_base) {
-        // adjust RF.saved_args_base by adding (close_count - open_count)
-        if (!new_argv.is_same_address(Address(rax_argv, 0)))
-          __ lea(rax_argv, new_argv);
-        __ movptr(saved_args_base_addr, rax_argv);
-      }
-
-      if (stomp_dest) {
-        // Stomp the return slot, so it doesn't hold garbage.
-        // This isn't strictly necessary, but it may help detect bugs.
-        int forty_two = RicochetFrame::RETURN_VALUE_PLACEHOLDER;
-        __ movptr(Address(rax_argv, keep3_count, Address::times_ptr),
-                  (int32_t) forty_two);
-        // uses rsi_keep3_count
-      }
-      BLOCK_COMMENT("} adjust trailing arguments");
-
-      BLOCK_COMMENT("do_recursive_call");
-      __ mov(saved_last_sp, rsp);    // set rsi/r13 for callee
-      __ pushptr(ExternalAddress(SharedRuntime::ricochet_blob()->bounce_addr()).addr());
-      // The globally unique bounce address has two purposes:
-      // 1. It helps the JVM recognize this frame (frame::is_ricochet_frame).
-      // 2. When returned to, it cuts back the stack and redirects control flow
-      //    to the return handler.
-      // The return handler will further cut back the stack when it takes
-      // down the RF.  Perhaps there is a way to streamline this further.
-
-      if (UseStackBanging) {
-        // Bang the stack before recursive call.
-        // Even if slots == 0, we are inside a RicochetFrame.
-        int frame_size = collect_count.is_constant() ? collect_count.as_constant() * wordSize : -1;
-        if (frame_size < 0) {
-          frame_size = 256 * Interpreter::stackElementSize;  // conservative
-        }
-        __ generate_stack_overflow_check(frame_size + sizeof(RicochetFrame));
-      }
-      // State during recursive call:
-      // ... keep1 | dest | dest=42 | keep3 | RF... | collect | bounce_pc |
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-
-      break;
-    }
-
-  case _adapter_opt_return_ref:
-  case _adapter_opt_return_int:
-  case _adapter_opt_return_long:
-  case _adapter_opt_return_float:
-  case _adapter_opt_return_double:
-  case _adapter_opt_return_void:
-  case _adapter_opt_return_S0_ref:
-  case _adapter_opt_return_S1_ref:
-  case _adapter_opt_return_S2_ref:
-  case _adapter_opt_return_S3_ref:
-  case _adapter_opt_return_S4_ref:
-  case _adapter_opt_return_S5_ref:
-    {
-      BasicType dest_type_constant = ek_adapter_opt_return_type(ek);
-      int       dest_slot_constant = ek_adapter_opt_return_slot(ek);
-
-      if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
-
-      if (dest_slot_constant == -1) {
-        // The current stub is a general handler for this dest_type.
-        // It can be called from _adapter_opt_return_any below.
-        // Stash the address in a little table.
-        assert((dest_type_constant & CONV_TYPE_MASK) == dest_type_constant, "oob");
-        address return_handler = __ pc();
-        _adapter_return_handlers[dest_type_constant] = return_handler;
-        if (dest_type_constant == T_INT) {
-          // do the subword types too
-          for (int bt = T_BOOLEAN; bt < T_INT; bt++) {
-            if (is_subword_type(BasicType(bt)) &&
-                _adapter_return_handlers[bt] == NULL) {
-              _adapter_return_handlers[bt] = return_handler;
-            }
-          }
-        }
-      }
-
-      Register rbx_arg_base = rbx_temp;
-      assert_different_registers(rax, rdx,  // possibly live return value registers
-                                 rdi_temp, rbx_arg_base);
-
-      Address conversion_addr      = RicochetFrame::frame_address(RicochetFrame::conversion_offset_in_bytes());
-      Address saved_args_base_addr = RicochetFrame::frame_address(RicochetFrame::saved_args_base_offset_in_bytes());
-
-      __ movptr(rbx_arg_base, saved_args_base_addr);
-      RegisterOrConstant dest_slot = dest_slot_constant;
-      if (dest_slot_constant == -1) {
-        load_conversion_vminfo(_masm, rdi_temp, conversion_addr);
-        dest_slot = rdi_temp;
-      }
-      // Store the result back into the argslot.
-      // This code uses the interpreter calling sequence, in which the return value
-      // is usually left in the TOS register, as defined by InterpreterMacroAssembler::pop.
-      // There are certain irregularities with floating point values, which can be seen
-      // in TemplateInterpreterGenerator::generate_return_entry_for.
-      move_return_value(_masm, dest_type_constant, Address(rbx_arg_base, dest_slot, Interpreter::stackElementScale()));
-
-      RicochetFrame::leave_ricochet_frame(_masm, rcx_recv, rbx_arg_base, rdx_temp);
-      __ push(rdx_temp);  // repush the return PC
-
-      // Load the final target and go.
-      if (VerifyMethodHandles)  verify_method_handle(_masm, rcx_recv);
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-      __ hlt(); // --------------------
-      break;
-    }
-
-  case _adapter_opt_return_any:
-    {
-      if (VerifyMethodHandles)  RicochetFrame::verify_clean(_masm);
-      Register rdi_conv = rdi_temp;
-      assert_different_registers(rax, rdx,  // possibly live return value registers
-                                 rdi_conv, rbx_temp);
-
-      Address conversion_addr = RicochetFrame::frame_address(RicochetFrame::conversion_offset_in_bytes());
-      load_conversion_dest_type(_masm, rdi_conv, conversion_addr);
-      __ lea(rbx_temp, ExternalAddress((address) &_adapter_return_handlers[0]));
-      __ movptr(rbx_temp, Address(rbx_temp, rdi_conv, Address::times_ptr));
-
-#ifdef ASSERT
-      { Label L_badconv;
-        __ testptr(rbx_temp, rbx_temp);
-        __ jccb(Assembler::zero, L_badconv);
-        __ jmp(rbx_temp);
-        __ bind(L_badconv);
-        __ stop("bad method handle return");
-      }
-#else //ASSERT
-      __ jmp(rbx_temp);
-#endif //ASSERT
-      break;
-    }
-
-  case _adapter_opt_spread_0:
-  case _adapter_opt_spread_1_ref:
-  case _adapter_opt_spread_2_ref:
-  case _adapter_opt_spread_3_ref:
-  case _adapter_opt_spread_4_ref:
-  case _adapter_opt_spread_5_ref:
-  case _adapter_opt_spread_ref:
-  case _adapter_opt_spread_byte:
-  case _adapter_opt_spread_char:
-  case _adapter_opt_spread_short:
-  case _adapter_opt_spread_int:
-  case _adapter_opt_spread_long:
-  case _adapter_opt_spread_float:
-  case _adapter_opt_spread_double:
-    {
-      // spread an array out into a group of arguments
-      int length_constant = ek_adapter_opt_spread_count(ek);
-      bool length_can_be_zero = (length_constant == 0);
-      if (length_constant < 0) {
-        // some adapters with variable length must handle the zero case
-        if (!OptimizeMethodHandles ||
-            ek_adapter_opt_spread_type(ek) != T_OBJECT)
-          length_can_be_zero = true;
-      }
-
-      // find the address of the array argument
-      __ movl(rax_argslot, rcx_amh_vmargslot);
-      __ lea(rax_argslot, __ argument_address(rax_argslot));
-
-      // grab another temp
-      Register rsi_temp = rsi;
-
-      // arx_argslot points both to the array and to the first output arg
-      vmarg = Address(rax_argslot, 0);
-
-      // Get the array value.
-      Register  rdi_array       = rdi_temp;
-      Register  rdx_array_klass = rdx_temp;
-      BasicType elem_type = ek_adapter_opt_spread_type(ek);
-      int       elem_slots = type2size[elem_type];  // 1 or 2
-      int       array_slots = 1;  // array is always a T_OBJECT
-      int       length_offset   = arrayOopDesc::length_offset_in_bytes();
-      int       elem0_offset    = arrayOopDesc::base_offset_in_bytes(elem_type);
-      __ movptr(rdi_array, vmarg);
-
-      Label L_array_is_empty, L_insert_arg_space, L_copy_args, L_args_done;
-      if (length_can_be_zero) {
-        // handle the null pointer case, if zero is allowed
-        Label L_skip;
-        if (length_constant < 0) {
-          load_conversion_vminfo(_masm, rbx_temp, rcx_amh_conversion);
-          __ testl(rbx_temp, rbx_temp);
-          __ jcc(Assembler::notZero, L_skip);
-        }
-        __ testptr(rdi_array, rdi_array);
-        __ jcc(Assembler::notZero, L_skip);
-
-        // If 'rsi' contains the 'saved_last_sp' (this is only the
-        // case in a 32-bit version of the VM) we have to save 'rsi'
-        // on the stack because later on (at 'L_array_is_empty') 'rsi'
-        // will be overwritten.
-        if (rsi_temp == saved_last_sp) {
-          __ push(saved_last_sp);
-          // Need to re-push return PC to keep it on stack top.
-          __ lea(saved_last_sp, ExternalAddress(SharedRuntime::ricochet_blob()->bounce_addr()).addr());
-          __ push(saved_last_sp);
-        }
-        // Also prepare a handy macro which restores 'rsi' if required.
-#define UNPUSH_RSI                                                      \
-        { if (rsi_temp == saved_last_sp) { __ pop(saved_last_sp); __ pop(saved_last_sp); } }
-
-        __ jmp(L_array_is_empty);
-        __ bind(L_skip);
-      }
-      __ null_check(rdi_array, oopDesc::klass_offset_in_bytes());
-      __ load_klass(rdx_array_klass, rdi_array);
-
-      // Save 'rsi' if required (see comment above).  Do this only
-      // after the null check such that the exception handler which is
-      // called in the case of a null pointer exception will not be
-      // confused by the extra value on the stack (it expects the
-      // return pointer on top of the stack)
-      if (rsi_temp == saved_last_sp) {
-        __ push(saved_last_sp);
-        // Need to re-push return PC to keep it on stack top.
-        __ lea(saved_last_sp, ExternalAddress(SharedRuntime::ricochet_blob()->bounce_addr()).addr());
-        __ push(saved_last_sp);
-      }
-
-      // Check the array type.
-      Register rbx_klass = rbx_temp;
-      __ load_heap_oop(rbx_klass, rcx_amh_argument); // this is a Class object!
-      load_klass_from_Class(_masm, rbx_klass);
-
-      Label ok_array_klass, bad_array_klass, bad_array_length;
-      __ check_klass_subtype(rdx_array_klass, rbx_klass, rsi_temp, ok_array_klass);
-      // If we get here, the type check failed!
-      __ jmp(bad_array_klass);
-      __ BIND(ok_array_klass);
-
-      // Check length.
-      if (length_constant >= 0) {
-        __ cmpl(Address(rdi_array, length_offset), length_constant);
-      } else {
-        Register rbx_vminfo = rbx_temp;
-        load_conversion_vminfo(_masm, rbx_vminfo, rcx_amh_conversion);
-        __ cmpl(rbx_vminfo, Address(rdi_array, length_offset));
-      }
-      __ jcc(Assembler::notEqual, bad_array_length);
-
-      Register rdx_argslot_limit = rdx_temp;
-
-      // Array length checks out.  Now insert any required stack slots.
-      if (length_constant == -1) {
-        // Form a pointer to the end of the affected region.
-        __ lea(rdx_argslot_limit, Address(rax_argslot, Interpreter::stackElementSize));
-        // 'stack_move' is negative number of words to insert
-        // This number already accounts for elem_slots.
-        Register rsi_stack_move = rsi_temp;
-        load_stack_move(_masm, rsi_stack_move, rcx_recv, true);
-        __ cmpptr(rsi_stack_move, 0);
-        assert(stack_move_unit() < 0, "else change this comparison");
-        __ jcc(Assembler::less, L_insert_arg_space);
-        __ jcc(Assembler::equal, L_copy_args);
-        // single argument case, with no array movement
-        __ BIND(L_array_is_empty);
-        remove_arg_slots(_masm, -stack_move_unit() * array_slots,
-                         rax_argslot, rbx_temp, rdx_temp);
-        __ jmp(L_args_done);  // no spreading to do
-        __ BIND(L_insert_arg_space);
-        // come here in the usual case, stack_move < 0 (2 or more spread arguments)
-        Register rdi_temp = rdi_array;  // spill this
-        insert_arg_slots(_masm, rsi_stack_move,
-                         rax_argslot, rbx_temp, rdi_temp);
-        // reload the array since rsi was killed
-        // reload from rdx_argslot_limit since rax_argslot is now decremented
-        __ movptr(rdi_array, Address(rdx_argslot_limit, -Interpreter::stackElementSize));
-      } else if (length_constant >= 1) {
-        int new_slots = (length_constant * elem_slots) - array_slots;
-        insert_arg_slots(_masm, new_slots * stack_move_unit(),
-                         rax_argslot, rbx_temp, rdx_temp);
-      } else if (length_constant == 0) {
-        __ BIND(L_array_is_empty);
-        remove_arg_slots(_masm, -stack_move_unit() * array_slots,
-                         rax_argslot, rbx_temp, rdx_temp);
-      } else {
-        ShouldNotReachHere();
-      }
-
-      // Copy from the array to the new slots.
-      // Note: Stack change code preserves integrity of rax_argslot pointer.
-      // So even after slot insertions, rax_argslot still points to first argument.
-      // Beware:  Arguments that are shallow on the stack are deep in the array,
-      // and vice versa.  So a downward-growing stack (the usual) has to be copied
-      // elementwise in reverse order from the source array.
-      __ BIND(L_copy_args);
-      if (length_constant == -1) {
-        // [rax_argslot, rdx_argslot_limit) is the area we are inserting into.
-        // Array element [0] goes at rdx_argslot_limit[-wordSize].
-        Register rdi_source = rdi_array;
-        __ lea(rdi_source, Address(rdi_array, elem0_offset));
-        Register rdx_fill_ptr = rdx_argslot_limit;
-        Label loop;
-        __ BIND(loop);
-        __ addptr(rdx_fill_ptr, -Interpreter::stackElementSize * elem_slots);
-        move_typed_arg(_masm, elem_type, true,
-                       Address(rdx_fill_ptr, 0), Address(rdi_source, 0),
-                       rbx_temp, rsi_temp);
-        __ addptr(rdi_source, type2aelembytes(elem_type));
-        __ cmpptr(rdx_fill_ptr, rax_argslot);
-        __ jcc(Assembler::above, loop);
-      } else if (length_constant == 0) {
-        // nothing to copy
-      } else {
-        int elem_offset = elem0_offset;
-        int slot_offset = length_constant * Interpreter::stackElementSize;
-        for (int index = 0; index < length_constant; index++) {
-          slot_offset -= Interpreter::stackElementSize * elem_slots;  // fill backward
-          move_typed_arg(_masm, elem_type, true,
-                         Address(rax_argslot, slot_offset), Address(rdi_array, elem_offset),
-                         rbx_temp, rsi_temp);
-          elem_offset += type2aelembytes(elem_type);
-        }
-      }
-      __ BIND(L_args_done);
-
-      // Arguments are spread.  Move to next method handle.
-      UNPUSH_RSI;
-      __ load_heap_oop(rcx_recv, rcx_mh_vmtarget);
-      __ jump_to_method_handle_entry(rcx_recv, rdx_temp);
-
-      __ bind(bad_array_klass);
-      UNPUSH_RSI;
-      assert(!vmarg.uses(rarg2_required), "must be different registers");
-      __ load_heap_oop( 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;
-      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
-
-      break;
-    }
-
-  default:
-    // do not require all platforms to recognize all adapter types
-    __ nop();
-    return;
-  }
-  BLOCK_COMMENT(err_msg("} Entry %s", entry_name(ek)));
-  __ hlt();
-
-  address me_cookie = MethodHandleEntry::start_compiled_entry(_masm, interp_entry);
-  __ unimplemented(entry_name(ek)); // %%% FIXME: NYI
-
-  init_entry(ek, MethodHandleEntry::finish_compiled_entry(_masm, me_cookie));
-}
diff --git a/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp b/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp
index 7557383..231bbee 100644
--- a/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/methodHandles_x86.hpp
@@ -27,266 +27,12 @@
 
 // Adapters
 enum /* platform_dependent_constants */ {
-  adapter_code_size = NOT_LP64(16000 DEBUG_ONLY(+ 15000)) LP64_ONLY(32000 DEBUG_ONLY(+ 120000))
-};
-
-public:
-
-// The stack just after the recursive call from a ricochet frame
-// looks something like this.  Offsets are marked in words, not bytes.
-// rsi (r13 on LP64) is part of the interpreter calling sequence
-// which tells the callee where is my real rsp (for frame walking).
-// (...lower memory addresses)
-// rsp:     [ return pc                 ]   always the global RicochetBlob::bounce_addr
-// rsp+1:   [ recursive arg N           ]
-// rsp+2:   [ recursive arg N-1         ]
-// ...
-// rsp+N:   [ recursive arg 1           ]
-// rsp+N+1: [ recursive method handle   ]
-// ...
-// rbp-6:   [ cleanup continuation pc   ]   <-- (struct RicochetFrame)
-// rbp-5:   [ saved target MH           ]   the MH we will call on the saved args
-// rbp-4:   [ saved args layout oop     ]   an int[] array which describes argument layout
-// rbp-3:   [ saved args pointer        ]   address of transformed adapter arg M (slot 0)
-// rbp-2:   [ conversion                ]   information about how the return value is used
-// rbp-1:   [ exact sender sp           ]   exact TOS (rsi/r13) of original sender frame
-// rbp+0:   [ saved sender fp           ]   (for original sender of AMH)
-// rbp+1:   [ saved sender pc           ]   (back to original sender of AMH)
-// rbp+2:   [ transformed adapter arg M ]   <-- (extended TOS of original sender)
-// rbp+3:   [ transformed adapter arg M-1]
-// ...
-// rbp+M+1: [ transformed adapter arg 1 ]
-// rbp+M+2: [ padding                   ] <-- (rbp + saved args base offset)
-// ...      [ optional padding]
-// (higher memory addresses...)
-//
-// The arguments originally passed by the original sender
-// are lost, and arbitrary amounts of stack motion might have
-// happened due to argument transformation.
-// (This is done by C2I/I2C adapters and non-direct method handles.)
-// This is why there is an unpredictable amount of memory between
-// the extended and exact TOS of the sender.
-// The ricochet adapter itself will also (in general) perform
-// transformations before the recursive call.
-//
-// The transformed and saved arguments, immediately above the saved
-// return PC, are a well-formed method handle invocation ready to execute.
-// When the GC needs to walk the stack, these arguments are described
-// via the saved arg types oop, an int[] array with a private format.
-// This array is derived from the type of the transformed adapter
-// method handle, which also sits at the base of the saved argument
-// bundle.  Since the GC may not be able to fish out the int[]
-// array, so it is pushed explicitly on the stack.  This may be
-// an unnecessary expense.
-//
-// The following register conventions are significant at this point:
-// rsp       the thread stack, as always; preserved by caller
-// rsi/r13   exact TOS of recursive frame (contents of [rbp-2])
-// rcx       recursive method handle (contents of [rsp+N+1])
-// rbp       preserved by caller (not used by caller)
-// Unless otherwise specified, all registers can be blown by the call.
-//
-// If this frame must be walked, the transformed adapter arguments
-// will be found with the help of the saved arguments descriptor.
-//
-// Therefore, the descriptor must match the referenced arguments.
-// The arguments must be followed by at least one word of padding,
-// which will be necessary to complete the final method handle call.
-// That word is not treated as holding an oop.  Neither is the word
-//
-// The word pointed to by the return argument pointer is not
-// treated as an oop, even if points to a saved argument.
-// This allows the saved argument list to have a "hole" in it
-// to receive an oop from the recursive call.
-// (The hole might temporarily contain RETURN_VALUE_PLACEHOLDER.)
-//
-// When the recursive callee returns, RicochetBlob::bounce_addr will
-// immediately jump to the continuation stored in the RF.
-// This continuation will merge the recursive return value
-// into the saved argument list.  At that point, the original
-// rsi, rbp, and rsp will be reloaded, the ricochet frame will
-// disappear, and the final target of the adapter method handle
-// will be invoked on the transformed argument list.
-
-class RicochetFrame {
-  friend class MethodHandles;
-  friend class VMStructs;
-
- private:
-  intptr_t* _continuation;          // what to do when control gets back here
-  oopDesc*  _saved_target;          // target method handle to invoke on saved_args
-  oopDesc*  _saved_args_layout;     // caching point for MethodTypeForm.vmlayout cookie
-  intptr_t* _saved_args_base;       // base of pushed arguments (slot 0, arg N) (-3)
-  intptr_t  _conversion;            // misc. information from original AdapterMethodHandle (-2)
-  intptr_t* _exact_sender_sp;       // parallel to interpreter_frame_sender_sp (-1)
-  intptr_t* _sender_link;           // *must* coincide with frame::link_offset (0)
-  address   _sender_pc;             // *must* coincide with frame::return_addr_offset (1)
-
- public:
-  intptr_t* continuation() const        { return _continuation; }
-  oop       saved_target() const        { return _saved_target; }
-  oop       saved_args_layout() const   { return _saved_args_layout; }
-  intptr_t* saved_args_base() const     { return _saved_args_base; }
-  intptr_t  conversion() const          { return _conversion; }
-  intptr_t* exact_sender_sp() const     { return _exact_sender_sp; }
-  intptr_t* sender_link() const         { return _sender_link; }
-  address   sender_pc() const           { return _sender_pc; }
-
-  intptr_t* extended_sender_sp() const {
-    // The extended sender SP is above the current RicochetFrame.
-    return (intptr_t*) (((address) this) + sizeof(RicochetFrame));
-  }
-
-  intptr_t  return_value_slot_number() const {
-    return adapter_conversion_vminfo(conversion());
-  }
-  BasicType return_value_type() const {
-    return adapter_conversion_dest_type(conversion());
-  }
-  bool has_return_value_slot() const {
-    return return_value_type() != T_VOID;
-  }
-  intptr_t* return_value_slot_addr() const {
-    assert(has_return_value_slot(), "");
-    return saved_arg_slot_addr(return_value_slot_number());
-  }
-  intptr_t* saved_target_slot_addr() const {
-    return saved_arg_slot_addr(saved_args_length());
-  }
-  intptr_t* saved_arg_slot_addr(int slot) const {
-    assert(slot >= 0, "");
-    return (intptr_t*)( (address)saved_args_base() + (slot * Interpreter::stackElementSize) );
-  }
-
-  jint      saved_args_length() const;
-  jint      saved_arg_offset(int arg) const;
-
-  // GC interface
-  oop*  saved_target_addr()                     { return (oop*)&_saved_target; }
-  oop*  saved_args_layout_addr()                { return (oop*)&_saved_args_layout; }
-
-  oop  compute_saved_args_layout(bool read_cache, bool write_cache);
-
-  // Compiler/assembler interface.
-  static int continuation_offset_in_bytes()     { return offset_of(RicochetFrame, _continuation); }
-  static int saved_target_offset_in_bytes()     { return offset_of(RicochetFrame, _saved_target); }
-  static int saved_args_layout_offset_in_bytes(){ return offset_of(RicochetFrame, _saved_args_layout); }
-  static int saved_args_base_offset_in_bytes()  { return offset_of(RicochetFrame, _saved_args_base); }
-  static int conversion_offset_in_bytes()       { return offset_of(RicochetFrame, _conversion); }
-  static int exact_sender_sp_offset_in_bytes()  { return offset_of(RicochetFrame, _exact_sender_sp); }
-  static int sender_link_offset_in_bytes()      { return offset_of(RicochetFrame, _sender_link); }
-  static int sender_pc_offset_in_bytes()        { return offset_of(RicochetFrame, _sender_pc); }
-
-  // This value is not used for much, but it apparently must be nonzero.
-  static int frame_size_in_bytes()              { return sender_link_offset_in_bytes(); }
-
-#ifdef ASSERT
-  // The magic number is supposed to help find ricochet frames within the bytes of stack dumps.
-  enum { MAGIC_NUMBER_1 = 0xFEED03E, MAGIC_NUMBER_2 = 0xBEEF03E };
-  static int magic_number_1_offset_in_bytes()   { return -wordSize; }
-  static int magic_number_2_offset_in_bytes()   { return sizeof(RicochetFrame); }
-  intptr_t magic_number_1() const               { return *(intptr_t*)((address)this + magic_number_1_offset_in_bytes()); };
-  intptr_t magic_number_2() const               { return *(intptr_t*)((address)this + magic_number_2_offset_in_bytes()); };
-#endif //ASSERT
-
-  enum { RETURN_VALUE_PLACEHOLDER = (NOT_DEBUG(0) DEBUG_ONLY(42)) };
-
-  static void verify_offsets() NOT_DEBUG_RETURN;
-  void verify() const NOT_DEBUG_RETURN; // check for MAGIC_NUMBER, etc.
-  void zap_arguments() NOT_DEBUG_RETURN;
-
-  static void generate_ricochet_blob(MacroAssembler* _masm,
-                                     // output params:
-                                     int* bounce_offset,
-                                     int* exception_offset,
-                                     int* frame_size_in_words);
-
-  static void enter_ricochet_frame(MacroAssembler* _masm,
-                                   Register rcx_recv,
-                                   Register rax_argv,
-                                   address return_handler,
-                                   Register rbx_temp);
-  static void leave_ricochet_frame(MacroAssembler* _masm,
-                                   Register rcx_recv,
-                                   Register new_sp_reg,
-                                   Register sender_pc_reg);
-
-  static Address frame_address(int offset = 0) {
-    // The RicochetFrame is found by subtracting a constant offset from rbp.
-    return Address(rbp, - sender_link_offset_in_bytes() + offset);
-  }
-
-  static RicochetFrame* from_frame(const frame& fr) {
-    address bp = (address) fr.fp();
-    RicochetFrame* rf = (RicochetFrame*)(bp - sender_link_offset_in_bytes());
-    rf->verify();
-    return rf;
-  }
-
-  static void verify_clean(MacroAssembler* _masm) NOT_DEBUG_RETURN;
-
-  static void describe(const frame* fr, FrameValues& values, int frame_no) PRODUCT_RETURN;
+  adapter_code_size = NOT_LP64(16000 DEBUG_ONLY(+ 25000)) LP64_ONLY(32000 DEBUG_ONLY(+ 150000))
 };
 
 // Additional helper methods for MethodHandles code generation:
 public:
   static void load_klass_from_Class(MacroAssembler* _masm, Register klass_reg);
-  static void load_conversion_vminfo(MacroAssembler* _masm, Register reg, Address conversion_field_addr);
-  static void load_conversion_dest_type(MacroAssembler* _masm, Register reg, Address conversion_field_addr);
-
-  static void load_stack_move(MacroAssembler* _masm,
-                              Register rdi_stack_move,
-                              Register rcx_amh,
-                              bool might_be_negative);
-
-  static void insert_arg_slots(MacroAssembler* _masm,
-                               RegisterOrConstant arg_slots,
-                               Register rax_argslot,
-                               Register rbx_temp, Register rdx_temp);
-
-  static void remove_arg_slots(MacroAssembler* _masm,
-                               RegisterOrConstant arg_slots,
-                               Register rax_argslot,
-                               Register rbx_temp, Register rdx_temp);
-
-  static void push_arg_slots(MacroAssembler* _masm,
-                                   Register rax_argslot,
-                                   RegisterOrConstant slot_count,
-                                   int skip_words_count,
-                                   Register rbx_temp, Register rdx_temp);
-
-  static void move_arg_slots_up(MacroAssembler* _masm,
-                                Register rbx_bottom,  // invariant
-                                Address  top_addr,    // can use rax_temp
-                                RegisterOrConstant positive_distance_in_slots,
-                                Register rax_temp, Register rdx_temp);
-
-  static void move_arg_slots_down(MacroAssembler* _masm,
-                                  Address  bottom_addr,  // can use rax_temp
-                                  Register rbx_top,      // invariant
-                                  RegisterOrConstant negative_distance_in_slots,
-                                  Register rax_temp, Register rdx_temp);
-
-  static void move_typed_arg(MacroAssembler* _masm,
-                             BasicType type, bool is_element,
-                             Address slot_dest, Address value_src,
-                             Register rbx_temp, Register rdx_temp);
-
-  static void move_return_value(MacroAssembler* _masm, BasicType type,
-                                Address return_slot);
-
-  static void verify_argslot(MacroAssembler* _masm, Register argslot_reg,
-                             const char* error_message) NOT_DEBUG_RETURN;
-
-  static void verify_argslots(MacroAssembler* _masm,
-                              RegisterOrConstant argslot_count,
-                              Register argslot_reg,
-                              bool negate_argslot,
-                              const char* error_message) NOT_DEBUG_RETURN;
-
-  static void verify_stack_move(MacroAssembler* _masm,
-                                RegisterOrConstant arg_slots,
-                                int direction) NOT_DEBUG_RETURN;
 
   static void verify_klass(MacroAssembler* _masm,
                            Register obj, KlassHandle klass,
@@ -297,11 +43,17 @@
                  "reference is a MH");
   }
 
+  static void verify_ref_kind(MacroAssembler* _masm, int ref_kind, Register member_reg, Register temp) NOT_DEBUG_RETURN;
+
   // Similar to InterpreterMacroAssembler::jump_from_interpreted.
   // Takes care of special dispatch from single stepping too.
-  static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp);
+  static void jump_from_method_handle(MacroAssembler* _masm, Register method, Register temp,
+                                      bool for_compiler_entry);
 
-  static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
+  static void jump_to_lambda_form(MacroAssembler* _masm,
+                                  Register recv, Register method_temp,
+                                  Register temp2,
+                                  bool for_compiler_entry);
 
   static Register saved_last_sp_register() {
     // Should be in sharedRuntime, not here.
diff --git a/hotspot/src/cpu/x86/vm/register_x86.cpp b/hotspot/src/cpu/x86/vm/register_x86.cpp
index a6301ea..a3763a3 100644
--- a/hotspot/src/cpu/x86/vm/register_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/register_x86.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -35,7 +35,7 @@
 const int ConcreteRegisterImpl::max_fpr = ConcreteRegisterImpl::max_gpr +
                                                                  2 * FloatRegisterImpl::number_of_registers;
 const int ConcreteRegisterImpl::max_xmm = ConcreteRegisterImpl::max_fpr +
-                                                                 2 * XMMRegisterImpl::number_of_registers;
+                                                                 8 * XMMRegisterImpl::number_of_registers;
 const char* RegisterImpl::name() const {
   const char* names[number_of_registers] = {
 #ifndef AMD64
diff --git a/hotspot/src/cpu/x86/vm/register_x86.hpp b/hotspot/src/cpu/x86/vm/register_x86.hpp
index 2f4cd0d..680dd90 100644
--- a/hotspot/src/cpu/x86/vm/register_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/register_x86.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -158,7 +158,7 @@
   XMMRegister successor() const                          { return as_XMMRegister(encoding() + 1); }
 
   // accessors
-  int   encoding() const                          { assert(is_valid(), "invalid register"); return (intptr_t)this; }
+  int   encoding() const                          { assert(is_valid(), err_msg("invalid register (%d)", (int)(intptr_t)this )); return (intptr_t)this; }
   bool  is_valid() const                          { return 0 <= (intptr_t)this && (intptr_t)this < number_of_registers; }
   const char* name() const;
 };
@@ -216,7 +216,7 @@
                                RegisterImpl::number_of_registers +  // "H" half of a 64bit register
 #endif // AMD64
                            2 * FloatRegisterImpl::number_of_registers +
-                           2 * XMMRegisterImpl::number_of_registers +
+                           8 * XMMRegisterImpl::number_of_registers +
                            1 // eflags
   };
 
diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
index c80f7c8..01f2dad 100644
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_32.cpp
@@ -46,11 +46,11 @@
 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
 
 class RegisterSaver {
-  enum { FPU_regs_live = 8 /*for the FPU stack*/+8/*eight more for XMM registers*/ };
   // Capture info about frame layout
+#define DEF_XMM_OFFS(regnum) xmm ## regnum ## _off = xmm_off + (regnum)*16/BytesPerInt, xmm ## regnum ## H_off
   enum layout {
                 fpu_state_off = 0,
-                fpu_state_end = fpu_state_off+FPUStateSizeInWords-1,
+                fpu_state_end = fpu_state_off+FPUStateSizeInWords,
                 st0_off, st0H_off,
                 st1_off, st1H_off,
                 st2_off, st2H_off,
@@ -59,16 +59,16 @@
                 st5_off, st5H_off,
                 st6_off, st6H_off,
                 st7_off, st7H_off,
-
-                xmm0_off, xmm0H_off,
-                xmm1_off, xmm1H_off,
-                xmm2_off, xmm2H_off,
-                xmm3_off, xmm3H_off,
-                xmm4_off, xmm4H_off,
-                xmm5_off, xmm5H_off,
-                xmm6_off, xmm6H_off,
-                xmm7_off, xmm7H_off,
-                flags_off,
+                xmm_off,
+                DEF_XMM_OFFS(0),
+                DEF_XMM_OFFS(1),
+                DEF_XMM_OFFS(2),
+                DEF_XMM_OFFS(3),
+                DEF_XMM_OFFS(4),
+                DEF_XMM_OFFS(5),
+                DEF_XMM_OFFS(6),
+                DEF_XMM_OFFS(7),
+                flags_off = xmm7_off + 16/BytesPerInt + 1, // 16-byte stack alignment fill word
                 rdi_off,
                 rsi_off,
                 ignore_off,  // extra copy of rbp,
@@ -83,13 +83,13 @@
                 rbp_off,
                 return_off,      // slot for return address
                 reg_save_size };
-
+  enum { FPU_regs_live = flags_off - fpu_state_end };
 
   public:
 
   static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words,
-                                     int* total_frame_words, bool verify_fpu = true);
-  static void restore_live_registers(MacroAssembler* masm);
+                                     int* total_frame_words, bool verify_fpu = true, bool save_vectors = false);
+  static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false);
 
   static int rax_offset() { return rax_off; }
   static int rbx_offset() { return rbx_off; }
@@ -113,9 +113,20 @@
 };
 
 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words,
-                                           int* total_frame_words, bool verify_fpu) {
-
-  int frame_size_in_bytes =  (reg_save_size + additional_frame_words) * wordSize;
+                                           int* total_frame_words, bool verify_fpu, bool save_vectors) {
+  int vect_words = 0;
+#ifdef COMPILER2
+  if (save_vectors) {
+    assert(UseAVX > 0, "256bit vectors are supported only with AVX");
+    assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
+    // Save upper half of YMM registes
+    vect_words = 8 * 16 / wordSize;
+    additional_frame_words += vect_words;
+  }
+#else
+  assert(!save_vectors, "vectors are generated only by C2");
+#endif
+  int frame_size_in_bytes = (reg_save_size + additional_frame_words) * wordSize;
   int frame_words = frame_size_in_bytes / wordSize;
   *total_frame_words = frame_words;
 
@@ -129,7 +140,7 @@
   __ enter();
   __ pusha();
   __ pushf();
-  __ subptr(rsp,FPU_regs_live*sizeof(jdouble)); // Push FPU registers space
+  __ subptr(rsp,FPU_regs_live*wordSize); // Push FPU registers space
   __ push_FPU_state();          // Save FPU state & init
 
   if (verify_fpu) {
@@ -183,14 +194,28 @@
     __ movflt(Address(rsp,xmm6_off*wordSize),xmm6);
     __ movflt(Address(rsp,xmm7_off*wordSize),xmm7);
   } else if( UseSSE >= 2 ) {
-    __ movdbl(Address(rsp,xmm0_off*wordSize),xmm0);
-    __ movdbl(Address(rsp,xmm1_off*wordSize),xmm1);
-    __ movdbl(Address(rsp,xmm2_off*wordSize),xmm2);
-    __ movdbl(Address(rsp,xmm3_off*wordSize),xmm3);
-    __ movdbl(Address(rsp,xmm4_off*wordSize),xmm4);
-    __ movdbl(Address(rsp,xmm5_off*wordSize),xmm5);
-    __ movdbl(Address(rsp,xmm6_off*wordSize),xmm6);
-    __ movdbl(Address(rsp,xmm7_off*wordSize),xmm7);
+    // Save whole 128bit (16 bytes) XMM regiters
+    __ movdqu(Address(rsp,xmm0_off*wordSize),xmm0);
+    __ movdqu(Address(rsp,xmm1_off*wordSize),xmm1);
+    __ movdqu(Address(rsp,xmm2_off*wordSize),xmm2);
+    __ movdqu(Address(rsp,xmm3_off*wordSize),xmm3);
+    __ movdqu(Address(rsp,xmm4_off*wordSize),xmm4);
+    __ movdqu(Address(rsp,xmm5_off*wordSize),xmm5);
+    __ movdqu(Address(rsp,xmm6_off*wordSize),xmm6);
+    __ movdqu(Address(rsp,xmm7_off*wordSize),xmm7);
+  }
+
+  if (vect_words > 0) {
+    assert(vect_words*wordSize == 128, "");
+    __ subptr(rsp, 128); // Save upper half of YMM registes
+    __ vextractf128h(Address(rsp,  0),xmm0);
+    __ vextractf128h(Address(rsp, 16),xmm1);
+    __ vextractf128h(Address(rsp, 32),xmm2);
+    __ vextractf128h(Address(rsp, 48),xmm3);
+    __ vextractf128h(Address(rsp, 64),xmm4);
+    __ vextractf128h(Address(rsp, 80),xmm5);
+    __ vextractf128h(Address(rsp, 96),xmm6);
+    __ vextractf128h(Address(rsp,112),xmm7);
   }
 
   // Set an oopmap for the call site.  This oopmap will map all
@@ -253,10 +278,20 @@
 
 }
 
-void RegisterSaver::restore_live_registers(MacroAssembler* masm) {
-
+void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
   // Recover XMM & FPU state
-  if( UseSSE == 1 ) {
+  int additional_frame_bytes = 0;
+#ifdef COMPILER2
+  if (restore_vectors) {
+    assert(UseAVX > 0, "256bit vectors are supported only with AVX");
+    assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
+    additional_frame_bytes = 128;
+  }
+#else
+  assert(!restore_vectors, "vectors are generated only by C2");
+#endif
+  if (UseSSE == 1) {
+    assert(additional_frame_bytes == 0, "");
     __ movflt(xmm0,Address(rsp,xmm0_off*wordSize));
     __ movflt(xmm1,Address(rsp,xmm1_off*wordSize));
     __ movflt(xmm2,Address(rsp,xmm2_off*wordSize));
@@ -265,18 +300,33 @@
     __ movflt(xmm5,Address(rsp,xmm5_off*wordSize));
     __ movflt(xmm6,Address(rsp,xmm6_off*wordSize));
     __ movflt(xmm7,Address(rsp,xmm7_off*wordSize));
-  } else if( UseSSE >= 2 ) {
-    __ movdbl(xmm0,Address(rsp,xmm0_off*wordSize));
-    __ movdbl(xmm1,Address(rsp,xmm1_off*wordSize));
-    __ movdbl(xmm2,Address(rsp,xmm2_off*wordSize));
-    __ movdbl(xmm3,Address(rsp,xmm3_off*wordSize));
-    __ movdbl(xmm4,Address(rsp,xmm4_off*wordSize));
-    __ movdbl(xmm5,Address(rsp,xmm5_off*wordSize));
-    __ movdbl(xmm6,Address(rsp,xmm6_off*wordSize));
-    __ movdbl(xmm7,Address(rsp,xmm7_off*wordSize));
+  } else if (UseSSE >= 2) {
+#define STACK_ADDRESS(x) Address(rsp,(x)*wordSize + additional_frame_bytes)
+    __ movdqu(xmm0,STACK_ADDRESS(xmm0_off));
+    __ movdqu(xmm1,STACK_ADDRESS(xmm1_off));
+    __ movdqu(xmm2,STACK_ADDRESS(xmm2_off));
+    __ movdqu(xmm3,STACK_ADDRESS(xmm3_off));
+    __ movdqu(xmm4,STACK_ADDRESS(xmm4_off));
+    __ movdqu(xmm5,STACK_ADDRESS(xmm5_off));
+    __ movdqu(xmm6,STACK_ADDRESS(xmm6_off));
+    __ movdqu(xmm7,STACK_ADDRESS(xmm7_off));
+#undef STACK_ADDRESS
+  }
+  if (restore_vectors) {
+    // Restore upper half of YMM registes.
+    assert(additional_frame_bytes == 128, "");
+    __ vinsertf128h(xmm0, Address(rsp,  0));
+    __ vinsertf128h(xmm1, Address(rsp, 16));
+    __ vinsertf128h(xmm2, Address(rsp, 32));
+    __ vinsertf128h(xmm3, Address(rsp, 48));
+    __ vinsertf128h(xmm4, Address(rsp, 64));
+    __ vinsertf128h(xmm5, Address(rsp, 80));
+    __ vinsertf128h(xmm6, Address(rsp, 96));
+    __ vinsertf128h(xmm7, Address(rsp,112));
+    __ addptr(rsp, additional_frame_bytes);
   }
   __ pop_FPU_state();
-  __ addptr(rsp, FPU_regs_live*sizeof(jdouble)); // Pop FPU registers
+  __ addptr(rsp, FPU_regs_live*wordSize); // Pop FPU registers
 
   __ popf();
   __ popa();
@@ -308,6 +358,13 @@
   __ addptr(rsp, return_off * wordSize);
 }
 
+// Is vector's size (in bytes) bigger than a size saved by default?
+// 16 bytes XMM registers are saved by default using SSE2 movdqu instructions.
+// Note, MaxVectorSize == 0 with UseSSE < 2 and vectors are not generated.
+bool SharedRuntime::is_wide_vector(int size) {
+  return size > 16;
+}
+
 // The java_calling_convention describes stack locations as ideal slots on
 // a frame with no abi restrictions. Since we must observe abi restrictions
 // (like the placement of the register window) the slots must be biased by
@@ -643,6 +700,19 @@
   __ movdbl(r, Address(saved_sp, next_val_off));
 }
 
+static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg,
+                        address code_start, address code_end,
+                        Label& L_ok) {
+  Label L_fail;
+  __ lea(temp_reg, ExternalAddress(code_start));
+  __ cmpptr(pc_reg, temp_reg);
+  __ jcc(Assembler::belowEqual, L_fail);
+  __ lea(temp_reg, ExternalAddress(code_end));
+  __ cmpptr(pc_reg, temp_reg);
+  __ jcc(Assembler::below, L_ok);
+  __ bind(L_fail);
+}
+
 static void gen_i2c_adapter(MacroAssembler *masm,
                             int total_args_passed,
                             int comp_args_on_stack,
@@ -653,9 +723,53 @@
   // we may do a i2c -> c2i transition if we lose a race where compiled
   // code goes non-entrant while we get args ready.
 
+  // Adapters can be frameless because they do not require the caller
+  // to perform additional cleanup work, such as correcting the stack pointer.
+  // An i2c adapter is frameless because the *caller* frame, which is interpreted,
+  // routinely repairs its own stack pointer (from interpreter_frame_last_sp),
+  // even if a callee has modified the stack pointer.
+  // A c2i adapter is frameless because the *callee* frame, which is interpreted,
+  // routinely repairs its caller's stack pointer (from sender_sp, which is set
+  // up via the senderSP register).
+  // In other words, if *either* the caller or callee is interpreted, we can
+  // get the stack pointer repaired after a call.
+  // This is why c2i and i2c adapters cannot be indefinitely composed.
+  // In particular, if a c2i adapter were to somehow call an i2c adapter,
+  // both caller and callee would be compiled methods, and neither would
+  // clean up the stack pointer changes performed by the two adapters.
+  // If this happens, control eventually transfers back to the compiled
+  // caller, but with an uncorrected stack, causing delayed havoc.
+
   // Pick up the return address
   __ movptr(rax, Address(rsp, 0));
 
+  if (VerifyAdapterCalls &&
+      (Interpreter::code() != NULL || StubRoutines::code1() != NULL)) {
+    // So, let's test for cascading c2i/i2c adapters right now.
+    //  assert(Interpreter::contains($return_addr) ||
+    //         StubRoutines::contains($return_addr),
+    //         "i2c adapter must return to an interpreter frame");
+    __ block_comment("verify_i2c { ");
+    Label L_ok;
+    if (Interpreter::code() != NULL)
+      range_check(masm, rax, rdi,
+                  Interpreter::code()->code_start(), Interpreter::code()->code_end(),
+                  L_ok);
+    if (StubRoutines::code1() != NULL)
+      range_check(masm, rax, rdi,
+                  StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(),
+                  L_ok);
+    if (StubRoutines::code2() != NULL)
+      range_check(masm, rax, rdi,
+                  StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(),
+                  L_ok);
+    const char* msg = "i2c adapter must return to an interpreter frame";
+    __ block_comment(msg);
+    __ stop(msg);
+    __ bind(L_ok);
+    __ block_comment("} verify_i2ce ");
+  }
+
   // Must preserve original SP for loading incoming arguments because
   // we need to align the outgoing SP for compiled code.
   __ movptr(rdi, rsp);
@@ -1293,6 +1407,86 @@
   __ bind(done);
 }
 
+static void verify_oop_args(MacroAssembler* masm,
+                            methodHandle method,
+                            const BasicType* sig_bt,
+                            const VMRegPair* regs) {
+  Register temp_reg = rbx;  // not part of any compiled calling seq
+  if (VerifyOops) {
+    for (int i = 0; i < method->size_of_parameters(); i++) {
+      if (sig_bt[i] == T_OBJECT ||
+          sig_bt[i] == T_ARRAY) {
+        VMReg r = regs[i].first();
+        assert(r->is_valid(), "bad oop arg");
+        if (r->is_stack()) {
+          __ movptr(temp_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
+          __ verify_oop(temp_reg);
+        } else {
+          __ verify_oop(r->as_Register());
+        }
+      }
+    }
+  }
+}
+
+static void gen_special_dispatch(MacroAssembler* masm,
+                                 methodHandle method,
+                                 const BasicType* sig_bt,
+                                 const VMRegPair* regs) {
+  verify_oop_args(masm, method, sig_bt, regs);
+  vmIntrinsics::ID iid = method->intrinsic_id();
+
+  // Now write the args into the outgoing interpreter space
+  bool     has_receiver   = false;
+  Register receiver_reg   = noreg;
+  int      member_arg_pos = -1;
+  Register member_reg     = noreg;
+  int      ref_kind       = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid);
+  if (ref_kind != 0) {
+    member_arg_pos = method->size_of_parameters() - 1;  // trailing MemberName argument
+    member_reg = rbx;  // known to be free at this point
+    has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind);
+  } else if (iid == vmIntrinsics::_invokeBasic) {
+    has_receiver = true;
+  } else {
+    fatal(err_msg_res("unexpected intrinsic id %d", iid));
+  }
+
+  if (member_reg != noreg) {
+    // Load the member_arg into register, if necessary.
+    SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs);
+    VMReg r = regs[member_arg_pos].first();
+    if (r->is_stack()) {
+      __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
+    } else {
+      // no data motion is needed
+      member_reg = r->as_Register();
+    }
+  }
+
+  if (has_receiver) {
+    // Make sure the receiver is loaded into a register.
+    assert(method->size_of_parameters() > 0, "oob");
+    assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object");
+    VMReg r = regs[0].first();
+    assert(r->is_valid(), "bad receiver arg");
+    if (r->is_stack()) {
+      // Porting note:  This assumes that compiled calling conventions always
+      // pass the receiver oop in a register.  If this is not true on some
+      // platform, pick a temp and load the receiver from stack.
+      fatal("receiver always in a register");
+      receiver_reg = rcx;  // known to be free at this point
+      __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
+    } else {
+      // no data motion is needed
+      receiver_reg = r->as_Register();
+    }
+  }
+
+  // Figure out which address we are really jumping to:
+  MethodHandles::generate_method_handle_dispatch(masm, iid,
+                                                 receiver_reg, member_reg, /*for_compiler_entry:*/ true);
+}
 
 // ---------------------------------------------------------------------------
 // Generate a native wrapper for a given method.  The method takes arguments
@@ -1323,14 +1517,33 @@
 //    transition back to thread_in_Java
 //    return to caller
 //
-nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
+nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
                                                 methodHandle method,
                                                 int compile_id,
-                                                int total_in_args,
-                                                int comp_args_on_stack,
-                                                BasicType *in_sig_bt,
-                                                VMRegPair *in_regs,
+                                                BasicType* in_sig_bt,
+                                                VMRegPair* in_regs,
                                                 BasicType ret_type) {
+  if (method->is_method_handle_intrinsic()) {
+    vmIntrinsics::ID iid = method->intrinsic_id();
+    intptr_t start = (intptr_t)__ pc();
+    int vep_offset = ((intptr_t)__ pc()) - start;
+    gen_special_dispatch(masm,
+                         method,
+                         in_sig_bt,
+                         in_regs);
+    int frame_complete = ((intptr_t)__ pc()) - start;  // not complete, period
+    __ flush();
+    int stack_slots = SharedRuntime::out_preserve_stack_slots();  // no out slots at all, actually
+    return nmethod::new_native_nmethod(method,
+                                       compile_id,
+                                       masm->code(),
+                                       vep_offset,
+                                       frame_complete,
+                                       stack_slots / VMRegImpl::slots_per_word,
+                                       in_ByteSize(-1),
+                                       in_ByteSize(-1),
+                                       (OopMapSet*)NULL);
+  }
   bool is_critical_native = true;
   address native_func = method->critical_native_function();
   if (native_func == NULL) {
@@ -1348,6 +1561,7 @@
   // we convert the java signature to a C signature by inserting
   // the hidden arguments as arg[0] and possibly arg[1] (static method)
 
+  const int total_in_args = method->size_of_parameters();
   int total_c_args = total_in_args;
   if (!is_critical_native) {
     total_c_args += 1;
@@ -1436,7 +1650,7 @@
       if (in_regs[i].first()->is_Register()) {
         const Register reg = in_regs[i].first()->as_Register();
         switch (in_sig_bt[i]) {
-          case T_ARRAY:
+          case T_ARRAY:  // critical array (uses 2 slots on LP64)
           case T_BOOLEAN:
           case T_BYTE:
           case T_SHORT:
@@ -2580,7 +2794,6 @@
   return 0;
 }
 
-
 //------------------------------generate_deopt_blob----------------------------
 void SharedRuntime::generate_deopt_blob() {
   // allocate space for the code
@@ -3118,7 +3331,7 @@
 // setup oopmap, and calls safepoint code to stop the compiled code for
 // a safepoint.
 //
-SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) {
+SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) {
 
   // Account for thread arg in our frame
   const int additional_words = 1;
@@ -3138,17 +3351,18 @@
   const Register java_thread = rdi; // callee-saved for VC++
   address start   = __ pc();
   address call_pc = NULL;
-
+  bool cause_return = (poll_type == POLL_AT_RETURN);
+  bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
   // If cause_return is true we are at a poll_return and there is
   // the return address on the stack to the caller on the nmethod
   // that is safepoint. We can leave this return on the stack and
   // effectively complete the return and safepoint in the caller.
   // Otherwise we push space for a return address that the safepoint
   // handler will install later to make the stack walking sensible.
-  if( !cause_return )
-    __ push(rbx);                // Make room for return address (or push it again)
+  if (!cause_return)
+    __ push(rbx);  // Make room for return address (or push it again)
 
-  map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false);
+  map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, false, save_vectors);
 
   // The following is basically a call_VM. However, we need the precise
   // address of the call in order to generate an oopmap. Hence, we do all the
@@ -3160,7 +3374,7 @@
   __ set_last_Java_frame(java_thread, noreg, noreg, NULL);
 
   // if this was not a poll_return then we need to correct the return address now.
-  if( !cause_return ) {
+  if (!cause_return) {
     __ movptr(rax, Address(java_thread, JavaThread::saved_exception_pc_offset()));
     __ movptr(Address(rbp, wordSize), rax);
   }
@@ -3188,15 +3402,14 @@
   __ jcc(Assembler::equal, noException);
 
   // Exception pending
-
-  RegisterSaver::restore_live_registers(masm);
+  RegisterSaver::restore_live_registers(masm, save_vectors);
 
   __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
 
   __ bind(noException);
 
   // Normal exit, register restoring and exit
-  RegisterSaver::restore_live_registers(masm);
+  RegisterSaver::restore_live_registers(masm, save_vectors);
 
   __ ret(0);
 
diff --git a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
index 30a4d76..1964ed5 100644
--- a/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/sharedRuntime_x86_64.cpp
@@ -116,8 +116,8 @@
   };
 
  public:
-  static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words);
-  static void restore_live_registers(MacroAssembler* masm);
+  static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors = false);
+  static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false);
 
   // Offsets into the register save area
   // Used by deoptimization when it is managing result register
@@ -134,7 +134,19 @@
   static void restore_result_registers(MacroAssembler* masm);
 };
 
-OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words) {
+OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
+  int vect_words = 0;
+#ifdef COMPILER2
+  if (save_vectors) {
+    assert(UseAVX > 0, "256bit vectors are supported only with AVX");
+    assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
+    // Save upper half of YMM registes
+    vect_words = 16 * 16 / wordSize;
+    additional_frame_words += vect_words;
+  }
+#else
+  assert(!save_vectors, "vectors are generated only by C2");
+#endif
 
   // Always make the frame size 16-byte aligned
   int frame_size_in_bytes = round_to(additional_frame_words*wordSize +
@@ -155,6 +167,27 @@
 
   __ enter();          // rsp becomes 16-byte aligned here
   __ push_CPU_state(); // Push a multiple of 16 bytes
+
+  if (vect_words > 0) {
+    assert(vect_words*wordSize == 256, "");
+    __ subptr(rsp, 256); // Save upper half of YMM registes
+    __ vextractf128h(Address(rsp,  0),xmm0);
+    __ vextractf128h(Address(rsp, 16),xmm1);
+    __ vextractf128h(Address(rsp, 32),xmm2);
+    __ vextractf128h(Address(rsp, 48),xmm3);
+    __ vextractf128h(Address(rsp, 64),xmm4);
+    __ vextractf128h(Address(rsp, 80),xmm5);
+    __ vextractf128h(Address(rsp, 96),xmm6);
+    __ vextractf128h(Address(rsp,112),xmm7);
+    __ vextractf128h(Address(rsp,128),xmm8);
+    __ vextractf128h(Address(rsp,144),xmm9);
+    __ vextractf128h(Address(rsp,160),xmm10);
+    __ vextractf128h(Address(rsp,176),xmm11);
+    __ vextractf128h(Address(rsp,192),xmm12);
+    __ vextractf128h(Address(rsp,208),xmm13);
+    __ vextractf128h(Address(rsp,224),xmm14);
+    __ vextractf128h(Address(rsp,240),xmm15);
+  }
   if (frame::arg_reg_save_area_bytes != 0) {
     // Allocate argument register save area
     __ subptr(rsp, frame::arg_reg_save_area_bytes);
@@ -167,112 +200,111 @@
 
   OopMapSet *oop_maps = new OopMapSet();
   OopMap* map = new OopMap(frame_size_in_slots, 0);
-  map->set_callee_saved(VMRegImpl::stack2reg( rax_off  + additional_frame_slots), rax->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( rcx_off  + additional_frame_slots), rcx->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( rdx_off  + additional_frame_slots), rdx->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( rbx_off  + additional_frame_slots), rbx->as_VMReg());
+
+#define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_slots)
+
+  map->set_callee_saved(STACK_OFFSET( rax_off ), rax->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( rcx_off ), rcx->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( rdx_off ), rdx->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( rbx_off ), rbx->as_VMReg());
   // rbp location is known implicitly by the frame sender code, needs no oopmap
   // and the location where rbp was saved by is ignored
-  map->set_callee_saved(VMRegImpl::stack2reg( rsi_off  + additional_frame_slots), rsi->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( rdi_off  + additional_frame_slots), rdi->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( r8_off   + additional_frame_slots), r8->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( r9_off   + additional_frame_slots), r9->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( r10_off  + additional_frame_slots), r10->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( r11_off  + additional_frame_slots), r11->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( r12_off  + additional_frame_slots), r12->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( r13_off  + additional_frame_slots), r13->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( r14_off  + additional_frame_slots), r14->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg( r15_off  + additional_frame_slots), r15->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm0_off  + additional_frame_slots), xmm0->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm1_off  + additional_frame_slots), xmm1->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm2_off  + additional_frame_slots), xmm2->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm3_off  + additional_frame_slots), xmm3->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm4_off  + additional_frame_slots), xmm4->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm5_off  + additional_frame_slots), xmm5->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm6_off  + additional_frame_slots), xmm6->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm7_off  + additional_frame_slots), xmm7->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm8_off  + additional_frame_slots), xmm8->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm9_off  + additional_frame_slots), xmm9->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm10_off + additional_frame_slots), xmm10->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm11_off + additional_frame_slots), xmm11->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm12_off + additional_frame_slots), xmm12->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm13_off + additional_frame_slots), xmm13->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm14_off + additional_frame_slots), xmm14->as_VMReg());
-  map->set_callee_saved(VMRegImpl::stack2reg(xmm15_off + additional_frame_slots), xmm15->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( rsi_off ), rsi->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( rdi_off ), rdi->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( r8_off  ), r8->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( r9_off  ), r9->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( r10_off ), r10->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( r11_off ), r11->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( r12_off ), r12->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( r13_off ), r13->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( r14_off ), r14->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET( r15_off ), r15->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm0_off ), xmm0->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm1_off ), xmm1->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm2_off ), xmm2->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm3_off ), xmm3->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm4_off ), xmm4->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm5_off ), xmm5->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm6_off ), xmm6->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm7_off ), xmm7->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm8_off ), xmm8->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm9_off ), xmm9->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm10_off), xmm10->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm11_off), xmm11->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm12_off), xmm12->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm13_off), xmm13->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm14_off), xmm14->as_VMReg());
+  map->set_callee_saved(STACK_OFFSET(xmm15_off), xmm15->as_VMReg());
 
   // %%% These should all be a waste but we'll keep things as they were for now
   if (true) {
-    map->set_callee_saved(VMRegImpl::stack2reg( raxH_off  + additional_frame_slots),
-                          rax->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( rcxH_off  + additional_frame_slots),
-                          rcx->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( rdxH_off  + additional_frame_slots),
-                          rdx->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( rbxH_off  + additional_frame_slots),
-                          rbx->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( raxH_off ), rax->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( rcxH_off ), rcx->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( rdxH_off ), rdx->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( rbxH_off ), rbx->as_VMReg()->next());
     // rbp location is known implicitly by the frame sender code, needs no oopmap
-    map->set_callee_saved(VMRegImpl::stack2reg( rsiH_off  + additional_frame_slots),
-                          rsi->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( rdiH_off  + additional_frame_slots),
-                          rdi->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( r8H_off   + additional_frame_slots),
-                          r8->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( r9H_off   + additional_frame_slots),
-                          r9->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( r10H_off  + additional_frame_slots),
-                          r10->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( r11H_off  + additional_frame_slots),
-                          r11->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( r12H_off  + additional_frame_slots),
-                          r12->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( r13H_off  + additional_frame_slots),
-                          r13->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( r14H_off  + additional_frame_slots),
-                          r14->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg( r15H_off  + additional_frame_slots),
-                          r15->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm0H_off  + additional_frame_slots),
-                          xmm0->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm1H_off  + additional_frame_slots),
-                          xmm1->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm2H_off  + additional_frame_slots),
-                          xmm2->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm3H_off  + additional_frame_slots),
-                          xmm3->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm4H_off  + additional_frame_slots),
-                          xmm4->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm5H_off  + additional_frame_slots),
-                          xmm5->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm6H_off  + additional_frame_slots),
-                          xmm6->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm7H_off  + additional_frame_slots),
-                          xmm7->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm8H_off  + additional_frame_slots),
-                          xmm8->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm9H_off  + additional_frame_slots),
-                          xmm9->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm10H_off + additional_frame_slots),
-                          xmm10->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm11H_off + additional_frame_slots),
-                          xmm11->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm12H_off + additional_frame_slots),
-                          xmm12->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm13H_off + additional_frame_slots),
-                          xmm13->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm14H_off + additional_frame_slots),
-                          xmm14->as_VMReg()->next());
-    map->set_callee_saved(VMRegImpl::stack2reg(xmm15H_off + additional_frame_slots),
-                          xmm15->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( rsiH_off ), rsi->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( rdiH_off ), rdi->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( r8H_off  ), r8->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( r9H_off  ), r9->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( r10H_off ), r10->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( r11H_off ), r11->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( r12H_off ), r12->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( r13H_off ), r13->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( r14H_off ), r14->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET( r15H_off ), r15->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm0H_off ), xmm0->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm1H_off ), xmm1->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm2H_off ), xmm2->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm3H_off ), xmm3->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm4H_off ), xmm4->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm5H_off ), xmm5->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm6H_off ), xmm6->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm7H_off ), xmm7->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm8H_off ), xmm8->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm9H_off ), xmm9->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm10H_off), xmm10->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm11H_off), xmm11->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm12H_off), xmm12->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm13H_off), xmm13->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm14H_off), xmm14->as_VMReg()->next());
+    map->set_callee_saved(STACK_OFFSET(xmm15H_off), xmm15->as_VMReg()->next());
   }
 
   return map;
 }
 
-void RegisterSaver::restore_live_registers(MacroAssembler* masm) {
+void RegisterSaver::restore_live_registers(MacroAssembler* masm, bool restore_vectors) {
   if (frame::arg_reg_save_area_bytes != 0) {
     // Pop arg register save area
     __ addptr(rsp, frame::arg_reg_save_area_bytes);
   }
+#ifdef COMPILER2
+  if (restore_vectors) {
+    // Restore upper half of YMM registes.
+    assert(UseAVX > 0, "256bit vectors are supported only with AVX");
+    assert(MaxVectorSize == 32, "only 256bit vectors are supported now");
+    __ vinsertf128h(xmm0, Address(rsp,  0));
+    __ vinsertf128h(xmm1, Address(rsp, 16));
+    __ vinsertf128h(xmm2, Address(rsp, 32));
+    __ vinsertf128h(xmm3, Address(rsp, 48));
+    __ vinsertf128h(xmm4, Address(rsp, 64));
+    __ vinsertf128h(xmm5, Address(rsp, 80));
+    __ vinsertf128h(xmm6, Address(rsp, 96));
+    __ vinsertf128h(xmm7, Address(rsp,112));
+    __ vinsertf128h(xmm8, Address(rsp,128));
+    __ vinsertf128h(xmm9, Address(rsp,144));
+    __ vinsertf128h(xmm10, Address(rsp,160));
+    __ vinsertf128h(xmm11, Address(rsp,176));
+    __ vinsertf128h(xmm12, Address(rsp,192));
+    __ vinsertf128h(xmm13, Address(rsp,208));
+    __ vinsertf128h(xmm14, Address(rsp,224));
+    __ vinsertf128h(xmm15, Address(rsp,240));
+    __ addptr(rsp, 256);
+  }
+#else
+  assert(!restore_vectors, "vectors are generated only by C2");
+#endif
   // Recover CPU state
   __ pop_CPU_state();
   // Get the rbp described implicitly by the calling convention (no oopMap)
@@ -297,6 +329,12 @@
   __ addptr(rsp, return_offset_in_bytes());
 }
 
+// Is vector's size (in bytes) bigger than a size saved by default?
+// 16 bytes XMM registers are saved by default using fxsave/fxrstor instructions.
+bool SharedRuntime::is_wide_vector(int size) {
+  return size > 16;
+}
+
 // The java_calling_convention describes stack locations as ideal slots on
 // a frame with no abi restrictions. Since we must observe abi restrictions
 // (like the placement of the register window) the slots must be biased by
@@ -590,6 +628,19 @@
   __ jmp(rcx);
 }
 
+static void range_check(MacroAssembler* masm, Register pc_reg, Register temp_reg,
+                        address code_start, address code_end,
+                        Label& L_ok) {
+  Label L_fail;
+  __ lea(temp_reg, ExternalAddress(code_start));
+  __ cmpptr(pc_reg, temp_reg);
+  __ jcc(Assembler::belowEqual, L_fail);
+  __ lea(temp_reg, ExternalAddress(code_end));
+  __ cmpptr(pc_reg, temp_reg);
+  __ jcc(Assembler::below, L_ok);
+  __ bind(L_fail);
+}
+
 static void gen_i2c_adapter(MacroAssembler *masm,
                             int total_args_passed,
                             int comp_args_on_stack,
@@ -605,9 +656,53 @@
   // save code can segv when fxsave instructions find improperly
   // aligned stack pointer.
 
+  // Adapters can be frameless because they do not require the caller
+  // to perform additional cleanup work, such as correcting the stack pointer.
+  // An i2c adapter is frameless because the *caller* frame, which is interpreted,
+  // routinely repairs its own stack pointer (from interpreter_frame_last_sp),
+  // even if a callee has modified the stack pointer.
+  // A c2i adapter is frameless because the *callee* frame, which is interpreted,
+  // routinely repairs its caller's stack pointer (from sender_sp, which is set
+  // up via the senderSP register).
+  // In other words, if *either* the caller or callee is interpreted, we can
+  // get the stack pointer repaired after a call.
+  // This is why c2i and i2c adapters cannot be indefinitely composed.
+  // In particular, if a c2i adapter were to somehow call an i2c adapter,
+  // both caller and callee would be compiled methods, and neither would
+  // clean up the stack pointer changes performed by the two adapters.
+  // If this happens, control eventually transfers back to the compiled
+  // caller, but with an uncorrected stack, causing delayed havoc.
+
   // Pick up the return address
   __ movptr(rax, Address(rsp, 0));
 
+  if (VerifyAdapterCalls &&
+      (Interpreter::code() != NULL || StubRoutines::code1() != NULL)) {
+    // So, let's test for cascading c2i/i2c adapters right now.
+    //  assert(Interpreter::contains($return_addr) ||
+    //         StubRoutines::contains($return_addr),
+    //         "i2c adapter must return to an interpreter frame");
+    __ block_comment("verify_i2c { ");
+    Label L_ok;
+    if (Interpreter::code() != NULL)
+      range_check(masm, rax, r11,
+                  Interpreter::code()->code_start(), Interpreter::code()->code_end(),
+                  L_ok);
+    if (StubRoutines::code1() != NULL)
+      range_check(masm, rax, r11,
+                  StubRoutines::code1()->code_begin(), StubRoutines::code1()->code_end(),
+                  L_ok);
+    if (StubRoutines::code2() != NULL)
+      range_check(masm, rax, r11,
+                  StubRoutines::code2()->code_begin(), StubRoutines::code2()->code_end(),
+                  L_ok);
+    const char* msg = "i2c adapter must return to an interpreter frame";
+    __ block_comment(msg);
+    __ stop(msg);
+    __ bind(L_ok);
+    __ block_comment("} verify_i2ce ");
+  }
+
   // Must preserve original SP for loading incoming arguments because
   // we need to align the outgoing SP for compiled code.
   __ movptr(r11, rsp);
@@ -1366,6 +1461,14 @@
 }
 
 
+// Different signatures may require very different orders for the move
+// to avoid clobbering other arguments.  There's no simple way to
+// order them safely.  Compute a safe order for issuing stores and
+// break any cycles in those stores.  This code is fairly general but
+// it's not necessary on the other platforms so we keep it in the
+// platform dependent code instead of moving it into a shared file.
+// (See bugs 7013347 & 7145024.)
+// Note that this code is specific to LP64.
 class ComputeMoveOrder: public StackObj {
   class MoveOperation: public ResourceObj {
     friend class ComputeMoveOrder;
@@ -1532,6 +1635,86 @@
   }
 };
 
+static void verify_oop_args(MacroAssembler* masm,
+                            methodHandle method,
+                            const BasicType* sig_bt,
+                            const VMRegPair* regs) {
+  Register temp_reg = rbx;  // not part of any compiled calling seq
+  if (VerifyOops) {
+    for (int i = 0; i < method->size_of_parameters(); i++) {
+      if (sig_bt[i] == T_OBJECT ||
+          sig_bt[i] == T_ARRAY) {
+        VMReg r = regs[i].first();
+        assert(r->is_valid(), "bad oop arg");
+        if (r->is_stack()) {
+          __ movptr(temp_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
+          __ verify_oop(temp_reg);
+        } else {
+          __ verify_oop(r->as_Register());
+        }
+      }
+    }
+  }
+}
+
+static void gen_special_dispatch(MacroAssembler* masm,
+                                 methodHandle method,
+                                 const BasicType* sig_bt,
+                                 const VMRegPair* regs) {
+  verify_oop_args(masm, method, sig_bt, regs);
+  vmIntrinsics::ID iid = method->intrinsic_id();
+
+  // Now write the args into the outgoing interpreter space
+  bool     has_receiver   = false;
+  Register receiver_reg   = noreg;
+  int      member_arg_pos = -1;
+  Register member_reg     = noreg;
+  int      ref_kind       = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid);
+  if (ref_kind != 0) {
+    member_arg_pos = method->size_of_parameters() - 1;  // trailing MemberName argument
+    member_reg = rbx;  // known to be free at this point
+    has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind);
+  } else if (iid == vmIntrinsics::_invokeBasic) {
+    has_receiver = true;
+  } else {
+    fatal(err_msg_res("unexpected intrinsic id %d", iid));
+  }
+
+  if (member_reg != noreg) {
+    // Load the member_arg into register, if necessary.
+    SharedRuntime::check_member_name_argument_is_last_argument(method, sig_bt, regs);
+    VMReg r = regs[member_arg_pos].first();
+    if (r->is_stack()) {
+      __ movptr(member_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
+    } else {
+      // no data motion is needed
+      member_reg = r->as_Register();
+    }
+  }
+
+  if (has_receiver) {
+    // Make sure the receiver is loaded into a register.
+    assert(method->size_of_parameters() > 0, "oob");
+    assert(sig_bt[0] == T_OBJECT, "receiver argument must be an object");
+    VMReg r = regs[0].first();
+    assert(r->is_valid(), "bad receiver arg");
+    if (r->is_stack()) {
+      // Porting note:  This assumes that compiled calling conventions always
+      // pass the receiver oop in a register.  If this is not true on some
+      // platform, pick a temp and load the receiver from stack.
+      fatal("receiver always in a register");
+      receiver_reg = j_rarg0;  // known to be free at this point
+      __ movptr(receiver_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize));
+    } else {
+      // no data motion is needed
+      receiver_reg = r->as_Register();
+    }
+  }
+
+  // Figure out which address we are really jumping to:
+  MethodHandles::generate_method_handle_dispatch(masm, iid,
+                                                 receiver_reg, member_reg, /*for_compiler_entry:*/ true);
+}
 
 // ---------------------------------------------------------------------------
 // Generate a native wrapper for a given method.  The method takes arguments
@@ -1539,14 +1722,56 @@
 // convention (handlizes oops, etc), transitions to native, makes the call,
 // returns to java state (possibly blocking), unhandlizes any result and
 // returns.
-nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler *masm,
+//
+// Critical native functions are a shorthand for the use of
+// GetPrimtiveArrayCritical and disallow the use of any other JNI
+// functions.  The wrapper is expected to unpack the arguments before
+// passing them to the callee and perform checks before and after the
+// native call to ensure that they GC_locker
+// lock_critical/unlock_critical semantics are followed.  Some other
+// parts of JNI setup are skipped like the tear down of the JNI handle
+// block and the check for pending exceptions it's impossible for them
+// to be thrown.
+//
+// They are roughly structured like this:
+//    if (GC_locker::needs_gc())
+//      SharedRuntime::block_for_jni_critical();
+//    tranistion to thread_in_native
+//    unpack arrray arguments and call native entry point
+//    check for safepoint in progress
+//    check if any thread suspend flags are set
+//      call into JVM and possible unlock the JNI critical
+//      if a GC was suppressed while in the critical native.
+//    transition back to thread_in_Java
+//    return to caller
+//
+nmethod* SharedRuntime::generate_native_wrapper(MacroAssembler* masm,
                                                 methodHandle method,
                                                 int compile_id,
-                                                int total_in_args,
-                                                int comp_args_on_stack,
-                                                BasicType *in_sig_bt,
-                                                VMRegPair *in_regs,
+                                                BasicType* in_sig_bt,
+                                                VMRegPair* in_regs,
                                                 BasicType ret_type) {
+  if (method->is_method_handle_intrinsic()) {
+    vmIntrinsics::ID iid = method->intrinsic_id();
+    intptr_t start = (intptr_t)__ pc();
+    int vep_offset = ((intptr_t)__ pc()) - start;
+    gen_special_dispatch(masm,
+                         method,
+                         in_sig_bt,
+                         in_regs);
+    int frame_complete = ((intptr_t)__ pc()) - start;  // not complete, period
+    __ flush();
+    int stack_slots = SharedRuntime::out_preserve_stack_slots();  // no out slots at all, actually
+    return nmethod::new_native_nmethod(method,
+                                       compile_id,
+                                       masm->code(),
+                                       vep_offset,
+                                       frame_complete,
+                                       stack_slots / VMRegImpl::slots_per_word,
+                                       in_ByteSize(-1),
+                                       in_ByteSize(-1),
+                                       (OopMapSet*)NULL);
+  }
   bool is_critical_native = true;
   address native_func = method->critical_native_function();
   if (native_func == NULL) {
@@ -1565,6 +1790,7 @@
   // we convert the java signature to a C signature by inserting
   // the hidden arguments as arg[0] and possibly arg[1] (static method)
 
+  const int total_in_args = method->size_of_parameters();
   int total_c_args = total_in_args;
   if (!is_critical_native) {
     total_c_args += 1;
@@ -1658,7 +1884,7 @@
           case T_SHORT:
           case T_CHAR:
           case T_INT:  single_slots++; break;
-          case T_ARRAY:
+          case T_ARRAY:  // specific to LP64 (7145024)
           case T_LONG: double_slots++; break;
           default:  ShouldNotReachHere();
         }
@@ -3052,7 +3278,6 @@
   return 0;
 }
 
-
 //------------------------------generate_deopt_blob----------------------------
 void SharedRuntime::generate_deopt_blob() {
   // Allocate space for the code
@@ -3557,7 +3782,7 @@
 // Generate a special Compile2Runtime blob that saves all registers,
 // and setup oopmap.
 //
-SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) {
+SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) {
   assert(StubRoutines::forward_exception_entry() != NULL,
          "must be generated before");
 
@@ -3572,6 +3797,8 @@
   address start   = __ pc();
   address call_pc = NULL;
   int frame_size_in_words;
+  bool cause_return = (poll_type == POLL_AT_RETURN);
+  bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP);
 
   // Make room for return address (or push it again)
   if (!cause_return) {
@@ -3579,7 +3806,7 @@
   }
 
   // Save registers, fpu state, and flags
-  map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
+  map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words, save_vectors);
 
   // The following is basically a call_VM.  However, we need the precise
   // address of the call in order to generate an oopmap. Hence, we do all the
@@ -3616,7 +3843,7 @@
 
   // Exception pending
 
-  RegisterSaver::restore_live_registers(masm);
+  RegisterSaver::restore_live_registers(masm, save_vectors);
 
   __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
 
@@ -3624,7 +3851,7 @@
   __ bind(noException);
 
   // Normal exit, restore registers and exit.
-  RegisterSaver::restore_live_registers(masm);
+  RegisterSaver::restore_live_registers(masm, save_vectors);
 
   __ ret(0);
 
@@ -3792,8 +4019,12 @@
   //
   // address OptoRuntime::handle_exception_C(JavaThread* thread)
 
-  __ set_last_Java_frame(noreg, noreg, NULL);
+  // At a method handle call, the stack may not be properly aligned
+  // when returning with an exception.
+  address the_pc = __ pc();
+  __ set_last_Java_frame(noreg, noreg, the_pc);
   __ mov(c_rarg0, r15_thread);
+  __ andptr(rsp, -(StackAlignmentInBytes));    // Align stack
   __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C)));
 
   // Set an oopmap for the call site.  This oopmap will only be used if we
@@ -3804,9 +4035,9 @@
 
   OopMapSet* oop_maps = new OopMapSet();
 
-  oop_maps->add_gc_map( __ pc()-start, new OopMap(SimpleRuntimeFrame::framesize, 0));
+  oop_maps->add_gc_map(the_pc - start, new OopMap(SimpleRuntimeFrame::framesize, 0));
 
-  __ reset_last_Java_frame(false, false);
+  __ reset_last_Java_frame(false, true);
 
   // Restore callee-saved registers
 
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
index 4d4e66f..fc696a6 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_32.cpp
@@ -2136,13 +2136,548 @@
       __ trigfunc('t');
       __ ret(0);
     }
+    {
+      StubCodeMark mark(this, "StubRoutines", "exp");
+      StubRoutines::_intrinsic_exp = (double (*)(double)) __ pc();
 
-    // The intrinsic version of these seem to return the same value as
-    // the strict version.
-    StubRoutines::_intrinsic_exp = SharedRuntime::dexp;
-    StubRoutines::_intrinsic_pow = SharedRuntime::dpow;
+      __ fld_d(Address(rsp, 4));
+      __ exp_with_fallback(0);
+      __ ret(0);
+    }
+    {
+      StubCodeMark mark(this, "StubRoutines", "pow");
+      StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc();
+
+      __ fld_d(Address(rsp, 12));
+      __ fld_d(Address(rsp, 4));
+      __ pow_with_fallback(0);
+      __ ret(0);
+    }
   }
 
+  // AES intrinsic stubs
+  enum {AESBlockSize = 16};
+
+  address generate_key_shuffle_mask() {
+    __ align(16);
+    StubCodeMark mark(this, "StubRoutines", "key_shuffle_mask");
+    address start = __ pc();
+    __ emit_data(0x00010203, relocInfo::none, 0 );
+    __ emit_data(0x04050607, relocInfo::none, 0 );
+    __ emit_data(0x08090a0b, relocInfo::none, 0 );
+    __ emit_data(0x0c0d0e0f, relocInfo::none, 0 );
+    return start;
+  }
+
+  // Utility routine for loading a 128-bit key word in little endian format
+  // can optionally specify that the shuffle mask is already in an xmmregister
+  void load_key(XMMRegister xmmdst, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
+    __ movdqu(xmmdst, Address(key, offset));
+    if (xmm_shuf_mask != NULL) {
+      __ pshufb(xmmdst, xmm_shuf_mask);
+    } else {
+      __ pshufb(xmmdst, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    }
+  }
+
+  // aesenc using specified key+offset
+  // can optionally specify that the shuffle mask is already in an xmmregister
+  void aes_enc_key(XMMRegister xmmdst, XMMRegister xmmtmp, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
+    load_key(xmmtmp, key, offset, xmm_shuf_mask);
+    __ aesenc(xmmdst, xmmtmp);
+  }
+
+  // aesdec using specified key+offset
+  // can optionally specify that the shuffle mask is already in an xmmregister
+  void aes_dec_key(XMMRegister xmmdst, XMMRegister xmmtmp, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
+    load_key(xmmtmp, key, offset, xmm_shuf_mask);
+    __ aesdec(xmmdst, xmmtmp);
+  }
+
+
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - source byte array address
+  //   c_rarg1   - destination byte array address
+  //   c_rarg2   - K (key) in little endian int array
+  //
+  address generate_aescrypt_encryptBlock() {
+    assert(UseAES && (UseAVX > 0), "need AES instructions and misaligned SSE support");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock");
+    Label L_doLast;
+    address start = __ pc();
+
+    const Register from        = rsi;      // source array address
+    const Register to          = rdx;      // destination array address
+    const Register key         = rcx;      // key array address
+    const Register keylen      = rax;
+    const Address  from_param(rbp, 8+0);
+    const Address  to_param  (rbp, 8+4);
+    const Address  key_param (rbp, 8+8);
+
+    const XMMRegister xmm_result = xmm0;
+    const XMMRegister xmm_temp   = xmm1;
+    const XMMRegister xmm_key_shuf_mask = xmm2;
+
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+    __ push(rsi);
+    __ movptr(from , from_param);
+    __ movptr(to   , to_param);
+    __ movptr(key  , key_param);
+
+    __ movl(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+    // keylen = # of 32-bit words, convert to 128-bit words
+    __ shrl(keylen, 2);
+    __ subl(keylen, 11);   // every key has at least 11 128-bit words, some have more
+
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    __ movdqu(xmm_result, Address(from, 0));  // get 16 bytes of input
+
+    // For encryption, the java expanded key ordering is just what we need
+
+    load_key(xmm_temp, key, 0x00, xmm_key_shuf_mask);
+    __ pxor(xmm_result, xmm_temp);
+    for (int offset = 0x10; offset <= 0x90; offset += 0x10) {
+      aes_enc_key(xmm_result, xmm_temp, key, offset, xmm_key_shuf_mask);
+    }
+    load_key  (xmm_temp, key, 0xa0, xmm_key_shuf_mask);
+    __ cmpl(keylen, 0);
+    __ jcc(Assembler::equal, L_doLast);
+    __ aesenc(xmm_result, xmm_temp);                   // only in 192 and 256 bit keys
+    aes_enc_key(xmm_result, xmm_temp, key, 0xb0, xmm_key_shuf_mask);
+    load_key(xmm_temp, key, 0xc0, xmm_key_shuf_mask);
+    __ subl(keylen, 2);
+    __ jcc(Assembler::equal, L_doLast);
+    __ aesenc(xmm_result, xmm_temp);                   // only in 256 bit keys
+    aes_enc_key(xmm_result, xmm_temp, key, 0xd0, xmm_key_shuf_mask);
+    load_key(xmm_temp, key, 0xe0, xmm_key_shuf_mask);
+
+    __ BIND(L_doLast);
+    __ aesenclast(xmm_result, xmm_temp);
+    __ movdqu(Address(to, 0), xmm_result);        // store the result
+    __ xorptr(rax, rax); // return 0
+    __ pop(rsi);
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    return start;
+  }
+
+
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - source byte array address
+  //   c_rarg1   - destination byte array address
+  //   c_rarg2   - K (key) in little endian int array
+  //
+  address generate_aescrypt_decryptBlock() {
+    assert(UseAES && (UseAVX > 0), "need AES instructions and misaligned SSE support");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock");
+    Label L_doLast;
+    address start = __ pc();
+
+    const Register from        = rsi;      // source array address
+    const Register to          = rdx;      // destination array address
+    const Register key         = rcx;      // key array address
+    const Register keylen      = rax;
+    const Address  from_param(rbp, 8+0);
+    const Address  to_param  (rbp, 8+4);
+    const Address  key_param (rbp, 8+8);
+
+    const XMMRegister xmm_result = xmm0;
+    const XMMRegister xmm_temp   = xmm1;
+    const XMMRegister xmm_key_shuf_mask = xmm2;
+
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+    __ push(rsi);
+    __ movptr(from , from_param);
+    __ movptr(to   , to_param);
+    __ movptr(key  , key_param);
+
+    __ movl(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+    // keylen = # of 32-bit words, convert to 128-bit words
+    __ shrl(keylen, 2);
+    __ subl(keylen, 11);   // every key has at least 11 128-bit words, some have more
+
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    __ movdqu(xmm_result, Address(from, 0));
+
+    // for decryption java expanded key ordering is rotated one position from what we want
+    // so we start from 0x10 here and hit 0x00 last
+    // we don't know if the key is aligned, hence not using load-execute form
+    load_key(xmm_temp, key, 0x10, xmm_key_shuf_mask);
+    __ pxor  (xmm_result, xmm_temp);
+    for (int offset = 0x20; offset <= 0xa0; offset += 0x10) {
+      aes_dec_key(xmm_result, xmm_temp, key, offset, xmm_key_shuf_mask);
+    }
+    __ cmpl(keylen, 0);
+    __ jcc(Assembler::equal, L_doLast);
+    // only in 192 and 256 bit keys
+    aes_dec_key(xmm_result, xmm_temp, key, 0xb0, xmm_key_shuf_mask);
+    aes_dec_key(xmm_result, xmm_temp, key, 0xc0, xmm_key_shuf_mask);
+    __ subl(keylen, 2);
+    __ jcc(Assembler::equal, L_doLast);
+    // only in 256 bit keys
+    aes_dec_key(xmm_result, xmm_temp, key, 0xd0, xmm_key_shuf_mask);
+    aes_dec_key(xmm_result, xmm_temp, key, 0xe0, xmm_key_shuf_mask);
+
+    __ BIND(L_doLast);
+    // for decryption the aesdeclast operation is always on key+0x00
+    load_key(xmm_temp, key, 0x00, xmm_key_shuf_mask);
+    __ aesdeclast(xmm_result, xmm_temp);
+
+    __ movdqu(Address(to, 0), xmm_result);  // store the result
+
+    __ xorptr(rax, rax); // return 0
+    __ pop(rsi);
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    return start;
+  }
+
+  void handleSOERegisters(bool saving) {
+    const int saveFrameSizeInBytes = 4 * wordSize;
+    const Address saved_rbx     (rbp, -3 * wordSize);
+    const Address saved_rsi     (rbp, -2 * wordSize);
+    const Address saved_rdi     (rbp, -1 * wordSize);
+
+    if (saving) {
+      __ subptr(rsp, saveFrameSizeInBytes);
+      __ movptr(saved_rsi, rsi);
+      __ movptr(saved_rdi, rdi);
+      __ movptr(saved_rbx, rbx);
+    } else {
+      // restoring
+      __ movptr(rsi, saved_rsi);
+      __ movptr(rdi, saved_rdi);
+      __ movptr(rbx, saved_rbx);
+    }
+  }
+
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - source byte array address
+  //   c_rarg1   - destination byte array address
+  //   c_rarg2   - K (key) in little endian int array
+  //   c_rarg3   - r vector byte array address
+  //   c_rarg4   - input length
+  //
+  address generate_cipherBlockChaining_encryptAESCrypt() {
+    assert(UseAES && (UseAVX > 0), "need AES instructions and misaligned SSE support");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt");
+    address start = __ pc();
+
+    Label L_exit, L_key_192_256, L_key_256, L_loopTop_128, L_loopTop_192, L_loopTop_256;
+    const Register from        = rsi;      // source array address
+    const Register to          = rdx;      // destination array address
+    const Register key         = rcx;      // key array address
+    const Register rvec        = rdi;      // r byte array initialized from initvector array address
+                                           // and left with the results of the last encryption block
+    const Register len_reg     = rbx;      // src len (must be multiple of blocksize 16)
+    const Register pos         = rax;
+
+    // xmm register assignments for the loops below
+    const XMMRegister xmm_result = xmm0;
+    const XMMRegister xmm_temp   = xmm1;
+    // first 6 keys preloaded into xmm2-xmm7
+    const int XMM_REG_NUM_KEY_FIRST = 2;
+    const int XMM_REG_NUM_KEY_LAST  = 7;
+    const XMMRegister xmm_key0   = as_XMMRegister(XMM_REG_NUM_KEY_FIRST);
+
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+    handleSOERegisters(true /*saving*/);
+
+    // load registers from incoming parameters
+    const Address  from_param(rbp, 8+0);
+    const Address  to_param  (rbp, 8+4);
+    const Address  key_param (rbp, 8+8);
+    const Address  rvec_param (rbp, 8+12);
+    const Address  len_param  (rbp, 8+16);
+    __ movptr(from , from_param);
+    __ movptr(to   , to_param);
+    __ movptr(key  , key_param);
+    __ movptr(rvec , rvec_param);
+    __ movptr(len_reg , len_param);
+
+    const XMMRegister xmm_key_shuf_mask = xmm_temp;  // used temporarily to swap key bytes up front
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    // load up xmm regs 2 thru 7 with keys 0-5
+    for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x00; rnum  <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask);
+      offset += 0x10;
+    }
+
+    __ movdqu(xmm_result, Address(rvec, 0x00));   // initialize xmm_result with r vec
+
+    // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256))
+    __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+    __ cmpl(rax, 44);
+    __ jcc(Assembler::notEqual, L_key_192_256);
+
+    // 128 bit code follows here
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_loopTop_128);
+    __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of input
+    __ pxor  (xmm_result, xmm_temp);                                // xor with the current r vector
+
+    __ pxor  (xmm_result, xmm_key0);                                // do the aes rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum  <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      __ aesenc(xmm_result, as_XMMRegister(rnum));
+    }
+    for (int key_offset = 0x60; key_offset <= 0x90; key_offset += 0x10) {
+      aes_enc_key(xmm_result, xmm_temp, key, key_offset);
+    }
+    load_key(xmm_temp, key, 0xa0);
+    __ aesenclast(xmm_result, xmm_temp);
+
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual, L_loopTop_128);
+
+    __ BIND(L_exit);
+    __ movdqu(Address(rvec, 0), xmm_result);     // final value of r stored in rvec of CipherBlockChaining object
+
+    handleSOERegisters(false /*restoring*/);
+    __ movl(rax, 0);                             // return 0 (why?)
+    __ leave();                                  // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+  __ BIND(L_key_192_256);
+  // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256)
+    __ cmpl(rax, 52);
+    __ jcc(Assembler::notEqual, L_key_256);
+
+    // 192-bit code follows here (could be changed to use more xmm registers)
+    __ movptr(pos, 0);
+  __ align(OptoLoopAlignment);
+  __ BIND(L_loopTop_192);
+    __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of input
+    __ pxor  (xmm_result, xmm_temp);                                // xor with the current r vector
+
+    __ pxor  (xmm_result, xmm_key0);                                // do the aes rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum  <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      __ aesenc(xmm_result, as_XMMRegister(rnum));
+    }
+    for (int key_offset = 0x60; key_offset <= 0xb0; key_offset += 0x10) {
+      aes_enc_key(xmm_result, xmm_temp, key, key_offset);
+    }
+    load_key(xmm_temp, key, 0xc0);
+    __ aesenclast(xmm_result, xmm_temp);
+
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);   // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual, L_loopTop_192);
+    __ jmp(L_exit);
+
+  __ BIND(L_key_256);
+    // 256-bit code follows here (could be changed to use more xmm registers)
+    __ movptr(pos, 0);
+  __ align(OptoLoopAlignment);
+  __ BIND(L_loopTop_256);
+    __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of input
+    __ pxor  (xmm_result, xmm_temp);                                // xor with the current r vector
+
+    __ pxor  (xmm_result, xmm_key0);                                // do the aes rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum  <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      __ aesenc(xmm_result, as_XMMRegister(rnum));
+    }
+    for (int key_offset = 0x60; key_offset <= 0xd0; key_offset += 0x10) {
+      aes_enc_key(xmm_result, xmm_temp, key, key_offset);
+    }
+    load_key(xmm_temp, key, 0xe0);
+    __ aesenclast(xmm_result, xmm_temp);
+
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);   // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual, L_loopTop_256);
+    __ jmp(L_exit);
+
+    return start;
+  }
+
+
+  // CBC AES Decryption.
+  // In 32-bit stub, because of lack of registers we do not try to parallelize 4 blocks at a time.
+  //
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - source byte array address
+  //   c_rarg1   - destination byte array address
+  //   c_rarg2   - K (key) in little endian int array
+  //   c_rarg3   - r vector byte array address
+  //   c_rarg4   - input length
+  //
+
+  address generate_cipherBlockChaining_decryptAESCrypt() {
+    assert(UseAES && (UseAVX > 0), "need AES instructions and misaligned SSE support");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt");
+    address start = __ pc();
+
+    Label L_exit, L_key_192_256, L_key_256;
+    Label L_singleBlock_loopTop_128;
+    Label L_singleBlock_loopTop_192, L_singleBlock_loopTop_256;
+    const Register from        = rsi;      // source array address
+    const Register to          = rdx;      // destination array address
+    const Register key         = rcx;      // key array address
+    const Register rvec        = rdi;      // r byte array initialized from initvector array address
+                                           // and left with the results of the last encryption block
+    const Register len_reg     = rbx;      // src len (must be multiple of blocksize 16)
+    const Register pos         = rax;
+
+    // xmm register assignments for the loops below
+    const XMMRegister xmm_result = xmm0;
+    const XMMRegister xmm_temp   = xmm1;
+    // first 6 keys preloaded into xmm2-xmm7
+    const int XMM_REG_NUM_KEY_FIRST = 2;
+    const int XMM_REG_NUM_KEY_LAST  = 7;
+    const int FIRST_NON_REG_KEY_offset = 0x70;
+    const XMMRegister xmm_key_first   = as_XMMRegister(XMM_REG_NUM_KEY_FIRST);
+
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+    handleSOERegisters(true /*saving*/);
+
+    // load registers from incoming parameters
+    const Address  from_param(rbp, 8+0);
+    const Address  to_param  (rbp, 8+4);
+    const Address  key_param (rbp, 8+8);
+    const Address  rvec_param (rbp, 8+12);
+    const Address  len_param  (rbp, 8+16);
+    __ movptr(from , from_param);
+    __ movptr(to   , to_param);
+    __ movptr(key  , key_param);
+    __ movptr(rvec , rvec_param);
+    __ movptr(len_reg , len_param);
+
+    // the java expanded key ordering is rotated one position from what we want
+    // so we start from 0x10 here and hit 0x00 last
+    const XMMRegister xmm_key_shuf_mask = xmm1;  // used temporarily to swap key bytes up front
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    // load up xmm regs 2 thru 6 with first 5 keys
+    for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x10; rnum  <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask);
+      offset += 0x10;
+    }
+
+    // inside here, use the rvec register to point to previous block cipher
+    // with which we xor at the end of each newly decrypted block
+    const Register  prev_block_cipher_ptr = rvec;
+
+    // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256))
+    __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+    __ cmpl(rax, 44);
+    __ jcc(Assembler::notEqual, L_key_192_256);
+
+
+    // 128-bit code follows here, parallelized
+    __ movptr(pos, 0);
+  __ align(OptoLoopAlignment);
+  __ BIND(L_singleBlock_loopTop_128);
+    __ cmpptr(len_reg, 0);           // any blocks left??
+    __ jcc(Assembler::equal, L_exit);
+    __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of cipher input
+    __ pxor  (xmm_result, xmm_key_first);                             // do the aes dec rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum  <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      __ aesdec(xmm_result, as_XMMRegister(rnum));
+    }
+    for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xa0; key_offset += 0x10) {   // 128-bit runs up to key offset a0
+      aes_dec_key(xmm_result, xmm_temp, key, key_offset);
+    }
+    load_key(xmm_temp, key, 0x00);                                     // final key is stored in java expanded array at offset 0
+    __ aesdeclast(xmm_result, xmm_temp);
+    __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00));
+    __ pxor  (xmm_result, xmm_temp);                                  // xor with the current r vector
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0));     // set up new ptr
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jmp(L_singleBlock_loopTop_128);
+
+
+    __ BIND(L_exit);
+    __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00));
+    __ movptr(rvec , rvec_param);                                     // restore this since used in loop
+    __ movdqu(Address(rvec, 0), xmm_temp);                            // final value of r stored in rvec of CipherBlockChaining object
+    handleSOERegisters(false /*restoring*/);
+    __ movl(rax, 0);                                                  // return 0 (why?)
+    __ leave();                                                       // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+
+    __ BIND(L_key_192_256);
+    // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256)
+    __ cmpl(rax, 52);
+    __ jcc(Assembler::notEqual, L_key_256);
+
+    // 192-bit code follows here (could be optimized to use parallelism)
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_singleBlock_loopTop_192);
+    __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of cipher input
+    __ pxor  (xmm_result, xmm_key_first);                             // do the aes dec rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      __ aesdec(xmm_result, as_XMMRegister(rnum));
+    }
+    for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xc0; key_offset += 0x10) {   // 192-bit runs up to key offset c0
+      aes_dec_key(xmm_result, xmm_temp, key, key_offset);
+    }
+    load_key(xmm_temp, key, 0x00);                                     // final key is stored in java expanded array at offset 0
+    __ aesdeclast(xmm_result, xmm_temp);
+    __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00));
+    __ pxor  (xmm_result, xmm_temp);                                  // xor with the current r vector
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0));     // set up new ptr
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual,L_singleBlock_loopTop_192);
+    __ jmp(L_exit);
+
+    __ BIND(L_key_256);
+    // 256-bit code follows here (could be optimized to use parallelism)
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_singleBlock_loopTop_256);
+    __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of cipher input
+    __ pxor  (xmm_result, xmm_key_first);                             // do the aes dec rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      __ aesdec(xmm_result, as_XMMRegister(rnum));
+    }
+    for (int key_offset = FIRST_NON_REG_KEY_offset; key_offset <= 0xe0; key_offset += 0x10) {   // 256-bit runs up to key offset e0
+      aes_dec_key(xmm_result, xmm_temp, key, key_offset);
+    }
+    load_key(xmm_temp, key, 0x00);                                     // final key is stored in java expanded array at offset 0
+    __ aesdeclast(xmm_result, xmm_temp);
+    __ movdqu(xmm_temp, Address(prev_block_cipher_ptr, 0x00));
+    __ pxor  (xmm_result, xmm_temp);                                  // xor with the current r vector
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ lea(prev_block_cipher_ptr, Address(from, pos, Address::times_1, 0));     // set up new ptr
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual,L_singleBlock_loopTop_256);
+    __ jmp(L_exit);
+
+    return start;
+  }
+
+
  public:
   // Information about frame layout at time of blocking runtime call.
   // Note that we only have to preserve callee-saved registers since
@@ -2315,12 +2850,6 @@
                                                                                    CAST_FROM_FN_PTR(address, SharedRuntime::d2l));
 
     // Build this early so it's available for the interpreter
-    StubRoutines::_throw_WrongMethodTypeException_entry =
-      generate_throw_exception("WrongMethodTypeException throw_exception",
-                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException),
-                               rax, rcx);
-
-    // Build this early so it's available for the interpreter
     StubRoutines::_throw_StackOverflowError_entry          = generate_throw_exception("StackOverflowError throw_exception",           CAST_FROM_FN_PTR(address, SharedRuntime::throw_StackOverflowError));
   }
 
@@ -2344,6 +2873,16 @@
     generate_arraycopy_stubs();
 
     generate_math_stubs();
+
+    // don't bother generating these AES intrinsic stubs unless global flag is set
+    if (UseAESIntrinsics) {
+      StubRoutines::x86::_key_shuffle_mask_addr = generate_key_shuffle_mask();  // might be needed by the others
+
+      StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
+      StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
+      StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
+      StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt();
+    }
   }
 
 
diff --git a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
index d68bdac..4af8e61 100644
--- a/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/stubGenerator_x86_64.cpp
@@ -710,6 +710,21 @@
     return start;
   }
 
+  // Support for intptr_t get_previous_sp()
+  //
+  // This routine is used to find the previous stack pointer for the
+  // caller.
+  address generate_get_previous_sp() {
+    StubCodeMark mark(this, "StubRoutines", "get_previous_sp");
+    address start = __ pc();
+
+    __ movptr(rax, rsp);
+    __ addptr(rax, 8); // return address is at the top of the stack.
+    __ ret(0);
+
+    return start;
+  }
+
   //----------------------------------------------------------------------------------------------------
   // Support for void verify_mxcsr()
   //
@@ -2913,13 +2928,578 @@
       __ addq(rsp, 8);
       __ ret(0);
     }
+    {
+      StubCodeMark mark(this, "StubRoutines", "exp");
+      StubRoutines::_intrinsic_exp = (double (*)(double)) __ pc();
 
-    // The intrinsic version of these seem to return the same value as
-    // the strict version.
-    StubRoutines::_intrinsic_exp = SharedRuntime::dexp;
-    StubRoutines::_intrinsic_pow = SharedRuntime::dpow;
+      __ subq(rsp, 8);
+      __ movdbl(Address(rsp, 0), xmm0);
+      __ fld_d(Address(rsp, 0));
+      __ exp_with_fallback(0);
+      __ fstp_d(Address(rsp, 0));
+      __ movdbl(xmm0, Address(rsp, 0));
+      __ addq(rsp, 8);
+      __ ret(0);
+    }
+    {
+      StubCodeMark mark(this, "StubRoutines", "pow");
+      StubRoutines::_intrinsic_pow = (double (*)(double,double)) __ pc();
+
+      __ subq(rsp, 8);
+      __ movdbl(Address(rsp, 0), xmm1);
+      __ fld_d(Address(rsp, 0));
+      __ movdbl(Address(rsp, 0), xmm0);
+      __ fld_d(Address(rsp, 0));
+      __ pow_with_fallback(0);
+      __ fstp_d(Address(rsp, 0));
+      __ movdbl(xmm0, Address(rsp, 0));
+      __ addq(rsp, 8);
+      __ ret(0);
+    }
   }
 
+  // AES intrinsic stubs
+  enum {AESBlockSize = 16};
+
+  address generate_key_shuffle_mask() {
+    __ align(16);
+    StubCodeMark mark(this, "StubRoutines", "key_shuffle_mask");
+    address start = __ pc();
+    __ emit_data64( 0x0405060700010203, relocInfo::none );
+    __ emit_data64( 0x0c0d0e0f08090a0b, relocInfo::none );
+    return start;
+  }
+
+  // Utility routine for loading a 128-bit key word in little endian format
+  // can optionally specify that the shuffle mask is already in an xmmregister
+  void load_key(XMMRegister xmmdst, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
+    __ movdqu(xmmdst, Address(key, offset));
+    if (xmm_shuf_mask != NULL) {
+      __ pshufb(xmmdst, xmm_shuf_mask);
+    } else {
+      __ pshufb(xmmdst, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    }
+  }
+
+  // aesenc using specified key+offset
+  // can optionally specify that the shuffle mask is already in an xmmregister
+  void aes_enc_key(XMMRegister xmmdst, XMMRegister xmmtmp, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
+    load_key(xmmtmp, key, offset, xmm_shuf_mask);
+    __ aesenc(xmmdst, xmmtmp);
+  }
+
+  // aesdec using specified key+offset
+  // can optionally specify that the shuffle mask is already in an xmmregister
+  void aes_dec_key(XMMRegister xmmdst, XMMRegister xmmtmp, Register key, int offset, XMMRegister xmm_shuf_mask=NULL) {
+    load_key(xmmtmp, key, offset, xmm_shuf_mask);
+    __ aesdec(xmmdst, xmmtmp);
+  }
+
+
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - source byte array address
+  //   c_rarg1   - destination byte array address
+  //   c_rarg2   - K (key) in little endian int array
+  //
+  address generate_aescrypt_encryptBlock() {
+    assert(UseAES && (UseAVX > 0), "need AES instructions and misaligned SSE support");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "aescrypt_encryptBlock");
+    Label L_doLast;
+    address start = __ pc();
+
+    const Register from        = c_rarg0;  // source array address
+    const Register to          = c_rarg1;  // destination array address
+    const Register key         = c_rarg2;  // key array address
+    const Register keylen      = rax;
+
+    const XMMRegister xmm_result = xmm0;
+    const XMMRegister xmm_temp   = xmm1;
+    const XMMRegister xmm_key_shuf_mask = xmm2;
+
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+
+    __ movl(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+    // keylen = # of 32-bit words, convert to 128-bit words
+    __ shrl(keylen, 2);
+    __ subl(keylen, 11);   // every key has at least 11 128-bit words, some have more
+
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    __ movdqu(xmm_result, Address(from, 0));  // get 16 bytes of input
+
+    // For encryption, the java expanded key ordering is just what we need
+    // we don't know if the key is aligned, hence not using load-execute form
+
+    load_key(xmm_temp, key, 0x00, xmm_key_shuf_mask);
+    __ pxor(xmm_result, xmm_temp);
+    for (int offset = 0x10; offset <= 0x90; offset += 0x10) {
+      aes_enc_key(xmm_result, xmm_temp, key, offset, xmm_key_shuf_mask);
+    }
+    load_key  (xmm_temp, key, 0xa0, xmm_key_shuf_mask);
+    __ cmpl(keylen, 0);
+    __ jcc(Assembler::equal, L_doLast);
+    __ aesenc(xmm_result, xmm_temp);                   // only in 192 and 256 bit keys
+    aes_enc_key(xmm_result, xmm_temp, key, 0xb0, xmm_key_shuf_mask);
+    load_key(xmm_temp, key, 0xc0, xmm_key_shuf_mask);
+    __ subl(keylen, 2);
+    __ jcc(Assembler::equal, L_doLast);
+    __ aesenc(xmm_result, xmm_temp);                   // only in 256 bit keys
+    aes_enc_key(xmm_result, xmm_temp, key, 0xd0, xmm_key_shuf_mask);
+    load_key(xmm_temp, key, 0xe0, xmm_key_shuf_mask);
+
+    __ BIND(L_doLast);
+    __ aesenclast(xmm_result, xmm_temp);
+    __ movdqu(Address(to, 0), xmm_result);        // store the result
+    __ xorptr(rax, rax); // return 0
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    return start;
+  }
+
+
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - source byte array address
+  //   c_rarg1   - destination byte array address
+  //   c_rarg2   - K (key) in little endian int array
+  //
+  address generate_aescrypt_decryptBlock() {
+    assert(UseAES && (UseAVX > 0), "need AES instructions and misaligned SSE support");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "aescrypt_decryptBlock");
+    Label L_doLast;
+    address start = __ pc();
+
+    const Register from        = c_rarg0;  // source array address
+    const Register to          = c_rarg1;  // destination array address
+    const Register key         = c_rarg2;  // key array address
+    const Register keylen      = rax;
+
+    const XMMRegister xmm_result = xmm0;
+    const XMMRegister xmm_temp   = xmm1;
+    const XMMRegister xmm_key_shuf_mask = xmm2;
+
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+
+    __ movl(keylen, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+    // keylen = # of 32-bit words, convert to 128-bit words
+    __ shrl(keylen, 2);
+    __ subl(keylen, 11);   // every key has at least 11 128-bit words, some have more
+
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    __ movdqu(xmm_result, Address(from, 0));
+
+    // for decryption java expanded key ordering is rotated one position from what we want
+    // so we start from 0x10 here and hit 0x00 last
+    // we don't know if the key is aligned, hence not using load-execute form
+    load_key(xmm_temp, key, 0x10, xmm_key_shuf_mask);
+    __ pxor  (xmm_result, xmm_temp);
+    for (int offset = 0x20; offset <= 0xa0; offset += 0x10) {
+      aes_dec_key(xmm_result, xmm_temp, key, offset, xmm_key_shuf_mask);
+    }
+    __ cmpl(keylen, 0);
+    __ jcc(Assembler::equal, L_doLast);
+    // only in 192 and 256 bit keys
+    aes_dec_key(xmm_result, xmm_temp, key, 0xb0, xmm_key_shuf_mask);
+    aes_dec_key(xmm_result, xmm_temp, key, 0xc0, xmm_key_shuf_mask);
+    __ subl(keylen, 2);
+    __ jcc(Assembler::equal, L_doLast);
+    // only in 256 bit keys
+    aes_dec_key(xmm_result, xmm_temp, key, 0xd0, xmm_key_shuf_mask);
+    aes_dec_key(xmm_result, xmm_temp, key, 0xe0, xmm_key_shuf_mask);
+
+    __ BIND(L_doLast);
+    // for decryption the aesdeclast operation is always on key+0x00
+    load_key(xmm_temp, key, 0x00, xmm_key_shuf_mask);
+    __ aesdeclast(xmm_result, xmm_temp);
+
+    __ movdqu(Address(to, 0), xmm_result);  // store the result
+
+    __ xorptr(rax, rax); // return 0
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    return start;
+  }
+
+
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - source byte array address
+  //   c_rarg1   - destination byte array address
+  //   c_rarg2   - K (key) in little endian int array
+  //   c_rarg3   - r vector byte array address
+  //   c_rarg4   - input length
+  //
+  address generate_cipherBlockChaining_encryptAESCrypt() {
+    assert(UseAES && (UseAVX > 0), "need AES instructions and misaligned SSE support");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_encryptAESCrypt");
+    address start = __ pc();
+
+    Label L_exit, L_key_192_256, L_key_256, L_loopTop_128, L_loopTop_192, L_loopTop_256;
+    const Register from        = c_rarg0;  // source array address
+    const Register to          = c_rarg1;  // destination array address
+    const Register key         = c_rarg2;  // key array address
+    const Register rvec        = c_rarg3;  // r byte array initialized from initvector array address
+                                           // and left with the results of the last encryption block
+#ifndef _WIN64
+    const Register len_reg     = c_rarg4;  // src len (must be multiple of blocksize 16)
+#else
+    const Address  len_mem(rsp, 6 * wordSize);  // length is on stack on Win64
+    const Register len_reg     = r10;      // pick the first volatile windows register
+#endif
+    const Register pos         = rax;
+
+    // xmm register assignments for the loops below
+    const XMMRegister xmm_result = xmm0;
+    const XMMRegister xmm_temp   = xmm1;
+    // keys 0-10 preloaded into xmm2-xmm12
+    const int XMM_REG_NUM_KEY_FIRST = 2;
+    const int XMM_REG_NUM_KEY_LAST  = 12;
+    const XMMRegister xmm_key0   = as_XMMRegister(XMM_REG_NUM_KEY_FIRST);
+    const XMMRegister xmm_key10  = as_XMMRegister(XMM_REG_NUM_KEY_LAST);
+
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+
+#ifdef _WIN64
+    // on win64, fill len_reg from stack position
+    __ movl(len_reg, len_mem);
+    // save the xmm registers which must be preserved 6-12
+    __ subptr(rsp, -rsp_after_call_off * wordSize);
+    for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) {
+      __ movdqu(xmm_save(i), as_XMMRegister(i));
+    }
+#endif
+
+    const XMMRegister xmm_key_shuf_mask = xmm_temp;  // used temporarily to swap key bytes up front
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    // load up xmm regs 2 thru 12 with key 0x00 - 0xa0
+    for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x00; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask);
+      offset += 0x10;
+    }
+
+    __ movdqu(xmm_result, Address(rvec, 0x00));   // initialize xmm_result with r vec
+
+    // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256))
+    __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+    __ cmpl(rax, 44);
+    __ jcc(Assembler::notEqual, L_key_192_256);
+
+    // 128 bit code follows here
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_loopTop_128);
+    __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of input
+    __ pxor  (xmm_result, xmm_temp);               // xor with the current r vector
+
+    __ pxor  (xmm_result, xmm_key0);               // do the aes rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
+      __ aesenc(xmm_result, as_XMMRegister(rnum));
+    }
+    __ aesenclast(xmm_result, xmm_key10);
+
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual, L_loopTop_128);
+
+    __ BIND(L_exit);
+    __ movdqu(Address(rvec, 0), xmm_result);     // final value of r stored in rvec of CipherBlockChaining object
+
+#ifdef _WIN64
+    // restore xmm regs belonging to calling function
+    for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) {
+      __ movdqu(as_XMMRegister(i), xmm_save(i));
+    }
+#endif
+    __ movl(rax, 0); // return 0 (why?)
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+    __ BIND(L_key_192_256);
+    // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256)
+    __ cmpl(rax, 52);
+    __ jcc(Assembler::notEqual, L_key_256);
+
+    // 192-bit code follows here (could be changed to use more xmm registers)
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_loopTop_192);
+    __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of input
+    __ pxor  (xmm_result, xmm_temp);               // xor with the current r vector
+
+    __ pxor  (xmm_result, xmm_key0);               // do the aes rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum  <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      __ aesenc(xmm_result, as_XMMRegister(rnum));
+    }
+    aes_enc_key(xmm_result, xmm_temp, key, 0xb0);
+    load_key(xmm_temp, key, 0xc0);
+    __ aesenclast(xmm_result, xmm_temp);
+
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual, L_loopTop_192);
+    __ jmp(L_exit);
+
+    __ BIND(L_key_256);
+    // 256-bit code follows here (could be changed to use more xmm registers)
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_loopTop_256);
+    __ movdqu(xmm_temp, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of input
+    __ pxor  (xmm_result, xmm_temp);               // xor with the current r vector
+
+    __ pxor  (xmm_result, xmm_key0);               // do the aes rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum  <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      __ aesenc(xmm_result, as_XMMRegister(rnum));
+    }
+    aes_enc_key(xmm_result, xmm_temp, key, 0xb0);
+    aes_enc_key(xmm_result, xmm_temp, key, 0xc0);
+    aes_enc_key(xmm_result, xmm_temp, key, 0xd0);
+    load_key(xmm_temp, key, 0xe0);
+    __ aesenclast(xmm_result, xmm_temp);
+
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual, L_loopTop_256);
+    __ jmp(L_exit);
+
+    return start;
+  }
+
+
+
+  // This is a version of CBC/AES Decrypt which does 4 blocks in a loop at a time
+  // to hide instruction latency
+  //
+  // Arguments:
+  //
+  // Inputs:
+  //   c_rarg0   - source byte array address
+  //   c_rarg1   - destination byte array address
+  //   c_rarg2   - K (key) in little endian int array
+  //   c_rarg3   - r vector byte array address
+  //   c_rarg4   - input length
+  //
+
+  address generate_cipherBlockChaining_decryptAESCrypt_Parallel() {
+    assert(UseAES && (UseAVX > 0), "need AES instructions and misaligned SSE support");
+    __ align(CodeEntryAlignment);
+    StubCodeMark mark(this, "StubRoutines", "cipherBlockChaining_decryptAESCrypt");
+    address start = __ pc();
+
+    Label L_exit, L_key_192_256, L_key_256;
+    Label L_singleBlock_loopTop_128, L_multiBlock_loopTop_128;
+    Label L_singleBlock_loopTop_192, L_singleBlock_loopTop_256;
+    const Register from        = c_rarg0;  // source array address
+    const Register to          = c_rarg1;  // destination array address
+    const Register key         = c_rarg2;  // key array address
+    const Register rvec        = c_rarg3;  // r byte array initialized from initvector array address
+                                           // and left with the results of the last encryption block
+#ifndef _WIN64
+    const Register len_reg     = c_rarg4;  // src len (must be multiple of blocksize 16)
+#else
+    const Address  len_mem(rsp, 6 * wordSize);  // length is on stack on Win64
+    const Register len_reg     = r10;      // pick the first volatile windows register
+#endif
+    const Register pos         = rax;
+
+    // xmm register assignments for the loops below
+    const XMMRegister xmm_result = xmm0;
+    // keys 0-10 preloaded into xmm2-xmm12
+    const int XMM_REG_NUM_KEY_FIRST = 5;
+    const int XMM_REG_NUM_KEY_LAST  = 15;
+    const XMMRegister xmm_key_first   = as_XMMRegister(XMM_REG_NUM_KEY_FIRST);
+    const XMMRegister xmm_key_last  = as_XMMRegister(XMM_REG_NUM_KEY_LAST);
+
+    __ enter(); // required for proper stackwalking of RuntimeStub frame
+
+#ifdef _WIN64
+    // on win64, fill len_reg from stack position
+    __ movl(len_reg, len_mem);
+    // save the xmm registers which must be preserved 6-15
+    __ subptr(rsp, -rsp_after_call_off * wordSize);
+    for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) {
+      __ movdqu(xmm_save(i), as_XMMRegister(i));
+    }
+#endif
+    // the java expanded key ordering is rotated one position from what we want
+    // so we start from 0x10 here and hit 0x00 last
+    const XMMRegister xmm_key_shuf_mask = xmm1;  // used temporarily to swap key bytes up front
+    __ movdqu(xmm_key_shuf_mask, ExternalAddress(StubRoutines::x86::key_shuffle_mask_addr()));
+    // load up xmm regs 5 thru 15 with key 0x10 - 0xa0 - 0x00
+    for (int rnum = XMM_REG_NUM_KEY_FIRST, offset = 0x10; rnum <= XMM_REG_NUM_KEY_LAST; rnum++) {
+      if (rnum == XMM_REG_NUM_KEY_LAST) offset = 0x00;
+      load_key(as_XMMRegister(rnum), key, offset, xmm_key_shuf_mask);
+      offset += 0x10;
+    }
+
+    const XMMRegister xmm_prev_block_cipher = xmm1;  // holds cipher of previous block
+    // registers holding the four results in the parallelized loop
+    const XMMRegister xmm_result0 = xmm0;
+    const XMMRegister xmm_result1 = xmm2;
+    const XMMRegister xmm_result2 = xmm3;
+    const XMMRegister xmm_result3 = xmm4;
+
+    __ movdqu(xmm_prev_block_cipher, Address(rvec, 0x00));   // initialize with initial rvec
+
+    // now split to different paths depending on the keylen (len in ints of AESCrypt.KLE array (52=192, or 60=256))
+    __ movl(rax, Address(key, arrayOopDesc::length_offset_in_bytes() - arrayOopDesc::base_offset_in_bytes(T_INT)));
+    __ cmpl(rax, 44);
+    __ jcc(Assembler::notEqual, L_key_192_256);
+
+
+    // 128-bit code follows here, parallelized
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_multiBlock_loopTop_128);
+    __ cmpptr(len_reg, 4*AESBlockSize);           // see if at least 4 blocks left
+    __ jcc(Assembler::less, L_singleBlock_loopTop_128);
+
+    __ movdqu(xmm_result0, Address(from, pos, Address::times_1, 0*AESBlockSize));   // get next 4 blocks into xmmresult registers
+    __ movdqu(xmm_result1, Address(from, pos, Address::times_1, 1*AESBlockSize));
+    __ movdqu(xmm_result2, Address(from, pos, Address::times_1, 2*AESBlockSize));
+    __ movdqu(xmm_result3, Address(from, pos, Address::times_1, 3*AESBlockSize));
+
+#define DoFour(opc, src_reg)                    \
+    __ opc(xmm_result0, src_reg);               \
+    __ opc(xmm_result1, src_reg);               \
+    __ opc(xmm_result2, src_reg);               \
+    __ opc(xmm_result3, src_reg);
+
+    DoFour(pxor, xmm_key_first);
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum  <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
+      DoFour(aesdec, as_XMMRegister(rnum));
+    }
+    DoFour(aesdeclast, xmm_key_last);
+    // for each result, xor with the r vector of previous cipher block
+    __ pxor(xmm_result0, xmm_prev_block_cipher);
+    __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 0*AESBlockSize));
+    __ pxor(xmm_result1, xmm_prev_block_cipher);
+    __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 1*AESBlockSize));
+    __ pxor(xmm_result2, xmm_prev_block_cipher);
+    __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 2*AESBlockSize));
+    __ pxor(xmm_result3, xmm_prev_block_cipher);
+    __ movdqu(xmm_prev_block_cipher, Address(from, pos, Address::times_1, 3*AESBlockSize));   // this will carry over to next set of blocks
+
+    __ movdqu(Address(to, pos, Address::times_1, 0*AESBlockSize), xmm_result0);     // store 4 results into the next 64 bytes of output
+    __ movdqu(Address(to, pos, Address::times_1, 1*AESBlockSize), xmm_result1);
+    __ movdqu(Address(to, pos, Address::times_1, 2*AESBlockSize), xmm_result2);
+    __ movdqu(Address(to, pos, Address::times_1, 3*AESBlockSize), xmm_result3);
+
+    __ addptr(pos, 4*AESBlockSize);
+    __ subptr(len_reg, 4*AESBlockSize);
+    __ jmp(L_multiBlock_loopTop_128);
+
+    // registers used in the non-parallelized loops
+    const XMMRegister xmm_prev_block_cipher_save = xmm2;
+    const XMMRegister xmm_temp   = xmm3;
+
+    __ align(OptoLoopAlignment);
+    __ BIND(L_singleBlock_loopTop_128);
+    __ cmpptr(len_reg, 0);           // any blocks left??
+    __ jcc(Assembler::equal, L_exit);
+    __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of cipher input
+    __ movdqa(xmm_prev_block_cipher_save, xmm_result);              // save for next r vector
+    __ pxor  (xmm_result, xmm_key_first);               // do the aes dec rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum  <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
+      __ aesdec(xmm_result, as_XMMRegister(rnum));
+    }
+    __ aesdeclast(xmm_result, xmm_key_last);
+    __ pxor  (xmm_result, xmm_prev_block_cipher);               // xor with the current r vector
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save);              // set up next r vector with cipher input from this block
+
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jmp(L_singleBlock_loopTop_128);
+
+
+    __ BIND(L_exit);
+    __ movdqu(Address(rvec, 0), xmm_prev_block_cipher);     // final value of r stored in rvec of CipherBlockChaining object
+#ifdef _WIN64
+    // restore regs belonging to calling function
+    for (int i = 6; i <= XMM_REG_NUM_KEY_LAST; i++) {
+      __ movdqu(as_XMMRegister(i), xmm_save(i));
+    }
+#endif
+    __ movl(rax, 0); // return 0 (why?)
+    __ leave(); // required for proper stackwalking of RuntimeStub frame
+    __ ret(0);
+
+
+    __ BIND(L_key_192_256);
+    // here rax = len in ints of AESCrypt.KLE array (52=192, or 60=256)
+    __ cmpl(rax, 52);
+    __ jcc(Assembler::notEqual, L_key_256);
+
+    // 192-bit code follows here (could be optimized to use parallelism)
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_singleBlock_loopTop_192);
+    __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of cipher input
+    __ movdqa(xmm_prev_block_cipher_save, xmm_result);              // save for next r vector
+    __ pxor  (xmm_result, xmm_key_first);               // do the aes dec rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
+      __ aesdec(xmm_result, as_XMMRegister(rnum));
+    }
+    aes_dec_key(xmm_result, xmm_temp, key, 0xb0);     // 192-bit key goes up to c0
+    aes_dec_key(xmm_result, xmm_temp, key, 0xc0);
+    __ aesdeclast(xmm_result, xmm_key_last);                    // xmm15 always came from key+0
+    __ pxor  (xmm_result, xmm_prev_block_cipher);               // xor with the current r vector
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save);              // set up next r vector with cipher input from this block
+
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual,L_singleBlock_loopTop_192);
+    __ jmp(L_exit);
+
+    __ BIND(L_key_256);
+    // 256-bit code follows here (could be optimized to use parallelism)
+    __ movptr(pos, 0);
+    __ align(OptoLoopAlignment);
+    __ BIND(L_singleBlock_loopTop_256);
+    __ movdqu(xmm_result, Address(from, pos, Address::times_1, 0));   // get next 16 bytes of cipher input
+    __ movdqa(xmm_prev_block_cipher_save, xmm_result);              // save for next r vector
+    __ pxor  (xmm_result, xmm_key_first);               // do the aes dec rounds
+    for (int rnum = XMM_REG_NUM_KEY_FIRST + 1; rnum <= XMM_REG_NUM_KEY_LAST - 1; rnum++) {
+      __ aesdec(xmm_result, as_XMMRegister(rnum));
+    }
+    aes_dec_key(xmm_result, xmm_temp, key, 0xb0);     // 256-bit key goes up to e0
+    aes_dec_key(xmm_result, xmm_temp, key, 0xc0);
+    aes_dec_key(xmm_result, xmm_temp, key, 0xd0);
+    aes_dec_key(xmm_result, xmm_temp, key, 0xe0);
+    __ aesdeclast(xmm_result, xmm_key_last);             // xmm15 came from key+0
+    __ pxor  (xmm_result, xmm_prev_block_cipher);               // xor with the current r vector
+    __ movdqu(Address(to, pos, Address::times_1, 0), xmm_result);     // store into the next 16 bytes of output
+    // no need to store r to memory until we exit
+    __ movdqa(xmm_prev_block_cipher, xmm_prev_block_cipher_save);              // set up next r vector with cipher input from this block
+
+    __ addptr(pos, AESBlockSize);
+    __ subptr(len_reg, AESBlockSize);
+    __ jcc(Assembler::notEqual,L_singleBlock_loopTop_256);
+    __ jmp(L_exit);
+
+    return start;
+  }
+
+
+
 #undef __
 #define __ masm->
 
@@ -3060,17 +3640,10 @@
 
     // platform dependent
     StubRoutines::x86::_get_previous_fp_entry = generate_get_previous_fp();
+    StubRoutines::x86::_get_previous_sp_entry = generate_get_previous_sp();
 
     StubRoutines::x86::_verify_mxcsr_entry    = generate_verify_mxcsr();
 
-    // Build this early so it's available for the interpreter.  Stub
-    // expects the required and actual types as register arguments in
-    // j_rarg0 and j_rarg1 respectively.
-    StubRoutines::_throw_WrongMethodTypeException_entry =
-      generate_throw_exception("WrongMethodTypeException throw_exception",
-                               CAST_FROM_FN_PTR(address, SharedRuntime::throw_WrongMethodTypeException),
-                               rax, rcx);
-
     // Build this early so it's available for the interpreter.
     StubRoutines::_throw_StackOverflowError_entry =
       generate_throw_exception("StackOverflowError throw_exception",
@@ -3121,6 +3694,16 @@
     generate_arraycopy_stubs();
 
     generate_math_stubs();
+
+    // don't bother generating these AES intrinsic stubs unless global flag is set
+    if (UseAESIntrinsics) {
+      StubRoutines::x86::_key_shuffle_mask_addr = generate_key_shuffle_mask();  // needed by the others
+
+      StubRoutines::_aescrypt_encryptBlock = generate_aescrypt_encryptBlock();
+      StubRoutines::_aescrypt_decryptBlock = generate_aescrypt_decryptBlock();
+      StubRoutines::_cipherBlockChaining_encryptAESCrypt = generate_cipherBlockChaining_encryptAESCrypt();
+      StubRoutines::_cipherBlockChaining_decryptAESCrypt = generate_cipherBlockChaining_decryptAESCrypt_Parallel();
+    }
   }
 
  public:
diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp
index 6ec4121..cfd4f33 100644
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.cpp
@@ -44,3 +44,4 @@
 
 address StubRoutines::x86::_verify_mxcsr_entry         = NULL;
 address StubRoutines::x86::_verify_fpu_cntrl_wrd_entry = NULL;
+address StubRoutines::x86::_key_shuffle_mask_addr = NULL;
diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp
index 64767c8..d53124f 100644
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_32.hpp
@@ -41,10 +41,14 @@
  private:
   static address _verify_mxcsr_entry;
   static address _verify_fpu_cntrl_wrd_entry;
+  // shuffle mask for fixing up 128-bit words consisting of big-endian 32-bit integers
+  static address _key_shuffle_mask_addr;
 
  public:
   static address verify_mxcsr_entry()                        { return _verify_mxcsr_entry; }
   static address verify_fpu_cntrl_wrd_entry()                { return _verify_fpu_cntrl_wrd_entry; }
+  static address key_shuffle_mask_addr()                     { return _key_shuffle_mask_addr; }
+
 };
 
   static bool    returns_to_call_stub(address return_pc)     { return return_pc == _call_stub_return_address; }
diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp
index 182872b..04d55c0 100644
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.cpp
@@ -43,6 +43,7 @@
 // a description of how to extend it, see the stubRoutines.hpp file.
 
 address StubRoutines::x86::_get_previous_fp_entry = NULL;
+address StubRoutines::x86::_get_previous_sp_entry = NULL;
 
 address StubRoutines::x86::_verify_mxcsr_entry = NULL;
 
@@ -55,3 +56,4 @@
 address StubRoutines::x86::_double_sign_mask = NULL;
 address StubRoutines::x86::_double_sign_flip = NULL;
 address StubRoutines::x86::_mxcsr_std = NULL;
+address StubRoutines::x86::_key_shuffle_mask_addr = NULL;
diff --git a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp
index 3d2a4fb..2044d5a 100644
--- a/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp
+++ b/hotspot/src/cpu/x86/vm/stubRoutines_x86_64.hpp
@@ -41,6 +41,7 @@
 
  private:
   static address _get_previous_fp_entry;
+  static address _get_previous_sp_entry;
   static address _verify_mxcsr_entry;
 
   static address _f2i_fixup;
@@ -53,6 +54,8 @@
   static address _double_sign_mask;
   static address _double_sign_flip;
   static address _mxcsr_std;
+  // shuffle mask for fixing up 128-bit words consisting of big-endian 32-bit integers
+  static address _key_shuffle_mask_addr;
 
  public:
 
@@ -61,6 +64,11 @@
     return _get_previous_fp_entry;
   }
 
+  static address get_previous_sp_entry()
+  {
+    return _get_previous_sp_entry;
+  }
+
   static address verify_mxcsr_entry()
   {
     return _verify_mxcsr_entry;
@@ -110,6 +118,9 @@
   {
     return _mxcsr_std;
   }
+
+  static address key_shuffle_mask_addr()                     { return _key_shuffle_mask_addr; }
+
 };
 
 #endif // CPU_X86_VM_STUBROUTINES_X86_64_HPP
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
index 2953383..bbf297b 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_32.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -566,7 +566,8 @@
     __ testl(rax, JVM_ACC_STATIC);
     __ movptr(rax, Address(rdi, Interpreter::local_offset_in_bytes(0)));  // get receiver (assume this is frequent case)
     __ jcc(Assembler::zero, done);
-    __ movptr(rax, Address(rbx, methodOopDesc::constants_offset()));
+    __ movptr(rax, Address(rbx, methodOopDesc::const_offset()));
+    __ movptr(rax, Address(rax, constMethodOopDesc::constants_offset()));
     __ movptr(rax, Address(rax, constantPoolOopDesc::pool_holder_offset_in_bytes()));
     __ movptr(rax, Address(rax, mirror_offset));
     __ bind(done);
@@ -606,7 +607,8 @@
     __ push(0);
   }
 
-  __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset()));
+  __ movptr(rdx, Address(rbx, methodOopDesc::const_offset()));
+  __ movptr(rdx, Address(rdx, constMethodOopDesc::constants_offset()));
   __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes()));
   __ push(rdx);                                       // set constant pool cache
   __ push(rdi);                                       // set locals pointer
@@ -661,9 +663,9 @@
     __ testptr(rax, rax);
     __ jcc(Assembler::zero, slow_path);
 
-    __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset()));
     // read first instruction word and extract bytecode @ 1 and index @ 2
     __ movptr(rdx, Address(rbx, methodOopDesc::const_offset()));
+    __ movptr(rdi, Address(rdx, constMethodOopDesc::constants_offset()));
     __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset()));
     // Shift codes right to get the index on the right.
     // The bytecode fetched looks like <index><0xb4><0x2a>
@@ -708,9 +710,9 @@
     // Need to differentiate between igetfield, agetfield, bgetfield etc.
     // because they are different sizes.
     // Use the type from the constant pool cache
-    __ shrl(rdx, ConstantPoolCacheEntry::tosBits);
-    // Make sure we don't need to mask rdx for tosBits after the above shift
-    ConstantPoolCacheEntry::verify_tosBits();
+    __ shrl(rdx, ConstantPoolCacheEntry::tos_state_shift);
+    // Make sure we don't need to mask rdx after the above shift
+    ConstantPoolCacheEntry::verify_tos_state_shift();
     __ cmpl(rdx, btos);
     __ jcc(Assembler::notEqual, notByte);
     __ load_signed_byte(rax, field_address);
@@ -1026,7 +1028,8 @@
     __ testl(t, JVM_ACC_STATIC);
     __ jcc(Assembler::zero, L);
     // get mirror
-    __ movptr(t, Address(method, methodOopDesc:: constants_offset()));
+    __ movptr(t, Address(method, methodOopDesc:: const_offset()));
+    __ movptr(t, Address(t, constMethodOopDesc::constants_offset()));
     __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes()));
     __ movptr(t, Address(t, mirror_offset));
     // copy mirror into activation frame
@@ -1510,7 +1513,6 @@
     case Interpreter::empty                  : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry();        break;
     case Interpreter::accessor               : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry();     break;
     case Interpreter::abstract               : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry();     break;
-    case Interpreter::method_handle          : entry_point = ((InterpreterGenerator*)this)->generate_method_handle_entry(); break;
 
     case Interpreter::java_lang_math_sin     : // fall thru
     case Interpreter::java_lang_math_cos     : // fall thru
@@ -1518,10 +1520,14 @@
     case Interpreter::java_lang_math_abs     : // fall thru
     case Interpreter::java_lang_math_log     : // fall thru
     case Interpreter::java_lang_math_log10   : // fall thru
-    case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);     break;
+    case Interpreter::java_lang_math_sqrt    : // fall thru
+    case Interpreter::java_lang_math_pow     : // fall thru
+    case Interpreter::java_lang_math_exp     : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);     break;
     case Interpreter::java_lang_ref_reference_get
                                              : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
-    default                                  : ShouldNotReachHere();                                                       break;
+    default:
+      fatal(err_msg("unexpected method kind: %d", kind));
+      break;
   }
 
   if (entry_point) return entry_point;
@@ -1540,7 +1546,9 @@
     case Interpreter::java_lang_math_abs     : // fall thru
     case Interpreter::java_lang_math_log     : // fall thru
     case Interpreter::java_lang_math_log10   : // fall thru
-    case Interpreter::java_lang_math_sqrt    :
+    case Interpreter::java_lang_math_sqrt    : // fall thru
+    case Interpreter::java_lang_math_pow     : // fall thru
+    case Interpreter::java_lang_math_exp     :
       return false;
     default:
       return true;
diff --git a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
index 110d8eb..c597926 100644
--- a/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/templateInterpreter_x86_64.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -522,7 +522,8 @@
     // get receiver (assume this is frequent case)
     __ movptr(rax, Address(r14, Interpreter::local_offset_in_bytes(0)));
     __ jcc(Assembler::zero, done);
-    __ movptr(rax, Address(rbx, methodOopDesc::constants_offset()));
+    __ movptr(rax, Address(rbx, methodOopDesc::const_offset()));
+    __ movptr(rax, Address(rax, constMethodOopDesc::constants_offset()));
     __ movptr(rax, Address(rax,
                            constantPoolOopDesc::pool_holder_offset_in_bytes()));
     __ movptr(rax, Address(rax, mirror_offset));
@@ -579,7 +580,8 @@
     __ push(0);
   }
 
-  __ movptr(rdx, Address(rbx, methodOopDesc::constants_offset()));
+  __ movptr(rdx, Address(rbx, methodOopDesc::const_offset()));
+  __ movptr(rdx, Address(rdx, constMethodOopDesc::constants_offset()));
   __ movptr(rdx, Address(rdx, constantPoolOopDesc::cache_offset_in_bytes()));
   __ push(rdx); // set constant pool cache
   __ push(r14); // set locals pointer
@@ -629,9 +631,9 @@
     __ testptr(rax, rax);
     __ jcc(Assembler::zero, slow_path);
 
-    __ movptr(rdi, Address(rbx, methodOopDesc::constants_offset()));
     // read first instruction word and extract bytecode @ 1 and index @ 2
     __ movptr(rdx, Address(rbx, methodOopDesc::const_offset()));
+    __ movptr(rdi, Address(rdx, constMethodOopDesc::constants_offset()));
     __ movl(rdx, Address(rdx, constMethodOopDesc::codes_offset()));
     // Shift codes right to get the index on the right.
     // The bytecode fetched looks like <index><0xb4><0x2a>
@@ -681,9 +683,9 @@
     // Need to differentiate between igetfield, agetfield, bgetfield etc.
     // because they are different sizes.
     // Use the type from the constant pool cache
-    __ shrl(rdx, ConstantPoolCacheEntry::tosBits);
-    // Make sure we don't need to mask edx for tosBits after the above shift
-    ConstantPoolCacheEntry::verify_tosBits();
+    __ shrl(rdx, ConstantPoolCacheEntry::tos_state_shift);
+    // Make sure we don't need to mask edx after the above shift
+    ConstantPoolCacheEntry::verify_tos_state_shift();
 
     __ cmpl(rdx, atos);
     __ jcc(Assembler::notEqual, notObj);
@@ -1020,7 +1022,8 @@
     __ testl(t, JVM_ACC_STATIC);
     __ jcc(Assembler::zero, L);
     // get mirror
-    __ movptr(t, Address(method, methodOopDesc::constants_offset()));
+    __ movptr(t, Address(method, methodOopDesc::const_offset()));
+    __ movptr(t, Address(t, constMethodOopDesc::constants_offset()));
     __ movptr(t, Address(t, constantPoolOopDesc::pool_holder_offset_in_bytes()));
     __ movptr(t, Address(t, mirror_offset));
     // copy mirror into activation frame
@@ -1521,12 +1524,11 @@
   switch (kind) {
   case Interpreter::zerolocals             :                                                                             break;
   case Interpreter::zerolocals_synchronized: synchronized = true;                                                        break;
-  case Interpreter::native                 : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(false); break;
-  case Interpreter::native_synchronized    : entry_point = ((InterpreterGenerator*) this)->generate_native_entry(true);  break;
-  case Interpreter::empty                  : entry_point = ((InterpreterGenerator*) this)->generate_empty_entry();       break;
-  case Interpreter::accessor               : entry_point = ((InterpreterGenerator*) this)->generate_accessor_entry();    break;
-  case Interpreter::abstract               : entry_point = ((InterpreterGenerator*) this)->generate_abstract_entry();    break;
-  case Interpreter::method_handle          : entry_point = ((InterpreterGenerator*) this)->generate_method_handle_entry();break;
+  case Interpreter::native                 : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(false); break;
+  case Interpreter::native_synchronized    : entry_point = ((InterpreterGenerator*)this)->generate_native_entry(true);  break;
+  case Interpreter::empty                  : entry_point = ((InterpreterGenerator*)this)->generate_empty_entry();       break;
+  case Interpreter::accessor               : entry_point = ((InterpreterGenerator*)this)->generate_accessor_entry();    break;
+  case Interpreter::abstract               : entry_point = ((InterpreterGenerator*)this)->generate_abstract_entry();    break;
 
   case Interpreter::java_lang_math_sin     : // fall thru
   case Interpreter::java_lang_math_cos     : // fall thru
@@ -1534,10 +1536,14 @@
   case Interpreter::java_lang_math_abs     : // fall thru
   case Interpreter::java_lang_math_log     : // fall thru
   case Interpreter::java_lang_math_log10   : // fall thru
-  case Interpreter::java_lang_math_sqrt    : entry_point = ((InterpreterGenerator*) this)->generate_math_entry(kind);    break;
+  case Interpreter::java_lang_math_sqrt    : // fall thru
+  case Interpreter::java_lang_math_pow     : // fall thru
+  case Interpreter::java_lang_math_exp     : entry_point = ((InterpreterGenerator*)this)->generate_math_entry(kind);    break;
   case Interpreter::java_lang_ref_reference_get
                                            : entry_point = ((InterpreterGenerator*)this)->generate_Reference_get_entry(); break;
-  default                                  : ShouldNotReachHere();                                                       break;
+  default:
+    fatal(err_msg("unexpected method kind: %d", kind));
+    break;
   }
 
   if (entry_point) {
@@ -1558,7 +1564,9 @@
     case Interpreter::java_lang_math_abs     : // fall thru
     case Interpreter::java_lang_math_log     : // fall thru
     case Interpreter::java_lang_math_log10   : // fall thru
-    case Interpreter::java_lang_math_sqrt    :
+    case Interpreter::java_lang_math_sqrt    : // fall thru
+    case Interpreter::java_lang_math_pow     : // fall thru
+    case Interpreter::java_lang_math_exp     :
       return false;
     default:
       return true;
diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
index 1cbc67e..fc19edc 100644
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.cpp
@@ -446,13 +446,13 @@
   const Register cache = rcx;
   const Register index = rdx;
 
-  resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1));
+  resolve_cache_and_index(f12_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1));
   if (VerifyOops) {
     __ verify_oop(rax);
   }
 
   Label L_done, L_throw_exception;
-  const Register con_klass_temp = rcx;  // same as Rcache
+  const Register con_klass_temp = rcx;  // same as cache
   __ load_klass(con_klass_temp, rax);
   __ cmpptr(con_klass_temp, ExternalAddress((address)Universe::systemObjArrayKlassObj_addr()));
   __ jcc(Assembler::notEqual, L_done);
@@ -2084,15 +2084,15 @@
                                             Register Rcache,
                                             Register index,
                                             size_t index_size) {
-  Register temp = rbx;
-
+  const Register temp = rbx;
   assert_different_registers(result, Rcache, index, temp);
 
   Label resolved;
-  if (byte_no == f1_oop) {
-    // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
-    // This kind of CP cache entry does not need to match the flags byte, because
+  if (byte_no == f12_oop) {
+    // We are resolved if the f1 field contains a non-null object (CallSite, MethodType, etc.)
+    // This kind of CP cache entry does not need to match bytecode_1 or bytecode_2, because
     // there is a 1-1 relation between bytecode type and CP entry type.
+    // The caller will also load a methodOop from f2.
     assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
     __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
     __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
@@ -2112,15 +2112,18 @@
     case Bytecodes::_getstatic      : // fall through
     case Bytecodes::_putstatic      : // fall through
     case Bytecodes::_getfield       : // fall through
-    case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put); break;
+    case Bytecodes::_putfield       : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put);        break;
     case Bytecodes::_invokevirtual  : // fall through
     case Bytecodes::_invokespecial  : // fall through
     case Bytecodes::_invokestatic   : // fall through
-    case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);  break;
-    case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic); break;
-    case Bytecodes::_fast_aldc      : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
-    case Bytecodes::_fast_aldc_w    : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);     break;
-    default                         : ShouldNotReachHere();                                 break;
+    case Bytecodes::_invokeinterface: entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);         break;
+    case Bytecodes::_invokehandle   : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);   break;
+    case Bytecodes::_invokedynamic  : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);  break;
+    case Bytecodes::_fast_aldc      : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);            break;
+    case Bytecodes::_fast_aldc_w    : entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);            break;
+    default:
+      fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
+      break;
   }
   __ movl(temp, (int)bytecode());
   __ call_VM(noreg, entry, temp);
@@ -2149,7 +2152,7 @@
   __ movl(flags, Address(cache, index, Address::times_ptr,
            in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset())));
 
-  // klass     overwrite register
+  // klass overwrite register
   if (is_static) {
     __ movptr(obj, Address(cache, index, Address::times_ptr,
                            in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset())));
@@ -2161,7 +2164,7 @@
                                                Register itable_index,
                                                Register flags,
                                                bool is_invokevirtual,
-                                               bool is_invokevfinal /*unused*/,
+                                               bool is_invokevfinal, /*unused*/
                                                bool is_invokedynamic) {
   // setup registers
   const Register cache = rcx;
@@ -2171,28 +2174,33 @@
   assert_different_registers(itable_index, flags);
   assert_different_registers(itable_index, cache, index);
   // determine constant pool cache field offsets
+  assert(is_invokevirtual == (byte_no == f2_byte), "is_invokevirtual flag redundant");
   const int method_offset = in_bytes(
     constantPoolCacheOopDesc::base_offset() +
-      (is_invokevirtual
+      ((byte_no == f2_byte)
        ? ConstantPoolCacheEntry::f2_offset()
-       : ConstantPoolCacheEntry::f1_offset()
-      )
-    );
+       : ConstantPoolCacheEntry::f1_offset()));
   const int flags_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
                                     ConstantPoolCacheEntry::flags_offset());
   // access constant pool cache fields
   const int index_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
                                     ConstantPoolCacheEntry::f2_offset());
 
-  if (byte_no == f1_oop) {
-    // Resolved f1_oop goes directly into 'method' register.
-    assert(is_invokedynamic, "");
-    resolve_cache_and_index(byte_no, method, cache, index, sizeof(u4));
+  if (byte_no == f12_oop) {
+    // Resolved f1_oop (CallSite, MethodType, etc.) goes into 'itable_index'.
+    // Resolved f2_oop (methodOop invoker) will go into 'method' (at index_offset).
+    // See ConstantPoolCacheEntry::set_dynamic_call and set_method_handle.
+    size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
+    resolve_cache_and_index(byte_no, itable_index, cache, index, index_size);
+    __ movptr(method, Address(cache, index, Address::times_ptr, index_offset));
+    itable_index = noreg;  // hack to disable load below
   } else {
     resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
     __ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
   }
   if (itable_index != noreg) {
+    // pick up itable index from f2 also:
+    assert(byte_no == f1_byte, "already picked up f1");
     __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset));
   }
   __ movl(flags, Address(cache, index, Address::times_ptr, flags_offset));
@@ -2260,10 +2268,10 @@
 
   Label Done, notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
 
-  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
+  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
   assert(btos == 0, "change code, btos != 0");
   // btos
-  __ andptr(flags, 0x0f);
+  __ andptr(flags, ConstantPoolCacheEntry::tos_state_mask);
   __ jcc(Assembler::notZero, notByte);
 
   __ load_signed_byte(rax, lo );
@@ -2415,9 +2423,9 @@
       __ movl(rcx, Address(rax, rdx, Address::times_ptr, in_bytes(cp_base_offset +
                                    ConstantPoolCacheEntry::flags_offset())));
       __ mov(rbx, rsp);
-      __ shrl(rcx, ConstantPoolCacheEntry::tosBits);
-      // Make sure we don't need to mask rcx for tosBits after the above shift
-      ConstantPoolCacheEntry::verify_tosBits();
+      __ shrl(rcx, ConstantPoolCacheEntry::tos_state_shift);
+      // Make sure we don't need to mask rcx after the above shift
+      ConstantPoolCacheEntry::verify_tos_state_shift();
       __ cmpl(rcx, ltos);
       __ jccb(Assembler::equal, two_word);
       __ cmpl(rcx, dtos);
@@ -2467,7 +2475,7 @@
 
   Label notVolatile, Done;
   __ movl(rdx, flags);
-  __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
+  __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
   __ andl(rdx, 0x1);
 
   // field addresses
@@ -2476,9 +2484,9 @@
 
   Label notByte, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
 
-  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
+  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
   assert(btos == 0, "change code, btos != 0");
-  __ andl(flags, 0x0f);
+  __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
   __ jcc(Assembler::notZero, notByte);
 
   // btos
@@ -2651,56 +2659,49 @@
     // Check to see if a field modification watch has been set before we take
     // the time to call into the VM.
     Label L2;
-    __ mov32(rcx, ExternalAddress((address)JvmtiExport::get_field_modification_count_addr()));
-    __ testl(rcx,rcx);
-    __ jcc(Assembler::zero, L2);
-    __ pop_ptr(rbx);               // copy the object pointer from tos
-    __ verify_oop(rbx);
-    __ push_ptr(rbx);              // put the object pointer back on tos
-    __ subptr(rsp, sizeof(jvalue));  // add space for a jvalue object
-    __ mov(rcx, rsp);
-    __ push_ptr(rbx);                 // save object pointer so we can steal rbx,
-    __ xorptr(rbx, rbx);
-    const Address lo_value(rcx, rbx, Address::times_1, 0*wordSize);
-    const Address hi_value(rcx, rbx, Address::times_1, 1*wordSize);
-    switch (bytecode()) {          // load values into the jvalue object
-    case Bytecodes::_fast_bputfield: __ movb(lo_value, rax); break;
-    case Bytecodes::_fast_sputfield: __ movw(lo_value, rax); break;
-    case Bytecodes::_fast_cputfield: __ movw(lo_value, rax); break;
-    case Bytecodes::_fast_iputfield: __ movl(lo_value, rax);                         break;
-    case Bytecodes::_fast_lputfield:
-      NOT_LP64(__ movptr(hi_value, rdx));
-      __ movptr(lo_value, rax);
-      break;
+     __ mov32(rcx, ExternalAddress((address)JvmtiExport::get_field_modification_count_addr()));
+     __ testl(rcx,rcx);
+     __ jcc(Assembler::zero, L2);
+     __ pop_ptr(rbx);               // copy the object pointer from tos
+     __ verify_oop(rbx);
+     __ push_ptr(rbx);              // put the object pointer back on tos
 
-    // need to call fld_s() after fstp_s() to restore the value for below
-    case Bytecodes::_fast_fputfield: __ fstp_s(lo_value); __ fld_s(lo_value);        break;
+     // Save tos values before call_VM() clobbers them. Since we have
+     // to do it for every data type, we use the saved values as the
+     // jvalue object.
+     switch (bytecode()) {          // load values into the jvalue object
+     case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
+     case Bytecodes::_fast_bputfield: // fall through
+     case Bytecodes::_fast_sputfield: // fall through
+     case Bytecodes::_fast_cputfield: // fall through
+     case Bytecodes::_fast_iputfield: __ push_i(rax); break;
+     case Bytecodes::_fast_dputfield: __ push_d(); break;
+     case Bytecodes::_fast_fputfield: __ push_f(); break;
+     case Bytecodes::_fast_lputfield: __ push_l(rax); break;
 
-    // need to call fld_d() after fstp_d() to restore the value for below
-    case Bytecodes::_fast_dputfield: __ fstp_d(lo_value); __ fld_d(lo_value);        break;
+     default:
+       ShouldNotReachHere();
+     }
+     __ mov(rcx, rsp);              // points to jvalue on the stack
+     // access constant pool cache entry
+     __ get_cache_entry_pointer_at_bcp(rax, rdx, 1);
+     __ verify_oop(rbx);
+     // rbx,: object pointer copied above
+     // rax,: cache entry pointer
+     // rcx: jvalue object on the stack
+     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx);
 
-    // since rcx is not an object we don't call store_check() here
-    case Bytecodes::_fast_aputfield: __ movptr(lo_value, rax);                       break;
-
-    default:  ShouldNotReachHere();
-    }
-    __ pop_ptr(rbx);  // restore copy of object pointer
-
-    // Save rax, and sometimes rdx because call_VM() will clobber them,
-    // then use them for JVM/DI purposes
-    __ push(rax);
-    if (bytecode() == Bytecodes::_fast_lputfield) __ push(rdx);
-    // access constant pool cache entry
-    __ get_cache_entry_pointer_at_bcp(rax, rdx, 1);
-    __ verify_oop(rbx);
-    // rbx,: object pointer copied above
-    // rax,: cache entry pointer
-    // rcx: jvalue object on the stack
-    __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_modification), rbx, rax, rcx);
-    if (bytecode() == Bytecodes::_fast_lputfield) __ pop(rdx);  // restore high value
-    __ pop(rax);     // restore lower value
-    __ addptr(rsp, sizeof(jvalue));  // release jvalue object space
-    __ bind(L2);
+     switch (bytecode()) {             // restore tos values
+     case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
+     case Bytecodes::_fast_bputfield: // fall through
+     case Bytecodes::_fast_sputfield: // fall through
+     case Bytecodes::_fast_cputfield: // fall through
+     case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
+     case Bytecodes::_fast_dputfield: __ pop_d(); break;
+     case Bytecodes::_fast_fputfield: __ pop_f(); break;
+     case Bytecodes::_fast_lputfield: __ pop_l(rax); break;
+     }
+     __ bind(L2);
   }
 }
 
@@ -2726,7 +2727,7 @@
   // volatile_barrier( );
 
   Label notVolatile, Done;
-  __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
+  __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
   __ andl(rdx, 0x1);
   // Check for volatile store
   __ testl(rdx, rdx);
@@ -2892,19 +2893,29 @@
 }
 
 
-void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
+void TemplateTable::prepare_invoke(int byte_no,
+                                   Register method,  // linked method (or i-klass)
+                                   Register index,   // itable index, MethodType, etc.
+                                   Register recv,    // if caller wants to see it
+                                   Register flags    // if caller wants to test it
+                                   ) {
   // determine flags
-  Bytecodes::Code code = bytecode();
+  const Bytecodes::Code code = bytecode();
   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
   const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
+  const bool is_invokehandle     = code == Bytecodes::_invokehandle;
   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
   const bool is_invokespecial    = code == Bytecodes::_invokespecial;
-  const bool load_receiver      = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
-  const bool receiver_null_check = is_invokespecial;
-  const bool save_flags = is_invokeinterface || is_invokevirtual;
+  const bool load_receiver       = (recv  != noreg);
+  const bool save_flags          = (flags != noreg);
+  assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), "");
+  assert(save_flags    == (is_invokeinterface || is_invokevirtual), "need flags for vfinal");
+  assert(flags == noreg || flags == rdx, "");
+  assert(recv  == noreg || recv  == rcx, "");
+
   // setup registers & access constant pool cache
-  const Register recv   = rcx;
-  const Register flags  = rdx;
+  if (recv  == noreg)  recv  = rcx;
+  if (flags == noreg)  flags = rdx;
   assert_different_registers(method, index, recv, flags);
 
   // save 'interpreter return address'
@@ -2912,20 +2923,28 @@
 
   load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
 
-  // load receiver if needed (note: no return address pushed yet)
-  if (load_receiver) {
-    assert(!is_invokedynamic, "");
-    __ movl(recv, flags);
-    __ andl(recv, 0xFF);
-    // recv count is 0 based?
-    Address recv_addr(rsp, recv, Interpreter::stackElementScale(), -Interpreter::expr_offset_in_bytes(1));
-    __ movptr(recv, recv_addr);
-    __ verify_oop(recv);
+  // maybe push appendix to arguments (just before return address)
+  if (is_invokedynamic || is_invokehandle) {
+    Label L_no_push;
+    __ verify_oop(index);
+    __ testl(flags, (1 << ConstantPoolCacheEntry::has_appendix_shift));
+    __ jccb(Assembler::zero, L_no_push);
+    // Push the appendix as a trailing parameter.
+    // This must be done before we get the receiver,
+    // since the parameter_size includes it.
+    __ push(index);  // push appendix (MethodType, CallSite, etc.)
+    __ bind(L_no_push);
   }
 
-  // do null check if needed
-  if (receiver_null_check) {
-    __ null_check(recv);
+  // load receiver if needed (note: no return address pushed yet)
+  if (load_receiver) {
+    __ movl(recv, flags);
+    __ andl(recv, ConstantPoolCacheEntry::parameter_size_mask);
+    const int no_return_pc_pushed_yet = -1;  // argument slot correction before we push return address
+    const int receiver_is_at_end      = -1;  // back off one slot to get receiver
+    Address recv_addr = __ argument_address(recv, no_return_pc_pushed_yet + receiver_is_at_end);
+    __ movptr(recv, recv_addr);
+    __ verify_oop(recv);
   }
 
   if (save_flags) {
@@ -2933,16 +2952,14 @@
   }
 
   // compute return type
-  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
-  // Make sure we don't need to mask flags for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
+  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
+  // Make sure we don't need to mask flags after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
   // load return address
   {
-    address table_addr;
-    if (is_invokeinterface || is_invokedynamic)
-      table_addr = (address)Interpreter::return_5_addrs_by_index_table();
-    else
-      table_addr = (address)Interpreter::return_3_addrs_by_index_table();
+    const address table_addr = (is_invokeinterface || is_invokedynamic) ?
+        (address)Interpreter::return_5_addrs_by_index_table() :
+        (address)Interpreter::return_3_addrs_by_index_table();
     ExternalAddress table(table_addr);
     __ movptr(flags, ArrayAddress(table, Address(noreg, flags, Address::times_ptr)));
   }
@@ -2950,7 +2967,7 @@
   // push return address
   __ push(flags);
 
-  // Restore flag value from the constant pool cache, and restore rsi
+  // Restore flags value from the constant pool cache, and restore rsi
   // for later null checks.  rsi is the bytecode pointer
   if (save_flags) {
     __ mov(flags, rsi);
@@ -2959,22 +2976,26 @@
 }
 
 
-void TemplateTable::invokevirtual_helper(Register index, Register recv,
-                        Register flags) {
-
+void TemplateTable::invokevirtual_helper(Register index,
+                                         Register recv,
+                                         Register flags) {
   // Uses temporary registers rax, rdx
   assert_different_registers(index, recv, rax, rdx);
+  assert(index == rbx, "");
+  assert(recv  == rcx, "");
 
   // Test for an invoke of a final method
   Label notFinal;
   __ movl(rax, flags);
-  __ andl(rax, (1 << ConstantPoolCacheEntry::vfinalMethod));
+  __ andl(rax, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
   __ jcc(Assembler::zero, notFinal);
 
-  Register method = index;  // method must be rbx,
-  assert(method == rbx, "methodOop must be rbx, for interpreter calling convention");
+  const Register method = index;  // method must be rbx
+  assert(method == rbx,
+         "methodOop must be rbx for interpreter calling convention");
 
   // do the call - the index is actually the method to call
+  // that is, f2 is a vtable index if !is_vfinal, else f2 is a methodOop
   __ verify_oop(method);
 
   // It's final, need a null check here!
@@ -2989,7 +3010,6 @@
 
   // get receiver klass
   __ null_check(recv, oopDesc::klass_offset_in_bytes());
-  // Keep recv in rcx for callee expects it there
   __ load_klass(rax, recv);
   __ verify_oop(rax);
 
@@ -2997,9 +3017,7 @@
   __ profile_virtual_call(rax, rdi, rdx);
 
   // get target methodOop & entry point
-  const int base = instanceKlass::vtable_start_offset() * wordSize;
-  assert(vtableEntry::size() * wordSize == 4, "adjust the scaling in the code below");
-  __ movptr(method, Address(rax, index, Address::times_ptr, base + vtableEntry::method_offset_in_bytes()));
+  __ lookup_virtual_method(rax, index, method);
   __ jump_from_interpreted(method, rdx);
 }
 
@@ -3007,9 +3025,12 @@
 void TemplateTable::invokevirtual(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f2_byte, "use this argument");
-  prepare_invoke(rbx, noreg, byte_no);
+  prepare_invoke(byte_no,
+                 rbx,    // method or vtable index
+                 noreg,  // unused itable index
+                 rcx, rdx); // recv, flags
 
-  // rbx,: index
+  // rbx: index
   // rcx: receiver
   // rdx: flags
 
@@ -3020,7 +3041,10 @@
 void TemplateTable::invokespecial(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
-  prepare_invoke(rbx, noreg, byte_no);
+  prepare_invoke(byte_no, rbx, noreg,  // get f1 methodOop
+                 rcx);  // get receiver also for null check
+  __ verify_oop(rcx);
+  __ null_check(rcx);
   // do the call
   __ verify_oop(rbx);
   __ profile_call(rax);
@@ -3031,7 +3055,7 @@
 void TemplateTable::invokestatic(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
-  prepare_invoke(rbx, noreg, byte_no);
+  prepare_invoke(byte_no, rbx);  // get f1 methodOop
   // do the call
   __ verify_oop(rbx);
   __ profile_call(rax);
@@ -3049,10 +3073,11 @@
 void TemplateTable::invokeinterface(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
-  prepare_invoke(rax, rbx, byte_no);
+  prepare_invoke(byte_no, rax, rbx,  // get f1 klassOop, f2 itable index
+                 rcx, rdx); // recv, flags
 
-  // rax,: Interface
-  // rbx,: index
+  // rax: interface klass (from f1)
+  // rbx: itable index (from f2)
   // rcx: receiver
   // rdx: flags
 
@@ -3062,7 +3087,7 @@
   // another compliant java compiler.
   Label notMethod;
   __ movl(rdi, rdx);
-  __ andl(rdi, (1 << ConstantPoolCacheEntry::methodInterface));
+  __ andl(rdi, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
   __ jcc(Assembler::zero, notMethod);
 
   invokevirtual_helper(rbx, rcx, rdx);
@@ -3070,6 +3095,7 @@
 
   // Get receiver klass into rdx - also a null check
   __ restore_locals();  // restore rdi
+  __ null_check(rcx, oopDesc::klass_offset_in_bytes());
   __ load_klass(rdx, rcx);
   __ verify_oop(rdx);
 
@@ -3084,7 +3110,7 @@
                              rbx, rsi,
                              no_such_interface);
 
-  // rbx,: methodOop to call
+  // rbx: methodOop to call
   // rcx: receiver
   // Check for abstract method error
   // Note: This should be done more efficiently via a throw_abstract_method_error
@@ -3123,9 +3149,39 @@
   __ should_not_reach_here();
 }
 
+void TemplateTable::invokehandle(int byte_no) {
+  transition(vtos, vtos);
+  assert(byte_no == f12_oop, "use this argument");
+  const Register rbx_method = rbx;  // (from f2)
+  const Register rax_mtype  = rax;  // (from f1)
+  const Register rcx_recv   = rcx;
+  const Register rdx_flags  = rdx;
+
+  if (!EnableInvokeDynamic) {
+    // rewriter does not generate this bytecode
+    __ should_not_reach_here();
+    return;
+  }
+
+  prepare_invoke(byte_no,
+                 rbx_method, rax_mtype,  // get f2 methodOop, f1 MethodType
+                 rcx_recv);
+  __ verify_oop(rbx_method);
+  __ verify_oop(rcx_recv);
+  __ null_check(rcx_recv);
+
+  // Note:  rax_mtype is already pushed (if necessary) by prepare_invoke
+
+  // FIXME: profile the LambdaForm also
+  __ profile_final_call(rax);
+
+  __ jump_from_interpreted(rbx_method, rdx);
+}
+
+
 void TemplateTable::invokedynamic(int byte_no) {
   transition(vtos, vtos);
-  assert(byte_no == f1_oop, "use this argument");
+  assert(byte_no == f12_oop, "use this argument");
 
   if (!EnableInvokeDynamic) {
     // We should not encounter this bytecode if !EnableInvokeDynamic.
@@ -3138,26 +3194,23 @@
     return;
   }
 
-  prepare_invoke(rax, rbx, byte_no);
+  const Register rbx_method   = rbx;
+  const Register rax_callsite = rax;
 
-  // rax: CallSite object (f1)
-  // rbx: unused (f2)
-  // rcx: receiver address
-  // rdx: flags (unused)
+  prepare_invoke(byte_no, rbx_method, rax_callsite);
 
-  Register rax_callsite      = rax;
-  Register rcx_method_handle = rcx;
+  // rax: CallSite object (from f1)
+  // rbx: MH.linkToCallSite method (from f2)
+
+  // Note:  rax_callsite is already pushed by prepare_invoke
 
   // %%% should make a type profile for any invokedynamic that takes a ref argument
   // profile this call
   __ profile_call(rsi);
 
   __ verify_oop(rax_callsite);
-  __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rdx)));
-  __ null_check(rcx_method_handle);
-  __ verify_oop(rcx_method_handle);
-  __ prepare_to_jump_from_interpreted();
-  __ jump_to_method_handle_entry(rcx_method_handle, rdx);
+
+  __ jump_from_interpreted(rbx_method, rdx);
 }
 
 //----------------------------------------------------------------------------------------------------
diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp b/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp
index 05293af..c0ff897 100644
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_32.hpp
@@ -25,10 +25,15 @@
 #ifndef CPU_X86_VM_TEMPLATETABLE_X86_32_HPP
 #define CPU_X86_VM_TEMPLATETABLE_X86_32_HPP
 
-  static void prepare_invoke(Register method, Register index, int byte_no);
+  static void prepare_invoke(int byte_no,
+                             Register method,         // linked method (or i-klass)
+                             Register index = noreg,  // itable index, MethodType, etc.
+                             Register recv  = noreg,  // if caller wants to see it
+                             Register flags = noreg   // if caller wants to test it
+                             );
   static void invokevirtual_helper(Register index, Register recv,
                                    Register flags);
-  static void volatile_barrier(Assembler::Membar_mask_bits order_constraint );
+  static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
 
   // Helpers
   static void index_check(Register array, Register index);
diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
index 0e5ac27..b13567c 100644
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.cpp
@@ -458,7 +458,7 @@
   const Register cache = rcx;
   const Register index = rdx;
 
-  resolve_cache_and_index(f1_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1));
+  resolve_cache_and_index(f12_oop, rax, cache, index, wide ? sizeof(u2) : sizeof(u1));
   if (VerifyOops) {
     __ verify_oop(rax);
   }
@@ -2125,10 +2125,11 @@
   assert_different_registers(result, Rcache, index, temp);
 
   Label resolved;
-  if (byte_no == f1_oop) {
-    // We are resolved if the f1 field contains a non-null object (CallSite, etc.)
-    // This kind of CP cache entry does not need to match the flags byte, because
+  if (byte_no == f12_oop) {
+    // We are resolved if the f1 field contains a non-null object (CallSite, MethodType, etc.)
+    // This kind of CP cache entry does not need to match bytecode_1 or bytecode_2, because
     // there is a 1-1 relation between bytecode type and CP entry type.
+    // The caller will also load a methodOop from f2.
     assert(result != noreg, ""); //else do cmpptr(Address(...), (int32_t) NULL_WORD)
     __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
     __ movptr(result, Address(Rcache, index, Address::times_ptr, constantPoolCacheOopDesc::base_offset() + ConstantPoolCacheEntry::f1_offset()));
@@ -2157,6 +2158,9 @@
   case Bytecodes::_invokeinterface:
     entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
     break;
+  case Bytecodes::_invokehandle:
+    entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);
+    break;
   case Bytecodes::_invokedynamic:
     entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
     break;
@@ -2167,7 +2171,7 @@
     entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
     break;
   default:
-    ShouldNotReachHere();
+    fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
     break;
   }
   __ movl(temp, (int) bytecode());
@@ -2180,7 +2184,7 @@
   __ bind(resolved);
 }
 
-// The Rcache and index registers must be set before call
+// The cache and index registers must be set before call
 void TemplateTable::load_field_cp_cache_entry(Register obj,
                                               Register cache,
                                               Register index,
@@ -2191,17 +2195,17 @@
 
   ByteSize cp_base_offset = constantPoolCacheOopDesc::base_offset();
   // Field offset
-  __ movptr(off, Address(cache, index, Address::times_8,
+  __ movptr(off, Address(cache, index, Address::times_ptr,
                          in_bytes(cp_base_offset +
                                   ConstantPoolCacheEntry::f2_offset())));
   // Flags
-  __ movl(flags, Address(cache, index, Address::times_8,
+  __ movl(flags, Address(cache, index, Address::times_ptr,
                          in_bytes(cp_base_offset +
                                   ConstantPoolCacheEntry::flags_offset())));
 
   // klass overwrite register
   if (is_static) {
-    __ movptr(obj, Address(cache, index, Address::times_8,
+    __ movptr(obj, Address(cache, index, Address::times_ptr,
                            in_bytes(cp_base_offset +
                                     ConstantPoolCacheEntry::f1_offset())));
   }
@@ -2222,9 +2226,10 @@
   assert_different_registers(itable_index, flags);
   assert_different_registers(itable_index, cache, index);
   // determine constant pool cache field offsets
+  assert(is_invokevirtual == (byte_no == f2_byte), "is_invokevirtual flag redundant");
   const int method_offset = in_bytes(
     constantPoolCacheOopDesc::base_offset() +
-      (is_invokevirtual
+      ((byte_no == f2_byte)
        ? ConstantPoolCacheEntry::f2_offset()
        : ConstantPoolCacheEntry::f1_offset()));
   const int flags_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
@@ -2233,15 +2238,21 @@
   const int index_offset = in_bytes(constantPoolCacheOopDesc::base_offset() +
                                     ConstantPoolCacheEntry::f2_offset());
 
-  if (byte_no == f1_oop) {
-    // Resolved f1_oop goes directly into 'method' register.
-    assert(is_invokedynamic, "");
-    resolve_cache_and_index(byte_no, method, cache, index, sizeof(u4));
+  if (byte_no == f12_oop) {
+    // Resolved f1_oop (CallSite, MethodType, etc.) goes into 'itable_index'.
+    // Resolved f2_oop (methodOop invoker) will go into 'method' (at index_offset).
+    // See ConstantPoolCacheEntry::set_dynamic_call and set_method_handle.
+    size_t index_size = (is_invokedynamic ? sizeof(u4) : sizeof(u2));
+    resolve_cache_and_index(byte_no, itable_index, cache, index, index_size);
+    __ movptr(method, Address(cache, index, Address::times_ptr, index_offset));
+    itable_index = noreg;  // hack to disable load below
   } else {
     resolve_cache_and_index(byte_no, noreg, cache, index, sizeof(u2));
     __ movptr(method, Address(cache, index, Address::times_ptr, method_offset));
   }
   if (itable_index != noreg) {
+    // pick up itable index from f2 also:
+    assert(byte_no == f1_byte, "already picked up f1");
     __ movptr(itable_index, Address(cache, index, Address::times_ptr, index_offset));
   }
   __ movl(flags, Address(cache, index, Address::times_ptr, flags_offset));
@@ -2317,10 +2328,11 @@
   Label Done, notByte, notInt, notShort, notChar,
               notLong, notFloat, notObj, notDouble;
 
-  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
+  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
+  // Make sure we don't need to mask edx after the above shift
   assert(btos == 0, "change code, btos != 0");
 
-  __ andl(flags, 0x0F);
+  __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
   __ jcc(Assembler::notZero, notByte);
   // btos
   __ load_signed_byte(rax, field);
@@ -2466,10 +2478,9 @@
                            Address::times_8,
                            in_bytes(cp_base_offset +
                                      ConstantPoolCacheEntry::flags_offset())));
-      __ shrl(c_rarg3, ConstantPoolCacheEntry::tosBits);
-      // Make sure we don't need to mask rcx for tosBits after the
-      // above shift
-      ConstantPoolCacheEntry::verify_tosBits();
+      __ shrl(c_rarg3, ConstantPoolCacheEntry::tos_state_shift);
+      // Make sure we don't need to mask rcx after the above shift
+      ConstantPoolCacheEntry::verify_tos_state_shift();
       __ movptr(c_rarg1, at_tos_p1());  // initially assume a one word jvalue
       __ cmpl(c_rarg3, ltos);
       __ cmovptr(Assembler::equal,
@@ -2516,7 +2527,7 @@
 
   Label notVolatile, Done;
   __ movl(rdx, flags);
-  __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
+  __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
   __ andl(rdx, 0x1);
 
   // field address
@@ -2525,10 +2536,10 @@
   Label notByte, notInt, notShort, notChar,
         notLong, notFloat, notObj, notDouble;
 
-  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
+  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
 
   assert(btos == 0, "change code, btos != 0");
-  __ andl(flags, 0x0f);
+  __ andl(flags, ConstantPoolCacheEntry::tos_state_mask);
   __ jcc(Assembler::notZero, notByte);
 
   // btos
@@ -2685,26 +2696,23 @@
     __ pop_ptr(rbx);                  // copy the object pointer from tos
     __ verify_oop(rbx);
     __ push_ptr(rbx);                 // put the object pointer back on tos
-    __ subptr(rsp, sizeof(jvalue));  // add space for a jvalue object
-    __ mov(c_rarg3, rsp);
-    const Address field(c_rarg3, 0);
-
+    // Save tos values before call_VM() clobbers them. Since we have
+    // to do it for every data type, we use the saved values as the
+    // jvalue object.
     switch (bytecode()) {          // load values into the jvalue object
-    case Bytecodes::_fast_aputfield: __ movq(field, rax); break;
-    case Bytecodes::_fast_lputfield: __ movq(field, rax); break;
-    case Bytecodes::_fast_iputfield: __ movl(field, rax); break;
-    case Bytecodes::_fast_bputfield: __ movb(field, rax); break;
+    case Bytecodes::_fast_aputfield: __ push_ptr(rax); break;
+    case Bytecodes::_fast_bputfield: // fall through
     case Bytecodes::_fast_sputfield: // fall through
-    case Bytecodes::_fast_cputfield: __ movw(field, rax); break;
-    case Bytecodes::_fast_fputfield: __ movflt(field, xmm0); break;
-    case Bytecodes::_fast_dputfield: __ movdbl(field, xmm0); break;
+    case Bytecodes::_fast_cputfield: // fall through
+    case Bytecodes::_fast_iputfield: __ push_i(rax); break;
+    case Bytecodes::_fast_dputfield: __ push_d(); break;
+    case Bytecodes::_fast_fputfield: __ push_f(); break;
+    case Bytecodes::_fast_lputfield: __ push_l(rax); break;
+
     default:
       ShouldNotReachHere();
     }
-
-    // Save rax because call_VM() will clobber it, then use it for
-    // JVMTI purposes
-    __ push(rax);
+    __ mov(c_rarg3, rsp);             // points to jvalue on the stack
     // access constant pool cache entry
     __ get_cache_entry_pointer_at_bcp(c_rarg2, rax, 1);
     __ verify_oop(rbx);
@@ -2715,8 +2723,17 @@
                CAST_FROM_FN_PTR(address,
                                 InterpreterRuntime::post_field_modification),
                rbx, c_rarg2, c_rarg3);
-    __ pop(rax);     // restore lower value
-    __ addptr(rsp, sizeof(jvalue));  // release jvalue object space
+
+    switch (bytecode()) {             // restore tos values
+    case Bytecodes::_fast_aputfield: __ pop_ptr(rax); break;
+    case Bytecodes::_fast_bputfield: // fall through
+    case Bytecodes::_fast_sputfield: // fall through
+    case Bytecodes::_fast_cputfield: // fall through
+    case Bytecodes::_fast_iputfield: __ pop_i(rax); break;
+    case Bytecodes::_fast_dputfield: __ pop_d(); break;
+    case Bytecodes::_fast_fputfield: __ pop_f(); break;
+    case Bytecodes::_fast_lputfield: __ pop_l(rax); break;
+    }
     __ bind(L2);
   }
 }
@@ -2745,7 +2762,7 @@
   //                                              Assembler::StoreStore));
 
   Label notVolatile;
-  __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
+  __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
   __ andl(rdx, 0x1);
 
   // Get object from stack
@@ -2826,7 +2843,7 @@
   //   __ movl(rdx, Address(rcx, rbx, Address::times_8,
   //                        in_bytes(constantPoolCacheOopDesc::base_offset() +
   //                                 ConstantPoolCacheEntry::flags_offset())));
-  //   __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
+  //   __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
   //   __ andl(rdx, 0x1);
   // }
   __ movptr(rbx, Address(rcx, rbx, Address::times_8,
@@ -2914,7 +2931,7 @@
   //   __ movl(rdx, Address(rcx, rdx, Address::times_8,
   //                        in_bytes(constantPoolCacheOopDesc::base_offset() +
   //                                 ConstantPoolCacheEntry::flags_offset())));
-  //   __ shrl(rdx, ConstantPoolCacheEntry::volatileField);
+  //   __ shrl(rdx, ConstantPoolCacheEntry::is_volatile_shift);
   //   __ testl(rdx, 0x1);
   //   __ jcc(Assembler::zero, notVolatile);
   //   __ membar(Assembler::LoadLoad);
@@ -2934,19 +2951,29 @@
   ShouldNotReachHere();
 }
 
-void TemplateTable::prepare_invoke(Register method, Register index, int byte_no) {
+void TemplateTable::prepare_invoke(int byte_no,
+                                   Register method,  // linked method (or i-klass)
+                                   Register index,   // itable index, MethodType, etc.
+                                   Register recv,    // if caller wants to see it
+                                   Register flags    // if caller wants to test it
+                                   ) {
   // determine flags
-  Bytecodes::Code code = bytecode();
+  const Bytecodes::Code code = bytecode();
   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
   const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
+  const bool is_invokehandle     = code == Bytecodes::_invokehandle;
   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
   const bool is_invokespecial    = code == Bytecodes::_invokespecial;
-  const bool load_receiver      = (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic);
-  const bool receiver_null_check = is_invokespecial;
-  const bool save_flags = is_invokeinterface || is_invokevirtual;
+  const bool load_receiver       = (recv  != noreg);
+  const bool save_flags          = (flags != noreg);
+  assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic), "");
+  assert(save_flags    == (is_invokeinterface || is_invokevirtual), "need flags for vfinal");
+  assert(flags == noreg || flags == rdx, "");
+  assert(recv  == noreg || recv  == rcx, "");
+
   // setup registers & access constant pool cache
-  const Register recv   = rcx;
-  const Register flags  = rdx;
+  if (recv  == noreg)  recv  = rcx;
+  if (flags == noreg)  flags = rdx;
   assert_different_registers(method, index, recv, flags);
 
   // save 'interpreter return address'
@@ -2954,19 +2981,29 @@
 
   load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
 
-  // load receiver if needed (note: no return address pushed yet)
-  if (load_receiver) {
-    assert(!is_invokedynamic, "");
-    __ movl(recv, flags);
-    __ andl(recv, 0xFF);
-    Address recv_addr(rsp, recv, Address::times_8, -Interpreter::expr_offset_in_bytes(1));
-    __ movptr(recv, recv_addr);
-    __ verify_oop(recv);
+  // maybe push appendix to arguments (just before return address)
+  if (is_invokedynamic || is_invokehandle) {
+    Label L_no_push;
+    __ verify_oop(index);
+    __ testl(flags, (1 << ConstantPoolCacheEntry::has_appendix_shift));
+    __ jccb(Assembler::zero, L_no_push);
+    // Push the appendix as a trailing parameter.
+    // This must be done before we get the receiver,
+    // since the parameter_size includes it.
+    __ push(index);  // push appendix (MethodType, CallSite, etc.)
+    __ bind(L_no_push);
   }
 
-  // do null check if needed
-  if (receiver_null_check) {
-    __ null_check(recv);
+  // load receiver if needed (after appendix is pushed so parameter size is correct)
+  // Note: no return address pushed yet
+  if (load_receiver) {
+    __ movl(recv, flags);
+    __ andl(recv, ConstantPoolCacheEntry::parameter_size_mask);
+    const int no_return_pc_pushed_yet = -1;  // argument slot correction before we push return address
+    const int receiver_is_at_end      = -1;  // back off one slot to get receiver
+    Address recv_addr = __ argument_address(recv, no_return_pc_pushed_yet + receiver_is_at_end);
+    __ movptr(recv, recv_addr);
+    __ verify_oop(recv);
   }
 
   if (save_flags) {
@@ -2974,16 +3011,14 @@
   }
 
   // compute return type
-  __ shrl(flags, ConstantPoolCacheEntry::tosBits);
-  // Make sure we don't need to mask flags for tosBits after the above shift
-  ConstantPoolCacheEntry::verify_tosBits();
+  __ shrl(flags, ConstantPoolCacheEntry::tos_state_shift);
+  // Make sure we don't need to mask flags after the above shift
+  ConstantPoolCacheEntry::verify_tos_state_shift();
   // load return address
   {
-    address table_addr;
-    if (is_invokeinterface || is_invokedynamic)
-      table_addr = (address)Interpreter::return_5_addrs_by_index_table();
-    else
-      table_addr = (address)Interpreter::return_3_addrs_by_index_table();
+    const address table_addr = (is_invokeinterface || is_invokedynamic) ?
+        (address)Interpreter::return_5_addrs_by_index_table() :
+        (address)Interpreter::return_3_addrs_by_index_table();
     ExternalAddress table(table_addr);
     __ lea(rscratch1, table);
     __ movptr(flags, Address(rscratch1, flags, Address::times_ptr));
@@ -2992,7 +3027,7 @@
   // push return address
   __ push(flags);
 
-  // Restore flag field from the constant pool cache, and restore esi
+  // Restore flags value from the constant pool cache, and restore rsi
   // for later null checks.  r13 is the bytecode pointer
   if (save_flags) {
     __ movl(flags, r13);
@@ -3006,11 +3041,13 @@
                                          Register flags) {
   // Uses temporary registers rax, rdx
   assert_different_registers(index, recv, rax, rdx);
+  assert(index == rbx, "");
+  assert(recv  == rcx, "");
 
   // Test for an invoke of a final method
   Label notFinal;
   __ movl(rax, flags);
-  __ andl(rax, (1 << ConstantPoolCacheEntry::vfinalMethod));
+  __ andl(rax, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
   __ jcc(Assembler::zero, notFinal);
 
   const Register method = index;  // method must be rbx
@@ -3018,6 +3055,7 @@
          "methodOop must be rbx for interpreter calling convention");
 
   // do the call - the index is actually the method to call
+  // that is, f2 is a vtable index if !is_vfinal, else f2 is a methodOop
   __ verify_oop(method);
 
   // It's final, need a null check here!
@@ -3033,20 +3071,13 @@
   // get receiver klass
   __ null_check(recv, oopDesc::klass_offset_in_bytes());
   __ load_klass(rax, recv);
-
   __ verify_oop(rax);
 
   // profile this call
   __ profile_virtual_call(rax, r14, rdx);
 
   // get target methodOop & entry point
-  const int base = instanceKlass::vtable_start_offset() * wordSize;
-  assert(vtableEntry::size() * wordSize == 8,
-         "adjust the scaling in the code below");
-  __ movptr(method, Address(rax, index,
-                                 Address::times_8,
-                                 base + vtableEntry::method_offset_in_bytes()));
-  __ movptr(rdx, Address(method, methodOopDesc::interpreter_entry_offset()));
+  __ lookup_virtual_method(rax, index, method);
   __ jump_from_interpreted(method, rdx);
 }
 
@@ -3054,7 +3085,10 @@
 void TemplateTable::invokevirtual(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f2_byte, "use this argument");
-  prepare_invoke(rbx, noreg, byte_no);
+  prepare_invoke(byte_no,
+                 rbx,    // method or vtable index
+                 noreg,  // unused itable index
+                 rcx, rdx); // recv, flags
 
   // rbx: index
   // rcx: receiver
@@ -3067,7 +3101,10 @@
 void TemplateTable::invokespecial(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
-  prepare_invoke(rbx, noreg, byte_no);
+  prepare_invoke(byte_no, rbx, noreg,  // get f1 methodOop
+                 rcx);  // get receiver also for null check
+  __ verify_oop(rcx);
+  __ null_check(rcx);
   // do the call
   __ verify_oop(rbx);
   __ profile_call(rax);
@@ -3078,7 +3115,7 @@
 void TemplateTable::invokestatic(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
-  prepare_invoke(rbx, noreg, byte_no);
+  prepare_invoke(byte_no, rbx);  // get f1 methodOop
   // do the call
   __ verify_oop(rbx);
   __ profile_call(rax);
@@ -3094,10 +3131,11 @@
 void TemplateTable::invokeinterface(int byte_no) {
   transition(vtos, vtos);
   assert(byte_no == f1_byte, "use this argument");
-  prepare_invoke(rax, rbx, byte_no);
+  prepare_invoke(byte_no, rax, rbx,  // get f1 klassOop, f2 itable index
+                 rcx, rdx); // recv, flags
 
-  // rax: Interface
-  // rbx: index
+  // rax: interface klass (from f1)
+  // rbx: itable index (from f2)
   // rcx: receiver
   // rdx: flags
 
@@ -3107,14 +3145,15 @@
   // another compliant java compiler.
   Label notMethod;
   __ movl(r14, rdx);
-  __ andl(r14, (1 << ConstantPoolCacheEntry::methodInterface));
+  __ andl(r14, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
   __ jcc(Assembler::zero, notMethod);
 
   invokevirtual_helper(rbx, rcx, rdx);
   __ bind(notMethod);
 
   // Get receiver klass into rdx - also a null check
-  __ restore_locals(); // restore r14
+  __ restore_locals();  // restore r14
+  __ null_check(rcx, oopDesc::klass_offset_in_bytes());
   __ load_klass(rdx, rcx);
   __ verify_oop(rdx);
 
@@ -3129,7 +3168,7 @@
                              rbx, r13,
                              no_such_interface);
 
-  // rbx,: methodOop to call
+  // rbx: methodOop to call
   // rcx: receiver
   // Check for abstract method error
   // Note: This should be done more efficiently via a throw_abstract_method_error
@@ -3166,12 +3205,42 @@
                    InterpreterRuntime::throw_IncompatibleClassChangeError));
   // the call_VM checks for exception, so we should never return here.
   __ should_not_reach_here();
-  return;
 }
 
+
+void TemplateTable::invokehandle(int byte_no) {
+  transition(vtos, vtos);
+  assert(byte_no == f12_oop, "use this argument");
+  const Register rbx_method = rbx;  // f2
+  const Register rax_mtype  = rax;  // f1
+  const Register rcx_recv   = rcx;
+  const Register rdx_flags  = rdx;
+
+  if (!EnableInvokeDynamic) {
+    // rewriter does not generate this bytecode
+    __ should_not_reach_here();
+    return;
+  }
+
+  prepare_invoke(byte_no,
+                 rbx_method, rax_mtype,  // get f2 methodOop, f1 MethodType
+                 rcx_recv);
+  __ verify_oop(rbx_method);
+  __ verify_oop(rcx_recv);
+  __ null_check(rcx_recv);
+
+  // Note:  rax_mtype is already pushed (if necessary) by prepare_invoke
+
+  // FIXME: profile the LambdaForm also
+  __ profile_final_call(rax);
+
+  __ jump_from_interpreted(rbx_method, rdx);
+}
+
+
 void TemplateTable::invokedynamic(int byte_no) {
   transition(vtos, vtos);
-  assert(byte_no == f1_oop, "use this argument");
+  assert(byte_no == f12_oop, "use this argument");
 
   if (!EnableInvokeDynamic) {
     // We should not encounter this bytecode if !EnableInvokeDynamic.
@@ -3184,26 +3253,23 @@
     return;
   }
 
-  prepare_invoke(rax, rbx, byte_no);
+  const Register rbx_method   = rbx;
+  const Register rax_callsite = rax;
 
-  // rax: CallSite object (f1)
-  // rbx: unused (f2)
-  // rcx: receiver address
-  // rdx: flags (unused)
+  prepare_invoke(byte_no, rbx_method, rax_callsite);
 
-  Register rax_callsite      = rax;
-  Register rcx_method_handle = rcx;
+  // rax: CallSite object (from f1)
+  // rbx: MH.linkToCallSite method (from f2)
+
+  // Note:  rax_callsite is already pushed by prepare_invoke
 
   // %%% should make a type profile for any invokedynamic that takes a ref argument
   // profile this call
   __ profile_call(r13);
 
   __ verify_oop(rax_callsite);
-  __ load_heap_oop(rcx_method_handle, Address(rax_callsite, __ delayed_value(java_lang_invoke_CallSite::target_offset_in_bytes, rdx)));
-  __ null_check(rcx_method_handle);
-  __ verify_oop(rcx_method_handle);
-  __ prepare_to_jump_from_interpreted();
-  __ jump_to_method_handle_entry(rcx_method_handle, rdx);
+
+  __ jump_from_interpreted(rbx_method, rdx);
 }
 
 
diff --git a/hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp b/hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp
index 922e495..15c4c00 100644
--- a/hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp
+++ b/hotspot/src/cpu/x86/vm/templateTable_x86_64.hpp
@@ -25,7 +25,12 @@
 #ifndef CPU_X86_VM_TEMPLATETABLE_X86_64_HPP
 #define CPU_X86_VM_TEMPLATETABLE_X86_64_HPP
 
-  static void prepare_invoke(Register method, Register index, int byte_no);
+  static void prepare_invoke(int byte_no,
+                             Register method,         // linked method (or i-klass)
+                             Register index = noreg,  // itable index, MethodType, etc.
+                             Register recv  = noreg,  // if caller wants to see it
+                             Register flags = noreg   // if caller wants to test it
+                             );
   static void invokevirtual_helper(Register index, Register recv,
                                    Register flags);
   static void volatile_barrier(Assembler::Membar_mask_bits order_constraint);
diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
index 121be7a2..21bb573 100644
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.cpp
@@ -363,6 +363,11 @@
   }
 
   _supports_cx8 = supports_cmpxchg8();
+  // xchg and xadd instructions
+  _supports_atomic_getset4 = true;
+  _supports_atomic_getadd4 = true;
+  LP64_ONLY(_supports_atomic_getset8 = true);
+  LP64_ONLY(_supports_atomic_getadd8 = true);
 
 #ifdef _LP64
   // OS should support SSE for x64 and hardware should support at least SSE2.
@@ -414,13 +419,16 @@
   if (UseAVX < 1)
     _cpuFeatures &= ~CPU_AVX;
 
+  if (!UseAES && !FLAG_IS_DEFAULT(UseAES))
+    _cpuFeatures &= ~CPU_AES;
+
   if (logical_processors_per_package() == 1) {
     // HT processor could be installed on a system which doesn't support HT.
     _cpuFeatures &= ~CPU_HT;
   }
 
   char buf[256];
-  jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
+  jio_snprintf(buf, sizeof(buf), "(%u cores per cpu, %u threads per core) family %d model %d stepping %d%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s",
                cores_per_cpu(), threads_per_core(),
                cpu_family(), _model, _stepping,
                (supports_cmov() ? ", cmov" : ""),
@@ -436,6 +444,7 @@
                (supports_popcnt() ? ", popcnt" : ""),
                (supports_avx()    ? ", avx" : ""),
                (supports_avx2()   ? ", avx2" : ""),
+               (supports_aes()    ? ", aes" : ""),
                (supports_mmx_ext() ? ", mmxext" : ""),
                (supports_3dnow_prefetch() ? ", 3dnowpref" : ""),
                (supports_lzcnt()   ? ", lzcnt": ""),
@@ -467,6 +476,55 @@
   if (!supports_avx ()) // Drop to 0 if no AVX  support
     UseAVX = 0;
 
+  // Use AES instructions if available.
+  if (supports_aes()) {
+    if (FLAG_IS_DEFAULT(UseAES)) {
+      UseAES = true;
+    }
+  } else if (UseAES) {
+    if (!FLAG_IS_DEFAULT(UseAES))
+      warning("AES instructions not available on this CPU");
+    FLAG_SET_DEFAULT(UseAES, false);
+  }
+
+  // The AES intrinsic stubs require AES instruction support (of course)
+  // but also require AVX and sse3 modes for instructions it use.
+  if (UseAES && (UseAVX > 0) && (UseSSE > 2)) {
+    if (FLAG_IS_DEFAULT(UseAESIntrinsics)) {
+      UseAESIntrinsics = true;
+    }
+  } else if (UseAESIntrinsics) {
+    if (!FLAG_IS_DEFAULT(UseAESIntrinsics))
+      warning("AES intrinsics not available on this CPU");
+    FLAG_SET_DEFAULT(UseAESIntrinsics, false);
+  }
+
+#ifdef COMPILER2
+  if (UseFPUForSpilling) {
+    if (UseSSE < 2) {
+      // Only supported with SSE2+
+      FLAG_SET_DEFAULT(UseFPUForSpilling, false);
+    }
+  }
+  if (MaxVectorSize > 0) {
+    if (!is_power_of_2(MaxVectorSize)) {
+      warning("MaxVectorSize must be a power of 2");
+      FLAG_SET_DEFAULT(MaxVectorSize, 32);
+    }
+    if (MaxVectorSize > 32) {
+      FLAG_SET_DEFAULT(MaxVectorSize, 32);
+    }
+    if (MaxVectorSize > 16 && UseAVX == 0) {
+      // Only supported with AVX+
+      FLAG_SET_DEFAULT(MaxVectorSize, 16);
+    }
+    if (UseSSE < 2) {
+      // Only supported with SSE2+
+      FLAG_SET_DEFAULT(MaxVectorSize, 0);
+    }
+  }
+#endif
+
   // On new cpus instructions which update whole XMM register should be used
   // to prevent partial register stall due to dependencies on high half.
   //
@@ -536,14 +594,20 @@
         AllocatePrefetchInstr = 3;
       }
       // On family 15h processors use XMM and UnalignedLoadStores for Array Copy
-      if( FLAG_IS_DEFAULT(UseXMMForArrayCopy) ) {
+      if (supports_sse2() && FLAG_IS_DEFAULT(UseXMMForArrayCopy)) {
         UseXMMForArrayCopy = true;
       }
-      if( FLAG_IS_DEFAULT(UseUnalignedLoadStores) && UseXMMForArrayCopy ) {
+      if (supports_sse2() && FLAG_IS_DEFAULT(UseUnalignedLoadStores)) {
         UseUnalignedLoadStores = true;
       }
     }
 
+#ifdef COMPILER2
+    if (MaxVectorSize > 16) {
+      // Limit vectors size to 16 bytes on current AMD cpus.
+      FLAG_SET_DEFAULT(MaxVectorSize, 16);
+    }
+#endif // COMPILER2
   }
 
   if( is_intel() ) { // Intel cpus specific settings
@@ -580,16 +644,16 @@
         MaxLoopPad = 11;
       }
 #endif // COMPILER2
-      if( FLAG_IS_DEFAULT(UseXMMForArrayCopy) ) {
+      if (FLAG_IS_DEFAULT(UseXMMForArrayCopy)) {
         UseXMMForArrayCopy = true; // use SSE2 movq on new Intel cpus
       }
-      if( supports_sse4_2() && supports_ht() ) { // Newest Intel cpus
-        if( FLAG_IS_DEFAULT(UseUnalignedLoadStores) && UseXMMForArrayCopy ) {
+      if (supports_sse4_2() && supports_ht()) { // Newest Intel cpus
+        if (FLAG_IS_DEFAULT(UseUnalignedLoadStores)) {
           UseUnalignedLoadStores = true; // use movdqu on newest Intel cpus
         }
       }
-      if( supports_sse4_2() && UseSSE >= 4 ) {
-        if( FLAG_IS_DEFAULT(UseSSE42Intrinsics)) {
+      if (supports_sse4_2() && UseSSE >= 4) {
+        if (FLAG_IS_DEFAULT(UseSSE42Intrinsics)) {
           UseSSE42Intrinsics = true;
         }
       }
@@ -607,13 +671,11 @@
   }
 
 #ifdef COMPILER2
-  if (UseFPUForSpilling) {
-    if (UseSSE < 2) {
-      // Only supported with SSE2+
-      FLAG_SET_DEFAULT(UseFPUForSpilling, false);
-    }
+  if (FLAG_IS_DEFAULT(AlignVector)) {
+    // Modern processors allow misaligned memory operations for vectors.
+    AlignVector = !UseUnalignedLoadStores;
   }
-#endif
+#endif // COMPILER2
 
   assert(0 <= ReadPrefetchInstr && ReadPrefetchInstr <= 3, "invalid value");
   assert(0 <= AllocatePrefetchInstr && AllocatePrefetchInstr <= 3, "invalid value");
@@ -679,6 +741,9 @@
     if (UseAVX > 0) {
       tty->print("  UseAVX=%d",UseAVX);
     }
+    if (UseAES) {
+      tty->print("  UseAES=1");
+    }
     tty->cr();
     tty->print("Allocation");
     if (AllocatePrefetchStyle <= 0 || UseSSE == 0 && !supports_3dnow_prefetch()) {
diff --git a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp
index 7e30977..aa3dc17 100644
--- a/hotspot/src/cpu/x86/vm/vm_version_x86.hpp
+++ b/hotspot/src/cpu/x86/vm/vm_version_x86.hpp
@@ -78,7 +78,9 @@
                sse4_2   : 1,
                         : 2,
                popcnt   : 1,
-                        : 3,
+                        : 1,
+               aes      : 1,
+                        : 1,
                osxsave  : 1,
                avx      : 1,
                         : 3;
@@ -244,7 +246,8 @@
     CPU_TSC    = (1 << 15),
     CPU_TSCINV = (1 << 16),
     CPU_AVX    = (1 << 17),
-    CPU_AVX2   = (1 << 18)
+    CPU_AVX2   = (1 << 18),
+    CPU_AES    = (1 << 19)
   } cpuFeatureFlags;
 
   enum {
@@ -420,6 +423,8 @@
       result |= CPU_TSC;
     if (_cpuid_info.ext_cpuid7_edx.bits.tsc_invariance != 0)
       result |= CPU_TSCINV;
+    if (_cpuid_info.std_cpuid1_ecx.bits.aes != 0)
+      result |= CPU_AES;
 
     // AMD features.
     if (is_amd()) {
@@ -544,6 +549,7 @@
   static bool supports_avx()      { return (_cpuFeatures & CPU_AVX) != 0; }
   static bool supports_avx2()     { return (_cpuFeatures & CPU_AVX2) != 0; }
   static bool supports_tsc()      { return (_cpuFeatures & CPU_TSC)    != 0; }
+  static bool supports_aes()      { return (_cpuFeatures & CPU_AES) != 0; }
 
   // Intel features
   static bool is_intel_family_core() { return is_intel() &&
diff --git a/hotspot/src/cpu/x86/vm/vmreg_x86.cpp b/hotspot/src/cpu/x86/vm/vmreg_x86.cpp
index a0bfe6e..8995977 100644
--- a/hotspot/src/cpu/x86/vm/vmreg_x86.cpp
+++ b/hotspot/src/cpu/x86/vm/vmreg_x86.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -48,8 +48,9 @@
 
   XMMRegister xreg = ::as_XMMRegister(0);
   for ( ; i < ConcreteRegisterImpl::max_xmm ; ) {
-    regName[i++] = xreg->name();
-    regName[i++] = xreg->name();
+    for (int j = 0 ; j < 8 ; j++) {
+      regName[i++] = xreg->name();
+    }
     xreg = xreg->successor();
   }
   for ( ; i < ConcreteRegisterImpl::number_of_registers ; i ++ ) {
diff --git a/hotspot/src/cpu/x86/vm/vmreg_x86.inline.hpp b/hotspot/src/cpu/x86/vm/vmreg_x86.inline.hpp
index 88201bd..0608d3e 100644
--- a/hotspot/src/cpu/x86/vm/vmreg_x86.inline.hpp
+++ b/hotspot/src/cpu/x86/vm/vmreg_x86.inline.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -39,7 +39,7 @@
 }
 
 inline VMReg XMMRegisterImpl::as_VMReg() {
-  return VMRegImpl::as_VMReg((encoding() << 1) + ConcreteRegisterImpl::max_fpr);
+  return VMRegImpl::as_VMReg((encoding() << 3) + ConcreteRegisterImpl::max_fpr);
 }
 
 
@@ -75,7 +75,7 @@
 inline XMMRegister VMRegImpl::as_XMMRegister() {
   assert( is_XMMRegister() && is_even(value()), "must be" );
   // Yuk
-  return ::as_XMMRegister((value() - ConcreteRegisterImpl::max_fpr) >> 1);
+  return ::as_XMMRegister((value() - ConcreteRegisterImpl::max_fpr) >> 3);
 }
 
 inline   bool VMRegImpl::is_concrete() {
diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp
index 1517ca3..87108d5 100644
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_32.cpp
@@ -76,8 +76,7 @@
   // get receiver klass
   address npe_addr = __ pc();
   __ movptr(rax, Address(rcx, oopDesc::klass_offset_in_bytes()));
-  // compute entry offset (in words)
-  int entry_offset = instanceKlass::vtable_start_offset() + vtable_index*vtableEntry::size();
+
 #ifndef PRODUCT
   if (DebugVtables) {
     Label L;
@@ -93,7 +92,8 @@
   const Register method = rbx;
 
   // load methodOop and target address
-  __ movptr(method, Address(rax, entry_offset*wordSize + vtableEntry::method_offset_in_bytes()));
+  __ lookup_virtual_method(rax, vtable_index, method);
+
   if (DebugVtables) {
     Label L;
     __ cmpptr(method, (int32_t)NULL_WORD);
diff --git a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
index f12d85a..5592c6f 100644
--- a/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
+++ b/hotspot/src/cpu/x86/vm/vtableStubs_x86_64.cpp
@@ -69,10 +69,6 @@
   address npe_addr = __ pc();
   __ load_klass(rax, j_rarg0);
 
-  // compute entry offset (in words)
-  int entry_offset =
-    instanceKlass::vtable_start_offset() + vtable_index * vtableEntry::size();
-
 #ifndef PRODUCT
   if (DebugVtables) {
     Label L;
@@ -90,9 +86,8 @@
   // load methodOop and target address
   const Register method = rbx;
 
-  __ movptr(method, Address(rax,
-                            entry_offset * wordSize +
-                            vtableEntry::method_offset_in_bytes()));
+  __ lookup_virtual_method(rax, vtable_index, method);
+
   if (DebugVtables) {
     Label L;
     __ cmpptr(method, (int32_t)NULL_WORD);
diff --git a/hotspot/src/cpu/x86/vm/x86.ad b/hotspot/src/cpu/x86/vm/x86.ad
index 6bd9128..5350a04 100644
--- a/hotspot/src/cpu/x86/vm/x86.ad
+++ b/hotspot/src/cpu/x86/vm/x86.ad
@@ -24,6 +24,456 @@
 
 // X86 Common Architecture Description File
 
+//----------REGISTER DEFINITION BLOCK------------------------------------------
+// This information is used by the matcher and the register allocator to
+// describe individual registers and classes of registers within the target
+// archtecture.
+
+register %{
+//----------Architecture Description Register Definitions----------------------
+// General Registers
+// "reg_def"  name ( register save type, C convention save type,
+//                   ideal register type, encoding );
+// Register Save Types:
+//
+// NS  = No-Save:       The register allocator assumes that these registers
+//                      can be used without saving upon entry to the method, &
+//                      that they do not need to be saved at call sites.
+//
+// SOC = Save-On-Call:  The register allocator assumes that these registers
+//                      can be used without saving upon entry to the method,
+//                      but that they must be saved at call sites.
+//
+// SOE = Save-On-Entry: The register allocator assumes that these registers
+//                      must be saved before using them upon entry to the
+//                      method, but they do not need to be saved at call
+//                      sites.
+//
+// AS  = Always-Save:   The register allocator assumes that these registers
+//                      must be saved before using them upon entry to the
+//                      method, & that they must be saved at call sites.
+//
+// Ideal Register Type is used to determine how to save & restore a
+// register.  Op_RegI will get spilled with LoadI/StoreI, Op_RegP will get
+// spilled with LoadP/StoreP.  If the register supports both, use Op_RegI.
+//
+// The encoding number is the actual bit-pattern placed into the opcodes.
+
+// XMM registers.  256-bit registers or 8 words each, labeled (a)-h.
+// Word a in each register holds a Float, words ab hold a Double.
+// The whole registers are used in SSE4.2 version intrinsics,
+// array copy stubs and superword operations (see UseSSE42Intrinsics,
+// UseXMMForArrayCopy and UseSuperword flags).
+// XMM8-XMM15 must be encoded with REX (VEX for UseAVX).
+// Linux ABI:   No register preserved across function calls
+//              XMM0-XMM7 might hold parameters
+// Windows ABI: XMM6-XMM15 preserved across function calls
+//              XMM0-XMM3 might hold parameters
+
+reg_def XMM0 ( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg());
+reg_def XMM0b( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(1));
+reg_def XMM0c( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(2));
+reg_def XMM0d( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(3));
+reg_def XMM0e( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(4));
+reg_def XMM0f( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(5));
+reg_def XMM0g( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(6));
+reg_def XMM0h( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next(7));
+
+reg_def XMM1 ( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg());
+reg_def XMM1b( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(1));
+reg_def XMM1c( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(2));
+reg_def XMM1d( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(3));
+reg_def XMM1e( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(4));
+reg_def XMM1f( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(5));
+reg_def XMM1g( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(6));
+reg_def XMM1h( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next(7));
+
+reg_def XMM2 ( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg());
+reg_def XMM2b( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(1));
+reg_def XMM2c( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(2));
+reg_def XMM2d( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(3));
+reg_def XMM2e( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(4));
+reg_def XMM2f( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(5));
+reg_def XMM2g( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(6));
+reg_def XMM2h( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next(7));
+
+reg_def XMM3 ( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg());
+reg_def XMM3b( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(1));
+reg_def XMM3c( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(2));
+reg_def XMM3d( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(3));
+reg_def XMM3e( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(4));
+reg_def XMM3f( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(5));
+reg_def XMM3g( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(6));
+reg_def XMM3h( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next(7));
+
+reg_def XMM4 ( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg());
+reg_def XMM4b( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(1));
+reg_def XMM4c( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(2));
+reg_def XMM4d( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(3));
+reg_def XMM4e( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(4));
+reg_def XMM4f( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(5));
+reg_def XMM4g( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(6));
+reg_def XMM4h( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next(7));
+
+reg_def XMM5 ( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg());
+reg_def XMM5b( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(1));
+reg_def XMM5c( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(2));
+reg_def XMM5d( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(3));
+reg_def XMM5e( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(4));
+reg_def XMM5f( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(5));
+reg_def XMM5g( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(6));
+reg_def XMM5h( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next(7));
+
+#ifdef _WIN64
+
+reg_def XMM6 ( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg());
+reg_def XMM6b( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(1));
+reg_def XMM6c( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(2));
+reg_def XMM6d( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(3));
+reg_def XMM6e( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(4));
+reg_def XMM6f( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(5));
+reg_def XMM6g( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(6));
+reg_def XMM6h( SOC, SOE, Op_RegF, 6, xmm6->as_VMReg()->next(7));
+
+reg_def XMM7 ( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg());
+reg_def XMM7b( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(1));
+reg_def XMM7c( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(2));
+reg_def XMM7d( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(3));
+reg_def XMM7e( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(4));
+reg_def XMM7f( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(5));
+reg_def XMM7g( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(6));
+reg_def XMM7h( SOC, SOE, Op_RegF, 7, xmm7->as_VMReg()->next(7));
+
+reg_def XMM8 ( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg());
+reg_def XMM8b( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(1));
+reg_def XMM8c( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(2));
+reg_def XMM8d( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(3));
+reg_def XMM8e( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(4));
+reg_def XMM8f( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(5));
+reg_def XMM8g( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(6));
+reg_def XMM8h( SOC, SOE, Op_RegF, 8, xmm8->as_VMReg()->next(7));
+
+reg_def XMM9 ( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg());
+reg_def XMM9b( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(1));
+reg_def XMM9c( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(2));
+reg_def XMM9d( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(3));
+reg_def XMM9e( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(4));
+reg_def XMM9f( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(5));
+reg_def XMM9g( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(6));
+reg_def XMM9h( SOC, SOE, Op_RegF, 9, xmm9->as_VMReg()->next(7));
+
+reg_def XMM10 ( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg());
+reg_def XMM10b( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(1));
+reg_def XMM10c( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(2));
+reg_def XMM10d( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(3));
+reg_def XMM10e( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(4));
+reg_def XMM10f( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(5));
+reg_def XMM10g( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(6));
+reg_def XMM10h( SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next(7));
+
+reg_def XMM11 ( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg());
+reg_def XMM11b( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(1));
+reg_def XMM11c( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(2));
+reg_def XMM11d( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(3));
+reg_def XMM11e( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(4));
+reg_def XMM11f( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(5));
+reg_def XMM11g( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(6));
+reg_def XMM11h( SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next(7));
+
+reg_def XMM12 ( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg());
+reg_def XMM12b( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(1));
+reg_def XMM12c( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(2));
+reg_def XMM12d( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(3));
+reg_def XMM12e( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(4));
+reg_def XMM12f( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(5));
+reg_def XMM12g( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(6));
+reg_def XMM12h( SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next(7));
+
+reg_def XMM13 ( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg());
+reg_def XMM13b( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(1));
+reg_def XMM13c( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(2));
+reg_def XMM13d( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(3));
+reg_def XMM13e( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(4));
+reg_def XMM13f( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(5));
+reg_def XMM13g( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(6));
+reg_def XMM13h( SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next(7));
+
+reg_def XMM14 ( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg());
+reg_def XMM14b( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(1));
+reg_def XMM14c( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(2));
+reg_def XMM14d( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(3));
+reg_def XMM14e( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(4));
+reg_def XMM14f( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(5));
+reg_def XMM14g( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(6));
+reg_def XMM14h( SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next(7));
+
+reg_def XMM15 ( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg());
+reg_def XMM15b( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(1));
+reg_def XMM15c( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(2));
+reg_def XMM15d( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(3));
+reg_def XMM15e( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(4));
+reg_def XMM15f( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(5));
+reg_def XMM15g( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(6));
+reg_def XMM15h( SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next(7));
+
+#else // _WIN64
+
+reg_def XMM6 ( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg());
+reg_def XMM6b( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(1));
+reg_def XMM6c( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(2));
+reg_def XMM6d( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(3));
+reg_def XMM6e( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(4));
+reg_def XMM6f( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(5));
+reg_def XMM6g( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(6));
+reg_def XMM6h( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next(7));
+
+reg_def XMM7 ( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg());
+reg_def XMM7b( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(1));
+reg_def XMM7c( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(2));
+reg_def XMM7d( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(3));
+reg_def XMM7e( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(4));
+reg_def XMM7f( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(5));
+reg_def XMM7g( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(6));
+reg_def XMM7h( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next(7));
+
+#ifdef _LP64
+
+reg_def XMM8 ( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg());
+reg_def XMM8b( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(1));
+reg_def XMM8c( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(2));
+reg_def XMM8d( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(3));
+reg_def XMM8e( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(4));
+reg_def XMM8f( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(5));
+reg_def XMM8g( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(6));
+reg_def XMM8h( SOC, SOC, Op_RegF, 8, xmm8->as_VMReg()->next(7));
+
+reg_def XMM9 ( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg());
+reg_def XMM9b( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(1));
+reg_def XMM9c( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(2));
+reg_def XMM9d( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(3));
+reg_def XMM9e( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(4));
+reg_def XMM9f( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(5));
+reg_def XMM9g( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(6));
+reg_def XMM9h( SOC, SOC, Op_RegF, 9, xmm9->as_VMReg()->next(7));
+
+reg_def XMM10 ( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg());
+reg_def XMM10b( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(1));
+reg_def XMM10c( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(2));
+reg_def XMM10d( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(3));
+reg_def XMM10e( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(4));
+reg_def XMM10f( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(5));
+reg_def XMM10g( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(6));
+reg_def XMM10h( SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next(7));
+
+reg_def XMM11 ( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg());
+reg_def XMM11b( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(1));
+reg_def XMM11c( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(2));
+reg_def XMM11d( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(3));
+reg_def XMM11e( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(4));
+reg_def XMM11f( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(5));
+reg_def XMM11g( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(6));
+reg_def XMM11h( SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next(7));
+
+reg_def XMM12 ( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg());
+reg_def XMM12b( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(1));
+reg_def XMM12c( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(2));
+reg_def XMM12d( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(3));
+reg_def XMM12e( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(4));
+reg_def XMM12f( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(5));
+reg_def XMM12g( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(6));
+reg_def XMM12h( SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next(7));
+
+reg_def XMM13 ( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg());
+reg_def XMM13b( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(1));
+reg_def XMM13c( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(2));
+reg_def XMM13d( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(3));
+reg_def XMM13e( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(4));
+reg_def XMM13f( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(5));
+reg_def XMM13g( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(6));
+reg_def XMM13h( SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next(7));
+
+reg_def XMM14 ( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg());
+reg_def XMM14b( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(1));
+reg_def XMM14c( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(2));
+reg_def XMM14d( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(3));
+reg_def XMM14e( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(4));
+reg_def XMM14f( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(5));
+reg_def XMM14g( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(6));
+reg_def XMM14h( SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next(7));
+
+reg_def XMM15 ( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg());
+reg_def XMM15b( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(1));
+reg_def XMM15c( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(2));
+reg_def XMM15d( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(3));
+reg_def XMM15e( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(4));
+reg_def XMM15f( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(5));
+reg_def XMM15g( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(6));
+reg_def XMM15h( SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next(7));
+
+#endif // _LP64
+
+#endif // _WIN64
+
+#ifdef _LP64
+reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad());
+#else
+reg_def RFLAGS(SOC, SOC, 0, 8, VMRegImpl::Bad());
+#endif // _LP64
+
+alloc_class chunk1(XMM0,  XMM0b,  XMM0c,  XMM0d,  XMM0e,  XMM0f,  XMM0g,  XMM0h,
+                   XMM1,  XMM1b,  XMM1c,  XMM1d,  XMM1e,  XMM1f,  XMM1g,  XMM1h,
+                   XMM2,  XMM2b,  XMM2c,  XMM2d,  XMM2e,  XMM2f,  XMM2g,  XMM2h,
+                   XMM3,  XMM3b,  XMM3c,  XMM3d,  XMM3e,  XMM3f,  XMM3g,  XMM3h,
+                   XMM4,  XMM4b,  XMM4c,  XMM4d,  XMM4e,  XMM4f,  XMM4g,  XMM4h,
+                   XMM5,  XMM5b,  XMM5c,  XMM5d,  XMM5e,  XMM5f,  XMM5g,  XMM5h,
+                   XMM6,  XMM6b,  XMM6c,  XMM6d,  XMM6e,  XMM6f,  XMM6g,  XMM6h,
+                   XMM7,  XMM7b,  XMM7c,  XMM7d,  XMM7e,  XMM7f,  XMM7g,  XMM7h
+#ifdef _LP64
+                  ,XMM8,  XMM8b,  XMM8c,  XMM8d,  XMM8e,  XMM8f,  XMM8g,  XMM8h,
+                   XMM9,  XMM9b,  XMM9c,  XMM9d,  XMM9e,  XMM9f,  XMM9g,  XMM9h,
+                   XMM10, XMM10b, XMM10c, XMM10d, XMM10e, XMM10f, XMM10g, XMM10h,
+                   XMM11, XMM11b, XMM11c, XMM11d, XMM11e, XMM11f, XMM11g, XMM11h,
+                   XMM12, XMM12b, XMM12c, XMM12d, XMM12e, XMM12f, XMM12g, XMM12h,
+                   XMM13, XMM13b, XMM13c, XMM13d, XMM13e, XMM13f, XMM13g, XMM13h,
+                   XMM14, XMM14b, XMM14c, XMM14d, XMM14e, XMM14f, XMM14g, XMM14h,
+                   XMM15, XMM15b, XMM15c, XMM15d, XMM15e, XMM15f, XMM15g, XMM15h
+#endif
+                   );
+
+// flags allocation class should be last.
+alloc_class chunk2(RFLAGS);
+
+// Singleton class for condition codes
+reg_class int_flags(RFLAGS);
+
+// Class for all float registers
+reg_class float_reg(XMM0,
+                    XMM1,
+                    XMM2,
+                    XMM3,
+                    XMM4,
+                    XMM5,
+                    XMM6,
+                    XMM7
+#ifdef _LP64
+                   ,XMM8,
+                    XMM9,
+                    XMM10,
+                    XMM11,
+                    XMM12,
+                    XMM13,
+                    XMM14,
+                    XMM15
+#endif
+                    );
+
+// Class for all double registers
+reg_class double_reg(XMM0,  XMM0b,
+                     XMM1,  XMM1b,
+                     XMM2,  XMM2b,
+                     XMM3,  XMM3b,
+                     XMM4,  XMM4b,
+                     XMM5,  XMM5b,
+                     XMM6,  XMM6b,
+                     XMM7,  XMM7b
+#ifdef _LP64
+                    ,XMM8,  XMM8b,
+                     XMM9,  XMM9b,
+                     XMM10, XMM10b,
+                     XMM11, XMM11b,
+                     XMM12, XMM12b,
+                     XMM13, XMM13b,
+                     XMM14, XMM14b,
+                     XMM15, XMM15b
+#endif
+                     );
+
+// Class for all 32bit vector registers
+reg_class vectors_reg(XMM0,
+                      XMM1,
+                      XMM2,
+                      XMM3,
+                      XMM4,
+                      XMM5,
+                      XMM6,
+                      XMM7
+#ifdef _LP64
+                     ,XMM8,
+                      XMM9,
+                      XMM10,
+                      XMM11,
+                      XMM12,
+                      XMM13,
+                      XMM14,
+                      XMM15
+#endif
+                      );
+
+// Class for all 64bit vector registers
+reg_class vectord_reg(XMM0,  XMM0b,
+                      XMM1,  XMM1b,
+                      XMM2,  XMM2b,
+                      XMM3,  XMM3b,
+                      XMM4,  XMM4b,
+                      XMM5,  XMM5b,
+                      XMM6,  XMM6b,
+                      XMM7,  XMM7b
+#ifdef _LP64
+                     ,XMM8,  XMM8b,
+                      XMM9,  XMM9b,
+                      XMM10, XMM10b,
+                      XMM11, XMM11b,
+                      XMM12, XMM12b,
+                      XMM13, XMM13b,
+                      XMM14, XMM14b,
+                      XMM15, XMM15b
+#endif
+                      );
+
+// Class for all 128bit vector registers
+reg_class vectorx_reg(XMM0,  XMM0b,  XMM0c,  XMM0d,
+                      XMM1,  XMM1b,  XMM1c,  XMM1d,
+                      XMM2,  XMM2b,  XMM2c,  XMM2d,
+                      XMM3,  XMM3b,  XMM3c,  XMM3d,
+                      XMM4,  XMM4b,  XMM4c,  XMM4d,
+                      XMM5,  XMM5b,  XMM5c,  XMM5d,
+                      XMM6,  XMM6b,  XMM6c,  XMM6d,
+                      XMM7,  XMM7b,  XMM7c,  XMM7d
+#ifdef _LP64
+                     ,XMM8,  XMM8b,  XMM8c,  XMM8d,
+                      XMM9,  XMM9b,  XMM9c,  XMM9d,
+                      XMM10, XMM10b, XMM10c, XMM10d,
+                      XMM11, XMM11b, XMM11c, XMM11d,
+                      XMM12, XMM12b, XMM12c, XMM12d,
+                      XMM13, XMM13b, XMM13c, XMM13d,
+                      XMM14, XMM14b, XMM14c, XMM14d,
+                      XMM15, XMM15b, XMM15c, XMM15d
+#endif
+                      );
+
+// Class for all 256bit vector registers
+reg_class vectory_reg(XMM0,  XMM0b,  XMM0c,  XMM0d,  XMM0e,  XMM0f,  XMM0g,  XMM0h,
+                      XMM1,  XMM1b,  XMM1c,  XMM1d,  XMM1e,  XMM1f,  XMM1g,  XMM1h,
+                      XMM2,  XMM2b,  XMM2c,  XMM2d,  XMM2e,  XMM2f,  XMM2g,  XMM2h,
+                      XMM3,  XMM3b,  XMM3c,  XMM3d,  XMM3e,  XMM3f,  XMM3g,  XMM3h,
+                      XMM4,  XMM4b,  XMM4c,  XMM4d,  XMM4e,  XMM4f,  XMM4g,  XMM4h,
+                      XMM5,  XMM5b,  XMM5c,  XMM5d,  XMM5e,  XMM5f,  XMM5g,  XMM5h,
+                      XMM6,  XMM6b,  XMM6c,  XMM6d,  XMM6e,  XMM6f,  XMM6g,  XMM6h,
+                      XMM7,  XMM7b,  XMM7c,  XMM7d,  XMM7e,  XMM7f,  XMM7g,  XMM7h
+#ifdef _LP64
+                     ,XMM8,  XMM8b,  XMM8c,  XMM8d,  XMM8e,  XMM8f,  XMM8g,  XMM8h,
+                      XMM9,  XMM9b,  XMM9c,  XMM9d,  XMM9e,  XMM9f,  XMM9g,  XMM9h,
+                      XMM10, XMM10b, XMM10c, XMM10d, XMM10e, XMM10f, XMM10g, XMM10h,
+                      XMM11, XMM11b, XMM11c, XMM11d, XMM11e, XMM11f, XMM11g, XMM11h,
+                      XMM12, XMM12b, XMM12c, XMM12d, XMM12e, XMM12f, XMM12g, XMM12h,
+                      XMM13, XMM13b, XMM13c, XMM13d, XMM13e, XMM13f, XMM13g, XMM13h,
+                      XMM14, XMM14b, XMM14c, XMM14d, XMM14e, XMM14f, XMM14g, XMM14h,
+                      XMM15, XMM15b, XMM15c, XMM15d, XMM15e, XMM15f, XMM15g, XMM15h
+#endif
+                      );
+
+%}
+
 source %{
   // Float masks come from different places depending on platform.
 #ifdef _LP64
@@ -38,6 +488,283 @@
   static address double_signflip() { return (address)double_signflip_pool; }
 #endif
 
+// Map Types to machine register types
+const int Matcher::base2reg[Type::lastype] = {
+  Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN,
+  Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */
+  Op_VecS, Op_VecD, Op_VecX, Op_VecY, /* Vectors */
+  Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */
+  0, 0/*abio*/,
+  Op_RegP /* Return address */, 0, /* the memories */
+  Op_RegF, Op_RegF, Op_RegF, Op_RegD, Op_RegD, Op_RegD,
+  0  /*bottom*/
+};
+
+const bool Matcher::match_rule_supported(int opcode) {
+  if (!has_match_rule(opcode))
+    return false;
+
+  switch (opcode) {
+    case Op_PopCountI:
+    case Op_PopCountL:
+      if (!UsePopCountInstruction)
+        return false;
+    break;
+    case Op_MulVI:
+      if ((UseSSE < 4) && (UseAVX < 1)) // only with SSE4_1 or AVX
+        return false;
+    break;
+    case Op_CompareAndSwapL:
+#ifdef _LP64
+    case Op_CompareAndSwapP:
+#endif
+      if (!VM_Version::supports_cx8())
+        return false;
+    break;
+  }
+
+  return true;  // Per default match rules are supported.
+}
+
+// Max vector size in bytes. 0 if not supported.
+const int Matcher::vector_width_in_bytes(BasicType bt) {
+  assert(is_java_primitive(bt), "only primitive type vectors");
+  if (UseSSE < 2) return 0;
+  // SSE2 supports 128bit vectors for all types.
+  // AVX2 supports 256bit vectors for all types.
+  int size = (UseAVX > 1) ? 32 : 16;
+  // AVX1 supports 256bit vectors only for FLOAT and DOUBLE.
+  if (UseAVX > 0 && (bt == T_FLOAT || bt == T_DOUBLE))
+    size = 32;
+  // Use flag to limit vector size.
+  size = MIN2(size,(int)MaxVectorSize);
+  // Minimum 2 values in vector (or 4 for bytes).
+  switch (bt) {
+  case T_DOUBLE:
+  case T_LONG:
+    if (size < 16) return 0;
+  case T_FLOAT:
+  case T_INT:
+    if (size < 8) return 0;
+  case T_BOOLEAN:
+  case T_BYTE:
+  case T_CHAR:
+  case T_SHORT:
+    if (size < 4) return 0;
+    break;
+  default:
+    ShouldNotReachHere();
+  }
+  return size;
+}
+
+// Limits on vector size (number of elements) loaded into vector.
+const int Matcher::max_vector_size(const BasicType bt) {
+  return vector_width_in_bytes(bt)/type2aelembytes(bt);
+}
+const int Matcher::min_vector_size(const BasicType bt) {
+  int max_size = max_vector_size(bt);
+  // Min size which can be loaded into vector is 4 bytes.
+  int size = (type2aelembytes(bt) == 1) ? 4 : 2;
+  return MIN2(size,max_size);
+}
+
+// Vector ideal reg corresponding to specidied size in bytes
+const int Matcher::vector_ideal_reg(int size) {
+  assert(MaxVectorSize >= size, "");
+  switch(size) {
+    case  4: return Op_VecS;
+    case  8: return Op_VecD;
+    case 16: return Op_VecX;
+    case 32: return Op_VecY;
+  }
+  ShouldNotReachHere();
+  return 0;
+}
+
+// Only lowest bits of xmm reg are used for vector shift count.
+const int Matcher::vector_shift_count_ideal_reg(int size) {
+  return Op_VecS;
+}
+
+// x86 supports misaligned vectors store/load.
+const bool Matcher::misaligned_vectors_ok() {
+  return !AlignVector; // can be changed by flag
+}
+
+// Helper methods for MachSpillCopyNode::implementation().
+static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
+                          int src_hi, int dst_hi, uint ireg, outputStream* st) {
+  // In 64-bit VM size calculation is very complex. Emitting instructions
+  // into scratch buffer is used to get size in 64-bit VM.
+  LP64_ONLY( assert(!do_size, "this method calculates size only for 32-bit VM"); )
+  assert(ireg == Op_VecS || // 32bit vector
+         (src_lo & 1) == 0 && (src_lo + 1) == src_hi &&
+         (dst_lo & 1) == 0 && (dst_lo + 1) == dst_hi,
+         "no non-adjacent vector moves" );
+  if (cbuf) {
+    MacroAssembler _masm(cbuf);
+    int offset = __ offset();
+    switch (ireg) {
+    case Op_VecS: // copy whole register
+    case Op_VecD:
+    case Op_VecX:
+      __ movdqu(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]));
+      break;
+    case Op_VecY:
+      __ vmovdqu(as_XMMRegister(Matcher::_regEncode[dst_lo]), as_XMMRegister(Matcher::_regEncode[src_lo]));
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+    int size = __ offset() - offset;
+#ifdef ASSERT
+    // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
+    assert(!do_size || size == 4, "incorrect size calculattion");
+#endif
+    return size;
+#ifndef PRODUCT
+  } else if (!do_size) {
+    switch (ireg) {
+    case Op_VecS:
+    case Op_VecD:
+    case Op_VecX:
+      st->print("movdqu  %s,%s\t# spill",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+      break;
+    case Op_VecY:
+      st->print("vmovdqu %s,%s\t# spill",Matcher::regName[dst_lo],Matcher::regName[src_lo]);
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+#endif
+  }
+  // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes as SIMD prefix.
+  return 4;
+}
+
+static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
+                            int stack_offset, int reg, uint ireg, outputStream* st) {
+  // In 64-bit VM size calculation is very complex. Emitting instructions
+  // into scratch buffer is used to get size in 64-bit VM.
+  LP64_ONLY( assert(!do_size, "this method calculates size only for 32-bit VM"); )
+  if (cbuf) {
+    MacroAssembler _masm(cbuf);
+    int offset = __ offset();
+    if (is_load) {
+      switch (ireg) {
+      case Op_VecS:
+        __ movdl(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
+        break;
+      case Op_VecD:
+        __ movq(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
+        break;
+      case Op_VecX:
+        __ movdqu(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
+        break;
+      case Op_VecY:
+        __ vmovdqu(as_XMMRegister(Matcher::_regEncode[reg]), Address(rsp, stack_offset));
+        break;
+      default:
+        ShouldNotReachHere();
+      }
+    } else { // store
+      switch (ireg) {
+      case Op_VecS:
+        __ movdl(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
+        break;
+      case Op_VecD:
+        __ movq(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
+        break;
+      case Op_VecX:
+        __ movdqu(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
+        break;
+      case Op_VecY:
+        __ vmovdqu(Address(rsp, stack_offset), as_XMMRegister(Matcher::_regEncode[reg]));
+        break;
+      default:
+        ShouldNotReachHere();
+      }
+    }
+    int size = __ offset() - offset;
+#ifdef ASSERT
+    int offset_size = (stack_offset == 0) ? 0 : ((stack_offset < 0x80) ? 1 : 4);
+    // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
+    assert(!do_size || size == (5+offset_size), "incorrect size calculattion");
+#endif
+    return size;
+#ifndef PRODUCT
+  } else if (!do_size) {
+    if (is_load) {
+      switch (ireg) {
+      case Op_VecS:
+        st->print("movd    %s,[rsp + %d]\t# spill", Matcher::regName[reg], stack_offset);
+        break;
+      case Op_VecD:
+        st->print("movq    %s,[rsp + %d]\t# spill", Matcher::regName[reg], stack_offset);
+        break;
+       case Op_VecX:
+        st->print("movdqu  %s,[rsp + %d]\t# spill", Matcher::regName[reg], stack_offset);
+        break;
+      case Op_VecY:
+        st->print("vmovdqu %s,[rsp + %d]\t# spill", Matcher::regName[reg], stack_offset);
+        break;
+      default:
+        ShouldNotReachHere();
+      }
+    } else { // store
+      switch (ireg) {
+      case Op_VecS:
+        st->print("movd    [rsp + %d],%s\t# spill", stack_offset, Matcher::regName[reg]);
+        break;
+      case Op_VecD:
+        st->print("movq    [rsp + %d],%s\t# spill", stack_offset, Matcher::regName[reg]);
+        break;
+       case Op_VecX:
+        st->print("movdqu  [rsp + %d],%s\t# spill", stack_offset, Matcher::regName[reg]);
+        break;
+      case Op_VecY:
+        st->print("vmovdqu [rsp + %d],%s\t# spill", stack_offset, Matcher::regName[reg]);
+        break;
+      default:
+        ShouldNotReachHere();
+      }
+    }
+#endif
+  }
+  int offset_size = (stack_offset == 0) ? 0 : ((stack_offset < 0x80) ? 1 : 4);
+  // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
+  return 5+offset_size;
+}
+
+static inline jfloat replicate4_imm(int con, int width) {
+  // Load a constant of "width" (in bytes) and replicate it to fill 32bit.
+  assert(width == 1 || width == 2, "only byte or short types here");
+  int bit_width = width * 8;
+  jint val = con;
+  val &= (1 << bit_width) - 1;  // mask off sign bits
+  while(bit_width < 32) {
+    val |= (val << bit_width);
+    bit_width <<= 1;
+  }
+  jfloat fval = *((jfloat*) &val);  // coerce to float type
+  return fval;
+}
+
+static inline jdouble replicate8_imm(int con, int width) {
+  // Load a constant of "width" (in bytes) and replicate it to fill 64bit.
+  assert(width == 1 || width == 2 || width == 4, "only byte, short or int types here");
+  int bit_width = width * 8;
+  jlong val = con;
+  val &= (((jlong) 1) << bit_width) - 1;  // mask off sign bits
+  while(bit_width < 64) {
+    val |= (val << bit_width);
+    bit_width <<= 1;
+  }
+  jdouble dval = *((jdouble*) &val);  // coerce to double type
+  return dval;
+}
+
 #ifndef PRODUCT
   void MachNopNode::format(PhaseRegAlloc*, outputStream* st) const {
     st->print("nop \t# %d bytes pad for loops and calls", _count);
@@ -103,6 +830,46 @@
 
 %}
 
+
+//----------OPERANDS-----------------------------------------------------------
+// Operand definitions must precede instruction definitions for correct parsing
+// in the ADLC because operands constitute user defined types which are used in
+// instruction definitions.
+
+// Vectors
+operand vecS() %{
+  constraint(ALLOC_IN_RC(vectors_reg));
+  match(VecS);
+
+  format %{ %}
+  interface(REG_INTER);
+%}
+
+operand vecD() %{
+  constraint(ALLOC_IN_RC(vectord_reg));
+  match(VecD);
+
+  format %{ %}
+  interface(REG_INTER);
+%}
+
+operand vecX() %{
+  constraint(ALLOC_IN_RC(vectorx_reg));
+  match(VecX);
+
+  format %{ %}
+  interface(REG_INTER);
+%}
+
+operand vecY() %{
+  constraint(ALLOC_IN_RC(vectory_reg));
+  match(VecY);
+
+  format %{ %}
+  interface(REG_INTER);
+%}
+
+
 // INSTRUCTIONS -- Platform independent definitions (same for 32- and 64-bit)
 
 // ============================================================================
@@ -153,7 +920,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vaddF_reg(regF dst, regF src1, regF src2) %{
+instruct addF_reg_reg(regF dst, regF src1, regF src2) %{
   predicate(UseAVX > 0);
   match(Set dst (AddF src1 src2));
 
@@ -165,7 +932,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vaddF_mem(regF dst, regF src1, memory src2) %{
+instruct addF_reg_mem(regF dst, regF src1, memory src2) %{
   predicate(UseAVX > 0);
   match(Set dst (AddF src1 (LoadF src2)));
 
@@ -177,7 +944,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vaddF_imm(regF dst, regF src, immF con) %{
+instruct addF_reg_imm(regF dst, regF src, immF con) %{
   predicate(UseAVX > 0);
   match(Set dst (AddF src con));
 
@@ -224,7 +991,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vaddD_reg(regD dst, regD src1, regD src2) %{
+instruct addD_reg_reg(regD dst, regD src1, regD src2) %{
   predicate(UseAVX > 0);
   match(Set dst (AddD src1 src2));
 
@@ -236,7 +1003,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vaddD_mem(regD dst, regD src1, memory src2) %{
+instruct addD_reg_mem(regD dst, regD src1, memory src2) %{
   predicate(UseAVX > 0);
   match(Set dst (AddD src1 (LoadD src2)));
 
@@ -248,7 +1015,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vaddD_imm(regD dst, regD src, immD con) %{
+instruct addD_reg_imm(regD dst, regD src, immD con) %{
   predicate(UseAVX > 0);
   match(Set dst (AddD src con));
 
@@ -295,7 +1062,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vsubF_reg(regF dst, regF src1, regF src2) %{
+instruct subF_reg_reg(regF dst, regF src1, regF src2) %{
   predicate(UseAVX > 0);
   match(Set dst (SubF src1 src2));
 
@@ -307,7 +1074,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vsubF_mem(regF dst, regF src1, memory src2) %{
+instruct subF_reg_mem(regF dst, regF src1, memory src2) %{
   predicate(UseAVX > 0);
   match(Set dst (SubF src1 (LoadF src2)));
 
@@ -319,7 +1086,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vsubF_imm(regF dst, regF src, immF con) %{
+instruct subF_reg_imm(regF dst, regF src, immF con) %{
   predicate(UseAVX > 0);
   match(Set dst (SubF src con));
 
@@ -366,7 +1133,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vsubD_reg(regD dst, regD src1, regD src2) %{
+instruct subD_reg_reg(regD dst, regD src1, regD src2) %{
   predicate(UseAVX > 0);
   match(Set dst (SubD src1 src2));
 
@@ -378,7 +1145,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vsubD_mem(regD dst, regD src1, memory src2) %{
+instruct subD_reg_mem(regD dst, regD src1, memory src2) %{
   predicate(UseAVX > 0);
   match(Set dst (SubD src1 (LoadD src2)));
 
@@ -390,7 +1157,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vsubD_imm(regD dst, regD src, immD con) %{
+instruct subD_reg_imm(regD dst, regD src, immD con) %{
   predicate(UseAVX > 0);
   match(Set dst (SubD src con));
 
@@ -437,7 +1204,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vmulF_reg(regF dst, regF src1, regF src2) %{
+instruct mulF_reg_reg(regF dst, regF src1, regF src2) %{
   predicate(UseAVX > 0);
   match(Set dst (MulF src1 src2));
 
@@ -449,7 +1216,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vmulF_mem(regF dst, regF src1, memory src2) %{
+instruct mulF_reg_mem(regF dst, regF src1, memory src2) %{
   predicate(UseAVX > 0);
   match(Set dst (MulF src1 (LoadF src2)));
 
@@ -461,7 +1228,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vmulF_imm(regF dst, regF src, immF con) %{
+instruct mulF_reg_imm(regF dst, regF src, immF con) %{
   predicate(UseAVX > 0);
   match(Set dst (MulF src con));
 
@@ -508,7 +1275,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vmulD_reg(regD dst, regD src1, regD src2) %{
+instruct mulD_reg_reg(regD dst, regD src1, regD src2) %{
   predicate(UseAVX > 0);
   match(Set dst (MulD src1 src2));
 
@@ -520,7 +1287,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vmulD_mem(regD dst, regD src1, memory src2) %{
+instruct mulD_reg_mem(regD dst, regD src1, memory src2) %{
   predicate(UseAVX > 0);
   match(Set dst (MulD src1 (LoadD src2)));
 
@@ -532,7 +1299,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vmulD_imm(regD dst, regD src, immD con) %{
+instruct mulD_reg_imm(regD dst, regD src, immD con) %{
   predicate(UseAVX > 0);
   match(Set dst (MulD src con));
 
@@ -579,7 +1346,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vdivF_reg(regF dst, regF src1, regF src2) %{
+instruct divF_reg_reg(regF dst, regF src1, regF src2) %{
   predicate(UseAVX > 0);
   match(Set dst (DivF src1 src2));
 
@@ -591,7 +1358,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vdivF_mem(regF dst, regF src1, memory src2) %{
+instruct divF_reg_mem(regF dst, regF src1, memory src2) %{
   predicate(UseAVX > 0);
   match(Set dst (DivF src1 (LoadF src2)));
 
@@ -603,7 +1370,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vdivF_imm(regF dst, regF src, immF con) %{
+instruct divF_reg_imm(regF dst, regF src, immF con) %{
   predicate(UseAVX > 0);
   match(Set dst (DivF src con));
 
@@ -650,7 +1417,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vdivD_reg(regD dst, regD src1, regD src2) %{
+instruct divD_reg_reg(regD dst, regD src1, regD src2) %{
   predicate(UseAVX > 0);
   match(Set dst (DivD src1 src2));
 
@@ -662,7 +1429,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vdivD_mem(regD dst, regD src1, memory src2) %{
+instruct divD_reg_mem(regD dst, regD src1, memory src2) %{
   predicate(UseAVX > 0);
   match(Set dst (DivD src1 (LoadD src2)));
 
@@ -674,7 +1441,7 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vdivD_imm(regD dst, regD src, immD con) %{
+instruct divD_reg_imm(regD dst, regD src, immD con) %{
   predicate(UseAVX > 0);
   match(Set dst (DivD src con));
 
@@ -697,14 +1464,15 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vabsF_reg(regF dst, regF src) %{
+instruct absF_reg_reg(regF dst, regF src) %{
   predicate(UseAVX > 0);
   match(Set dst (AbsF src));
   ins_cost(150);
   format %{ "vandps  $dst, $src, [0x7fffffff]\t# abs float by sign masking" %}
   ins_encode %{
+    bool vector256 = false;
     __ vandps($dst$$XMMRegister, $src$$XMMRegister,
-              ExternalAddress(float_signmask()));
+              ExternalAddress(float_signmask()), vector256);
   %}
   ins_pipe(pipe_slow);
 %}
@@ -721,15 +1489,16 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vabsD_reg(regD dst, regD src) %{
+instruct absD_reg_reg(regD dst, regD src) %{
   predicate(UseAVX > 0);
   match(Set dst (AbsD src));
   ins_cost(150);
   format %{ "vandpd  $dst, $src, [0x7fffffffffffffff]\t"
             "# abs double by sign masking" %}
   ins_encode %{
+    bool vector256 = false;
     __ vandpd($dst$$XMMRegister, $src$$XMMRegister,
-              ExternalAddress(double_signmask()));
+              ExternalAddress(double_signmask()), vector256);
   %}
   ins_pipe(pipe_slow);
 %}
@@ -745,14 +1514,15 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vnegF_reg(regF dst, regF src) %{
+instruct negF_reg_reg(regF dst, regF src) %{
   predicate(UseAVX > 0);
   match(Set dst (NegF src));
   ins_cost(150);
   format %{ "vxorps  $dst, $src, [0x80000000]\t# neg float by sign flipping" %}
   ins_encode %{
+    bool vector256 = false;
     __ vxorps($dst$$XMMRegister, $src$$XMMRegister,
-              ExternalAddress(float_signflip()));
+              ExternalAddress(float_signflip()), vector256);
   %}
   ins_pipe(pipe_slow);
 %}
@@ -769,15 +1539,16 @@
   ins_pipe(pipe_slow);
 %}
 
-instruct vnegD_reg(regD dst, regD src) %{
+instruct negD_reg_reg(regD dst, regD src) %{
   predicate(UseAVX > 0);
   match(Set dst (NegD src));
   ins_cost(150);
   format %{ "vxorpd  $dst, $src, [0x8000000000000000]\t"
             "# neg double by sign flipping" %}
   ins_encode %{
+    bool vector256 = false;
     __ vxorpd($dst$$XMMRegister, $src$$XMMRegister,
-              ExternalAddress(double_signflip()));
+              ExternalAddress(double_signflip()), vector256);
   %}
   ins_pipe(pipe_slow);
 %}
@@ -852,3 +1623,3373 @@
   ins_pipe(pipe_slow);
 %}
 
+
+// ====================VECTOR INSTRUCTIONS=====================================
+
+// Load vectors (4 bytes long)
+instruct loadV4(vecS dst, memory mem) %{
+  predicate(n->as_LoadVector()->memory_size() == 4);
+  match(Set dst (LoadVector mem));
+  ins_cost(125);
+  format %{ "movd    $dst,$mem\t! load vector (4 bytes)" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $mem$$Address);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Load vectors (8 bytes long)
+instruct loadV8(vecD dst, memory mem) %{
+  predicate(n->as_LoadVector()->memory_size() == 8);
+  match(Set dst (LoadVector mem));
+  ins_cost(125);
+  format %{ "movq    $dst,$mem\t! load vector (8 bytes)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $mem$$Address);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Load vectors (16 bytes long)
+instruct loadV16(vecX dst, memory mem) %{
+  predicate(n->as_LoadVector()->memory_size() == 16);
+  match(Set dst (LoadVector mem));
+  ins_cost(125);
+  format %{ "movdqu  $dst,$mem\t! load vector (16 bytes)" %}
+  ins_encode %{
+    __ movdqu($dst$$XMMRegister, $mem$$Address);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Load vectors (32 bytes long)
+instruct loadV32(vecY dst, memory mem) %{
+  predicate(n->as_LoadVector()->memory_size() == 32);
+  match(Set dst (LoadVector mem));
+  ins_cost(125);
+  format %{ "vmovdqu $dst,$mem\t! load vector (32 bytes)" %}
+  ins_encode %{
+    __ vmovdqu($dst$$XMMRegister, $mem$$Address);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Store vectors
+instruct storeV4(memory mem, vecS src) %{
+  predicate(n->as_StoreVector()->memory_size() == 4);
+  match(Set mem (StoreVector mem src));
+  ins_cost(145);
+  format %{ "movd    $mem,$src\t! store vector (4 bytes)" %}
+  ins_encode %{
+    __ movdl($mem$$Address, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct storeV8(memory mem, vecD src) %{
+  predicate(n->as_StoreVector()->memory_size() == 8);
+  match(Set mem (StoreVector mem src));
+  ins_cost(145);
+  format %{ "movq    $mem,$src\t! store vector (8 bytes)" %}
+  ins_encode %{
+    __ movq($mem$$Address, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct storeV16(memory mem, vecX src) %{
+  predicate(n->as_StoreVector()->memory_size() == 16);
+  match(Set mem (StoreVector mem src));
+  ins_cost(145);
+  format %{ "movdqu  $mem,$src\t! store vector (16 bytes)" %}
+  ins_encode %{
+    __ movdqu($mem$$Address, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct storeV32(memory mem, vecY src) %{
+  predicate(n->as_StoreVector()->memory_size() == 32);
+  match(Set mem (StoreVector mem src));
+  ins_cost(145);
+  format %{ "vmovdqu $mem,$src\t! store vector (32 bytes)" %}
+  ins_encode %{
+    __ vmovdqu($mem$$Address, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate byte scalar to be vector
+instruct Repl4B(vecS dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateB src));
+  format %{ "movd    $dst,$src\n\t"
+            "punpcklbw $dst,$dst\n\t"
+            "pshuflw $dst,$dst,0x00\t! replicate4B" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
+    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl8B(vecD dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateB src));
+  format %{ "movd    $dst,$src\n\t"
+            "punpcklbw $dst,$dst\n\t"
+            "pshuflw $dst,$dst,0x00\t! replicate8B" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
+    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl16B(vecX dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 16);
+  match(Set dst (ReplicateB src));
+  format %{ "movd    $dst,$src\n\t"
+            "punpcklbw $dst,$dst\n\t"
+            "pshuflw $dst,$dst,0x00\n\t"
+            "punpcklqdq $dst,$dst\t! replicate16B" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
+    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl32B(vecY dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 32);
+  match(Set dst (ReplicateB src));
+  format %{ "movd    $dst,$src\n\t"
+            "punpcklbw $dst,$dst\n\t"
+            "pshuflw $dst,$dst,0x00\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate32B" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
+    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate byte scalar immediate to be vector by loading from const table.
+instruct Repl4B_imm(vecS dst, immI con) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateB con));
+  format %{ "movdl   $dst,[$constantaddress]\t! replicate4B($con)" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $constantaddress(replicate4_imm($con$$constant, 1)));
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl8B_imm(vecD dst, immI con) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateB con));
+  format %{ "movq    $dst,[$constantaddress]\t! replicate8B($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl16B_imm(vecX dst, immI con) %{
+  predicate(n->as_Vector()->length() == 16);
+  match(Set dst (ReplicateB con));
+  format %{ "movq    $dst,[$constantaddress]\n\t"
+            "punpcklqdq $dst,$dst\t! replicate16B($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl32B_imm(vecY dst, immI con) %{
+  predicate(n->as_Vector()->length() == 32);
+  match(Set dst (ReplicateB con));
+  format %{ "movq    $dst,[$constantaddress]\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst\t! lreplicate32B($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 1)));
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate byte scalar zero to be vector
+instruct Repl4B_zero(vecS dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateB zero));
+  format %{ "pxor    $dst,$dst\t! replicate4B zero" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl8B_zero(vecD dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateB zero));
+  format %{ "pxor    $dst,$dst\t! replicate8B zero" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl16B_zero(vecX dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 16);
+  match(Set dst (ReplicateB zero));
+  format %{ "pxor    $dst,$dst\t! replicate16B zero" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl32B_zero(vecY dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 32);
+  match(Set dst (ReplicateB zero));
+  format %{ "vpxor   $dst,$dst,$dst\t! replicate32B zero" %}
+  ins_encode %{
+    // Use vxorpd since AVX does not have vpxor for 256-bit (AVX2 will have it).
+    bool vector256 = true;
+    __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+// Replicate char/short (2 byte) scalar to be vector
+instruct Repl2S(vecS dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateS src));
+  format %{ "movd    $dst,$src\n\t"
+            "pshuflw $dst,$dst,0x00\t! replicate2S" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4S(vecD dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateS src));
+  format %{ "movd    $dst,$src\n\t"
+            "pshuflw $dst,$dst,0x00\t! replicate4S" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl8S(vecX dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateS src));
+  format %{ "movd    $dst,$src\n\t"
+            "pshuflw $dst,$dst,0x00\n\t"
+            "punpcklqdq $dst,$dst\t! replicate8S" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl16S(vecY dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 16);
+  match(Set dst (ReplicateS src));
+  format %{ "movd    $dst,$src\n\t"
+            "pshuflw $dst,$dst,0x00\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate16S" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate char/short (2 byte) scalar immediate to be vector by loading from const table.
+instruct Repl2S_imm(vecS dst, immI con) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateS con));
+  format %{ "movdl   $dst,[$constantaddress]\t! replicate2S($con)" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $constantaddress(replicate4_imm($con$$constant, 2)));
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4S_imm(vecD dst, immI con) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateS con));
+  format %{ "movq    $dst,[$constantaddress]\t! replicate4S($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl8S_imm(vecX dst, immI con) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateS con));
+  format %{ "movq    $dst,[$constantaddress]\n\t"
+            "punpcklqdq $dst,$dst\t! replicate8S($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl16S_imm(vecY dst, immI con) %{
+  predicate(n->as_Vector()->length() == 16);
+  match(Set dst (ReplicateS con));
+  format %{ "movq    $dst,[$constantaddress]\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate16S($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 2)));
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate char/short (2 byte) scalar zero to be vector
+instruct Repl2S_zero(vecS dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateS zero));
+  format %{ "pxor    $dst,$dst\t! replicate2S zero" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4S_zero(vecD dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateS zero));
+  format %{ "pxor    $dst,$dst\t! replicate4S zero" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl8S_zero(vecX dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateS zero));
+  format %{ "pxor    $dst,$dst\t! replicate8S zero" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl16S_zero(vecY dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 16);
+  match(Set dst (ReplicateS zero));
+  format %{ "vpxor   $dst,$dst,$dst\t! replicate16S zero" %}
+  ins_encode %{
+    // Use vxorpd since AVX does not have vpxor for 256-bit (AVX2 will have it).
+    bool vector256 = true;
+    __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+// Replicate integer (4 byte) scalar to be vector
+instruct Repl2I(vecD dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateI src));
+  format %{ "movd    $dst,$src\n\t"
+            "pshufd  $dst,$dst,0x00\t! replicate2I" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4I(vecX dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateI src));
+  format %{ "movd    $dst,$src\n\t"
+            "pshufd  $dst,$dst,0x00\t! replicate4I" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl8I(vecY dst, rRegI src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateI src));
+  format %{ "movd    $dst,$src\n\t"
+            "pshufd  $dst,$dst,0x00\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate8I" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate integer (4 byte) scalar immediate to be vector by loading from const table.
+instruct Repl2I_imm(vecD dst, immI con) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateI con));
+  format %{ "movq    $dst,[$constantaddress]\t! replicate2I($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4I_imm(vecX dst, immI con) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateI con));
+  format %{ "movq    $dst,[$constantaddress]\t! replicate4I($con)\n\t"
+            "punpcklqdq $dst,$dst" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl8I_imm(vecY dst, immI con) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateI con));
+  format %{ "movq    $dst,[$constantaddress]\t! replicate8I($con)\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress(replicate8_imm($con$$constant, 4)));
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Integer could be loaded into xmm register directly from memory.
+instruct Repl2I_mem(vecD dst, memory mem) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateI (LoadI mem)));
+  format %{ "movd    $dst,$mem\n\t"
+            "pshufd  $dst,$dst,0x00\t! replicate2I" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $mem$$Address);
+    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4I_mem(vecX dst, memory mem) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateI (LoadI mem)));
+  format %{ "movd    $dst,$mem\n\t"
+            "pshufd  $dst,$dst,0x00\t! replicate4I" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $mem$$Address);
+    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl8I_mem(vecY dst, memory mem) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateI (LoadI mem)));
+  format %{ "movd    $dst,$mem\n\t"
+            "pshufd  $dst,$dst,0x00\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate8I" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $mem$$Address);
+    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate integer (4 byte) scalar zero to be vector
+instruct Repl2I_zero(vecD dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateI zero));
+  format %{ "pxor    $dst,$dst\t! replicate2I" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4I_zero(vecX dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateI zero));
+  format %{ "pxor    $dst,$dst\t! replicate4I zero)" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl8I_zero(vecY dst, immI0 zero) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateI zero));
+  format %{ "vpxor   $dst,$dst,$dst\t! replicate8I zero" %}
+  ins_encode %{
+    // Use vxorpd since AVX does not have vpxor for 256-bit (AVX2 will have it).
+    bool vector256 = true;
+    __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+// Replicate long (8 byte) scalar to be vector
+#ifdef _LP64
+instruct Repl2L(vecX dst, rRegL src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateL src));
+  format %{ "movdq   $dst,$src\n\t"
+            "punpcklqdq $dst,$dst\t! replicate2L" %}
+  ins_encode %{
+    __ movdq($dst$$XMMRegister, $src$$Register);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl4L(vecY dst, rRegL src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateL src));
+  format %{ "movdq   $dst,$src\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate4L" %}
+  ins_encode %{
+    __ movdq($dst$$XMMRegister, $src$$Register);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+#else // _LP64
+instruct Repl2L(vecX dst, eRegL src, regD tmp) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateL src));
+  effect(TEMP dst, USE src, TEMP tmp);
+  format %{ "movdl   $dst,$src.lo\n\t"
+            "movdl   $tmp,$src.hi\n\t"
+            "punpckldq $dst,$tmp\n\t"
+            "punpcklqdq $dst,$dst\t! replicate2L"%}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ movdl($tmp$$XMMRegister, HIGH_FROM_LOW($src$$Register));
+    __ punpckldq($dst$$XMMRegister, $tmp$$XMMRegister);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl4L(vecY dst, eRegL src, regD tmp) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateL src));
+  effect(TEMP dst, USE src, TEMP tmp);
+  format %{ "movdl   $dst,$src.lo\n\t"
+            "movdl   $tmp,$src.hi\n\t"
+            "punpckldq $dst,$tmp\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate4L" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $src$$Register);
+    __ movdl($tmp$$XMMRegister, HIGH_FROM_LOW($src$$Register));
+    __ punpckldq($dst$$XMMRegister, $tmp$$XMMRegister);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+#endif // _LP64
+
+// Replicate long (8 byte) scalar immediate to be vector by loading from const table.
+instruct Repl2L_imm(vecX dst, immL con) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateL con));
+  format %{ "movq    $dst,[$constantaddress]\n\t"
+            "punpcklqdq $dst,$dst\t! replicate2L($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress($con));
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl4L_imm(vecY dst, immL con) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateL con));
+  format %{ "movq    $dst,[$constantaddress]\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate4L($con)" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $constantaddress($con));
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Long could be loaded into xmm register directly from memory.
+instruct Repl2L_mem(vecX dst, memory mem) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateL (LoadL mem)));
+  format %{ "movq    $dst,$mem\n\t"
+            "punpcklqdq $dst,$dst\t! replicate2L" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $mem$$Address);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl4L_mem(vecY dst, memory mem) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateL (LoadL mem)));
+  format %{ "movq    $dst,$mem\n\t"
+            "punpcklqdq $dst,$dst\n\t"
+            "vinserti128h $dst,$dst,$dst\t! replicate4L" %}
+  ins_encode %{
+    __ movq($dst$$XMMRegister, $mem$$Address);
+    __ punpcklqdq($dst$$XMMRegister, $dst$$XMMRegister);
+    __ vinserti128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate long (8 byte) scalar zero to be vector
+instruct Repl2L_zero(vecX dst, immL0 zero) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateL zero));
+  format %{ "pxor    $dst,$dst\t! replicate2L zero" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4L_zero(vecY dst, immL0 zero) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateL zero));
+  format %{ "vpxor   $dst,$dst,$dst\t! replicate4L zero" %}
+  ins_encode %{
+    // Use vxorpd since AVX does not have vpxor for 256-bit (AVX2 will have it).
+    bool vector256 = true;
+    __ vpxor($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+// Replicate float (4 byte) scalar to be vector
+instruct Repl2F(vecD dst, regF src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateF src));
+  format %{ "pshufd  $dst,$dst,0x00\t! replicate2F" %}
+  ins_encode %{
+    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4F(vecX dst, regF src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateF src));
+  format %{ "pshufd  $dst,$dst,0x00\t! replicate4F" %}
+  ins_encode %{
+    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl8F(vecY dst, regF src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateF src));
+  format %{ "pshufd  $dst,$src,0x00\n\t"
+            "vinsertf128h $dst,$dst,$dst\t! replicate8F" %}
+  ins_encode %{
+    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
+    __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate float (4 byte) scalar zero to be vector
+instruct Repl2F_zero(vecD dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateF zero));
+  format %{ "xorps   $dst,$dst\t! replicate2F zero" %}
+  ins_encode %{
+    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4F_zero(vecX dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateF zero));
+  format %{ "xorps   $dst,$dst\t! replicate4F zero" %}
+  ins_encode %{
+    __ xorps($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl8F_zero(vecY dst, immF0 zero) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (ReplicateF zero));
+  format %{ "vxorps  $dst,$dst,$dst\t! replicate8F zero" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vxorps($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+// Replicate double (8 bytes) scalar to be vector
+instruct Repl2D(vecX dst, regD src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateD src));
+  format %{ "pshufd  $dst,$src,0x44\t! replicate2D" %}
+  ins_encode %{
+    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x44);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct Repl4D(vecY dst, regD src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateD src));
+  format %{ "pshufd  $dst,$src,0x44\n\t"
+            "vinsertf128h $dst,$dst,$dst\t! replicate4D" %}
+  ins_encode %{
+    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x44);
+    __ vinsertf128h($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Replicate double (8 byte) scalar zero to be vector
+instruct Repl2D_zero(vecX dst, immD0 zero) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (ReplicateD zero));
+  format %{ "xorpd   $dst,$dst\t! replicate2D zero" %}
+  ins_encode %{
+    __ xorpd($dst$$XMMRegister, $dst$$XMMRegister);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+instruct Repl4D_zero(vecY dst, immD0 zero) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (ReplicateD zero));
+  format %{ "vxorpd  $dst,$dst,$dst,vect256\t! replicate4D zero" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vxorpd($dst$$XMMRegister, $dst$$XMMRegister, $dst$$XMMRegister, vector256);
+  %}
+  ins_pipe( fpu_reg_reg );
+%}
+
+// ====================VECTOR ARITHMETIC=======================================
+
+// --------------------------------- ADD --------------------------------------
+
+// Bytes vector add
+instruct vadd4B(vecS dst, vecS src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (AddVB dst src));
+  format %{ "paddb   $dst,$src\t! add packed4B" %}
+  ins_encode %{
+    __ paddb($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4B_reg(vecS dst, vecS src1, vecS src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVB src1 src2));
+  format %{ "vpaddb  $dst,$src1,$src2\t! add packed4B" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddb($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8B(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (AddVB dst src));
+  format %{ "paddb   $dst,$src\t! add packed8B" %}
+  ins_encode %{
+    __ paddb($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8B_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (AddVB src1 src2));
+  format %{ "vpaddb  $dst,$src1,$src2\t! add packed8B" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddb($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd16B(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 16);
+  match(Set dst (AddVB dst src));
+  format %{ "paddb   $dst,$src\t! add packed16B" %}
+  ins_encode %{
+    __ paddb($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 16);
+  match(Set dst (AddVB src1 src2));
+  format %{ "vpaddb  $dst,$src1,$src2\t! add packed16B" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddb($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd16B_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 16);
+  match(Set dst (AddVB src (LoadVector mem)));
+  format %{ "vpaddb  $dst,$src,$mem\t! add packed16B" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddb($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd32B_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 32);
+  match(Set dst (AddVB src1 src2));
+  format %{ "vpaddb  $dst,$src1,$src2\t! add packed32B" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpaddb($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd32B_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 32);
+  match(Set dst (AddVB src (LoadVector mem)));
+  format %{ "vpaddb  $dst,$src,$mem\t! add packed32B" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpaddb($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Shorts/Chars vector add
+instruct vadd2S(vecS dst, vecS src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AddVS dst src));
+  format %{ "paddw   $dst,$src\t! add packed2S" %}
+  ins_encode %{
+    __ paddw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd2S_reg(vecS dst, vecS src1, vecS src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (AddVS src1 src2));
+  format %{ "vpaddw  $dst,$src1,$src2\t! add packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4S(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (AddVS dst src));
+  format %{ "paddw   $dst,$src\t! add packed4S" %}
+  ins_encode %{
+    __ paddw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4S_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVS src1 src2));
+  format %{ "vpaddw  $dst,$src1,$src2\t! add packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8S(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (AddVS dst src));
+  format %{ "paddw   $dst,$src\t! add packed8S" %}
+  ins_encode %{
+    __ paddw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (AddVS src1 src2));
+  format %{ "vpaddw  $dst,$src1,$src2\t! add packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8S_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (AddVS src (LoadVector mem)));
+  format %{ "vpaddw  $dst,$src,$mem\t! add packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddw($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd16S_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (AddVS src1 src2));
+  format %{ "vpaddw  $dst,$src1,$src2\t! add packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpaddw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd16S_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (AddVS src (LoadVector mem)));
+  format %{ "vpaddw  $dst,$src,$mem\t! add packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpaddw($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Integers vector add
+instruct vadd2I(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AddVI dst src));
+  format %{ "paddd   $dst,$src\t! add packed2I" %}
+  ins_encode %{
+    __ paddd($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd2I_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (AddVI src1 src2));
+  format %{ "vpaddd  $dst,$src1,$src2\t! add packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4I(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (AddVI dst src));
+  format %{ "paddd   $dst,$src\t! add packed4I" %}
+  ins_encode %{
+    __ paddd($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVI src1 src2));
+  format %{ "vpaddd  $dst,$src1,$src2\t! add packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4I_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVI src (LoadVector mem)));
+  format %{ "vpaddd  $dst,$src,$mem\t! add packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8I_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (AddVI src1 src2));
+  format %{ "vpaddd  $dst,$src1,$src2\t! add packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpaddd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8I_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (AddVI src (LoadVector mem)));
+  format %{ "vpaddd  $dst,$src,$mem\t! add packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpaddd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Longs vector add
+instruct vadd2L(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AddVL dst src));
+  format %{ "paddq   $dst,$src\t! add packed2L" %}
+  ins_encode %{
+    __ paddq($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (AddVL src1 src2));
+  format %{ "vpaddq  $dst,$src1,$src2\t! add packed2L" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddq($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd2L_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (AddVL src (LoadVector mem)));
+  format %{ "vpaddq  $dst,$src,$mem\t! add packed2L" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpaddq($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4L_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVL src1 src2));
+  format %{ "vpaddq  $dst,$src1,$src2\t! add packed4L" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpaddq($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4L_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVL src (LoadVector mem)));
+  format %{ "vpaddq  $dst,$src,$mem\t! add packed4L" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpaddq($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Floats vector add
+instruct vadd2F(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AddVF dst src));
+  format %{ "addps   $dst,$src\t! add packed2F" %}
+  ins_encode %{
+    __ addps($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd2F_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (AddVF src1 src2));
+  format %{ "vaddps  $dst,$src1,$src2\t! add packed2F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vaddps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4F(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (AddVF dst src));
+  format %{ "addps   $dst,$src\t! add packed4F" %}
+  ins_encode %{
+    __ addps($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVF src1 src2));
+  format %{ "vaddps  $dst,$src1,$src2\t! add packed4F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vaddps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4F_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVF src (LoadVector mem)));
+  format %{ "vaddps  $dst,$src,$mem\t! add packed4F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vaddps($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8F_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (AddVF src1 src2));
+  format %{ "vaddps  $dst,$src1,$src2\t! add packed8F" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vaddps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd8F_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (AddVF src (LoadVector mem)));
+  format %{ "vaddps  $dst,$src,$mem\t! add packed8F" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vaddps($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Doubles vector add
+instruct vadd2D(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (AddVD dst src));
+  format %{ "addpd   $dst,$src\t! add packed2D" %}
+  ins_encode %{
+    __ addpd($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (AddVD src1 src2));
+  format %{ "vaddpd  $dst,$src1,$src2\t! add packed2D" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vaddpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd2D_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (AddVD src (LoadVector mem)));
+  format %{ "vaddpd  $dst,$src,$mem\t! add packed2D" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vaddpd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4D_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVD src1 src2));
+  format %{ "vaddpd  $dst,$src1,$src2\t! add packed4D" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vaddpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vadd4D_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (AddVD src (LoadVector mem)));
+  format %{ "vaddpd  $dst,$src,$mem\t! add packed4D" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vaddpd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// --------------------------------- SUB --------------------------------------
+
+// Bytes vector sub
+instruct vsub4B(vecS dst, vecS src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (SubVB dst src));
+  format %{ "psubb   $dst,$src\t! sub packed4B" %}
+  ins_encode %{
+    __ psubb($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4B_reg(vecS dst, vecS src1, vecS src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVB src1 src2));
+  format %{ "vpsubb  $dst,$src1,$src2\t! sub packed4B" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubb($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8B(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (SubVB dst src));
+  format %{ "psubb   $dst,$src\t! sub packed8B" %}
+  ins_encode %{
+    __ psubb($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8B_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SubVB src1 src2));
+  format %{ "vpsubb  $dst,$src1,$src2\t! sub packed8B" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubb($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub16B(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 16);
+  match(Set dst (SubVB dst src));
+  format %{ "psubb   $dst,$src\t! sub packed16B" %}
+  ins_encode %{
+    __ psubb($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 16);
+  match(Set dst (SubVB src1 src2));
+  format %{ "vpsubb  $dst,$src1,$src2\t! sub packed16B" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubb($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub16B_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 16);
+  match(Set dst (SubVB src (LoadVector mem)));
+  format %{ "vpsubb  $dst,$src,$mem\t! sub packed16B" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubb($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub32B_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 32);
+  match(Set dst (SubVB src1 src2));
+  format %{ "vpsubb  $dst,$src1,$src2\t! sub packed32B" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsubb($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub32B_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 32);
+  match(Set dst (SubVB src (LoadVector mem)));
+  format %{ "vpsubb  $dst,$src,$mem\t! sub packed32B" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsubb($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Shorts/Chars vector sub
+instruct vsub2S(vecS dst, vecS src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (SubVS dst src));
+  format %{ "psubw   $dst,$src\t! sub packed2S" %}
+  ins_encode %{
+    __ psubw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub2S_reg(vecS dst, vecS src1, vecS src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SubVS src1 src2));
+  format %{ "vpsubw  $dst,$src1,$src2\t! sub packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4S(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (SubVS dst src));
+  format %{ "psubw   $dst,$src\t! sub packed4S" %}
+  ins_encode %{
+    __ psubw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4S_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVS src1 src2));
+  format %{ "vpsubw  $dst,$src1,$src2\t! sub packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8S(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (SubVS dst src));
+  format %{ "psubw   $dst,$src\t! sub packed8S" %}
+  ins_encode %{
+    __ psubw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SubVS src1 src2));
+  format %{ "vpsubw  $dst,$src1,$src2\t! sub packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8S_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SubVS src (LoadVector mem)));
+  format %{ "vpsubw  $dst,$src,$mem\t! sub packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubw($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub16S_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (SubVS src1 src2));
+  format %{ "vpsubw  $dst,$src1,$src2\t! sub packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsubw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub16S_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (SubVS src (LoadVector mem)));
+  format %{ "vpsubw  $dst,$src,$mem\t! sub packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsubw($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Integers vector sub
+instruct vsub2I(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (SubVI dst src));
+  format %{ "psubd   $dst,$src\t! sub packed2I" %}
+  ins_encode %{
+    __ psubd($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub2I_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SubVI src1 src2));
+  format %{ "vpsubd  $dst,$src1,$src2\t! sub packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4I(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (SubVI dst src));
+  format %{ "psubd   $dst,$src\t! sub packed4I" %}
+  ins_encode %{
+    __ psubd($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVI src1 src2));
+  format %{ "vpsubd  $dst,$src1,$src2\t! sub packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4I_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVI src (LoadVector mem)));
+  format %{ "vpsubd  $dst,$src,$mem\t! sub packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8I_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (SubVI src1 src2));
+  format %{ "vpsubd  $dst,$src1,$src2\t! sub packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsubd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8I_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (SubVI src (LoadVector mem)));
+  format %{ "vpsubd  $dst,$src,$mem\t! sub packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsubd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Longs vector sub
+instruct vsub2L(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (SubVL dst src));
+  format %{ "psubq   $dst,$src\t! sub packed2L" %}
+  ins_encode %{
+    __ psubq($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SubVL src1 src2));
+  format %{ "vpsubq  $dst,$src1,$src2\t! sub packed2L" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubq($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub2L_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SubVL src (LoadVector mem)));
+  format %{ "vpsubq  $dst,$src,$mem\t! sub packed2L" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsubq($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4L_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVL src1 src2));
+  format %{ "vpsubq  $dst,$src1,$src2\t! sub packed4L" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsubq($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4L_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVL src (LoadVector mem)));
+  format %{ "vpsubq  $dst,$src,$mem\t! sub packed4L" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsubq($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Floats vector sub
+instruct vsub2F(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (SubVF dst src));
+  format %{ "subps   $dst,$src\t! sub packed2F" %}
+  ins_encode %{
+    __ subps($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub2F_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SubVF src1 src2));
+  format %{ "vsubps  $dst,$src1,$src2\t! sub packed2F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vsubps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4F(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (SubVF dst src));
+  format %{ "subps   $dst,$src\t! sub packed4F" %}
+  ins_encode %{
+    __ subps($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVF src1 src2));
+  format %{ "vsubps  $dst,$src1,$src2\t! sub packed4F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vsubps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4F_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVF src (LoadVector mem)));
+  format %{ "vsubps  $dst,$src,$mem\t! sub packed4F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vsubps($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8F_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SubVF src1 src2));
+  format %{ "vsubps  $dst,$src1,$src2\t! sub packed8F" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vsubps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub8F_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (SubVF src (LoadVector mem)));
+  format %{ "vsubps  $dst,$src,$mem\t! sub packed8F" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vsubps($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Doubles vector sub
+instruct vsub2D(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (SubVD dst src));
+  format %{ "subpd   $dst,$src\t! sub packed2D" %}
+  ins_encode %{
+    __ subpd($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SubVD src1 src2));
+  format %{ "vsubpd  $dst,$src1,$src2\t! sub packed2D" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vsubpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub2D_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (SubVD src (LoadVector mem)));
+  format %{ "vsubpd  $dst,$src,$mem\t! sub packed2D" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vsubpd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4D_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVD src1 src2));
+  format %{ "vsubpd  $dst,$src1,$src2\t! sub packed4D" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vsubpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsub4D_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (SubVD src (LoadVector mem)));
+  format %{ "vsubpd  $dst,$src,$mem\t! sub packed4D" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vsubpd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// --------------------------------- MUL --------------------------------------
+
+// Shorts/Chars vector mul
+instruct vmul2S(vecS dst, vecS src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (MulVS dst src));
+  format %{ "pmullw $dst,$src\t! mul packed2S" %}
+  ins_encode %{
+    __ pmullw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul2S_reg(vecS dst, vecS src1, vecS src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (MulVS src1 src2));
+  format %{ "vpmullw $dst,$src1,$src2\t! mul packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpmullw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4S(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (MulVS dst src));
+  format %{ "pmullw  $dst,$src\t! mul packed4S" %}
+  ins_encode %{
+    __ pmullw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4S_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (MulVS src1 src2));
+  format %{ "vpmullw $dst,$src1,$src2\t! mul packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpmullw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul8S(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (MulVS dst src));
+  format %{ "pmullw  $dst,$src\t! mul packed8S" %}
+  ins_encode %{
+    __ pmullw($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (MulVS src1 src2));
+  format %{ "vpmullw $dst,$src1,$src2\t! mul packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpmullw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul8S_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (MulVS src (LoadVector mem)));
+  format %{ "vpmullw $dst,$src,$mem\t! mul packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpmullw($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul16S_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (MulVS src1 src2));
+  format %{ "vpmullw $dst,$src1,$src2\t! mul packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpmullw($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul16S_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (MulVS src (LoadVector mem)));
+  format %{ "vpmullw $dst,$src,$mem\t! mul packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpmullw($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Integers vector mul (sse4_1)
+instruct vmul2I(vecD dst, vecD src) %{
+  predicate(UseSSE > 3 && n->as_Vector()->length() == 2);
+  match(Set dst (MulVI dst src));
+  format %{ "pmulld  $dst,$src\t! mul packed2I" %}
+  ins_encode %{
+    __ pmulld($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul2I_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (MulVI src1 src2));
+  format %{ "vpmulld $dst,$src1,$src2\t! mul packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpmulld($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4I(vecX dst, vecX src) %{
+  predicate(UseSSE > 3 && n->as_Vector()->length() == 4);
+  match(Set dst (MulVI dst src));
+  format %{ "pmulld  $dst,$src\t! mul packed4I" %}
+  ins_encode %{
+    __ pmulld($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (MulVI src1 src2));
+  format %{ "vpmulld $dst,$src1,$src2\t! mul packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpmulld($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4I_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (MulVI src (LoadVector mem)));
+  format %{ "vpmulld $dst,$src,$mem\t! mul packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpmulld($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul8I_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (MulVI src1 src2));
+  format %{ "vpmulld $dst,$src1,$src2\t! mul packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpmulld($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul8I_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (MulVI src (LoadVector mem)));
+  format %{ "vpmulld $dst,$src,$mem\t! mul packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpmulld($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Floats vector mul
+instruct vmul2F(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (MulVF dst src));
+  format %{ "mulps   $dst,$src\t! mul packed2F" %}
+  ins_encode %{
+    __ mulps($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul2F_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (MulVF src1 src2));
+  format %{ "vmulps  $dst,$src1,$src2\t! mul packed2F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vmulps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4F(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (MulVF dst src));
+  format %{ "mulps   $dst,$src\t! mul packed4F" %}
+  ins_encode %{
+    __ mulps($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (MulVF src1 src2));
+  format %{ "vmulps  $dst,$src1,$src2\t! mul packed4F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vmulps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4F_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (MulVF src (LoadVector mem)));
+  format %{ "vmulps  $dst,$src,$mem\t! mul packed4F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vmulps($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul8F_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (MulVF src1 src2));
+  format %{ "vmulps  $dst,$src1,$src2\t! mul packed8F" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vmulps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul8F_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (MulVF src (LoadVector mem)));
+  format %{ "vmulps  $dst,$src,$mem\t! mul packed8F" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vmulps($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Doubles vector mul
+instruct vmul2D(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (MulVD dst src));
+  format %{ "mulpd   $dst,$src\t! mul packed2D" %}
+  ins_encode %{
+    __ mulpd($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (MulVD src1 src2));
+  format %{ "vmulpd  $dst,$src1,$src2\t! mul packed2D" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vmulpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul2D_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (MulVD src (LoadVector mem)));
+  format %{ "vmulpd  $dst,$src,$mem\t! mul packed2D" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vmulpd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4D_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (MulVD src1 src2));
+  format %{ "vmulpd  $dst,$src1,$src2\t! mul packed4D" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vmulpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vmul4D_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (MulVD src (LoadVector mem)));
+  format %{ "vmulpd  $dst,$src,$mem\t! mul packed4D" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vmulpd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// --------------------------------- DIV --------------------------------------
+
+// Floats vector div
+instruct vdiv2F(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (DivVF dst src));
+  format %{ "divps   $dst,$src\t! div packed2F" %}
+  ins_encode %{
+    __ divps($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv2F_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (DivVF src1 src2));
+  format %{ "vdivps  $dst,$src1,$src2\t! div packed2F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vdivps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv4F(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (DivVF dst src));
+  format %{ "divps   $dst,$src\t! div packed4F" %}
+  ins_encode %{
+    __ divps($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (DivVF src1 src2));
+  format %{ "vdivps  $dst,$src1,$src2\t! div packed4F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vdivps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv4F_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (DivVF src (LoadVector mem)));
+  format %{ "vdivps  $dst,$src,$mem\t! div packed4F" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vdivps($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv8F_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (DivVF src1 src2));
+  format %{ "vdivps  $dst,$src1,$src2\t! div packed8F" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vdivps($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv8F_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (DivVF src (LoadVector mem)));
+  format %{ "vdivps  $dst,$src,$mem\t! div packed8F" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vdivps($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Doubles vector div
+instruct vdiv2D(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (DivVD dst src));
+  format %{ "divpd   $dst,$src\t! div packed2D" %}
+  ins_encode %{
+    __ divpd($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (DivVD src1 src2));
+  format %{ "vdivpd  $dst,$src1,$src2\t! div packed2D" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vdivpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv2D_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (DivVD src (LoadVector mem)));
+  format %{ "vdivpd  $dst,$src,$mem\t! div packed2D" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vdivpd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv4D_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (DivVD src1 src2));
+  format %{ "vdivpd  $dst,$src1,$src2\t! div packed4D" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vdivpd($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vdiv4D_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (DivVD src (LoadVector mem)));
+  format %{ "vdivpd  $dst,$src,$mem\t! div packed4D" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vdivpd($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// ------------------------------ Shift ---------------------------------------
+
+// Left and right shift count vectors are the same on x86
+// (only lowest bits of xmm reg are used for count).
+instruct vshiftcnt(vecS dst, rRegI cnt) %{
+  match(Set dst (LShiftCntV cnt));
+  match(Set dst (RShiftCntV cnt));
+  format %{ "movd    $dst,$cnt\t! load shift count" %}
+  ins_encode %{
+    __ movdl($dst$$XMMRegister, $cnt$$Register);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// ------------------------------ LeftShift -----------------------------------
+
+// Shorts/Chars vector left shift
+instruct vsll2S(vecS dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVS dst shift));
+  format %{ "psllw   $dst,$shift\t! left shift packed2S" %}
+  ins_encode %{
+    __ psllw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2S_imm(vecS dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVS dst shift));
+  format %{ "psllw   $dst,$shift\t! left shift packed2S" %}
+  ins_encode %{
+    __ psllw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2S_reg(vecS dst, vecS src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVS src shift));
+  format %{ "vpsllw  $dst,$src,$shift\t! left shift packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2S_reg_imm(vecS dst, vecS src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVS src shift));
+  format %{ "vpsllw  $dst,$src,$shift\t! left shift packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4S(vecD dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVS dst shift));
+  format %{ "psllw   $dst,$shift\t! left shift packed4S" %}
+  ins_encode %{
+    __ psllw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4S_imm(vecD dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVS dst shift));
+  format %{ "psllw   $dst,$shift\t! left shift packed4S" %}
+  ins_encode %{
+    __ psllw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4S_reg(vecD dst, vecD src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVS src shift));
+  format %{ "vpsllw  $dst,$src,$shift\t! left shift packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4S_reg_imm(vecD dst, vecD src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVS src shift));
+  format %{ "vpsllw  $dst,$src,$shift\t! left shift packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll8S(vecX dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (LShiftVS dst shift));
+  format %{ "psllw   $dst,$shift\t! left shift packed8S" %}
+  ins_encode %{
+    __ psllw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll8S_imm(vecX dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (LShiftVS dst shift));
+  format %{ "psllw   $dst,$shift\t! left shift packed8S" %}
+  ins_encode %{
+    __ psllw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll8S_reg(vecX dst, vecX src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (LShiftVS src shift));
+  format %{ "vpsllw  $dst,$src,$shift\t! left shift packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll8S_reg_imm(vecX dst, vecX src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (LShiftVS src shift));
+  format %{ "vpsllw  $dst,$src,$shift\t! left shift packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll16S_reg(vecY dst, vecY src, vecS shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (LShiftVS src shift));
+  format %{ "vpsllw  $dst,$src,$shift\t! left shift packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll16S_reg_imm(vecY dst, vecY src, immI8 shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (LShiftVS src shift));
+  format %{ "vpsllw  $dst,$src,$shift\t! left shift packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsllw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Integers vector left shift
+instruct vsll2I(vecD dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVI dst shift));
+  format %{ "pslld   $dst,$shift\t! left shift packed2I" %}
+  ins_encode %{
+    __ pslld($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2I_imm(vecD dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVI dst shift));
+  format %{ "pslld   $dst,$shift\t! left shift packed2I" %}
+  ins_encode %{
+    __ pslld($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2I_reg(vecD dst, vecD src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVI src shift));
+  format %{ "vpslld  $dst,$src,$shift\t! left shift packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpslld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVI src shift));
+  format %{ "vpslld  $dst,$src,$shift\t! left shift packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpslld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4I(vecX dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVI dst shift));
+  format %{ "pslld   $dst,$shift\t! left shift packed4I" %}
+  ins_encode %{
+    __ pslld($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4I_imm(vecX dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVI dst shift));
+  format %{ "pslld   $dst,$shift\t! left shift packed4I" %}
+  ins_encode %{
+    __ pslld($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4I_reg(vecX dst, vecX src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVI src shift));
+  format %{ "vpslld  $dst,$src,$shift\t! left shift packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpslld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVI src shift));
+  format %{ "vpslld  $dst,$src,$shift\t! left shift packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpslld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll8I_reg(vecY dst, vecY src, vecS shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (LShiftVI src shift));
+  format %{ "vpslld  $dst,$src,$shift\t! left shift packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpslld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll8I_reg_imm(vecY dst, vecY src, immI8 shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (LShiftVI src shift));
+  format %{ "vpslld  $dst,$src,$shift\t! left shift packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpslld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Longs vector left shift
+instruct vsll2L(vecX dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVL dst shift));
+  format %{ "psllq   $dst,$shift\t! left shift packed2L" %}
+  ins_encode %{
+    __ psllq($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2L_imm(vecX dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVL dst shift));
+  format %{ "psllq   $dst,$shift\t! left shift packed2L" %}
+  ins_encode %{
+    __ psllq($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2L_reg(vecX dst, vecX src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVL src shift));
+  format %{ "vpsllq  $dst,$src,$shift\t! left shift packed2L" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll2L_reg_imm(vecX dst, vecX src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (LShiftVL src shift));
+  format %{ "vpsllq  $dst,$src,$shift\t! left shift packed2L" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4L_reg(vecY dst, vecY src, vecS shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVL src shift));
+  format %{ "vpsllq  $dst,$src,$shift\t! left shift packed4L" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsll4L_reg_imm(vecY dst, vecY src, immI8 shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+  match(Set dst (LShiftVL src shift));
+  format %{ "vpsllq  $dst,$src,$shift\t! left shift packed4L" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsllq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// ----------------------- LogicalRightShift -----------------------------------
+
+// Shorts vector logical right shift produces incorrect Java result
+// for negative data because java code convert short value into int with
+// sign extension before a shift. But char vectors are fine since chars are
+// unsigned values.
+
+instruct vsrl2S(vecS dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVS dst shift));
+  format %{ "psrlw   $dst,$shift\t! logical right shift packed2S" %}
+  ins_encode %{
+    __ psrlw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2S_imm(vecS dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVS dst shift));
+  format %{ "psrlw   $dst,$shift\t! logical right shift packed2S" %}
+  ins_encode %{
+    __ psrlw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2S_reg(vecS dst, vecS src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVS src shift));
+  format %{ "vpsrlw  $dst,$src,$shift\t! logical right shift packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2S_reg_imm(vecS dst, vecS src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVS src shift));
+  format %{ "vpsrlw  $dst,$src,$shift\t! logical right shift packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4S(vecD dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVS dst shift));
+  format %{ "psrlw   $dst,$shift\t! logical right shift packed4S" %}
+  ins_encode %{
+    __ psrlw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4S_imm(vecD dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVS dst shift));
+  format %{ "psrlw   $dst,$shift\t! logical right shift packed4S" %}
+  ins_encode %{
+    __ psrlw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4S_reg(vecD dst, vecD src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVS src shift));
+  format %{ "vpsrlw  $dst,$src,$shift\t! logical right shift packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4S_reg_imm(vecD dst, vecD src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVS src shift));
+  format %{ "vpsrlw  $dst,$src,$shift\t! logical right shift packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl8S(vecX dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (URShiftVS dst shift));
+  format %{ "psrlw   $dst,$shift\t! logical right shift packed8S" %}
+  ins_encode %{
+    __ psrlw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl8S_imm(vecX dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (URShiftVS dst shift));
+  format %{ "psrlw   $dst,$shift\t! logical right shift packed8S" %}
+  ins_encode %{
+    __ psrlw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl8S_reg(vecX dst, vecX src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (URShiftVS src shift));
+  format %{ "vpsrlw  $dst,$src,$shift\t! logical right shift packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl8S_reg_imm(vecX dst, vecX src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (URShiftVS src shift));
+  format %{ "vpsrlw  $dst,$src,$shift\t! logical right shift packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl16S_reg(vecY dst, vecY src, vecS shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (URShiftVS src shift));
+  format %{ "vpsrlw  $dst,$src,$shift\t! logical right shift packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl16S_reg_imm(vecY dst, vecY src, immI8 shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (URShiftVS src shift));
+  format %{ "vpsrlw  $dst,$src,$shift\t! logical right shift packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsrlw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Integers vector logical right shift
+instruct vsrl2I(vecD dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVI dst shift));
+  format %{ "psrld   $dst,$shift\t! logical right shift packed2I" %}
+  ins_encode %{
+    __ psrld($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2I_imm(vecD dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVI dst shift));
+  format %{ "psrld   $dst,$shift\t! logical right shift packed2I" %}
+  ins_encode %{
+    __ psrld($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2I_reg(vecD dst, vecD src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVI src shift));
+  format %{ "vpsrld  $dst,$src,$shift\t! logical right shift packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVI src shift));
+  format %{ "vpsrld  $dst,$src,$shift\t! logical right shift packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4I(vecX dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVI dst shift));
+  format %{ "psrld   $dst,$shift\t! logical right shift packed4I" %}
+  ins_encode %{
+    __ psrld($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4I_imm(vecX dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVI dst shift));
+  format %{ "psrld   $dst,$shift\t! logical right shift packed4I" %}
+  ins_encode %{
+    __ psrld($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4I_reg(vecX dst, vecX src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVI src shift));
+  format %{ "vpsrld  $dst,$src,$shift\t! logical right shift packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVI src shift));
+  format %{ "vpsrld  $dst,$src,$shift\t! logical right shift packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl8I_reg(vecY dst, vecY src, vecS shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (URShiftVI src shift));
+  format %{ "vpsrld  $dst,$src,$shift\t! logical right shift packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl8I_reg_imm(vecY dst, vecY src, immI8 shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (URShiftVI src shift));
+  format %{ "vpsrld  $dst,$src,$shift\t! logical right shift packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsrld($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Longs vector logical right shift
+instruct vsrl2L(vecX dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVL dst shift));
+  format %{ "psrlq   $dst,$shift\t! logical right shift packed2L" %}
+  ins_encode %{
+    __ psrlq($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2L_imm(vecX dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVL dst shift));
+  format %{ "psrlq   $dst,$shift\t! logical right shift packed2L" %}
+  ins_encode %{
+    __ psrlq($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2L_reg(vecX dst, vecX src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVL src shift));
+  format %{ "vpsrlq  $dst,$src,$shift\t! logical right shift packed2L" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl2L_reg_imm(vecX dst, vecX src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (URShiftVL src shift));
+  format %{ "vpsrlq  $dst,$src,$shift\t! logical right shift packed2L" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4L_reg(vecY dst, vecY src, vecS shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVL src shift));
+  format %{ "vpsrlq  $dst,$src,$shift\t! logical right shift packed4L" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsrl4L_reg_imm(vecY dst, vecY src, immI8 shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 4);
+  match(Set dst (URShiftVL src shift));
+  format %{ "vpsrlq  $dst,$src,$shift\t! logical right shift packed4L" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsrlq($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// ------------------- ArithmeticRightShift -----------------------------------
+
+// Shorts/Chars vector arithmetic right shift
+instruct vsra2S(vecS dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVS dst shift));
+  format %{ "psraw   $dst,$shift\t! arithmetic right shift packed2S" %}
+  ins_encode %{
+    __ psraw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra2S_imm(vecS dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVS dst shift));
+  format %{ "psraw   $dst,$shift\t! arithmetic right shift packed2S" %}
+  ins_encode %{
+    __ psraw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra2S_reg(vecS dst, vecS src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVS src shift));
+  format %{ "vpsraw  $dst,$src,$shift\t! arithmetic right shift packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra2S_reg_imm(vecS dst, vecS src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVS src shift));
+  format %{ "vpsraw  $dst,$src,$shift\t! arithmetic right shift packed2S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra4S(vecD dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVS dst shift));
+  format %{ "psraw   $dst,$shift\t! arithmetic right shift packed4S" %}
+  ins_encode %{
+    __ psraw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra4S_imm(vecD dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVS dst shift));
+  format %{ "psraw   $dst,$shift\t! arithmetic right shift packed4S" %}
+  ins_encode %{
+    __ psraw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra4S_reg(vecD dst, vecD src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVS src shift));
+  format %{ "vpsraw  $dst,$src,$shift\t! arithmetic right shift packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra4S_reg_imm(vecD dst, vecD src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVS src shift));
+  format %{ "vpsraw  $dst,$src,$shift\t! arithmetic right shift packed4S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra8S(vecX dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (RShiftVS dst shift));
+  format %{ "psraw   $dst,$shift\t! arithmetic right shift packed8S" %}
+  ins_encode %{
+    __ psraw($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra8S_imm(vecX dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 8);
+  match(Set dst (RShiftVS dst shift));
+  format %{ "psraw   $dst,$shift\t! arithmetic right shift packed8S" %}
+  ins_encode %{
+    __ psraw($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra8S_reg(vecX dst, vecX src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (RShiftVS src shift));
+  format %{ "vpsraw  $dst,$src,$shift\t! arithmetic right shift packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra8S_reg_imm(vecX dst, vecX src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 8);
+  match(Set dst (RShiftVS src shift));
+  format %{ "vpsraw  $dst,$src,$shift\t! arithmetic right shift packed8S" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra16S_reg(vecY dst, vecY src, vecS shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (RShiftVS src shift));
+  format %{ "vpsraw  $dst,$src,$shift\t! arithmetic right shift packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra16S_reg_imm(vecY dst, vecY src, immI8 shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 16);
+  match(Set dst (RShiftVS src shift));
+  format %{ "vpsraw  $dst,$src,$shift\t! arithmetic right shift packed16S" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsraw($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// Integers vector arithmetic right shift
+instruct vsra2I(vecD dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVI dst shift));
+  format %{ "psrad   $dst,$shift\t! arithmetic right shift packed2I" %}
+  ins_encode %{
+    __ psrad($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra2I_imm(vecD dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVI dst shift));
+  format %{ "psrad   $dst,$shift\t! arithmetic right shift packed2I" %}
+  ins_encode %{
+    __ psrad($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra2I_reg(vecD dst, vecD src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVI src shift));
+  format %{ "vpsrad  $dst,$src,$shift\t! arithmetic right shift packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra2I_reg_imm(vecD dst, vecD src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 2);
+  match(Set dst (RShiftVI src shift));
+  format %{ "vpsrad  $dst,$src,$shift\t! arithmetic right shift packed2I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra4I(vecX dst, vecS shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVI dst shift));
+  format %{ "psrad   $dst,$shift\t! arithmetic right shift packed4I" %}
+  ins_encode %{
+    __ psrad($dst$$XMMRegister, $shift$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra4I_imm(vecX dst, immI8 shift) %{
+  predicate(n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVI dst shift));
+  format %{ "psrad   $dst,$shift\t! arithmetic right shift packed4I" %}
+  ins_encode %{
+    __ psrad($dst$$XMMRegister, (int)$shift$$constant);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra4I_reg(vecX dst, vecX src, vecS shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVI src shift));
+  format %{ "vpsrad  $dst,$src,$shift\t! arithmetic right shift packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra4I_reg_imm(vecX dst, vecX src, immI8 shift) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length() == 4);
+  match(Set dst (RShiftVI src shift));
+  format %{ "vpsrad  $dst,$src,$shift\t! arithmetic right shift packed4I" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra8I_reg(vecY dst, vecY src, vecS shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (RShiftVI src shift));
+  format %{ "vpsrad  $dst,$src,$shift\t! arithmetic right shift packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, $shift$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vsra8I_reg_imm(vecY dst, vecY src, immI8 shift) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length() == 8);
+  match(Set dst (RShiftVI src shift));
+  format %{ "vpsrad  $dst,$src,$shift\t! arithmetic right shift packed8I" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpsrad($dst$$XMMRegister, $src$$XMMRegister, (int)$shift$$constant, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// There are no longs vector arithmetic right shift instructions.
+
+
+// --------------------------------- AND --------------------------------------
+
+instruct vand4B(vecS dst, vecS src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 4);
+  match(Set dst (AndV dst src));
+  format %{ "pand    $dst,$src\t! and vectors (4 bytes)" %}
+  ins_encode %{
+    __ pand($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vand4B_reg(vecS dst, vecS src1, vecS src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 4);
+  match(Set dst (AndV src1 src2));
+  format %{ "vpand   $dst,$src1,$src2\t! and vectors (4 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpand($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vand8B(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (AndV dst src));
+  format %{ "pand    $dst,$src\t! and vectors (8 bytes)" %}
+  ins_encode %{
+    __ pand($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vand8B_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (AndV src1 src2));
+  format %{ "vpand   $dst,$src1,$src2\t! and vectors (8 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpand($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vand16B(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (AndV dst src));
+  format %{ "pand    $dst,$src\t! and vectors (16 bytes)" %}
+  ins_encode %{
+    __ pand($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vand16B_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (AndV src1 src2));
+  format %{ "vpand   $dst,$src1,$src2\t! and vectors (16 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpand($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vand16B_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (AndV src (LoadVector mem)));
+  format %{ "vpand   $dst,$src,$mem\t! and vectors (16 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpand($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vand32B_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length_in_bytes() == 32);
+  match(Set dst (AndV src1 src2));
+  format %{ "vpand   $dst,$src1,$src2\t! and vectors (32 bytes)" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpand($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vand32B_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length_in_bytes() == 32);
+  match(Set dst (AndV src (LoadVector mem)));
+  format %{ "vpand   $dst,$src,$mem\t! and vectors (32 bytes)" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpand($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// --------------------------------- OR ---------------------------------------
+
+instruct vor4B(vecS dst, vecS src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 4);
+  match(Set dst (OrV dst src));
+  format %{ "por     $dst,$src\t! or vectors (4 bytes)" %}
+  ins_encode %{
+    __ por($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vor4B_reg(vecS dst, vecS src1, vecS src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 4);
+  match(Set dst (OrV src1 src2));
+  format %{ "vpor    $dst,$src1,$src2\t! or vectors (4 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpor($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vor8B(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (OrV dst src));
+  format %{ "por     $dst,$src\t! or vectors (8 bytes)" %}
+  ins_encode %{
+    __ por($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vor8B_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (OrV src1 src2));
+  format %{ "vpor    $dst,$src1,$src2\t! or vectors (8 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpor($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vor16B(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (OrV dst src));
+  format %{ "por     $dst,$src\t! or vectors (16 bytes)" %}
+  ins_encode %{
+    __ por($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vor16B_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (OrV src1 src2));
+  format %{ "vpor    $dst,$src1,$src2\t! or vectors (16 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpor($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vor16B_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (OrV src (LoadVector mem)));
+  format %{ "vpor    $dst,$src,$mem\t! or vectors (16 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpor($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vor32B_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length_in_bytes() == 32);
+  match(Set dst (OrV src1 src2));
+  format %{ "vpor    $dst,$src1,$src2\t! or vectors (32 bytes)" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpor($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vor32B_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length_in_bytes() == 32);
+  match(Set dst (OrV src (LoadVector mem)));
+  format %{ "vpor    $dst,$src,$mem\t! or vectors (32 bytes)" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpor($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+// --------------------------------- XOR --------------------------------------
+
+instruct vxor4B(vecS dst, vecS src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 4);
+  match(Set dst (XorV dst src));
+  format %{ "pxor    $dst,$src\t! xor vectors (4 bytes)" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vxor4B_reg(vecS dst, vecS src1, vecS src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 4);
+  match(Set dst (XorV src1 src2));
+  format %{ "vpxor   $dst,$src1,$src2\t! xor vectors (4 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpxor($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vxor8B(vecD dst, vecD src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (XorV dst src));
+  format %{ "pxor    $dst,$src\t! xor vectors (8 bytes)" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vxor8B_reg(vecD dst, vecD src1, vecD src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 8);
+  match(Set dst (XorV src1 src2));
+  format %{ "vpxor   $dst,$src1,$src2\t! xor vectors (8 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpxor($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vxor16B(vecX dst, vecX src) %{
+  predicate(n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (XorV dst src));
+  format %{ "pxor    $dst,$src\t! xor vectors (16 bytes)" %}
+  ins_encode %{
+    __ pxor($dst$$XMMRegister, $src$$XMMRegister);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vxor16B_reg(vecX dst, vecX src1, vecX src2) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (XorV src1 src2));
+  format %{ "vpxor   $dst,$src1,$src2\t! xor vectors (16 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpxor($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vxor16B_mem(vecX dst, vecX src, memory mem) %{
+  predicate(UseAVX > 0 && n->as_Vector()->length_in_bytes() == 16);
+  match(Set dst (XorV src (LoadVector mem)));
+  format %{ "vpxor   $dst,$src,$mem\t! xor vectors (16 bytes)" %}
+  ins_encode %{
+    bool vector256 = false;
+    __ vpxor($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vxor32B_reg(vecY dst, vecY src1, vecY src2) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length_in_bytes() == 32);
+  match(Set dst (XorV src1 src2));
+  format %{ "vpxor   $dst,$src1,$src2\t! xor vectors (32 bytes)" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpxor($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
+instruct vxor32B_mem(vecY dst, vecY src, memory mem) %{
+  predicate(UseAVX > 1 && n->as_Vector()->length_in_bytes() == 32);
+  match(Set dst (XorV src (LoadVector mem)));
+  format %{ "vpxor   $dst,$src,$mem\t! xor vectors (32 bytes)" %}
+  ins_encode %{
+    bool vector256 = true;
+    __ vpxor($dst$$XMMRegister, $src$$XMMRegister, $mem$$Address, vector256);
+  %}
+  ins_pipe( pipe_slow );
+%}
+
diff --git a/hotspot/src/cpu/x86/vm/x86_32.ad b/hotspot/src/cpu/x86/vm/x86_32.ad
index adfb97b..ce671f5 100644
--- a/hotspot/src/cpu/x86/vm/x86_32.ad
+++ b/hotspot/src/cpu/x86/vm/x86_32.ad
@@ -74,9 +74,6 @@
 reg_def EAX(SOC, SOC, Op_RegI, 0, rax->as_VMReg());
 reg_def ESP( NS,  NS, Op_RegI, 4, rsp->as_VMReg());
 
-// Special Registers
-reg_def EFLAGS(SOC, SOC, 0, 8, VMRegImpl::Bad());
-
 // Float registers.  We treat TOS/FPR0 special.  It is invisible to the
 // allocator, and only shows up in the encodings.
 reg_def FPR0L( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad());
@@ -105,27 +102,6 @@
 reg_def FPR7L( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg());
 reg_def FPR7H( SOC, SOC, Op_RegF, 7, as_FloatRegister(6)->as_VMReg()->next());
 
-// XMM registers.  128-bit registers or 4 words each, labeled a-d.
-// Word a in each register holds a Float, words ab hold a Double.
-// We currently do not use the SIMD capabilities, so registers cd
-// are unused at the moment.
-reg_def XMM0a( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg());
-reg_def XMM0b( SOC, SOC, Op_RegF, 0, xmm0->as_VMReg()->next());
-reg_def XMM1a( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg());
-reg_def XMM1b( SOC, SOC, Op_RegF, 1, xmm1->as_VMReg()->next());
-reg_def XMM2a( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg());
-reg_def XMM2b( SOC, SOC, Op_RegF, 2, xmm2->as_VMReg()->next());
-reg_def XMM3a( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg());
-reg_def XMM3b( SOC, SOC, Op_RegF, 3, xmm3->as_VMReg()->next());
-reg_def XMM4a( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg());
-reg_def XMM4b( SOC, SOC, Op_RegF, 4, xmm4->as_VMReg()->next());
-reg_def XMM5a( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg());
-reg_def XMM5b( SOC, SOC, Op_RegF, 5, xmm5->as_VMReg()->next());
-reg_def XMM6a( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg());
-reg_def XMM6b( SOC, SOC, Op_RegF, 6, xmm6->as_VMReg()->next());
-reg_def XMM7a( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg());
-reg_def XMM7b( SOC, SOC, Op_RegF, 7, xmm7->as_VMReg()->next());
-
 // Specify priority of register selection within phases of register
 // allocation.  Highest priority is first.  A useful heuristic is to
 // give registers a low priority when they are required by machine
@@ -138,15 +114,6 @@
                     FPR3L, FPR3H, FPR4L, FPR4H, FPR5L, FPR5H,
                     FPR6L, FPR6H, FPR7L, FPR7H );
 
-alloc_class chunk1( XMM0a, XMM0b,
-                    XMM1a, XMM1b,
-                    XMM2a, XMM2b,
-                    XMM3a, XMM3b,
-                    XMM4a, XMM4b,
-                    XMM5a, XMM5b,
-                    XMM6a, XMM6b,
-                    XMM7a, XMM7b, EFLAGS);
-
 
 //----------Architecture Description Register Classes--------------------------
 // Several register classes are automatically defined based upon information in
@@ -159,12 +126,12 @@
 // Class for all registers
 reg_class any_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX, ESP);
 // Class for general registers
-reg_class e_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX);
+reg_class int_reg(EAX, EDX, EBP, EDI, ESI, ECX, EBX);
 // Class for general registers which may be used for implicit null checks on win95
 // Also safe for use by tailjump. We don't want to allocate in rbp,
-reg_class e_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX);
+reg_class int_reg_no_rbp(EAX, EDX, EDI, ESI, ECX, EBX);
 // Class of "X" registers
-reg_class x_reg(EBX, ECX, EDX, EAX);
+reg_class int_x_reg(EBX, ECX, EDX, EAX);
 // Class of registers that can appear in an address with no offset.
 // EBP and ESP require an extra instruction byte for zero offset.
 // Used in fast-unlock
@@ -193,8 +160,6 @@
 reg_class sp_reg(ESP);
 // Singleton class for instruction pointer
 // reg_class ip_reg(EIP);
-// Singleton class for condition codes
-reg_class int_flags(EFLAGS);
 // Class of integer register pairs
 reg_class long_reg( EAX,EDX, ECX,EBX, EBP,EDI );
 // Class of integer register pairs that aligns with calling convention
@@ -206,29 +171,18 @@
 // Floating point registers.  Notice FPR0 is not a choice.
 // FPR0 is not ever allocated; we use clever encodings to fake
 // a 2-address instructions out of Intels FP stack.
-reg_class flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L );
+reg_class fp_flt_reg( FPR1L,FPR2L,FPR3L,FPR4L,FPR5L,FPR6L,FPR7L );
 
-// make a register class for SSE registers
-reg_class xmm_reg(XMM0a, XMM1a, XMM2a, XMM3a, XMM4a, XMM5a, XMM6a, XMM7a);
+reg_class fp_dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H,
+                      FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H,
+                      FPR7L,FPR7H );
 
-// make a double register class for SSE2 registers
-reg_class xdb_reg(XMM0a,XMM0b, XMM1a,XMM1b, XMM2a,XMM2b, XMM3a,XMM3b,
-                  XMM4a,XMM4b, XMM5a,XMM5b, XMM6a,XMM6b, XMM7a,XMM7b );
+reg_class fp_flt_reg0( FPR1L );
+reg_class fp_dbl_reg0( FPR1L,FPR1H );
+reg_class fp_dbl_reg1( FPR2L,FPR2H );
+reg_class fp_dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H,
+                          FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H );
 
-reg_class dbl_reg( FPR1L,FPR1H, FPR2L,FPR2H, FPR3L,FPR3H,
-                   FPR4L,FPR4H, FPR5L,FPR5H, FPR6L,FPR6H,
-                   FPR7L,FPR7H );
-
-reg_class flt_reg0( FPR1L );
-reg_class dbl_reg0( FPR1L,FPR1H );
-reg_class dbl_reg1( FPR2L,FPR2H );
-reg_class dbl_notreg0( FPR2L,FPR2H, FPR3L,FPR3H, FPR4L,FPR4H,
-                       FPR5L,FPR5H, FPR6L,FPR6H, FPR7L,FPR7H );
-
-// XMM6 and XMM7 could be used as temporary registers for long, float and
-// double values for SSE2.
-reg_class xdb_reg6( XMM6a,XMM6b );
-reg_class xdb_reg7( XMM7a,XMM7b );
 %}
 
 
@@ -412,7 +366,7 @@
   }
 }
 
-   // eRegI ereg, memory mem) %{    // emit_reg_mem
+   // rRegI ereg, memory mem) %{    // emit_reg_mem
 void encode_RegMem( CodeBuffer &cbuf, int reg_encoding, int base, int index, int scale, int displace, bool displace_is_oop ) {
   // There is no index & no scale, use form without SIB byte
   if ((index == 0x4) &&
@@ -787,7 +741,7 @@
 #endif
   }
   int offset_size = (offset == 0) ? 0 : ((offset <= 127) ? 1 : 4);
-  // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes.
+  // VEX_2bytes prefix is used if UseAVX > 0, so it takes the same 2 bytes as SIMD prefix.
   return size+5+offset_size;
 }
 
@@ -821,7 +775,7 @@
     }
 #endif
   }
-  // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes.
+  // VEX_2bytes prefix is used if UseAVX > 0, and it takes the same 2 bytes as SIMD prefix.
   // Only MOVAPS SSE prefix uses 1 byte.
   int sz = 4;
   if (!(src_lo+1 == src_hi && dst_lo+1 == dst_hi) &&
@@ -903,6 +857,108 @@
   return impl_helper(cbuf,do_size,false,offset,st_op,op,op_str,size, st);
 }
 
+// Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
+static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
+                          int src_hi, int dst_hi, uint ireg, outputStream* st);
+
+static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
+                            int stack_offset, int reg, uint ireg, outputStream* st);
+
+static int vec_stack_to_stack_helper(CodeBuffer *cbuf, bool do_size, int src_offset,
+                                     int dst_offset, uint ireg, outputStream* st) {
+  int calc_size = 0;
+  int src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4);
+  int dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4);
+  switch (ireg) {
+  case Op_VecS:
+    calc_size = 3+src_offset_size + 3+dst_offset_size;
+    break;
+  case Op_VecD:
+    calc_size = 3+src_offset_size + 3+dst_offset_size;
+    src_offset += 4;
+    dst_offset += 4;
+    src_offset_size = (src_offset == 0) ? 0 : ((src_offset < 0x80) ? 1 : 4);
+    dst_offset_size = (dst_offset == 0) ? 0 : ((dst_offset < 0x80) ? 1 : 4);
+    calc_size += 3+src_offset_size + 3+dst_offset_size;
+    break;
+  case Op_VecX:
+    calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
+    break;
+  case Op_VecY:
+    calc_size = 6 + 6 + 5+src_offset_size + 5+dst_offset_size;
+    break;
+  default:
+    ShouldNotReachHere();
+  }
+  if (cbuf) {
+    MacroAssembler _masm(cbuf);
+    int offset = __ offset();
+    switch (ireg) {
+    case Op_VecS:
+      __ pushl(Address(rsp, src_offset));
+      __ popl (Address(rsp, dst_offset));
+      break;
+    case Op_VecD:
+      __ pushl(Address(rsp, src_offset));
+      __ popl (Address(rsp, dst_offset));
+      __ pushl(Address(rsp, src_offset+4));
+      __ popl (Address(rsp, dst_offset+4));
+      break;
+    case Op_VecX:
+      __ movdqu(Address(rsp, -16), xmm0);
+      __ movdqu(xmm0, Address(rsp, src_offset));
+      __ movdqu(Address(rsp, dst_offset), xmm0);
+      __ movdqu(xmm0, Address(rsp, -16));
+      break;
+    case Op_VecY:
+      __ vmovdqu(Address(rsp, -32), xmm0);
+      __ vmovdqu(xmm0, Address(rsp, src_offset));
+      __ vmovdqu(Address(rsp, dst_offset), xmm0);
+      __ vmovdqu(xmm0, Address(rsp, -32));
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+    int size = __ offset() - offset;
+    assert(size == calc_size, "incorrect size calculattion");
+    return size;
+#ifndef PRODUCT
+  } else if (!do_size) {
+    switch (ireg) {
+    case Op_VecS:
+      st->print("pushl   [rsp + #%d]\t# 32-bit mem-mem spill\n\t"
+                "popl    [rsp + #%d]",
+                src_offset, dst_offset);
+      break;
+    case Op_VecD:
+      st->print("pushl   [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
+                "popq    [rsp + #%d]\n\t"
+                "pushl   [rsp + #%d]\n\t"
+                "popq    [rsp + #%d]",
+                src_offset, dst_offset, src_offset+4, dst_offset+4);
+      break;
+     case Op_VecX:
+      st->print("movdqu  [rsp - #16], xmm0\t# 128-bit mem-mem spill\n\t"
+                "movdqu  xmm0, [rsp + #%d]\n\t"
+                "movdqu  [rsp + #%d], xmm0\n\t"
+                "movdqu  xmm0, [rsp - #16]",
+                src_offset, dst_offset);
+      break;
+    case Op_VecY:
+      st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
+                "vmovdqu xmm0, [rsp + #%d]\n\t"
+                "vmovdqu [rsp + #%d], xmm0\n\t"
+                "vmovdqu xmm0, [rsp - #32]",
+                src_offset, dst_offset);
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+#endif
+  }
+  return calc_size;
+}
+
 uint MachSpillCopyNode::implementation( CodeBuffer *cbuf, PhaseRegAlloc *ra_, bool do_size, outputStream* st ) const {
   // Get registers to move
   OptoReg::Name src_second = ra_->get_reg_second(in(1));
@@ -923,6 +979,29 @@
   if( src_first == dst_first && src_second == dst_second )
     return size;            // Self copy, no move
 
+  if (bottom_type()->isa_vect() != NULL) {
+    uint ireg = ideal_reg();
+    assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
+    assert((src_first_rc != rc_float && dst_first_rc != rc_float), "sanity");
+    assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
+    if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
+      // mem -> mem
+      int src_offset = ra_->reg2offset(src_first);
+      int dst_offset = ra_->reg2offset(dst_first);
+      return vec_stack_to_stack_helper(cbuf, do_size, src_offset, dst_offset, ireg, st);
+    } else if (src_first_rc == rc_xmm && dst_first_rc == rc_xmm ) {
+      return vec_mov_helper(cbuf, do_size, src_first, dst_first, src_second, dst_second, ireg, st);
+    } else if (src_first_rc == rc_xmm && dst_first_rc == rc_stack ) {
+      int stack_offset = ra_->reg2offset(dst_first);
+      return vec_spill_helper(cbuf, do_size, false, stack_offset, src_first, ireg, st);
+    } else if (src_first_rc == rc_stack && dst_first_rc == rc_xmm ) {
+      int stack_offset = ra_->reg2offset(src_first);
+      return vec_spill_helper(cbuf, do_size, true,  stack_offset, dst_first, ireg, st);
+    } else {
+      ShouldNotReachHere();
+    }
+  }
+
   // --------------------------------------
   // Check for mem-mem move.  push/pop to move.
   if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
@@ -1288,14 +1367,6 @@
   return offset;
 }
 
-
-const bool Matcher::match_rule_supported(int opcode) {
-  if (!has_match_rule(opcode))
-    return false;
-
-  return true;  // Per default match rules are supported.
-}
-
 int Matcher::regnum_to_fpu_offset(int regnum) {
   return regnum - 32; // The FP registers are in the second chunk
 }
@@ -1305,16 +1376,6 @@
   return true;
 }
 
-// Vector width in bytes
-const uint Matcher::vector_width_in_bytes(void) {
-  return UseSSE >= 2 ? 8 : 0;
-}
-
-// Vector ideal reg
-const uint Matcher::vector_ideal_reg(void) {
-  return Op_RegD;
-}
-
 // Is this branch offset short enough that a short branch can be used?
 //
 // NOTE: If the platform does not provide any short branch variants, then
@@ -1444,7 +1505,7 @@
 // arguments in those registers not be available to the callee.
 bool Matcher::can_be_java_arg( int reg ) {
   if(  reg == ECX_num   || reg == EDX_num   ) return true;
-  if( (reg == XMM0a_num || reg == XMM1a_num) && UseSSE>=1 ) return true;
+  if( (reg == XMM0_num  || reg == XMM1_num ) && UseSSE>=1 ) return true;
   if( (reg == XMM0b_num || reg == XMM1b_num) && UseSSE>=2 ) return true;
   return false;
 }
@@ -1492,9 +1553,6 @@
 // Returns true if the high 32 bits of the value is known to be zero.
 bool is_operand_hi32_zero(Node* n) {
   int opc = n->Opcode();
-  if (opc == Op_LoadUI2L) {
-    return true;
-  }
   if (opc == Op_AndL) {
     Node* o2 = n->in(2);
     if (o2->is_Con() && (o2->get_long() & 0xFFFFFFFF00000000LL) == 0LL) {
@@ -1557,16 +1615,16 @@
     emit_opcode(cbuf,0x66);
   %}
 
-  enc_class RegReg (eRegI dst, eRegI src) %{    // RegReg(Many)
+  enc_class RegReg (rRegI dst, rRegI src) %{    // RegReg(Many)
     emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
   %}
 
-  enc_class OpcRegReg (immI opcode, eRegI dst, eRegI src) %{    // OpcRegReg(Many)
+  enc_class OpcRegReg (immI opcode, rRegI dst, rRegI src) %{    // OpcRegReg(Many)
     emit_opcode(cbuf,$opcode$$constant);
     emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
   %}
 
-  enc_class mov_r32_imm0( eRegI dst ) %{
+  enc_class mov_r32_imm0( rRegI dst ) %{
     emit_opcode( cbuf, 0xB8 + $dst$$reg ); // 0xB8+ rd   -- MOV r32  ,imm32
     emit_d32   ( cbuf, 0x0  );             //                         imm32==0x0
   %}
@@ -1613,7 +1671,7 @@
   %}
 
   // Dense encoding for older common ops
-  enc_class Opc_plus(immI opcode, eRegI reg) %{
+  enc_class Opc_plus(immI opcode, rRegI reg) %{
     emit_opcode(cbuf, $opcode$$constant + $reg$$reg);
   %}
 
@@ -1629,7 +1687,7 @@
     }
   %}
 
-  enc_class OpcSErm (eRegI dst, immI imm) %{    // OpcSEr/m
+  enc_class OpcSErm (rRegI dst, immI imm) %{    // OpcSEr/m
     // Emit primary opcode and set sign-extend bit
     // Check for 8-bit immediate, and set sign extend bit in opcode
     if (($imm$$constant >= -128) && ($imm$$constant <= 127)) {
@@ -1674,7 +1732,7 @@
     else                               emit_d32(cbuf,con);
   %}
 
-  enc_class OpcSReg (eRegI dst) %{    // BSWAP
+  enc_class OpcSReg (rRegI dst) %{    // BSWAP
     emit_cc(cbuf, $secondary, $dst$$reg );
   %}
 
@@ -1692,7 +1750,7 @@
     emit_rm(cbuf, 0x3, destlo, desthi);
   %}
 
-  enc_class RegOpc (eRegI div) %{    // IDIV, IMOD, JMP indirect, ...
+  enc_class RegOpc (rRegI div) %{    // IDIV, IMOD, JMP indirect, ...
     emit_rm(cbuf, 0x3, $secondary, $div$$reg );
   %}
 
@@ -1883,20 +1941,20 @@
 //                 runtime_call_Relocation::spec(), RELOC_IMM32 );
 //   %}
 
-  enc_class RegOpcImm (eRegI dst, immI8 shift) %{    // SHL, SAR, SHR
+  enc_class RegOpcImm (rRegI dst, immI8 shift) %{    // SHL, SAR, SHR
     $$$emit8$primary;
     emit_rm(cbuf, 0x3, $secondary, $dst$$reg);
     $$$emit8$shift$$constant;
   %}
 
-  enc_class LdImmI (eRegI dst, immI src) %{    // Load Immediate
+  enc_class LdImmI (rRegI dst, immI src) %{    // Load Immediate
     // Load immediate does not have a zero or sign extended version
     // for 8-bit immediates
     emit_opcode(cbuf, 0xB8 + $dst$$reg);
     $$$emit32$src$$constant;
   %}
 
-  enc_class LdImmP (eRegI dst, immI src) %{    // Load Immediate
+  enc_class LdImmP (rRegI dst, immI src) %{    // Load Immediate
     // Load immediate does not have a zero or sign extended version
     // for 8-bit immediates
     emit_opcode(cbuf, $primary + $dst$$reg);
@@ -1935,15 +1993,15 @@
 
 
   // Encode a reg-reg copy.  If it is useless, then empty encoding.
-  enc_class enc_Copy( eRegI dst, eRegI src ) %{
+  enc_class enc_Copy( rRegI dst, rRegI src ) %{
     encode_Copy( cbuf, $dst$$reg, $src$$reg );
   %}
 
-  enc_class enc_CopyL_Lo( eRegI dst, eRegL src ) %{
+  enc_class enc_CopyL_Lo( rRegI dst, eRegL src ) %{
     encode_Copy( cbuf, $dst$$reg, $src$$reg );
   %}
 
-  enc_class RegReg (eRegI dst, eRegI src) %{    // RegReg(Many)
+  enc_class RegReg (rRegI dst, rRegI src) %{    // RegReg(Many)
     emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
   %}
 
@@ -1965,7 +2023,7 @@
     emit_rm(cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), HIGH_FROM_LOW($src$$reg));
   %}
 
-  enc_class RegReg_HiLo( eRegL src, eRegI dst ) %{
+  enc_class RegReg_HiLo( eRegL src, rRegI dst ) %{
     emit_rm(cbuf, 0x3, $dst$$reg, HIGH_FROM_LOW($src$$reg));
   %}
 
@@ -2060,7 +2118,7 @@
     cbuf.set_insts_mark();            // Mark start of opcode for reloc info in mem operand
   %}
 
-  enc_class RegMem (eRegI ereg, memory mem) %{    // emit_reg_mem
+  enc_class RegMem (rRegI ereg, memory mem) %{    // emit_reg_mem
     int reg_encoding = $ereg$$reg;
     int base  = $mem$$base;
     int index = $mem$$index;
@@ -2124,7 +2182,7 @@
 
   // Clone of RegMem but accepts an extra parameter to access each
   // half of a double in memory; it never needs relocation info.
-  enc_class Mov_MemD_half_to_Reg (immI opcode, memory mem, immI disp_for_half, eRegI rm_reg) %{
+  enc_class Mov_MemD_half_to_Reg (immI opcode, memory mem, immI disp_for_half, rRegI rm_reg) %{
     emit_opcode(cbuf,$opcode$$constant);
     int reg_encoding = $rm_reg$$reg;
     int base     = $mem$$base;
@@ -2160,7 +2218,7 @@
     encode_RegMem(cbuf, rm_byte_opcode, base, index, scale, displace, disp_is_oop);
   %}
 
-  enc_class RegLea (eRegI dst, eRegI src0, immI src1 ) %{    // emit_reg_lea
+  enc_class RegLea (rRegI dst, rRegI src0, immI src1 ) %{    // emit_reg_lea
     int reg_encoding = $dst$$reg;
     int base         = $src0$$reg;      // 0xFFFFFFFF indicates no base
     int index        = 0x04;            // 0x04 indicates no index
@@ -2170,7 +2228,7 @@
     encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
   %}
 
-  enc_class min_enc (eRegI dst, eRegI src) %{    // MIN
+  enc_class min_enc (rRegI dst, rRegI src) %{    // MIN
     // Compare dst,src
     emit_opcode(cbuf,0x3B);
     emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
@@ -2182,7 +2240,7 @@
     emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
   %}
 
-  enc_class max_enc (eRegI dst, eRegI src) %{    // MAX
+  enc_class max_enc (rRegI dst, rRegI src) %{    // MAX
     // Compare dst,src
     emit_opcode(cbuf,0x3B);
     emit_rm(cbuf, 0x3, $dst$$reg, $src$$reg);
@@ -2213,7 +2271,7 @@
     encode_RegMem(cbuf, reg_encoding, base, index, scale, displace, disp_is_oop);
   %}
 
-  enc_class neg_reg(eRegI dst) %{
+  enc_class neg_reg(rRegI dst) %{
     // NEG $dst
     emit_opcode(cbuf,0xF7);
     emit_rm(cbuf, 0x3, 0x03, $dst$$reg );
@@ -2243,7 +2301,7 @@
     emit_rm(cbuf, 0x3, $p$$reg, tmpReg);
   %}
 
-  enc_class enc_cmpLTP_mem(eRegI p, eRegI q, memory mem, eCXRegI tmp) %{    // cadd_cmpLT
+  enc_class enc_cmpLTP_mem(rRegI p, rRegI q, memory mem, eCXRegI tmp) %{    // cadd_cmpLT
     int tmpReg = $tmp$$reg;
 
     // SUB $p,$q
@@ -2382,12 +2440,12 @@
   %}
 
   // Special case for moving an integer register to a stack slot.
-  enc_class OpcPRegSS( stackSlotI dst, eRegI src ) %{ // RegSS
+  enc_class OpcPRegSS( stackSlotI dst, rRegI src ) %{ // RegSS
     store_to_stackslot( cbuf, $primary, $src$$reg, $dst$$disp );
   %}
 
   // Special case for moving a register to a stack slot.
-  enc_class RegSS( stackSlotI dst, eRegI src ) %{ // RegSS
+  enc_class RegSS( stackSlotI dst, rRegI src ) %{ // RegSS
     // Opcode already emitted
     emit_rm( cbuf, 0x02, $src$$reg, ESP_enc );   // R/M byte
     emit_rm( cbuf, 0x00, ESP_enc, ESP_enc);          // SIB byte
@@ -2528,45 +2586,6 @@
     __ fld_d(Address(rsp, 0));
   %}
 
-  // Compute X^Y using Intel's fast hardware instructions, if possible.
-  // Otherwise return a NaN.
-  enc_class pow_exp_core_encoding %{
-    // FPR1 holds Y*ln2(X).  Compute FPR1 = 2^(Y*ln2(X))
-    emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xC0);  // fdup = fld st(0)          Q       Q
-    emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xFC);  // frndint               int(Q)      Q
-    emit_opcode(cbuf,0xDC); emit_opcode(cbuf,0xE9);  // fsub st(1) -= st(0);  int(Q) frac(Q)
-    emit_opcode(cbuf,0xDB);                          // FISTP [ESP]           frac(Q)
-    emit_opcode(cbuf,0x1C);
-    emit_d8(cbuf,0x24);
-    emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xF0);  // f2xm1                 2^frac(Q)-1
-    emit_opcode(cbuf,0xD9); emit_opcode(cbuf,0xE8);  // fld1                  1 2^frac(Q)-1
-    emit_opcode(cbuf,0xDE); emit_opcode(cbuf,0xC1);  // faddp                 2^frac(Q)
-    emit_opcode(cbuf,0x8B);                          // mov rax,[esp+0]=int(Q)
-    encode_RegMem(cbuf, EAX_enc, ESP_enc, 0x4, 0, 0, false);
-    emit_opcode(cbuf,0xC7);                          // mov rcx,0xFFFFF800 - overflow mask
-    emit_rm(cbuf, 0x3, 0x0, ECX_enc);
-    emit_d32(cbuf,0xFFFFF800);
-    emit_opcode(cbuf,0x81);                          // add rax,1023 - the double exponent bias
-    emit_rm(cbuf, 0x3, 0x0, EAX_enc);
-    emit_d32(cbuf,1023);
-    emit_opcode(cbuf,0x8B);                          // mov rbx,eax
-    emit_rm(cbuf, 0x3, EBX_enc, EAX_enc);
-    emit_opcode(cbuf,0xC1);                          // shl rax,20 - Slide to exponent position
-    emit_rm(cbuf,0x3,0x4,EAX_enc);
-    emit_d8(cbuf,20);
-    emit_opcode(cbuf,0x85);                          // test rbx,ecx - check for overflow
-    emit_rm(cbuf, 0x3, EBX_enc, ECX_enc);
-    emit_opcode(cbuf,0x0F); emit_opcode(cbuf,0x45);  // CMOVne rax,ecx - overflow; stuff NAN into EAX
-    emit_rm(cbuf, 0x3, EAX_enc, ECX_enc);
-    emit_opcode(cbuf,0x89);                          // mov [esp+4],eax - Store as part of double word
-    encode_RegMem(cbuf, EAX_enc, ESP_enc, 0x4, 0, 4, false);
-    emit_opcode(cbuf,0xC7);                          // mov [esp+0],0   - [ESP] = (double)(1<<int(Q)) = 2^int(Q)
-    encode_RegMem(cbuf, 0x0, ESP_enc, 0x4, 0, 0, false);
-    emit_d32(cbuf,0);
-    emit_opcode(cbuf,0xDC);                          // fmul dword st(0),[esp+0]; FPR1 = 2^int(Q)*2^frac(Q) = 2^Q
-    encode_RegMem(cbuf, 0x1, ESP_enc, 0x4, 0, 0, false);
-  %}
-
   enc_class Push_Result_Mod_DPR( regDPR src) %{
     if ($src$$reg != FPR1L_enc) {
       // fincstp
@@ -2671,7 +2690,7 @@
 // equal_result    = 0;
 // nan_result      = -1;
 
-  enc_class CmpF_Result(eRegI dst) %{
+  enc_class CmpF_Result(rRegI dst) %{
     // fnstsw_ax();
     emit_opcode( cbuf, 0xDF);
     emit_opcode( cbuf, 0xE0);
@@ -2716,7 +2735,7 @@
 // done:
   %}
 
-  enc_class convert_int_long( regL dst, eRegI src ) %{
+  enc_class convert_int_long( regL dst, rRegI src ) %{
     // mov $dst.lo,$src
     int dst_encoding = $dst$$reg;
     int src_encoding = $src$$reg;
@@ -2785,7 +2804,7 @@
     emit_rm( cbuf, 0x3, 0x4, $src$$reg);
   %}
 
-  enc_class long_multiply( eADXRegL dst, eRegL src, eRegI tmp ) %{
+  enc_class long_multiply( eADXRegL dst, eRegL src, rRegI tmp ) %{
     // Basic idea: lo(result) = lo(x_lo * y_lo)
     //             hi(result) = hi(x_lo * y_lo) + lo(x_hi * y_lo) + lo(x_lo * y_hi)
     // MOV    $tmp,$src.lo
@@ -2811,7 +2830,7 @@
     emit_rm( cbuf, 0x3, HIGH_FROM_LOW($dst$$reg), $tmp$$reg );
   %}
 
-  enc_class long_multiply_con( eADXRegL dst, immL_127 src, eRegI tmp ) %{
+  enc_class long_multiply_con( eADXRegL dst, immL_127 src, rRegI tmp ) %{
     // Basic idea: lo(result) = lo(src * y_lo)
     //             hi(result) = hi(src * y_lo) + lo(src * y_hi)
     // IMUL   $tmp,EDX,$src
@@ -2867,7 +2886,7 @@
     emit_d8(cbuf, 4*4);
   %}
 
-  enc_class long_cmp_flags0( eRegL src, eRegI tmp ) %{
+  enc_class long_cmp_flags0( eRegL src, rRegI tmp ) %{
     // MOV   $tmp,$src.lo
     emit_opcode(cbuf, 0x8B);
     emit_rm(cbuf, 0x3, $tmp$$reg, $src$$reg);
@@ -2888,7 +2907,7 @@
     emit_rm(cbuf, 0x3, HIGH_FROM_LOW($src1$$reg), HIGH_FROM_LOW($src2$$reg) );
   %}
 
-  enc_class long_cmp_flags2( eRegL src1, eRegL src2, eRegI tmp ) %{
+  enc_class long_cmp_flags2( eRegL src1, eRegL src2, rRegI tmp ) %{
     // CMP    $src1.lo,$src2.lo\t! Long compare; set flags for low bits
     emit_opcode( cbuf, 0x3B );
     emit_rm(cbuf, 0x3, $src1$$reg, $src2$$reg );
@@ -2900,7 +2919,7 @@
     emit_rm(cbuf, 0x3, $tmp$$reg, HIGH_FROM_LOW($src2$$reg) );
   %}
 
-  enc_class long_cmp_flags3( eRegL src, eRegI tmp ) %{
+  enc_class long_cmp_flags3( eRegL src, rRegI tmp ) %{
     // XOR    $tmp,$tmp
     emit_opcode(cbuf,0x33);  // XOR
     emit_rm(cbuf,0x3, $tmp$$reg, $tmp$$reg);
@@ -3793,9 +3812,9 @@
     // in SSE2+ mode we want to keep the FPU stack clean so pretend
     // that C functions return float and double results in XMM0.
     if( ideal_reg == Op_RegD && UseSSE>=2 )
-      return OptoRegPair(XMM0b_num,XMM0a_num);
+      return OptoRegPair(XMM0b_num,XMM0_num);
     if( ideal_reg == Op_RegF && UseSSE>=2 )
-      return OptoRegPair(OptoReg::Bad,XMM0a_num);
+      return OptoRegPair(OptoReg::Bad,XMM0_num);
 
     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
   %}
@@ -3806,9 +3825,9 @@
     static int lo[Op_RegL+1] = { 0, 0, OptoReg::Bad, EAX_num,      EAX_num,      FPR1L_num,    FPR1L_num, EAX_num };
     static int hi[Op_RegL+1] = { 0, 0, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, OptoReg::Bad, FPR1H_num, EDX_num };
     if( ideal_reg == Op_RegD && UseSSE>=2 )
-      return OptoRegPair(XMM0b_num,XMM0a_num);
+      return OptoRegPair(XMM0b_num,XMM0_num);
     if( ideal_reg == Op_RegF && UseSSE>=1 )
-      return OptoRegPair(OptoReg::Bad,XMM0a_num);
+      return OptoRegPair(OptoReg::Bad,XMM0_num);
     return OptoRegPair(hi[ideal_reg],lo[ideal_reg]);
   %}
 
@@ -4178,8 +4197,8 @@
 
 // Register Operands
 // Integer Register
-operand eRegI() %{
-  constraint(ALLOC_IN_RC(e_reg));
+operand rRegI() %{
+  constraint(ALLOC_IN_RC(int_reg));
   match(RegI);
   match(xRegI);
   match(eAXRegI);
@@ -4194,8 +4213,8 @@
 %}
 
 // Subset of Integer Register
-operand xRegI(eRegI reg) %{
-  constraint(ALLOC_IN_RC(x_reg));
+operand xRegI(rRegI reg) %{
+  constraint(ALLOC_IN_RC(int_x_reg));
   match(reg);
   match(eAXRegI);
   match(eBXRegI);
@@ -4210,7 +4229,7 @@
 operand eAXRegI(xRegI reg) %{
   constraint(ALLOC_IN_RC(eax_reg));
   match(reg);
-  match(eRegI);
+  match(rRegI);
 
   format %{ "EAX" %}
   interface(REG_INTER);
@@ -4220,7 +4239,7 @@
 operand eBXRegI(xRegI reg) %{
   constraint(ALLOC_IN_RC(ebx_reg));
   match(reg);
-  match(eRegI);
+  match(rRegI);
 
   format %{ "EBX" %}
   interface(REG_INTER);
@@ -4229,7 +4248,7 @@
 operand eCXRegI(xRegI reg) %{
   constraint(ALLOC_IN_RC(ecx_reg));
   match(reg);
-  match(eRegI);
+  match(rRegI);
 
   format %{ "ECX" %}
   interface(REG_INTER);
@@ -4238,7 +4257,7 @@
 operand eDXRegI(xRegI reg) %{
   constraint(ALLOC_IN_RC(edx_reg));
   match(reg);
-  match(eRegI);
+  match(rRegI);
 
   format %{ "EDX" %}
   interface(REG_INTER);
@@ -4247,7 +4266,7 @@
 operand eDIRegI(xRegI reg) %{
   constraint(ALLOC_IN_RC(edi_reg));
   match(reg);
-  match(eRegI);
+  match(rRegI);
 
   format %{ "EDI" %}
   interface(REG_INTER);
@@ -4294,7 +4313,7 @@
 operand eSIRegI(xRegI reg) %{
    constraint(ALLOC_IN_RC(esi_reg));
    match(reg);
-   match(eRegI);
+   match(rRegI);
 
    format %{ "ESI" %}
    interface(REG_INTER);
@@ -4315,7 +4334,7 @@
 %}
 
 operand eRegP() %{
-  constraint(ALLOC_IN_RC(e_reg));
+  constraint(ALLOC_IN_RC(int_reg));
   match(RegP);
   match(eAXRegP);
   match(eBXRegP);
@@ -4328,7 +4347,7 @@
 
 // On windows95, EBP is not safe to use for implicit null tests.
 operand eRegP_no_EBP() %{
-  constraint(ALLOC_IN_RC(e_reg_no_rbp));
+  constraint(ALLOC_IN_RC(int_reg_no_rbp));
   match(RegP);
   match(eAXRegP);
   match(eBXRegP);
@@ -4508,7 +4527,7 @@
 // Float register operands
 operand regDPR() %{
   predicate( UseSSE < 2 );
-  constraint(ALLOC_IN_RC(dbl_reg));
+  constraint(ALLOC_IN_RC(fp_dbl_reg));
   match(RegD);
   match(regDPR1);
   match(regDPR2);
@@ -4518,7 +4537,7 @@
 
 operand regDPR1(regDPR reg) %{
   predicate( UseSSE < 2 );
-  constraint(ALLOC_IN_RC(dbl_reg0));
+  constraint(ALLOC_IN_RC(fp_dbl_reg0));
   match(reg);
   format %{ "FPR1" %}
   interface(REG_INTER);
@@ -4526,7 +4545,7 @@
 
 operand regDPR2(regDPR reg) %{
   predicate( UseSSE < 2 );
-  constraint(ALLOC_IN_RC(dbl_reg1));
+  constraint(ALLOC_IN_RC(fp_dbl_reg1));
   match(reg);
   format %{ "FPR2" %}
   interface(REG_INTER);
@@ -4534,45 +4553,16 @@
 
 operand regnotDPR1(regDPR reg) %{
   predicate( UseSSE < 2 );
-  constraint(ALLOC_IN_RC(dbl_notreg0));
+  constraint(ALLOC_IN_RC(fp_dbl_notreg0));
   match(reg);
   format %{ %}
   interface(REG_INTER);
 %}
 
-// XMM Double register operands
-operand regD() %{
-  predicate( UseSSE>=2 );
-  constraint(ALLOC_IN_RC(xdb_reg));
-  match(RegD);
-  match(regD6);
-  match(regD7);
-  format %{ %}
-  interface(REG_INTER);
-%}
-
-// XMM6 double register operands
-operand regD6(regD reg) %{
-  predicate( UseSSE>=2 );
-  constraint(ALLOC_IN_RC(xdb_reg6));
-  match(reg);
-  format %{ "XMM6" %}
-  interface(REG_INTER);
-%}
-
-// XMM7 double register operands
-operand regD7(regD reg) %{
-  predicate( UseSSE>=2 );
-  constraint(ALLOC_IN_RC(xdb_reg7));
-  match(reg);
-  format %{ "XMM7" %}
-  interface(REG_INTER);
-%}
-
 // Float register operands
 operand regFPR() %{
   predicate( UseSSE < 2 );
-  constraint(ALLOC_IN_RC(flt_reg));
+  constraint(ALLOC_IN_RC(fp_flt_reg));
   match(RegF);
   match(regFPR1);
   format %{ %}
@@ -4582,21 +4572,30 @@
 // Float register operands
 operand regFPR1(regFPR reg) %{
   predicate( UseSSE < 2 );
-  constraint(ALLOC_IN_RC(flt_reg0));
+  constraint(ALLOC_IN_RC(fp_flt_reg0));
   match(reg);
   format %{ "FPR1" %}
   interface(REG_INTER);
 %}
 
-// XMM register operands
+// XMM Float register operands
 operand regF() %{
   predicate( UseSSE>=1 );
-  constraint(ALLOC_IN_RC(xmm_reg));
+  constraint(ALLOC_IN_RC(float_reg));
   match(RegF);
   format %{ %}
   interface(REG_INTER);
 %}
 
+// XMM Double register operands
+operand regD() %{
+  predicate( UseSSE>=2 );
+  constraint(ALLOC_IN_RC(double_reg));
+  match(RegD);
+  format %{ %}
+  interface(REG_INTER);
+%}
+
 
 //----------Memory Operands----------------------------------------------------
 // Direct Memory Operand
@@ -4614,7 +4613,7 @@
 
 // Indirect Memory Operand
 operand indirect(eRegP reg) %{
-  constraint(ALLOC_IN_RC(e_reg));
+  constraint(ALLOC_IN_RC(int_reg));
   match(reg);
 
   format %{ "[$reg]" %}
@@ -4653,7 +4652,7 @@
 %}
 
 // Indirect Memory Plus Long Offset Operand
-operand indOffset32X(eRegI reg, immP off) %{
+operand indOffset32X(rRegI reg, immP off) %{
   match(AddP off reg);
 
   format %{ "[$reg + $off]" %}
@@ -4666,7 +4665,7 @@
 %}
 
 // Indirect Memory Plus Index Register Plus Offset Operand
-operand indIndexOffset(eRegP reg, eRegI ireg, immI off) %{
+operand indIndexOffset(eRegP reg, rRegI ireg, immI off) %{
   match(AddP (AddP reg ireg) off);
 
   op_cost(10);
@@ -4680,7 +4679,7 @@
 %}
 
 // Indirect Memory Plus Index Register Plus Offset Operand
-operand indIndex(eRegP reg, eRegI ireg) %{
+operand indIndex(eRegP reg, rRegI ireg) %{
   match(AddP reg ireg);
 
   op_cost(10);
@@ -4698,7 +4697,7 @@
 // // -------------------------------------------------------------------------
 // // Scaled Memory Operands
 // // Indirect Memory Times Scale Plus Offset Operand
-// operand indScaleOffset(immP off, eRegI ireg, immI2 scale) %{
+// operand indScaleOffset(immP off, rRegI ireg, immI2 scale) %{
 //   match(AddP off (LShiftI ireg scale));
 //
 //   op_cost(10);
@@ -4712,7 +4711,7 @@
 // %}
 
 // Indirect Memory Times Scale Plus Index Register
-operand indIndexScale(eRegP reg, eRegI ireg, immI2 scale) %{
+operand indIndexScale(eRegP reg, rRegI ireg, immI2 scale) %{
   match(AddP reg (LShiftI ireg scale));
 
   op_cost(10);
@@ -4726,7 +4725,7 @@
 %}
 
 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
-operand indIndexScaleOffset(eRegP reg, immI off, eRegI ireg, immI2 scale) %{
+operand indIndexScaleOffset(eRegP reg, immI off, rRegI ireg, immI2 scale) %{
   match(AddP (AddP reg (LShiftI ireg scale)) off);
 
   op_cost(10);
@@ -4854,7 +4853,7 @@
 // Indirect Memory Operand
 operand indirect_win95_safe(eRegP_no_EBP reg)
 %{
-  constraint(ALLOC_IN_RC(e_reg));
+  constraint(ALLOC_IN_RC(int_reg));
   match(reg);
 
   op_cost(100);
@@ -4898,7 +4897,7 @@
 %}
 
 // Indirect Memory Plus Index Register Plus Offset Operand
-operand indIndexOffset_win95_safe(eRegP_no_EBP reg, eRegI ireg, immI off)
+operand indIndexOffset_win95_safe(eRegP_no_EBP reg, rRegI ireg, immI off)
 %{
   match(AddP (AddP reg ireg) off);
 
@@ -4913,7 +4912,7 @@
 %}
 
 // Indirect Memory Times Scale Plus Index Register
-operand indIndexScale_win95_safe(eRegP_no_EBP reg, eRegI ireg, immI2 scale)
+operand indIndexScale_win95_safe(eRegP_no_EBP reg, rRegI ireg, immI2 scale)
 %{
   match(AddP reg (LShiftI ireg scale));
 
@@ -4928,7 +4927,7 @@
 %}
 
 // Indirect Memory Times Scale Plus Index Register Plus Offset Operand
-operand indIndexScaleOffset_win95_safe(eRegP_no_EBP reg, immI off, eRegI ireg, immI2 scale)
+operand indIndexScaleOffset_win95_safe(eRegP_no_EBP reg, immI off, rRegI ireg, immI2 scale)
 %{
   match(AddP (AddP reg (LShiftI ireg scale)) off);
 
@@ -5117,7 +5116,7 @@
 //   Or: _mem if it requires the big decoder and a memory unit.
 
 // Integer ALU reg operation
-pipe_class ialu_reg(eRegI dst) %{
+pipe_class ialu_reg(rRegI dst) %{
     single_instruction;
     dst    : S4(write);
     dst    : S3(read);
@@ -5135,7 +5134,7 @@
 %}
 
 // Integer ALU reg operation using big decoder
-pipe_class ialu_reg_fat(eRegI dst) %{
+pipe_class ialu_reg_fat(rRegI dst) %{
     single_instruction;
     dst    : S4(write);
     dst    : S3(read);
@@ -5153,7 +5152,7 @@
 %}
 
 // Integer ALU reg-reg operation
-pipe_class ialu_reg_reg(eRegI dst, eRegI src) %{
+pipe_class ialu_reg_reg(rRegI dst, rRegI src) %{
     single_instruction;
     dst    : S4(write);
     src    : S3(read);
@@ -5171,7 +5170,7 @@
 %}
 
 // Integer ALU reg-reg operation
-pipe_class ialu_reg_reg_fat(eRegI dst, memory src) %{
+pipe_class ialu_reg_reg_fat(rRegI dst, memory src) %{
     single_instruction;
     dst    : S4(write);
     src    : S3(read);
@@ -5189,7 +5188,7 @@
 %}
 
 // Integer ALU reg-mem operation
-pipe_class ialu_reg_mem(eRegI dst, memory mem) %{
+pipe_class ialu_reg_mem(rRegI dst, memory mem) %{
     single_instruction;
     dst    : S5(write);
     mem    : S3(read);
@@ -5218,7 +5217,7 @@
 %}
 
 // Integer Store to Memory
-pipe_class ialu_mem_reg(memory mem, eRegI src) %{
+pipe_class ialu_mem_reg(memory mem, rRegI src) %{
     single_instruction;
     mem    : S3(read);
     src    : S5(read);
@@ -5247,7 +5246,7 @@
 %}
 
 // Integer ALU0 reg-reg operation
-pipe_class ialu_reg_reg_alu0(eRegI dst, eRegI src) %{
+pipe_class ialu_reg_reg_alu0(rRegI dst, rRegI src) %{
     single_instruction;
     dst    : S4(write);
     src    : S3(read);
@@ -5256,7 +5255,7 @@
 %}
 
 // Integer ALU0 reg-mem operation
-pipe_class ialu_reg_mem_alu0(eRegI dst, memory mem) %{
+pipe_class ialu_reg_mem_alu0(rRegI dst, memory mem) %{
     single_instruction;
     dst    : S5(write);
     mem    : S3(read);
@@ -5266,7 +5265,7 @@
 %}
 
 // Integer ALU reg-reg operation
-pipe_class ialu_cr_reg_reg(eFlagsReg cr, eRegI src1, eRegI src2) %{
+pipe_class ialu_cr_reg_reg(eFlagsReg cr, rRegI src1, rRegI src2) %{
     single_instruction;
     cr     : S4(write);
     src1   : S3(read);
@@ -5276,7 +5275,7 @@
 %}
 
 // Integer ALU reg-imm operation
-pipe_class ialu_cr_reg_imm(eFlagsReg cr, eRegI src1) %{
+pipe_class ialu_cr_reg_imm(eFlagsReg cr, rRegI src1) %{
     single_instruction;
     cr     : S4(write);
     src1   : S3(read);
@@ -5285,7 +5284,7 @@
 %}
 
 // Integer ALU reg-mem operation
-pipe_class ialu_cr_reg_mem(eFlagsReg cr, eRegI src1, memory src2) %{
+pipe_class ialu_cr_reg_mem(eFlagsReg cr, rRegI src1, memory src2) %{
     single_instruction;
     cr     : S4(write);
     src1   : S3(read);
@@ -5296,7 +5295,7 @@
 %}
 
 // Conditional move reg-reg
-pipe_class pipe_cmplt( eRegI p, eRegI q, eRegI y ) %{
+pipe_class pipe_cmplt( rRegI p, rRegI q, rRegI y ) %{
     instruction_count(4);
     y      : S4(read);
     q      : S3(read);
@@ -5305,7 +5304,7 @@
 %}
 
 // Conditional move reg-reg
-pipe_class pipe_cmov_reg( eRegI dst, eRegI src, eFlagsReg cr ) %{
+pipe_class pipe_cmov_reg( rRegI dst, rRegI src, eFlagsReg cr ) %{
     single_instruction;
     dst    : S4(write);
     src    : S3(read);
@@ -5314,7 +5313,7 @@
 %}
 
 // Conditional move reg-mem
-pipe_class pipe_cmov_mem( eFlagsReg cr, eRegI dst, memory src) %{
+pipe_class pipe_cmov_mem( eFlagsReg cr, rRegI dst, memory src) %{
     single_instruction;
     dst    : S4(write);
     src    : S3(read);
@@ -5565,7 +5564,7 @@
 //               in the encode section of the architecture description.
 
 //----------BSWAP-Instruction--------------------------------------------------
-instruct bytes_reverse_int(eRegI dst) %{
+instruct bytes_reverse_int(rRegI dst) %{
   match(Set dst (ReverseBytesI dst));
 
   format %{ "BSWAP  $dst" %}
@@ -5586,7 +5585,7 @@
   ins_pipe( ialu_reg_reg);
 %}
 
-instruct bytes_reverse_unsigned_short(eRegI dst, eFlagsReg cr) %{
+instruct bytes_reverse_unsigned_short(rRegI dst, eFlagsReg cr) %{
   match(Set dst (ReverseBytesUS dst));
   effect(KILL cr);
 
@@ -5599,7 +5598,7 @@
   ins_pipe( ialu_reg );
 %}
 
-instruct bytes_reverse_short(eRegI dst, eFlagsReg cr) %{
+instruct bytes_reverse_short(rRegI dst, eFlagsReg cr) %{
   match(Set dst (ReverseBytesS dst));
   effect(KILL cr);
 
@@ -5615,7 +5614,7 @@
 
 //---------- Zeros Count Instructions ------------------------------------------
 
-instruct countLeadingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct countLeadingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{
   predicate(UseCountLeadingZerosInstruction);
   match(Set dst (CountLeadingZerosI src));
   effect(KILL cr);
@@ -5627,7 +5626,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct countLeadingZerosI_bsr(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct countLeadingZerosI_bsr(rRegI dst, rRegI src, eFlagsReg cr) %{
   predicate(!UseCountLeadingZerosInstruction);
   match(Set dst (CountLeadingZerosI src));
   effect(KILL cr);
@@ -5652,7 +5651,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct countLeadingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
+instruct countLeadingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{
   predicate(UseCountLeadingZerosInstruction);
   match(Set dst (CountLeadingZerosL src));
   effect(TEMP dst, KILL cr);
@@ -5675,7 +5674,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct countLeadingZerosL_bsr(eRegI dst, eRegL src, eFlagsReg cr) %{
+instruct countLeadingZerosL_bsr(rRegI dst, eRegL src, eFlagsReg cr) %{
   predicate(!UseCountLeadingZerosInstruction);
   match(Set dst (CountLeadingZerosL src));
   effect(TEMP dst, KILL cr);
@@ -5711,7 +5710,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct countTrailingZerosI(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct countTrailingZerosI(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (CountTrailingZerosI src));
   effect(KILL cr);
 
@@ -5730,7 +5729,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct countTrailingZerosL(eRegI dst, eRegL src, eFlagsReg cr) %{
+instruct countTrailingZerosL(rRegI dst, eRegL src, eFlagsReg cr) %{
   match(Set dst (CountTrailingZerosL src));
   effect(TEMP dst, KILL cr);
 
@@ -5762,7 +5761,7 @@
 
 //---------- Population Count Instructions -------------------------------------
 
-instruct popCountI(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct popCountI(rRegI dst, rRegI src, eFlagsReg cr) %{
   predicate(UsePopCountInstruction);
   match(Set dst (PopCountI src));
   effect(KILL cr);
@@ -5774,7 +5773,7 @@
   ins_pipe(ialu_reg);
 %}
 
-instruct popCountI_mem(eRegI dst, memory mem, eFlagsReg cr) %{
+instruct popCountI_mem(rRegI dst, memory mem, eFlagsReg cr) %{
   predicate(UsePopCountInstruction);
   match(Set dst (PopCountI (LoadI mem)));
   effect(KILL cr);
@@ -5787,7 +5786,7 @@
 %}
 
 // Note: Long.bitCount(long) returns an int.
-instruct popCountL(eRegI dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
+instruct popCountL(rRegI dst, eRegL src, rRegI tmp, eFlagsReg cr) %{
   predicate(UsePopCountInstruction);
   match(Set dst (PopCountL src));
   effect(KILL cr, TEMP tmp, TEMP dst);
@@ -5804,7 +5803,7 @@
 %}
 
 // Note: Long.bitCount(long) returns an int.
-instruct popCountL_mem(eRegI dst, memory mem, eRegI tmp, eFlagsReg cr) %{
+instruct popCountL_mem(rRegI dst, memory mem, rRegI tmp, eFlagsReg cr) %{
   predicate(UsePopCountInstruction);
   match(Set dst (PopCountL (LoadL mem)));
   effect(KILL cr, TEMP tmp, TEMP dst);
@@ -5908,7 +5907,7 @@
 %}
 
 // Load Short (16bit signed)
-instruct loadS(eRegI dst, memory mem) %{
+instruct loadS(rRegI dst, memory mem) %{
   match(Set dst (LoadS mem));
 
   ins_cost(125);
@@ -5922,7 +5921,7 @@
 %}
 
 // Load Short (16 bit signed) to Byte (8 bit signed)
-instruct loadS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
+instruct loadS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
   match(Set dst (RShiftI (LShiftI (LoadS mem) twentyfour) twentyfour));
 
   ins_cost(125);
@@ -5953,7 +5952,7 @@
 %}
 
 // Load Unsigned Short/Char (16bit unsigned)
-instruct loadUS(eRegI dst, memory mem) %{
+instruct loadUS(rRegI dst, memory mem) %{
   match(Set dst (LoadUS mem));
 
   ins_cost(125);
@@ -5967,7 +5966,7 @@
 %}
 
 // Load Unsigned Short/Char (16 bit UNsigned) to Byte (8 bit signed)
-instruct loadUS2B(eRegI dst, memory mem, immI_24 twentyfour) %{
+instruct loadUS2B(rRegI dst, memory mem, immI_24 twentyfour) %{
   match(Set dst (RShiftI (LShiftI (LoadUS mem) twentyfour) twentyfour));
 
   ins_cost(125);
@@ -6028,7 +6027,7 @@
 %}
 
 // Load Integer
-instruct loadI(eRegI dst, memory mem) %{
+instruct loadI(rRegI dst, memory mem) %{
   match(Set dst (LoadI mem));
 
   ins_cost(125);
@@ -6042,7 +6041,7 @@
 %}
 
 // Load Integer (32 bit signed) to Byte (8 bit signed)
-instruct loadI2B(eRegI dst, memory mem, immI_24 twentyfour) %{
+instruct loadI2B(rRegI dst, memory mem, immI_24 twentyfour) %{
   match(Set dst (RShiftI (LShiftI (LoadI mem) twentyfour) twentyfour));
 
   ins_cost(125);
@@ -6054,7 +6053,7 @@
 %}
 
 // Load Integer (32 bit signed) to Unsigned Byte (8 bit UNsigned)
-instruct loadI2UB(eRegI dst, memory mem, immI_255 mask) %{
+instruct loadI2UB(rRegI dst, memory mem, immI_255 mask) %{
   match(Set dst (AndI (LoadI mem) mask));
 
   ins_cost(125);
@@ -6066,7 +6065,7 @@
 %}
 
 // Load Integer (32 bit signed) to Short (16 bit signed)
-instruct loadI2S(eRegI dst, memory mem, immI_16 sixteen) %{
+instruct loadI2S(rRegI dst, memory mem, immI_16 sixteen) %{
   match(Set dst (RShiftI (LShiftI (LoadI mem) sixteen) sixteen));
 
   ins_cost(125);
@@ -6078,7 +6077,7 @@
 %}
 
 // Load Integer (32 bit signed) to Unsigned Short/Char (16 bit UNsigned)
-instruct loadI2US(eRegI dst, memory mem, immI_65535 mask) %{
+instruct loadI2US(rRegI dst, memory mem, immI_65535 mask) %{
   match(Set dst (AndI (LoadI mem) mask));
 
   ins_cost(125);
@@ -6156,8 +6155,8 @@
 %}
 
 // Load Unsigned Integer into Long Register
-instruct loadUI2L(eRegL dst, memory mem, eFlagsReg cr) %{
-  match(Set dst (LoadUI2L mem));
+instruct loadUI2L(eRegL dst, memory mem, immL_32bits mask, eFlagsReg cr) %{
+  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
   effect(KILL cr);
 
   ins_cost(250);
@@ -6239,7 +6238,7 @@
 %}
 
 // Load Range
-instruct loadRange(eRegI dst, memory mem) %{
+instruct loadRange(rRegI dst, memory mem) %{
   match(Set dst (LoadRange mem));
 
   ins_cost(125);
@@ -6336,66 +6335,6 @@
   ins_pipe( fpu_reg_mem );
 %}
 
-// Load Aligned Packed Byte to XMM register
-instruct loadA8B(regD dst, memory mem) %{
-  predicate(UseSSE>=1);
-  match(Set dst (Load8B mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed8B" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Load Aligned Packed Short to XMM register
-instruct loadA4S(regD dst, memory mem) %{
-  predicate(UseSSE>=1);
-  match(Set dst (Load4S mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed4S" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Load Aligned Packed Char to XMM register
-instruct loadA4C(regD dst, memory mem) %{
-  predicate(UseSSE>=1);
-  match(Set dst (Load4C mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed4C" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Load Aligned Packed Integer to XMM register
-instruct load2IU(regD dst, memory mem) %{
-  predicate(UseSSE>=1);
-  match(Set dst (Load2I mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed2I" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Load Aligned Packed Single to XMM
-instruct loadA2F(regD dst, memory mem) %{
-  predicate(UseSSE>=1);
-  match(Set dst (Load2F mem));
-  ins_cost(145);
-  format %{ "MOVQ  $dst,$mem\t! packed2F" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 // Load Effective Address
 instruct leaP8(eRegP dst, indOffset8 mem) %{
   match(Set dst mem);
@@ -6448,7 +6387,7 @@
 %}
 
 // Load Constant
-instruct loadConI(eRegI dst, immI src) %{
+instruct loadConI(rRegI dst, immI src) %{
   match(Set dst src);
 
   format %{ "MOV    $dst,$src" %}
@@ -6457,7 +6396,7 @@
 %}
 
 // Load Constant zero
-instruct loadConI0(eRegI dst, immI0 src, eFlagsReg cr) %{
+instruct loadConI0(rRegI dst, immI0 src, eFlagsReg cr) %{
   match(Set dst src);
   effect(KILL cr);
 
@@ -6625,7 +6564,7 @@
 %}
 
 // Load Stack Slot
-instruct loadSSI(eRegI dst, stackSlotI src) %{
+instruct loadSSI(rRegI dst, stackSlotI src) %{
   match(Set dst src);
   ins_cost(125);
 
@@ -6852,7 +6791,7 @@
 %}
 
 // Store Char/Short
-instruct storeC(memory mem, eRegI src) %{
+instruct storeC(memory mem, rRegI src) %{
   match(Set mem (StoreC mem src));
 
   ins_cost(125);
@@ -6863,7 +6802,7 @@
 %}
 
 // Store Integer
-instruct storeI(memory mem, eRegI src) %{
+instruct storeI(memory mem, rRegI src) %{
   match(Set mem (StoreI mem src));
 
   ins_cost(125);
@@ -7007,42 +6946,6 @@
   ins_pipe( ialu_mem_imm );
 %}
 
-// Store Aligned Packed Byte XMM register to memory
-instruct storeA8B(memory mem, regD src) %{
-  predicate(UseSSE>=1);
-  match(Set mem (Store8B mem src));
-  ins_cost(145);
-  format %{ "MOVQ  $mem,$src\t! packed8B" %}
-  ins_encode %{
-    __ movq($mem$$Address, $src$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Store Aligned Packed Char/Short XMM register to memory
-instruct storeA4C(memory mem, regD src) %{
-  predicate(UseSSE>=1);
-  match(Set mem (Store4C mem src));
-  ins_cost(145);
-  format %{ "MOVQ  $mem,$src\t! packed4C" %}
-  ins_encode %{
-    __ movq($mem$$Address, $src$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Store Aligned Packed Integer XMM register to memory
-instruct storeA2I(memory mem, regD src) %{
-  predicate(UseSSE>=1);
-  match(Set mem (Store2I mem src));
-  ins_cost(145);
-  format %{ "MOVQ  $mem,$src\t! packed2I" %}
-  ins_encode %{
-    __ movq($mem$$Address, $src$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 // Store CMS card-mark Immediate
 instruct storeImmCM(memory mem, immI8 src) %{
   match(Set mem (StoreCM mem src));
@@ -7104,18 +7007,6 @@
   ins_pipe( pipe_slow );
 %}
 
-// Store Aligned Packed Single Float XMM register to memory
-instruct storeA2F(memory mem, regD src) %{
-  predicate(UseSSE>=1);
-  match(Set mem (Store2F mem src));
-  ins_cost(145);
-  format %{ "MOVQ  $mem,$src\t! packed2F" %}
-  ins_encode %{
-    __ movq($mem$$Address, $src$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 // Store Float
 instruct storeFPR( memory mem, regFPR1 src) %{
   predicate(UseSSE==0);
@@ -7177,7 +7068,7 @@
 %}
 
 // Store Integer to stack slot
-instruct storeSSI(stackSlotI dst, eRegI src) %{
+instruct storeSSI(stackSlotI dst, rRegI src) %{
   match(Set dst src);
 
   ins_cost(100);
@@ -7302,7 +7193,7 @@
   ins_pipe(empty);
 %}
 
-instruct castP2X(eRegI dst, eRegP src ) %{
+instruct castP2X(rRegI dst, eRegP src ) %{
   match(Set dst (CastP2X src));
   ins_cost(50);
   format %{ "MOV    $dst, $src\t# CastP2X" %}
@@ -7312,7 +7203,7 @@
 
 //----------Conditional Move---------------------------------------------------
 // Conditional move
-instruct jmovI_reg(cmpOp cop, eFlagsReg cr, eRegI dst, eRegI src) %{
+instruct jmovI_reg(cmpOp cop, eFlagsReg cr, rRegI dst, rRegI src) %{
   predicate(!VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7329,7 +7220,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct jmovI_regU(cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src) %{
+instruct jmovI_regU(cmpOpU cop, eFlagsRegU cr, rRegI dst, rRegI src) %{
   predicate(!VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7346,7 +7237,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovI_reg(eRegI dst, eRegI src, eFlagsReg cr, cmpOp cop ) %{
+instruct cmovI_reg(rRegI dst, rRegI src, eFlagsReg cr, cmpOp cop ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7356,7 +7247,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, eRegI dst, eRegI src ) %{
+instruct cmovI_regU( cmpOpU cop, eFlagsRegU cr, rRegI dst, rRegI src ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7366,7 +7257,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, eRegI src ) %{
+instruct cmovI_regUCF( cmpOpUCF cop, eFlagsRegUCF cr, rRegI dst, rRegI src ) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst src)));
   ins_cost(200);
@@ -7376,7 +7267,7 @@
 %}
 
 // Conditional move
-instruct cmovI_mem(cmpOp cop, eFlagsReg cr, eRegI dst, memory src) %{
+instruct cmovI_mem(cmpOp cop, eFlagsReg cr, rRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -7387,7 +7278,7 @@
 %}
 
 // Conditional move
-instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, eRegI dst, memory src) %{
+instruct cmovI_memU(cmpOpU cop, eFlagsRegU cr, rRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -7397,7 +7288,7 @@
   ins_pipe( pipe_cmov_mem );
 %}
 
-instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, eRegI dst, memory src) %{
+instruct cmovI_memUCF(cmpOpUCF cop, eFlagsRegUCF cr, rRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() );
   match(Set dst (CMoveI (Binary cop cr) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -7651,7 +7542,7 @@
 //----------Arithmetic Instructions--------------------------------------------
 //----------Addition Instructions----------------------------------------------
 // Integer Addition Instructions
-instruct addI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct addI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (AddI dst src));
   effect(KILL cr);
 
@@ -7662,7 +7553,7 @@
   ins_pipe( ialu_reg_reg );
 %}
 
-instruct addI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
+instruct addI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
   match(Set dst (AddI dst src));
   effect(KILL cr);
 
@@ -7672,7 +7563,7 @@
   ins_pipe( ialu_reg );
 %}
 
-instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
+instruct incI_eReg(rRegI dst, immI1 src, eFlagsReg cr) %{
   predicate(UseIncDec);
   match(Set dst (AddI dst src));
   effect(KILL cr);
@@ -7684,7 +7575,7 @@
   ins_pipe( ialu_reg );
 %}
 
-instruct leaI_eReg_immI(eRegI dst, eRegI src0, immI src1) %{
+instruct leaI_eReg_immI(rRegI dst, rRegI src0, immI src1) %{
   match(Set dst (AddI src0 src1));
   ins_cost(110);
 
@@ -7704,7 +7595,7 @@
   ins_pipe( ialu_reg_reg );
 %}
 
-instruct decI_eReg(eRegI dst, immI_M1 src, eFlagsReg cr) %{
+instruct decI_eReg(rRegI dst, immI_M1 src, eFlagsReg cr) %{
   predicate(UseIncDec);
   match(Set dst (AddI dst src));
   effect(KILL cr);
@@ -7716,7 +7607,7 @@
   ins_pipe( ialu_reg );
 %}
 
-instruct addP_eReg(eRegP dst, eRegI src, eFlagsReg cr) %{
+instruct addP_eReg(eRegP dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (AddP dst src));
   effect(KILL cr);
 
@@ -7738,7 +7629,7 @@
   ins_pipe( ialu_reg );
 %}
 
-instruct addI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
+instruct addI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
   match(Set dst (AddI dst (LoadI src)));
   effect(KILL cr);
 
@@ -7749,7 +7640,7 @@
   ins_pipe( ialu_reg_mem );
 %}
 
-instruct addI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
+instruct addI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (StoreI dst (AddI (LoadI dst) src)));
   effect(KILL cr);
 
@@ -7811,7 +7702,7 @@
   ins_pipe( empty );
 %}
 
-instruct castII( eRegI dst ) %{
+instruct castII( rRegI dst ) %{
   match(Set dst (CastII dst));
   format %{ "#castII of $dst" %}
   ins_encode( /*empty encoding*/ );
@@ -7831,50 +7722,6 @@
   ins_pipe( ialu_reg_mem );
 %}
 
-// LoadLong-locked - same as a volatile long load when used with compare-swap
-instruct loadLLocked(stackSlotL dst, memory mem) %{
-  predicate(UseSSE<=1);
-  match(Set dst (LoadLLocked mem));
-
-  ins_cost(200);
-  format %{ "FILD   $mem\t# Atomic volatile long load\n\t"
-            "FISTp  $dst" %}
-  ins_encode(enc_loadL_volatile(mem,dst));
-  ins_pipe( fpu_reg_mem );
-%}
-
-instruct loadLX_Locked(stackSlotL dst, memory mem, regD tmp) %{
-  predicate(UseSSE>=2);
-  match(Set dst (LoadLLocked mem));
-  effect(TEMP tmp);
-  ins_cost(180);
-  format %{ "MOVSD  $tmp,$mem\t# Atomic volatile long load\n\t"
-            "MOVSD  $dst,$tmp" %}
-  ins_encode %{
-    __ movdbl($tmp$$XMMRegister, $mem$$Address);
-    __ movdbl(Address(rsp, $dst$$disp), $tmp$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-instruct loadLX_reg_Locked(eRegL dst, memory mem, regD tmp) %{
-  predicate(UseSSE>=2);
-  match(Set dst (LoadLLocked mem));
-  effect(TEMP tmp);
-  ins_cost(160);
-  format %{ "MOVSD  $tmp,$mem\t# Atomic volatile long load\n\t"
-            "MOVD   $dst.lo,$tmp\n\t"
-            "PSRLQ  $tmp,32\n\t"
-            "MOVD   $dst.hi,$tmp" %}
-  ins_encode %{
-    __ movdbl($tmp$$XMMRegister, $mem$$Address);
-    __ movdl($dst$$Register, $tmp$$XMMRegister);
-    __ psrlq($tmp$$XMMRegister, 32);
-    __ movdl(HIGH_FROM_LOW($dst$$Register), $tmp$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 // Conditional-store of the updated heap-top.
 // Used during allocation of the shared heap.
 // Sets flags (EQ) on success.  Implemented with a CMPXCHG on Intel.
@@ -7889,7 +7736,7 @@
 
 // Conditional-store of an int value.
 // ZF flag is set on success, reset otherwise.  Implemented with a CMPXCHG on Intel.
-instruct storeIConditional( memory mem, eAXRegI oldval, eRegI newval, eFlagsReg cr ) %{
+instruct storeIConditional( memory mem, eAXRegI oldval, rRegI newval, eFlagsReg cr ) %{
   match(Set cr (StoreIConditional mem (Binary oldval newval)));
   effect(KILL oldval);
   format %{ "CMPXCHG $mem,$newval\t# If EAX==$mem Then store $newval into $mem" %}
@@ -7922,7 +7769,8 @@
 
 // No flag versions for CompareAndSwap{P,I,L} because matcher can't match them
 
-instruct compareAndSwapL( eRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
+instruct compareAndSwapL( rRegI res, eSIRegP mem_ptr, eADXRegL oldval, eBCXRegL newval, eFlagsReg cr ) %{
+  predicate(VM_Version::supports_cx8());
   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
   effect(KILL cr, KILL oldval);
   format %{ "CMPXCHG8 [$mem_ptr],$newval\t# If EDX:EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
@@ -7935,7 +7783,7 @@
   ins_pipe( pipe_cmpxchg );
 %}
 
-instruct compareAndSwapP( eRegI res,  pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
+instruct compareAndSwapP( rRegI res,  pRegP mem_ptr, eAXRegP oldval, eCXRegP newval, eFlagsReg cr) %{
   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
   effect(KILL cr, KILL oldval);
   format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
@@ -7947,7 +7795,48 @@
   ins_pipe( pipe_cmpxchg );
 %}
 
-instruct compareAndSwapI( eRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
+instruct xaddI_no_res( memory mem, Universe dummy, immI add, eFlagsReg cr) %{
+  predicate(n->as_LoadStore()->result_not_used());
+  match(Set dummy (GetAndAddI mem add));
+  effect(KILL cr);
+  format %{ "ADDL  [$mem],$add" %}
+  ins_encode %{
+    if (os::is_MP()) { __ lock(); }
+    __ addl($mem$$Address, $add$$constant);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xaddI( memory mem, rRegI newval, eFlagsReg cr) %{
+  match(Set newval (GetAndAddI mem newval));
+  effect(KILL cr);
+  format %{ "XADDL  [$mem],$newval" %}
+  ins_encode %{
+    if (os::is_MP()) { __ lock(); }
+    __ xaddl($mem$$Address, $newval$$Register);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xchgI( memory mem, rRegI newval) %{
+  match(Set newval (GetAndSetI mem newval));
+  format %{ "XCHGL  $newval,[$mem]" %}
+  ins_encode %{
+    __ xchgl($newval$$Register, $mem$$Address);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xchgP( memory mem, pRegP newval) %{
+  match(Set newval (GetAndSetP mem newval));
+  format %{ "XCHGL  $newval,[$mem]" %}
+  ins_encode %{
+    __ xchgl($newval$$Register, $mem$$Address);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct compareAndSwapI( rRegI res, pRegP mem_ptr, eAXRegI oldval, eCXRegI newval, eFlagsReg cr) %{
   match(Set res (CompareAndSwapI mem_ptr (Binary oldval newval)));
   effect(KILL cr, KILL oldval);
   format %{ "CMPXCHG [$mem_ptr],$newval\t# If EAX==[$mem_ptr] Then store $newval into [$mem_ptr]\n\t"
@@ -7961,7 +7850,7 @@
 
 //----------Subtraction Instructions-------------------------------------------
 // Integer Subtraction Instructions
-instruct subI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct subI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (SubI dst src));
   effect(KILL cr);
 
@@ -7972,7 +7861,7 @@
   ins_pipe( ialu_reg_reg );
 %}
 
-instruct subI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
+instruct subI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
   match(Set dst (SubI dst src));
   effect(KILL cr);
 
@@ -7983,7 +7872,7 @@
   ins_pipe( ialu_reg );
 %}
 
-instruct subI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
+instruct subI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
   match(Set dst (SubI dst (LoadI src)));
   effect(KILL cr);
 
@@ -7994,7 +7883,7 @@
   ins_pipe( ialu_reg_mem );
 %}
 
-instruct subI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
+instruct subI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (StoreI dst (SubI (LoadI dst) src)));
   effect(KILL cr);
 
@@ -8006,7 +7895,7 @@
 %}
 
 // Subtract from a pointer
-instruct subP_eReg(eRegP dst, eRegI src, immI0 zero, eFlagsReg cr) %{
+instruct subP_eReg(eRegP dst, rRegI src, immI0 zero, eFlagsReg cr) %{
   match(Set dst (AddP dst (SubI zero src)));
   effect(KILL cr);
 
@@ -8017,7 +7906,7 @@
   ins_pipe( ialu_reg_reg );
 %}
 
-instruct negI_eReg(eRegI dst, immI0 zero, eFlagsReg cr) %{
+instruct negI_eReg(rRegI dst, immI0 zero, eFlagsReg cr) %{
   match(Set dst (SubI zero dst));
   effect(KILL cr);
 
@@ -8032,7 +7921,7 @@
 //----------Multiplication/Division Instructions-------------------------------
 // Integer Multiplication Instructions
 // Multiply Register
-instruct mulI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct mulI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (MulI dst src));
   effect(KILL cr);
 
@@ -8045,7 +7934,7 @@
 %}
 
 // Multiply 32-bit Immediate
-instruct mulI_eReg_imm(eRegI dst, eRegI src, immI imm, eFlagsReg cr) %{
+instruct mulI_eReg_imm(rRegI dst, rRegI src, immI imm, eFlagsReg cr) %{
   match(Set dst (MulI src imm));
   effect(KILL cr);
 
@@ -8101,7 +7990,7 @@
 %}
 
 // Multiply Memory 32-bit Immediate
-instruct mulI_mem_imm(eRegI dst, memory src, immI imm, eFlagsReg cr) %{
+instruct mulI_mem_imm(rRegI dst, memory src, immI imm, eFlagsReg cr) %{
   match(Set dst (MulI (LoadI src) imm));
   effect(KILL cr);
 
@@ -8113,7 +8002,7 @@
 %}
 
 // Multiply Memory
-instruct mulI(eRegI dst, memory src, eFlagsReg cr) %{
+instruct mulI(rRegI dst, memory src, eFlagsReg cr) %{
   match(Set dst (MulI dst (LoadI src)));
   effect(KILL cr);
 
@@ -8150,7 +8039,7 @@
 %}
 
 // Multiply Register Long
-instruct mulL_eReg(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
+instruct mulL_eReg(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{
   match(Set dst (MulL dst src));
   effect(KILL cr, TEMP tmp);
   ins_cost(4*100+3*400);
@@ -8168,7 +8057,7 @@
 %}
 
 // Multiply Register Long where the left operand's high 32 bits are zero
-instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
+instruct mulL_eReg_lhi0(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{
   predicate(is_operand_hi32_zero(n->in(1)));
   match(Set dst (MulL dst src));
   effect(KILL cr, TEMP tmp);
@@ -8189,7 +8078,7 @@
 %}
 
 // Multiply Register Long where the right operand's high 32 bits are zero
-instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, eRegI tmp, eFlagsReg cr) %{
+instruct mulL_eReg_rhi0(eADXRegL dst, eRegL src, rRegI tmp, eFlagsReg cr) %{
   predicate(is_operand_hi32_zero(n->in(2)));
   match(Set dst (MulL dst src));
   effect(KILL cr, TEMP tmp);
@@ -8225,7 +8114,7 @@
 %}
 
 // Multiply Register Long by small constant
-instruct mulL_eReg_con(eADXRegL dst, immL_127 src, eRegI tmp, eFlagsReg cr) %{
+instruct mulL_eReg_con(eADXRegL dst, immL_127 src, rRegI tmp, eFlagsReg cr) %{
   match(Set dst (MulL dst src));
   effect(KILL cr, TEMP tmp);
   ins_cost(2*100+2*400);
@@ -8323,7 +8212,7 @@
 %}
 
 // Divide Register Long (no special case since divisor != -1)
-instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{
+instruct divL_eReg_imm32( eADXRegL dst, immL32 imm, rRegI tmp, rRegI tmp2, eFlagsReg cr ) %{
   match(Set dst (DivL dst imm));
   effect( TEMP tmp, TEMP tmp2, KILL cr );
   ins_cost(1000);
@@ -8394,7 +8283,7 @@
 %}
 
 // Remainder Register Long (remainder fit into 32 bits)
-instruct modL_eReg_imm32( eADXRegL dst, immL32 imm, eRegI tmp, eRegI tmp2, eFlagsReg cr ) %{
+instruct modL_eReg_imm32( eADXRegL dst, immL32 imm, rRegI tmp, rRegI tmp2, eFlagsReg cr ) %{
   match(Set dst (ModL dst imm));
   effect( TEMP tmp, TEMP tmp2, KILL cr );
   ins_cost(1000);
@@ -8462,7 +8351,7 @@
 
 // Integer Shift Instructions
 // Shift Left by one
-instruct shlI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
+instruct shlI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{
   match(Set dst (LShiftI dst shift));
   effect(KILL cr);
 
@@ -8474,7 +8363,7 @@
 %}
 
 // Shift Left by 8-bit immediate
-instruct salI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
+instruct salI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{
   match(Set dst (LShiftI dst shift));
   effect(KILL cr);
 
@@ -8486,7 +8375,7 @@
 %}
 
 // Shift Left by variable
-instruct salI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
+instruct salI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{
   match(Set dst (LShiftI dst shift));
   effect(KILL cr);
 
@@ -8498,7 +8387,7 @@
 %}
 
 // Arithmetic shift right by one
-instruct sarI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
+instruct sarI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{
   match(Set dst (RShiftI dst shift));
   effect(KILL cr);
 
@@ -8520,7 +8409,7 @@
 %}
 
 // Arithmetic Shift Right by 8-bit immediate
-instruct sarI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
+instruct sarI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{
   match(Set dst (RShiftI dst shift));
   effect(KILL cr);
 
@@ -8543,7 +8432,7 @@
 %}
 
 // Arithmetic Shift Right by variable
-instruct sarI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
+instruct sarI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{
   match(Set dst (RShiftI dst shift));
   effect(KILL cr);
 
@@ -8555,7 +8444,7 @@
 %}
 
 // Logical shift right by one
-instruct shrI_eReg_1(eRegI dst, immI1 shift, eFlagsReg cr) %{
+instruct shrI_eReg_1(rRegI dst, immI1 shift, eFlagsReg cr) %{
   match(Set dst (URShiftI dst shift));
   effect(KILL cr);
 
@@ -8567,7 +8456,7 @@
 %}
 
 // Logical Shift Right by 8-bit immediate
-instruct shrI_eReg_imm(eRegI dst, immI8 shift, eFlagsReg cr) %{
+instruct shrI_eReg_imm(rRegI dst, immI8 shift, eFlagsReg cr) %{
   match(Set dst (URShiftI dst shift));
   effect(KILL cr);
 
@@ -8581,7 +8470,7 @@
 
 // Logical Shift Right by 24, followed by Arithmetic Shift Left by 24.
 // This idiom is used by the compiler for the i2b bytecode.
-instruct i2b(eRegI dst, xRegI src, immI_24 twentyfour) %{
+instruct i2b(rRegI dst, xRegI src, immI_24 twentyfour) %{
   match(Set dst (RShiftI (LShiftI src twentyfour) twentyfour));
 
   size(3);
@@ -8594,7 +8483,7 @@
 
 // Logical Shift Right by 16, followed by Arithmetic Shift Left by 16.
 // This idiom is used by the compiler the i2s bytecode.
-instruct i2s(eRegI dst, xRegI src, immI_16 sixteen) %{
+instruct i2s(rRegI dst, xRegI src, immI_16 sixteen) %{
   match(Set dst (RShiftI (LShiftI src sixteen) sixteen));
 
   size(3);
@@ -8607,7 +8496,7 @@
 
 
 // Logical Shift Right by variable
-instruct shrI_eReg_CL(eRegI dst, eCXRegI shift, eFlagsReg cr) %{
+instruct shrI_eReg_CL(rRegI dst, eCXRegI shift, eFlagsReg cr) %{
   match(Set dst (URShiftI dst shift));
   effect(KILL cr);
 
@@ -8623,7 +8512,7 @@
 //----------Integer Logical Instructions---------------------------------------
 // And Instructions
 // And Register with Register
-instruct andI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct andI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (AndI dst src));
   effect(KILL cr);
 
@@ -8635,7 +8524,7 @@
 %}
 
 // And Register with Immediate
-instruct andI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
+instruct andI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
   match(Set dst (AndI dst src));
   effect(KILL cr);
 
@@ -8647,7 +8536,7 @@
 %}
 
 // And Register with Memory
-instruct andI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
+instruct andI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
   match(Set dst (AndI dst (LoadI src)));
   effect(KILL cr);
 
@@ -8659,7 +8548,7 @@
 %}
 
 // And Memory with Register
-instruct andI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
+instruct andI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (StoreI dst (AndI (LoadI dst) src)));
   effect(KILL cr);
 
@@ -8685,7 +8574,7 @@
 
 // Or Instructions
 // Or Register with Register
-instruct orI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct orI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (OrI dst src));
   effect(KILL cr);
 
@@ -8696,7 +8585,7 @@
   ins_pipe( ialu_reg_reg );
 %}
 
-instruct orI_eReg_castP2X(eRegI dst, eRegP src, eFlagsReg cr) %{
+instruct orI_eReg_castP2X(rRegI dst, eRegP src, eFlagsReg cr) %{
   match(Set dst (OrI dst (CastP2X src)));
   effect(KILL cr);
 
@@ -8709,7 +8598,7 @@
 
 
 // Or Register with Immediate
-instruct orI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
+instruct orI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
   match(Set dst (OrI dst src));
   effect(KILL cr);
 
@@ -8721,7 +8610,7 @@
 %}
 
 // Or Register with Memory
-instruct orI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
+instruct orI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
   match(Set dst (OrI dst (LoadI src)));
   effect(KILL cr);
 
@@ -8733,7 +8622,7 @@
 %}
 
 // Or Memory with Register
-instruct orI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
+instruct orI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (StoreI dst (OrI (LoadI dst) src)));
   effect(KILL cr);
 
@@ -8759,7 +8648,7 @@
 
 // ROL/ROR
 // ROL expand
-instruct rolI_eReg_imm1(eRegI dst, immI1 shift, eFlagsReg cr) %{
+instruct rolI_eReg_imm1(rRegI dst, immI1 shift, eFlagsReg cr) %{
   effect(USE_DEF dst, USE shift, KILL cr);
 
   format %{ "ROL    $dst, $shift" %}
@@ -8768,7 +8657,7 @@
   ins_pipe( ialu_reg );
 %}
 
-instruct rolI_eReg_imm8(eRegI dst, immI8 shift, eFlagsReg cr) %{
+instruct rolI_eReg_imm8(rRegI dst, immI8 shift, eFlagsReg cr) %{
   effect(USE_DEF dst, USE shift, KILL cr);
 
   format %{ "ROL    $dst, $shift" %}
@@ -8788,7 +8677,7 @@
 // end of ROL expand
 
 // ROL 32bit by one once
-instruct rolI_eReg_i1(eRegI dst, immI1 lshift, immI_M1 rshift, eFlagsReg cr) %{
+instruct rolI_eReg_i1(rRegI dst, immI1 lshift, immI_M1 rshift, eFlagsReg cr) %{
   match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift)));
 
   expand %{
@@ -8797,7 +8686,7 @@
 %}
 
 // ROL 32bit var by imm8 once
-instruct rolI_eReg_i8(eRegI dst, immI8 lshift, immI8 rshift, eFlagsReg cr) %{
+instruct rolI_eReg_i8(rRegI dst, immI8 lshift, immI8 rshift, eFlagsReg cr) %{
   predicate(  0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
   match(Set dst ( OrI (LShiftI dst lshift) (URShiftI dst rshift)));
 
@@ -8825,7 +8714,7 @@
 %}
 
 // ROR expand
-instruct rorI_eReg_imm1(eRegI dst, immI1 shift, eFlagsReg cr) %{
+instruct rorI_eReg_imm1(rRegI dst, immI1 shift, eFlagsReg cr) %{
   effect(USE_DEF dst, USE shift, KILL cr);
 
   format %{ "ROR    $dst, $shift" %}
@@ -8834,7 +8723,7 @@
   ins_pipe( ialu_reg );
 %}
 
-instruct rorI_eReg_imm8(eRegI dst, immI8 shift, eFlagsReg cr) %{
+instruct rorI_eReg_imm8(rRegI dst, immI8 shift, eFlagsReg cr) %{
   effect (USE_DEF dst, USE shift, KILL cr);
 
   format %{ "ROR    $dst, $shift" %}
@@ -8854,7 +8743,7 @@
 // end of ROR expand
 
 // ROR right once
-instruct rorI_eReg_i1(eRegI dst, immI1 rshift, immI_M1 lshift, eFlagsReg cr) %{
+instruct rorI_eReg_i1(rRegI dst, immI1 rshift, immI_M1 lshift, eFlagsReg cr) %{
   match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift)));
 
   expand %{
@@ -8863,7 +8752,7 @@
 %}
 
 // ROR 32bit by immI8 once
-instruct rorI_eReg_i8(eRegI dst, immI8 rshift, immI8 lshift, eFlagsReg cr) %{
+instruct rorI_eReg_i8(rRegI dst, immI8 rshift, immI8 lshift, eFlagsReg cr) %{
   predicate(  0 == ((n->in(1)->in(2)->get_int() + n->in(2)->in(2)->get_int()) & 0x1f));
   match(Set dst ( OrI (URShiftI dst rshift) (LShiftI dst lshift)));
 
@@ -8892,7 +8781,7 @@
 
 // Xor Instructions
 // Xor Register with Register
-instruct xorI_eReg(eRegI dst, eRegI src, eFlagsReg cr) %{
+instruct xorI_eReg(rRegI dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (XorI dst src));
   effect(KILL cr);
 
@@ -8904,7 +8793,7 @@
 %}
 
 // Xor Register with Immediate -1
-instruct xorI_eReg_im1(eRegI dst, immI_M1 imm) %{
+instruct xorI_eReg_im1(rRegI dst, immI_M1 imm) %{
   match(Set dst (XorI dst imm));  
 
   size(2);
@@ -8916,7 +8805,7 @@
 %}
 
 // Xor Register with Immediate
-instruct xorI_eReg_imm(eRegI dst, immI src, eFlagsReg cr) %{
+instruct xorI_eReg_imm(rRegI dst, immI src, eFlagsReg cr) %{
   match(Set dst (XorI dst src));
   effect(KILL cr);
 
@@ -8928,7 +8817,7 @@
 %}
 
 // Xor Register with Memory
-instruct xorI_eReg_mem(eRegI dst, memory src, eFlagsReg cr) %{
+instruct xorI_eReg_mem(rRegI dst, memory src, eFlagsReg cr) %{
   match(Set dst (XorI dst (LoadI src)));
   effect(KILL cr);
 
@@ -8940,7 +8829,7 @@
 %}
 
 // Xor Memory with Register
-instruct xorI_mem_eReg(memory dst, eRegI src, eFlagsReg cr) %{
+instruct xorI_mem_eReg(memory dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (StoreI dst (XorI (LoadI dst) src)));
   effect(KILL cr);
 
@@ -8965,14 +8854,14 @@
 
 //----------Convert Int to Boolean---------------------------------------------
 
-instruct movI_nocopy(eRegI dst, eRegI src) %{
+instruct movI_nocopy(rRegI dst, rRegI src) %{
   effect( DEF dst, USE src );
   format %{ "MOV    $dst,$src" %}
   ins_encode( enc_Copy( dst, src) );
   ins_pipe( ialu_reg_reg );
 %}
 
-instruct ci2b( eRegI dst, eRegI src, eFlagsReg cr ) %{
+instruct ci2b( rRegI dst, rRegI src, eFlagsReg cr ) %{
   effect( USE_DEF dst, USE src, KILL cr );
 
   size(4);
@@ -8983,7 +8872,7 @@
   ins_pipe( ialu_reg_reg_long );
 %}
 
-instruct convI2B( eRegI dst, eRegI src, eFlagsReg cr ) %{
+instruct convI2B( rRegI dst, rRegI src, eFlagsReg cr ) %{
   match(Set dst (Conv2B src));
 
   expand %{
@@ -8992,14 +8881,14 @@
   %}
 %}
 
-instruct movP_nocopy(eRegI dst, eRegP src) %{
+instruct movP_nocopy(rRegI dst, eRegP src) %{
   effect( DEF dst, USE src );
   format %{ "MOV    $dst,$src" %}
   ins_encode( enc_Copy( dst, src) );
   ins_pipe( ialu_reg_reg );
 %}
 
-instruct cp2b( eRegI dst, eRegP src, eFlagsReg cr ) %{
+instruct cp2b( rRegI dst, eRegP src, eFlagsReg cr ) %{
   effect( USE_DEF dst, USE src, KILL cr );
   format %{ "NEG    $dst\n\t"
             "ADC    $dst,$src" %}
@@ -9008,7 +8897,7 @@
   ins_pipe( ialu_reg_reg_long );
 %}
 
-instruct convP2B( eRegI dst, eRegP src, eFlagsReg cr ) %{
+instruct convP2B( rRegI dst, eRegP src, eFlagsReg cr ) %{
   match(Set dst (Conv2B src));
 
   expand %{
@@ -9033,7 +8922,7 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct cmpLTMask0( eRegI dst, immI0 zero, eFlagsReg cr ) %{
+instruct cmpLTMask0( rRegI dst, immI0 zero, eFlagsReg cr ) %{
   match(Set dst (CmpLTMask dst zero));
   effect( DEF dst, KILL cr );
   ins_cost(100);
@@ -9505,7 +9394,7 @@
 %}
 
 // Compare vs zero into -1,0,1
-instruct cmpDPR_0(eRegI dst, regDPR src1, immDPR0 zero, eAXRegI rax, eFlagsReg cr) %{
+instruct cmpDPR_0(rRegI dst, regDPR src1, immDPR0 zero, eAXRegI rax, eFlagsReg cr) %{
   predicate(UseSSE<=1);
   match(Set dst (CmpD3 src1 zero));
   effect(KILL cr, KILL rax);
@@ -9519,7 +9408,7 @@
 %}
 
 // Compare into -1,0,1
-instruct cmpDPR_reg(eRegI dst, regDPR src1, regDPR src2, eAXRegI rax, eFlagsReg cr) %{
+instruct cmpDPR_reg(rRegI dst, regDPR src1, regDPR src2, eAXRegI rax, eFlagsReg cr) %{
   predicate(UseSSE<=1);
   match(Set dst (CmpD3 src1 src2));
   effect(KILL cr, KILL rax);
@@ -10096,162 +9985,68 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct powDPR_reg(regDPR X, regDPR1 Y, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
+instruct powDPR_reg(regDPR X, regDPR1 Y, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{
   predicate (UseSSE<=1);
   match(Set Y (PowD X Y));  // Raise X to the Yth power
-  effect(KILL rax, KILL rbx, KILL rcx);
-  format %{ "SUB    ESP,8\t\t# Fast-path POW encoding\n\t"
-            "FLD_D  $X\n\t"
-            "FYL2X  \t\t\t# Q=Y*ln2(X)\n\t"
-
-            "FDUP   \t\t\t# Q Q\n\t"
-            "FRNDINT\t\t\t# int(Q) Q\n\t"
-            "FSUB   ST(1),ST(0)\t# int(Q) frac(Q)\n\t"
-            "FISTP  dword [ESP]\n\t"
-            "F2XM1  \t\t\t# 2^frac(Q)-1 int(Q)\n\t"
-            "FLD1   \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t"
-            "FADDP  \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead
-            "MOV    EAX,[ESP]\t# Pick up int(Q)\n\t"
-            "MOV    ECX,0xFFFFF800\t# Overflow mask\n\t"
-            "ADD    EAX,1023\t\t# Double exponent bias\n\t"
-            "MOV    EBX,EAX\t\t# Preshifted biased expo\n\t"
-            "SHL    EAX,20\t\t# Shift exponent into place\n\t"
-            "TEST   EBX,ECX\t\t# Check for overflow\n\t"
-            "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t"
-            "MOV    [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t"
-            "MOV    [ESP+0],0\n\t"
-            "FMUL   ST(0),[ESP+0]\t# Scale\n\t"
-
-            "ADD    ESP,8"
-             %}
-  ins_encode( push_stack_temp_qword,
-              Push_Reg_DPR(X),
-              Opcode(0xD9), Opcode(0xF1),   // fyl2x
-              pow_exp_core_encoding,
-              pop_stack_temp_qword);
+  effect(KILL rax, KILL rdx, KILL rcx, KILL cr);
+  format %{ "fast_pow $X $Y -> $Y  // KILL $rax, $rcx, $rdx" %}
+  ins_encode %{
+    __ subptr(rsp, 8);
+    __ fld_s($X$$reg - 1);
+    __ fast_pow();
+    __ addptr(rsp, 8);
+  %}
   ins_pipe( pipe_slow );
 %}
 
-instruct powD_reg(regD dst, regD src0, regD src1, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx ) %{
+instruct powD_reg(regD dst, regD src0, regD src1, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{
   predicate (UseSSE>=2);
   match(Set dst (PowD src0 src1));  // Raise src0 to the src1'th power
-  effect(KILL tmp1, KILL rax, KILL rbx, KILL rcx );
-  format %{ "SUB    ESP,8\t\t# Fast-path POW encoding\n\t"
-            "MOVSD  [ESP],$src1\n\t"
-            "FLD    FPR1,$src1\n\t"
-            "MOVSD  [ESP],$src0\n\t"
-            "FLD    FPR1,$src0\n\t"
-            "FYL2X  \t\t\t# Q=Y*ln2(X)\n\t"
-
-            "FDUP   \t\t\t# Q Q\n\t"
-            "FRNDINT\t\t\t# int(Q) Q\n\t"
-            "FSUB   ST(1),ST(0)\t# int(Q) frac(Q)\n\t"
-            "FISTP  dword [ESP]\n\t"
-            "F2XM1  \t\t\t# 2^frac(Q)-1 int(Q)\n\t"
-            "FLD1   \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t"
-            "FADDP  \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead
-            "MOV    EAX,[ESP]\t# Pick up int(Q)\n\t"
-            "MOV    ECX,0xFFFFF800\t# Overflow mask\n\t"
-            "ADD    EAX,1023\t\t# Double exponent bias\n\t"
-            "MOV    EBX,EAX\t\t# Preshifted biased expo\n\t"
-            "SHL    EAX,20\t\t# Shift exponent into place\n\t"
-            "TEST   EBX,ECX\t\t# Check for overflow\n\t"
-            "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t"
-            "MOV    [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t"
-            "MOV    [ESP+0],0\n\t"
-            "FMUL   ST(0),[ESP+0]\t# Scale\n\t"
-
-            "FST_D  [ESP]\n\t"
-            "MOVSD  $dst,[ESP]\n\t"
-            "ADD    ESP,8"
-             %}
-  ins_encode( push_stack_temp_qword,
-              push_xmm_to_fpr1(src1),
-              push_xmm_to_fpr1(src0),
-              Opcode(0xD9), Opcode(0xF1),   // fyl2x
-              pow_exp_core_encoding,
-              Push_ResultD(dst) );
+  effect(KILL rax, KILL rdx, KILL rcx, KILL cr);
+  format %{ "fast_pow $src0 $src1 -> $dst  // KILL $rax, $rcx, $rdx" %}
+  ins_encode %{
+    __ subptr(rsp, 8);
+    __ movdbl(Address(rsp, 0), $src1$$XMMRegister);
+    __ fld_d(Address(rsp, 0));
+    __ movdbl(Address(rsp, 0), $src0$$XMMRegister);
+    __ fld_d(Address(rsp, 0));
+    __ fast_pow();
+    __ fstp_d(Address(rsp, 0));
+    __ movdbl($dst$$XMMRegister, Address(rsp, 0));
+    __ addptr(rsp, 8);
+  %}
   ins_pipe( pipe_slow );
 %}
 
 
-instruct expDPR_reg(regDPR1 dpr1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
+instruct expDPR_reg(regDPR1 dpr1, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{
   predicate (UseSSE<=1);
   match(Set dpr1 (ExpD dpr1));
-  effect(KILL rax, KILL rbx, KILL rcx);
-  format %{ "SUB    ESP,8\t\t# Fast-path EXP encoding"
-            "FLDL2E \t\t\t# Ld log2(e) X\n\t"
-            "FMULP  \t\t\t# Q=X*log2(e)\n\t"
-
-            "FDUP   \t\t\t# Q Q\n\t"
-            "FRNDINT\t\t\t# int(Q) Q\n\t"
-            "FSUB   ST(1),ST(0)\t# int(Q) frac(Q)\n\t"
-            "FISTP  dword [ESP]\n\t"
-            "F2XM1  \t\t\t# 2^frac(Q)-1 int(Q)\n\t"
-            "FLD1   \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t"
-            "FADDP  \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead
-            "MOV    EAX,[ESP]\t# Pick up int(Q)\n\t"
-            "MOV    ECX,0xFFFFF800\t# Overflow mask\n\t"
-            "ADD    EAX,1023\t\t# Double exponent bias\n\t"
-            "MOV    EBX,EAX\t\t# Preshifted biased expo\n\t"
-            "SHL    EAX,20\t\t# Shift exponent into place\n\t"
-            "TEST   EBX,ECX\t\t# Check for overflow\n\t"
-            "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t"
-            "MOV    [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t"
-            "MOV    [ESP+0],0\n\t"
-            "FMUL   ST(0),[ESP+0]\t# Scale\n\t"
-
-            "ADD    ESP,8"
-             %}
-  ins_encode( push_stack_temp_qword,
-              Opcode(0xD9), Opcode(0xEA),   // fldl2e
-              Opcode(0xDE), Opcode(0xC9),   // fmulp
-              pow_exp_core_encoding,
-              pop_stack_temp_qword);
+  effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
+  format %{ "fast_exp $dpr1 -> $dpr1  // KILL $rax, $rcx, $rdx" %}
+  ins_encode %{
+    __ fast_exp();
+  %}
   ins_pipe( pipe_slow );
 %}
 
-instruct expD_reg(regD dst, regD src, regDPR1 tmp1, eAXRegI rax, eBXRegI rbx, eCXRegI rcx) %{
+instruct expD_reg(regD dst, regD src, eAXRegI rax, eDXRegI rdx, eCXRegI rcx, eFlagsReg cr) %{
   predicate (UseSSE>=2);
   match(Set dst (ExpD src));
-  effect(KILL tmp1, KILL rax, KILL rbx, KILL rcx);
-  format %{ "SUB    ESP,8\t\t# Fast-path EXP encoding\n\t"
-            "MOVSD  [ESP],$src\n\t"
-            "FLDL2E \t\t\t# Ld log2(e) X\n\t"
-            "FMULP  \t\t\t# Q=X*log2(e) X\n\t"
-
-            "FDUP   \t\t\t# Q Q\n\t"
-            "FRNDINT\t\t\t# int(Q) Q\n\t"
-            "FSUB   ST(1),ST(0)\t# int(Q) frac(Q)\n\t"
-            "FISTP  dword [ESP]\n\t"
-            "F2XM1  \t\t\t# 2^frac(Q)-1 int(Q)\n\t"
-            "FLD1   \t\t\t# 1 2^frac(Q)-1 int(Q)\n\t"
-            "FADDP  \t\t\t# 2^frac(Q) int(Q)\n\t" // could use FADD [1.000] instead
-            "MOV    EAX,[ESP]\t# Pick up int(Q)\n\t"
-            "MOV    ECX,0xFFFFF800\t# Overflow mask\n\t"
-            "ADD    EAX,1023\t\t# Double exponent bias\n\t"
-            "MOV    EBX,EAX\t\t# Preshifted biased expo\n\t"
-            "SHL    EAX,20\t\t# Shift exponent into place\n\t"
-            "TEST   EBX,ECX\t\t# Check for overflow\n\t"
-            "CMOVne EAX,ECX\t\t# If overflow, stuff NaN into EAX\n\t"
-            "MOV    [ESP+4],EAX\t# Marshal 64-bit scaling double\n\t"
-            "MOV    [ESP+0],0\n\t"
-            "FMUL   ST(0),[ESP+0]\t# Scale\n\t"
-
-            "FST_D  [ESP]\n\t"
-            "MOVSD  $dst,[ESP]\n\t"
-            "ADD    ESP,8"
-             %}
-  ins_encode( Push_SrcD(src),
-              Opcode(0xD9), Opcode(0xEA),   // fldl2e
-              Opcode(0xDE), Opcode(0xC9),   // fmulp
-              pow_exp_core_encoding,
-              Push_ResultD(dst) );
+  effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
+  format %{ "fast_exp $dst -> $src  // KILL $rax, $rcx, $rdx" %}
+  ins_encode %{
+    __ subptr(rsp, 8);
+    __ movdbl(Address(rsp, 0), $src$$XMMRegister);
+    __ fld_d(Address(rsp, 0));
+    __ fast_exp();
+    __ fstp_d(Address(rsp, 0));
+    __ movdbl($dst$$XMMRegister, Address(rsp, 0));
+    __ addptr(rsp, 8);
+  %}
   ins_pipe( pipe_slow );
 %}
 
-
-
 instruct log10DPR_reg(regDPR1 dst, regDPR1 src) %{
   predicate (UseSSE<=1);
   // The source Double operand on FPU stack
@@ -10391,7 +10186,7 @@
 %}
 
 // Compare vs zero into -1,0,1
-instruct cmpFPR_0(eRegI dst, regFPR src1, immFPR0 zero, eAXRegI rax, eFlagsReg cr) %{
+instruct cmpFPR_0(rRegI dst, regFPR src1, immFPR0 zero, eAXRegI rax, eFlagsReg cr) %{
   predicate(UseSSE == 0);
   match(Set dst (CmpF3 src1 zero));
   effect(KILL cr, KILL rax);
@@ -10405,7 +10200,7 @@
 %}
 
 // Compare into -1,0,1
-instruct cmpFPR_reg(eRegI dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{
+instruct cmpFPR_reg(rRegI dst, regFPR src1, regFPR src2, eAXRegI rax, eFlagsReg cr) %{
   predicate(UseSSE == 0);
   match(Set dst (CmpF3 src1 src2));
   effect(KILL cr, KILL rax);
@@ -11325,7 +11120,7 @@
   ins_pipe( fpu_reg_mem );
 %}
 
-instruct convI2D_reg(regD dst, eRegI src) %{
+instruct convI2D_reg(regD dst, rRegI src) %{
   predicate( UseSSE>=2 && !UseXmmI2D );
   match(Set dst (ConvI2D src));
   format %{ "CVTSI2SD $dst,$src" %}
@@ -11345,7 +11140,7 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct convXI2D_reg(regD dst, eRegI src)
+instruct convXI2D_reg(regD dst, rRegI src)
 %{
   predicate( UseSSE>=2 && UseXmmI2D );
   match(Set dst (ConvI2D src));
@@ -11433,7 +11228,7 @@
 %}
 
 // Convert an int to a float in xmm; no rounding step needed.
-instruct convI2F_reg(regF dst, eRegI src) %{
+instruct convI2F_reg(regF dst, rRegI src) %{
   predicate( UseSSE==1 || UseSSE>=2 && !UseXmmI2F );
   match(Set dst (ConvI2F src));
   format %{ "CVTSI2SS $dst, $src" %}
@@ -11443,7 +11238,7 @@
   ins_pipe( pipe_slow );
 %}
 
- instruct convXI2F_reg(regF dst, eRegI src)
+ instruct convXI2F_reg(regF dst, rRegI src)
 %{
   predicate( UseSSE>=2 && UseXmmI2F );
   match(Set dst (ConvI2F src));
@@ -11457,7 +11252,7 @@
   ins_pipe(pipe_slow); // XXX
 %}
 
-instruct convI2L_reg( eRegL dst, eRegI src, eFlagsReg cr) %{
+instruct convI2L_reg( eRegL dst, rRegI src, eFlagsReg cr) %{
   match(Set dst (ConvI2L src));
   effect(KILL cr);
   ins_cost(375);
@@ -11469,7 +11264,7 @@
 %}
 
 // Zero-extend convert int to long
-instruct convI2L_reg_zex(eRegL dst, eRegI src, immL_32bits mask, eFlagsReg flags ) %{
+instruct convI2L_reg_zex(eRegL dst, rRegI src, immL_32bits mask, eFlagsReg flags ) %{
   match(Set dst (AndL (ConvI2L src) mask) );
   effect( KILL flags );
   ins_cost(250);
@@ -11549,7 +11344,7 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct convL2I_reg( eRegI dst, eRegL src ) %{
+instruct convL2I_reg( rRegI dst, eRegL src ) %{
   match(Set dst (ConvL2I src));
   effect( DEF dst, USE src );
   format %{ "MOV    $dst,$src.lo" %}
@@ -11558,7 +11353,7 @@
 %}
 
 
-instruct MoveF2I_stack_reg(eRegI dst, stackSlotF src) %{
+instruct MoveF2I_stack_reg(rRegI dst, stackSlotF src) %{
   match(Set dst (MoveF2I src));
   effect( DEF dst, USE src );
   ins_cost(100);
@@ -11593,7 +11388,7 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct MoveF2I_reg_reg_sse(eRegI dst, regF src) %{
+instruct MoveF2I_reg_reg_sse(rRegI dst, regF src) %{
   predicate(UseSSE>=2);
   match(Set dst (MoveF2I src));
   effect( DEF dst, USE src );
@@ -11605,7 +11400,7 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct MoveI2F_reg_stack(stackSlotF dst, eRegI src) %{
+instruct MoveI2F_reg_stack(stackSlotF dst, rRegI src) %{
   match(Set dst (MoveI2F src));
   effect( DEF dst, USE src );
 
@@ -11645,7 +11440,7 @@
   ins_pipe( pipe_slow );
 %}
 
-instruct MoveI2F_reg_reg_sse(regF dst, eRegI src) %{
+instruct MoveI2F_reg_reg_sse(regF dst, rRegI src) %{
   predicate(UseSSE>=2);
   match(Set dst (MoveI2F src));
   effect( DEF dst, USE src );
@@ -11779,186 +11574,6 @@
   ins_pipe( pipe_slow );
 %}
 
-// Replicate scalar to packed byte (1 byte) values in xmm
-instruct Repl8B_reg(regD dst, regD src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate8B src));
-  format %{ "MOVDQA  $dst,$src\n\t"
-            "PUNPCKLBW $dst,$dst\n\t"
-            "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
-  ins_encode %{
-    if ($dst$$reg != $src$$reg) {
-      __ movdqa($dst$$XMMRegister, $src$$XMMRegister);
-    }
-    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Replicate scalar to packed byte (1 byte) values in xmm
-instruct Repl8B_eRegI(regD dst, eRegI src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate8B src));
-  format %{ "MOVD    $dst,$src\n\t"
-            "PUNPCKLBW $dst,$dst\n\t"
-            "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
-  ins_encode %{
-    __ movdl($dst$$XMMRegister, $src$$Register);
-    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Replicate scalar zero to packed byte (1 byte) values in xmm
-instruct Repl8B_immI0(regD dst, immI0 zero) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate8B zero));
-  format %{ "PXOR  $dst,$dst\t! replicate8B" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed shore (2 byte) values in xmm
-instruct Repl4S_reg(regD dst, regD src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate4S src));
-  format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
-  ins_encode %{
-    __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed shore (2 byte) values in xmm
-instruct Repl4S_eRegI(regD dst, eRegI src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate4S src));
-  format %{ "MOVD    $dst,$src\n\t"
-            "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
-  ins_encode %{
-    __ movdl($dst$$XMMRegister, $src$$Register);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar zero to packed short (2 byte) values in xmm
-instruct Repl4S_immI0(regD dst, immI0 zero) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate4S zero));
-  format %{ "PXOR  $dst,$dst\t! replicate4S" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed char (2 byte) values in xmm
-instruct Repl4C_reg(regD dst, regD src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate4C src));
-  format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
-  ins_encode %{
-    __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed char (2 byte) values in xmm
-instruct Repl4C_eRegI(regD dst, eRegI src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate4C src));
-  format %{ "MOVD    $dst,$src\n\t"
-            "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
-  ins_encode %{
-    __ movdl($dst$$XMMRegister, $src$$Register);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar zero to packed char (2 byte) values in xmm
-instruct Repl4C_immI0(regD dst, immI0 zero) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate4C zero));
-  format %{ "PXOR  $dst,$dst\t! replicate4C" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed integer (4 byte) values in xmm
-instruct Repl2I_reg(regD dst, regD src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate2I src));
-  format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
-  ins_encode %{
-    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed integer (4 byte) values in xmm
-instruct Repl2I_eRegI(regD dst, eRegI src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate2I src));
-  format %{ "MOVD   $dst,$src\n\t"
-            "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
-  ins_encode %{
-    __ movdl($dst$$XMMRegister, $src$$Register);
-    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar zero to packed integer (2 byte) values in xmm
-instruct Repl2I_immI0(regD dst, immI0 zero) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate2I zero));
-  format %{ "PXOR  $dst,$dst\t! replicate2I" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed single precision floating point values in xmm
-instruct Repl2F_reg(regD dst, regD src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate2F src));
-  format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
-  ins_encode %{
-    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed single precision floating point values in xmm
-instruct Repl2F_regF(regD dst, regF src) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate2F src));
-  format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
-  ins_encode %{
-    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed single precision floating point values in xmm
-instruct Repl2F_immF0(regD dst, immF0 zero) %{
-  predicate(UseSSE>=2);
-  match(Set dst (Replicate2F zero));
-  format %{ "PXOR  $dst,$dst\t! replicate2F" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
 
 // =======================================================================
 // fast clearing of an array
@@ -12067,7 +11682,7 @@
 
 //----------Control Flow Instructions------------------------------------------
 // Signed compare Instructions
-instruct compI_eReg(eFlagsReg cr, eRegI op1, eRegI op2) %{
+instruct compI_eReg(eFlagsReg cr, rRegI op1, rRegI op2) %{
   match(Set cr (CmpI op1 op2));
   effect( DEF cr, USE op1, USE op2 );
   format %{ "CMP    $op1,$op2" %}
@@ -12076,7 +11691,7 @@
   ins_pipe( ialu_cr_reg_reg );
 %}
 
-instruct compI_eReg_imm(eFlagsReg cr, eRegI op1, immI op2) %{
+instruct compI_eReg_imm(eFlagsReg cr, rRegI op1, immI op2) %{
   match(Set cr (CmpI op1 op2));
   effect( DEF cr, USE op1 );
   format %{ "CMP    $op1,$op2" %}
@@ -12087,7 +11702,7 @@
 %}
 
 // Cisc-spilled version of cmpI_eReg
-instruct compI_eReg_mem(eFlagsReg cr, eRegI op1, memory op2) %{
+instruct compI_eReg_mem(eFlagsReg cr, rRegI op1, memory op2) %{
   match(Set cr (CmpI op1 (LoadI op2)));
 
   format %{ "CMP    $op1,$op2" %}
@@ -12097,7 +11712,7 @@
   ins_pipe( ialu_cr_reg_mem );
 %}
 
-instruct testI_reg( eFlagsReg cr, eRegI src, immI0 zero ) %{
+instruct testI_reg( eFlagsReg cr, rRegI src, immI0 zero ) %{
   match(Set cr (CmpI src zero));
   effect( DEF cr, USE src );
 
@@ -12107,7 +11722,7 @@
   ins_pipe( ialu_cr_reg_imm );
 %}
 
-instruct testI_reg_imm( eFlagsReg cr, eRegI src, immI con, immI0 zero ) %{
+instruct testI_reg_imm( eFlagsReg cr, rRegI src, immI con, immI0 zero ) %{
   match(Set cr (CmpI (AndI src con) zero));
 
   format %{ "TEST   $src,$con" %}
@@ -12116,7 +11731,7 @@
   ins_pipe( ialu_cr_reg_imm );
 %}
 
-instruct testI_reg_mem( eFlagsReg cr, eRegI src, memory mem, immI0 zero ) %{
+instruct testI_reg_mem( eFlagsReg cr, rRegI src, memory mem, immI0 zero ) %{
   match(Set cr (CmpI (AndI src mem) zero));
 
   format %{ "TEST   $src,$mem" %}
@@ -12127,7 +11742,7 @@
 
 // Unsigned compare Instructions; really, same as signed except they
 // produce an eFlagsRegU instead of eFlagsReg.
-instruct compU_eReg(eFlagsRegU cr, eRegI op1, eRegI op2) %{
+instruct compU_eReg(eFlagsRegU cr, rRegI op1, rRegI op2) %{
   match(Set cr (CmpU op1 op2));
 
   format %{ "CMPu   $op1,$op2" %}
@@ -12136,7 +11751,7 @@
   ins_pipe( ialu_cr_reg_reg );
 %}
 
-instruct compU_eReg_imm(eFlagsRegU cr, eRegI op1, immI op2) %{
+instruct compU_eReg_imm(eFlagsRegU cr, rRegI op1, immI op2) %{
   match(Set cr (CmpU op1 op2));
 
   format %{ "CMPu   $op1,$op2" %}
@@ -12146,7 +11761,7 @@
 %}
 
 // // Cisc-spilled version of cmpU_eReg
-instruct compU_eReg_mem(eFlagsRegU cr, eRegI op1, memory op2) %{
+instruct compU_eReg_mem(eFlagsRegU cr, rRegI op1, memory op2) %{
   match(Set cr (CmpU op1 (LoadI op2)));
 
   format %{ "CMPu   $op1,$op2" %}
@@ -12157,7 +11772,7 @@
 %}
 
 // // Cisc-spilled version of cmpU_eReg
-//instruct compU_mem_eReg(eFlagsRegU cr, memory op1, eRegI op2) %{
+//instruct compU_mem_eReg(eFlagsRegU cr, memory op1, rRegI op2) %{
 //  match(Set cr (CmpU (LoadI op1) op2));
 //
 //  format %{ "CMPu   $op1,$op2" %}
@@ -12166,7 +11781,7 @@
 //  ins_encode( OpcP, RegMem( op1, op2) );
 //%}
 
-instruct testU_reg( eFlagsRegU cr, eRegI src, immI0 zero ) %{
+instruct testU_reg( eFlagsRegU cr, rRegI src, immI0 zero ) %{
   match(Set cr (CmpU src zero));
 
   format %{ "TESTu  $src,$src" %}
@@ -12262,7 +11877,7 @@
 //   *** Min and Max using the conditional move are slower than the
 //   *** branch version on a Pentium III.
 // // Conditional move for min
-//instruct cmovI_reg_lt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
+//instruct cmovI_reg_lt( rRegI op2, rRegI op1, eFlagsReg cr ) %{
 //  effect( USE_DEF op2, USE op1, USE cr );
 //  format %{ "CMOVlt $op2,$op1\t! min" %}
 //  opcode(0x4C,0x0F);
@@ -12271,7 +11886,7 @@
 //%}
 //
 //// Min Register with Register (P6 version)
-//instruct minI_eReg_p6( eRegI op1, eRegI op2 ) %{
+//instruct minI_eReg_p6( rRegI op1, rRegI op2 ) %{
 //  predicate(VM_Version::supports_cmov() );
 //  match(Set op2 (MinI op1 op2));
 //  ins_cost(200);
@@ -12283,7 +11898,7 @@
 //%}
 
 // Min Register with Register (generic version)
-instruct minI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{
+instruct minI_eReg(rRegI dst, rRegI src, eFlagsReg flags) %{
   match(Set dst (MinI dst src));
   effect(KILL flags);
   ins_cost(300);
@@ -12298,7 +11913,7 @@
 //   *** Min and Max using the conditional move are slower than the
 //   *** branch version on a Pentium III.
 // // Conditional move for max
-//instruct cmovI_reg_gt( eRegI op2, eRegI op1, eFlagsReg cr ) %{
+//instruct cmovI_reg_gt( rRegI op2, rRegI op1, eFlagsReg cr ) %{
 //  effect( USE_DEF op2, USE op1, USE cr );
 //  format %{ "CMOVgt $op2,$op1\t! max" %}
 //  opcode(0x4F,0x0F);
@@ -12307,7 +11922,7 @@
 //%}
 //
 // // Max Register with Register (P6 version)
-//instruct maxI_eReg_p6( eRegI op1, eRegI op2 ) %{
+//instruct maxI_eReg_p6( rRegI op1, rRegI op2 ) %{
 //  predicate(VM_Version::supports_cmov() );
 //  match(Set op2 (MaxI op1 op2));
 //  ins_cost(200);
@@ -12319,7 +11934,7 @@
 //%}
 
 // Max Register with Register (generic version)
-instruct maxI_eReg(eRegI dst, eRegI src, eFlagsReg flags) %{
+instruct maxI_eReg(rRegI dst, rRegI src, eFlagsReg flags) %{
   match(Set dst (MaxI dst src));
   effect(KILL flags);
   ins_cost(300);
@@ -12380,7 +11995,7 @@
 // ============================================================================
 // Branch Instructions
 // Jump Table
-instruct jumpXtnd(eRegI switch_val) %{
+instruct jumpXtnd(rRegI switch_val) %{
   match(Jump switch_val);
   ins_cost(350);
   format %{  "JMP    [$constantaddress](,$switch_val,1)\n\t" %}
@@ -12798,7 +12413,7 @@
 // Manifest a CmpL result in the normal flags.  Only good for LT or GE
 // compares.  Can be used for LE or GT compares by reversing arguments.
 // NOT GOOD FOR EQ/NE tests.
-instruct cmpL_reg_flags_LTGE( flagsReg_long_LTGE flags, eRegL src1, eRegL src2, eRegI tmp ) %{
+instruct cmpL_reg_flags_LTGE( flagsReg_long_LTGE flags, eRegL src1, eRegL src2, rRegI tmp ) %{
   match( Set flags (CmpL src1 src2 ));
   effect( TEMP tmp );
   ins_cost(300);
@@ -12844,7 +12459,7 @@
 %}
 
 // Compare 2 longs and CMOVE ints.
-instruct cmovII_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegI dst, eRegI src) %{
+instruct cmovII_reg_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, rRegI dst, rRegI src) %{
   predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
   match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
   ins_cost(200);
@@ -12854,7 +12469,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovII_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, eRegI dst, memory src) %{
+instruct cmovII_mem_LTGE(cmpOp cmp, flagsReg_long_LTGE flags, rRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::lt || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ge ));
   match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -12915,7 +12530,7 @@
 
 //======
 // Manifest a CmpL result in the normal flags.  Only good for EQ/NE compares.
-instruct cmpL_zero_flags_EQNE( flagsReg_long_EQNE flags, eRegL src, immL0 zero, eRegI tmp ) %{
+instruct cmpL_zero_flags_EQNE( flagsReg_long_EQNE flags, eRegL src, immL0 zero, rRegI tmp ) %{
   match( Set flags (CmpL src zero ));
   effect(TEMP tmp);
   ins_cost(200);
@@ -12972,7 +12587,7 @@
 %}
 
 // Compare 2 longs and CMOVE ints.
-instruct cmovII_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegI dst, eRegI src) %{
+instruct cmovII_reg_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, rRegI dst, rRegI src) %{
   predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
   match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
   ins_cost(200);
@@ -12982,7 +12597,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovII_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, eRegI dst, memory src) %{
+instruct cmovII_mem_EQNE(cmpOp cmp, flagsReg_long_EQNE flags, rRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::eq || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::ne ));
   match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -13044,7 +12659,7 @@
 //======
 // Manifest a CmpL result in the normal flags.  Only good for LE or GT compares.
 // Same as cmpL_reg_flags_LEGT except must negate src
-instruct cmpL_zero_flags_LEGT( flagsReg_long_LEGT flags, eRegL src, immL0 zero, eRegI tmp ) %{
+instruct cmpL_zero_flags_LEGT( flagsReg_long_LEGT flags, eRegL src, immL0 zero, rRegI tmp ) %{
   match( Set flags (CmpL src zero ));
   effect( TEMP tmp );
   ins_cost(300);
@@ -13058,7 +12673,7 @@
 // Manifest a CmpL result in the normal flags.  Only good for LE or GT compares.
 // Same as cmpL_reg_flags_LTGE except operands swapped.  Swapping operands
 // requires a commuted test to get the same result.
-instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, eRegI tmp ) %{
+instruct cmpL_reg_flags_LEGT( flagsReg_long_LEGT flags, eRegL src1, eRegL src2, rRegI tmp ) %{
   match( Set flags (CmpL src1 src2 ));
   effect( TEMP tmp );
   ins_cost(300);
@@ -13105,7 +12720,7 @@
 %}
 
 // Compare 2 longs and CMOVE ints.
-instruct cmovII_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegI dst, eRegI src) %{
+instruct cmovII_reg_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, rRegI dst, rRegI src) %{
   predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
   match(Set dst (CMoveI (Binary cmp flags) (Binary dst src)));
   ins_cost(200);
@@ -13115,7 +12730,7 @@
   ins_pipe( pipe_cmov_reg );
 %}
 
-instruct cmovII_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, eRegI dst, memory src) %{
+instruct cmovII_mem_LEGT(cmpOp_commute cmp, flagsReg_long_LEGT flags, rRegI dst, memory src) %{
   predicate(VM_Version::supports_cmov() && ( _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::le || _kids[0]->_kids[0]->_leaf->as_Bool()->_test._test == BoolTest::gt ));
   match(Set dst (CMoveI (Binary cmp flags) (Binary dst (LoadI src))));
   ins_cost(250);
@@ -13444,11 +13059,11 @@
 // ---------EXAMPLE----------------------------------------------------------
 //
 // // pertinent parts of existing instructions in architecture description
-// instruct movI(eRegI dst, eRegI src) %{
+// instruct movI(rRegI dst, rRegI src) %{
 //   match(Set dst (CopyI src));
 // %}
 //
-// instruct incI_eReg(eRegI dst, immI1 src, eFlagsReg cr) %{
+// instruct incI_eReg(rRegI dst, immI1 src, eFlagsReg cr) %{
 //   match(Set dst (AddI dst src));
 //   effect(KILL cr);
 // %}
@@ -13493,11 +13108,11 @@
 // %}
 
 // // Change load of spilled value to only a spill
-// instruct storeI(memory mem, eRegI src) %{
+// instruct storeI(memory mem, rRegI src) %{
 //   match(Set mem (StoreI mem src));
 // %}
 //
-// instruct loadI(eRegI dst, memory mem) %{
+// instruct loadI(rRegI dst, memory mem) %{
 //   match(Set dst (LoadI mem));
 // %}
 //
diff --git a/hotspot/src/cpu/x86/vm/x86_64.ad b/hotspot/src/cpu/x86/vm/x86_64.ad
index 0eade36..f4bed3c 100644
--- a/hotspot/src/cpu/x86/vm/x86_64.ad
+++ b/hotspot/src/cpu/x86/vm/x86_64.ad
@@ -131,102 +131,6 @@
 
 // Floating Point Registers
 
-// XMM registers.  128-bit registers or 4 words each, labeled (a)-d.
-// Word a in each register holds a Float, words ab hold a Double.  We
-// currently do not use the SIMD capabilities, so registers cd are
-// unused at the moment.
-// XMM8-XMM15 must be encoded with REX.
-// Linux ABI:   No register preserved across function calls
-//              XMM0-XMM7 might hold parameters
-// Windows ABI: XMM6-XMM15 preserved across function calls
-//              XMM0-XMM3 might hold parameters
-
-reg_def XMM0   (SOC, SOC, Op_RegF,  0, xmm0->as_VMReg());
-reg_def XMM0_H (SOC, SOC, Op_RegF,  0, xmm0->as_VMReg()->next());
-
-reg_def XMM1   (SOC, SOC, Op_RegF,  1, xmm1->as_VMReg());
-reg_def XMM1_H (SOC, SOC, Op_RegF,  1, xmm1->as_VMReg()->next());
-
-reg_def XMM2   (SOC, SOC, Op_RegF,  2, xmm2->as_VMReg());
-reg_def XMM2_H (SOC, SOC, Op_RegF,  2, xmm2->as_VMReg()->next());
-
-reg_def XMM3   (SOC, SOC, Op_RegF,  3, xmm3->as_VMReg());
-reg_def XMM3_H (SOC, SOC, Op_RegF,  3, xmm3->as_VMReg()->next());
-
-reg_def XMM4   (SOC, SOC, Op_RegF,  4, xmm4->as_VMReg());
-reg_def XMM4_H (SOC, SOC, Op_RegF,  4, xmm4->as_VMReg()->next());
-
-reg_def XMM5   (SOC, SOC, Op_RegF,  5, xmm5->as_VMReg());
-reg_def XMM5_H (SOC, SOC, Op_RegF,  5, xmm5->as_VMReg()->next());
-
-#ifdef _WIN64
-
-reg_def XMM6   (SOC, SOE, Op_RegF,  6, xmm6->as_VMReg());
-reg_def XMM6_H (SOC, SOE, Op_RegF,  6, xmm6->as_VMReg()->next());
-
-reg_def XMM7   (SOC, SOE, Op_RegF,  7, xmm7->as_VMReg());
-reg_def XMM7_H (SOC, SOE, Op_RegF,  7, xmm7->as_VMReg()->next());
-
-reg_def XMM8   (SOC, SOE, Op_RegF,  8, xmm8->as_VMReg());
-reg_def XMM8_H (SOC, SOE, Op_RegF,  8, xmm8->as_VMReg()->next());
-
-reg_def XMM9   (SOC, SOE, Op_RegF,  9, xmm9->as_VMReg());
-reg_def XMM9_H (SOC, SOE, Op_RegF,  9, xmm9->as_VMReg()->next());
-
-reg_def XMM10  (SOC, SOE, Op_RegF, 10, xmm10->as_VMReg());
-reg_def XMM10_H(SOC, SOE, Op_RegF, 10, xmm10->as_VMReg()->next());
-
-reg_def XMM11  (SOC, SOE, Op_RegF, 11, xmm11->as_VMReg());
-reg_def XMM11_H(SOC, SOE, Op_RegF, 11, xmm11->as_VMReg()->next());
-
-reg_def XMM12  (SOC, SOE, Op_RegF, 12, xmm12->as_VMReg());
-reg_def XMM12_H(SOC, SOE, Op_RegF, 12, xmm12->as_VMReg()->next());
-
-reg_def XMM13  (SOC, SOE, Op_RegF, 13, xmm13->as_VMReg());
-reg_def XMM13_H(SOC, SOE, Op_RegF, 13, xmm13->as_VMReg()->next());
-
-reg_def XMM14  (SOC, SOE, Op_RegF, 14, xmm14->as_VMReg());
-reg_def XMM14_H(SOC, SOE, Op_RegF, 14, xmm14->as_VMReg()->next());
-
-reg_def XMM15  (SOC, SOE, Op_RegF, 15, xmm15->as_VMReg());
-reg_def XMM15_H(SOC, SOE, Op_RegF, 15, xmm15->as_VMReg()->next());
-
-#else
-
-reg_def XMM6   (SOC, SOC, Op_RegF,  6, xmm6->as_VMReg());
-reg_def XMM6_H (SOC, SOC, Op_RegF,  6, xmm6->as_VMReg()->next());
-
-reg_def XMM7   (SOC, SOC, Op_RegF,  7, xmm7->as_VMReg());
-reg_def XMM7_H (SOC, SOC, Op_RegF,  7, xmm7->as_VMReg()->next());
-
-reg_def XMM8   (SOC, SOC, Op_RegF,  8, xmm8->as_VMReg());
-reg_def XMM8_H (SOC, SOC, Op_RegF,  8, xmm8->as_VMReg()->next());
-
-reg_def XMM9   (SOC, SOC, Op_RegF,  9, xmm9->as_VMReg());
-reg_def XMM9_H (SOC, SOC, Op_RegF,  9, xmm9->as_VMReg()->next());
-
-reg_def XMM10  (SOC, SOC, Op_RegF, 10, xmm10->as_VMReg());
-reg_def XMM10_H(SOC, SOC, Op_RegF, 10, xmm10->as_VMReg()->next());
-
-reg_def XMM11  (SOC, SOC, Op_RegF, 11, xmm11->as_VMReg());
-reg_def XMM11_H(SOC, SOC, Op_RegF, 11, xmm11->as_VMReg()->next());
-
-reg_def XMM12  (SOC, SOC, Op_RegF, 12, xmm12->as_VMReg());
-reg_def XMM12_H(SOC, SOC, Op_RegF, 12, xmm12->as_VMReg()->next());
-
-reg_def XMM13  (SOC, SOC, Op_RegF, 13, xmm13->as_VMReg());
-reg_def XMM13_H(SOC, SOC, Op_RegF, 13, xmm13->as_VMReg()->next());
-
-reg_def XMM14  (SOC, SOC, Op_RegF, 14, xmm14->as_VMReg());
-reg_def XMM14_H(SOC, SOC, Op_RegF, 14, xmm14->as_VMReg()->next());
-
-reg_def XMM15  (SOC, SOC, Op_RegF, 15, xmm15->as_VMReg());
-reg_def XMM15_H(SOC, SOC, Op_RegF, 15, xmm15->as_VMReg()->next());
-
-#endif // _WIN64
-
-reg_def RFLAGS(SOC, SOC, 0, 16, VMRegImpl::Bad());
-
 // Specify priority of register selection within phases of register
 // allocation.  Highest priority is first.  A useful heuristic is to
 // give registers a low priority when they are required by machine
@@ -252,26 +156,6 @@
                    R15,         R15_H,
                    RSP,         RSP_H);
 
-// XXX probably use 8-15 first on Linux
-alloc_class chunk1(XMM0,  XMM0_H,
-                   XMM1,  XMM1_H,
-                   XMM2,  XMM2_H,
-                   XMM3,  XMM3_H,
-                   XMM4,  XMM4_H,
-                   XMM5,  XMM5_H,
-                   XMM6,  XMM6_H,
-                   XMM7,  XMM7_H,
-                   XMM8,  XMM8_H,
-                   XMM9,  XMM9_H,
-                   XMM10, XMM10_H,
-                   XMM11, XMM11_H,
-                   XMM12, XMM12_H,
-                   XMM13, XMM13_H,
-                   XMM14, XMM14_H,
-                   XMM15, XMM15_H);
-
-alloc_class chunk2(RFLAGS);
-
 
 //----------Architecture Description Register Classes--------------------------
 // Several register classes are automatically defined based upon information in
@@ -501,47 +385,8 @@
 // Singleton class for instruction pointer
 // reg_class ip_reg(RIP);
 
-// Singleton class for condition codes
-reg_class int_flags(RFLAGS);
-
-// Class for all float registers
-reg_class float_reg(XMM0,
-                    XMM1,
-                    XMM2,
-                    XMM3,
-                    XMM4,
-                    XMM5,
-                    XMM6,
-                    XMM7,
-                    XMM8,
-                    XMM9,
-                    XMM10,
-                    XMM11,
-                    XMM12,
-                    XMM13,
-                    XMM14,
-                    XMM15);
-
-// Class for all double registers
-reg_class double_reg(XMM0,  XMM0_H,
-                     XMM1,  XMM1_H,
-                     XMM2,  XMM2_H,
-                     XMM3,  XMM3_H,
-                     XMM4,  XMM4_H,
-                     XMM5,  XMM5_H,
-                     XMM6,  XMM6_H,
-                     XMM7,  XMM7_H,
-                     XMM8,  XMM8_H,
-                     XMM9,  XMM9_H,
-                     XMM10, XMM10_H,
-                     XMM11, XMM11_H,
-                     XMM12, XMM12_H,
-                     XMM13, XMM13_H,
-                     XMM14, XMM14_H,
-                     XMM15, XMM15_H);
 %}
 
-
 //----------SOURCE BLOCK-------------------------------------------------------
 // This is a block of C++ code which provides values, functions, and
 // definitions necessary in the rest of the architecture description
@@ -1027,12 +872,84 @@
   return rc_float;
 }
 
+// Next two methods are shared by 32- and 64-bit VM. They are defined in x86.ad.
+static int vec_mov_helper(CodeBuffer *cbuf, bool do_size, int src_lo, int dst_lo,
+                          int src_hi, int dst_hi, uint ireg, outputStream* st);
+
+static int vec_spill_helper(CodeBuffer *cbuf, bool do_size, bool is_load,
+                            int stack_offset, int reg, uint ireg, outputStream* st);
+
+static void vec_stack_to_stack_helper(CodeBuffer *cbuf, int src_offset,
+                                      int dst_offset, uint ireg, outputStream* st) {
+  if (cbuf) {
+    MacroAssembler _masm(cbuf);
+    switch (ireg) {
+    case Op_VecS:
+      __ movq(Address(rsp, -8), rax);
+      __ movl(rax, Address(rsp, src_offset));
+      __ movl(Address(rsp, dst_offset), rax);
+      __ movq(rax, Address(rsp, -8));
+      break;
+    case Op_VecD:
+      __ pushq(Address(rsp, src_offset));
+      __ popq (Address(rsp, dst_offset));
+      break;
+    case Op_VecX:
+      __ pushq(Address(rsp, src_offset));
+      __ popq (Address(rsp, dst_offset));
+      __ pushq(Address(rsp, src_offset+8));
+      __ popq (Address(rsp, dst_offset+8));
+      break;
+    case Op_VecY:
+      __ vmovdqu(Address(rsp, -32), xmm0);
+      __ vmovdqu(xmm0, Address(rsp, src_offset));
+      __ vmovdqu(Address(rsp, dst_offset), xmm0);
+      __ vmovdqu(xmm0, Address(rsp, -32));
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+#ifndef PRODUCT
+  } else {
+    switch (ireg) {
+    case Op_VecS:
+      st->print("movq    [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
+                "movl    rax, [rsp + #%d]\n\t"
+                "movl    [rsp + #%d], rax\n\t"
+                "movq    rax, [rsp - #8]",
+                src_offset, dst_offset);
+      break;
+    case Op_VecD:
+      st->print("pushq   [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
+                "popq    [rsp + #%d]",
+                src_offset, dst_offset);
+      break;
+     case Op_VecX:
+      st->print("pushq   [rsp + #%d]\t# 128-bit mem-mem spill\n\t"
+                "popq    [rsp + #%d]\n\t"
+                "pushq   [rsp + #%d]\n\t"
+                "popq    [rsp + #%d]",
+                src_offset, dst_offset, src_offset+8, dst_offset+8);
+      break;
+    case Op_VecY:
+      st->print("vmovdqu [rsp - #32], xmm0\t# 256-bit mem-mem spill\n\t"
+                "vmovdqu xmm0, [rsp + #%d]\n\t"
+                "vmovdqu [rsp + #%d], xmm0\n\t"
+                "vmovdqu xmm0, [rsp - #32]",
+                src_offset, dst_offset);
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+#endif
+  }
+}
+
 uint MachSpillCopyNode::implementation(CodeBuffer* cbuf,
                                        PhaseRegAlloc* ra_,
                                        bool do_size,
-                                       outputStream* st) const
-{
-
+                                       outputStream* st) const {
+  assert(cbuf != NULL || st  != NULL, "sanity");
   // Get registers to move
   OptoReg::Name src_second = ra_->get_reg_second(in(1));
   OptoReg::Name src_first = ra_->get_reg_first(in(1));
@@ -1050,7 +967,30 @@
   if (src_first == dst_first && src_second == dst_second) {
     // Self copy, no move
     return 0;
-  } else if (src_first_rc == rc_stack) {
+  }
+  if (bottom_type()->isa_vect() != NULL) {
+    uint ireg = ideal_reg();
+    assert((src_first_rc != rc_int && dst_first_rc != rc_int), "sanity");
+    assert((ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY), "sanity");
+    if( src_first_rc == rc_stack && dst_first_rc == rc_stack ) {
+      // mem -> mem
+      int src_offset = ra_->reg2offset(src_first);
+      int dst_offset = ra_->reg2offset(dst_first);
+      vec_stack_to_stack_helper(cbuf, src_offset, dst_offset, ireg, st);
+    } else if (src_first_rc == rc_float && dst_first_rc == rc_float ) {
+      vec_mov_helper(cbuf, false, src_first, dst_first, src_second, dst_second, ireg, st);
+    } else if (src_first_rc == rc_float && dst_first_rc == rc_stack ) {
+      int stack_offset = ra_->reg2offset(dst_first);
+      vec_spill_helper(cbuf, false, false, stack_offset, src_first, ireg, st);
+    } else if (src_first_rc == rc_stack && dst_first_rc == rc_float ) {
+      int stack_offset = ra_->reg2offset(src_first);
+      vec_spill_helper(cbuf, false, true,  stack_offset, dst_first, ireg, st);
+    } else {
+      ShouldNotReachHere();
+    }
+    return 0;
+  }
+  if (src_first_rc == rc_stack) {
     // mem ->
     if (dst_first_rc == rc_stack) {
       // mem -> mem
@@ -1061,23 +1001,16 @@
         int src_offset = ra_->reg2offset(src_first);
         int dst_offset = ra_->reg2offset(dst_first);
         if (cbuf) {
-          emit_opcode(*cbuf, 0xFF);
-          encode_RegMem(*cbuf, RSI_enc, RSP_enc, 0x4, 0, src_offset, false);
-
-          emit_opcode(*cbuf, 0x8F);
-          encode_RegMem(*cbuf, RAX_enc, RSP_enc, 0x4, 0, dst_offset, false);
-
+          MacroAssembler _masm(cbuf);
+          __ pushq(Address(rsp, src_offset));
+          __ popq (Address(rsp, dst_offset));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("pushq   [rsp + #%d]\t# 64-bit mem-mem spill\n\t"
-                     "popq    [rsp + #%d]",
-                     src_offset,
-                     dst_offset);
+                    "popq    [rsp + #%d]",
+                     src_offset, dst_offset);
 #endif
         }
-        return
-          3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) +
-          3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4));
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
@@ -1086,46 +1019,22 @@
         int src_offset = ra_->reg2offset(src_first);
         int dst_offset = ra_->reg2offset(dst_first);
         if (cbuf) {
-          emit_opcode(*cbuf, Assembler::REX_W);
-          emit_opcode(*cbuf, 0x89);
-          emit_opcode(*cbuf, 0x44);
-          emit_opcode(*cbuf, 0x24);
-          emit_opcode(*cbuf, 0xF8);
-
-          emit_opcode(*cbuf, 0x8B);
-          encode_RegMem(*cbuf,
-                        RAX_enc,
-                        RSP_enc, 0x4, 0, src_offset,
-                        false);
-
-          emit_opcode(*cbuf, 0x89);
-          encode_RegMem(*cbuf,
-                        RAX_enc,
-                        RSP_enc, 0x4, 0, dst_offset,
-                        false);
-
-          emit_opcode(*cbuf, Assembler::REX_W);
-          emit_opcode(*cbuf, 0x8B);
-          emit_opcode(*cbuf, 0x44);
-          emit_opcode(*cbuf, 0x24);
-          emit_opcode(*cbuf, 0xF8);
-
+          MacroAssembler _masm(cbuf);
+          __ movq(Address(rsp, -8), rax);
+          __ movl(rax, Address(rsp, src_offset));
+          __ movl(Address(rsp, dst_offset), rax);
+          __ movq(rax, Address(rsp, -8));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movq    [rsp - #8], rax\t# 32-bit mem-mem spill\n\t"
-                     "movl    rax, [rsp + #%d]\n\t"
-                     "movl    [rsp + #%d], rax\n\t"
-                     "movq    rax, [rsp - #8]",
-                     src_offset,
-                     dst_offset);
+                    "movl    rax, [rsp + #%d]\n\t"
+                    "movl    [rsp + #%d], rax\n\t"
+                    "movq    rax, [rsp - #8]",
+                     src_offset, dst_offset);
 #endif
         }
-        return
-          5 + // movq
-          3 + ((src_offset == 0) ? 0 : (src_offset < 0x80 ? 1 : 4)) + // movl
-          3 + ((dst_offset == 0) ? 0 : (dst_offset < 0x80 ? 1 : 4)) + // movl
-          5; // movq
       }
+      return 0;
     } else if (dst_first_rc == rc_int) {
       // mem -> gpr
       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
@@ -1133,52 +1042,32 @@
         // 64-bit
         int offset = ra_->reg2offset(src_first);
         if (cbuf) {
-          if (Matcher::_regEncode[dst_first] < 8) {
-            emit_opcode(*cbuf, Assembler::REX_W);
-          } else {
-            emit_opcode(*cbuf, Assembler::REX_WR);
-          }
-          emit_opcode(*cbuf, 0x8B);
-          encode_RegMem(*cbuf,
-                        Matcher::_regEncode[dst_first],
-                        RSP_enc, 0x4, 0, offset,
-                        false);
+          MacroAssembler _masm(cbuf);
+          __ movq(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movq    %s, [rsp + #%d]\t# spill",
                      Matcher::regName[dst_first],
                      offset);
 #endif
         }
-        return
-          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
         int offset = ra_->reg2offset(src_first);
         if (cbuf) {
-          if (Matcher::_regEncode[dst_first] >= 8) {
-            emit_opcode(*cbuf, Assembler::REX_R);
-          }
-          emit_opcode(*cbuf, 0x8B);
-          encode_RegMem(*cbuf,
-                        Matcher::_regEncode[dst_first],
-                        RSP_enc, 0x4, 0, offset,
-                        false);
+          MacroAssembler _masm(cbuf);
+          __ movl(as_Register(Matcher::_regEncode[dst_first]), Address(rsp, offset));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movl    %s, [rsp + #%d]\t# spill",
                      Matcher::regName[dst_first],
                      offset);
 #endif
         }
-        return
-          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
-          ((Matcher::_regEncode[dst_first] < 8)
-           ? 3
-           : 4); // REX
       }
+      return 0;
     } else if (dst_first_rc == rc_float) {
       // mem-> xmm
       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
@@ -1189,18 +1078,13 @@
           MacroAssembler _masm(cbuf);
           __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("%s  %s, [rsp + #%d]\t# spill",
                      UseXmmLoadAndClearUpper ? "movsd " : "movlpd",
                      Matcher::regName[dst_first],
                      offset);
 #endif
         }
-        return
-          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
-          ((Matcher::_regEncode[dst_first] >= 8)
-           ? 6
-           : (5 + ((UseAVX>0)?1:0))); // REX
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
@@ -1210,18 +1094,14 @@
           MacroAssembler _masm(cbuf);
           __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), Address(rsp, offset));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movss   %s, [rsp + #%d]\t# spill",
                      Matcher::regName[dst_first],
                      offset);
 #endif
         }
-        return
-          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
-          ((Matcher::_regEncode[dst_first] >= 8)
-           ? 6
-           : (5 + ((UseAVX>0)?1:0))); // REX
       }
+      return 0;
     }
   } else if (src_first_rc == rc_int) {
     // gpr ->
@@ -1232,113 +1112,65 @@
         // 64-bit
         int offset = ra_->reg2offset(dst_first);
         if (cbuf) {
-          if (Matcher::_regEncode[src_first] < 8) {
-            emit_opcode(*cbuf, Assembler::REX_W);
-          } else {
-            emit_opcode(*cbuf, Assembler::REX_WR);
-          }
-          emit_opcode(*cbuf, 0x89);
-          encode_RegMem(*cbuf,
-                        Matcher::_regEncode[src_first],
-                        RSP_enc, 0x4, 0, offset,
-                        false);
+          MacroAssembler _masm(cbuf);
+          __ movq(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movq    [rsp + #%d], %s\t# spill",
                      offset,
                      Matcher::regName[src_first]);
 #endif
         }
-        return ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) + 4; // REX
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
         int offset = ra_->reg2offset(dst_first);
         if (cbuf) {
-          if (Matcher::_regEncode[src_first] >= 8) {
-            emit_opcode(*cbuf, Assembler::REX_R);
-          }
-          emit_opcode(*cbuf, 0x89);
-          encode_RegMem(*cbuf,
-                        Matcher::_regEncode[src_first],
-                        RSP_enc, 0x4, 0, offset,
-                        false);
+          MacroAssembler _masm(cbuf);
+          __ movl(Address(rsp, offset), as_Register(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movl    [rsp + #%d], %s\t# spill",
                      offset,
                      Matcher::regName[src_first]);
 #endif
         }
-        return
-          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
-          ((Matcher::_regEncode[src_first] < 8)
-           ? 3
-           : 4); // REX
       }
+      return 0;
     } else if (dst_first_rc == rc_int) {
       // gpr -> gpr
       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
           (dst_first & 1) == 0 && dst_first + 1 == dst_second) {
         // 64-bit
         if (cbuf) {
-          if (Matcher::_regEncode[dst_first] < 8) {
-            if (Matcher::_regEncode[src_first] < 8) {
-              emit_opcode(*cbuf, Assembler::REX_W);
-            } else {
-              emit_opcode(*cbuf, Assembler::REX_WB);
-            }
-          } else {
-            if (Matcher::_regEncode[src_first] < 8) {
-              emit_opcode(*cbuf, Assembler::REX_WR);
-            } else {
-              emit_opcode(*cbuf, Assembler::REX_WRB);
-            }
-          }
-          emit_opcode(*cbuf, 0x8B);
-          emit_rm(*cbuf, 0x3,
-                  Matcher::_regEncode[dst_first] & 7,
-                  Matcher::_regEncode[src_first] & 7);
+          MacroAssembler _masm(cbuf);
+          __ movq(as_Register(Matcher::_regEncode[dst_first]),
+                  as_Register(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movq    %s, %s\t# spill",
                      Matcher::regName[dst_first],
                      Matcher::regName[src_first]);
 #endif
         }
-        return 3; // REX
+        return 0;
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
         assert(!((dst_first & 1) == 0 && dst_first + 1 == dst_second), "no transform");
         if (cbuf) {
-          if (Matcher::_regEncode[dst_first] < 8) {
-            if (Matcher::_regEncode[src_first] >= 8) {
-              emit_opcode(*cbuf, Assembler::REX_B);
-            }
-          } else {
-            if (Matcher::_regEncode[src_first] < 8) {
-              emit_opcode(*cbuf, Assembler::REX_R);
-            } else {
-              emit_opcode(*cbuf, Assembler::REX_RB);
-            }
-          }
-          emit_opcode(*cbuf, 0x8B);
-          emit_rm(*cbuf, 0x3,
-                  Matcher::_regEncode[dst_first] & 7,
-                  Matcher::_regEncode[src_first] & 7);
+          MacroAssembler _masm(cbuf);
+          __ movl(as_Register(Matcher::_regEncode[dst_first]),
+                  as_Register(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movl    %s, %s\t# spill",
                      Matcher::regName[dst_first],
                      Matcher::regName[src_first]);
 #endif
         }
-        return
-          (Matcher::_regEncode[src_first] < 8 && Matcher::_regEncode[dst_first] < 8)
-          ? 2
-          : 3; // REX
+        return 0;
       }
     } else if (dst_first_rc == rc_float) {
       // gpr -> xmm
@@ -1349,13 +1181,12 @@
           MacroAssembler _masm(cbuf);
           __ movdq( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movdq   %s, %s\t# spill",
                      Matcher::regName[dst_first],
                      Matcher::regName[src_first]);
 #endif
         }
-        return 5; // REX
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
@@ -1364,17 +1195,14 @@
           MacroAssembler _masm(cbuf);
           __ movdl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_Register(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movdl   %s, %s\t# spill",
                      Matcher::regName[dst_first],
                      Matcher::regName[src_first]);
 #endif
         }
-        return
-          (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
-          ? 5
-          : (4 + ((UseAVX>0)?1:0)); // REX
       }
+      return 0;
     }
   } else if (src_first_rc == rc_float) {
     // xmm ->
@@ -1388,17 +1216,12 @@
           MacroAssembler _masm(cbuf);
           __ movdbl( Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movsd   [rsp + #%d], %s\t# spill",
                      offset,
                      Matcher::regName[src_first]);
 #endif
         }
-        return
-          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
-          ((Matcher::_regEncode[src_first] >= 8)
-           ? 6
-           : (5 + ((UseAVX>0)?1:0))); // REX
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
@@ -1408,18 +1231,14 @@
           MacroAssembler _masm(cbuf);
           __ movflt(Address(rsp, offset), as_XMMRegister(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movss   [rsp + #%d], %s\t# spill",
                      offset,
                      Matcher::regName[src_first]);
 #endif
         }
-        return
-          ((offset == 0) ? 0 : (offset < 0x80 ? 1 : 4)) +
-          ((Matcher::_regEncode[src_first] >=8)
-           ? 6
-           : (5 + ((UseAVX>0)?1:0))); // REX
       }
+      return 0;
     } else if (dst_first_rc == rc_int) {
       // xmm -> gpr
       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
@@ -1429,13 +1248,12 @@
           MacroAssembler _masm(cbuf);
           __ movdq( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movdq   %s, %s\t# spill",
                      Matcher::regName[dst_first],
                      Matcher::regName[src_first]);
 #endif
         }
-        return 5; // REX
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
@@ -1444,17 +1262,14 @@
           MacroAssembler _masm(cbuf);
           __ movdl( as_Register(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("movdl   %s, %s\t# spill",
                      Matcher::regName[dst_first],
                      Matcher::regName[src_first]);
 #endif
         }
-        return
-          (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
-          ? 5
-          : (4 + ((UseAVX>0)?1:0)); // REX
       }
+      return 0;
     } else if (dst_first_rc == rc_float) {
       // xmm -> xmm
       if ((src_first & 1) == 0 && src_first + 1 == src_second &&
@@ -1464,17 +1279,13 @@
           MacroAssembler _masm(cbuf);
           __ movdbl( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("%s  %s, %s\t# spill",
                      UseXmmRegToRegMoveAll ? "movapd" : "movsd ",
                      Matcher::regName[dst_first],
                      Matcher::regName[src_first]);
 #endif
         }
-        return
-          (Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
-          ? 5
-          : (4 + ((UseAVX>0)?1:0)); // REX
       } else {
         // 32-bit
         assert(!((src_first & 1) == 0 && src_first + 1 == src_second), "no transform");
@@ -1483,42 +1294,35 @@
           MacroAssembler _masm(cbuf);
           __ movflt( as_XMMRegister(Matcher::_regEncode[dst_first]), as_XMMRegister(Matcher::_regEncode[src_first]));
 #ifndef PRODUCT
-        } else if (!do_size) {
+        } else {
           st->print("%s  %s, %s\t# spill",
                      UseXmmRegToRegMoveAll ? "movaps" : "movss ",
                      Matcher::regName[dst_first],
                      Matcher::regName[src_first]);
 #endif
         }
-        return ((UseAVX>0) ? 5:
-          ((Matcher::_regEncode[src_first] >= 8 || Matcher::_regEncode[dst_first] >= 8)
-           ? (UseXmmRegToRegMoveAll ? 4 : 5)
-           : (UseXmmRegToRegMoveAll ? 3 : 4))); // REX
       }
+      return 0;
     }
   }
 
   assert(0," foo ");
   Unimplemented();
-
   return 0;
 }
 
 #ifndef PRODUCT
-void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const
-{
+void MachSpillCopyNode::format(PhaseRegAlloc *ra_, outputStream* st) const {
   implementation(NULL, ra_, false, st);
 }
 #endif
 
-void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const
-{
+void MachSpillCopyNode::emit(CodeBuffer &cbuf, PhaseRegAlloc *ra_) const {
   implementation(&cbuf, ra_, false, NULL);
 }
 
-uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const
-{
-  return implementation(NULL, ra_, true, NULL);
+uint MachSpillCopyNode::size(PhaseRegAlloc *ra_) const {
+  return MachNode::size(ra_);
 }
 
 //=============================================================================
@@ -1709,14 +1513,6 @@
   return offset;
 }
 
-
-const bool Matcher::match_rule_supported(int opcode) {
-  if (!has_match_rule(opcode))
-    return false;
-
-  return true;  // Per default match rules are supported.
-}
-
 int Matcher::regnum_to_fpu_offset(int regnum)
 {
   return regnum - 32; // The FP registers are in the second chunk
@@ -1727,16 +1523,6 @@
   return true;
 }
 
-// Vector width in bytes
-const uint Matcher::vector_width_in_bytes(void) {
-  return 8;
-}
-
-// Vector ideal reg
-const uint Matcher::vector_ideal_reg(void) {
-  return Op_RegD;
-}
-
 // Is this branch offset short enough that a short branch can be used?
 //
 // NOTE: If the platform does not provide any short branch variants, then
@@ -1823,21 +1609,21 @@
 bool Matcher::can_be_java_arg(int reg)
 {
   return
-    reg ==  RDI_num || reg ==  RDI_H_num ||
-    reg ==  RSI_num || reg ==  RSI_H_num ||
-    reg ==  RDX_num || reg ==  RDX_H_num ||
-    reg ==  RCX_num || reg ==  RCX_H_num ||
-    reg ==   R8_num || reg ==   R8_H_num ||
-    reg ==   R9_num || reg ==   R9_H_num ||
-    reg ==  R12_num || reg ==  R12_H_num ||
-    reg == XMM0_num || reg == XMM0_H_num ||
-    reg == XMM1_num || reg == XMM1_H_num ||
-    reg == XMM2_num || reg == XMM2_H_num ||
-    reg == XMM3_num || reg == XMM3_H_num ||
-    reg == XMM4_num || reg == XMM4_H_num ||
-    reg == XMM5_num || reg == XMM5_H_num ||
-    reg == XMM6_num || reg == XMM6_H_num ||
-    reg == XMM7_num || reg == XMM7_H_num;
+    reg ==  RDI_num || reg == RDI_H_num ||
+    reg ==  RSI_num || reg == RSI_H_num ||
+    reg ==  RDX_num || reg == RDX_H_num ||
+    reg ==  RCX_num || reg == RCX_H_num ||
+    reg ==   R8_num || reg ==  R8_H_num ||
+    reg ==   R9_num || reg ==  R9_H_num ||
+    reg ==  R12_num || reg == R12_H_num ||
+    reg == XMM0_num || reg == XMM0b_num ||
+    reg == XMM1_num || reg == XMM1b_num ||
+    reg == XMM2_num || reg == XMM2b_num ||
+    reg == XMM3_num || reg == XMM3b_num ||
+    reg == XMM4_num || reg == XMM4b_num ||
+    reg == XMM5_num || reg == XMM5b_num ||
+    reg == XMM6_num || reg == XMM6b_num ||
+    reg == XMM7_num || reg == XMM7b_num;
 }
 
 bool Matcher::is_spillable_arg(int reg)
@@ -3212,10 +2998,11 @@
       OptoReg::Bad, // Op_RegI
       RAX_H_num,    // Op_RegP
       OptoReg::Bad, // Op_RegF
-      XMM0_H_num,   // Op_RegD
+      XMM0b_num,    // Op_RegD
       RAX_H_num     // Op_RegL
     };
-    assert(ARRAY_SIZE(hi) == _last_machine_leaf - 1, "missing type");
+    // Excluded flags and vector registers.
+    assert(ARRAY_SIZE(hi) == _last_machine_leaf - 5, "missing type");
     return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
   %}
 %}
@@ -3977,7 +3764,6 @@
   interface(REG_INTER);
 %}
 
-
 //----------Memory Operands----------------------------------------------------
 // Direct Memory Operand
 // operand direct(immP addr)
@@ -5276,9 +5062,9 @@
 %}
 
 // Load Unsigned Integer into Long Register
-instruct loadUI2L(rRegL dst, memory mem)
+instruct loadUI2L(rRegL dst, memory mem, immL_32bits mask) 
 %{
-  match(Set dst (LoadUI2L mem));
+  match(Set dst (AndL (ConvI2L (LoadI mem)) mask));
 
   ins_cost(125);
   format %{ "movl    $dst, $mem\t# uint -> long" %}
@@ -5408,61 +5194,6 @@
   ins_pipe(pipe_slow); // XXX
 %}
 
-// Load Aligned Packed Byte to XMM register
-instruct loadA8B(regD dst, memory mem) %{
-  match(Set dst (Load8B mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed8B" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Load Aligned Packed Short to XMM register
-instruct loadA4S(regD dst, memory mem) %{
-  match(Set dst (Load4S mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed4S" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Load Aligned Packed Char to XMM register
-instruct loadA4C(regD dst, memory mem) %{
-  match(Set dst (Load4C mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed4C" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Load Aligned Packed Integer to XMM register
-instruct load2IU(regD dst, memory mem) %{
-  match(Set dst (Load2I mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed2I" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Load Aligned Packed Single to XMM
-instruct loadA2F(regD dst, memory mem) %{
-  match(Set dst (Load2F mem));
-  ins_cost(125);
-  format %{ "MOVQ  $dst,$mem\t! packed2F" %}
-  ins_encode %{
-    __ movq($dst$$XMMRegister, $mem$$Address);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 // Load Effective Address
 instruct leaP8(rRegP dst, indOffset8 mem)
 %{
@@ -6192,39 +5923,6 @@
   ins_pipe(ialu_mem_imm);
 %}
 
-// Store Aligned Packed Byte XMM register to memory
-instruct storeA8B(memory mem, regD src) %{
-  match(Set mem (Store8B mem src));
-  ins_cost(145);
-  format %{ "MOVQ  $mem,$src\t! packed8B" %}
-  ins_encode %{
-    __ movq($mem$$Address, $src$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Store Aligned Packed Char/Short XMM register to memory
-instruct storeA4C(memory mem, regD src) %{
-  match(Set mem (Store4C mem src));
-  ins_cost(145);
-  format %{ "MOVQ  $mem,$src\t! packed4C" %}
-  ins_encode %{
-    __ movq($mem$$Address, $src$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Store Aligned Packed Integer XMM register to memory
-instruct storeA2I(memory mem, regD src) %{
-  match(Set mem (Store2I mem src));
-  ins_cost(145);
-  format %{ "MOVQ  $mem,$src\t! packed2I" %}
-  ins_encode %{
-    __ movq($mem$$Address, $src$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 // Store CMS card-mark Immediate
 instruct storeImmCM0_reg(memory mem, immI0 zero)
 %{
@@ -6250,17 +5948,6 @@
   ins_pipe(ialu_mem_imm);
 %}
 
-// Store Aligned Packed Single Float XMM register to memory
-instruct storeA2F(memory mem, regD src) %{
-  match(Set mem (Store2F mem src));
-  ins_cost(145);
-  format %{ "MOVQ  $mem,$src\t! packed2F" %}
-  ins_encode %{
-    __ movq($mem$$Address, $src$$XMMRegister);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
 // Store Float
 instruct storeF(memory mem, regF src)
 %{
@@ -6724,6 +6411,31 @@
   ins_pipe(ialu_reg_reg); // XXX
 %}
 
+// Convert oop into int for vectors alignment masking
+instruct convP2I(rRegI dst, rRegP src)
+%{
+  match(Set dst (ConvL2I (CastP2X src)));
+
+  format %{ "movl    $dst, $src\t# ptr -> int" %}
+  ins_encode %{
+    __ movl($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg); // XXX
+%}
+
+// Convert compressed oop into int for vectors alignment masking
+// in case of 32bit oops (heap < 4Gb).
+instruct convN2I(rRegI dst, rRegN src)
+%{
+  predicate(Universe::narrow_oop_shift() == 0);
+  match(Set dst (ConvL2I (CastP2X (DecodeN src))));
+
+  format %{ "movl    $dst, $src\t# compressed ptr -> int" %}
+  ins_encode %{
+    __ movl($dst$$Register, $src$$Register);
+  %}
+  ins_pipe(ialu_reg_reg); // XXX
+%}
 
 // Convert oop pointer into compressed form
 instruct encodeHeapOop(rRegN dst, rRegP src, rFlagsReg cr) %{
@@ -7489,18 +7201,6 @@
   ins_pipe(ialu_reg_mem); // XXX
 %}
 
-// LoadL-locked - same as a regular LoadL when used with compare-swap
-instruct loadLLocked(rRegL dst, memory mem)
-%{
-  match(Set dst (LoadLLocked mem));
-
-  ins_cost(125); // XXX
-  format %{ "movq    $dst, $mem\t# long locked" %}
-  opcode(0x8B);
-  ins_encode(REX_reg_mem_wide(dst, mem), OpcP, reg_mem(dst, mem));
-  ins_pipe(ialu_reg_mem); // XXX
-%}
-
 // Conditional-store of the updated heap-top.
 // Used during allocation of the shared heap.
 // Sets flags (EQ) on success.  Implemented with a CMPXCHG on Intel.
@@ -7560,6 +7260,7 @@
                          rax_RegP oldval, rRegP newval,
                          rFlagsReg cr)
 %{
+  predicate(VM_Version::supports_cx8());
   match(Set res (CompareAndSwapP mem_ptr (Binary oldval newval)));
   effect(KILL cr, KILL oldval);
 
@@ -7583,6 +7284,7 @@
                          rax_RegL oldval, rRegL newval,
                          rFlagsReg cr)
 %{
+  predicate(VM_Version::supports_cx8());
   match(Set res (CompareAndSwapL mem_ptr (Binary oldval newval)));
   effect(KILL cr, KILL oldval);
 
@@ -7624,6 +7326,88 @@
   ins_pipe( pipe_cmpxchg );
 %}
 
+instruct xaddI_no_res( memory mem, Universe dummy, immI add, rFlagsReg cr) %{
+  predicate(n->as_LoadStore()->result_not_used());
+  match(Set dummy (GetAndAddI mem add));
+  effect(KILL cr);
+  format %{ "ADDL  [$mem],$add" %}
+  ins_encode %{
+    if (os::is_MP()) { __ lock(); }
+    __ addl($mem$$Address, $add$$constant);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xaddI( memory mem, rRegI newval, rFlagsReg cr) %{
+  match(Set newval (GetAndAddI mem newval));
+  effect(KILL cr);
+  format %{ "XADDL  [$mem],$newval" %}
+  ins_encode %{
+    if (os::is_MP()) { __ lock(); }
+    __ xaddl($mem$$Address, $newval$$Register);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xaddL_no_res( memory mem, Universe dummy, immL add, rFlagsReg cr) %{
+  predicate(n->as_LoadStore()->result_not_used());
+  match(Set dummy (GetAndAddL mem add));
+  effect(KILL cr);
+  format %{ "ADDQ  [$mem],$add" %}
+  ins_encode %{
+    if (os::is_MP()) { __ lock(); }
+    __ addq($mem$$Address, $add$$constant);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xaddL( memory mem, rRegL newval, rFlagsReg cr) %{
+  match(Set newval (GetAndAddL mem newval));
+  effect(KILL cr);
+  format %{ "XADDQ  [$mem],$newval" %}
+  ins_encode %{
+    if (os::is_MP()) { __ lock(); }
+    __ xaddq($mem$$Address, $newval$$Register);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xchgI( memory mem, rRegI newval) %{
+  match(Set newval (GetAndSetI mem newval));
+  format %{ "XCHGL  $newval,[$mem]" %}
+  ins_encode %{
+    __ xchgl($newval$$Register, $mem$$Address);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xchgL( memory mem, rRegL newval) %{
+  match(Set newval (GetAndSetL mem newval));
+  format %{ "XCHGL  $newval,[$mem]" %}
+  ins_encode %{
+    __ xchgq($newval$$Register, $mem$$Address);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xchgP( memory mem, rRegP newval) %{
+  match(Set newval (GetAndSetP mem newval));
+  format %{ "XCHGQ  $newval,[$mem]" %}
+  ins_encode %{
+    __ xchgq($newval$$Register, $mem$$Address);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
+instruct xchgN( memory mem, rRegN newval) %{
+  match(Set newval (GetAndSetN mem newval));
+  format %{ "XCHGL  $newval,$mem]" %}
+  ins_encode %{
+    __ xchgl($newval$$Register, $mem$$Address);
+  %}
+  ins_pipe( pipe_cmpxchg );
+%}
+
 
 instruct compareAndSwapN(rRegI res,
                           memory mem_ptr,
@@ -9820,7 +9604,39 @@
   ins_pipe( pipe_slow );
 %}
 
+instruct powD_reg(regD dst, regD src0, regD src1, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
+  match(Set dst (PowD src0 src1));  // Raise src0 to the src1'th power
+  effect(KILL rax, KILL rdx, KILL rcx, KILL cr);
+  format %{ "fast_pow $src0 $src1 -> $dst  // KILL $rax, $rcx, $rdx" %}
+  ins_encode %{
+    __ subptr(rsp, 8);
+    __ movdbl(Address(rsp, 0), $src1$$XMMRegister);
+    __ fld_d(Address(rsp, 0));
+    __ movdbl(Address(rsp, 0), $src0$$XMMRegister);
+    __ fld_d(Address(rsp, 0));
+    __ fast_pow();
+    __ fstp_d(Address(rsp, 0));
+    __ movdbl($dst$$XMMRegister, Address(rsp, 0));
+    __ addptr(rsp, 8);
+  %}
+  ins_pipe( pipe_slow );
+%}
 
+instruct expD_reg(regD dst, regD src, rax_RegI rax, rdx_RegI rdx, rcx_RegI rcx, rFlagsReg cr) %{
+  match(Set dst (ExpD src));
+  effect(KILL rax, KILL rcx, KILL rdx, KILL cr);
+  format %{ "fast_exp $dst -> $src  // KILL $rax, $rcx, $rdx" %}
+  ins_encode %{
+    __ subptr(rsp, 8);
+    __ movdbl(Address(rsp, 0), $src$$XMMRegister);
+    __ fld_d(Address(rsp, 0));
+    __ fast_exp();
+    __ fstp_d(Address(rsp, 0));
+    __ movdbl($dst$$XMMRegister, Address(rsp, 0));
+    __ addptr(rsp, 8);
+  %}
+  ins_pipe( pipe_slow );
+%}
 
 //----------Arithmetic Conversion Instructions---------------------------------
 
@@ -10326,11 +10142,10 @@
   ins_pipe( pipe_slow );
 %}
 
-// The next instructions have long latency and use Int unit. Set high cost.
 instruct MoveI2F_reg_reg(regF dst, rRegI src) %{
   match(Set dst (MoveI2F src));
   effect(DEF dst, USE src);
-  ins_cost(300);
+  ins_cost(100);
   format %{ "movd    $dst,$src\t# MoveI2F" %}
   ins_encode %{
     __ movdl($dst$$XMMRegister, $src$$Register);
@@ -10341,7 +10156,7 @@
 instruct MoveL2D_reg_reg(regD dst, rRegL src) %{
   match(Set dst (MoveL2D src));
   effect(DEF dst, USE src);
-  ins_cost(300);
+  ins_cost(100);
   format %{ "movd    $dst,$src\t# MoveL2D" %}
   ins_encode %{
      __ movdq($dst$$XMMRegister, $src$$Register);
@@ -10349,172 +10164,6 @@
   ins_pipe( pipe_slow );
 %}
 
-// Replicate scalar to packed byte (1 byte) values in xmm
-instruct Repl8B_reg(regD dst, regD src) %{
-  match(Set dst (Replicate8B src));
-  format %{ "MOVDQA  $dst,$src\n\t"
-            "PUNPCKLBW $dst,$dst\n\t"
-            "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
-  ins_encode %{
-    if ($dst$$reg != $src$$reg) {
-      __ movdqa($dst$$XMMRegister, $src$$XMMRegister);
-    }
-    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Replicate scalar to packed byte (1 byte) values in xmm
-instruct Repl8B_rRegI(regD dst, rRegI src) %{
-  match(Set dst (Replicate8B src));
-  format %{ "MOVD    $dst,$src\n\t"
-            "PUNPCKLBW $dst,$dst\n\t"
-            "PSHUFLW $dst,$dst,0x00\t! replicate8B" %}
-  ins_encode %{
-    __ movdl($dst$$XMMRegister, $src$$Register);
-    __ punpcklbw($dst$$XMMRegister, $dst$$XMMRegister);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( pipe_slow );
-%}
-
-// Replicate scalar zero to packed byte (1 byte) values in xmm
-instruct Repl8B_immI0(regD dst, immI0 zero) %{
-  match(Set dst (Replicate8B zero));
-  format %{ "PXOR  $dst,$dst\t! replicate8B" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed shore (2 byte) values in xmm
-instruct Repl4S_reg(regD dst, regD src) %{
-  match(Set dst (Replicate4S src));
-  format %{ "PSHUFLW $dst,$src,0x00\t! replicate4S" %}
-  ins_encode %{
-    __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed shore (2 byte) values in xmm
-instruct Repl4S_rRegI(regD dst, rRegI src) %{
-  match(Set dst (Replicate4S src));
-  format %{ "MOVD    $dst,$src\n\t"
-            "PSHUFLW $dst,$dst,0x00\t! replicate4S" %}
-  ins_encode %{
-    __ movdl($dst$$XMMRegister, $src$$Register);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar zero to packed short (2 byte) values in xmm
-instruct Repl4S_immI0(regD dst, immI0 zero) %{
-  match(Set dst (Replicate4S zero));
-  format %{ "PXOR  $dst,$dst\t! replicate4S" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed char (2 byte) values in xmm
-instruct Repl4C_reg(regD dst, regD src) %{
-  match(Set dst (Replicate4C src));
-  format %{ "PSHUFLW $dst,$src,0x00\t! replicate4C" %}
-  ins_encode %{
-    __ pshuflw($dst$$XMMRegister, $src$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed char (2 byte) values in xmm
-instruct Repl4C_rRegI(regD dst, rRegI src) %{
-  match(Set dst (Replicate4C src));
-  format %{ "MOVD    $dst,$src\n\t"
-            "PSHUFLW $dst,$dst,0x00\t! replicate4C" %}
-  ins_encode %{
-    __ movdl($dst$$XMMRegister, $src$$Register);
-    __ pshuflw($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar zero to packed char (2 byte) values in xmm
-instruct Repl4C_immI0(regD dst, immI0 zero) %{
-  match(Set dst (Replicate4C zero));
-  format %{ "PXOR  $dst,$dst\t! replicate4C" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed integer (4 byte) values in xmm
-instruct Repl2I_reg(regD dst, regD src) %{
-  match(Set dst (Replicate2I src));
-  format %{ "PSHUFD $dst,$src,0x00\t! replicate2I" %}
-  ins_encode %{
-    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed integer (4 byte) values in xmm
-instruct Repl2I_rRegI(regD dst, rRegI src) %{
-  match(Set dst (Replicate2I src));
-  format %{ "MOVD   $dst,$src\n\t"
-            "PSHUFD $dst,$dst,0x00\t! replicate2I" %}
-  ins_encode %{
-    __ movdl($dst$$XMMRegister, $src$$Register);
-    __ pshufd($dst$$XMMRegister, $dst$$XMMRegister, 0x00);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar zero to packed integer (2 byte) values in xmm
-instruct Repl2I_immI0(regD dst, immI0 zero) %{
-  match(Set dst (Replicate2I zero));
-  format %{ "PXOR  $dst,$dst\t! replicate2I" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed single precision floating point values in xmm
-instruct Repl2F_reg(regD dst, regD src) %{
-  match(Set dst (Replicate2F src));
-  format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
-  ins_encode %{
-    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed single precision floating point values in xmm
-instruct Repl2F_regF(regD dst, regF src) %{
-  match(Set dst (Replicate2F src));
-  format %{ "PSHUFD $dst,$src,0xe0\t! replicate2F" %}
-  ins_encode %{
-    __ pshufd($dst$$XMMRegister, $src$$XMMRegister, 0xe0);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
-// Replicate scalar to packed single precision floating point values in xmm
-instruct Repl2F_immF0(regD dst, immF0 zero) %{
-  match(Set dst (Replicate2F zero));
-  format %{ "PXOR  $dst,$dst\t! replicate2F" %}
-  ins_encode %{
-    __ pxor($dst$$XMMRegister, $dst$$XMMRegister);
-  %}
-  ins_pipe( fpu_reg_reg );
-%}
-
 
 // =======================================================================
 // fast clearing of an array
diff --git a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
index ec2805b..f42ffce 100644
--- a/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/cppInterpreter_zero.cpp
@@ -646,16 +646,15 @@
   oop method_type = (oop) p;
 
   // The MethodHandle is in the slot after the arguments
-  oop form = java_lang_invoke_MethodType::form(method_type);
-  int num_vmslots = java_lang_invoke_MethodTypeForm::vmslots(form);
-  assert(argument_slots == num_vmslots + 1, "should be");
+  int num_vmslots = argument_slots - 1;
   oop method_handle = VMSLOTS_OBJECT(num_vmslots);
 
   // InvokeGeneric requires some extra shuffling
   oop mhtype = java_lang_invoke_MethodHandle::type(method_handle);
   bool is_exact = mhtype == method_type;
   if (!is_exact) {
-    if (method->intrinsic_id() == vmIntrinsics::_invokeExact) {
+    if (true || // FIXME
+        method->intrinsic_id() == vmIntrinsics::_invokeExact) {
       CALL_VM_NOCHECK_NOFIX(
         SharedRuntime::throw_WrongMethodTypeException(
           thread, method_type, mhtype));
@@ -670,8 +669,8 @@
     // NB the x86 code for this (in methodHandles_x86.cpp, search for
     // "genericInvoker") is really really odd.  I'm hoping it's trying
     // to accomodate odd VM/class library combinations I can ignore.
-    oop adapter = java_lang_invoke_MethodTypeForm::genericInvoker(form);
-    if (adapter == NULL) {
+    oop adapter = NULL; //FIXME: load the adapter from the CP cache
+    IF (adapter == NULL) {
       CALL_VM_NOCHECK_NOFIX(
         SharedRuntime::throw_WrongMethodTypeException(
           thread, method_type, mhtype));
@@ -761,7 +760,7 @@
           return;
       }
       if (entry_kind != MethodHandles::_invokespecial_mh) {
-        int index = java_lang_invoke_DirectMethodHandle::vmindex(method_handle);
+        intptr_t index = java_lang_invoke_DirectMethodHandle::vmindex(method_handle);
         instanceKlass* rcvrKlass =
           (instanceKlass *) receiver->klass()->klass_part();
         if (entry_kind == MethodHandles::_invokevirtual_mh) {
@@ -1179,8 +1178,7 @@
 intptr_t* CppInterpreter::calculate_unwind_sp(ZeroStack* stack,
                                               oop method_handle) {
   oop method_type = java_lang_invoke_MethodHandle::type(method_handle);
-  oop form = java_lang_invoke_MethodType::form(method_type);
-  int argument_slots = java_lang_invoke_MethodTypeForm::vmslots(form);
+  int argument_slots = java_lang_invoke_MethodType::ptype_slot_count(method_type);
 
   return stack->sp() + argument_slots;
 }
diff --git a/hotspot/src/cpu/zero/vm/globals_zero.hpp b/hotspot/src/cpu/zero/vm/globals_zero.hpp
index 6754e69..7e0ae86 100644
--- a/hotspot/src/cpu/zero/vm/globals_zero.hpp
+++ b/hotspot/src/cpu/zero/vm/globals_zero.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * Copyright 2007, 2008, 2009, 2010, 2011 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
@@ -60,4 +60,7 @@
 
 // GC Ergo Flags
 define_pd_global(intx, CMSYoungGenPerWorker, 16*M);  // default max size of CMS young gen, per GC worker thread
+
+#define ARCH_FLAGS(develop, product, diagnostic, experimental, notproduct)
+
 #endif // CPU_ZERO_VM_GLOBALS_ZERO_HPP
diff --git a/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp b/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp
index e583c83..322f62c 100644
--- a/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp
+++ b/hotspot/src/cpu/zero/vm/interpreterGenerator_zero.hpp
@@ -38,6 +38,5 @@
   address generate_empty_entry();
   address generate_accessor_entry();
   address generate_Reference_get_entry();
-  address generate_method_handle_entry();
 
 #endif // CPU_ZERO_VM_INTERPRETERGENERATOR_ZERO_HPP
diff --git a/hotspot/src/cpu/zero/vm/interpreter_zero.cpp b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp
index 93c3b90..c86a70c 100644
--- a/hotspot/src/cpu/zero/vm/interpreter_zero.cpp
+++ b/hotspot/src/cpu/zero/vm/interpreter_zero.cpp
@@ -70,14 +70,6 @@
   return generate_entry((address) ShouldNotCallThisEntry());
 }
 
-address InterpreterGenerator::generate_method_handle_entry() {
-#ifdef CC_INTERP
-  return generate_entry((address) CppInterpreter::method_handle_entry);
-#else
-  return generate_entry((address) ShouldNotCallThisEntry());
-#endif // CC_INTERP
-}
-
 bool AbstractInterpreter::can_be_compiled(methodHandle m) {
   return true;
 }
diff --git a/hotspot/src/os/bsd/vm/decoder_machO.cpp b/hotspot/src/os/bsd/vm/decoder_machO.cpp
index d77a32f..75250d1 100644
--- a/hotspot/src/os/bsd/vm/decoder_machO.cpp
+++ b/hotspot/src/os/bsd/vm/decoder_machO.cpp
@@ -26,6 +26,139 @@
 
 #ifdef __APPLE__
 #include "decoder_machO.hpp"
+
+#include <cxxabi.h>
+#include <mach-o/loader.h>
+#include <mach-o/nlist.h>
+
+
+bool MachODecoder::demangle(const char* symbol, char *buf, int buflen) {
+  int   status;
+  char* result;
+  size_t size = (size_t)buflen;
+  // Don't pass buf to __cxa_demangle. In case of the 'buf' is too small,
+  // __cxa_demangle will call system "realloc" for additional memory, which
+  // may use different malloc/realloc mechanism that allocates 'buf'.
+  if ((result = abi::__cxa_demangle(symbol, NULL, NULL, &status)) != NULL) {
+    jio_snprintf(buf, buflen, "%s", result);
+      // call c library's free
+      ::free(result);
+      return true;
+  }
+  return false;
+}
+
+bool MachODecoder::decode(address addr, char *buf,
+      int buflen, int *offset, const void *mach_base) {
+  struct symtab_command * symt = (struct symtab_command *)
+    mach_find_command((struct mach_header_64 *)mach_base, LC_SYMTAB);
+  if (symt == NULL) {
+    DEBUG_ONLY(tty->print_cr("no symtab in mach file at 0x%lx", mach_base));
+    return false;
+  }
+  uint32_t off = symt->symoff;          /* symbol table offset (within this mach file) */
+  uint32_t nsyms = symt->nsyms;         /* number of symbol table entries */
+  uint32_t stroff = symt->stroff;       /* string table offset */
+  uint32_t strsize = symt->strsize;     /* string table size in bytes */
+
+  // iterate through symbol table trying to match our offset
+
+  uint32_t addr_relative = (uintptr_t) mach_base - (uintptr_t) addr; // offset we seek in the symtab
+  void * symtab_addr = (void*) ((uintptr_t) mach_base + off);
+  struct nlist_64 *cur_nlist = (struct nlist_64 *) symtab_addr;
+  struct nlist_64 *last_nlist = cur_nlist;  // no size stored in an entry, so keep previously seen nlist
+
+  int32_t found_strx = 0;
+  int32_t found_symval = 0;
+
+  for (uint32_t i=0; i < nsyms; i++) {
+    uint32_t this_value = cur_nlist->n_value;
+
+    if (addr_relative == this_value) {
+      found_strx =  cur_nlist->n_un.n_strx;
+      found_symval = this_value;
+      break;
+    } else if (addr_relative > this_value) {
+      // gone past it, use previously seen nlist:
+      found_strx = last_nlist->n_un.n_strx;
+      found_symval = last_nlist->n_value;
+      break;
+    }
+    last_nlist = cur_nlist;
+    cur_nlist = cur_nlist + sizeof(struct nlist_64);
+  }
+  if (found_strx == 0) {
+    return false;
+  }
+  // write the offset:
+  *offset = addr_relative - found_symval;
+
+  // lookup found_strx in the string table
+  char * symname = mach_find_in_stringtable((char*) ((uintptr_t)mach_base + stroff), strsize, found_strx);
+  if (symname) {
+      strncpy(buf, symname, buflen);
+      return true;
+  }
+  DEBUG_ONLY(tty->print_cr("no string or null string found."));
+  return false;
+}
+
+void* MachODecoder::mach_find_command(struct mach_header_64 * mach_base, uint32_t command_wanted) {
+  // possibly verify it is a mach_header, use magic number.
+  // commands begin immediately after the header.
+  struct load_command *pos = (struct load_command *) mach_base + sizeof(struct mach_header_64);
+  for (uint32_t i = 0; i < mach_base->ncmds; i++) {
+    struct load_command *this_cmd = (struct load_command *) pos;
+    if (this_cmd->cmd == command_wanted) {
+       return pos;
+    }
+    int cmdsize = this_cmd->cmdsize;
+    pos += cmdsize;
+  }
+  return NULL;
+}
+
+char* MachODecoder::mach_find_in_stringtable(char *strtab, uint32_t tablesize, int strx_wanted) {
+
+  if (strx_wanted == 0) {
+    return NULL;
+  }
+  char *strtab_end = strtab + tablesize;
+
+  // find the first string, skip over the space char
+  // (or the four zero bytes we see e.g. in libclient)
+  if (*strtab == ' ') {
+      strtab++;
+      if (*strtab != 0) {
+          DEBUG_ONLY(tty->print_cr("string table has leading space but no following zero."));
+          return NULL;
+      }
+      strtab++;
+  } else {
+      if ((uint32_t) *strtab != 0) {
+          DEBUG_ONLY(tty->print_cr("string table without leading space or leading int of zero."));
+          return NULL;
+      }
+      strtab+=4;
+  }
+  // read the real strings starting at index 1
+  int cur_strx = 1;
+  while (strtab < strtab_end) {
+    if (cur_strx == strx_wanted) {
+        return strtab;
+    }
+    // find start of next string
+    while (*strtab != 0) {
+        strtab++;
+    }
+    strtab++; // skip the terminating zero
+    cur_strx++;
+  }
+  DEBUG_ONLY(tty->print_cr("string number %d not found.", strx_wanted));
+  return NULL;
+}
+
+
 #endif
 
 
diff --git a/hotspot/src/os/bsd/vm/decoder_machO.hpp b/hotspot/src/os/bsd/vm/decoder_machO.hpp
index 9fb1689..25dedc6 100644
--- a/hotspot/src/os/bsd/vm/decoder_machO.hpp
+++ b/hotspot/src/os/bsd/vm/decoder_machO.hpp
@@ -31,10 +31,25 @@
 
 // Just a placehold for now, a real implementation should derive
 // from AbstractDecoder
-class MachODecoder : public NullDecoder {
-public:
+class MachODecoder : public AbstractDecoder {
+ public:
   MachODecoder() { }
   ~MachODecoder() { }
+  virtual bool can_decode_C_frame_in_vm() const {
+    return true;
+  }
+  virtual bool demangle(const char* symbol, char* buf, int buflen);
+  virtual bool decode(address pc, char* buf, int buflen, int* offset,
+                      const void* base);
+  virtual bool decode(address pc, char* buf, int buflen, int* offset,
+                      const char* module_path = NULL) {
+    ShouldNotReachHere();
+    return false;
+  }
+
+ private:
+  void * mach_find_command(struct mach_header_64 * mach_base, uint32_t command_wanted);
+  char * mach_find_in_stringtable(char *strtab, uint32_t tablesize, int strx_wanted);
 };
 
 #endif
diff --git a/hotspot/src/os/bsd/vm/osThread_bsd.hpp b/hotspot/src/os/bsd/vm/osThread_bsd.hpp
index 0e60cc3..c72b360 100644
--- a/hotspot/src/os/bsd/vm/osThread_bsd.hpp
+++ b/hotspot/src/os/bsd/vm/osThread_bsd.hpp
@@ -42,26 +42,19 @@
 #ifdef _ALLBSD_SOURCE
 
 #ifdef __APPLE__
-  thread_t  _thread_id;
+  typedef thread_t thread_id_t;
 #else
-  pthread_t _thread_id;
+  typedef pthread_t thread_id_t;
+#endif
+
+#else
+  typedef pid_t thread_id_t;
 #endif
 
   // _pthread_id is the pthread id, which is used by library calls
   // (e.g. pthread_kill).
   pthread_t _pthread_id;
 
-#else
-  // _thread_id is kernel thread id (similar to LWP id on Solaris). Each
-  // thread has a unique thread_id (BsdThreads or NPTL). It can be used
-  // to access /proc.
-  pid_t     _thread_id;
-
-  // _pthread_id is the pthread id, which is used by library calls
-  // (e.g. pthread_kill).
-  pthread_t _pthread_id;
-#endif
-
   sigset_t _caller_sigmask; // Caller's signal mask
 
  public:
@@ -70,25 +63,11 @@
   sigset_t  caller_sigmask() const       { return _caller_sigmask; }
   void    set_caller_sigmask(sigset_t sigmask)  { _caller_sigmask = sigmask; }
 
-#ifdef _ALLBSD_SOURCE
-#ifdef __APPLE__
-  thread_t thread_id() const {
-    return _thread_id;
-  }
-#else
-  pthread_t thread_id() const {
-    return _thread_id;
-  }
-#endif
-#else
-  pid_t thread_id() const {
-    return _thread_id;
-  }
-#endif
 #ifndef PRODUCT
   // Used for debugging, return a unique integer for each thread.
   intptr_t thread_identifier() const   { return (intptr_t)_pthread_id; }
 #endif
+
 #ifdef ASSERT
   // We expect no reposition failures so kill vm if we get one.
   //
@@ -96,21 +75,7 @@
     return false;
   }
 #endif // ASSERT
-#ifdef _ALLBSD_SOURCE
-#ifdef __APPLE__
-  void set_thread_id(thread_t id) {
-    _thread_id = id;
-  }
-#else
-  void set_thread_id(pthread_t id) {
-    _thread_id = id;
-  }
-#endif
-#else
-  void set_thread_id(pid_t id) {
-    _thread_id = id;
-  }
-#endif
+
   pthread_t pthread_id() const {
     return _pthread_id;
   }
diff --git a/hotspot/src/os/bsd/vm/os_bsd.cpp b/hotspot/src/os/bsd/vm/os_bsd.cpp
index f9b21ac..984e25c 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.cpp
@@ -82,12 +82,6 @@
 # include "assembler_ppc.inline.hpp"
 # include "nativeInst_ppc.hpp"
 #endif
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 // put OS-includes here
 # include <sys/types.h>
@@ -440,7 +434,7 @@
   // code needs to be changed accordingly.
 
   // The next few definitions allow the code to be verbatim:
-#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n))
+#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal)
 #define getenv(n) ::getenv(n)
 
 /*
@@ -1913,11 +1907,11 @@
     // release the storage
     for (int i = 0 ; i < n ; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i]);
+        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements);
+      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
     }
   } else {
     snprintf(buffer, buflen, "%s/" JNI_LIB_PREFIX "%s" JNI_LIB_SUFFIX, pname, fname);
@@ -1946,10 +1940,16 @@
   return false;
 }
 
+
+#define MACH_MAXSYMLEN 256
+
 bool os::dll_address_to_function_name(address addr, char *buf,
                                       int buflen, int *offset) {
   Dl_info dlinfo;
+  char localbuf[MACH_MAXSYMLEN];
 
+  // dladdr will find names of dynamic functions only, but does
+  // it set dli_fbase with mach_header address when it "fails" ?
   if (dladdr((void*)addr, &dlinfo) && dlinfo.dli_sname != NULL) {
     if (buf != NULL) {
       if(!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
@@ -1965,6 +1965,14 @@
     }
   }
 
+  // Handle non-dymanic manually:
+  if (dlinfo.dli_fbase != NULL &&
+      Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset, dlinfo.dli_fbase)) {
+    if(!Decoder::demangle(localbuf, buf, buflen)) {
+      jio_snprintf(buf, buflen, "%s", localbuf);
+    }
+    return true;
+  }
   if (buf != NULL) buf[0] = '\0';
   if (offset != NULL) *offset = -1;
   return false;
@@ -2766,7 +2774,7 @@
 //       All it does is to check if there are enough free pages
 //       left at the time of mmap(). This could be a potential
 //       problem.
-bool os::commit_memory(char* addr, size_t size, bool exec) {
+bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
 #ifdef __OpenBSD__
   // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
@@ -2790,7 +2798,7 @@
 #endif
 #endif
 
-bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
                        bool exec) {
 #ifndef _ALLBSD_SOURCE
   if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
@@ -2806,7 +2814,7 @@
   return commit_memory(addr, size, exec);
 }
 
-void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
+void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
 #ifndef _ALLBSD_SOURCE
   if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
     // We don't check the return value: madvise(MADV_HUGEPAGE) may not
@@ -2816,7 +2824,7 @@
 #endif
 }
 
-void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) {
+void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {
   ::madvise(addr, bytes, MADV_DONTNEED);
 }
 
@@ -2958,7 +2966,7 @@
 unsigned long* os::Bsd::_numa_all_nodes;
 #endif
 
-bool os::uncommit_memory(char* addr, size_t size) {
+bool os::pd_uncommit_memory(char* addr, size_t size) {
 #ifdef __OpenBSD__
   // XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD
   return ::mprotect(addr, size, PROT_NONE) == 0;
@@ -2969,7 +2977,7 @@
 #endif
 }
 
-bool os::create_stack_guard_pages(char* addr, size_t size) {
+bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
   return os::commit_memory(addr, size);
 }
 
@@ -3023,12 +3031,12 @@
   return ::munmap(addr, size) == 0;
 }
 
-char* os::reserve_memory(size_t bytes, char* requested_addr,
+char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
                          size_t alignment_hint) {
   return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
 }
 
-bool os::release_memory(char* addr, size_t size) {
+bool os::pd_release_memory(char* addr, size_t size) {
   return anon_munmap(addr, size);
 }
 
@@ -3331,7 +3339,7 @@
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
-char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
   const int max_tries = 10;
   char* base[max_tries];
   size_t size[max_tries];
@@ -4987,7 +4995,7 @@
 }
 
 // Map a block of memory.
-char* os::map_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
                      char *addr, size_t bytes, bool read_only,
                      bool allow_exec) {
   int prot;
@@ -5019,7 +5027,7 @@
 
 
 // Remap a block of memory.
-char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
                        char *addr, size_t bytes, bool read_only,
                        bool allow_exec) {
   // same as map_memory() on this OS
@@ -5029,7 +5037,7 @@
 
 
 // Unmap a block of memory.
-bool os::unmap_memory(char* addr, size_t bytes) {
+bool os::pd_unmap_memory(char* addr, size_t bytes) {
   return munmap(addr, bytes) == 0;
 }
 
@@ -5801,3 +5809,14 @@
 
     return true;
 }
+
+// Get the default path to the core file
+// Returns the length of the string
+int os::get_core_path(char* buffer, size_t bufferSize) {
+  int n = jio_snprintf(buffer, bufferSize, "/cores");
+
+  // Truncate if theoretical string was longer than bufferSize
+  n = MIN2(n, (int)bufferSize);
+
+  return n;
+}
diff --git a/hotspot/src/os/bsd/vm/os_bsd.hpp b/hotspot/src/os/bsd/vm/os_bsd.hpp
index 271d1e2..d9ab28a 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.hpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -202,7 +202,7 @@
   static void fast_thread_clock_init(void);
 #endif
 
-  static bool supports_monotonic_clock() {
+  static inline bool supports_monotonic_clock() {
     return _clock_gettime != NULL;
   }
 
@@ -312,7 +312,7 @@
 };
 
 
-class PlatformEvent : public CHeapObj {
+class PlatformEvent : public CHeapObj<mtInternal> {
   private:
     double CachePad [4] ;   // increase odds that _mutex is sole occupant of cache line
     volatile int _Event ;
@@ -347,7 +347,7 @@
     void SetAssociation (Thread * a) { _Assoc = a ; }
 } ;
 
-class PlatformParker : public CHeapObj {
+class PlatformParker : public CHeapObj<mtInternal> {
   protected:
     pthread_mutex_t _mutex [1] ;
     pthread_cond_t  _cond  [1] ;
diff --git a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
index c582a45..9980d46 100644
--- a/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
+++ b/hotspot/src/os/bsd/vm/os_bsd.inline.hpp
@@ -95,7 +95,7 @@
 
 
 // On Bsd, reservations are made on a page by page basis, nothing to do.
-inline void os::split_reserved_memory(char *base, size_t size,
+inline void os::pd_split_reserved_memory(char *base, size_t size,
                                       size_t split, bool realloc) {
 }
 
diff --git a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
index c93289e..2d0a03c 100644
--- a/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
+++ b/hotspot/src/os/bsd/vm/perfMemory_bsd.cpp
@@ -30,6 +30,7 @@
 #include "os_bsd.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/perfMemory.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
 
 // put OS-includes here
@@ -126,7 +127,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(char, destfile);
+  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
 }
 
 
@@ -153,7 +154,7 @@
   const char* tmpdir = os::get_temp_directory();
   const char* perfdir = PERFDATA_NAME;
   size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
-  char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   // construct the path name to user specific tmp directory
   snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
@@ -246,7 +247,7 @@
   if (bufsize == -1)
     bufsize = 1024;
 
-  char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize);
+  char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
 
   // POSIX interface to getpwuid_r is used on LINUX
   struct passwd* p;
@@ -278,14 +279,14 @@
                                      "pw_name zero length");
       }
     }
-    FREE_C_HEAP_ARRAY(char, pwbuf);
+    FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
     return NULL;
   }
 
-  char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1);
+  char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
   strcpy(user_name, p->pw_name);
 
-  FREE_C_HEAP_ARRAY(char, pwbuf);
+  FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
   return user_name;
 }
 
@@ -328,7 +329,7 @@
   // to determine the user name for the process id.
   //
   struct dirent* dentry;
-  char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
+  char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
   errno = 0;
   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 
@@ -338,7 +339,7 @@
     }
 
     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
-                              strlen(tmpdirname) + strlen(dentry->d_name) + 2);
+                 strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
     strcpy(usrdir_name, tmpdirname);
     strcat(usrdir_name, "/");
     strcat(usrdir_name, dentry->d_name);
@@ -346,7 +347,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
+      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
       continue;
     }
 
@@ -357,13 +358,13 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
+      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
       os::closedir(subdirp);
       continue;
     }
 
     struct dirent* udentry;
-    char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name));
+    char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
     errno = 0;
     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 
@@ -372,7 +373,7 @@
         int result;
 
         char* filename = NEW_C_HEAP_ARRAY(char,
-                            strlen(usrdir_name) + strlen(udentry->d_name) + 2);
+                 strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 
         strcpy(filename, usrdir_name);
         strcat(filename, "/");
@@ -381,13 +382,13 @@
         // don't follow symbolic links for the file
         RESTARTABLE(::lstat(filename, &statbuf), result);
         if (result == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename);
+           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
            continue;
         }
 
         // skip over files that are not regular files.
         if (!S_ISREG(statbuf.st_mode)) {
-          FREE_C_HEAP_ARRAY(char, filename);
+          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
           continue;
         }
 
@@ -397,23 +398,23 @@
           if (statbuf.st_ctime > oldest_ctime) {
             char* user = strchr(dentry->d_name, '_') + 1;
 
-            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
-            oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
+            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+            oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
             strcpy(oldest_user, user);
             oldest_ctime = statbuf.st_ctime;
           }
         }
 
-        FREE_C_HEAP_ARRAY(char, filename);
+        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf);
-    FREE_C_HEAP_ARRAY(char, usrdir_name);
+    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf);
+  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
 
   return(oldest_user);
 }
@@ -434,7 +435,7 @@
   // add 2 for the file separator and a null terminator.
   size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
 
-  char* name = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
   snprintf(name, nbytes, "%s/%d", dirname, vmid);
 
   return name;
@@ -472,7 +473,7 @@
 static void remove_file(const char* dirname, const char* filename) {
 
   size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   strcpy(path, dirname);
   strcat(path, "/");
@@ -480,7 +481,7 @@
 
   remove_file(path);
 
-  FREE_C_HEAP_ARRAY(char, path);
+  FREE_C_HEAP_ARRAY(char, path, mtInternal);
 }
 
 
@@ -517,7 +518,7 @@
   // opendir/readdir.
   //
   struct dirent* entry;
-  char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname));
+  char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -556,7 +557,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf);
+  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
 }
 
 // make the user specific temporary directory. Returns true if
@@ -723,11 +724,11 @@
 
   fd = create_sharedmem_resources(dirname, filename, size);
 
-  FREE_C_HEAP_ARRAY(char, user_name);
-  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
 
   if (fd == -1) {
-    FREE_C_HEAP_ARRAY(char, filename);
+    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
     return NULL;
   }
 
@@ -743,7 +744,7 @@
       warning("mmap failed -  %s\n", strerror(errno));
     }
     remove_file(filename);
-    FREE_C_HEAP_ARRAY(char, filename);
+    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
     return NULL;
   }
 
@@ -753,6 +754,10 @@
   // clear the shared memory region
   (void)::memset((void*) mapAddress, 0, size);
 
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC);
+  MemTracker::record_virtual_memory_type((address)mapAddress, mtInternal);
+
   return mapAddress;
 }
 
@@ -869,7 +874,7 @@
   // store file, we don't follow them when attaching either.
   //
   if (!is_directory_secure(dirname)) {
-    FREE_C_HEAP_ARRAY(char, dirname);
+    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Process not found");
   }
@@ -884,9 +889,9 @@
   strcpy(rfilename, filename);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
-  FREE_C_HEAP_ARRAY(char, dirname);
-  FREE_C_HEAP_ARRAY(char, filename);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 
   // open the shared memory file for the give vmid
   fd = open_sharedmem_file(rfilename, file_flags, CHECK);
@@ -912,6 +917,10 @@
               "Could not map PerfMemory");
   }
 
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC);
+  MemTracker::record_virtual_memory_type((address)mapAddress, mtInternal);
+
   *addr = mapAddress;
   *sizep = size;
 
diff --git a/hotspot/src/os/linux/vm/osThread_linux.hpp b/hotspot/src/os/linux/vm/osThread_linux.hpp
index 2294513..904ab52 100644
--- a/hotspot/src/os/linux/vm/osThread_linux.hpp
+++ b/hotspot/src/os/linux/vm/osThread_linux.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -24,6 +24,8 @@
 
 #ifndef OS_LINUX_VM_OSTHREAD_LINUX_HPP
 #define OS_LINUX_VM_OSTHREAD_LINUX_HPP
+ public:
+  typedef pid_t thread_id_t;
 
  private:
   int _thread_type;
@@ -37,13 +39,6 @@
     _thread_type = type;
   }
 
- private:
-
-  // _thread_id is kernel thread id (similar to LWP id on Solaris). Each
-  // thread has a unique thread_id (LinuxThreads or NPTL). It can be used
-  // to access /proc.
-  pid_t     _thread_id;
-
   // _pthread_id is the pthread id, which is used by library calls
   // (e.g. pthread_kill).
   pthread_t _pthread_id;
@@ -56,9 +51,6 @@
   sigset_t  caller_sigmask() const       { return _caller_sigmask; }
   void    set_caller_sigmask(sigset_t sigmask)  { _caller_sigmask = sigmask; }
 
-  pid_t thread_id() const {
-    return _thread_id;
-  }
 #ifndef PRODUCT
   // Used for debugging, return a unique integer for each thread.
   int thread_identifier() const   { return _thread_id; }
@@ -70,9 +62,6 @@
     return false;
   }
 #endif // ASSERT
-  void set_thread_id(pid_t id) {
-    _thread_id = id;
-  }
   pthread_t pthread_id() const {
     return _pthread_id;
   }
diff --git a/hotspot/src/os/linux/vm/os_linux.cpp b/hotspot/src/os/linux/vm/os_linux.cpp
index 70ac4d3..d2f92f8 100644
--- a/hotspot/src/os/linux/vm/os_linux.cpp
+++ b/hotspot/src/os/linux/vm/os_linux.cpp
@@ -82,12 +82,6 @@
 # include "assembler_ppc.inline.hpp"
 # include "nativeInst_ppc.hpp"
 #endif
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 // put OS-includes here
 # include <sys/types.h>
@@ -371,7 +365,7 @@
   // code needs to be changed accordingly.
 
   // The next few definitions allow the code to be verbatim:
-#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n))
+#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal)
 #define getenv(n) ::getenv(n)
 
 /*
@@ -639,7 +633,7 @@
 
   size_t n = confstr(_CS_GNU_LIBC_VERSION, NULL, 0);
   if (n > 0) {
-     char *str = (char *)malloc(n);
+     char *str = (char *)malloc(n, mtInternal);
      confstr(_CS_GNU_LIBC_VERSION, str, n);
      os::Linux::set_glibc_version(str);
   } else {
@@ -652,7 +646,7 @@
 
   n = confstr(_CS_GNU_LIBPTHREAD_VERSION, NULL, 0);
   if (n > 0) {
-     char *str = (char *)malloc(n);
+     char *str = (char *)malloc(n, mtInternal);
      confstr(_CS_GNU_LIBPTHREAD_VERSION, str, n);
      // Vanilla RH-9 (glibc 2.3.2) has a bug that confstr() always tells
      // us "NPTL-0.29" even we are running with LinuxThreads. Check if this
@@ -1685,11 +1679,11 @@
     // release the storage
     for (int i = 0 ; i < n ; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i]);
+        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements);
+      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
     }
   } else {
     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
@@ -2469,7 +2463,7 @@
 //       All it does is to check if there are enough free pages
 //       left at the time of mmap(). This could be a potential
 //       problem.
-bool os::commit_memory(char* addr, size_t size, bool exec) {
+bool os::pd_commit_memory(char* addr, size_t size, bool exec) {
   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
   uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,
                                    MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
@@ -2492,7 +2486,7 @@
 #define MADV_HUGEPAGE 14
 #endif
 
-bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
                        bool exec) {
   if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
     int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
@@ -2516,7 +2510,7 @@
   return false;
 }
 
-void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
+void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
   if (UseHugeTLBFS && alignment_hint > (size_t)vm_page_size()) {
     // We don't check the return value: madvise(MADV_HUGEPAGE) may not
     // be supported or the memory may already be backed by huge pages.
@@ -2524,8 +2518,15 @@
   }
 }
 
-void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) {
-  commit_memory(addr, bytes, alignment_hint, false);
+void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {
+  // This method works by doing an mmap over an existing mmaping and effectively discarding
+  // the existing pages. However it won't work for SHM-based large pages that cannot be
+  // uncommitted at all. We don't do anything in this case to avoid creating a segment with
+  // small pages on top of the SHM segment. This method always works for small pages, so we
+  // allow that in any case.
+  if (alignment_hint <= (size_t)os::vm_page_size() || !UseSHM) {
+    commit_memory(addr, bytes, alignment_hint, false);
+  }
 }
 
 void os::numa_make_global(char *addr, size_t bytes) {
@@ -2639,7 +2640,7 @@
       if (numa_available() != -1) {
         set_numa_all_nodes((unsigned long*)libnuma_dlsym(handle, "numa_all_nodes"));
         // Create a cpu -> node mapping
-        _cpu_to_node = new (ResourceObj::C_HEAP) GrowableArray<int>(0, true);
+        _cpu_to_node = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(0, true);
         rebuild_cpu_to_node_map();
         return true;
       }
@@ -2669,7 +2670,7 @@
   cpu_to_node()->at_grow(cpu_num - 1);
   size_t node_num = numa_get_groups_num();
 
-  unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size);
+  unsigned long *cpu_map = NEW_C_HEAP_ARRAY(unsigned long, cpu_map_size, mtInternal);
   for (size_t i = 0; i < node_num; i++) {
     if (numa_node_to_cpus(i, cpu_map, cpu_map_size * sizeof(unsigned long)) != -1) {
       for (size_t j = 0; j < cpu_map_valid_size; j++) {
@@ -2683,7 +2684,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(unsigned long, cpu_map);
+  FREE_C_HEAP_ARRAY(unsigned long, cpu_map, mtInternal);
 }
 
 int os::Linux::get_node_by_cpu(int cpu_id) {
@@ -2702,7 +2703,7 @@
 os::Linux::numa_interleave_memory_func_t os::Linux::_numa_interleave_memory;
 unsigned long* os::Linux::_numa_all_nodes;
 
-bool os::uncommit_memory(char* addr, size_t size) {
+bool os::pd_uncommit_memory(char* addr, size_t size) {
   uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,
                 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);
   return res  != (uintptr_t) MAP_FAILED;
@@ -2767,7 +2768,7 @@
 // munmap() the guard pages we don't leave a hole in the stack
 // mapping. This only affects the main/initial thread, but guard
 // against future OS changes
-bool os::create_stack_guard_pages(char* addr, size_t size) {
+bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
   uintptr_t stack_extent, stack_base;
   bool chk_bounds = NOT_DEBUG(os::Linux::is_initial_thread()) DEBUG_ONLY(true);
   if (chk_bounds && get_stack_bounds(&stack_extent, &stack_base)) {
@@ -2840,12 +2841,12 @@
   return ::munmap(addr, size) == 0;
 }
 
-char* os::reserve_memory(size_t bytes, char* requested_addr,
+char* os::pd_reserve_memory(size_t bytes, char* requested_addr,
                          size_t alignment_hint) {
   return anon_mmap(requested_addr, bytes, (requested_addr != NULL));
 }
 
-bool os::release_memory(char* addr, size_t size) {
+bool os::pd_release_memory(char* addr, size_t size) {
   return anon_munmap(addr, size);
 }
 
@@ -3142,7 +3143,7 @@
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
-char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
   const int max_tries = 10;
   char* base[max_tries];
   size_t size[max_tries];
@@ -4664,7 +4665,7 @@
 }
 
 // Map a block of memory.
-char* os::map_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
                      char *addr, size_t bytes, bool read_only,
                      bool allow_exec) {
   int prot;
@@ -4694,7 +4695,7 @@
 
 
 // Remap a block of memory.
-char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
                        char *addr, size_t bytes, bool read_only,
                        bool allow_exec) {
   // same as map_memory() on this OS
@@ -4704,7 +4705,7 @@
 
 
 // Unmap a block of memory.
-bool os::unmap_memory(char* addr, size_t bytes) {
+bool os::pd_unmap_memory(char* addr, size_t bytes) {
   return munmap(addr, bytes) == 0;
 }
 
@@ -5440,6 +5441,18 @@
     return true;
 }
 
+// Get the default path to the core file
+// Returns the length of the string
+int os::get_core_path(char* buffer, size_t bufferSize) {
+  const char* p = get_current_directory(buffer, bufferSize);
+
+  if (p == NULL) {
+    assert(p != NULL, "failed to get current directory");
+    return 0;
+  }
+
+  return strlen(buffer);
+}
 
 #ifdef JAVASE_EMBEDDED
 //
diff --git a/hotspot/src/os/linux/vm/os_linux.hpp b/hotspot/src/os/linux/vm/os_linux.hpp
index 7c19517..7bbc041 100644
--- a/hotspot/src/os/linux/vm/os_linux.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -178,7 +178,7 @@
   // fast POSIX clocks support
   static void fast_thread_clock_init(void);
 
-  static bool supports_monotonic_clock() {
+  static inline bool supports_monotonic_clock() {
     return _clock_gettime != NULL;
   }
 
@@ -287,7 +287,7 @@
 };
 
 
-class PlatformEvent : public CHeapObj {
+class PlatformEvent : public CHeapObj<mtInternal> {
   private:
     double CachePad [4] ;   // increase odds that _mutex is sole occupant of cache line
     volatile int _Event ;
@@ -322,7 +322,7 @@
     void SetAssociation (Thread * a) { _Assoc = a ; }
 } ;
 
-class PlatformParker : public CHeapObj {
+class PlatformParker : public CHeapObj<mtInternal> {
   protected:
     pthread_mutex_t _mutex [1] ;
     pthread_cond_t  _cond  [1] ;
diff --git a/hotspot/src/os/linux/vm/os_linux.inline.hpp b/hotspot/src/os/linux/vm/os_linux.inline.hpp
index 566c0ad..c663c9b 100644
--- a/hotspot/src/os/linux/vm/os_linux.inline.hpp
+++ b/hotspot/src/os/linux/vm/os_linux.inline.hpp
@@ -99,7 +99,7 @@
 
 
 // On Linux, reservations are made on a page by page basis, nothing to do.
-inline void os::split_reserved_memory(char *base, size_t size,
+inline void os::pd_split_reserved_memory(char *base, size_t size,
                                       size_t split, bool realloc) {
 }
 
diff --git a/hotspot/src/os/linux/vm/perfMemory_linux.cpp b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
index 1cd430c..edd9a4f 100644
--- a/hotspot/src/os/linux/vm/perfMemory_linux.cpp
+++ b/hotspot/src/os/linux/vm/perfMemory_linux.cpp
@@ -30,6 +30,7 @@
 #include "os_linux.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/perfMemory.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
 
 // put OS-includes here
@@ -126,7 +127,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(char, destfile);
+  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
 }
 
 
@@ -153,7 +154,7 @@
   const char* tmpdir = os::get_temp_directory();
   const char* perfdir = PERFDATA_NAME;
   size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
-  char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   // construct the path name to user specific tmp directory
   snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
@@ -246,7 +247,7 @@
   if (bufsize == -1)
     bufsize = 1024;
 
-  char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize);
+  char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
 
   // POSIX interface to getpwuid_r is used on LINUX
   struct passwd* p;
@@ -278,14 +279,14 @@
                                      "pw_name zero length");
       }
     }
-    FREE_C_HEAP_ARRAY(char, pwbuf);
+    FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
     return NULL;
   }
 
-  char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1);
+  char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
   strcpy(user_name, p->pw_name);
 
-  FREE_C_HEAP_ARRAY(char, pwbuf);
+  FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
   return user_name;
 }
 
@@ -328,7 +329,7 @@
   // to determine the user name for the process id.
   //
   struct dirent* dentry;
-  char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
+  char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
   errno = 0;
   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 
@@ -338,7 +339,7 @@
     }
 
     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
-                              strlen(tmpdirname) + strlen(dentry->d_name) + 2);
+                     strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
     strcpy(usrdir_name, tmpdirname);
     strcat(usrdir_name, "/");
     strcat(usrdir_name, dentry->d_name);
@@ -346,7 +347,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
+      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
       continue;
     }
 
@@ -357,13 +358,13 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
+      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
       os::closedir(subdirp);
       continue;
     }
 
     struct dirent* udentry;
-    char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name));
+    char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
     errno = 0;
     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 
@@ -372,7 +373,7 @@
         int result;
 
         char* filename = NEW_C_HEAP_ARRAY(char,
-                            strlen(usrdir_name) + strlen(udentry->d_name) + 2);
+                   strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 
         strcpy(filename, usrdir_name);
         strcat(filename, "/");
@@ -381,13 +382,13 @@
         // don't follow symbolic links for the file
         RESTARTABLE(::lstat(filename, &statbuf), result);
         if (result == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename);
+           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
            continue;
         }
 
         // skip over files that are not regular files.
         if (!S_ISREG(statbuf.st_mode)) {
-          FREE_C_HEAP_ARRAY(char, filename);
+          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
           continue;
         }
 
@@ -397,23 +398,23 @@
           if (statbuf.st_ctime > oldest_ctime) {
             char* user = strchr(dentry->d_name, '_') + 1;
 
-            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
-            oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
+            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+            oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
             strcpy(oldest_user, user);
             oldest_ctime = statbuf.st_ctime;
           }
         }
 
-        FREE_C_HEAP_ARRAY(char, filename);
+        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf);
-    FREE_C_HEAP_ARRAY(char, usrdir_name);
+    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf);
+  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
 
   return(oldest_user);
 }
@@ -434,7 +435,7 @@
   // add 2 for the file separator and a null terminator.
   size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
 
-  char* name = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
   snprintf(name, nbytes, "%s/%d", dirname, vmid);
 
   return name;
@@ -472,7 +473,7 @@
 static void remove_file(const char* dirname, const char* filename) {
 
   size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   strcpy(path, dirname);
   strcat(path, "/");
@@ -480,7 +481,7 @@
 
   remove_file(path);
 
-  FREE_C_HEAP_ARRAY(char, path);
+  FREE_C_HEAP_ARRAY(char, path, mtInternal);
 }
 
 
@@ -517,7 +518,7 @@
   // opendir/readdir.
   //
   struct dirent* entry;
-  char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname));
+  char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -556,7 +557,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf);
+  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
 }
 
 // make the user specific temporary directory. Returns true if
@@ -723,11 +724,11 @@
 
   fd = create_sharedmem_resources(dirname, filename, size);
 
-  FREE_C_HEAP_ARRAY(char, user_name);
-  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
 
   if (fd == -1) {
-    FREE_C_HEAP_ARRAY(char, filename);
+    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
     return NULL;
   }
 
@@ -743,7 +744,7 @@
       warning("mmap failed -  %s\n", strerror(errno));
     }
     remove_file(filename);
-    FREE_C_HEAP_ARRAY(char, filename);
+    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
     return NULL;
   }
 
@@ -753,6 +754,10 @@
   // clear the shared memory region
   (void)::memset((void*) mapAddress, 0, size);
 
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC);
+  MemTracker::record_virtual_memory_type((address)mapAddress, mtInternal);
+
   return mapAddress;
 }
 
@@ -869,7 +874,7 @@
   // store file, we don't follow them when attaching either.
   //
   if (!is_directory_secure(dirname)) {
-    FREE_C_HEAP_ARRAY(char, dirname);
+    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Process not found");
   }
@@ -884,9 +889,9 @@
   strcpy(rfilename, filename);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
-  FREE_C_HEAP_ARRAY(char, dirname);
-  FREE_C_HEAP_ARRAY(char, filename);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 
   // open the shared memory file for the give vmid
   fd = open_sharedmem_file(rfilename, file_flags, CHECK);
@@ -912,6 +917,10 @@
               "Could not map PerfMemory");
   }
 
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC);
+  MemTracker::record_virtual_memory_type((address)mapAddress, mtInternal);
+
   *addr = mapAddress;
   *sizep = size;
 
diff --git a/hotspot/src/os/linux/vm/vmError_linux.cpp b/hotspot/src/os/linux/vm/vmError_linux.cpp
index 8ec6ca0..378c9a6 100644
--- a/hotspot/src/os/linux/vm/vmError_linux.cpp
+++ b/hotspot/src/os/linux/vm/vmError_linux.cpp
@@ -44,7 +44,7 @@
     jio_snprintf(p, buflen - len,
                "\n\n"
                "Do you want to debug the problem?\n\n"
-               "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n"
+               "To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " UINTX_FORMAT " (" INTPTR_FORMAT ")\n"
                "Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"
                "Otherwise, press RETURN to abort...",
                os::current_process_id(), os::current_process_id(),
diff --git a/hotspot/src/os/posix/launcher/launcher.script b/hotspot/src/os/posix/launcher/launcher.script
index c4db5a4..4f5fff8 100644
--- a/hotspot/src/os/posix/launcher/launcher.script
+++ b/hotspot/src/os/posix/launcher/launcher.script
@@ -29,7 +29,7 @@
 # inside Emacs".
 #
 # If the first parameter is "-dbx", HotSpot will be launched inside dbx.
-# 
+#
 # If the first parameter is "-valgrind", HotSpot will be launched
 # inside Valgrind (http://valgrind.kde.org) using the Memcheck skin,
 # and with memory leak detection enabled.  This currently (2005jan19)
@@ -45,19 +45,19 @@
 
 # This is the name of the gdb binary to use
 if [ ! "$GDB" ]
-then 
+then
     GDB=gdb
 fi
 
 # This is the name of the gdb binary to use
 if [ ! "$DBX" ]
-then 
+then
     DBX=dbx
 fi
 
 # This is the name of the Valgrind binary to use
 if [ ! "$VALGRIND" ]
-then 
+then
     VALGRIND=valgrind
 fi
 
@@ -98,7 +98,7 @@
 JDK=
 if [ "${ALT_JAVA_HOME}" = "" ]; then
     . ${MYDIR}/jdkpath.sh
-else 
+else
     JDK=${ALT_JAVA_HOME%%/jre};
 fi
 
@@ -114,22 +114,34 @@
 # any.
 JRE=$JDK/jre
 JAVA_HOME=$JDK
-ARCH=@@LIBARCH@@
+export JAVA_HOME
 
+ARCH=@@LIBARCH@@
 SBP=${MYDIR}:${JRE}/lib/${ARCH}
 
-# Set up a suitable LD_LIBRARY_PATH
 
-if [ -z "$LD_LIBRARY_PATH" ]
+# Set up a suitable LD_LIBRARY_PATH or DYLD_LIBRARY_PATH
+OS=`uname -s`
+if [ "${OS}" = "Darwin" ]
 then
-    LD_LIBRARY_PATH="$SBP"
+    if [ -z "$DYLD_LIBRARY_PATH" ]
+    then
+        DYLD_LIBRARY_PATH="$SBP"
+    else
+        DYLD_LIBRARY_PATH="$SBP:$DYLD_LIBRARY_PATH"
+    fi
+    export DYLD_LIBRARY_PATH
 else
-    LD_LIBRARY_PATH="$SBP:$LD_LIBRARY_PATH"
+    # not 'Darwin'
+    if [ -z "$LD_LIBRARY_PATH" ]
+    then
+        LD_LIBRARY_PATH="$SBP"
+    else
+        LD_LIBRARY_PATH="$SBP:$LD_LIBRARY_PATH"
+    fi
+    export LD_LIBRARY_PATH
 fi
 
-export LD_LIBRARY_PATH
-export JAVA_HOME
-
 JPARMS="$@ $JAVA_ARGS";
 
 # Locate the gamma development launcher
diff --git a/hotspot/src/os/posix/vm/os_posix.cpp b/hotspot/src/os/posix/vm/os_posix.cpp
index 9f05a74..f7891df 100644
--- a/hotspot/src/os/posix/vm/os_posix.cpp
+++ b/hotspot/src/os/posix/vm/os_posix.cpp
@@ -23,6 +23,7 @@
 */
 
 #include "prims/jvm.h"
+#include "runtime/frame.inline.hpp"
 #include "runtime/os.hpp"
 #include "utilities/vmError.hpp"
 
@@ -33,19 +34,19 @@
 
 // Check core dump limit and report possible place where core can be found
 void os::check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize) {
+  int n;
   struct rlimit rlim;
-  static char cwd[O_BUFLEN];
   bool success;
 
-  get_current_directory(cwd, sizeof(cwd));
+  n = get_core_path(buffer, bufferSize);
 
   if (getrlimit(RLIMIT_CORE, &rlim) != 0) {
-    jio_snprintf(buffer, bufferSize, "%s/core or core.%d (may not exist)", cwd, current_process_id());
+    jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (may not exist)", current_process_id());
     success = true;
   } else {
     switch(rlim.rlim_cur) {
       case RLIM_INFINITY:
-        jio_snprintf(buffer, bufferSize, "%s/core or core.%d", cwd, current_process_id());
+        jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d", current_process_id());
         success = true;
         break;
       case 0:
@@ -53,7 +54,7 @@
         success = false;
         break;
       default:
-        jio_snprintf(buffer, bufferSize, "%s/core or core.%d (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", cwd, current_process_id(), (unsigned long)(rlim.rlim_cur >> 10));
+        jio_snprintf(buffer + n, bufferSize - n, "/core or core.%d (max size %lu kB). To ensure a full core dump, try \"ulimit -c unlimited\" before starting Java again", current_process_id(), (unsigned long)(rlim.rlim_cur >> 10));
         success = true;
         break;
     }
@@ -61,6 +62,23 @@
   VMError::report_coredump_status(buffer, success);
 }
 
+address os::get_caller_pc(int n) {
+#ifdef _NMT_NOINLINE_
+  n ++;
+#endif
+  frame fr = os::current_frame();
+  while (n > 0 && fr.pc() &&
+    !os::is_first_C_frame(&fr) && fr.sender_pc()) {
+    fr = os::get_sender_for_C_frame(&fr);
+    n --;
+  }
+  if (n == 0) {
+    return fr.pc();
+  } else {
+    return NULL;
+  }
+}
+
 int os::get_last_error() {
   return errno;
 }
@@ -75,6 +93,47 @@
   return;
 }
 
+// Multiple threads can race in this code, and can remap over each other with MAP_FIXED,
+// so on posix, unmap the section at the start and at the end of the chunk that we mapped
+// rather than unmapping and remapping the whole chunk to get requested alignment.
+char* os::reserve_memory_aligned(size_t size, size_t alignment) {
+  assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
+      "Alignment must be a multiple of allocation granularity (page size)");
+  assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
+
+  size_t extra_size = size + alignment;
+  assert(extra_size >= size, "overflow, size is too large to allow alignment");
+
+  char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+
+  if (extra_base == NULL) {
+    return NULL;
+  }
+
+  // Do manual alignment
+  char* aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);
+
+  // [  |                                       |  ]
+  // ^ extra_base
+  //    ^ extra_base + begin_offset == aligned_base
+  //     extra_base + begin_offset + size       ^
+  //                       extra_base + extra_size ^
+  // |<>| == begin_offset
+  //                              end_offset == |<>|
+  size_t begin_offset = aligned_base - extra_base;
+  size_t end_offset = (extra_base + extra_size) - (aligned_base + size);
+
+  if (begin_offset > 0) {
+      os::release_memory(extra_base, begin_offset);
+  }
+
+  if (end_offset > 0) {
+      os::release_memory(extra_base + begin_offset + size, end_offset);
+  }
+
+  return aligned_base;
+}
+
 void os::Posix::print_load_average(outputStream* st) {
   st->print("load average:");
   double loadavg[3];
diff --git a/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp b/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp
index 0226431..9457ab4 100644
--- a/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp
+++ b/hotspot/src/os/solaris/dtrace/generateJvmOffsets.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -220,10 +220,10 @@
   printf("\n");
 
   GEN_OFFS(methodOopDesc, _constMethod);
-  GEN_OFFS(methodOopDesc, _constants);
   GEN_OFFS(methodOopDesc, _access_flags);
   printf("\n");
 
+  GEN_OFFS(constMethodOopDesc, _constants);
   GEN_OFFS(constMethodOopDesc, _flags);
   GEN_OFFS(constMethodOopDesc, _code_size);
   GEN_OFFS(constMethodOopDesc, _name_index);
diff --git a/hotspot/src/os/solaris/dtrace/hs_private.d b/hotspot/src/os/solaris/dtrace/hs_private.d
index 23463a4..df395e5 100644
--- a/hotspot/src/os/solaris/dtrace/hs_private.d
+++ b/hotspot/src/os/solaris/dtrace/hs_private.d
@@ -23,7 +23,6 @@
  */
 
 provider hs_private {
-  probe hashtable__new_entry(void*, uintptr_t, void*); 
   probe safepoint__begin();
   probe safepoint__end();
   probe cms__initmark__begin();
diff --git a/hotspot/src/os/solaris/dtrace/jhelper.d b/hotspot/src/os/solaris/dtrace/jhelper.d
index 75e7426..ad68ac1 100644
--- a/hotspot/src/os/solaris/dtrace/jhelper.d
+++ b/hotspot/src/os/solaris/dtrace/jhelper.d
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -118,7 +118,7 @@
   copyin_offset(OFFSET_Symbol_body);
 
   copyin_offset(OFFSET_methodOopDesc_constMethod);
-  copyin_offset(OFFSET_methodOopDesc_constants);
+  copyin_offset(OFFSET_constMethodOopDesc_constants);
   copyin_offset(OFFSET_constMethodOopDesc_name_index);
   copyin_offset(OFFSET_constMethodOopDesc_signature_index);
 
@@ -359,8 +359,8 @@
   this->signatureIndex = copyin_uint16(this->constMethod +
       OFFSET_constMethodOopDesc_signature_index);
 
-  this->constantPool = copyin_ptr(this->methodOopPtr +
-      OFFSET_methodOopDesc_constants);
+  this->constantPool = copyin_ptr(this->constMethod +
+      OFFSET_constMethodOopDesc_constants);
 
   this->nameSymbol = copyin_ptr(this->constantPool +
       this->nameIndex * sizeof (pointer) + SIZE_constantPoolOopDesc);
diff --git a/hotspot/src/os/solaris/dtrace/libjvm_db.c b/hotspot/src/os/solaris/dtrace/libjvm_db.c
index 8caac23..62304ec 100644
--- a/hotspot/src/os/solaris/dtrace/libjvm_db.c
+++ b/hotspot/src/os/solaris/dtrace/libjvm_db.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -514,10 +514,10 @@
   char * signatureString = NULL;
   int err;
 
-  err = read_pointer(J, methodOopPtr + OFFSET_methodOopDesc_constants, &constantPool);
-  CHECK_FAIL(err);
   err = read_pointer(J, methodOopPtr + OFFSET_methodOopDesc_constMethod, &constMethod);
   CHECK_FAIL(err);
+  err = read_pointer(J, constMethod + OFFSET_constMethodOopDesc_constants, &constantPool);
+  CHECK_FAIL(err);
 
   /* To get name string */
   err = ps_pread(J->P, constMethod + OFFSET_constMethodOopDesc_name_index, &nameIndex, 2);
diff --git a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp
index b56a32a..b5b38bd 100644
--- a/hotspot/src/os/solaris/vm/attachListener_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/attachListener_solaris.cpp
@@ -336,7 +336,9 @@
     // Return 0 (success) + file descriptor, or non-0 (error)
     if (res == 0) {
       door_desc_t desc;
-      desc.d_attributes = DOOR_DESCRIPTOR;
+      // DOOR_RELEASE flag makes sure fd is closed after passing it to
+      // the client.  See door_return(3DOOR) man page.
+      desc.d_attributes = DOOR_DESCRIPTOR | DOOR_RELEASE;
       desc.d_data.d_desc.d_descriptor = return_fd;
       door_return((char*)&res, sizeof(res), &desc, 1);
     } else {
diff --git a/hotspot/src/os/solaris/vm/dtraceJSDT_solaris.cpp b/hotspot/src/os/solaris/vm/dtraceJSDT_solaris.cpp
index 60baff5..4884930 100644
--- a/hotspot/src/os/solaris/vm/dtraceJSDT_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/dtraceJSDT_solaris.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -626,45 +626,6 @@
   }
 }
 
-/**
- * This prints out hex data in a 'windbg' or 'xxd' form, where each line is:
- *   <hex-address>: 8 * <hex-halfword> <ascii translation>
- * example:
- * 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000  .DOF............
- * 0000010: 0000 0000 0000 0040 0000 0020 0000 0005  .......@... ....
- * 0000020: 0000 0000 0000 0040 0000 0000 0000 015d  .......@.......]
- * ...
- */
-static void printDOFRawData(void* dof) {
-  size_t size = ((dof_hdr_t*)dof)->dofh_loadsz;
-  size_t limit = (size + 16) / 16 * 16;
-  for (size_t i = 0; i < limit; ++i) {
-    if (i % 16 == 0) {
-      tty->print("%07x:", i);
-    }
-    if (i % 2 == 0) {
-      tty->print(" ");
-    }
-    if (i < size) {
-      tty->print("%02x", ((unsigned char*)dof)[i]);
-    } else {
-      tty->print("  ");
-    }
-    if ((i + 1) % 16 == 0) {
-      tty->print("  ");
-      for (size_t j = 0; j < 16; ++j) {
-        size_t idx = i + j - 15;
-        char c = ((char*)dof)[idx];
-        if (idx < size) {
-          tty->print("%c", c >= 32 && c <= 126 ? c : '.');
-        }
-      }
-      tty->print_cr("");
-    }
-  }
-  tty->print_cr("");
-}
-
 static void printDOFHelper(dof_helper_t* helper) {
   tty->print_cr("// dof_helper_t {");
   tty->print_cr("//   dofhp_mod = \"%s\"", helper->dofhp_mod);
@@ -672,7 +633,8 @@
   tty->print_cr("//   dofhp_dof = 0x%016llx", helper->dofhp_dof);
   printDOF((void*)helper->dofhp_dof);
   tty->print_cr("// }");
-  printDOFRawData((void*)helper->dofhp_dof);
+  size_t len = ((dof_hdr_t*)helper)->dofh_loadsz;
+  tty->print_data((void*)helper->dofhp_dof, len, true);
 }
 
 #else // ndef HAVE_DTRACE_H
diff --git a/hotspot/src/os/solaris/vm/osThread_solaris.hpp b/hotspot/src/os/solaris/vm/osThread_solaris.hpp
index 7fe1417..2a7a247 100644
--- a/hotspot/src/os/solaris/vm/osThread_solaris.hpp
+++ b/hotspot/src/os/solaris/vm/osThread_solaris.hpp
@@ -26,9 +26,10 @@
 #define OS_SOLARIS_VM_OSTHREAD_SOLARIS_HPP
 
 // This is embedded via include into the class OSThread
+ public:
+  typedef thread_t thread_id_t;
 
  private:
-  thread_t _thread_id;         // Solaris thread id
   uint     _lwp_id;            // lwp ID, only used with bound threads
   int      _native_priority;   // Saved native priority when starting
                                // a bound thread
@@ -36,7 +37,6 @@
   bool     _vm_created_thread; // true if the VM created this thread,
                                // false if primary thread or attached thread
  public:
-  thread_t thread_id() const       { return _thread_id; }
   uint     lwp_id() const          { return _lwp_id; }
   int      native_priority() const { return _native_priority; }
 
@@ -62,7 +62,6 @@
     return true;
   }
 #endif
-  void set_thread_id(thread_t id)    { _thread_id = id; }
   void set_lwp_id(uint id)           { _lwp_id = id; }
   void set_native_priority(int prio) { _native_priority = prio; }
 
diff --git a/hotspot/src/os/solaris/vm/os_solaris.cpp b/hotspot/src/os/solaris/vm/os_solaris.cpp
index b29a9d2..f16cedabd 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.cpp
@@ -55,6 +55,7 @@
 #include "runtime/threadCritical.hpp"
 #include "runtime/timer.hpp"
 #include "services/attachListener.hpp"
+#include "services/memTracker.hpp"
 #include "services/runtimeService.hpp"
 #include "thread_solaris.inline.hpp"
 #include "utilities/decoder.hpp"
@@ -70,12 +71,6 @@
 # include "assembler_sparc.inline.hpp"
 # include "nativeInst_sparc.hpp"
 #endif
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 // put OS-includes here
 # include <dlfcn.h>
@@ -546,7 +541,7 @@
   // Find the number of processors in the processor set.
   if (pset_info(pset, NULL, id_length, NULL) == 0) {
     // Make up an array to hold their ids.
-    *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length);
+    *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal);
     // Fill in the array with their processor ids.
     if (pset_info(pset, NULL, id_length, *id_array) == 0) {
       result = true;
@@ -577,7 +572,7 @@
   // Find the number of processors online.
   *id_length = sysconf(_SC_NPROCESSORS_ONLN);
   // Make up an array to hold their ids.
-  *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length);
+  *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal);
   // Processors need not be numbered consecutively.
   long found = 0;
   processorid_t next = 0;
@@ -629,7 +624,7 @@
   // The next id, to limit loops.
   const processorid_t limit_id = max_id + 1;
   // Make up markers for available processors.
-  bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id);
+  bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id, mtInternal);
   for (uint c = 0; c < limit_id; c += 1) {
     available_id[c] = false;
   }
@@ -666,7 +661,7 @@
     }
   }
   if (available_id != NULL) {
-    FREE_C_HEAP_ARRAY(bool, available_id);
+    FREE_C_HEAP_ARRAY(bool, available_id, mtInternal);
   }
   return true;
 }
@@ -698,7 +693,7 @@
     }
   }
   if (id_array != NULL) {
-    FREE_C_HEAP_ARRAY(processorid_t, id_array);
+    FREE_C_HEAP_ARRAY(processorid_t, id_array, mtInternal);
   }
   return result;
 }
@@ -771,8 +766,8 @@
   // code needs to be changed accordingly.
 
   // The next few definitions allow the code to be verbatim:
-#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n))
-#define free(p) FREE_C_HEAP_ARRAY(char, p)
+#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal)
+#define free(p) FREE_C_HEAP_ARRAY(char, p, mtInternal)
 #define getenv(n) ::getenv(n)
 
 #define EXTENSIONS_DIR  "/lib/ext"
@@ -1013,15 +1008,6 @@
   // use debugger to set breakpoint here
 }
 
-// Returns an estimate of the current stack pointer. Result must be guaranteed to
-// point into the calling threads stack, and be no lower than the current stack
-// pointer.
-address os::current_stack_pointer() {
-  volatile int dummy;
-  address sp = (address)&dummy + 8;     // %%%% need to confirm if this is right
-  return sp;
-}
-
 static thread_t main_thread;
 
 // Thread start routine for all new Java threads
@@ -1497,11 +1483,11 @@
 
 
 // First crack at OS-specific initialization, from inside the new thread.
-void os::initialize_thread() {
+void os::initialize_thread(Thread* thr) {
   int r = thr_main() ;
   guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
   if (r) {
-    JavaThread* jt = (JavaThread *)Thread::current();
+    JavaThread* jt = (JavaThread *)thr;
     assert(jt != NULL,"Sanity check");
     size_t stack_size;
     address base = jt->stack_base();
@@ -1936,11 +1922,11 @@
     // release the storage
     for (int i = 0 ; i < n ; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i]);
+        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements);
+      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
     }
   } else {
     snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
@@ -2671,17 +2657,17 @@
 
   // pending_signals has one int per signal
   // The additional signal is for SIGEXIT - exit signal to signal_thread
-  pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1));
+  pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1), mtInternal);
   memset(pending_signals, 0, (sizeof(jint) * (Sigexit+1)));
 
   if (UseSignalChaining) {
      chainedsigactions = (struct sigaction *)malloc(sizeof(struct sigaction)
-       * (Maxsignum + 1));
+       * (Maxsignum + 1), mtInternal);
      memset(chainedsigactions, 0, (sizeof(struct sigaction) * (Maxsignum + 1)));
-     preinstalled_sigs = (int *)os::malloc(sizeof(int) * (Maxsignum + 1));
+     preinstalled_sigs = (int *)os::malloc(sizeof(int) * (Maxsignum + 1), mtInternal);
      memset(preinstalled_sigs, 0, (sizeof(int) * (Maxsignum + 1)));
   }
-  ourSigFlags = (int*)malloc(sizeof(int) * (Maxsignum + 1 ));
+  ourSigFlags = (int*)malloc(sizeof(int) * (Maxsignum + 1 ), mtInternal);
   memset(ourSigFlags, 0, sizeof(int) * (Maxsignum + 1));
 }
 
@@ -2769,7 +2755,7 @@
   return page_size;
 }
 
-bool os::commit_memory(char* addr, size_t bytes, bool exec) {
+bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
   int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
   size_t size = bytes;
   char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
@@ -2782,7 +2768,7 @@
   return false;
 }
 
-bool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint,
+bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint,
                        bool exec) {
   if (commit_memory(addr, bytes, exec)) {
     if (UseMPSS && alignment_hint > (size_t)vm_page_size()) {
@@ -2812,14 +2798,14 @@
 }
 
 // Uncommit the pages in a specified region.
-void os::free_memory(char* addr, size_t bytes, size_t alignment_hint) {
+void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) {
   if (madvise(addr, bytes, MADV_FREE) < 0) {
     debug_only(warning("MADV_FREE failed."));
     return;
   }
 }
 
-bool os::create_stack_guard_pages(char* addr, size_t size) {
+bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
   return os::commit_memory(addr, size);
 }
 
@@ -2828,7 +2814,7 @@
 }
 
 // Change the page size in a given range.
-void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
+void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
   assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
   assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned.");
   if (UseLargePages && UseMPSS) {
@@ -3015,7 +3001,7 @@
   return end;
 }
 
-bool os::uncommit_memory(char* addr, size_t bytes) {
+bool os::pd_uncommit_memory(char* addr, size_t bytes) {
   size_t size = bytes;
   // Map uncommitted pages PROT_NONE so we fail early if we touch an
   // uncommitted page. Otherwise, the read/write might succeed if we
@@ -3054,7 +3040,7 @@
   return mmap_chunk(addr, bytes, flags, PROT_NONE);
 }
 
-char* os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
+char* os::pd_reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
   char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL));
 
   guarantee(requested_addr == NULL || requested_addr == addr,
@@ -3065,7 +3051,7 @@
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
 
-char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
   const int max_tries = 10;
   char* base[max_tries];
   size_t size[max_tries];
@@ -3087,11 +3073,12 @@
   // Since snv_84, Solaris attempts to honor the address hint - see 5003415.
   // Give it a try, if the kernel honors the hint we can return immediately.
   char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false);
+
   volatile int err = errno;
   if (addr == requested_addr) {
     return addr;
   } else if (addr != NULL) {
-    unmap_memory(addr, bytes);
+    pd_unmap_memory(addr, bytes);
   }
 
   if (PrintMiscellaneous && Verbose) {
@@ -3187,7 +3174,7 @@
   return (i < max_tries) ? requested_addr : NULL;
 }
 
-bool os::release_memory(char* addr, size_t bytes) {
+bool os::pd_release_memory(char* addr, size_t bytes) {
   size_t size = bytes;
   return munmap(addr, size) == 0;
 }
@@ -4801,7 +4788,7 @@
   lwpSize = 16*1024;
   for (;;) {
     ::lseek64 (lwpFile, 0, SEEK_SET);
-    lwpArray = (prheader_t *)NEW_C_HEAP_ARRAY(char, lwpSize);
+    lwpArray = (prheader_t *)NEW_C_HEAP_ARRAY(char, lwpSize, mtInternal);
     if (::read(lwpFile, lwpArray, lwpSize) < 0) {
       if (ThreadPriorityVerbose) warning("Error reading /proc/self/lstatus\n");
       break;
@@ -4819,10 +4806,10 @@
       break;
     }
     lwpSize = lwpArray->pr_nent * lwpArray->pr_entsize;
-    FREE_C_HEAP_ARRAY(char, lwpArray);  // retry.
+    FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal);  // retry.
   }
 
-  FREE_C_HEAP_ARRAY(char, lwpArray);
+  FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal);
   ::close (lwpFile);
   if (ThreadPriorityVerbose) {
     if (isT2) tty->print_cr("We are running with a T2 libthread\n");
@@ -5146,9 +5133,9 @@
       UseNUMA = false;
     } else {
       size_t lgrp_limit = os::numa_get_groups_num();
-      int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit);
+      int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal);
       size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
-      FREE_C_HEAP_ARRAY(int, lgrp_ids);
+      FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal);
       if (lgrp_num < 2) {
         // There's only one locality group, disable NUMA.
         UseNUMA = false;
@@ -5494,7 +5481,7 @@
 }
 
 // Map a block of memory.
-char* os::map_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
                      char *addr, size_t bytes, bool read_only,
                      bool allow_exec) {
   int prot;
@@ -5526,7 +5513,7 @@
 
 
 // Remap a block of memory.
-char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
                        char *addr, size_t bytes, bool read_only,
                        bool allow_exec) {
   // same as map_memory() on this OS
@@ -5536,7 +5523,7 @@
 
 
 // Unmap a block of memory.
-bool os::unmap_memory(char* addr, size_t bytes) {
+bool os::pd_unmap_memory(char* addr, size_t bytes) {
   return munmap(addr, bytes) == 0;
 }
 
@@ -6546,3 +6533,16 @@
    INTERRUPTIBLE_RETURN_INT_NORESTART(::bind(fd, him, len),\
                                       os::Solaris::clear_interrupted);
 }
+
+// Get the default path to the core file
+// Returns the length of the string
+int os::get_core_path(char* buffer, size_t bufferSize) {
+  const char* p = get_current_directory(buffer, bufferSize);
+
+  if (p == NULL) {
+    assert(p != NULL, "failed to get current directory");
+    return 0;
+  }
+
+  return strlen(buffer);
+}
diff --git a/hotspot/src/os/solaris/vm/os_solaris.hpp b/hotspot/src/os/solaris/vm/os_solaris.hpp
index 340aa4b..174f252 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.hpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.hpp
@@ -346,7 +346,7 @@
 
 };
 
-class PlatformEvent : public CHeapObj {
+class PlatformEvent : public CHeapObj<mtInternal> {
   private:
     double CachePad [4] ;   // increase odds that _mutex is sole occupant of cache line
     volatile int _Event ;
@@ -383,7 +383,7 @@
     void unpark () ;
 } ;
 
-class PlatformParker : public CHeapObj {
+class PlatformParker : public CHeapObj<mtInternal> {
   protected:
     mutex_t _mutex [1] ;
     cond_t  _cond  [1] ;
diff --git a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
index 7b63bad..2468100 100644
--- a/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
+++ b/hotspot/src/os/solaris/vm/os_solaris.inline.hpp
@@ -71,7 +71,7 @@
 
 
 // On Solaris, reservations are made on a page by page basis, nothing to do.
-inline void os::split_reserved_memory(char *base, size_t size,
+inline void os::pd_split_reserved_memory(char *base, size_t size,
                                       size_t split, bool realloc) {
 }
 
diff --git a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
index 1d1ff26..91a7a6f 100644
--- a/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
+++ b/hotspot/src/os/solaris/vm/perfMemory_solaris.cpp
@@ -30,6 +30,7 @@
 #include "os_solaris.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/perfMemory.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
 
 // put OS-includes here
@@ -128,7 +129,7 @@
       }
     }
   }
-  FREE_C_HEAP_ARRAY(char, destfile);
+  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
 }
 
 
@@ -155,7 +156,7 @@
   const char* tmpdir = os::get_temp_directory();
   const char* perfdir = PERFDATA_NAME;
   size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
-  char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   // construct the path name to user specific tmp directory
   snprintf(dirname, nbytes, "%s/%s_%s", tmpdir, perfdir, user);
@@ -248,7 +249,7 @@
   if (bufsize == -1)
     bufsize = 1024;
 
-  char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize);
+  char* pwbuf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
 
 #ifdef _GNU_SOURCE
   struct passwd* p = NULL;
@@ -269,14 +270,14 @@
                                      "pw_name zero length");
       }
     }
-    FREE_C_HEAP_ARRAY(char, pwbuf);
+    FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
     return NULL;
   }
 
-  char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1);
+  char* user_name = NEW_C_HEAP_ARRAY(char, strlen(p->pw_name) + 1, mtInternal);
   strcpy(user_name, p->pw_name);
 
-  FREE_C_HEAP_ARRAY(char, pwbuf);
+  FREE_C_HEAP_ARRAY(char, pwbuf, mtInternal);
   return user_name;
 }
 
@@ -319,7 +320,7 @@
   // to determine the user name for the process id.
   //
   struct dirent* dentry;
-  char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
+  char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
   errno = 0;
   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 
@@ -329,7 +330,7 @@
     }
 
     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
-                              strlen(tmpdirname) + strlen(dentry->d_name) + 2);
+                  strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
     strcpy(usrdir_name, tmpdirname);
     strcat(usrdir_name, "/");
     strcat(usrdir_name, dentry->d_name);
@@ -337,7 +338,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
+      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
       continue;
     }
 
@@ -348,13 +349,13 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
+      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
       os::closedir(subdirp);
       continue;
     }
 
     struct dirent* udentry;
-    char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name));
+    char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
     errno = 0;
     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 
@@ -363,7 +364,7 @@
         int result;
 
         char* filename = NEW_C_HEAP_ARRAY(char,
-                            strlen(usrdir_name) + strlen(udentry->d_name) + 2);
+                 strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 
         strcpy(filename, usrdir_name);
         strcat(filename, "/");
@@ -372,13 +373,13 @@
         // don't follow symbolic links for the file
         RESTARTABLE(::lstat(filename, &statbuf), result);
         if (result == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename);
+           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
            continue;
         }
 
         // skip over files that are not regular files.
         if (!S_ISREG(statbuf.st_mode)) {
-          FREE_C_HEAP_ARRAY(char, filename);
+          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
           continue;
         }
 
@@ -388,23 +389,23 @@
           if (statbuf.st_ctime > oldest_ctime) {
             char* user = strchr(dentry->d_name, '_') + 1;
 
-            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user);
-            oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
+            if (oldest_user != NULL) FREE_C_HEAP_ARRAY(char, oldest_user, mtInternal);
+            oldest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
             strcpy(oldest_user, user);
             oldest_ctime = statbuf.st_ctime;
           }
         }
 
-        FREE_C_HEAP_ARRAY(char, filename);
+        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf);
-    FREE_C_HEAP_ARRAY(char, usrdir_name);
+    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf);
+  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
 
   return(oldest_user);
 }
@@ -471,7 +472,7 @@
   // add 2 for the file separator and a NULL terminator.
   size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
 
-  char* name = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
   snprintf(name, nbytes, "%s/%d", dirname, vmid);
 
   return name;
@@ -509,7 +510,7 @@
 static void remove_file(const char* dirname, const char* filename) {
 
   size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   strcpy(path, dirname);
   strcat(path, "/");
@@ -517,7 +518,7 @@
 
   remove_file(path);
 
-  FREE_C_HEAP_ARRAY(char, path);
+  FREE_C_HEAP_ARRAY(char, path, mtInternal);
 }
 
 
@@ -554,7 +555,7 @@
   // opendir/readdir.
   //
   struct dirent* entry;
-  char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname));
+  char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -593,7 +594,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf);
+  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
 }
 
 // make the user specific temporary directory. Returns true if
@@ -738,11 +739,11 @@
 
   fd = create_sharedmem_resources(dirname, filename, size);
 
-  FREE_C_HEAP_ARRAY(char, user_name);
-  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, user_name, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
 
   if (fd == -1) {
-    FREE_C_HEAP_ARRAY(char, filename);
+    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
     return NULL;
   }
 
@@ -758,7 +759,7 @@
       warning("mmap failed -  %s\n", strerror(errno));
     }
     remove_file(filename);
-    FREE_C_HEAP_ARRAY(char, filename);
+    FREE_C_HEAP_ARRAY(char, filename, mtInternal);
     return NULL;
   }
 
@@ -768,6 +769,10 @@
   // clear the shared memory region
   (void)::memset((void*) mapAddress, 0, size);
 
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC);
+  MemTracker::record_virtual_memory_type((address)mapAddress, mtInternal);
+
   return mapAddress;
 }
 
@@ -884,7 +889,7 @@
   // store file, we don't follow them when attaching either.
   //
   if (!is_directory_secure(dirname)) {
-    FREE_C_HEAP_ARRAY(char, dirname);
+    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Process not found");
   }
@@ -899,9 +904,9 @@
   strcpy(rfilename, filename);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
-  FREE_C_HEAP_ARRAY(char, dirname);
-  FREE_C_HEAP_ARRAY(char, filename);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
 
   // open the shared memory file for the give vmid
   fd = open_sharedmem_file(rfilename, file_flags, CHECK);
@@ -927,6 +932,10 @@
               "Could not map PerfMemory");
   }
 
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC);
+  MemTracker::record_virtual_memory_type((address)mapAddress, mtInternal);
+
   *addr = mapAddress;
   *sizep = size;
 
diff --git a/hotspot/src/os/windows/vm/decoder_windows.cpp b/hotspot/src/os/windows/vm/decoder_windows.cpp
index 847e231..6500e59 100644
--- a/hotspot/src/os/windows/vm/decoder_windows.cpp
+++ b/hotspot/src/os/windows/vm/decoder_windows.cpp
@@ -72,10 +72,10 @@
 
      // find out if jvm.dll contains private symbols, by decoding
      // current function and comparing the result
-     address addr = (address)Decoder::decode;
+     address addr = (address)Decoder::demangle;
      char buf[MAX_PATH];
      if (decode(addr, buf, sizeof(buf), NULL)) {
-       _can_decode_in_vm = !strcmp(buf, "Decoder::decode");
+       _can_decode_in_vm = !strcmp(buf, "Decoder::demangle");
      }
   }
 }
diff --git a/hotspot/src/os/windows/vm/decoder_windows.hpp b/hotspot/src/os/windows/vm/decoder_windows.hpp
index 05a5dc2..ad80e5b 100644
--- a/hotspot/src/os/windows/vm/decoder_windows.hpp
+++ b/hotspot/src/os/windows/vm/decoder_windows.hpp
@@ -45,6 +45,10 @@
   bool can_decode_C_frame_in_vm() const;
   bool demangle(const char* symbol, char *buf, int buflen);
   bool decode(address addr, char *buf, int buflen, int* offset, const char* modulepath = NULL);
+  bool decode(address addr, char *buf, int buflen, int* offset, const void* base) {
+    ShouldNotReachHere();
+    return false;
+  }
 
 private:
   void initialize();
diff --git a/hotspot/src/os/windows/vm/jvm_windows.h b/hotspot/src/os/windows/vm/jvm_windows.h
index a45f86c..9103982 100644
--- a/hotspot/src/os/windows/vm/jvm_windows.h
+++ b/hotspot/src/os/windows/vm/jvm_windows.h
@@ -59,7 +59,7 @@
 
 #include <Tlhelp32.h>
 
-typedef unsigned int socklen_t;
+typedef int socklen_t;
 
 // #include "jni.h"
 
diff --git a/hotspot/src/os/windows/vm/osThread_windows.hpp b/hotspot/src/os/windows/vm/osThread_windows.hpp
index 1df8925..af07695 100644
--- a/hotspot/src/os/windows/vm/osThread_windows.hpp
+++ b/hotspot/src/os/windows/vm/osThread_windows.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,12 +25,13 @@
 #ifndef OS_WINDOWS_VM_OSTHREAD_WINDOWS_HPP
 #define OS_WINDOWS_VM_OSTHREAD_WINDOWS_HPP
 
-typedef void* HANDLE;
+  typedef void* HANDLE;
+ public:
+  typedef unsigned long thread_id_t;
 
  private:
   // Win32-specific thread information
   HANDLE _thread_handle;        // Win32 thread handle
-  unsigned long _thread_id;     // Win32 thread id
   HANDLE _interrupt_event;      // Event signalled on thread interrupt
   ThreadState _last_state;
 
@@ -42,7 +43,6 @@
   HANDLE interrupt_event() const                   { return _interrupt_event; }
   void set_interrupt_event(HANDLE interrupt_event) { _interrupt_event = interrupt_event; }
 
-  unsigned long thread_id() const                  { return _thread_id; }
 #ifndef PRODUCT
   // Used for debugging, return a unique integer for each thread.
   int thread_identifier() const                    { return _thread_id; }
@@ -54,8 +54,6 @@
     return false;
   }
 #endif // ASSERT
-  void set_thread_id(unsigned long thread_id)      { _thread_id = thread_id; }
-
   bool is_try_mutex_enter()                        { return false; }
 
   // This is a temporary fix for the thread states during
diff --git a/hotspot/src/os/windows/vm/os_windows.cpp b/hotspot/src/os/windows/vm/os_windows.cpp
index e2ecf53..64837ec 100644
--- a/hotspot/src/os/windows/vm/os_windows.cpp
+++ b/hotspot/src/os/windows/vm/os_windows.cpp
@@ -69,12 +69,6 @@
 # include "assembler_x86.inline.hpp"
 # include "nativeInst_x86.hpp"
 #endif
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 #ifdef _DEBUG
 #include <crtdbg.h>
@@ -96,7 +90,6 @@
 #include <io.h>
 #include <process.h>              // For _beginthreadex(), _endthreadex()
 #include <imagehlp.h>             // For os::dll_address_to_function_name
-
 /* for enumerating dll libraries */
 #include <vdmdbg.h>
 
@@ -214,13 +207,13 @@
           }
       }
 
-      home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1);
+      home_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + 1, mtInternal);
       if (home_path == NULL)
           return;
       strcpy(home_path, home_dir);
       Arguments::set_java_home(home_path);
 
-      dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1);
+      dll_path = NEW_C_HEAP_ARRAY(char, strlen(home_dir) + strlen(bin) + 1, mtInternal);
       if (dll_path == NULL)
           return;
       strcpy(dll_path, home_dir);
@@ -251,7 +244,7 @@
     char *path_str = ::getenv("PATH");
 
     library_path = NEW_C_HEAP_ARRAY(char, MAX_PATH * 5 + sizeof(PACKAGE_DIR) +
-        sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10);
+        sizeof(BIN_DIR) + (path_str ? strlen(path_str) : 0) + 10, mtInternal);
 
     library_path[0] = '\0';
 
@@ -280,7 +273,7 @@
     strcat(library_path, ";.");
 
     Arguments::set_library_path(library_path);
-    FREE_C_HEAP_ARRAY(char, library_path);
+    FREE_C_HEAP_ARRAY(char, library_path, mtInternal);
   }
 
   /* Default extensions directory */
@@ -300,7 +293,7 @@
   {
     #define ENDORSED_DIR "\\lib\\endorsed"
     size_t len = strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR);
-    char * buf = NEW_C_HEAP_ARRAY(char, len);
+    char * buf = NEW_C_HEAP_ARRAY(char, len, mtInternal);
     sprintf(buf, "%s%s", Arguments::get_java_home(), ENDORSED_DIR);
     Arguments::set_endorsed_dirs(buf);
     #undef ENDORSED_DIR
@@ -324,16 +317,23 @@
   os::breakpoint();
 }
 
-// Returns an estimate of the current stack pointer. Result must be guaranteed
-// to point into the calling threads stack, and be no lower than the current
-// stack pointer.
-
-address os::current_stack_pointer() {
-  int dummy;
-  address sp = (address)&dummy;
-  return sp;
+/*
+ * RtlCaptureStackBackTrace Windows API may not exist prior to Windows XP.
+ * So far, this method is only used by Native Memory Tracking, which is
+ * only supported on Windows XP or later.
+ */
+address os::get_caller_pc(int n) {
+#ifdef _NMT_NOINLINE_
+  n ++;
+#endif
+  address pc;
+  if (os::Kernel32Dll::RtlCaptureStackBackTrace(n + 1, 1, (PVOID*)&pc, NULL) == 1) {
+    return pc;
+  }
+  return NULL;
 }
 
+
 // os::current_stack_base()
 //
 //   Returns the base of the stack, which is the stack's
@@ -1024,7 +1024,7 @@
 os::opendir(const char *dirname)
 {
     assert(dirname != NULL, "just checking");   // hotspot change
-    DIR *dirp = (DIR *)malloc(sizeof(DIR));
+    DIR *dirp = (DIR *)malloc(sizeof(DIR), mtInternal);
     DWORD fattr;                                // hotspot change
     char alt_dirname[4] = { 0, 0, 0, 0 };
 
@@ -1046,9 +1046,9 @@
         dirname = alt_dirname;
     }
 
-    dirp->path = (char *)malloc(strlen(dirname) + 5);
+    dirp->path = (char *)malloc(strlen(dirname) + 5, mtInternal);
     if (dirp->path == 0) {
-        free(dirp);
+        free(dirp, mtInternal);
         errno = ENOMEM;
         return 0;
     }
@@ -1056,13 +1056,13 @@
 
     fattr = GetFileAttributes(dirp->path);
     if (fattr == 0xffffffff) {
-        free(dirp->path);
-        free(dirp);
+        free(dirp->path, mtInternal);
+        free(dirp, mtInternal);
         errno = ENOENT;
         return 0;
     } else if ((fattr & FILE_ATTRIBUTE_DIRECTORY) == 0) {
-        free(dirp->path);
-        free(dirp);
+        free(dirp->path, mtInternal);
+        free(dirp, mtInternal);
         errno = ENOTDIR;
         return 0;
     }
@@ -1080,8 +1080,8 @@
     dirp->handle = FindFirstFile(dirp->path, &dirp->find_data);
     if (dirp->handle == INVALID_HANDLE_VALUE) {
         if (GetLastError() != ERROR_FILE_NOT_FOUND) {
-            free(dirp->path);
-            free(dirp);
+            free(dirp->path, mtInternal);
+            free(dirp, mtInternal);
             errno = EACCES;
             return 0;
         }
@@ -1124,8 +1124,8 @@
         }
         dirp->handle = INVALID_HANDLE_VALUE;
     }
-    free(dirp->path);
-    free(dirp);
+    free(dirp->path, mtInternal);
+    free(dirp, mtInternal);
     return 0;
 }
 
@@ -1186,11 +1186,11 @@
     // release the storage
     for (int i = 0 ; i < n ; i++) {
       if (pelements[i] != NULL) {
-        FREE_C_HEAP_ARRAY(char, pelements[i]);
+        FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
       }
     }
     if (pelements != NULL) {
-      FREE_C_HEAP_ARRAY(char*, pelements);
+      FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
     }
   } else {
     jio_snprintf(buffer, buflen, "%s\\%s.dll", pname, fname);
@@ -2647,7 +2647,7 @@
 
   void free_node_list() {
     if (_numa_used_node_list != NULL) {
-      FREE_C_HEAP_ARRAY(int, _numa_used_node_list);
+      FREE_C_HEAP_ARRAY(int, _numa_used_node_list, mtInternal);
     }
   }
 
@@ -2669,7 +2669,7 @@
     ULONG highest_node_number;
     if (!os::Kernel32Dll::GetNumaHighestNodeNumber(&highest_node_number)) return false;
     free_node_list();
-    _numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number + 1);
+    _numa_used_node_list = NEW_C_HEAP_ARRAY(int, highest_node_number + 1, mtInternal);
     for (unsigned int i = 0; i <= highest_node_number; i++) {
       ULONGLONG proc_mask_numa_node;
       if (!os::Kernel32Dll::GetNumaNodeProcessorMask(i, &proc_mask_numa_node)) return false;
@@ -2928,7 +2928,7 @@
 // On win32, one cannot release just a part of reserved memory, it's an
 // all or nothing deal.  When we split a reservation, we must break the
 // reservation into two reservations.
-void os::split_reserved_memory(char *base, size_t size, size_t split,
+void os::pd_split_reserved_memory(char *base, size_t size, size_t split,
                               bool realloc) {
   if (size > 0) {
     release_memory(base, size);
@@ -2941,7 +2941,37 @@
   }
 }
 
-char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
+// Multiple threads can race in this code but it's not possible to unmap small sections of
+// virtual space to get requested alignment, like posix-like os's.
+// Windows prevents multiple thread from remapping over each other so this loop is thread-safe.
+char* os::reserve_memory_aligned(size_t size, size_t alignment) {
+  assert((alignment & (os::vm_allocation_granularity() - 1)) == 0,
+      "Alignment must be a multiple of allocation granularity (page size)");
+  assert((size & (alignment -1)) == 0, "size must be 'alignment' aligned");
+
+  size_t extra_size = size + alignment;
+  assert(extra_size >= size, "overflow, size is too large to allow alignment");
+
+  char* aligned_base = NULL;
+
+  do {
+    char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
+    if (extra_base == NULL) {
+      return NULL;
+    }
+    // Do manual alignment
+    aligned_base = (char*) align_size_up((uintptr_t) extra_base, alignment);
+
+    os::release_memory(extra_base, extra_size);
+
+    aligned_base = os::reserve_memory(size, aligned_base);
+
+  } while (aligned_base == NULL);
+
+  return aligned_base;
+}
+
+char* os::pd_reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
   assert((size_t)addr % os::vm_allocation_granularity() == 0,
          "reserve alignment");
   assert(bytes % os::vm_allocation_granularity() == 0, "reserve block size");
@@ -2974,7 +3004,7 @@
 
 // Reserve memory at an arbitrary address, only if that area is
 // available (and not reserved for something else).
-char* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
+char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
   // Windows os::reserve_memory() fails of the requested address range is
   // not avilable.
   return reserve_memory(bytes, requested_addr);
@@ -3037,7 +3067,7 @@
 void os::print_statistics() {
 }
 
-bool os::commit_memory(char* addr, size_t bytes, bool exec) {
+bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
   if (bytes == 0) {
     // Don't bother the OS with noops.
     return true;
@@ -3085,26 +3115,26 @@
   return true;
 }
 
-bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
                        bool exec) {
   return commit_memory(addr, size, exec);
 }
 
-bool os::uncommit_memory(char* addr, size_t bytes) {
+bool os::pd_uncommit_memory(char* addr, size_t bytes) {
   if (bytes == 0) {
     // Don't bother the OS with noops.
     return true;
   }
   assert((size_t) addr % os::vm_page_size() == 0, "uncommit on page boundaries");
   assert(bytes % os::vm_page_size() == 0, "uncommit in page-sized chunks");
-  return VirtualFree(addr, bytes, MEM_DECOMMIT) != 0;
+  return (VirtualFree(addr, bytes, MEM_DECOMMIT) != 0);
 }
 
-bool os::release_memory(char* addr, size_t bytes) {
+bool os::pd_release_memory(char* addr, size_t bytes) {
   return VirtualFree(addr, 0, MEM_RELEASE) != 0;
 }
 
-bool os::create_stack_guard_pages(char* addr, size_t size) {
+bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
   return os::commit_memory(addr, size);
 }
 
@@ -3151,8 +3181,8 @@
   return VirtualProtect(addr, bytes, PAGE_READWRITE, &old_status) != 0;
 }
 
-void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
-void os::free_memory(char *addr, size_t bytes, size_t alignment_hint)    { }
+void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { }
+void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) { }
 void os::numa_make_global(char *addr, size_t bytes)    { }
 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint)    { }
 bool os::numa_topology_changed()                       { return false; }
@@ -4286,14 +4316,14 @@
     numEvents = MAX_INPUT_EVENTS;
   }
 
-  lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD));
+  lpBuffer = (INPUT_RECORD *)os::malloc(numEvents * sizeof(INPUT_RECORD), mtInternal);
   if (lpBuffer == NULL) {
     return FALSE;
   }
 
   error = ::PeekConsoleInput(han, lpBuffer, numEvents, &numEventsRead);
   if (error == 0) {
-    os::free(lpBuffer);
+    os::free(lpBuffer, mtInternal);
     return FALSE;
   }
 
@@ -4314,7 +4344,7 @@
   }
 
   if(lpBuffer != NULL) {
-    os::free(lpBuffer);
+    os::free(lpBuffer, mtInternal);
   }
 
   *pbytes = (long) actualLength;
@@ -4322,7 +4352,7 @@
 }
 
 // Map a block of memory.
-char* os::map_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
                      char *addr, size_t bytes, bool read_only,
                      bool allow_exec) {
   HANDLE hFile;
@@ -4442,7 +4472,7 @@
 
 
 // Remap a block of memory.
-char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
+char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
                        char *addr, size_t bytes, bool read_only,
                        bool allow_exec) {
   // This OS does not allow existing memory maps to be remapped so we
@@ -4455,15 +4485,15 @@
   // call above and the map_memory() call below where a thread in native
   // code may be able to access an address that is no longer mapped.
 
-  return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
-                        allow_exec);
+  return os::map_memory(fd, file_name, file_offset, addr, bytes,
+           read_only, allow_exec);
 }
 
 
 // Unmap a block of memory.
 // Returns true=success, otherwise false.
 
-bool os::unmap_memory(char* addr, size_t bytes) {
+bool os::pd_unmap_memory(char* addr, size_t bytes) {
   BOOL result = UnmapViewOfFile(addr);
   if (result == 0) {
     if (PrintMiscellaneous && Verbose) {
@@ -4847,99 +4877,92 @@
   return (struct hostent*)os::WinSock2Dll::gethostbyname(name);
 }
 
-
 int os::socket_close(int fd) {
-  ShouldNotReachHere();
-  return 0;
+  return ::closesocket(fd);
 }
 
 int os::socket_available(int fd, jint *pbytes) {
-  ShouldNotReachHere();
-  return 0;
+  int ret = ::ioctlsocket(fd, FIONREAD, (u_long*)pbytes);
+  return (ret < 0) ? 0 : 1;
 }
 
 int os::socket(int domain, int type, int protocol) {
-  ShouldNotReachHere();
-  return 0;
+  return ::socket(domain, type, protocol);
 }
 
 int os::listen(int fd, int count) {
-  ShouldNotReachHere();
-  return 0;
+  return ::listen(fd, count);
 }
 
 int os::connect(int fd, struct sockaddr* him, socklen_t len) {
-  ShouldNotReachHere();
-  return 0;
+  return ::connect(fd, him, len);
 }
 
 int os::accept(int fd, struct sockaddr* him, socklen_t* len) {
-  ShouldNotReachHere();
-  return 0;
+  return ::accept(fd, him, len);
 }
 
 int os::sendto(int fd, char* buf, size_t len, uint flags,
                struct sockaddr* to, socklen_t tolen) {
-  ShouldNotReachHere();
-  return 0;
+
+  return ::sendto(fd, buf, (int)len, flags, to, tolen);
 }
 
 int os::recvfrom(int fd, char *buf, size_t nBytes, uint flags,
                  sockaddr* from, socklen_t* fromlen) {
-  ShouldNotReachHere();
-  return 0;
+
+  return ::recvfrom(fd, buf, (int)nBytes, flags, from, fromlen);
 }
 
 int os::recv(int fd, char* buf, size_t nBytes, uint flags) {
-  ShouldNotReachHere();
-  return 0;
+  return ::recv(fd, buf, (int)nBytes, flags);
 }
 
 int os::send(int fd, char* buf, size_t nBytes, uint flags) {
-  ShouldNotReachHere();
-  return 0;
+  return ::send(fd, buf, (int)nBytes, flags);
 }
 
 int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
-  ShouldNotReachHere();
-  return 0;
+  return ::send(fd, buf, (int)nBytes, flags);
 }
 
 int os::timeout(int fd, long timeout) {
-  ShouldNotReachHere();
-  return 0;
+  fd_set tbl;
+  struct timeval t;
+
+  t.tv_sec  = timeout / 1000;
+  t.tv_usec = (timeout % 1000) * 1000;
+
+  tbl.fd_count    = 1;
+  tbl.fd_array[0] = fd;
+
+  return ::select(1, &tbl, 0, 0, &t);
 }
 
 int os::get_host_name(char* name, int namelen) {
-  ShouldNotReachHere();
-  return 0;
+  return ::gethostname(name, namelen);
 }
 
 int os::socket_shutdown(int fd, int howto) {
-  ShouldNotReachHere();
-  return 0;
+  return ::shutdown(fd, howto);
 }
 
 int os::bind(int fd, struct sockaddr* him, socklen_t len) {
-  ShouldNotReachHere();
-  return 0;
+  return ::bind(fd, him, len);
 }
 
 int os::get_sock_name(int fd, struct sockaddr* him, socklen_t* len) {
-  ShouldNotReachHere();
-  return 0;
+  return ::getsockname(fd, him, len);
 }
 
 int os::get_sock_opt(int fd, int level, int optname,
                      char* optval, socklen_t* optlen) {
-  ShouldNotReachHere();
-  return 0;
+  return ::getsockopt(fd, level, optname, optval, optlen);
 }
 
 int os::set_sock_opt(int fd, int level, int optname,
                      const char* optval, socklen_t optlen) {
-  ShouldNotReachHere();
-  return 0;
+  return ::setsockopt(fd, level, optname, optval, optlen);
 }
 
 
@@ -4948,11 +4971,15 @@
 typedef LPVOID (WINAPI *VirtualAllocExNuma_Fn) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
 typedef BOOL (WINAPI *GetNumaHighestNodeNumber_Fn) (PULONG);
 typedef BOOL (WINAPI *GetNumaNodeProcessorMask_Fn) (UCHAR, PULONGLONG);
+typedef USHORT (WINAPI* RtlCaptureStackBackTrace_Fn)(ULONG, ULONG, PVOID*, PULONG);
 
 GetLargePageMinimum_Fn      os::Kernel32Dll::_GetLargePageMinimum = NULL;
 VirtualAllocExNuma_Fn       os::Kernel32Dll::_VirtualAllocExNuma = NULL;
 GetNumaHighestNodeNumber_Fn os::Kernel32Dll::_GetNumaHighestNodeNumber = NULL;
 GetNumaNodeProcessorMask_Fn os::Kernel32Dll::_GetNumaNodeProcessorMask = NULL;
+RtlCaptureStackBackTrace_Fn os::Kernel32Dll::_RtlCaptureStackBackTrace = NULL;
+
+
 BOOL                        os::Kernel32Dll::initialized = FALSE;
 SIZE_T os::Kernel32Dll::GetLargePageMinimum() {
   assert(initialized && _GetLargePageMinimum != NULL,
@@ -4995,6 +5022,19 @@
   return _GetNumaNodeProcessorMask(node, proc_mask);
 }
 
+USHORT os::Kernel32Dll::RtlCaptureStackBackTrace(ULONG FrameToSkip,
+  ULONG FrameToCapture, PVOID* BackTrace, PULONG BackTraceHash) {
+    if (!initialized) {
+      initialize();
+    }
+
+    if (_RtlCaptureStackBackTrace != NULL) {
+      return _RtlCaptureStackBackTrace(FrameToSkip, FrameToCapture,
+        BackTrace, BackTraceHash);
+    } else {
+      return 0;
+    }
+}
 
 void os::Kernel32Dll::initializeCommon() {
   if (!initialized) {
@@ -5004,6 +5044,7 @@
     _VirtualAllocExNuma = (VirtualAllocExNuma_Fn)::GetProcAddress(handle, "VirtualAllocExNuma");
     _GetNumaHighestNodeNumber = (GetNumaHighestNodeNumber_Fn)::GetProcAddress(handle, "GetNumaHighestNodeNumber");
     _GetNumaNodeProcessorMask = (GetNumaNodeProcessorMask_Fn)::GetProcAddress(handle, "GetNumaNodeProcessorMask");
+    _RtlCaptureStackBackTrace = (RtlCaptureStackBackTrace_Fn)::GetProcAddress(handle, "RtlCaptureStackBackTrace");
     initialized = TRUE;
   }
 }
@@ -5118,7 +5159,6 @@
 Module32Next_Fn             os::Kernel32Dll::_Module32Next = NULL;
 GetNativeSystemInfo_Fn      os::Kernel32Dll::_GetNativeSystemInfo = NULL;
 
-
 void os::Kernel32Dll::initialize() {
   if (!initialized) {
     HMODULE handle = ::GetModuleHandle("Kernel32.dll");
@@ -5196,8 +5236,6 @@
   _GetNativeSystemInfo(lpSystemInfo);
 }
 
-
-
 // PSAPI API
 
 
diff --git a/hotspot/src/os/windows/vm/os_windows.hpp b/hotspot/src/os/windows/vm/os_windows.hpp
index e0692e5..33ea706 100644
--- a/hotspot/src/os/windows/vm/os_windows.hpp
+++ b/hotspot/src/os/windows/vm/os_windows.hpp
@@ -98,7 +98,7 @@
   static LONG WINAPI serialize_fault_filter(struct _EXCEPTION_POINTERS* e);
 };
 
-class PlatformEvent : public CHeapObj {
+class PlatformEvent : public CHeapObj<mtInternal> {
   private:
     double CachePad [4] ;   // increase odds that _Event is sole occupant of cache line
     volatile int _Event ;
@@ -124,7 +124,7 @@
 
 
 
-class PlatformParker : public CHeapObj {
+class PlatformParker : public CHeapObj<mtInternal> {
   protected:
     HANDLE _ParkEvent ;
 
@@ -182,6 +182,9 @@
   static BOOL GetNumaHighestNodeNumber(PULONG);
   static BOOL GetNumaNodeProcessorMask(UCHAR, PULONGLONG);
 
+  // Stack walking
+  static USHORT RtlCaptureStackBackTrace(ULONG, ULONG, PVOID*, PULONG);
+
 private:
   // GetLargePageMinimum available on Windows Vista/Windows Server 2003
   // and later
@@ -191,6 +194,7 @@
   static LPVOID (WINAPI *_VirtualAllocExNuma) (HANDLE, LPVOID, SIZE_T, DWORD, DWORD, DWORD);
   static BOOL (WINAPI *_GetNumaHighestNodeNumber) (PULONG);
   static BOOL (WINAPI *_GetNumaNodeProcessorMask) (UCHAR, PULONGLONG);
+  static USHORT (WINAPI *_RtlCaptureStackBackTrace)(ULONG, ULONG, PVOID*, PULONG);
   static BOOL initialized;
 
   static void initialize();
diff --git a/hotspot/src/os/windows/vm/perfMemory_windows.cpp b/hotspot/src/os/windows/vm/perfMemory_windows.cpp
index 4f3280d..fc86d7b 100644
--- a/hotspot/src/os/windows/vm/perfMemory_windows.cpp
+++ b/hotspot/src/os/windows/vm/perfMemory_windows.cpp
@@ -30,6 +30,7 @@
 #include "os_windows.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/perfMemory.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/exceptions.hpp"
 
 #include <windows.h>
@@ -120,7 +121,7 @@
     }
   }
 
-  FREE_C_HEAP_ARRAY(char, destfile);
+  FREE_C_HEAP_ARRAY(char, destfile, mtInternal);
 }
 
 // Shared Memory Implementation Details
@@ -157,7 +158,7 @@
   const char* tmpdir = os::get_temp_directory();
   const char* perfdir = PERFDATA_NAME;
   size_t nbytes = strlen(tmpdir) + strlen(perfdir) + strlen(user) + 3;
-  char* dirname = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* dirname = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   // construct the path name to user specific tmp directory
   _snprintf(dirname, nbytes, "%s\\%s_%s", tmpdir, perfdir, user);
@@ -281,7 +282,7 @@
     }
   }
 
-  char* user_name = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
+  char* user_name = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
   strcpy(user_name, user);
 
   return user_name;
@@ -315,7 +316,7 @@
   // to determine the user name for the process id.
   //
   struct dirent* dentry;
-  char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname));
+  char* tdbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(tmpdirname), mtInternal);
   errno = 0;
   while ((dentry = os::readdir(tmpdirp, (struct dirent *)tdbuf)) != NULL) {
 
@@ -325,7 +326,7 @@
     }
 
     char* usrdir_name = NEW_C_HEAP_ARRAY(char,
-                              strlen(tmpdirname) + strlen(dentry->d_name) + 2);
+        strlen(tmpdirname) + strlen(dentry->d_name) + 2, mtInternal);
     strcpy(usrdir_name, tmpdirname);
     strcat(usrdir_name, "\\");
     strcat(usrdir_name, dentry->d_name);
@@ -333,7 +334,7 @@
     DIR* subdirp = os::opendir(usrdir_name);
 
     if (subdirp == NULL) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
+      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
       continue;
     }
 
@@ -344,13 +345,13 @@
     // symlink can be exploited.
     //
     if (!is_directory_secure(usrdir_name)) {
-      FREE_C_HEAP_ARRAY(char, usrdir_name);
+      FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
       os::closedir(subdirp);
       continue;
     }
 
     struct dirent* udentry;
-    char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name));
+    char* udbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(usrdir_name), mtInternal);
     errno = 0;
     while ((udentry = os::readdir(subdirp, (struct dirent *)udbuf)) != NULL) {
 
@@ -358,20 +359,20 @@
         struct stat statbuf;
 
         char* filename = NEW_C_HEAP_ARRAY(char,
-                            strlen(usrdir_name) + strlen(udentry->d_name) + 2);
+           strlen(usrdir_name) + strlen(udentry->d_name) + 2, mtInternal);
 
         strcpy(filename, usrdir_name);
         strcat(filename, "\\");
         strcat(filename, udentry->d_name);
 
         if (::stat(filename, &statbuf) == OS_ERR) {
-           FREE_C_HEAP_ARRAY(char, filename);
+           FREE_C_HEAP_ARRAY(char, filename, mtInternal);
            continue;
         }
 
         // skip over files that are not regular files.
         if ((statbuf.st_mode & S_IFMT) != S_IFREG) {
-          FREE_C_HEAP_ARRAY(char, filename);
+          FREE_C_HEAP_ARRAY(char, filename, mtInternal);
           continue;
         }
 
@@ -393,22 +394,22 @@
         if (statbuf.st_ctime > latest_ctime) {
           char* user = strchr(dentry->d_name, '_') + 1;
 
-          if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user);
-          latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1);
+          if (latest_user != NULL) FREE_C_HEAP_ARRAY(char, latest_user, mtInternal);
+          latest_user = NEW_C_HEAP_ARRAY(char, strlen(user)+1, mtInternal);
 
           strcpy(latest_user, user);
           latest_ctime = statbuf.st_ctime;
         }
 
-        FREE_C_HEAP_ARRAY(char, filename);
+        FREE_C_HEAP_ARRAY(char, filename, mtInternal);
       }
     }
     os::closedir(subdirp);
-    FREE_C_HEAP_ARRAY(char, udbuf);
-    FREE_C_HEAP_ARRAY(char, usrdir_name);
+    FREE_C_HEAP_ARRAY(char, udbuf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, usrdir_name, mtInternal);
   }
   os::closedir(tmpdirp);
-  FREE_C_HEAP_ARRAY(char, tdbuf);
+  FREE_C_HEAP_ARRAY(char, tdbuf, mtInternal);
 
   return(latest_user);
 }
@@ -453,7 +454,7 @@
   // about a name containing a '-' characters.
   //
   nbytes += UINT_CHARS;
-  char* name = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
   _snprintf(name, nbytes, "%s_%s_%u", PERFDATA_NAME, user, vmid);
 
   return name;
@@ -469,7 +470,7 @@
   // add 2 for the file separator and a null terminator.
   size_t nbytes = strlen(dirname) + UINT_CHARS + 2;
 
-  char* name = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* name = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
   _snprintf(name, nbytes, "%s\\%d", dirname, vmid);
 
   return name;
@@ -485,7 +486,7 @@
 static void remove_file(const char* dirname, const char* filename) {
 
   size_t nbytes = strlen(dirname) + strlen(filename) + 2;
-  char* path = NEW_C_HEAP_ARRAY(char, nbytes);
+  char* path = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   strcpy(path, dirname);
   strcat(path, "\\");
@@ -500,7 +501,7 @@
     }
   }
 
-  FREE_C_HEAP_ARRAY(char, path);
+  FREE_C_HEAP_ARRAY(char, path, mtInternal);
 }
 
 // returns true if the process represented by pid is alive, otherwise
@@ -638,7 +639,7 @@
   // opendir/readdir.
   //
   struct dirent* entry;
-  char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname));
+  char* dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(dirname), mtInternal);
   errno = 0;
   while ((entry = os::readdir(dirp, (struct dirent *)dbuf)) != NULL) {
 
@@ -681,7 +682,7 @@
     errno = 0;
   }
   os::closedir(dirp);
-  FREE_C_HEAP_ARRAY(char, dbuf);
+  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
 }
 
 // create a file mapping object with the requested name, and size
@@ -747,11 +748,11 @@
     // be an ACL we enlisted. free the resources.
     //
     if (success && exists && pACL != NULL && !isdefault) {
-      FREE_C_HEAP_ARRAY(char, pACL);
+      FREE_C_HEAP_ARRAY(char, pACL, mtInternal);
     }
 
     // free the security descriptor
-    FREE_C_HEAP_ARRAY(char, pSD);
+    FREE_C_HEAP_ARRAY(char, pSD, mtInternal);
   }
 }
 
@@ -766,7 +767,7 @@
     lpSA->lpSecurityDescriptor = NULL;
 
     // free the security attributes structure
-    FREE_C_HEAP_ARRAY(char, lpSA);
+    FREE_C_HEAP_ARRAY(char, lpSA, mtInternal);
   }
 }
 
@@ -805,7 +806,7 @@
     }
   }
 
-  token_buf = (PTOKEN_USER) NEW_C_HEAP_ARRAY(char, rsize);
+  token_buf = (PTOKEN_USER) NEW_C_HEAP_ARRAY(char, rsize, mtInternal);
 
   // get the user token information
   if (!GetTokenInformation(hAccessToken, TokenUser, token_buf, rsize, &rsize)) {
@@ -813,28 +814,28 @@
       warning("GetTokenInformation failure: lasterror = %d,"
               " rsize = %d\n", GetLastError(), rsize);
     }
-    FREE_C_HEAP_ARRAY(char, token_buf);
+    FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
     CloseHandle(hAccessToken);
     return NULL;
   }
 
   DWORD nbytes = GetLengthSid(token_buf->User.Sid);
-  PSID pSID = NEW_C_HEAP_ARRAY(char, nbytes);
+  PSID pSID = NEW_C_HEAP_ARRAY(char, nbytes, mtInternal);
 
   if (!CopySid(nbytes, pSID, token_buf->User.Sid)) {
     if (PrintMiscellaneous && Verbose) {
       warning("GetTokenInformation failure: lasterror = %d,"
               " rsize = %d\n", GetLastError(), rsize);
     }
-    FREE_C_HEAP_ARRAY(char, token_buf);
-    FREE_C_HEAP_ARRAY(char, pSID);
+    FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
+    FREE_C_HEAP_ARRAY(char, pSID, mtInternal);
     CloseHandle(hAccessToken);
     return NULL;
   }
 
   // close the access token.
   CloseHandle(hAccessToken);
-  FREE_C_HEAP_ARRAY(char, token_buf);
+  FREE_C_HEAP_ARRAY(char, token_buf, mtInternal);
 
   return pSID;
 }
@@ -912,13 +913,13 @@
   }
 
   // create the new ACL
-  newACL = (PACL) NEW_C_HEAP_ARRAY(char, newACLsize);
+  newACL = (PACL) NEW_C_HEAP_ARRAY(char, newACLsize, mtInternal);
 
   if (!InitializeAcl(newACL, newACLsize, ACL_REVISION)) {
     if (PrintMiscellaneous && Verbose) {
       warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
     }
-    FREE_C_HEAP_ARRAY(char, newACL);
+    FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
     return false;
   }
 
@@ -931,7 +932,7 @@
         if (PrintMiscellaneous && Verbose) {
           warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
         }
-        FREE_C_HEAP_ARRAY(char, newACL);
+        FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
         return false;
       }
       if (((ACCESS_ALLOWED_ACE *)ace)->Header.AceFlags && INHERITED_ACE) {
@@ -958,7 +959,7 @@
           if (PrintMiscellaneous && Verbose) {
             warning("AddAce failure: lasterror = %d \n", GetLastError());
           }
-          FREE_C_HEAP_ARRAY(char, newACL);
+          FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
           return false;
         }
       }
@@ -974,7 +975,7 @@
         warning("AddAccessAllowedAce failure: lasterror = %d \n",
                 GetLastError());
       }
-      FREE_C_HEAP_ARRAY(char, newACL);
+      FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
       return false;
     }
   }
@@ -989,7 +990,7 @@
         if (PrintMiscellaneous && Verbose) {
           warning("InitializeAcl failure: lasterror = %d \n", GetLastError());
         }
-        FREE_C_HEAP_ARRAY(char, newACL);
+        FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
         return false;
       }
       if (!AddAce(newACL, ACL_REVISION, MAXDWORD, ace,
@@ -997,7 +998,7 @@
         if (PrintMiscellaneous && Verbose) {
           warning("AddAce failure: lasterror = %d \n", GetLastError());
         }
-        FREE_C_HEAP_ARRAY(char, newACL);
+        FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
         return false;
       }
       ace_index++;
@@ -1010,7 +1011,7 @@
       warning("SetSecurityDescriptorDacl failure:"
               " lasterror = %d \n", GetLastError());
     }
-    FREE_C_HEAP_ARRAY(char, newACL);
+    FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
     return false;
   }
 
@@ -1030,7 +1031,7 @@
         warning("SetSecurityDescriptorControl failure:"
                 " lasterror = %d \n", GetLastError());
       }
-      FREE_C_HEAP_ARRAY(char, newACL);
+      FREE_C_HEAP_ARRAY(char, newACL, mtInternal);
       return false;
     }
   }
@@ -1054,7 +1055,7 @@
 
   // allocate space for a security descriptor
   PSECURITY_DESCRIPTOR pSD = (PSECURITY_DESCRIPTOR)
-                         NEW_C_HEAP_ARRAY(char, SECURITY_DESCRIPTOR_MIN_LENGTH);
+     NEW_C_HEAP_ARRAY(char, SECURITY_DESCRIPTOR_MIN_LENGTH, mtInternal);
 
   // initialize the security descriptor
   if (!InitializeSecurityDescriptor(pSD, SECURITY_DESCRIPTOR_REVISION)) {
@@ -1076,7 +1077,7 @@
   // return it to the caller.
   //
   LPSECURITY_ATTRIBUTES lpSA = (LPSECURITY_ATTRIBUTES)
-                            NEW_C_HEAP_ARRAY(char, sizeof(SECURITY_ATTRIBUTES));
+    NEW_C_HEAP_ARRAY(char, sizeof(SECURITY_ATTRIBUTES), mtInternal);
   lpSA->nLength = sizeof(SECURITY_ATTRIBUTES);
   lpSA->lpSecurityDescriptor = pSD;
   lpSA->bInheritHandle = FALSE;
@@ -1147,7 +1148,7 @@
   // create a security attributes structure with access control
   // entries as initialized above.
   LPSECURITY_ATTRIBUTES lpSA = make_security_attr(aces, 3);
-  FREE_C_HEAP_ARRAY(char, aces[0].pSid);
+  FREE_C_HEAP_ARRAY(char, aces[0].pSid, mtInternal);
   FreeSid(everybodySid);
   FreeSid(administratorsSid);
   return(lpSA);
@@ -1462,15 +1463,15 @@
   assert(((size != 0) && (size % os::vm_page_size() == 0)),
          "unexpected PerfMemry region size");
 
-  FREE_C_HEAP_ARRAY(char, user);
+  FREE_C_HEAP_ARRAY(char, user, mtInternal);
 
   // create the shared memory resources
   sharedmem_fileMapHandle =
                create_sharedmem_resources(dirname, filename, objectname, size);
 
-  FREE_C_HEAP_ARRAY(char, filename);
-  FREE_C_HEAP_ARRAY(char, objectname);
-  FREE_C_HEAP_ARRAY(char, dirname);
+  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+  FREE_C_HEAP_ARRAY(char, objectname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
 
   if (sharedmem_fileMapHandle == NULL) {
     return NULL;
@@ -1496,6 +1497,10 @@
   // clear the shared memory region
   (void)memset(mapAddress, '\0', size);
 
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC);
+  MemTracker::record_virtual_memory_type((address)mapAddress, mtInternal);
+
   return (char*) mapAddress;
 }
 
@@ -1621,7 +1626,7 @@
   // store file, we also don't following them when attaching
   //
   if (!is_directory_secure(dirname)) {
-    FREE_C_HEAP_ARRAY(char, dirname);
+    FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
               "Process not found");
   }
@@ -1640,10 +1645,10 @@
   strcpy(robjectname, objectname);
 
   // free the c heap resources that are no longer needed
-  if (luser != user) FREE_C_HEAP_ARRAY(char, luser);
-  FREE_C_HEAP_ARRAY(char, dirname);
-  FREE_C_HEAP_ARRAY(char, filename);
-  FREE_C_HEAP_ARRAY(char, objectname);
+  if (luser != user) FREE_C_HEAP_ARRAY(char, luser, mtInternal);
+  FREE_C_HEAP_ARRAY(char, dirname, mtInternal);
+  FREE_C_HEAP_ARRAY(char, filename, mtInternal);
+  FREE_C_HEAP_ARRAY(char, objectname, mtInternal);
 
   if (*sizep == 0) {
     size = sharedmem_filesize(rfilename, CHECK);
@@ -1672,6 +1677,11 @@
               "Could not map PerfMemory");
   }
 
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_reserve((address)mapAddress, size, CURRENT_PC);
+  MemTracker::record_virtual_memory_type((address)mapAddress, mtInternal);
+
+
   *addrp = (char*)mapAddress;
   *sizep = size;
 
@@ -1824,6 +1834,8 @@
   }
 
   remove_file_mapping(addr);
+  // it does not go through os api, the operation has to record from here
+  MemTracker::record_virtual_memory_release((address)addr, bytes);
 }
 
 char* PerfMemory::backing_store_filename() {
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
index 0a67d0a..b7b3e4c 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/os_bsd_x86.cpp
@@ -52,12 +52,6 @@
 #include "thread_bsd.inline.hpp"
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 // put OS-includes here
 # include <sys/types.h>
@@ -297,7 +291,7 @@
   return (char*) -1;
 }
 
-void os::initialize_thread() {
+void os::initialize_thread(Thread* thr) {
 // Nothing to do.
 }
 
@@ -1132,3 +1126,8 @@
                       : "r" (fpu_cntrl) : "memory");
 #endif // !AMD64
 }
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
diff --git a/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp b/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
index 4ccf807..b98d975 100644
--- a/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
+++ b/hotspot/src/os_cpu/bsd_x86/vm/vmStructs_bsd_x86.hpp
@@ -29,18 +29,12 @@
 // constants required by the Serviceability Agent. This file is
 // referenced by vmStructs.cpp.
 
-#ifdef __APPLE__
-#define OS_THREAD_ID_TYPE thread_t
-#else
-#define OS_THREAD_ID_TYPE pthread_t
-#endif
-
 #define VM_STRUCTS_OS_CPU(nonstatic_field, static_field, unchecked_nonstatic_field, volatile_nonstatic_field, nonproduct_nonstatic_field, c2_nonstatic_field, unchecked_c1_static_field, unchecked_c2_static_field, last_entry) \
                                                                                                                                      \
   /******************************/                                                                                                   \
   /* Threads (NOTE: incomplete) */                                                                                                   \
   /******************************/                                                                                                   \
-  nonstatic_field(OSThread,                      _thread_id,                                      OS_THREAD_ID_TYPE)                 \
+  nonstatic_field(OSThread,                      _thread_id,                                      OSThread::thread_id_t)             \
   nonstatic_field(OSThread,                      _pthread_id,                                     pthread_t)                         \
   /* This must be the last entry, and must be present */                                                                             \
   last_entry()
@@ -52,7 +46,7 @@
   /* Posix Thread IDs   */                                                \
   /**********************/                                                \
                                                                           \
-  declare_unsigned_integer_type(thread_t)                                 \
+  declare_unsigned_integer_type(OSThread::thread_id_t)                    \
   declare_unsigned_integer_type(pthread_t)                                \
                                                                           \
   /* This must be the last entry, and must be present */                  \
diff --git a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
index ff5b32d..75287b3 100644
--- a/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
+++ b/hotspot/src/os_cpu/bsd_zero/vm/os_bsd_zero.cpp
@@ -58,12 +58,6 @@
 #include "thread_bsd.inline.hpp"
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 address os::current_stack_pointer() {
   address dummy = (address) &dummy;
@@ -103,7 +97,7 @@
 #endif // SPARC
 }
 
-void os::initialize_thread() {
+void os::initialize_thread(Thread* thr) {
   // Nothing to do.
 }
 
@@ -562,3 +556,8 @@
   }
 };
 #endif // !_LP64
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
diff --git a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
index 62131ee..bb0be1c 100644
--- a/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
+++ b/hotspot/src/os_cpu/linux_sparc/vm/os_linux_sparc.cpp
@@ -52,13 +52,6 @@
 #include "thread_linux.inline.hpp"
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
-
 
 // Linux/Sparc has rather obscure naming of registers in sigcontext
 // different between 32 and 64 bits
@@ -225,7 +218,7 @@
   return (char*) 0;
 }
 
-void os::initialize_thread() {}
+void os::initialize_thread(Thread* thr) {}
 
 void os::print_context(outputStream *st, void *context) {
   if (context == NULL) return;
@@ -756,3 +749,8 @@
   // guard page, only enable glibc guard page for non-Java threads.
   return (thr_type == java_thread ? 0 : page_size());
 }
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
diff --git a/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp b/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp
index 4b0a3e6..58fc94b 100644
--- a/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp
+++ b/hotspot/src/os_cpu/linux_sparc/vm/vmStructs_linux_sparc.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -36,7 +36,7 @@
   /******************************/                                                                                                   \
                                                                                                                                      \
   nonstatic_field(JavaThread,                  _base_of_stack_pointer,                        intptr_t*)                             \
-  nonstatic_field(OSThread,                    _thread_id,                                    pid_t)                                 \
+  nonstatic_field(OSThread,                    _thread_id,                                    OSThread::thread_id_t)                 \
   nonstatic_field(OSThread,                    _pthread_id,                                   pthread_t)                             \
   /* This must be the last entry, and must be present */                                                                             \
   last_entry()
@@ -48,7 +48,7 @@
   /* POSIX Thread IDs */                                                  \
   /**********************/                                                \
                                                                           \
-  declare_integer_type(pid_t)                                             \
+  declare_integer_type(OSThread::thread_id_t)                             \
   declare_unsigned_integer_type(pthread_t)                                \
                                                                           \
   /* This must be the last entry, and must be present */                  \
diff --git a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
index ba484b9..10bd5f5 100644
--- a/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
+++ b/hotspot/src/os_cpu/linux_x86/vm/os_linux_x86.cpp
@@ -52,12 +52,6 @@
 #include "thread_linux.inline.hpp"
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 // put OS-includes here
 # include <sys/types.h>
@@ -114,7 +108,7 @@
   return (char*) -1;
 }
 
-void os::initialize_thread() {
+void os::initialize_thread(Thread* thr) {
 // Nothing to do.
 }
 
@@ -862,3 +856,11 @@
                       : "r" (fpu_cntrl) : "memory");
 #endif // !AMD64
 }
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+#ifdef AMD64
+  assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
+#endif
+}
+#endif
diff --git a/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp b/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp
index c54cb1d..c01e6c9 100644
--- a/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp
+++ b/hotspot/src/os_cpu/linux_x86/vm/vmStructs_linux_x86.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -34,7 +34,7 @@
   /******************************/                                                                                                   \
   /* Threads (NOTE: incomplete) */                                                                                                   \
   /******************************/                                                                                                   \
-  nonstatic_field(OSThread,                      _thread_id,                                      pid_t)                             \
+  nonstatic_field(OSThread,                      _thread_id,                                      OSThread::thread_id_t)             \
   nonstatic_field(OSThread,                      _pthread_id,                                     pthread_t)                         \
   /* This must be the last entry, and must be present */                                                                             \
   last_entry()
@@ -46,7 +46,7 @@
   /* Posix Thread IDs   */                                                \
   /**********************/                                                \
                                                                           \
-  declare_integer_type(pid_t)                                             \
+  declare_integer_type(OSThread::thread_id_t)                             \
   declare_unsigned_integer_type(pthread_t)                                \
                                                                           \
   /* This must be the last entry, and must be present */                  \
diff --git a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
index 32c2d0a..90190bf 100644
--- a/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
+++ b/hotspot/src/os_cpu/linux_zero/vm/os_linux_zero.cpp
@@ -53,12 +53,6 @@
 #include "thread_linux.inline.hpp"
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 address os::current_stack_pointer() {
   address dummy = (address) &dummy;
@@ -98,7 +92,7 @@
 #endif // SPARC
 }
 
-void os::initialize_thread() {
+void os::initialize_thread(Thread * thr){
   // Nothing to do.
 }
 
@@ -506,3 +500,8 @@
   }
 };
 #endif // !_LP64
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
index 971f600..e0e3ad8 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/os_solaris_sparc.cpp
@@ -52,13 +52,6 @@
 #include "thread_solaris.inline.hpp"
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
-
 
 # include <signal.h>        // needed first to avoid name collision for "std" with SC 5.0
 
@@ -251,6 +244,15 @@
   return frame(fr->sender_sp(), frame::unpatchable, fr->sender_pc());
 }
 
+// Returns an estimate of the current stack pointer. Result must be guaranteed to
+// point into the calling threads stack, and be no lower than the current stack
+// pointer.
+address os::current_stack_pointer() {
+  volatile int dummy;
+  address sp = (address)&dummy + 8;     // %%%% need to confirm if this is right
+  return sp;
+}
+
 frame os::current_frame() {
   intptr_t* sp = StubRoutines::Sparc::flush_callers_register_windows_func()();
   frame myframe(sp, frame::unpatchable,
@@ -815,3 +817,8 @@
    __asm__ __volatile__ ("wr %%g0, 0, %%fprs \n\t" : : :);
   }
 #endif //defined(__sparc) && defined(COMPILER2)
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+}
+#endif
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp b/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp
index 710e336..58113a9 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vmStructs_solaris_sparc.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -36,7 +36,7 @@
   /******************************/                                                                                                   \
                                                                                                                                      \
   nonstatic_field(JavaThread,                  _base_of_stack_pointer,                        intptr_t*)                             \
-  nonstatic_field(OSThread,                    _thread_id,                                    thread_t)                              \
+  nonstatic_field(OSThread,                    _thread_id,                                    OSThread::thread_id_t)                 \
   /* This must be the last entry, and must be present */                                                                             \
   last_entry()
 
@@ -47,7 +47,7 @@
   /* Solaris Thread IDs */                                                \
   /**********************/                                                \
                                                                           \
-  declare_unsigned_integer_type(thread_t)                                 \
+  declare_unsigned_integer_type(OSThread::thread_id_t)                    \
                                                                           \
   /* This must be the last entry, and must be present */                  \
   last_entry()
diff --git a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
index d53de80..edf46ce 100644
--- a/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
+++ b/hotspot/src/os_cpu/solaris_sparc/vm/vm_version_solaris_sparc.cpp
@@ -201,13 +201,23 @@
               impl[i] = (char)toupper((uint)impl[i]);
             if (strstr(impl, "SPARC64") != NULL) {
               features |= sparc64_family_m;
+            } else if (strstr(impl, "SPARC-M") != NULL) {
+              // M-series SPARC is based on T-series.
+              features |= (M_family_m | T_family_m);
             } else if (strstr(impl, "SPARC-T") != NULL) {
               features |= T_family_m;
               if (strstr(impl, "SPARC-T1") != NULL) {
                 features |= T1_model_m;
               }
             } else {
-              assert(strstr(impl, "SPARC") != NULL, "should be sparc");
+              if (strstr(impl, "SPARC") == NULL) {
+#ifndef PRODUCT
+                // kstat on Solaris 8 virtual machines (branded zones)
+                // returns "(unsupported)" implementation.
+                warning("kstat cpu_info implementation = '%s', should contain SPARC", impl);
+#endif
+                implementation = "SPARC";
+              }
             }
             free((void*)impl);
             break;
diff --git a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
index 78e93ea..06cbb7c 100644
--- a/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
+++ b/hotspot/src/os_cpu/solaris_x86/vm/os_solaris_x86.cpp
@@ -52,12 +52,6 @@
 #include "thread_solaris.inline.hpp"
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 // put OS-includes here
 # include <sys/types.h>
@@ -237,6 +231,12 @@
   return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
 }
 
+extern "C" intptr_t *_get_current_sp();  // in .il file
+
+address os::current_stack_pointer() {
+  return (address)_get_current_sp();
+}
+
 extern "C" intptr_t *_get_current_fp();  // in .il file
 
 frame os::current_frame() {
@@ -954,3 +954,11 @@
   _solaris_raw_setup_fpu(fpu_cntrl);
 }
 #endif // AMD64
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+#ifdef AMD64
+  assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
+#endif
+}
+#endif
diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il
index b635a82..9b0f07d 100644
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_32.il
@@ -37,6 +37,12 @@
       movl     %gs:0, %eax 
       .end
 
+  // Get current sp
+      .inline _get_current_sp,0
+      .volatile
+      movl     %esp, %eax 
+      .end
+
   // Get current fp
       .inline _get_current_fp,0
       .volatile
diff --git a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il
index fb7946b..89809bc 100644
--- a/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il
+++ b/hotspot/src/os_cpu/solaris_x86/vm/solaris_x86_64.il
@@ -30,6 +30,12 @@
       movq     %fs:0, %rax 
       .end
 
+  // Get current sp
+      .inline _get_current_sp,0
+      .volatile
+      movq     %rsp, %rax 
+      .end
+
   // Get current fp
       .inline _get_current_fp,0
       .volatile
diff --git a/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp b/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp
index 7633895..a2a4f7c 100644
--- a/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp
+++ b/hotspot/src/os_cpu/solaris_x86/vm/vmStructs_solaris_x86.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -35,7 +35,7 @@
   /* Threads (NOTE: incomplete) */                                                                                                   \
   /******************************/                                                                                                   \
                                                                                                                                      \
-  nonstatic_field(OSThread,                      _thread_id,                                    thread_t)                              \
+  nonstatic_field(OSThread,                      _thread_id,                                    OSThread::thread_id_t)               \
                                                                                                                                      \
   /* This must be the last entry, and must be present */                                                                             \
   last_entry()
@@ -46,7 +46,7 @@
   /* Solaris Thread IDs */                                                \
   /**********************/                                                \
                                                                           \
-  declare_unsigned_integer_type(thread_t)                                 \
+  declare_unsigned_integer_type(OSThread::thread_id_t)                    \
                                                                           \
   /* This must be the last entry, and must be present */                  \
   last_entry()
diff --git a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
index 960ceab..eb5ff87 100644
--- a/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
+++ b/hotspot/src/os_cpu/windows_x86/vm/os_windows_x86.cpp
@@ -52,12 +52,6 @@
 #include "thread_windows.inline.hpp"
 #include "utilities/events.hpp"
 #include "utilities/vmError.hpp"
-#ifdef COMPILER1
-#include "c1/c1_Runtime1.hpp"
-#endif
-#ifdef COMPILER2
-#include "opto/runtime.hpp"
-#endif
 
 # include "unwind_windows_x86.hpp"
 #undef REG_SP
@@ -219,7 +213,7 @@
   return true;
 }
 
-void os::initialize_thread() {
+void os::initialize_thread(Thread* thr) {
 // Nothing to do.
 }
 
@@ -370,6 +364,26 @@
   return frame(fr->sender_sp(), fr->link(), fr->sender_pc());
 }
 
+#ifndef AMD64
+// Returns an estimate of the current stack pointer. Result must be guaranteed
+// to point into the calling threads stack, and be no lower than the current
+// stack pointer.
+address os::current_stack_pointer() {
+  int dummy;
+  address sp = (address)&dummy;
+  return sp;
+}
+#else
+// Returns the current stack pointer. Accurate value needed for
+// os::verify_stack_alignment().
+address os::current_stack_pointer() {
+  typedef address get_sp_func();
+  get_sp_func* func = CAST_TO_FN_PTR(get_sp_func*,
+                                     StubRoutines::x86::get_previous_sp_entry());
+  return (*func)();
+}
+#endif
+
 
 #ifndef AMD64
 intptr_t* _get_previous_fp() {
@@ -546,3 +560,11 @@
   __asm fldcw fpu_cntrl_word;
 #endif // !AMD64
 }
+
+#ifndef PRODUCT
+void os::verify_stack_alignment() {
+#ifdef AMD64
+  assert(((intptr_t)os::current_stack_pointer() & (StackAlignmentInBytes-1)) == 0, "incorrect stack alignment");
+#endif
+}
+#endif
diff --git a/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp b/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp
index 6df1f72..69d25c9 100644
--- a/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp
+++ b/hotspot/src/os_cpu/windows_x86/vm/vmStructs_windows_x86.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -35,7 +35,7 @@
   /* Threads (NOTE: incomplete) */                                                                                                   \
   /******************************/                                                                                                   \
                                                                                                                                      \
-  nonstatic_field(OSThread,                    _thread_id,                                    unsigned long)                         \
+  nonstatic_field(OSThread,                    _thread_id,                                    OSThread::thread_id_t)                 \
   unchecked_nonstatic_field(OSThread,          _thread_handle,                                sizeof(HANDLE)) /* NOTE: no type */    \
                                                                                                                                      \
   /* This must be the last entry, and must be present */                                                                             \
@@ -43,6 +43,7 @@
 
 #define VM_TYPES_OS_CPU(declare_type, declare_toplevel_type, declare_oop_type, declare_integer_type, declare_unsigned_integer_type, declare_c1_toplevel_type, declare_c2_type, declare_c2_toplevel_type, last_entry) \
                                                                           \
+  declare_unsigned_integer_type(OSThread::thread_id_t)                    \
   /* This must be the last entry, and must be present */                  \
   last_entry()
 
diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java
index 73e5956..861fe44 100644
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/Compilation.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +33,7 @@
     private boolean osr;
     private Method method;
     private CallSite call = new CallSite();
+    private CallSite lateInlineCall = new CallSite();
     private int osrBci;
     private String icount;
     private String bcount;
@@ -80,6 +81,13 @@
             sb.append(site);
             sb.append("\n");
         }
+        if (getLateInlineCall().getCalls() != null) {
+            sb.append("late inline:\n");
+            for (CallSite site : getLateInlineCall().getCalls()) {
+                sb.append(site);
+                sb.append("\n");
+            }
+        }
         return sb.toString();
     }
 
@@ -115,6 +123,12 @@
                     site.print(stream, indent + 2);
                 }
             }
+            if (printInlining && lateInlineCall.getCalls() != null) {
+                stream.println("late inline:");
+                for (CallSite site : lateInlineCall.getCalls()) {
+                    site.print(stream, indent + 2);
+                }
+            }
         }
     }
 
@@ -215,7 +229,11 @@
     }
 
     public void setMethod(Method method) {
-        this.method = method;
+        // Don't change method if it is already set to avoid changing
+        // it by post parse inlining info.
+        if (getMethod() == null) {
+            this.method = method;
+        }
     }
 
     public CallSite getCall() {
@@ -226,6 +244,10 @@
         this.call = call;
     }
 
+    public CallSite getLateInlineCall() {
+        return lateInlineCall;
+    }
+
     public double getElapsedTime() {
         return end - start;
     }
diff --git a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java
index d864db0..dc0b7ab 100644
--- a/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java
+++ b/hotspot/src/share/tools/LogCompilation/src/com/sun/hotspot/tools/compiler/LogParser.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, 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
@@ -146,6 +146,7 @@
     private CallSite site;
     private Stack<Phase> phaseStack = new Stack<Phase>();
     private UncommonTrapEvent currentTrap;
+    private Stack<CallSite> late_inline_scope;
 
     long parseLong(String l) {
         try {
@@ -302,6 +303,7 @@
             }
             events.add(compile);
             compiles.put(makeId(atts), compile);
+            site = compile.getCall();
         } else if (qname.equals("type")) {
             type(search(atts, "id"), search(atts, "name"));
         } else if (qname.equals("bc")) {
@@ -360,12 +362,22 @@
                 // uncommon trap inserted during parsing.
                 // ignore for now
             }
+        } else if (qname.equals("late_inline")) {
+            late_inline_scope = new Stack<CallSite>();
+            site = new CallSite(-999, method(search(atts, "method")));
+            late_inline_scope.push(site);
         } else if (qname.equals("jvms")) {
             // <jvms bci='4' method='java/io/DataInputStream readChar ()C' bytes='40' count='5815' iicount='20815'/>
             if (currentTrap != null) {
                 currentTrap.addJVMS(atts.getValue("method"), Integer.parseInt(atts.getValue("bci")));
+            } else if (late_inline_scope != null) {
+                bci = Integer.parseInt(search(atts, "bci"));
+                site = new CallSite(bci, method(search(atts, "method")));
+                late_inline_scope.push(site);
             } else {
-                // Ignore <eliminate_allocation type='667'> and <eliminate_lock lock='1'>
+                // Ignore <eliminate_allocation type='667'>,
+                //        <eliminate_lock lock='1'>,
+                //        <replace_string_concat arguments='2' string_alloc='0' multiple='0'>
             }
         } else if (qname.equals("nmethod")) {
             String id = makeId(atts);
@@ -379,7 +391,7 @@
             Method m = method(search(atts, "method"));
             if (scopes.size() == 0) {
                 compile.setMethod(m);
-                scopes.push(compile.getCall());
+                scopes.push(site);
             } else {
                 if (site.getMethod() == m) {
                     scopes.push(site);
@@ -393,7 +405,7 @@
             }
         } else if (qname.equals("parse_done")) {
             CallSite call = scopes.pop();
-            call.setEndNodes(Integer.parseInt(search(atts, "nodes")));
+            call.setEndNodes(Integer.parseInt(search(atts, "nodes", "1")));
             call.setTimeStamp(Double.parseDouble(search(atts, "stamp")));
             scopes.push(call);
         }
@@ -408,6 +420,43 @@
             scopes.pop();
         } else if (qname.equals("uncommon_trap")) {
             currentTrap = null;
+        } else if (qname.equals("late_inline")) {
+            // Populate late inlining info.
+
+            // late_inline scopes are specified in reverse order:
+            // compiled method should be on top of stack.
+            CallSite caller = late_inline_scope.pop();
+            Method m = compile.getMethod();
+            if (m != caller.getMethod()) {
+                System.out.println(m);
+                System.out.println(caller.getMethod() + " bci: " + bci);
+                throw new InternalError("call site and late_inline info don't match");
+            }
+
+            // late_inline contains caller+bci info, convert it
+            // to bci+callee info used by LogCompilation.
+            site = compile.getLateInlineCall();
+            do {
+                bci = caller.getBci();
+                // Next inlined call.
+                caller = late_inline_scope.pop();
+                CallSite callee =  new CallSite(bci, caller.getMethod());
+                site.add(callee);
+                site = callee;
+            } while (!late_inline_scope.empty());
+
+            if (caller.getBci() != -999) {
+                System.out.println(caller.getMethod());
+                throw new InternalError("broken late_inline info");
+            }
+            if (site.getMethod() != caller.getMethod()) {
+                System.out.println(site.getMethod());
+                System.out.println(caller.getMethod());
+                throw new InternalError("call site and late_inline info don't match");
+            }
+            // late_inline is followed by parse with scopes.size() == 0,
+            // 'site' will be pushed to scopes.
+            late_inline_scope = null;
         } else if (qname.equals("task")) {
             types.clear();
             methods.clear();
diff --git a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
index 92fbf77..00441df 100644
--- a/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
+++ b/hotspot/src/share/tools/ProjectCreator/BuildConfig.java
@@ -22,15 +22,14 @@
  *
  */
 
-import java.io.File;
 import java.util.Enumeration;
 import java.util.Hashtable;
-import java.util.Iterator;
 import java.util.Vector;
 
 class BuildConfig {
+    @SuppressWarnings("rawtypes")
     Hashtable vars;
-    Vector basicNames, basicPaths;
+    Vector<String> basicNames, basicPaths;
     String[] context;
 
     static CompilerInterface ci;
@@ -47,6 +46,7 @@
         return ci;
     }
 
+    @SuppressWarnings("rawtypes")
     protected void initNames(String flavour, String build, String outDll) {
         if (vars == null) vars = new Hashtable();
 
@@ -63,26 +63,28 @@
         // ones mentioned above were needed to expand format
         String buildBase = expandFormat(getFieldString(null, "BuildBase"));
         String sourceBase = getFieldString(null, "SourceBase");
+        String buildSpace = getFieldString(null, "BuildSpace");
         String outDir = buildBase;
 
         put("Id", flavourBuild);
         put("OutputDir", outDir);
         put("SourceBase", sourceBase);
         put("BuildBase", buildBase);
+        put("BuildSpace", buildSpace);
         put("OutputDll", outDir + Util.sep + outDll);
 
         context = new String [] {flavourBuild, flavour, build, null};
     }
 
-    protected void init(Vector includes, Vector defines) {
+    protected void init(Vector<String> includes, Vector<String> defines) {
         initDefaultDefines(defines);
         initDefaultCompilerFlags(includes);
         initDefaultLinkerFlags();
-        handleDB();
+        //handleDB();
     }
 
 
-    protected void initDefaultCompilerFlags(Vector includes) {
+    protected void initDefaultCompilerFlags(Vector<String> includes) {
         Vector compilerFlags = new Vector();
 
         compilerFlags.addAll(getCI().getBaseCompilerFlags(getV("Define"),
@@ -100,143 +102,48 @@
         put("LinkerFlags", linkerFlags);
     }
 
-    DirectoryTree getSourceTree(String sourceBase, String startAt) {
-        DirectoryTree tree = new DirectoryTree();
-
-        tree.addSubdirToIgnore("Codemgr_wsdata");
-        tree.addSubdirToIgnore("deleted_files");
-        tree.addSubdirToIgnore("SCCS");
-        tree.setVerbose(true);
-        if (startAt != null) {
-            tree.readDirectory(sourceBase + File.separator + startAt);
-        } else {
-            tree.readDirectory(sourceBase);
-        }
-
-        return tree;
-    }
-
-
-    Vector getPreferredPaths() {
-        Vector preferredPaths = new Vector();
-
-        // In the case of multiple files with the same name in
-        // different subdirectories, prefer these versions
-        preferredPaths.add("windows");
-        preferredPaths.add("x86");
-        preferredPaths.add("closed");
-
-        // Also prefer "opto" over "adlc" for adlcVMDeps.hpp
-        preferredPaths.add("opto");
-
-        return preferredPaths;
-    }
-
-
-    void handleDB() {
-        WinGammaPlatform platform = (WinGammaPlatform)getField(null, "PlatformObject");
-
-        putSpecificField("AllFilesHash", computeAllFiles(platform));
-    }
-
-
-    private boolean matchesIgnoredPath(String prefixedName) {
-        Vector rv = new Vector();
+    public boolean matchesIgnoredPath(String path) {
+        Vector<String> rv = new Vector<String>();
         collectRelevantVectors(rv, "IgnorePath");
-        for (Iterator i = rv.iterator(); i.hasNext(); ) {
-            String pathPart = (String) i.next();
-            if (prefixedName.contains(Util.normalize(pathPart)))  {
+        for (String pathPart : rv) {
+            if (path.contains(pathPart))  {
                 return true;
             }
         }
         return false;
     }
 
-    void addAll(Iterator i, Hashtable hash,
-                WinGammaPlatform platform, DirectoryTree tree,
-                Vector preferredPaths, Vector filesNotFound, Vector filesDuplicate) {
-        for (; i.hasNext(); ) {
-            String fileName = (String) i.next();
-            if (lookupHashFieldInContext("IgnoreFile", fileName) == null) {
-                String prefixedName = platform.envVarPrefixedFileName(fileName,
-                                                                      0, /* ignored */
-                                                                      tree,
-                                                                      preferredPaths,
-                                                                      filesNotFound,
-                                                                      filesDuplicate);
-                if (prefixedName != null) {
-                    prefixedName = Util.normalize(prefixedName);
-                    if (!matchesIgnoredPath(prefixedName)) {
-                        addTo(hash, prefixedName, fileName);
-                    }
+    public boolean matchesHidePath(String path) {
+        Vector<String> rv = new Vector<String>();
+        collectRelevantVectors(rv, "HidePath");
+        for (String pathPart : rv) {
+            if (path.contains(Util.normalize(pathPart)))  {
+                return true;
+            }
+        }
+        return false;
+    }
+
+   public Vector<String> matchesAdditionalGeneratedPath(String fullPath) {
+        Vector<String> rv = new Vector<String>();
+        Hashtable<String, String> v = (Hashtable<String, String>)BuildConfig.getField(this.toString(), "AdditionalGeneratedFile");
+        if (v != null) {
+            for (Enumeration<String> e=v.keys(); e.hasMoreElements(); ) {
+                String key = e.nextElement();
+                String val = v.get(key);
+
+                if (fullPath.endsWith(expandFormat(key))) {
+                    rv.add(expandFormat(val));
                 }
             }
         }
+        return rv;
     }
 
     void addTo(Hashtable ht, String key, String value) {
         ht.put(expandFormat(key), expandFormat(value));
     }
 
-    Hashtable computeAllFiles(WinGammaPlatform platform) {
-        Hashtable rv = new Hashtable();
-        DirectoryTree tree = getSourceTree(get("SourceBase"), getFieldString(null, "StartAt"));
-        Vector preferredPaths = getPreferredPaths();
-
-        // Hold errors until end
-        Vector filesNotFound = new Vector();
-        Vector filesDuplicate = new Vector();
-
-        Vector includedFiles = new Vector();
-
-        // find all files
-        Vector dirs = getSourceIncludes();
-        for (Iterator i = dirs.iterator(); i.hasNext(); ) {
-            String dir = (String)i.next();
-            DirectoryTree subtree = getSourceTree(dir, null);
-            for (Iterator fi = subtree.getFileIterator(); fi.hasNext(); ) {
-                String name = ((File)fi.next()).getName();
-                includedFiles.add(name);
-            }
-        }
-        addAll(includedFiles.iterator(), rv,
-               platform, tree,
-               preferredPaths, filesNotFound, filesDuplicate);
-
-        Vector addFiles = new Vector();
-        collectRelevantVectors(addFiles, "AdditionalFile");
-        addAll(addFiles.iterator(), rv,
-               platform, tree,
-               preferredPaths, filesNotFound, filesDuplicate);
-
-        collectRelevantHashes(rv, "AdditionalGeneratedFile");
-
-        if ((filesNotFound.size() != 0) ||
-            (filesDuplicate.size() != 0)) {
-            System.err.println("Error: some files were not found or " +
-                               "appeared in multiple subdirectories of " +
-                               "directory " + get("SourceBase") + " and could not " +
-                               "be resolved with os_family and arch.");
-            if (filesNotFound.size() != 0) {
-                System.err.println("Files not found:");
-                for (Iterator iter = filesNotFound.iterator();
-                     iter.hasNext(); ) {
-                    System.err.println("  " + (String) iter.next());
-                }
-            }
-            if (filesDuplicate.size() != 0) {
-                System.err.println("Duplicate files:");
-                for (Iterator iter = filesDuplicate.iterator();
-                     iter.hasNext(); ) {
-                    System.err.println("  " + (String) iter.next());
-                }
-            }
-            throw new RuntimeException();
-        }
-
-        return rv;
-    }
-
     void initDefaultDefines(Vector defines) {
         Vector sysDefines = new Vector();
         sysDefines.add("WIN32");
@@ -324,20 +231,19 @@
     }
 
     void collectRelevantVectors(Vector rv, String field) {
-        for (int i = 0; i < context.length; i++) {
-            Vector v = getFieldVector(context[i], field);
+        for (String ctx : context) {
+            Vector<String> v = getFieldVector(ctx, field);
             if (v != null) {
-                for (Iterator j=v.iterator(); j.hasNext(); ) {
-                    String val = (String)j.next();
-                    rv.add(expandFormat(val));
+                for (String val : v) {
+                    rv.add(expandFormat(val).replace('/', '\\'));
                 }
             }
         }
     }
 
     void collectRelevantHashes(Hashtable rv, String field) {
-        for (int i = 0; i < context.length; i++) {
-            Hashtable v = (Hashtable)getField(context[i], field);
+        for (String ctx : context) {
+            Hashtable v = (Hashtable)getField(ctx, field);
             if (v != null) {
                 for (Enumeration e=v.keys(); e.hasMoreElements(); ) {
                     String key = (String)e.nextElement();
@@ -357,21 +263,17 @@
 
     Vector getIncludes() {
         Vector rv = new Vector();
-
         collectRelevantVectors(rv, "AbsoluteInclude");
-
         rv.addAll(getSourceIncludes());
-
         return rv;
     }
 
     private Vector getSourceIncludes() {
-        Vector rv = new Vector();
-        Vector ri = new Vector();
+        Vector<String> rv = new Vector<String>();
+        Vector<String> ri = new Vector<String>();
         String sourceBase = getFieldString(null, "SourceBase");
         collectRelevantVectors(ri, "RelativeInclude");
-        for (Iterator i = ri.iterator(); i.hasNext(); ) {
-            String f = (String)i.next();
+        for (String f : ri) {
             rv.add(sourceBase + Util.sep + f);
         }
         return rv;
@@ -604,7 +506,6 @@
     }
 }
 
-
 abstract class ProductConfig extends BuildConfig {
     protected void init(Vector includes, Vector defines) {
         defines.add("NDEBUG");
@@ -638,7 +539,6 @@
     }
 }
 
-
 class CoreDebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getNoOptFlag();
@@ -650,7 +550,6 @@
     }
 }
 
-
 class CoreFastDebugConfig extends GenericDebugNonKernelConfig {
     String getOptFlag() {
         return getCI().getOptFlag();
@@ -662,7 +561,6 @@
     }
 }
 
-
 class CoreProductConfig extends ProductConfig {
     CoreProductConfig() {
         initNames("core", "product", "jvm.dll");
@@ -700,6 +598,7 @@
         init(getIncludes(), getDefines());
     }
 }
+
 abstract class CompilerInterface {
     abstract Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir);
     abstract Vector getBaseLinkerFlags(String outDir, String outDll, String platformName);
diff --git a/hotspot/src/share/tools/ProjectCreator/DirectoryTree.java b/hotspot/src/share/tools/ProjectCreator/DirectoryTree.java
deleted file mode 100644
index 76a5e46..0000000
--- a/hotspot/src/share/tools/ProjectCreator/DirectoryTree.java
+++ /dev/null
@@ -1,287 +0,0 @@
-/*
- * 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
- * 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.
- *
- */
-
-/** Encapsulates a notion of a directory tree. Designed to allow fast
-    querying of full paths for unique filenames in the hierarchy. */
-
-import java.io.*;
-import java.util.*;
-
-public class DirectoryTree {
-
-    /** The root of the read directoryTree */
-    private Node rootNode;
-
-    /** Subdirs to ignore; Vector of Strings */
-    private Vector subdirsToIgnore;
-
-    /** This maps file names to Lists of nodes. */
-    private Hashtable nameToNodeListTable;
-
-    /** Output "."'s as directories are read. Defaults to false. */
-    private boolean verbose;
-
-    public DirectoryTree() {
-        subdirsToIgnore = new Vector();
-        verbose = false;
-    }
-
-    public void addSubdirToIgnore(String subdir) {
-        subdirsToIgnore.add(subdir);
-    }
-
-    private class FileIterator implements Iterator {
-        private Vector nodes = new Vector();
-
-        public FileIterator(Node rootNode) {
-            if(rootNode == null) {
-                return;
-            }
-            nodes.add(rootNode);
-            prune();
-        }
-        public boolean hasNext() {
-            return nodes.size() > 0;
-        }
-        public Object next() {
-            Node last = (Node)nodes.remove(nodes.size() - 1);
-            prune();
-            return new File(last.getName());
-        }
-
-        public void remove() {
-            throw new RuntimeException();
-        }
-
-        private void prune() {
-            while (nodes.size() > 0) {
-                Node last = (Node)nodes.get(nodes.size() - 1);
-
-                if (last.isDirectory()) {
-                    nodes.remove(nodes.size() - 1);
-                    nodes.addAll(last.children);
-                } else {
-                    // Is at file
-                    return;
-                }
-            }
-        }
-    }
-
-    public Iterator getFileIterator() {
-        return new FileIterator(rootNode);
-    }
-
-    /** Output "."'s to System.out as directories are read. Defaults
-        to false. */
-    public void setVerbose(boolean newValue) {
-        verbose = newValue;
-    }
-
-    public boolean getVerbose() {
-        return verbose;
-    }
-
-    public String getRootNodeName() {
-        return rootNode.getName();
-    }
-
-    /** Takes an absolute path to the root directory of this
-        DirectoryTree. Throws IllegalArgumentException if the given
-        string represents a plain file or nonexistent directory. */
-
-    public void readDirectory(String baseDirectory)
-        throws IllegalArgumentException {
-        File root = new File(Util.normalize(baseDirectory));
-        if (!root.isDirectory()) {
-            return;
-        }
-        try {
-            root = root.getCanonicalFile();
-        }
-        catch (IOException e) {
-            throw new RuntimeException(e.toString());
-        }
-        rootNode = new Node(root);
-        readDirectory(rootNode, root);
-    }
-
-    /** Queries the DirectoryTree for a file or directory name. Takes
-        only the name of the file or directory itself (i.e., no parent
-        directory information should be in the passed name). Returns a
-        List of DirectoryTreeNodes specifying the full paths of all of
-        the files or directories of this name in the DirectoryTree.
-        Returns null if the directory tree has not been read from disk
-        yet or if the file was not found in the tree. */
-    public List findFile(String name) {
-        if (rootNode == null) {
-            return null;
-        }
-
-        if (nameToNodeListTable == null) {
-            nameToNodeListTable = new Hashtable();
-            try {
-                buildNameToNodeListTable(rootNode);
-            } catch (IOException e) {
-                e.printStackTrace();
-                return null;
-            }
-        }
-
-        return (List) nameToNodeListTable.get(name);
-    }
-
-    private void buildNameToNodeListTable(Node curNode)
-      throws IOException {
-        String fullName = curNode.getName();
-        String parent = curNode.getParent();
-        String separator = System.getProperty("file.separator");
-
-        if (parent != null) {
-          if (!fullName.startsWith(parent)) {
-            throw new RuntimeException(
-                "Internal error: parent of file name \"" + fullName +
-                "\" does not match file name \"" + parent + "\""
-            );
-          }
-
-          int len = parent.length();
-          if (!parent.endsWith(separator)) {
-            len += separator.length();
-          }
-
-          String fileName = fullName.substring(len);
-
-          if (fileName == null) {
-            throw new RuntimeException(
-                "Internal error: file name was empty"
-            );
-          }
-
-          List nodeList = (List) nameToNodeListTable.get(fileName);
-          if (nodeList == null) {
-            nodeList = new Vector();
-            nameToNodeListTable.put(fileName, nodeList);
-          }
-
-          nodeList.add(curNode);
-        } else {
-          if (curNode != rootNode) {
-            throw new RuntimeException(
-                "Internal error: parent of file + \"" + fullName + "\"" +
-                " was null"
-            );
-          }
-        }
-
-        if (curNode.isDirectory()) {
-          Iterator iter = curNode.getChildren();
-          if (iter != null) {
-            while (iter.hasNext()) {
-              buildNameToNodeListTable((Node) iter.next());
-            }
-          }
-        }
-    }
-
-    /** Reads all of the files in the given directory and adds them as
-        children of the directory tree node. Requires that the passed
-        node represents a directory. */
-
-    private void readDirectory(Node parentNode, File parentDir) {
-        File[] children = parentDir.listFiles();
-        if (children == null)
-            return;
-        if (verbose) {
-            System.out.print(".");
-            System.out.flush();
-        }
-        for (int i = 0; i < children.length; i++) {
-            File child = children[i];
-            children[i] = null;
-            boolean isDir = child.isDirectory();
-            boolean mustSkip = false;
-            if (isDir) {
-                for (Iterator iter = subdirsToIgnore.iterator();
-                     iter.hasNext(); ) {
-                    if (child.getName().equals((String) iter.next())) {
-                        mustSkip = true;
-                        break;
-                    }
-                }
-            }
-            if (!mustSkip) {
-                Node childNode = new Node(child);
-                parentNode.addChild(childNode);
-                if (isDir) {
-                    readDirectory(childNode, child);
-                }
-            }
-        }
-    }
-
-    private class Node implements DirectoryTreeNode {
-        private File file;
-        private Vector children;
-
-        /** file must be a canonical file */
-        Node(File file) {
-            this.file = file;
-            children = new Vector();
-        }
-
-        public boolean isFile() {
-            return file.isFile();
-        }
-
-        public boolean isDirectory() {
-            return file.isDirectory();
-        }
-
-        public String getName() {
-            return file.getPath();
-        }
-
-        public String getParent() {
-            return file.getParent();
-        }
-
-        public void addChild(Node n) {
-            children.add(n);
-        }
-
-        public Iterator getChildren() throws IllegalArgumentException {
-            return children.iterator();
-        }
-
-        public int getNumChildren() throws IllegalArgumentException {
-            return children.size();
-        }
-
-        public DirectoryTreeNode getChild(int i)
-            throws IllegalArgumentException, ArrayIndexOutOfBoundsException {
-            return (DirectoryTreeNode) children.get(i);
-        }
-    }
-}
diff --git a/hotspot/src/share/tools/ProjectCreator/DirectoryTreeNode.java b/hotspot/src/share/tools/ProjectCreator/DirectoryTreeNode.java
deleted file mode 100644
index f198dc2..0000000
--- a/hotspot/src/share/tools/ProjectCreator/DirectoryTreeNode.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-import java.util.*;
-
-public interface DirectoryTreeNode {
-    public boolean isFile();
-    public boolean isDirectory();
-    public String getName();
-    public String getParent();
-    public Iterator getChildren() throws IllegalArgumentException;
-    public int getNumChildren() throws IllegalArgumentException;
-    public DirectoryTreeNode getChild(int i)
-        throws IllegalArgumentException, ArrayIndexOutOfBoundsException;
-}
diff --git a/hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java b/hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java
new file mode 100644
index 0000000..3643c57
--- /dev/null
+++ b/hotspot/src/share/tools/ProjectCreator/FileTreeCreator.java
@@ -0,0 +1,72 @@
+import java.nio.file.FileSystems;
+import java.nio.file.Path;
+import java.nio.file.SimpleFileVisitor;
+import java.util.HashSet;
+import java.util.Stack;
+import java.util.Vector;
+
+public class FileTreeCreator extends SimpleFileVisitor<Path>
+{
+   Path vcProjLocation;
+   Path startDir;
+   final int startDirLength;
+   Stack<DirAttributes> attributes = new Stack<DirAttributes>();
+   Vector<BuildConfig> allConfigs;
+   WinGammaPlatformVC10 wg;
+
+   public FileTreeCreator(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatformVC10 wg) {
+      super();
+      this.wg = wg;
+      this.allConfigs = allConfigs;
+      this.startDir = startDir;
+      startDirLength = startDir.toAbsolutePath().toString().length();
+      vcProjLocation = FileSystems.getDefault().getPath(allConfigs.firstElement().get("BuildSpace"));
+      attributes.push(new DirAttributes());
+   }
+
+   public class DirAttributes {
+
+      private HashSet<BuildConfig> ignores;
+      private HashSet<BuildConfig> disablePch;
+
+      public DirAttributes() {
+         ignores = new HashSet<BuildConfig>();
+         disablePch = new HashSet<BuildConfig>();
+      }
+
+      public DirAttributes(HashSet<BuildConfig> excludes2, HashSet<BuildConfig> disablePch2) {
+         ignores = excludes2;
+         disablePch = disablePch2;
+      }
+
+      @SuppressWarnings("unchecked")
+      public DirAttributes clone() {
+         return new DirAttributes((HashSet<BuildConfig>)this.ignores.clone(), (HashSet<BuildConfig>)this.disablePch.clone());
+      }
+
+      public void setIgnore(BuildConfig conf) {
+         ignores.add(conf);
+      }
+
+      public boolean hasIgnore(BuildConfig cfg) {
+         return ignores.contains(cfg);
+      }
+
+      public void removeFromIgnored(BuildConfig cfg) {
+         ignores.remove(cfg);
+      }
+
+      public void setDisablePch(BuildConfig conf) {
+         disablePch.add(conf);
+      }
+
+      public boolean hasDisablePch(BuildConfig cfg) {
+         return disablePch.contains(cfg);
+      }
+
+      public void removeFromDisablePch(BuildConfig cfg) {
+         disablePch.remove(cfg);
+      }
+
+   }
+}
diff --git a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java
new file mode 100644
index 0000000..837eef1
--- /dev/null
+++ b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC10.java
@@ -0,0 +1,142 @@
+import static java.nio.file.FileVisitResult.CONTINUE;
+
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Stack;
+import java.util.Vector;
+
+public class FileTreeCreatorVC10 extends FileTreeCreator {
+
+      public FileTreeCreatorVC10(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatformVC10 wg) {
+         super(startDir, allConfigs, wg);
+      }
+
+      @Override
+      public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
+         DirAttributes currentFileAttr = attributes.peek().clone();
+         boolean usePch = false;
+         boolean disablePch = false;
+         boolean useIgnore = false;
+         String fileName = file.getFileName().toString();
+
+         // TODO hideFile
+
+         // usePch applies to all configs for a file.
+         if (fileName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch"))) {
+            usePch = true;
+         }
+
+         for (BuildConfig cfg : allConfigs) {
+            if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) {
+               useIgnore = true;
+               currentFileAttr.setIgnore(cfg);
+            } else if (cfg.matchesIgnoredPath(file.toAbsolutePath().toString())) {
+               useIgnore = true;
+               currentFileAttr.setIgnore(cfg);
+            }
+
+            if (cfg.lookupHashFieldInContext("DisablePch", fileName) != null) {
+               disablePch = true;
+               currentFileAttr.setDisablePch(cfg);
+            }
+
+            Vector<String> rv = new Vector<String>();
+            cfg.collectRelevantVectors(rv, "AdditionalFile");
+            for(String addFile : rv) {
+               if (addFile.equals(fileName)) {
+                  // supress any ignore
+                  // TODO - may need some adjustments
+                  if (file.toAbsolutePath().toString().contains(cfg.get("Flavour"))) {
+                     currentFileAttr.removeFromIgnored(cfg);
+                  }
+               }
+            }
+         }
+
+         String tagName = wg.getFileTagFromSuffix(fileName);
+         String fileLoc = vcProjLocation.relativize(file).toString();
+
+         if (!useIgnore && !disablePch && !usePch) {
+            wg.tag(tagName, new String[] { "Include", fileLoc});
+         } else {
+            wg.startTag(
+                  tagName,
+                  new String[] { "Include", fileLoc});
+
+            for (BuildConfig cfg : allConfigs) {
+               boolean ignore = currentFileAttr.hasIgnore(cfg);
+               if (ignore) {
+                  wg.tagData("ExcludedFromBuild", "true", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
+               }
+               if (usePch) {
+                  wg.tagData("PrecompiledHeader", "Create", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
+               }
+               if (disablePch) {
+                  wg.tag("PrecompiledHeader", "Condition", "'$(Configuration)|$(Platform)'=='" + cfg.get("Name") + "'");
+               }
+            }
+            wg.endTag();
+         }
+
+         String filter = startDir.relativize(file.getParent().toAbsolutePath()).toString();
+         wg.addFilterDependency(fileLoc, filter);
+
+         return CONTINUE;
+      }
+
+      @Override
+      public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs)
+            throws IOException {
+         Boolean hide = false;
+         // TODO remove attrs, if path is matched in this dir, then it is too in every subdir.
+         // And we will check anyway
+         DirAttributes newAttr = attributes.peek().clone();
+
+         // check per config ignorePaths!
+         for (BuildConfig cfg : allConfigs) {
+            if (cfg.matchesIgnoredPath(path.toAbsolutePath().toString())) {
+               newAttr.setIgnore(cfg);
+            }
+
+            // Hide is always on all configs. And additional files are never hiddden
+            if (cfg.matchesHidePath(path.toAbsolutePath().toString())) {
+               hide = true;
+               break;
+            }
+         }
+
+         if (!hide) {
+            String name = startDir.relativize(path.toAbsolutePath()).toString();
+            if (!"".equals(name)) {
+               wg.addFilter(name);
+            }
+
+            attributes.push(newAttr);
+            return super.preVisitDirectory(path, attrs);
+         } else {
+            return FileVisitResult.SKIP_SUBTREE;
+         }
+      }
+
+      @Override
+      public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+         //end matching attributes set by ignorepath
+         attributes.pop();
+         return CONTINUE;
+      }
+
+      @Override
+      public FileVisitResult visitFileFailed(Path file, IOException exc) {
+         return CONTINUE;
+      }
+
+      public void writeFileTree() throws IOException {
+         Files.walkFileTree(this.startDir, this);
+      }
+
+
+   }
\ No newline at end of file
diff --git a/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java
new file mode 100644
index 0000000..b36e012
--- /dev/null
+++ b/hotspot/src/share/tools/ProjectCreator/FileTreeCreatorVC7.java
@@ -0,0 +1,156 @@
+import static java.nio.file.FileVisitResult.CONTINUE;
+
+import java.io.IOException;
+import java.nio.file.FileSystems;
+import java.nio.file.FileVisitResult;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.util.Stack;
+import java.util.Vector;
+
+public class FileTreeCreatorVC7 extends FileTreeCreator {
+
+      public FileTreeCreatorVC7(Path startDir, Vector<BuildConfig> allConfigs, WinGammaPlatform wg) {
+         super(startDir, allConfigs, null);
+      }
+
+      @Override
+      public FileVisitResult visitFile(Path file, BasicFileAttributes attr) {
+         DirAttributes currentFileAttr = attributes.peek().clone();
+         boolean usePch = false;
+         boolean disablePch = false;
+         boolean useIgnore = false;
+         String fileName = file.getFileName().toString();
+
+         // usePch applies to all configs for a file.
+         if (fileName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch"))) {
+            usePch = true;
+         }
+
+         for (BuildConfig cfg : allConfigs) {
+            if (cfg.lookupHashFieldInContext("IgnoreFile", fileName) != null) {
+               useIgnore = true;
+               currentFileAttr.setIgnore(cfg);
+            } else if (cfg.matchesIgnoredPath(file.toAbsolutePath().toString())) {
+               useIgnore = true;
+               currentFileAttr.setIgnore(cfg);
+            }
+
+            if (cfg.lookupHashFieldInContext("DisablePch", fileName) != null) {
+               disablePch = true;
+               currentFileAttr.setDisablePch(cfg);
+            }
+
+            Vector<String> rv = new Vector<String>();
+            cfg.collectRelevantVectors(rv, "AdditionalFile");
+            for(String addFile : rv) {
+               if (addFile.equals(fileName)) {
+                  // supress any ignore
+                  currentFileAttr.removeFromIgnored(cfg);
+               }
+            }
+         }
+
+         if (!useIgnore && !disablePch && !usePch) {
+            wg.tag("File", new String[] { "RelativePath", vcProjLocation.relativize(file).toString()});
+         } else {
+            wg.startTag(
+                  "File",
+                  new String[] { "RelativePath", vcProjLocation.relativize(file).toString()});
+
+            for (BuildConfig cfg : allConfigs) {
+               boolean ignore = currentFileAttr.hasIgnore(cfg);
+               String [] fileConfAttr;
+
+               if (ignore) {
+                  fileConfAttr = new String[] {"Name", cfg.get("Name"), "ExcludedFromBuild", "TRUE" };
+               } else {
+                  fileConfAttr = new String[] {"Name", cfg.get("Name")};
+               }
+
+               if (!disablePch && !usePch && !ignore) {
+                  continue;
+               } else if (!disablePch && !usePch) {
+                  wg.tag("FileConfiguration", fileConfAttr);
+               } else {
+                  wg.startTag("FileConfiguration", fileConfAttr);
+                  if (usePch) {
+                     // usePch always applies to all configs, might not always be so.
+                     wg.tag("Tool", new String[] {
+                           "Name", "VCCLCompilerTool", "UsePrecompiledHeader",
+                     "1" });
+                     assert(!disablePch);
+                  }
+                  if (disablePch) {
+                     if (currentFileAttr.hasDisablePch(cfg)) {
+                        wg.tag("Tool", new String[] {
+                              "Name", "VCCLCompilerTool", "UsePrecompiledHeader",
+                        "0" });
+                     }
+                     assert(!usePch);
+                  }
+                  wg.endTag();
+               }
+            }
+            wg.endTag();
+         }
+
+         return CONTINUE;
+      }
+
+      @Override
+      public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs)
+            throws IOException {
+         Boolean hide = false;
+         DirAttributes newAttr = attributes.peek().clone();
+
+         String rPath;
+         if (path.toAbsolutePath().toString().equals(this.startDir.toAbsolutePath().toString())){
+            rPath = startDir.toString();
+         } else {
+            rPath = path.getFileName().toString();
+         }
+
+         // check per config ignorePaths!
+         for (BuildConfig cfg : allConfigs) {
+            if (cfg.matchesIgnoredPath(path.toAbsolutePath().toString())) {
+               newAttr.setIgnore(cfg);
+            }
+
+            // Hide is always on all configs. And additional files are never hiddden
+            if (cfg.matchesHidePath(path.toAbsolutePath().toString())) {
+               hide = true;
+               break;
+            }
+         }
+
+         if (!hide) {
+            wg.startTag("Filter", new String[] {
+                  "Name", rPath});
+
+            attributes.push(newAttr);
+            return super.preVisitDirectory(path, attrs);
+         } else {
+            return FileVisitResult.SKIP_SUBTREE;
+         }
+      }
+
+      @Override
+      public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
+         //end matching attributes set by ignorepath
+         wg.endTag();
+         attributes.pop();
+
+         return CONTINUE;
+      }
+
+      @Override
+      public FileVisitResult visitFileFailed(Path file, IOException exc) {
+         return CONTINUE;
+      }
+
+      public void writeFileTree() throws IOException {
+         Files.walkFileTree(this.startDir, this);
+      }
+   }
\ No newline at end of file
diff --git a/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java b/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java
index 5203c5a..93a7b1d 100644
--- a/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java
+++ b/hotspot/src/share/tools/ProjectCreator/ProjectCreator.java
@@ -24,75 +24,76 @@
 
 public class ProjectCreator {
 
-    public static void usage() {
-        System.out.println("ProjectCreator options:");
-        System.err.println("WinGammaPlatform platform-specific options:");
-        System.err.println("  -sourceBase <path to directory (workspace) " +
-                           "containing source files; no trailing slash>");
-        System.err.println("  -dspFileName <full pathname to which .dsp file " +
-                           "will be written; all parent directories must " +
-                           "already exist>");
-        System.err.println("  -envVar <environment variable to be inserted " +
-                           "into .dsp file, substituting for path given in " +
-                           "-sourceBase. Example: HotSpotWorkSpace>");
-        System.err.println("  -dllLoc <path to directory in which to put " +
-                           "jvm.dll and jvm_g.dll; no trailing slash>");
-        System.err.println("  If any of the above are specified, "+
-                           "they must all be.");
-        System.err.println("  Additional, optional arguments, which can be " +
-                           "specified multiple times:");
-        System.err.println("    -absoluteInclude <string containing absolute " +
-                           "path to include directory>");
-        System.err.println("    -relativeInclude <string containing include " +
-                           "directory relative to -envVar>");
-        System.err.println("    -define <preprocessor flag to be #defined " +
-                           "(note: doesn't yet support " +
-                           "#define (flag) (value))>");
-        System.err.println("    -perFileLine <file> <line>");
-        System.err.println("    -conditionalPerFileLine <file> <line for " +
-                           "release build> <line for debug build>");
-        System.err.println("  (NOTE: To work around a bug in nmake, where " +
-                           "you can't have a '#' character in a quoted " +
-                           "string, all of the lines outputted have \"#\"" +
-                           "prepended)");
-        System.err.println("    -startAt <subdir of sourceBase>");
-        System.err.println("    -ignoreFile <file which won't be able to be " +
-                           "found in the sourceBase because it's generated " +
-                           "later>");
-        System.err.println("    -additionalFile <file not in database but " +
-                           "which should show up in .dsp file>");
-        System.err.println("    -additionalGeneratedFile <environment variable of " +
-                           "generated file's location> <relative path to " +
-                           "directory containing file; no trailing slash> " +
-                           "<name of file generated later in the build process>");
-        System.err.println("    -prelink <build> <desc> <cmds>:");
-        System.err.println(" Generate a set of prelink commands for the given BUILD");
-        System.err.println(" (\"Debug\" or \"Release\"). The prelink description and commands");
-        System.err.println(" are both quoted strings.");
-        System.err.println("    Default includes: \".\"");
-        System.err.println("    Default defines: WIN32, _WINDOWS, \"HOTSPOT_BUILD_USER=$(USERNAME)\"");
-    }
+   public static void usage() {
+      System.out.println("ProjectCreator options:");
+      System.err.println("WinGammaPlatform platform-specific options:");
+      System.err.println("  -sourceBase <path to directory (workspace) "
+            + "containing source files; no trailing slash>");
+      System.err.println("  -dspFileName <full pathname to which .dsp file "
+            + "will be written; all parent directories must "
+            + "already exist>");
+      System.err.println("  -envVar <environment variable to be inserted "
+            + "into .dsp file, substituting for path given in "
+            + "-sourceBase. Example: HotSpotWorkSpace>");
+      System.err.println("  -dllLoc <path to directory in which to put "
+            + "jvm.dll and jvm_g.dll; no trailing slash>");
+      System.err.println("  If any of the above are specified, "
+            + "they must all be.");
+      System.err.println("  Additional, optional arguments, which can be "
+            + "specified multiple times:");
+      System.err.println("    -absoluteInclude <string containing absolute "
+            + "path to include directory>");
+      System.err.println("    -relativeInclude <string containing include "
+            + "directory relative to -envVar>");
+      System.err.println("    -define <preprocessor flag to be #defined "
+            + "(note: doesn't yet support " + "#define (flag) (value))>");
+      System.err.println("    -perFileLine <file> <line>");
+      System.err.println("    -conditionalPerFileLine <file> <line for "
+            + "release build> <line for debug build>");
+      System.err.println("  (NOTE: To work around a bug in nmake, where "
+            + "you can't have a '#' character in a quoted "
+            + "string, all of the lines outputted have \"#\"" + "prepended)");
+      System.err.println("    -startAt <subdir of sourceBase>");
+      System.err.println("    -ignoreFile <file which won't be able to be "
+            + "found in the sourceBase because it's generated " + "later>");
+      System.err.println("    -additionalFile <file not in database but "
+            + "which should show up in .dsp file>");
+      System.err
+            .println("    -additionalGeneratedFile <environment variable of "
+                  + "generated file's location> <relative path to "
+                  + "directory containing file; no trailing slash> "
+                  + "<name of file generated later in the build process>");
+      System.err.println("    -prelink <build> <desc> <cmds>:");
+      System.err
+            .println(" Generate a set of prelink commands for the given BUILD");
+      System.err
+            .println(" (\"Debug\" or \"Release\"). The prelink description and commands");
+      System.err.println(" are both quoted strings.");
+      System.err.println("    Default includes: \".\"");
+      System.err
+            .println("    Default defines: WIN32, _WINDOWS, \"HOTSPOT_BUILD_USER=$(USERNAME)\"");
+   }
 
-    public static void main(String[] args) {
-        try {
-            if (args.length < 3) {
-                usage();
-                System.exit(1);
-            }
+   public static void main(String[] args) {
+      try {
+         if (args.length < 3) {
+            usage();
+            System.exit(1);
+         }
 
-            String platformName = args[0];
-            Class platformClass = Class.forName(platformName);
-            WinGammaPlatform platform = (WinGammaPlatform) platformClass.newInstance();
+         String platformName = args[0];
+         Class platformClass = Class.forName(platformName);
+         WinGammaPlatform platform = (WinGammaPlatform) platformClass
+               .newInstance();
 
-            String[] platformArgs = new String[args.length - 1];
-            System.arraycopy(args, 1, platformArgs, 0, platformArgs.length);
+         String[] platformArgs = new String[args.length - 1];
+         System.arraycopy(args, 1, platformArgs, 0, platformArgs.length);
 
-            // Allow the platform to write platform-specific files
-            platform.createVcproj(platformArgs);
-        }
-        catch (Exception e) {
-            e.printStackTrace();
-              System.exit(1);
-        }
-    }
+         // Allow the platform to write platform-specific files
+         platform.createVcproj(platformArgs);
+      } catch (Exception e) {
+         e.printStackTrace();
+         System.exit(1);
+      }
+   }
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/Util.java b/hotspot/src/share/tools/ProjectCreator/Util.java
index 466a099..b8fe156 100644
--- a/hotspot/src/share/tools/ProjectCreator/Util.java
+++ b/hotspot/src/share/tools/ProjectCreator/Util.java
@@ -26,18 +26,19 @@
 import java.io.File;
 
 public class Util {
-    static String join(String padder, Vector v) {
+
+    static String join(String padder, Vector<String> v) {
         return join(padder, v, false);
     }
 
-    static String join(String padder, Vector v, boolean quoted) {
+    static String join(String padder, Vector<String> v, boolean quoted) {
         StringBuffer sb = new StringBuffer();
 
-        for (Iterator iter = v.iterator(); iter.hasNext(); ) {
+        for (Iterator<String> iter = v.iterator(); iter.hasNext(); ) {
             if (quoted) {
                 sb.append('"');
             }
-            sb.append((String)iter.next());
+            sb.append(iter.next());
             if (quoted) {
                 sb.append('"');
             }
@@ -48,10 +49,10 @@
     }
 
 
-    static String prefixed_join(String padder, Vector v, boolean quoted) {
+    static String prefixed_join(String padder, Vector<String> v, boolean quoted) {
         StringBuffer sb = new StringBuffer();
 
-        for (Iterator iter = v.iterator(); iter.hasNext(); ) {
+        for (Iterator<String> iter = v.iterator(); iter.hasNext(); ) {
             sb.append(padder);
 
             if (quoted) {
diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java
index 7c4dc53..41deb52 100644
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatform.java
@@ -29,6 +29,7 @@
 import java.util.Hashtable;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Stack;
 import java.util.TreeSet;
 import java.util.Vector;
 
@@ -218,69 +219,6 @@
         return false;
     }
 
-    /* This returns a String containing the full path to the passed
-       file name, or null if an error occurred. If the file was not
-       found or was a duplicate and couldn't be resolved using the
-       preferred paths, the file name is added to the appropriate
-       Vector of Strings. */
-    private String findFileInDirectory(String fileName,
-                                       DirectoryTree directory,
-                                       Vector preferredPaths,
-                                       Vector filesNotFound,
-                                       Vector filesDuplicate) {
-        List locationsInTree = directory.findFile(fileName);
-        int  rootNameLength = directory.getRootNodeName().length();
-        String name = null;
-        if ((locationsInTree == null) ||
-            (locationsInTree.size() == 0)) {
-            filesNotFound.add(fileName);
-        } else if (locationsInTree.size() > 1) {
-            // Iterate through them, trying to find one with a
-            // preferred path
-        search:
-            {
-                for (Iterator locIter = locationsInTree.iterator();
-                     locIter.hasNext(); ) {
-                    DirectoryTreeNode node =
-                        (DirectoryTreeNode) locIter.next();
-                    String tmpName = node.getName();
-                    for (Iterator prefIter = preferredPaths.iterator();
-                         prefIter.hasNext(); ) {
-                        // We need to make sure the preferred path is
-                        // found from the file path not including the root node name.
-                        if (tmpName.indexOf((String)prefIter.next(),
-                                            rootNameLength) != -1) {
-                            name = tmpName;
-                            break search;
-                        }
-                    }
-                }
-            }
-
-            if (name == null) {
-                filesDuplicate.add(fileName);
-            }
-        } else {
-            name = ((DirectoryTreeNode) locationsInTree.get(0)).getName();
-        }
-
-        return name;
-    }
-
-    protected String envVarPrefixedFileName(String fileName,
-                                            int sourceBaseLen,
-                                            DirectoryTree tree,
-                                            Vector preferredPaths,
-                                            Vector filesNotFound,
-                                            Vector filesDuplicate) {
-        String fullName = findFileInDirectory(fileName,
-                                              tree,
-                                              preferredPaths,
-                                              filesNotFound,
-                                              filesDuplicate);
-        return fullName;
-    }
-
      String getProjectName(String fullPath, String extension)
         throws IllegalArgumentException, IOException {
         File file = new File(fullPath).getCanonicalFile();
@@ -369,6 +307,12 @@
                               HsArgHandler.STRING
                               ),
 
+               new HsArgRule("-buildSpace",
+                              "BuildSpace",
+                              null,
+                              HsArgHandler.STRING
+                              ),
+
               new HsArgRule("-platformName",
                               "PlatformName",
                               null,
@@ -405,6 +349,18 @@
                               HsArgHandler.VECTOR
                               ),
 
+                new HsArgRule("-absoluteSrcInclude",
+                              "AbsoluteSrcInclude",
+                              null,
+                              HsArgHandler.VECTOR
+                              ),
+
+                new HsArgRule("-relativeSrcInclude",
+                              "RelativeSrcInclude",
+                              null,
+                              HsArgHandler.VECTOR
+                              ),
+
                 new HsArgRule("-define",
                               "Define",
                               null,
@@ -494,6 +450,12 @@
                               HsArgHandler.VECTOR
                               ),
 
+                new HsArgRule("-hidePath",
+                      "HidePath",
+                      null,
+                      HsArgHandler.VECTOR
+                      ),
+
                 new HsArgRule("-additionalFile",
                               "AdditionalFile",
                               null,
@@ -611,107 +573,101 @@
         return allConfigs;
     }
 
-    class FileAttribute {
-        int     numConfigs;
-        Vector  configs;
-        String  shortName;
-        boolean noPch, pchRoot;
-
-        FileAttribute(String shortName, BuildConfig cfg, int numConfigs) {
-            this.shortName = shortName;
-            this.noPch =  (cfg.lookupHashFieldInContext("DisablePch", shortName) != null);
-            this.pchRoot = shortName.equals(BuildConfig.getFieldString(null, "UseToGeneratePch"));
-            this.numConfigs = numConfigs;
-
-            configs = new Vector();
-            add(cfg.get("Name"));
-        }
-
-        void add(String confName) {
-            configs.add(confName);
-
-            // if presented in all configs
-            if (configs.size() == numConfigs) {
-                configs = null;
-            }
-        }
-    }
-
-    class FileInfo implements Comparable {
-        String        full;
-        FileAttribute attr;
-
-        FileInfo(String full, FileAttribute  attr) {
-            this.full = full;
-            this.attr = attr;
-        }
-
-        public int compareTo(Object o) {
-            FileInfo oo = (FileInfo)o;
-            return full.compareTo(oo.full);
-        }
-
-        boolean isHeader() {
-            return attr.shortName.endsWith(".h") || attr.shortName.endsWith(".hpp");
-        }
-
-        boolean isCpp() {
-            return attr.shortName.endsWith(".cpp");
-        }
-    }
-
-
-    TreeSet sortFiles(Hashtable allFiles) {
-        TreeSet rv = new TreeSet();
-        Enumeration e = allFiles.keys();
-        while (e.hasMoreElements()) {
-            String fullPath = (String)e.nextElement();
-            rv.add(new FileInfo(fullPath, (FileAttribute)allFiles.get(fullPath)));
-        }
-        return rv;
-    }
-
-    Hashtable computeAttributedFiles(Vector allConfigs) {
-        Hashtable ht = new Hashtable();
-        int numConfigs = allConfigs.size();
-
-        for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
-            BuildConfig bc = (BuildConfig)i.next();
-            Hashtable  confFiles = (Hashtable)bc.getSpecificField("AllFilesHash");
-            String confName = bc.get("Name");
-
-            for (Enumeration e=confFiles.keys(); e.hasMoreElements(); ) {
-                String filePath = (String)e.nextElement();
-                FileAttribute fa = (FileAttribute)ht.get(filePath);
-
-                if (fa == null) {
-                    fa = new FileAttribute((String)confFiles.get(filePath), bc, numConfigs);
-                    ht.put(filePath, fa);
-                } else {
-                    fa.add(confName);
-                }
-            }
-        }
-
-        return ht;
-    }
-
-     Hashtable computeAttributedFiles(BuildConfig bc) {
-        Hashtable ht = new Hashtable();
-        Hashtable confFiles = (Hashtable)bc.getSpecificField("AllFilesHash");
-
-        for (Enumeration e = confFiles.keys(); e.hasMoreElements(); ) {
-            String filePath = (String)e.nextElement();
-            ht.put(filePath,  new FileAttribute((String)confFiles.get(filePath), bc, 1));
-        }
-
-        return ht;
-    }
-
     PrintWriter printWriter;
 
     public void writeProjectFile(String projectFileName, String projectName,
                                  Vector<BuildConfig> allConfigs) throws IOException {
         throw new RuntimeException("use compiler version specific version");
     }
+
+    int indent;
+    private Stack<String> tagStack = new Stack<String>();
+
+    private void startTagPrim(String name, String[] attrs, boolean close) {
+       startTagPrim(name, attrs, close, true);
+    }
+
+    private void startTagPrim(String name, String[] attrs, boolean close,
+          boolean newline) {
+       doIndent();
+       printWriter.print("<" + name);
+       indent++;
+
+       if (attrs != null && attrs.length > 0) {
+          for (int i = 0; i < attrs.length; i += 2) {
+             printWriter.print(" " + attrs[i] + "=\"" + attrs[i + 1] + "\"");
+             if (i < attrs.length - 2) {
+             }
+          }
+       }
+
+       if (close) {
+          indent--;
+          printWriter.print(" />");
+       } else {
+          // TODO push tag name, and change endTag to pop and print.
+          tagStack.push(name);
+          printWriter.print(">");
+       }
+       if (newline) {
+          printWriter.println();
+       }
+    }
+
+    void startTag(String name, String... attrs) {
+       startTagPrim(name, attrs, false);
+    }
+
+    void startTagV(String name, Vector attrs) {
+       String s[] = new String[attrs.size()];
+       for (int i = 0; i < attrs.size(); i++) {
+          s[i] = (String) attrs.elementAt(i);
+       }
+       startTagPrim(name, s, false);
+    }
+
+    void endTag() {
+       String name = tagStack.pop();
+       indent--;
+       doIndent();
+       printWriter.println("</" + name + ">");
+    }
+
+    private void endTagNoIndent() {
+       String name = tagStack.pop();
+       indent--;
+       printWriter.println("</" + name + ">");
+    }
+
+    void tag(String name, String... attrs) {
+       startTagPrim(name, attrs, true);
+    }
+
+    void tagData(String name, String data) {
+       startTagPrim(name, null, false, false);
+       printWriter.print(data);
+       endTagNoIndent();
+    }
+
+    void tagData(String name, String data, String... attrs) {
+       startTagPrim(name, attrs, false, false);
+       printWriter.print(data);
+       endTagNoIndent();
+    }
+
+    void tagV(String name, Vector attrs) {
+       String s[] = new String[attrs.size()];
+       for (int i = 0; i < attrs.size(); i++) {
+          s[i] = (String) attrs.elementAt(i);
+       }
+       startTagPrim(name, s, true);
+    }
+
+    void doIndent() {
+       for (int i = 0; i < indent; i++) {
+          printWriter.print("  ");
+       }
+    }
+
+
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
index 4a96981..137abdc 100644
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC10.java
@@ -3,14 +3,18 @@
 import java.io.IOException;
 import java.io.PrintWriter;
 import java.io.UnsupportedEncodingException;
-import java.util.Hashtable;
+import java.nio.file.FileSystems;
 import java.util.Iterator;
-import java.util.TreeSet;
+import java.util.LinkedList;
 import java.util.UUID;
 import java.util.Vector;
 
 public class WinGammaPlatformVC10 extends WinGammaPlatformVC7 {
 
+
+   LinkedList <String>filters = new LinkedList<String>();
+   LinkedList <String[]>filterDeps = new LinkedList<String[]>();
+
     @Override
     protected String getProjectExt() {
         return ".vcxproj";
@@ -37,15 +41,15 @@
                     "Include", cfg.get("Name"));
             tagData("Configuration", cfg.get("Id"));
             tagData("Platform", cfg.get("PlatformName"));
-            endTag("ProjectConfiguration");
+            endTag();
         }
-        endTag("ItemGroup");
+        endTag();
 
         startTag("PropertyGroup", "Label", "Globals");
         tagData("ProjectGuid", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}");
         tag("SccProjectName");
         tag("SccLocalPath");
-        endTag("PropertyGroup");
+        endTag();
 
         tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.Default.props");
 
@@ -53,19 +57,19 @@
             startTag(cfg, "PropertyGroup", "Label", "Configuration");
             tagData("ConfigurationType", "DynamicLibrary");
             tagData("UseOfMfc", "false");
-            endTag("PropertyGroup");
+            endTag();
         }
 
         tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.props");
         startTag("ImportGroup", "Label", "ExtensionSettings");
-        endTag("ImportGroup");
+        endTag();
         for (BuildConfig cfg : allConfigs) {
             startTag(cfg, "ImportGroup", "Label", "PropertySheets");
             tag("Import",
                     "Project", "$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props",
                     "Condition", "exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')",
                     "Label", "LocalAppDataPlatform");
-            endTag("ImportGroup");
+            endTag();
         }
 
         tag("PropertyGroup", "Label", "UserMacros");
@@ -82,38 +86,38 @@
             tag(cfg, "CodeAnalysisRules");
             tag(cfg, "CodeAnalysisRuleAssemblies");
         }
-        endTag("PropertyGroup");
+        endTag();
 
         for (BuildConfig cfg : allConfigs) {
             startTag(cfg, "ItemDefinitionGroup");
             startTag("ClCompile");
             tagV(cfg.getV("CompilerFlags"));
-            endTag("ClCompile");
+            endTag();
 
             startTag("Link");
             tagV(cfg.getV("LinkerFlags"));
-            endTag("Link");
+            endTag();
 
             startTag("PostBuildEvent");
             tagData("Message", BuildConfig.getFieldString(null, "PostbuildDescription"));
             tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace("\t", "\r\n")));
-            endTag("PostBuildEvent");
+            endTag();
 
             startTag("PreLinkEvent");
             tagData("Message", BuildConfig.getFieldString(null, "PrelinkDescription"));
             tagData("Command", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace("\t", "\r\n")));
-            endTag("PreLinkEvent");
+            endTag();
 
-            endTag("ItemDefinitionGroup");
+            endTag();
         }
 
         writeFiles(allConfigs, projDir);
 
         tag("Import", "Project", "$(VCTargetsPath)\\Microsoft.Cpp.targets");
         startTag("ImportGroup", "Label", "ExtensionTargets");
-        endTag("ImportGroup");
+        endTag();
 
-        endTag("Project");
+        endTag();
         printWriter.close();
         System.out.println("    Done.");
 
@@ -138,14 +142,22 @@
         for (BuildConfig cfg : allConfigs) {
             startTag(cfg, "PropertyGroup");
             tagData("LocalDebuggerCommand", "$(TargetDir)/hotspot.exe");
-            endTag("PropertyGroup");
+            endTag();
         }
 
-        endTag("Project");
+        endTag();
         printWriter.close();
         System.out.println("    Done.");
     }
 
+    public void addFilter(String rPath) {
+       filters.add(rPath);
+    }
+
+    public void addFilterDependency(String fileLoc, String filter) {
+      filterDeps.add(new String[] {fileLoc, filter});
+    }
+
     private void writeFilterFile(String projectFileName, String projectName,
             Vector<BuildConfig> allConfigs, String base) throws FileNotFoundException, UnsupportedEncodingException {
         String filterFileName = projectFileName + ".filters";
@@ -157,210 +169,92 @@
                 "ToolsVersion", "4.0",
                 "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
 
-        Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs);
-        TreeSet<FileInfo> sortedFiles = sortFiles(allFiles);
-        Vector<NameFilter> filters = makeFilters(sortedFiles);
-
-        // first all filters
         startTag("ItemGroup");
-        for (NameFilter filter : filters) {
-            doWriteFilter(filter, "");
+        for (String filter : filters) {
+           startTag("Filter", "Include",filter);
+           UUID uuid = UUID.randomUUID();
+           tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
+           endTag();
         }
         startTag("Filter", "Include", "Resource Files");
         UUID uuid = UUID.randomUUID();
         tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
         tagData("Extensions", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe");
-        endTag("Filter");
-        endTag("ItemGroup");
+        endTag();
+        endTag();
 
-        // then all cpp files
+        //TODO - do I need to split cpp and hpp files?
+
+        // then all files
         startTag("ItemGroup");
-        for (NameFilter filter : filters) {
-            doWriteFiles(sortedFiles, filter, "", "ClCompile", new Evaluator() {
-                public boolean pick(FileInfo fi) {
-                    return fi.isCpp();
-                }
-            }, base);
-        }
-        endTag("ItemGroup");
+        for (String[] dep : filterDeps) {
+           String tagName = getFileTagFromSuffix(dep[0]);
 
-        // then all header files
-        startTag("ItemGroup");
-        for (NameFilter filter : filters) {
-            doWriteFiles(sortedFiles, filter, "", "ClInclude", new Evaluator() {
-                public boolean pick(FileInfo fi) {
-                    return fi.isHeader();
-                }
-            }, base);
+           startTag(tagName, "Include", dep[0]);
+           tagData("Filter", dep[1]);
+           endTag();
         }
-        endTag("ItemGroup");
+        endTag();
 
-        // then all other files
-        startTag("ItemGroup");
-        for (NameFilter filter : filters) {
-            doWriteFiles(sortedFiles, filter, "", "None", new Evaluator() {
-                public boolean pick(FileInfo fi) {
-                    return true;
-                }
-            }, base);
-        }
-        endTag("ItemGroup");
-
-        endTag("Project");
+        endTag();
         printWriter.close();
         System.out.println("    Done.");
     }
 
-
-    private void doWriteFilter(NameFilter filter, String start) {
-        startTag("Filter", "Include", start + filter.fname);
-        UUID uuid = UUID.randomUUID();
-        tagData("UniqueIdentifier", "{" + uuid.toString() + "}");
-        endTag("Filter");
-        if (filter instanceof ContainerFilter) {
-            Iterator i = ((ContainerFilter)filter).babies();
-            while (i.hasNext()) {
-                doWriteFilter((NameFilter)i.next(), start + filter.fname + "\\");
-            }
-        }
+    public String getFileTagFromSuffix(String fileName) {
+       if (fileName.endsWith(".cpp")) {
+          return"ClCompile";
+       } else if (fileName.endsWith(".c")) {
+          return "ClCompile";
+       } else if (fileName.endsWith(".hpp")) {
+          return"ClInclude";
+       } else if (fileName.endsWith(".h")) {
+          return "ClInclude";
+       } else {
+          return"None";
+       }
     }
 
-    interface Evaluator {
-        boolean pick(FileInfo fi);
-    }
-
-    private void doWriteFiles(TreeSet<FileInfo> allFiles, NameFilter filter, String start, String tool, Evaluator eval, String base) {
-        if (filter instanceof ContainerFilter) {
-            Iterator i = ((ContainerFilter)filter).babies();
-            while (i.hasNext()) {
-                doWriteFiles(allFiles, (NameFilter)i.next(), start + filter.fname + "\\", tool, eval, base);
-            }
-        }
-        else {
-            Iterator i = allFiles.iterator();
-            while (i.hasNext()) {
-                FileInfo fi = (FileInfo)i.next();
-
-                if (!filter.match(fi)) {
-                    continue;
-                }
-                if (eval.pick(fi)) {
-                    startTag(tool, "Include", rel(fi.full, base));
-                    tagData("Filter", start + filter.fname);
-                    endTag(tool);
-
-                    // we not gonna look at this file anymore (sic!)
-                    i.remove();
-                }
-            }
-        }
-    }
-
-
     void writeFiles(Vector<BuildConfig> allConfigs, String projDir) {
-        Hashtable<String, FileAttribute> allFiles = computeAttributedFiles(allConfigs);
-        TreeSet<FileInfo> sortedFiles = sortFiles(allFiles);
+       // This code assummes there are no config specific includes.
+       startTag("ItemGroup");
 
-        // first cpp-files
-        startTag("ItemGroup");
-        for (FileInfo fi : sortedFiles) {
-            if (!fi.isCpp()) {
-                continue;
-            }
-            writeFile("ClCompile", allConfigs, fi, projDir);
-        }
-        endTag("ItemGroup");
+       String sourceBase = BuildConfig.getFieldString(null, "SourceBase");
 
-        // then header-files
-        startTag("ItemGroup");
-        for (FileInfo fi : sortedFiles) {
-            if (!fi.isHeader()) {
-                continue;
-            }
-            writeFile("ClInclude", allConfigs, fi, projDir);
-        }
-        endTag("ItemGroup");
+       // Use first config for all global absolute includes.
+       BuildConfig baseConfig = allConfigs.firstElement();
+       Vector<String> rv = new Vector<String>();
 
-        // then others
-        startTag("ItemGroup");
-        for (FileInfo fi : sortedFiles) {
-            if (fi.isHeader() || fi.isCpp()) {
-                continue;
-            }
-            writeFile("None", allConfigs, fi, projDir);
-        }
-        endTag("ItemGroup");
+       // Then use first config for all relative includes
+       Vector<String> ri = new Vector<String>();
+       baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude");
+       for (String f : ri) {
+          rv.add(sourceBase + Util.sep + f);
+       }
+
+       baseConfig.collectRelevantVectors(rv, "AbsoluteSrcInclude");
+
+       handleIncludes(rv, allConfigs);
+
+       endTag();
     }
 
-    /**
-     * Make "path" into a relative path using "base" as the base.
-     *
-     * path and base are assumed to be normalized with / as the file separator.
-     * returned path uses "\\" as file separator
-     */
-    private String rel(String path, String base)
-    {
-        if(!base.endsWith("/")) {
-                base += "/";
-        }
-        String[] pathTok = path.split("/");
-        String[] baseTok = base.split("/");
-        int pi = 0;
-        int bi = 0;
-        StringBuilder newPath = new StringBuilder();
-
-        // first step past all path components that are the same
-        while (pi < pathTok.length &&
-                bi < baseTok.length &&
-                pathTok[pi].equals(baseTok[bi])) {
-            pi++;
-            bi++;
-        }
-
-        // for each path component left in base, add "../"
-        while (bi < baseTok.length) {
-            bi++;
-                newPath.append("..\\");
-        }
-
-        // now add everything left in path
-        while (pi < pathTok.length) {
-                newPath.append(pathTok[pi]);
-                pi++;
-            if (pi != pathTok.length) {
-                newPath.append("\\");
-            }
-        }
-        return newPath.toString();
-    }
-
-    private void writeFile(String tool, Vector<BuildConfig> allConfigs, FileInfo fi, String base) {
-        if (fi.attr.configs == null && fi.attr.pchRoot == false && fi.attr.noPch == false) {
-            tag(tool, "Include", rel(fi.full, base));
-        }
-        else {
-            startTag(tool, "Include", rel(fi.full, base));
-            for (BuildConfig cfg : allConfigs) {
-                if (fi.attr.configs != null && !fi.attr.configs.contains(cfg.get("Name"))) {
-                    tagData(cfg, "ExcludedFromBuild", "true");
-                }
-                if (fi.attr.pchRoot) {
-                        tagData(cfg, "PrecompiledHeader", "Create");
-                }
-                if (fi.attr.noPch) {
-                        startTag(cfg, "PrecompiledHeader");
-                        endTag("PrecompiledHeader");
-                }
-            }
-            endTag(tool);
-        }
+    // Will visit file tree for each include
+    private void handleIncludes(Vector<String> includes, Vector<BuildConfig> allConfigs) {
+       for (String path : includes)  {
+          FileTreeCreatorVC10 ftc = new FileTreeCreatorVC10(FileSystems.getDefault().getPath(path) , allConfigs, this);
+          try {
+             ftc.writeFileTree();
+          } catch (IOException e) {
+             e.printStackTrace();
+          }
+       }
     }
 
     String buildCond(BuildConfig cfg) {
         return "'$(Configuration)|$(Platform)'=='"+cfg.get("Name")+"'";
     }
 
-
     void tagV(Vector<String> v) {
         Iterator<String> i = v.iterator();
         while(i.hasNext()) {
@@ -391,6 +285,7 @@
 
         startTag(name, ss);
     }
+
 }
 
 class CompilerInterfaceVC10 extends CompilerInterface {
diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java
deleted file mode 100644
index f29abc0..0000000
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC6.java
+++ /dev/null
@@ -1,297 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-import java.io.*;
-import java.util.*;
-
-public class WinGammaPlatformVC6 extends WinGammaPlatform {
-    public void writeProjectFile(String projectFileName, String projectName,
-                                 Vector allConfigs) throws IOException {
-        Vector allConfigNames = new Vector();
-
-        printWriter = new PrintWriter(new FileWriter(projectFileName));
-        String cfg = ((BuildConfig)allConfigs.get(0)).get("Name");
-
-        printWriter.println("# Microsoft Developer Studio Project File - Name=\"" + projectName + "\" - Package Owner=<4>");
-        printWriter.println("# Microsoft Developer Studio Generated Build File, Format Version 6.00");
-        printWriter.println("# ** DO NOT EDIT **");
-        printWriter.println("");
-        printWriter.println("# TARGTYPE \"Win32 (x86) Dynamic-Link Library\" 0x0102");
-        printWriter.println("CFG=" + cfg);
-        printWriter.println("");
-
-        printWriter.println("!MESSAGE This is not a valid makefile. To build this project using NMAKE,");
-        printWriter.println("!MESSAGE use the Export Makefile command and run");
-        printWriter.println("!MESSAGE ");
-        printWriter.println("!MESSAGE NMAKE /f \"" + projectName + ".mak\".");
-        printWriter.println("!MESSAGE ");
-        printWriter.println("!MESSAGE You can specify a configuration when running NMAKE");
-        printWriter.println("!MESSAGE by defining the macro CFG on the command line. For example:");
-        printWriter.println("!MESSAGE ");
-        printWriter.println("!MESSAGE NMAKE /f \"" + projectName + ".mak\" CFG=\"" + cfg + "\"");
-        printWriter.println("!MESSAGE ");
-        printWriter.println("!MESSAGE Possible choices for configuration are:");
-        printWriter.println("!MESSAGE ");
-        for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
-            String name = ((BuildConfig)i.next()).get("Name");
-            printWriter.println("!MESSAGE \""+ name + "\" (based on \"Win32 (x86) Dynamic-Link Library\")");
-            allConfigNames.add(name);
-        }
-        printWriter.println("!MESSAGE ");
-        printWriter.println("");
-
-        printWriter.println("# Begin Project");
-        printWriter.println("# PROP AllowPerConfigDependencies 0");
-        printWriter.println("# PROP Scc_ProjName \"\"");
-        printWriter.println("# PROP Scc_LocalPath \"\"");
-        printWriter.println("CPP=cl.exe");
-        printWriter.println("MTL=midl.exe");
-        printWriter.println("RSC=rc.exe");
-
-
-        String keyword = "!IF";
-        for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
-            BuildConfig bcfg = (BuildConfig)i.next();
-            printWriter.println(keyword + "  \"$(CFG)\" == \"" + bcfg.get("Name") + "\"");
-            writeConfigHeader(bcfg);
-            keyword = "!ELSEIF";
-            if (!i.hasNext()) printWriter.println("!ENDIF");
-        }
-
-
-        TreeSet sortedFiles = sortFiles(computeAttributedFiles(allConfigs));
-
-        printWriter.println("# Begin Target");
-
-        for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
-            printWriter.println("# Name \"" + ((BuildConfig)i.next()).get("Name") + "\"");
-        }
-        printWriter.println("# Begin Group \"Header Files\"");
-        printWriter.println("# PROP Default_Filter \"h;hpp;hxx;hm;inl;fi;fd\"");
-
-        Iterator i = sortedFiles.iterator();
-
-        while (i.hasNext()) {
-            FileInfo fi = (FileInfo)i.next();
-
-            // skip sources
-            if (!fi.isHeader()) {
-                continue;
-            }
-
-            printFile(fi, allConfigNames);
-        }
-        printWriter.println("# End Group");
-        printWriter.println("");
-
-        printWriter.println("# Begin Group \"Source Files\"");
-        printWriter.println("# PROP Default_Filter \"cpp;c;cxx;rc;def;r;odl;hpj;bat;for;f90\"");
-
-        i = sortedFiles.iterator();
-        while (i.hasNext()) {
-            FileInfo fi = (FileInfo)i.next();
-
-            // skip headers
-            if (fi.isHeader()) {
-                continue;
-            }
-
-            printFile(fi, allConfigNames);
-        }
-        printWriter.println("# End Group");
-        printWriter.println("");
-
-
-        printWriter.println("# Begin Group \"Resource Files\"");
-        printWriter.println("# PROP Default_Filter \"ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe\"");
-        printWriter.println("# End Group");
-        printWriter.println("");
-        printWriter.println("# End Target");
-
-        printWriter.println("# End Project");
-
-        printWriter.close();
-    }
-
-
-    void printFile(FileInfo fi, Vector allConfigNames) {
-        printWriter.println("# Begin Source File");
-        printWriter.println("");
-        printWriter.println("SOURCE=\"" + fi.full + "\"");
-        FileAttribute attr = fi.attr;
-
-        if (attr.noPch) {
-            printWriter.println("# SUBTRACT CPP /YX /Yc /Yu");
-        }
-
-        if (attr.pchRoot) {
-            printWriter.println("# ADD CPP /Yc\"incls/_precompiled.incl\"");
-        }
-        if (attr.configs != null) {
-            String keyword = "!IF";
-            for (Iterator j=allConfigNames.iterator(); j.hasNext();) {
-                String cfg = (String)j.next();
-                if (!attr.configs.contains(cfg)) {
-                    printWriter.println(keyword+" \"$(CFG)\" == \"" + cfg +"\"");
-                    printWriter.println("# PROP BASE Exclude_From_Build 1");
-                    printWriter.println("# PROP Exclude_From_Build 1");
-                    keyword = "!ELSEIF";
-                }
-            }
-            printWriter.println("!ENDIF");
-        }
-
-        printWriter.println("# End Source File");
-    }
-
-    void writeConfigHeader(BuildConfig cfg) {
-        printWriter.println("# Begin Special Build Tool");
-        printWriter.println("SOURCE=\"$(InputPath)\"");
-        printWriter.println("PreLink_Desc=" +  BuildConfig.getFieldString(null, "PrelinkDescription"));
-        printWriter.println("PreLink_Cmds=" +
-                            cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand")));
-        printWriter.println("# End Special Build Tool");
-        printWriter.println("");
-
-        for (Iterator i = cfg.getV("CompilerFlags").iterator(); i.hasNext(); ) {
-            printWriter.println("# "+(String)i.next());
-        }
-
-
-        printWriter.println("LINK32=link.exe");
-
-        for (Iterator i = cfg.getV("LinkerFlags").iterator(); i.hasNext(); ) {
-            printWriter.println("# "+(String)i.next());
-        }
-
-        printWriter.println("ADD BASE MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32");
-        printWriter.println("ADD MTL /nologo /D \"_DEBUG\" /mktyplib203 /win32");
-        printWriter.println("ADD BASE RSC /l 0x409 /d \"_DEBUG\"");
-        printWriter.println("ADD RSC /l 0x409 /d \"_DEBUG\"");
-        printWriter.println("BSC32=bscmake.exe");
-        printWriter.println("ADD BASE BSC32 /nologo");
-        printWriter.println("ADD BSC32 /nologo");
-        printWriter.println("");
-    }
-
-    protected String getProjectExt() {
-        return ".dsp";
-    }
-}
-
-
-class CompilerInterfaceVC6  extends CompilerInterface {
-    Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
-        Vector rv = new Vector();
-
-        rv.add("PROP BASE Use_MFC 0");
-        rv.add("PROP Use_MFC 0");
-        rv.add("ADD CPP /nologo /MT /W3 /WX /GX /YX /Fr /FD /c");
-        rv.add("PROP BASE Output_Dir \""+outDir+"\"");
-        rv.add("PROP Output_Dir \""+outDir+"\"");
-        rv.add("PROP BASE Intermediate_Dir \""+outDir+"\"");
-        rv.add("PROP Intermediate_Dir \""+outDir+"\"");
-        rv.add("PROP BASE Target_Dir \"\"");
-        rv.add("PROP Target_Dir \"\"");
-        rv.add("ADD BASE CPP "+Util.prefixed_join(" /I ", includes, true));
-        rv.add("ADD CPP "+Util.prefixed_join(" /I ", includes, true));
-        rv.add("ADD BASE CPP "+Util.prefixed_join(" /D ", defines, true));
-        rv.add("ADD CPP "+Util.prefixed_join(" /D ", defines, true));
-        rv.add("ADD CPP /Yu\"incls/_precompiled.incl\"");
-
-        return rv;
-    }
-
-    Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
-        Vector rv = new Vector();
-
-        rv.add("PROP Ignore_Export_Lib 0");
-        rv.add("ADD BASE CPP /MD");
-        rv.add("ADD CPP /MD");
-        rv.add("ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib " +
-               "           advapi32.lib shell32.lib ole32.lib oleaut32.lib winmm.lib");
-        String machine = "/machine:I386";
-        if (platformName.equals("x64")) {
-                machine = "/machine:X64";
-        }
-        rv.add("ADD LINK32      /out:\""+outDll+"\" "+
-               "                /nologo /subsystem:windows /machine:" + machine +
-               "                /nologo /base:\"0x8000000\" /subsystem:windows /dll" +
-               "                /export:JNI_GetDefaultJavaVMInitArgs /export:JNI_CreateJavaVM /export:JNI_GetCreatedJavaVMs "+
-               "                /export:jio_snprintf /export:jio_printf /export:jio_fprintf /export:jio_vfprintf "+
-               "                /export:jio_vsnprintf ");
-        rv.add("SUBTRACT LINK32 /pdb:none /map");
-
-        return rv;
-    }
-
-    Vector getDebugCompilerFlags(String opt) {
-        Vector rv = new Vector();
-
-        rv.add("ADD BASE CPP /Gm /Zi /O"+opt);
-
-        return rv;
-    }
-
-    Vector getDebugLinkerFlags() {
-        Vector rv = new Vector();
-
-        rv.add("PROP BASE Use_Debug_Libraries 1");
-        rv.add("PROP Use_Debug_Libraries 1");
-        rv.add("ADD LINK32 /debug");
-
-        return rv;
-    }
-
-    void getAdditionalNonKernelLinkerFlags(Vector rv) {}
-
-    Vector getProductCompilerFlags() {
-        Vector rv = new Vector();
-
-        rv.add("ADD CPP /O"+getOptFlag());
-
-        return rv;
-    }
-
-    Vector getProductLinkerFlags() {
-        Vector rv = new Vector();
-
-        rv.add("PROP BASE Use_Debug_Libraries 0");
-        rv.add("PROP Use_Debug_Libraries 0");
-
-        return rv;
-    }
-
-    String getOptFlag() {
-        return "2";
-    }
-
-    String getNoOptFlag() {
-        return "d";
-    }
-
-    String makeCfgName(String flavourBuild, String platform) {
-        return "vm - "+ platform + " " + flavourBuild;
-    }
-}
diff --git a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
index d1d63c8..735b1a8 100644
--- a/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
+++ b/hotspot/src/share/tools/ProjectCreator/WinGammaPlatformVC7.java
@@ -25,758 +25,326 @@
 import java.io.FileWriter;
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.util.Hashtable;
-import java.util.Iterator;
-import java.util.TreeSet;
+import java.nio.file.FileSystems;
 import java.util.Vector;
 
 public class WinGammaPlatformVC7 extends WinGammaPlatform {
 
-    String projectVersion() {return "7.10";};
+   // TODO How about moving all globals configs to its own BuildConfig?
 
-    public void writeProjectFile(String projectFileName, String projectName,
-                                 Vector<BuildConfig> allConfigs) throws IOException {
-        System.out.println();
-        System.out.println("    Writing .vcproj file: "+projectFileName);
-        // If we got this far without an error, we're safe to actually
-        // write the .vcproj file
-        printWriter = new PrintWriter(new FileWriter(projectFileName));
+   String projectVersion() {
+      return "7.10";
+   };
 
-        printWriter.println("<?xml version=\"1.0\" encoding=\"windows-1251\"?>");
-        startTag(
-            "VisualStudioProject",
-            new String[] {
-                "ProjectType", "Visual C++",
-                "Version", projectVersion(),
-                "Name", projectName,
-                "ProjectGUID", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}",
-                "SccProjectName", "",
-                "SccLocalPath", ""
-            }
-            );
-        startTag("Platforms");
-        tag("Platform", new String[] {"Name", (String) BuildConfig.getField(null, "PlatformName")});
-        endTag("Platforms");
+   public void writeProjectFile(String projectFileName, String projectName,
+         Vector<BuildConfig> allConfigs) throws IOException {
+      System.out.println();
+      System.out.println("    Writing .vcproj file: " + projectFileName);
+      // If we got this far without an error, we're safe to actually
+      // write the .vcproj file
+      printWriter = new PrintWriter(new FileWriter(projectFileName));
 
-        startTag("Configurations");
+      printWriter
+      .println("<?xml version=\"1.0\" encoding=\"windows-1251\"?>");
+      startTag("VisualStudioProject", new String[] { "ProjectType",
+            "Visual C++", "Version", projectVersion(), "Name", projectName,
+            "ProjectGUID", "{8822CB5C-1C41-41C2-8493-9F6E1994338B}",
+            "SccProjectName", "", "SccLocalPath", "" });
+      startTag("Platforms");
+      tag("Platform",
+            new String[] { "Name",
+            (String) BuildConfig.getField(null, "PlatformName") });
+      endTag();
 
-        for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
-            writeConfiguration((BuildConfig)i.next());
-        }
+      startTag("Configurations");
 
-        endTag("Configurations");
+      for (BuildConfig cfg : allConfigs) {
+         writeConfiguration(cfg);
+      }
 
-        tag("References");
+      endTag();
 
-        writeFiles(allConfigs);
+      tag("References");
 
-        tag("Globals");
+      writeFiles(allConfigs);
 
-        endTag("VisualStudioProject");
-        printWriter.close();
+      tag("Globals");
 
-        System.out.println("    Done.");
-    }
+      endTag();
+      printWriter.close();
 
+      System.out.println("    Done.");
+   }
 
-    abstract class NameFilter {
-                protected String fname;
+   void writeCustomToolConfig(Vector<BuildConfig> configs, String[] customToolAttrs) {
+      for (BuildConfig cfg : configs) {
+         startTag("FileConfiguration",
+               new String[] { "Name", (String) cfg.get("Name") });
+         tag("Tool", customToolAttrs);
 
-        abstract boolean match(FileInfo fi);
+         endTag();
+      }
+   }
 
-        String  filterString() { return ""; }
-        String name() { return this.fname;}
+   void writeFiles(Vector<BuildConfig> allConfigs) {
 
-        @Override
-        // eclipse auto-generated
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            result = prime * result + getOuterType().hashCode();
-            result = prime * result + ((fname == null) ? 0 : fname.hashCode());
-            return result;
-        }
+      // This code assummes there are no config specific includes.
+      startTag("Files");
+      String sourceBase = BuildConfig.getFieldString(null, "SourceBase");
 
-        @Override
-        // eclipse auto-generated
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-            if (obj == null)
-                return false;
-            if (getClass() != obj.getClass())
-                return false;
-            NameFilter other = (NameFilter) obj;
-            if (!getOuterType().equals(other.getOuterType()))
-                return false;
-            if (fname == null) {
-                if (other.fname != null)
-                    return false;
-            } else if (!fname.equals(other.fname))
-                return false;
-            return true;
-        }
+      // Use first config for all global absolute includes.
+      BuildConfig baseConfig = allConfigs.firstElement();
+      Vector<String> rv = new Vector<String>();
 
-        // eclipse auto-generated
-        private WinGammaPlatformVC7 getOuterType() {
-            return WinGammaPlatformVC7.this;
-        }
-    }
+      // Then use first config for all relative includes
+      Vector<String> ri = new Vector<String>();
+      baseConfig.collectRelevantVectors(ri, "RelativeSrcInclude");
+      for (String f : ri) {
+         rv.add(sourceBase + Util.sep + f);
+      }
 
-    class DirectoryFilter extends NameFilter {
-        String dir;
-        int baseLen, dirLen;
+      baseConfig.collectRelevantVectors(rv, "AbsoluteSrcInclude");
 
-        DirectoryFilter(String dir, String sbase) {
-            this.dir = dir;
-            this.baseLen = sbase.length();
-            this.dirLen = dir.length();
-            this.fname = dir;
-        }
+      handleIncludes(rv, allConfigs);
 
-        DirectoryFilter(String fname, String dir, String sbase) {
-            this.dir = dir;
-            this.baseLen = sbase.length();
-            this.dirLen = dir.length();
-            this.fname = fname;
-        }
+      startTag("Filter", new String[] { "Name", "Resource Files", "Filter",
+      "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe" });
+      endTag();
 
+      endTag();
+   }
 
-        boolean match(FileInfo fi) {
-            int lastSlashIndex = fi.full.lastIndexOf('/');
-            String fullDir = fi.full.substring(0, lastSlashIndex);
-            return fullDir.endsWith(dir);
-        }
-
-        @Override
-        // eclipse auto-generated
-        public int hashCode() {
-            final int prime = 31;
-            int result = super.hashCode();
-            result = prime * result + getOuterType().hashCode();
-            result = prime * result + baseLen;
-            result = prime * result + ((dir == null) ? 0 : dir.hashCode());
-            result = prime * result + dirLen;
-            return result;
-        }
-
-        @Override
-        // eclipse auto-generated
-        public boolean equals(Object obj) {
-            if (this == obj)
-                return true;
-            if (!super.equals(obj))
-                return false;
-            if (getClass() != obj.getClass())
-                return false;
-            DirectoryFilter other = (DirectoryFilter) obj;
-            if (!getOuterType().equals(other.getOuterType()))
-                return false;
-            if (baseLen != other.baseLen)
-                return false;
-            if (dir == null) {
-                if (other.dir != null)
-                    return false;
-            } else if (!dir.equals(other.dir))
-                return false;
-            if (dirLen != other.dirLen)
-                return false;
-            return true;
-        }
-
-        // eclipse auto-generated
-        private WinGammaPlatformVC7 getOuterType() {
-            return WinGammaPlatformVC7.this;
-        }
-    }
-
-    class TerminatorFilter extends NameFilter {
-        TerminatorFilter(String fname) {
-            this.fname = fname;
-
-        }
-        boolean match(FileInfo fi) {
-            return true;
-        }
-
-    }
-
-    class SpecificNameFilter extends NameFilter {
-        String pats[];
-
-        SpecificNameFilter(String fname, String[] pats) {
-            this.fname = fname;
-            this.pats = pats;
-        }
-
-        boolean match(FileInfo fi) {
-            for (int i=0; i<pats.length; i++) {
-                if (fi.attr.shortName.matches(pats[i])) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-    }
-
-    class SpecificPathFilter extends NameFilter {
-        String pats[];
-
-        SpecificPathFilter(String fname, String[] pats) {
-            this.fname = fname;
-            this.pats = pats;
-        }
-
-        boolean match(FileInfo fi) {
-            for (int i=0; i<pats.length; i++) {
-                if (fi.full.matches(pats[i])) {
-                    return true;
-                }
-            }
-            return false;
-        }
-
-    }
-
-    class ContainerFilter extends NameFilter {
-        Vector children;
-
-        ContainerFilter(String fname) {
-            this.fname = fname;
-            children = new Vector();
-
-        }
-        boolean match(FileInfo fi) {
-            return false;
-        }
-
-        Iterator babies() { return children.iterator(); }
-
-        void add(NameFilter f) {
-            children.add(f);
-        }
-    }
-
-
-    void writeCustomToolConfig(Vector configs, String[] customToolAttrs) {
-        for (Iterator i = configs.iterator(); i.hasNext(); ) {
-            startTag("FileConfiguration",
-                     new String[] {
-                         "Name",  (String)i.next()
-                     }
-                     );
-            tag("Tool", customToolAttrs);
-
-            endTag("FileConfiguration");
-        }
-    }
-
-    // here we define filters, which define layout of what can be seen in 'Solution View' of MSVC
-    // Basically there are two types of entities - container filters and real filters
-    //   - container filter just provides a container to group together real filters
-    //   - real filter can select elements from the set according to some rule, put it into XML
-    //     and remove from the list
-    Vector<NameFilter> makeFilters(TreeSet<FileInfo> files) {
-        Vector<NameFilter> rv = new Vector<NameFilter>();
-        String sbase = Util.normalize(BuildConfig.getFieldString(null, "SourceBase")+"/src/");
-
-        String currentDir = "";
-        DirectoryFilter container = null;
-        for(FileInfo fileInfo : files) {
-
-            if (!fileInfo.full.startsWith(sbase)) {
-                continue;
-            }
-
-            int lastSlash = fileInfo.full.lastIndexOf('/');
-            String dir = fileInfo.full.substring(sbase.length(), lastSlash);
-            if(dir.equals("share/vm")) {
-                // skip files directly in share/vm - should only be precompiled.hpp which is handled below
-                continue;
-            }
-            if (!dir.equals(currentDir)) {
-                currentDir = dir;
-                if (container != null && !rv.contains(container)) {
-                    rv.add(container);
-                }
-
-                // remove "share/vm/" from names
-                String name = dir;
-                if (dir.startsWith("share/vm/")) {
-                    name = dir.substring("share/vm/".length(), dir.length());
-                }
-                DirectoryFilter newfilter = new DirectoryFilter(name, dir, sbase);
-                int i = rv.indexOf(newfilter);
-                if(i == -1) {
-                    container = newfilter;
-                } else {
-                    // if the filter already exists, reuse it
-                    container = (DirectoryFilter) rv.get(i);
-                }
-            }
-        }
-        if (container != null && !rv.contains(container)) {
-            rv.add(container);
-        }
-
-        ContainerFilter generated = new ContainerFilter("Generated");
-        ContainerFilter c1Generated = new ContainerFilter("C1");
-        c1Generated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*compiler1/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"}));
-        c1Generated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*compiler1/generated/jvmtifiles/.*"}));
-        generated.add(c1Generated);
-        ContainerFilter c2Generated = new ContainerFilter("C2");
-        c2Generated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*compiler2/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"}));
-        c2Generated.add(new SpecificPathFilter("adfiles", new String[] {".*compiler2/generated/adfiles/.*"}));
-        c2Generated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*compiler2/generated/jvmtifiles/.*"}));
-        generated.add(c2Generated);
-        ContainerFilter coreGenerated = new ContainerFilter("Core");
-        coreGenerated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*core/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"}));
-        coreGenerated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*core/generated/jvmtifiles/.*"}));
-        generated.add(coreGenerated);
-        ContainerFilter tieredGenerated = new ContainerFilter("Tiered");
-        tieredGenerated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*tiered/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"}));
-        tieredGenerated.add(new SpecificPathFilter("adfiles", new String[] {".*tiered/generated/adfiles/.*"}));
-        tieredGenerated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*tiered/generated/jvmtifiles/.*"}));
-        generated.add(tieredGenerated);
-        ContainerFilter kernelGenerated = new ContainerFilter("Kernel");
-        kernelGenerated.add(new SpecificPathFilter("C++ Interpreter Generated", new String[] {".*kernel/generated/jvmtifiles/bytecodeInterpreterWithChecks.+"}));
-        kernelGenerated.add(new SpecificPathFilter("jvmtifiles", new String[] {".*kernel/generated/jvmtifiles/.*"}));
-        generated.add(kernelGenerated);
-        rv.add(generated);
-
-        rv.add(new SpecificNameFilter("Precompiled Header", new String[] {"precompiled.hpp"}));
-
-        // this one is to catch files not caught by other filters
-        rv.add(new TerminatorFilter("Source Files"));
-
-        return rv;
-    }
-
-    void writeFiles(Vector<BuildConfig> allConfigs) {
-
-        Hashtable allFiles = computeAttributedFiles(allConfigs);
-
-        Vector allConfigNames = new Vector();
-        for (Iterator i = allConfigs.iterator(); i.hasNext(); ) {
-            allConfigNames.add(((BuildConfig)i.next()).get("Name"));
-        }
-
-        TreeSet sortedFiles = sortFiles(allFiles);
-
-        startTag("Files");
-
-        for (Iterator i = makeFilters(sortedFiles).iterator(); i.hasNext(); ) {
-            doWriteFiles(sortedFiles, allConfigNames, (NameFilter)i.next());
-        }
-
-
-        startTag("Filter",
-                 new String[] {
-                     "Name", "Resource Files",
-                     "Filter", "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
-                 }
-                 );
-        endTag("Filter");
-
-        endTag("Files");
-    }
-
-    void doWriteFiles(TreeSet allFiles, Vector allConfigNames, NameFilter filter) {
-        startTag("Filter",
-                 new String[] {
-                     "Name",   filter.name(),
-                     "Filter", filter.filterString()
-                 }
-                 );
-
-        if (filter instanceof ContainerFilter) {
-
-            Iterator i = ((ContainerFilter)filter).babies();
-            while (i.hasNext()) {
-                doWriteFiles(allFiles, allConfigNames, (NameFilter)i.next());
-            }
-
-        } else {
-
-            Iterator i = allFiles.iterator();
-            while (i.hasNext()) {
-                FileInfo fi = (FileInfo)i.next();
-
-                if (!filter.match(fi)) {
-                    continue;
-                }
-
-                startTag("File",
-                         new String[] {
-                             "RelativePath", fi.full.replace('/', '\\')
-                         }
-                         );
-
-                FileAttribute a = fi.attr;
-                if (a.pchRoot) {
-                    writeCustomToolConfig(allConfigNames,
-                                          new String[] {
-                                              "Name", "VCCLCompilerTool",
-                                              "UsePrecompiledHeader", "1"
-                                          });
-                }
-
-                if (a.noPch) {
-                    writeCustomToolConfig(allConfigNames,
-                                          new String[] {
-                                              "Name", "VCCLCompilerTool",
-                                              "UsePrecompiledHeader", "0"
-                                          });
-                }
-
-                if (a.configs != null) {
-                    for (Iterator j=allConfigNames.iterator(); j.hasNext();) {
-                        String cfg = (String)j.next();
-                        if (!a.configs.contains(cfg)) {
-                            startTag("FileConfiguration",
-                                     new String[] {
-                                         "Name", cfg,
-                                         "ExcludedFromBuild", "TRUE"
-                                     });
-                            endTag("FileConfiguration");
-
-                        }
-                    }
-                }
-
-                endTag("File");
-
-                // we not gonna look at this file anymore
-                i.remove();
-            }
-        }
-
-        endTag("Filter");
-    }
-
-
-    void writeConfiguration(BuildConfig cfg) {
-        startTag("Configuration",
-                 new String[] {
-                     "Name", cfg.get("Name"),
-                     "OutputDirectory",  cfg.get("OutputDir"),
-                     "IntermediateDirectory",  cfg.get("OutputDir"),
-                     "ConfigurationType", "2",
-                     "UseOfMFC", "0",
-                     "ATLMinimizesCRunTimeLibraryUsage", "FALSE"
-                 }
-                 );
-
-
-
-        tagV("Tool", cfg.getV("CompilerFlags"));
-
-        tag("Tool",
-            new String[] {
-                "Name", "VCCustomBuildTool"
-            }
-            );
-
-        tagV("Tool", cfg.getV("LinkerFlags"));
-
-        tag("Tool",
-            new String[] {
-               "Name", "VCPostBuildEventTool",
-                "Description", BuildConfig.getFieldString(null, "PostbuildDescription"),
-                //Caution: String.replace(String,String) is available from JDK5 onwards only
-                "CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PostbuildCommand").replace
-                   ("\t", "&#x0D;&#x0A;"))
-            }
-            );
-
-        tag("Tool",
-            new String[] {
-                "Name", "VCPreBuildEventTool"
-            }
-            );
-
-        tag("Tool",
-            new String[] {
-                "Name", "VCPreLinkEventTool",
-                "Description", BuildConfig.getFieldString(null, "PrelinkDescription"),
-                //Caution: String.replace(String,String) is available from JDK5 onwards only
-                "CommandLine", cfg.expandFormat(BuildConfig.getFieldString(null, "PrelinkCommand").replace
-                   ("\t", "&#x0D;&#x0A;"))
-            }
-            );
-
-        tag("Tool",
-            new String[] {
-                "Name", "VCResourceCompilerTool",
-                // XXX???
-                "PreprocessorDefinitions", "NDEBUG",
-                "Culture", "1033"
-            }
-            );
-
-        tag("Tool",
-            new String[] {
-                "Name", "VCMIDLTool",
-                "PreprocessorDefinitions", "NDEBUG",
-                "MkTypLibCompatible", "TRUE",
-                "SuppressStartupBanner", "TRUE",
-                "TargetEnvironment", "1",
-                "TypeLibraryName", cfg.get("OutputDir") + Util.sep + "vm.tlb",
-                "HeaderFileName", ""
-            }
-            );
-
-        endTag("Configuration");
-    }
-
-    int indent;
-
-    private void startTagPrim(String name,
-            String[] attrs,
-            boolean close) {
-        startTagPrim(name, attrs, close, true);
-    }
-
-    private void startTagPrim(String name,
-                              String[] attrs,
-                              boolean close,
-                              boolean newline) {
-        doIndent();
-        printWriter.print("<"+name);
-        indent++;
-
-        if (attrs != null && attrs.length > 0) {
-            for (int i=0; i<attrs.length; i+=2) {
-                printWriter.print(" " + attrs[i]+"=\""+attrs[i+1]+"\"");
-                if (i < attrs.length - 2) {
-                }
-            }
-        }
-
-        if (close) {
-            indent--;
-            printWriter.print(" />");
-        } else {
-                printWriter.print(">");
-        }
-        if(newline) {
-                printWriter.println();
-        }
-    }
-
-    void startTag(String name, String... attrs) {
-        startTagPrim(name, attrs, false);
-    }
-
-    void startTagV(String name, Vector attrs) {
-        String s[] = new String [attrs.size()];
-         for (int i=0; i<attrs.size(); i++) {
-             s[i] = (String)attrs.elementAt(i);
+   // Will visit file tree for each include
+   private void handleIncludes(Vector<String> includes, Vector<BuildConfig> allConfigs) {
+      for (String path : includes)  {
+         FileTreeCreatorVC7 ftc = new FileTreeCreatorVC7(FileSystems.getDefault().getPath(path) , allConfigs, this);
+         try {
+            ftc.writeFileTree();
+         } catch (IOException e) {
+            e.printStackTrace();
          }
-        startTagPrim(name, s, false);
-    }
+      }
+   }
 
-    void endTag(String name) {
-        indent--;
-        doIndent();
-        printWriter.println("</"+name+">");
-    }
+   void writeConfiguration(BuildConfig cfg) {
+      startTag("Configuration", new String[] { "Name", cfg.get("Name"),
+            "OutputDirectory", cfg.get("OutputDir"),
+            "IntermediateDirectory", cfg.get("OutputDir"),
+            "ConfigurationType", "2", "UseOfMFC", "0",
+            "ATLMinimizesCRunTimeLibraryUsage", "FALSE" });
 
-    void tag(String name, String... attrs) {
-        startTagPrim(name, attrs, true);
-    }
+      tagV("Tool", cfg.getV("CompilerFlags"));
 
-    void tagData(String name, String data) {
-        doIndent();
-        printWriter.print("<"+name+">");
-        printWriter.print(data);
-        printWriter.println("</"+name+">");
-    }
+      tag("Tool", new String[] { "Name", "VCCustomBuildTool" });
 
-    void tagData(String name, String data, String... attrs) {
-        startTagPrim(name, attrs, false, false);
-        printWriter.print(data);
-        printWriter.println("</"+name+">");
-        indent--;
-    }
+      tagV("Tool", cfg.getV("LinkerFlags"));
 
-    void tagV(String name, Vector attrs) {
-         String s[] = new String [attrs.size()];
-         for (int i=0; i<attrs.size(); i++) {
-             s[i] = (String)attrs.elementAt(i);
-         }
-         startTagPrim(name, s, true);
-    }
+      tag("Tool",
+            new String[] {
+            "Name",
+            "VCPostBuildEventTool",
+            "Description",
+            BuildConfig
+            .getFieldString(null, "PostbuildDescription"),
+            // Caution: String.replace(String,String) is available
+            // from JDK5 onwards only
+            "CommandLine",
+            cfg.expandFormat(BuildConfig.getFieldString(null,
+                  "PostbuildCommand").replace("\t",
+                        "&#x0D;&#x0A;")) });
+
+      tag("Tool", new String[] { "Name", "VCPreBuildEventTool" });
+
+      tag("Tool",
+            new String[] {
+            "Name",
+            "VCPreLinkEventTool",
+            "Description",
+            BuildConfig.getFieldString(null, "PrelinkDescription"),
+            // Caution: String.replace(String,String) is available
+            // from JDK5 onwards only
+            "CommandLine",
+            cfg.expandFormat(BuildConfig.getFieldString(null,
+                  "PrelinkCommand").replace("\t", "&#x0D;&#x0A;")) });
+
+      tag("Tool", new String[] { "Name", "VCResourceCompilerTool",
+            "PreprocessorDefinitions", "NDEBUG", "Culture", "1033" });
+
+      tag("Tool", new String[] { "Name", "VCMIDLTool",
+            "PreprocessorDefinitions", "NDEBUG", "MkTypLibCompatible",
+            "TRUE", "SuppressStartupBanner", "TRUE", "TargetEnvironment",
+            "1", "TypeLibraryName",
+            cfg.get("OutputDir") + Util.sep + "vm.tlb", "HeaderFileName",
+      "" });
+
+      endTag();
+   }
 
 
-    void doIndent() {
-        for (int i=0; i<indent; i++) {
-            printWriter.print("  ");
-        }
-    }
 
-    protected String getProjectExt() {
-        return ".vcproj";
-    }
+   protected String getProjectExt() {
+      return ".vcproj";
+   }
 }
 
 class CompilerInterfaceVC7 extends CompilerInterface {
-    void getBaseCompilerFlags_common(Vector defines, Vector includes, String outDir,Vector rv) {
+   void getBaseCompilerFlags_common(Vector defines, Vector includes,
+         String outDir, Vector rv) {
 
-        // advanced M$ IDE (2003) can only recognize name if it's first or
-        // second attribute in the tag - go guess
-        addAttr(rv, "Name", "VCCLCompilerTool");
-        addAttr(rv, "AdditionalIncludeDirectories", Util.join(",", includes));
-        addAttr(rv, "PreprocessorDefinitions",
-                                Util.join(";", defines).replace("\"","&quot;"));
-        addAttr(rv, "PrecompiledHeaderThrough", "precompiled.hpp");
-        addAttr(rv, "PrecompiledHeaderFile", outDir+Util.sep+"vm.pch");
-        addAttr(rv, "AssemblerListingLocation", outDir);
-        addAttr(rv, "ObjectFile", outDir+Util.sep);
-        addAttr(rv, "ProgramDataBaseFileName", outDir+Util.sep+"jvm.pdb");
-        // Set /nologo optin
-        addAttr(rv, "SuppressStartupBanner", "TRUE");
-        // Surpass the default /Tc or /Tp. 0 is compileAsDefault
-        addAttr(rv, "CompileAs", "0");
-        // Set /W3 option. 3 is warningLevel_3
-        addAttr(rv, "WarningLevel", "3");
-        // Set /WX option,
-        addAttr(rv, "WarnAsError", "TRUE");
-        // Set /GS option
-        addAttr(rv, "BufferSecurityCheck", "FALSE");
-        // Set /Zi option. 3 is debugEnabled
-        addAttr(rv, "DebugInformationFormat", "3");
-    }
-    Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
-        Vector rv = new Vector();
+      // advanced M$ IDE (2003) can only recognize name if it's first or
+      // second attribute in the tag - go guess
+      addAttr(rv, "Name", "VCCLCompilerTool");
+      addAttr(rv, "AdditionalIncludeDirectories", Util.join(",", includes));
+      addAttr(rv, "PreprocessorDefinitions",
+            Util.join(";", defines).replace("\"", "&quot;"));
+      addAttr(rv, "PrecompiledHeaderThrough", "precompiled.hpp");
+      addAttr(rv, "PrecompiledHeaderFile", outDir + Util.sep + "vm.pch");
+      addAttr(rv, "AssemblerListingLocation", outDir);
+      addAttr(rv, "ObjectFile", outDir + Util.sep);
+      addAttr(rv, "ProgramDataBaseFileName", outDir + Util.sep + "jvm.pdb");
+      // Set /nologo optin
+      addAttr(rv, "SuppressStartupBanner", "TRUE");
+      // Surpass the default /Tc or /Tp. 0 is compileAsDefault
+      addAttr(rv, "CompileAs", "0");
+      // Set /W3 option. 3 is warningLevel_3
+      addAttr(rv, "WarningLevel", "3");
+      // Set /WX option,
+      addAttr(rv, "WarnAsError", "TRUE");
+      // Set /GS option
+      addAttr(rv, "BufferSecurityCheck", "FALSE");
+      // Set /Zi option. 3 is debugEnabled
+      addAttr(rv, "DebugInformationFormat", "3");
+   }
 
-        getBaseCompilerFlags_common(defines,includes, outDir, rv);
-        // Set /Yu option. 3 is pchUseUsingSpecific
-        // Note: Starting VC8 pchUseUsingSpecific is 2 !!!
-        addAttr(rv, "UsePrecompiledHeader", "3");
-        // Set /EHsc- option
-        addAttr(rv, "ExceptionHandling", "FALSE");
+   Vector getBaseCompilerFlags(Vector defines, Vector includes, String outDir) {
+      Vector rv = new Vector();
 
-        return rv;
-    }
+      getBaseCompilerFlags_common(defines, includes, outDir, rv);
+      // Set /Yu option. 3 is pchUseUsingSpecific
+      // Note: Starting VC8 pchUseUsingSpecific is 2 !!!
+      addAttr(rv, "UsePrecompiledHeader", "3");
+      // Set /EHsc- option
+      addAttr(rv, "ExceptionHandling", "FALSE");
 
-    Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
-        Vector rv = new Vector();
+      return rv;
+   }
 
-        addAttr(rv, "Name", "VCLinkerTool");
-        addAttr(rv, "AdditionalOptions",
-                "/export:JNI_GetDefaultJavaVMInitArgs " +
-                "/export:JNI_CreateJavaVM " +
-                "/export:JVM_FindClassFromBootLoader "+
-                "/export:JNI_GetCreatedJavaVMs "+
-                "/export:jio_snprintf /export:jio_printf "+
-                "/export:jio_fprintf /export:jio_vfprintf "+
-                "/export:jio_vsnprintf "+
-                "/export:JVM_GetVersionInfo "+
-                "/export:JVM_GetThreadStateNames "+
-                "/export:JVM_GetThreadStateValues "+
-                "/export:JVM_InitAgentProperties ");
-        addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib");
-        addAttr(rv, "OutputFile", outDll);
-        // Set /INCREMENTAL option. 1 is linkIncrementalNo
-        addAttr(rv, "LinkIncremental", "1");
-        addAttr(rv, "SuppressStartupBanner", "TRUE");
-        addAttr(rv, "ModuleDefinitionFile", outDir+Util.sep+"vm.def");
-        addAttr(rv, "ProgramDatabaseFile", outDir+Util.sep+"jvm.pdb");
-        // Set /SUBSYSTEM option. 2 is subSystemWindows
-        addAttr(rv, "SubSystem", "2");
-        addAttr(rv, "BaseAddress", "0x8000000");
-        addAttr(rv, "ImportLibrary", outDir+Util.sep+"jvm.lib");
-        if(platformName.equals("Win32")) {
-            // Set /MACHINE option. 1 is X86
-            addAttr(rv, "TargetMachine", "1");
-        } else {
-            // Set /MACHINE option. 17 is X64
-            addAttr(rv, "TargetMachine", "17");
-        }
+   Vector getBaseLinkerFlags(String outDir, String outDll, String platformName) {
+      Vector rv = new Vector();
 
-        return rv;
-    }
+      addAttr(rv, "Name", "VCLinkerTool");
+      addAttr(rv, "AdditionalOptions",
+            "/export:JNI_GetDefaultJavaVMInitArgs "
+                  + "/export:JNI_CreateJavaVM "
+                  + "/export:JVM_FindClassFromBootLoader "
+                  + "/export:JNI_GetCreatedJavaVMs "
+                  + "/export:jio_snprintf /export:jio_printf "
+                  + "/export:jio_fprintf /export:jio_vfprintf "
+                  + "/export:jio_vsnprintf "
+                  + "/export:JVM_GetVersionInfo "
+                  + "/export:JVM_GetThreadStateNames "
+                  + "/export:JVM_GetThreadStateValues "
+                  + "/export:JVM_InitAgentProperties ");
+      addAttr(rv, "AdditionalDependencies", "Wsock32.lib winmm.lib");
+      addAttr(rv, "OutputFile", outDll);
+      // Set /INCREMENTAL option. 1 is linkIncrementalNo
+      addAttr(rv, "LinkIncremental", "1");
+      addAttr(rv, "SuppressStartupBanner", "TRUE");
+      addAttr(rv, "ModuleDefinitionFile", outDir + Util.sep + "vm.def");
+      addAttr(rv, "ProgramDatabaseFile", outDir + Util.sep + "jvm.pdb");
+      // Set /SUBSYSTEM option. 2 is subSystemWindows
+      addAttr(rv, "SubSystem", "2");
+      addAttr(rv, "BaseAddress", "0x8000000");
+      addAttr(rv, "ImportLibrary", outDir + Util.sep + "jvm.lib");
+      if (platformName.equals("Win32")) {
+         // Set /MACHINE option. 1 is X86
+         addAttr(rv, "TargetMachine", "1");
+      } else {
+         // Set /MACHINE option. 17 is X64
+         addAttr(rv, "TargetMachine", "17");
+      }
 
-    void  getDebugCompilerFlags_common(String opt,Vector rv) {
+      return rv;
+   }
 
-        // Set /On option
-        addAttr(rv, "Optimization", opt);
-        // Set /FR option. 1 is brAllInfo
-        addAttr(rv, "BrowseInformation", "1");
-        addAttr(rv, "BrowseInformationFile", "$(IntDir)" + Util.sep);
-        // Set /MD option. 2 is rtMultiThreadedDLL
-        addAttr(rv, "RuntimeLibrary", "2");
-        // Set /Oy- option
-        addAttr(rv, "OmitFramePointers", "FALSE");
+   void getDebugCompilerFlags_common(String opt, Vector rv) {
 
-    }
+      // Set /On option
+      addAttr(rv, "Optimization", opt);
+      // Set /FR option. 1 is brAllInfo
+      addAttr(rv, "BrowseInformation", "1");
+      addAttr(rv, "BrowseInformationFile", "$(IntDir)" + Util.sep);
+      // Set /MD option. 2 is rtMultiThreadedDLL
+      addAttr(rv, "RuntimeLibrary", "2");
+      // Set /Oy- option
+      addAttr(rv, "OmitFramePointers", "FALSE");
 
-    Vector getDebugCompilerFlags(String opt) {
-        Vector rv = new Vector();
+   }
 
-        getDebugCompilerFlags_common(opt,rv);
+   Vector getDebugCompilerFlags(String opt) {
+      Vector rv = new Vector();
 
-        return rv;
-    }
+      getDebugCompilerFlags_common(opt, rv);
 
-    Vector getDebugLinkerFlags() {
-        Vector rv = new Vector();
+      return rv;
+   }
 
-        addAttr(rv, "GenerateDebugInformation", "TRUE"); // == /DEBUG option
+   Vector getDebugLinkerFlags() {
+      Vector rv = new Vector();
 
-        return rv;
-    }
+      addAttr(rv, "GenerateDebugInformation", "TRUE"); // == /DEBUG option
 
-    void getAdditionalNonKernelLinkerFlags(Vector rv) {
-        extAttr(rv, "AdditionalOptions",
-                "/export:AsyncGetCallTrace ");
-    }
+      return rv;
+   }
 
-    void getProductCompilerFlags_common(Vector rv) {
-        // Set /O2 option. 2 is optimizeMaxSpeed
-        addAttr(rv, "Optimization", "2");
-        // Set /Oy- option
-        addAttr(rv, "OmitFramePointers", "FALSE");
-        // Set /Ob option.  1 is expandOnlyInline
-        addAttr(rv, "InlineFunctionExpansion", "1");
-        // Set /GF option.
-        addAttr(rv, "StringPooling", "TRUE");
-        // Set /MD option. 2 is rtMultiThreadedDLL
-        addAttr(rv, "RuntimeLibrary", "2");
-        // Set /Gy option
-        addAttr(rv, "EnableFunctionLevelLinking", "TRUE");
-    }
+   void getAdditionalNonKernelLinkerFlags(Vector rv) {
+      extAttr(rv, "AdditionalOptions", "/export:AsyncGetCallTrace ");
+   }
 
-    Vector getProductCompilerFlags() {
-        Vector rv = new Vector();
+   void getProductCompilerFlags_common(Vector rv) {
+      // Set /O2 option. 2 is optimizeMaxSpeed
+      addAttr(rv, "Optimization", "2");
+      // Set /Oy- option
+      addAttr(rv, "OmitFramePointers", "FALSE");
+      // Set /Ob option. 1 is expandOnlyInline
+      addAttr(rv, "InlineFunctionExpansion", "1");
+      // Set /GF option.
+      addAttr(rv, "StringPooling", "TRUE");
+      // Set /MD option. 2 is rtMultiThreadedDLL
+      addAttr(rv, "RuntimeLibrary", "2");
+      // Set /Gy option
+      addAttr(rv, "EnableFunctionLevelLinking", "TRUE");
+   }
 
-        getProductCompilerFlags_common(rv);
+   Vector getProductCompilerFlags() {
+      Vector rv = new Vector();
 
-        return rv;
-    }
+      getProductCompilerFlags_common(rv);
 
-    Vector getProductLinkerFlags() {
-        Vector rv = new Vector();
+      return rv;
+   }
 
-        // Set /OPT:REF option. 2 is optReferences
-        addAttr(rv, "OptimizeReferences", "2");
-        // Set /OPT:optFolding option. 2 is optFolding
-        addAttr(rv, "EnableCOMDATFolding", "2");
+   Vector getProductLinkerFlags() {
+      Vector rv = new Vector();
 
-        return rv;
-    }
+      // Set /OPT:REF option. 2 is optReferences
+      addAttr(rv, "OptimizeReferences", "2");
+      // Set /OPT:optFolding option. 2 is optFolding
+      addAttr(rv, "EnableCOMDATFolding", "2");
 
-    String getOptFlag() {
-        return "2";
-    }
+      return rv;
+   }
 
-    String getNoOptFlag() {
-        return "0";
-    }
+   String getOptFlag() {
+      return "2";
+   }
 
-    String makeCfgName(String flavourBuild, String platform) {
-        return  flavourBuild + "|" + platform;
-    }
+   String getNoOptFlag() {
+      return "0";
+   }
+
+   String makeCfgName(String flavourBuild, String platform) {
+      return flavourBuild + "|" + platform;
+   }
+
 }
diff --git a/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java b/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
new file mode 100644
index 0000000..1495b73
--- /dev/null
+++ b/hotspot/src/share/tools/whitebox/sun/hotspot/WhiteBox.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+package sun.hotspot;
+import java.security.BasicPermission;
+import sun.hotspot.parser.DiagnosticCommand;
+
+public class WhiteBox {
+
+  @SuppressWarnings("serial")
+  public static class WhiteBoxPermission extends BasicPermission {
+    public WhiteBoxPermission(String s) {
+      super(s);
+    }
+  }
+
+  private WhiteBox() {}
+  private static final WhiteBox instance = new WhiteBox();
+  private static native void registerNatives();
+
+  /**
+   * Returns the singleton WhiteBox instance.
+   *
+   * The returned WhiteBox object should be carefully guarded
+   * by the caller, since it can be used to read and write data
+   * at arbitrary memory addresses. It must never be passed to
+   * untrusted code.
+   */
+  public synchronized static WhiteBox getWhiteBox() {
+    SecurityManager sm = System.getSecurityManager();
+    if (sm != null) {
+      sm.checkPermission(new WhiteBoxPermission("getInstance"));
+    }
+    return instance;
+  }
+
+  static {
+    registerNatives();
+  }
+
+  // Memory
+  public native long getObjectAddress(Object o);
+  public native int  getHeapOopSize();
+
+  // G1
+  public native boolean g1InConcurrentMark();
+  public native boolean g1IsHumongous(Object o);
+  public native long    g1NumFreeRegions();
+  public native int     g1RegionSize();
+  public native Object[]    parseCommandLine(String commandline, DiagnosticCommand[] args);
+}
diff --git a/hotspot/src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java b/hotspot/src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
new file mode 100644
index 0000000..2099901
--- /dev/null
+++ b/hotspot/src/share/tools/whitebox/sun/hotspot/parser/DiagnosticCommand.java
@@ -0,0 +1,43 @@
+package sun.hotspot.parser;
+
+public class DiagnosticCommand {
+
+    public enum DiagnosticArgumentType {
+        JLONG, BOOLEAN, STRING, NANOTIME, STRINGARRAY, MEMORYSIZE
+    }
+
+    private String name;
+    private String desc;
+    private DiagnosticArgumentType type;
+    private boolean mandatory;
+    private String defaultValue;
+
+    public DiagnosticCommand(String name, String desc, DiagnosticArgumentType type,
+            boolean mandatory, String defaultValue) {
+        this.name = name;
+        this.desc = desc;
+        this.type = type;
+        this.mandatory = mandatory;
+        this.defaultValue = defaultValue;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDesc() {
+        return desc;
+    }
+
+    public DiagnosticArgumentType getType() {
+        return type;
+    }
+
+    public boolean isMandatory() {
+        return mandatory;
+    }
+
+    public String getDefaultValue() {
+        return defaultValue;
+    }
+}
diff --git a/hotspot/src/share/vm/adlc/adlparse.cpp b/hotspot/src/share/vm/adlc/adlparse.cpp
index ec31e36..6d08eab 100644
--- a/hotspot/src/share/vm/adlc/adlparse.cpp
+++ b/hotspot/src/share/vm/adlc/adlparse.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -115,6 +115,12 @@
       parse_err(SYNERR, "expected one of - instruct, operand, ins_attrib, op_attrib, source, register, pipeline, encode\n     Found %s",ident);
     }
   }
+  // Add reg_class spill_regs after parsing.
+  RegisterForm *regBlock = _AD.get_registers();
+  if (regBlock == NULL) {
+    parse_err(SEMERR, "Did not declare 'register' definitions");
+  }
+  regBlock->addSpillRegClass();
 
   // Done with parsing, check consistency.
 
@@ -768,11 +774,12 @@
 
 //------------------------------reg_parse--------------------------------------
 void ADLParser::reg_parse(void) {
-
-  // Create the RegisterForm for the architecture description.
-  RegisterForm *regBlock = new RegisterForm();    // Build new Source object
-  regBlock->_linenum = linenum();
-  _AD.addForm(regBlock);
+  RegisterForm *regBlock = _AD.get_registers(); // Information about registers encoding
+  if (regBlock == NULL) {
+    // Create the RegisterForm for the architecture description.
+    regBlock = new RegisterForm();    // Build new Source object
+    _AD.addForm(regBlock);
+  }
 
   skipws();                       // Skip leading whitespace
   if (_curchar == '%' && *(_ptr+1) == '{') {
@@ -796,15 +803,11 @@
     parse_err(SYNERR, "Missing %c{ ... %c} block after register keyword.\n",'%','%');
     return;
   }
-
-  // Add reg_class spill_regs
-  regBlock->addSpillRegClass();
 }
 
 //------------------------------encode_parse-----------------------------------
 void ADLParser::encode_parse(void) {
   EncodeForm *encBlock;         // Information about instruction/operand encoding
-  char       *desc = NULL;      // String representation of encode rule
 
   _AD.getForm(&encBlock);
   if ( encBlock == NULL) {
@@ -1389,7 +1392,7 @@
       _AD.addForm(machnode);
     }
     else if (!strcmp(ident, "attributes")) {
-      bool vsi_seen = false, bhds_seen = false;
+      bool vsi_seen = false;
 
       skipws();
       if ( (_curchar != '%')
@@ -1433,7 +1436,6 @@
           }
 
           pipeline->_branchHasDelaySlot = true;
-          bhds_seen = true;
           continue;
         }
 
@@ -1636,6 +1638,12 @@
     next_char();                   // Skip "(" or ","
     ident = get_ident();           // Grab next identifier
 
+    if (_AD._adl_debug > 1) {
+      if (ident != NULL) {
+        fprintf(stderr, "resource_parse: identifier: %s\n", ident);
+      }
+    }
+
     if (ident == NULL) {
       parse_err(SYNERR, "keyword identifier expected at \"%c\"\n", _curchar);
       return;
@@ -2424,7 +2432,6 @@
   int        lparen = 0;          // keep track of parenthesis nesting depth
   int        rparen = 0;          // position of instruction at this depth
   InstructForm *inst_seen  = NULL;
-  InstructForm *child_seen = NULL;
 
   // Walk the match tree,
   // Record <parent, position, instruction name, input position>
@@ -2434,7 +2441,7 @@
     if (_curchar == '(') {
       ++lparen;
       next_char();
-      child_seen = peep_match_child_parse(match, parent, position, rparen);
+      ( void ) peep_match_child_parse(match, parent, position, rparen);
     }
     // Right paren signals end of an input, may be more
     else if (_curchar == ')') {
@@ -3151,6 +3158,9 @@
 
 
 //------------------------------size_parse-----------------------------------
+// Parse a 'size(<expr>)' attribute which specifies the size of the
+// emitted instructions in bytes. <expr> can be a C++ expression,
+// e.g. a constant.
 char* ADLParser::size_parse(InstructForm *instr) {
   char* sizeOfInstr = NULL;
 
@@ -4271,7 +4281,17 @@
             || ((c >= '0') && (c <= '9'))
             || ((c == '_')) || ((c == ':')) || ((c == '#')) );
   if (start == end) {             // We popped out on the first try
-    parse_err(SYNERR, "identifier expected at %c\n", c);
+    // It can occur that `start' contains the rest of the input file.
+    // In this case the output should be truncated.
+    if (strlen(start) > 24) {
+      char buf[32];
+      strncpy(buf, start, 20);
+      buf[20] = '\0';
+      strcat(buf, "[...]");
+      parse_err(SYNERR, "Identifier expected, but found '%s'.", buf);
+    } else {
+      parse_err(SYNERR, "Identifier expected, but found '%s'.", start);
+    }
     start = NULL;
   }
   else {
diff --git a/hotspot/src/share/vm/adlc/archDesc.cpp b/hotspot/src/share/vm/adlc/archDesc.cpp
index 294e88c..81b54dd 100644
--- a/hotspot/src/share/vm/adlc/archDesc.cpp
+++ b/hotspot/src/share/vm/adlc/archDesc.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+// Copyright (c) 1997, 2012, 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
@@ -221,6 +221,7 @@
       _register = NULL;
       _encode = NULL;
       _pipeline = NULL;
+      _frame = NULL;
 }
 
 ArchDesc::~ArchDesc() {
@@ -648,7 +649,10 @@
 // Return the textual binding for a given CPP flag name.
 // Return NULL if there is no binding, or it has been #undef-ed.
 char* ArchDesc::get_preproc_def(const char* flag) {
-  SourceForm* deff = (SourceForm*) _preproc_table[flag];
+  // In case of syntax errors, flag may take the value NULL.
+  SourceForm* deff = NULL;
+  if (flag != NULL)
+    deff = (SourceForm*) _preproc_table[flag];
   return (deff == NULL) ? NULL : deff->_code;
 }
 
@@ -803,7 +807,9 @@
     while (i++ <= 15)  fputc(' ', errfile);
     fprintf(errfile, "%-8s:", pref);
     vfprintf(errfile, fmt, args);
-    fprintf(errfile, "\n"); }
+    fprintf(errfile, "\n");
+    fflush(errfile);
+  }
   return 1;
 }
 
@@ -855,8 +861,14 @@
 
   // Check constraints on result's register class
   const char *result_class = opForm.constrained_reg_class();
-  if (!result_class) opForm.dump();
-  assert( result_class, "Resulting register class was not defined for operand");
+  if (result_class == NULL) {
+    opForm.dump();
+    syntax_err(opForm._linenum,
+               "Use of an undefined result class for operand: %s",
+               opForm._ident);
+    abort();
+  }
+
   regMask = reg_class_to_reg_mask( result_class );
 
   return regMask;
@@ -865,8 +877,14 @@
 // Obtain the name of the RegMask for an InstructForm
 const char *ArchDesc::reg_mask(InstructForm &inForm) {
   const char *result = inForm.reduce_result();
-  assert( result,
-          "Did not find result operand or RegMask for this instruction");
+
+  if (result == NULL) {
+    syntax_err(inForm._linenum,
+               "Did not find result operand or RegMask"
+               " for this instruction: %s",
+               inForm._ident);
+    abort();
+  }
 
   // Instructions producing 'Universe' use RegMask::Empty
   if( strcmp(result,"Universe")==0 ) {
@@ -875,10 +893,17 @@
 
   // Lookup this result operand and get its register class
   Form *form = (Form*)_globalNames[result];
-  assert( form, "Result operand must be defined");
+  if (form == NULL) {
+    syntax_err(inForm._linenum,
+               "Did not find result operand for result: %s", result);
+    abort();
+  }
   OperandForm *oper = form->is_operand();
-  if (oper == NULL) form->dump();
-  assert( oper, "Result must be an OperandForm");
+  if (oper == NULL) {
+    syntax_err(inForm._linenum, "Form is not an OperandForm:");
+    form->dump();
+    abort();
+  }
   return reg_mask( *oper );
 }
 
@@ -887,7 +912,13 @@
 char *ArchDesc::stack_or_reg_mask(OperandForm  &opForm) {
   // name of cisc_spillable version
   const char *reg_mask_name = reg_mask(opForm);
-  assert( reg_mask_name != NULL, "called with incorrect opForm");
+
+  if (reg_mask_name == NULL) {
+     syntax_err(opForm._linenum,
+                "Did not find reg_mask for opForm: %s",
+                opForm._ident);
+     abort();
+  }
 
   const char *stack_or = "STACK_OR_";
   int   length         = (int)strlen(stack_or) + (int)strlen(reg_mask_name) + 1;
@@ -911,12 +942,24 @@
   // Find last character in idealOp, it specifies the type
   char  last_char = 0;
   const char *ptr = idealOp;
-  for( ; *ptr != '\0'; ++ptr) {
+  for (; *ptr != '\0'; ++ptr) {
     last_char = *ptr;
   }
 
+  // Match Vector types.
+  if (strncmp(idealOp, "Vec",3)==0) {
+    switch(last_char) {
+    case 'S':  return "TypeVect::VECTS";
+    case 'D':  return "TypeVect::VECTD";
+    case 'X':  return "TypeVect::VECTX";
+    case 'Y':  return "TypeVect::VECTY";
+    default:
+      internal_err("Vector type %s with unrecognized type\n",idealOp);
+    }
+  }
+
   // !!!!!
-  switch( last_char ) {
+  switch(last_char) {
   case 'I':    return "TypeInt::INT";
   case 'P':    return "TypePtr::BOTTOM";
   case 'N':    return "TypeNarrowOop::BOTTOM";
diff --git a/hotspot/src/share/vm/adlc/archDesc.hpp b/hotspot/src/share/vm/adlc/archDesc.hpp
index ad8f454..f6ae35a 100644
--- a/hotspot/src/share/vm/adlc/archDesc.hpp
+++ b/hotspot/src/share/vm/adlc/archDesc.hpp
@@ -365,13 +365,14 @@
 // A derived class defines the appropriate output for a specific mapping.
 class OutputMap {
 protected:
-  FILE     *_hpp;
-  FILE     *_cpp;
-  FormDict &_globals;
-  ArchDesc &_AD;
+  FILE       *_hpp;
+  FILE       *_cpp;
+  FormDict   &_globals;
+  ArchDesc   &_AD;
+  const char *_name;
 public:
-  OutputMap (FILE *decl_file, FILE *def_file, FormDict &globals, ArchDesc &AD)
-    : _hpp(decl_file), _cpp(def_file), _globals(globals), _AD(AD) {};
+  OutputMap (FILE *decl_file, FILE *def_file, FormDict &globals, ArchDesc &AD, const char *name)
+    : _hpp(decl_file), _cpp(def_file), _globals(globals), _AD(AD), _name(name) {};
   // Access files used by this routine
   FILE        *decl_file() { return _hpp; }
   FILE        *def_file()  { return _cpp; }
diff --git a/hotspot/src/share/vm/adlc/dict2.cpp b/hotspot/src/share/vm/adlc/dict2.cpp
index 22ec13d..c7797c7 100644
--- a/hotspot/src/share/vm/adlc/dict2.cpp
+++ b/hotspot/src/share/vm/adlc/dict2.cpp
@@ -33,7 +33,7 @@
 // String hash tables
 #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 char shft[MAXID + 1] = {1,2,3,4,5,6,7,1,2,3,4,5,6,7,1,2,3,4,5,6,7};
 static short xsum[MAXID];
 
 //------------------------------bucket---------------------------------------
diff --git a/hotspot/src/share/vm/adlc/filebuff.hpp b/hotspot/src/share/vm/adlc/filebuff.hpp
index 3d8bdad..894a2c5 100644
--- a/hotspot/src/share/vm/adlc/filebuff.hpp
+++ b/hotspot/src/share/vm/adlc/filebuff.hpp
@@ -31,10 +31,14 @@
 using namespace std;
 
 // STRUCTURE FOR HANDLING INPUT AND OUTPUT FILES
-typedef struct {
+
+class BufferedFile {
+ public:
   const char *_name;
   FILE *_fp;
-} BufferedFile;
+  inline BufferedFile() { _name = NULL; _fp = NULL; };
+  inline ~BufferedFile() {};
+};
 
 class ArchDesc;
 
diff --git a/hotspot/src/share/vm/adlc/forms.cpp b/hotspot/src/share/vm/adlc/forms.cpp
index 5e05a84..08c2dcf 100644
--- a/hotspot/src/share/vm/adlc/forms.cpp
+++ b/hotspot/src/share/vm/adlc/forms.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -255,58 +255,31 @@
   if( strcmp(opType,"LoadD_unaligned")==0 )  return Form::idealD;
   if( strcmp(opType,"LoadF")==0 )  return Form::idealF;
   if( strcmp(opType,"LoadI")==0 )  return Form::idealI;
-  if( strcmp(opType,"LoadUI2L")==0 )  return Form::idealI;
   if( strcmp(opType,"LoadKlass")==0 )  return Form::idealP;
   if( strcmp(opType,"LoadNKlass")==0 ) return Form::idealN;
   if( strcmp(opType,"LoadL")==0 )  return Form::idealL;
   if( strcmp(opType,"LoadL_unaligned")==0 )  return Form::idealL;
   if( strcmp(opType,"LoadPLocked")==0 )  return Form::idealP;
-  if( strcmp(opType,"LoadLLocked")==0 )  return Form::idealL;
   if( strcmp(opType,"LoadP")==0 )  return Form::idealP;
   if( strcmp(opType,"LoadN")==0 )  return Form::idealN;
   if( strcmp(opType,"LoadRange")==0 )  return Form::idealI;
   if( strcmp(opType,"LoadS")==0 )  return Form::idealS;
-  if( strcmp(opType,"Load16B")==0 )  return Form::idealB;
-  if( strcmp(opType,"Load8B")==0 )  return Form::idealB;
-  if( strcmp(opType,"Load4B")==0 )  return Form::idealB;
-  if( strcmp(opType,"Load8C")==0 )  return Form::idealC;
-  if( strcmp(opType,"Load4C")==0 )  return Form::idealC;
-  if( strcmp(opType,"Load2C")==0 )  return Form::idealC;
-  if( strcmp(opType,"Load8S")==0 )  return Form::idealS;
-  if( strcmp(opType,"Load4S")==0 )  return Form::idealS;
-  if( strcmp(opType,"Load2S")==0 )  return Form::idealS;
-  if( strcmp(opType,"Load2D")==0 )  return Form::idealD;
-  if( strcmp(opType,"Load4F")==0 )  return Form::idealF;
-  if( strcmp(opType,"Load2F")==0 )  return Form::idealF;
-  if( strcmp(opType,"Load4I")==0 )  return Form::idealI;
-  if( strcmp(opType,"Load2I")==0 )  return Form::idealI;
-  if( strcmp(opType,"Load2L")==0 )  return Form::idealL;
+  if( strcmp(opType,"LoadVector")==0 )  return Form::idealV;
   assert( strcmp(opType,"Load") != 0, "Must type Loads" );
   return Form::none;
 }
 
 Form::DataType Form::is_store_to_memory(const char *opType) const {
   if( strcmp(opType,"StoreB")==0)  return Form::idealB;
-  if( strcmp(opType,"StoreCM")==0)  return Form::idealB;
+  if( strcmp(opType,"StoreCM")==0) return Form::idealB;
   if( strcmp(opType,"StoreC")==0)  return Form::idealC;
   if( strcmp(opType,"StoreD")==0)  return Form::idealD;
   if( strcmp(opType,"StoreF")==0)  return Form::idealF;
   if( strcmp(opType,"StoreI")==0)  return Form::idealI;
   if( strcmp(opType,"StoreL")==0)  return Form::idealL;
   if( strcmp(opType,"StoreP")==0)  return Form::idealP;
-  if( strcmp(opType,"StoreN")==0) return Form::idealN;
-  if( strcmp(opType,"Store16B")==0)  return Form::idealB;
-  if( strcmp(opType,"Store8B")==0)  return Form::idealB;
-  if( strcmp(opType,"Store4B")==0)  return Form::idealB;
-  if( strcmp(opType,"Store8C")==0)  return Form::idealC;
-  if( strcmp(opType,"Store4C")==0)  return Form::idealC;
-  if( strcmp(opType,"Store2C")==0)  return Form::idealC;
-  if( strcmp(opType,"Store2D")==0)  return Form::idealD;
-  if( strcmp(opType,"Store4F")==0)  return Form::idealF;
-  if( strcmp(opType,"Store2F")==0)  return Form::idealF;
-  if( strcmp(opType,"Store4I")==0)  return Form::idealI;
-  if( strcmp(opType,"Store2I")==0)  return Form::idealI;
-  if( strcmp(opType,"Store2L")==0)  return Form::idealL;
+  if( strcmp(opType,"StoreN")==0)  return Form::idealN;
+  if( strcmp(opType,"StoreVector")==0 )  return Form::idealV;
   assert( strcmp(opType,"Store") != 0, "Must type Stores" );
   return Form::none;
 }
diff --git a/hotspot/src/share/vm/adlc/forms.hpp b/hotspot/src/share/vm/adlc/forms.hpp
index 3132c6a..09c7ac7 100644
--- a/hotspot/src/share/vm/adlc/forms.hpp
+++ b/hotspot/src/share/vm/adlc/forms.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -172,7 +172,8 @@
     idealB      =  6,  // Byte    type
     idealC      =  7,  // Char    type
     idealS      =  8,  // String  type
-    idealN      =  9   // Narrow oop types
+    idealN      =  9,  // Narrow oop types
+    idealV      = 10   // Vector  type
   };
   // Convert ideal name to a DataType, return DataType::none if not a 'ConX'
   Form::DataType  ideal_to_const_type(const char *ideal_type_name) const;
@@ -447,11 +448,11 @@
   // Return number of USEs + number of DEFs
   int        num_operands();
   // Return zero-based position in list;  -1 if not in list.
-  int        operand_position(const char *name, int usedef);
+  int        operand_position(const char *name, int usedef, Form *fm);
   // Find position for this name, regardless of use/def information
   int        operand_position(const char *name);
   // Find position for this name when looked up for output via "format"
-  int        operand_position_format(const char *name);
+  int        operand_position_format(const char *name, Form *fm);
   // Find position for the Label when looked up for output via "format"
   int        label_position();
   // Find position for the Method when looked up for output via "format"
diff --git a/hotspot/src/share/vm/adlc/formsopt.cpp b/hotspot/src/share/vm/adlc/formsopt.cpp
index 302cd84..07d70fc 100644
--- a/hotspot/src/share/vm/adlc/formsopt.cpp
+++ b/hotspot/src/share/vm/adlc/formsopt.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -66,7 +66,7 @@
 // for spill-slots/regs.
 void RegisterForm::addSpillRegClass() {
   // Stack slots start at the next available even register number.
-  _reg_ctr = (_reg_ctr+1) & ~1;
+  _reg_ctr = (_reg_ctr+7) & ~7;
   const char *rc_name   = "stack_slots";
   RegClass   *reg_class = new RegClass(rc_name);
   reg_class->_stack_or_reg = true;
@@ -150,9 +150,14 @@
 int RegisterForm::RegMask_Size() {
   // Need at least this many words
   int words_for_regs = (_reg_ctr + 31)>>5;
-  // Add a few for incoming & outgoing arguments to calls.
+  // The array of Register Mask bits should be large enough to cover
+  // all the machine registers and all parameters that need to be passed
+  // on the stack (stack registers) up to some interesting limit.  Methods
+  // that need more parameters will NOT be compiled.  On Intel, the limit
+  // is something like 90+ parameters.
+  // Add a few (3 words == 96 bits) for incoming & outgoing arguments to calls.
   // Round up to the next doubleword size.
-  return (words_for_regs + 2 + 1) & ~1;
+  return (words_for_regs + 3 + 1) & ~1;
 }
 
 void RegisterForm::dump() {                  // Debug printer
diff --git a/hotspot/src/share/vm/adlc/formssel.cpp b/hotspot/src/share/vm/adlc/formssel.cpp
index 3c69d6a..e76d5f5 100644
--- a/hotspot/src/share/vm/adlc/formssel.cpp
+++ b/hotspot/src/share/vm/adlc/formssel.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -432,6 +432,14 @@
   return  _matrule->is_ideal_store();
 }
 
+// Return 'true' if this instruction matches an ideal vector node
+bool InstructForm::is_vector() const {
+  if( _matrule == NULL ) return false;
+
+  return _matrule->is_vector();
+}
+
+
 // Return the input register that must match the output register
 // If this is not required, return 0
 uint InstructForm::two_address(FormDict &globals) {
@@ -559,7 +567,7 @@
         if( strcmp(rc_name,"stack_slots") ) {
           // Check for ideal_type of RegFlags
           const char *type = opform->ideal_type( globals, registers );
-          if( !strcmp(type,"RegFlags") )
+          if( (type != NULL) && !strcmp(type, "RegFlags") )
             rematerialize = true;
         } else
           rematerialize = false; // Do not rematerialize things target stk
@@ -743,6 +751,7 @@
         !strcmp(_matrule->_rChild->_opType,"DecodeN")    ||
         !strcmp(_matrule->_rChild->_opType,"EncodeP")    ||
         !strcmp(_matrule->_rChild->_opType,"LoadN")      ||
+        !strcmp(_matrule->_rChild->_opType,"GetAndSetN") ||
         !strcmp(_matrule->_rChild->_opType,"LoadNKlass") ||
         !strcmp(_matrule->_rChild->_opType,"CreateEx")   ||  // type of exception
         !strcmp(_matrule->_rChild->_opType,"CheckCastPP")) ) return true;
@@ -751,6 +760,9 @@
 
   if (needs_base_oop_edge(globals)) return true;
 
+  if (is_vector()) return true;
+  if (is_mach_constant()) return true;
+
   return  false;
 }
 
@@ -781,6 +793,20 @@
   return num_opnds;
 }
 
+const char *InstructForm::opnd_ident(int idx) {
+  return _components.at(idx)->_name;
+}
+
+const char *InstructForm::unique_opnd_ident(int idx) {
+  uint i;
+  for (i = 1; i < num_opnds(); ++i) {
+    if (unique_opnds_idx(i) == idx) {
+      break;
+    }
+  }
+  return (_components.at(i) != NULL) ? _components.at(i)->_name : "";
+}
+
 // Return count of unmatched operands.
 uint InstructForm::num_post_match_opnds() {
   uint  num_post_match_opnds = _components.count();
@@ -852,6 +878,9 @@
   return base;
 }
 
+// This function determines the order of the MachOper in _opnds[]
+// by writing the operand names into the _components list.
+//
 // Implementation does not modify state of internal structures
 void InstructForm::build_components() {
   // Add top-level operands to the components
@@ -947,11 +976,11 @@
 
 // Return zero-based position in component list;  -1 if not in list.
 int   InstructForm::operand_position(const char *name, int usedef) {
-  return unique_opnds_idx(_components.operand_position(name, usedef));
+  return unique_opnds_idx(_components.operand_position(name, usedef, this));
 }
 
 int   InstructForm::operand_position_format(const char *name) {
-  return unique_opnds_idx(_components.operand_position_format(name));
+  return unique_opnds_idx(_components.operand_position_format(name, this));
 }
 
 // Return zero-based position in component list; -1 if not in list.
@@ -1211,7 +1240,7 @@
     if (different) {
       globalAD->syntax_err(short_branch->_linenum, "Instruction %s and its short form %s have different parameters\n", _ident, short_branch->_ident);
     }
-    if (AD._short_branch_debug) {
+    if (AD._adl_debug > 1 || AD._short_branch_debug) {
       fprintf(stderr, "Instruction %s has short form %s\n", _ident, short_branch->_ident);
     }
     _short_branch_form = short_branch;
@@ -1243,16 +1272,19 @@
   // Find replacement variable's type
   const Form *form   = _localNames[rep_var];
   if (form == NULL) {
-    fprintf(stderr, "unknown replacement variable in format statement: '%s'\n", rep_var);
-    assert(false, "ShouldNotReachHere()");
+    globalAD->syntax_err(_linenum, "Unknown replacement variable %s in format statement of %s.",
+                         rep_var, _ident);
+    return;
   }
   OpClassForm *opc   = form->is_opclass();
   assert( opc, "replacement variable was not found in local names");
   // Lookup the index position of the replacement variable
   int idx  = operand_position_format(rep_var);
   if ( idx == -1 ) {
-    assert( strcmp(opc->_ident,"label")==0, "Unimplemented");
-    assert( false, "ShouldNotReachHere()");
+    globalAD->syntax_err(_linenum, "Could not find replacement variable %s in format statement of %s.\n",
+                         rep_var, _ident);
+    assert(strcmp(opc->_ident, "label") == 0, "Unimplemented");
+    return;
   }
 
   if (is_noninput_operand(idx)) {
@@ -1261,7 +1293,7 @@
     OperandForm* oper = form->is_operand();
     if (oper != NULL && oper->is_bound_register()) {
       const RegDef* first = oper->get_RegClass()->find_first_elem();
-      fprintf(fp, "    tty->print(\"%s\");\n", first->_regname);
+      fprintf(fp, "    st->print(\"%s\");\n", first->_regname);
     } else {
       globalAD->syntax_err(_linenum, "In %s can't find format for %s %s", _ident, opc->_ident, rep_var);
     }
@@ -1359,26 +1391,28 @@
   // idx0=0 is used to indicate that info comes from this same node, not from input edge.
   // idx1 starts at oper_input_base()
   if ( cur_num_opnds >= 1 ) {
-    fprintf(fp,"    // Start at oper_input_base() and count operands\n");
-    fprintf(fp,"    unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals));
-    fprintf(fp,"    unsigned %sidx1 = %d;\n", prefix, oper_input_base(globals));
+    fprintf(fp,"  // Start at oper_input_base() and count operands\n");
+    fprintf(fp,"  unsigned %sidx0 = %d;\n", prefix, oper_input_base(globals));
+    fprintf(fp,"  unsigned %sidx1 = %d;", prefix, oper_input_base(globals));
+    fprintf(fp," \t// %s\n", unique_opnd_ident(1));
 
     // Generate starting points for other unique operands if they exist
     for ( idx = 2; idx < num_unique_opnds(); ++idx ) {
       if( *receiver == 0 ) {
-        fprintf(fp,"    unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();\n",
+        fprintf(fp,"  unsigned %sidx%d = %sidx%d + opnd_array(%d)->num_edges();",
                 prefix, idx, prefix, idx-1, idx-1 );
       } else {
-        fprintf(fp,"    unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();\n",
+        fprintf(fp,"  unsigned %sidx%d = %sidx%d + %s_opnds[%d]->num_edges();",
                 prefix, idx, prefix, idx-1, receiver, idx-1 );
       }
+      fprintf(fp," \t// %s\n", unique_opnd_ident(idx));
     }
   }
   if( *receiver != 0 ) {
     // This value is used by generate_peepreplace when copying a node.
     // Don't emit it in other cases since it can hide bugs with the
     // use invalid idx's.
-    fprintf(fp,"    unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver);
+    fprintf(fp,"  unsigned %sidx%d = %sreq(); \n", prefix, idx, receiver);
   }
 
 }
@@ -1762,9 +1796,25 @@
   return Component::INVALID;
 }
 
+const char *Component::getUsedefName() {
+  switch (_usedef) {
+    case Component::INVALID:  return "INVALID";  break;
+    case Component::USE:      return "USE";      break;
+    case Component::USE_DEF:  return "USE_DEF";  break;
+    case Component::USE_KILL: return "USE_KILL"; break;
+    case Component::KILL:     return "KILL";     break;
+    case Component::TEMP:     return "TEMP";     break;
+    case Component::DEF:      return "DEF";      break;
+    case Component::CALL:     return "CALL";     break;
+    default: assert(false, "unknown effect");
+  }
+  return "Undefined Use/Def info";
+}
+
 Effect::Effect(const char *name) : _name(name), _use_def(effect_lookup(name)) {
   _ftype = Form::EFF;
 }
+
 Effect::~Effect() {
 }
 
@@ -2261,7 +2311,7 @@
 }
 
 int OperandForm::operand_position(const char *name, int usedef) {
-  return _components.operand_position(name, usedef);
+  return _components.operand_position(name, usedef, this);
 }
 
 
@@ -2387,20 +2437,20 @@
   if (_matrule && (_matrule->is_base_register(globals) ||
                    strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
     // !!!!! !!!!!
-    fprintf(fp,    "{ char reg_str[128];\n");
-    fprintf(fp,"      ra->dump_register(node,reg_str);\n");
-    fprintf(fp,"      tty->print(\"%cs\",reg_str);\n",'%');
-    fprintf(fp,"    }\n");
+    fprintf(fp,"  { char reg_str[128];\n");
+    fprintf(fp,"    ra->dump_register(node,reg_str);\n");
+    fprintf(fp,"    st->print(\"%cs\",reg_str);\n",'%');
+    fprintf(fp,"  }\n");
   } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
     format_constant( fp, index, dtype );
   } else if (ideal_to_sReg_type(_ident) != Form::none) {
     // Special format for Stack Slot Register
-    fprintf(fp,    "{ char reg_str[128];\n");
-    fprintf(fp,"      ra->dump_register(node,reg_str);\n");
-    fprintf(fp,"      tty->print(\"%cs\",reg_str);\n",'%');
-    fprintf(fp,"    }\n");
+    fprintf(fp,"  { char reg_str[128];\n");
+    fprintf(fp,"    ra->dump_register(node,reg_str);\n");
+    fprintf(fp,"    st->print(\"%cs\",reg_str);\n",'%');
+    fprintf(fp,"  }\n");
   } else {
-    fprintf(fp,"tty->print(\"No format defined for %s\n\");\n", _ident);
+    fprintf(fp,"  st->print(\"No format defined for %s\n\");\n", _ident);
     fflush(fp);
     fprintf(stderr,"No format defined for %s\n", _ident);
     dump();
@@ -2414,36 +2464,36 @@
   Form::DataType dtype;
   if (_matrule && (_matrule->is_base_register(globals) ||
                    strcmp(ideal_type(globalAD->globalNames()), "RegFlags") == 0)) {
-    fprintf(fp,    "{ char reg_str[128];\n");
-    fprintf(fp,"      ra->dump_register(node->in(idx");
-    if ( index != 0 ) fprintf(fp,                  "+%d",index);
-    fprintf(fp,                                       "),reg_str);\n");
-    fprintf(fp,"      tty->print(\"%cs\",reg_str);\n",'%');
-    fprintf(fp,"    }\n");
+    fprintf(fp,"  { char reg_str[128];\n");
+    fprintf(fp,"    ra->dump_register(node->in(idx");
+    if ( index != 0 ) fprintf(fp,              "+%d",index);
+    fprintf(fp,                                      "),reg_str);\n");
+    fprintf(fp,"    st->print(\"%cs\",reg_str);\n",'%');
+    fprintf(fp,"  }\n");
   } else if (_matrule && (dtype = _matrule->is_base_constant(globals)) != Form::none) {
     format_constant( fp, index, dtype );
   } else if (ideal_to_sReg_type(_ident) != Form::none) {
     // Special format for Stack Slot Register
-    fprintf(fp,    "{ char reg_str[128];\n");
-    fprintf(fp,"      ra->dump_register(node->in(idx");
+    fprintf(fp,"  { char reg_str[128];\n");
+    fprintf(fp,"    ra->dump_register(node->in(idx");
     if ( index != 0 ) fprintf(fp,                  "+%d",index);
     fprintf(fp,                                       "),reg_str);\n");
-    fprintf(fp,"      tty->print(\"%cs\",reg_str);\n",'%');
-    fprintf(fp,"    }\n");
+    fprintf(fp,"    st->print(\"%cs\",reg_str);\n",'%');
+    fprintf(fp,"  }\n");
   } else {
-    fprintf(fp,"tty->print(\"No format defined for %s\n\");\n", _ident);
+    fprintf(fp,"  st->print(\"No format defined for %s\n\");\n", _ident);
     assert( false,"Internal error:\n  output_external_operand() attempting to output other than a Register or Constant");
   }
 }
 
 void OperandForm::format_constant(FILE *fp, uint const_index, uint const_type) {
   switch(const_type) {
-  case Form::idealI:  fprintf(fp,"st->print(\"#%%d\", _c%d);\n", const_index); break;
-  case Form::idealP:  fprintf(fp,"_c%d->dump_on(st);\n",         const_index); break;
-  case Form::idealN:  fprintf(fp,"_c%d->dump_on(st);\n",         const_index); break;
-  case Form::idealL:  fprintf(fp,"st->print(\"#%%lld\", _c%d);\n", const_index); break;
-  case Form::idealF:  fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
-  case Form::idealD:  fprintf(fp,"st->print(\"#%%f\", _c%d);\n", const_index); break;
+  case Form::idealI: fprintf(fp,"  st->print(\"#%%d\", _c%d);\n", const_index); break;
+  case Form::idealP: fprintf(fp,"  if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;
+  case Form::idealN: fprintf(fp,"  if (_c%d) _c%d->dump_on(st);\n", const_index, const_index); break;
+  case Form::idealL: fprintf(fp,"  st->print(\"#%%lld\", _c%d);\n", const_index); break;
+  case Form::idealF: fprintf(fp,"  st->print(\"#%%f\", _c%d);\n", const_index); break;
+  case Form::idealD: fprintf(fp,"  st->print(\"#%%f\", _c%d);\n", const_index); break;
   default:
     assert( false, "ShouldNotReachHere()");
   }
@@ -2813,17 +2863,8 @@
   fprintf(fp,"Component:");  // Write to output files
   fprintf(fp, "  name = %s", _name);
   fprintf(fp, ", type = %s", _type);
-  const char * usedef = "Undefined Use/Def info";
-  switch (_usedef) {
-    case USE:      usedef = "USE";      break;
-    case USE_DEF:  usedef = "USE_DEF";  break;
-    case USE_KILL: usedef = "USE_KILL"; break;
-    case KILL:     usedef = "KILL";     break;
-    case TEMP:     usedef = "TEMP";     break;
-    case DEF:      usedef = "DEF";      break;
-    default: assert(false, "unknown effect");
-  }
-  fprintf(fp, ", use/def = %s\n", usedef);
+  assert(_usedef != 0, "unknown effect");
+  fprintf(fp, ", use/def = %s\n", getUsedefName());
 }
 
 
@@ -2915,9 +2956,9 @@
   return count;
 }
 
-// Return zero-based position in list;  -1 if not in list.
+// Return zero-based position of operand 'name' in list;  -1 if not in list.
 // if parameter 'usedef' is ::USE, it will match USE, USE_DEF, ...
-int ComponentList::operand_position(const char *name, int usedef) {
+int ComponentList::operand_position(const char *name, int usedef, Form *fm) {
   PreserveIter pi(this);
   int position = 0;
   int num_opnds = num_operands();
@@ -2940,10 +2981,18 @@
         return position+1;
       } else {
         if( preceding_non_use && strcmp(component->_name, preceding_non_use->_name) ) {
-          fprintf(stderr, "the name '%s' should not precede the name '%s'\n", preceding_non_use->_name, name);
+          fprintf(stderr, "the name '%s(%s)' should not precede the name '%s(%s)'",
+                  preceding_non_use->_name, preceding_non_use->getUsedefName(),
+                  name, component->getUsedefName());
+          if (fm && fm->is_instruction()) fprintf(stderr,  "in form '%s'", fm->is_instruction()->_ident);
+          if (fm && fm->is_operand()) fprintf(stderr,  "in form '%s'", fm->is_operand()->_ident);
+          fprintf(stderr,  "\n");
         }
         if( position >= num_opnds ) {
-          fprintf(stderr, "the name '%s' is too late in its name list\n", name);
+          fprintf(stderr, "the name '%s' is too late in its name list", name);
+          if (fm && fm->is_instruction()) fprintf(stderr,  "in form '%s'", fm->is_instruction()->_ident);
+          if (fm && fm->is_operand()) fprintf(stderr,  "in form '%s'", fm->is_operand()->_ident);
+          fprintf(stderr,  "\n");
         }
         assert(position < num_opnds, "advertised index in bounds");
         return position;
@@ -2989,10 +3038,10 @@
   return Not_in_list;
 }
 
-int ComponentList::operand_position_format(const char *name) {
+int ComponentList::operand_position_format(const char *name, Form *fm) {
   PreserveIter pi(this);
   int  first_position = operand_position(name);
-  int  use_position   = operand_position(name, Component::USE);
+  int  use_position   = operand_position(name, Component::USE, fm);
 
   return ((first_position < use_position) ? use_position : first_position);
 }
@@ -3255,8 +3304,8 @@
 
   // If we are a "Set", start from the right child.
   const MatchNode *const mnode = sets_result() ?
-    (const MatchNode *const)this->_rChild :
-    (const MatchNode *const)this;
+    (const MatchNode *)this->_rChild :
+    (const MatchNode *)this;
 
   // If our right child exists, it is the right reduction
   if ( mnode->_rChild ) {
@@ -3273,8 +3322,8 @@
 
   // If we are a "Set", start from the right child.
   const MatchNode *const mnode = sets_result() ?
-    (const MatchNode *const)this->_rChild :
-    (const MatchNode *const)this;
+    (const MatchNode *)this->_rChild :
+    (const MatchNode *)this;
 
   // If our left child exists, it is the left reduction
   if ( mnode->_lChild ) {
@@ -3380,18 +3429,17 @@
   static const char *needs_ideal_memory_list[] = {
     "StoreI","StoreL","StoreP","StoreN","StoreD","StoreF" ,
     "StoreB","StoreC","Store" ,"StoreFP",
-    "LoadI", "LoadUI2L", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
-    "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load"   ,
-    "Store4I","Store2I","Store2L","Store2D","Store4F","Store2F","Store16B",
-    "Store8B","Store4B","Store8C","Store4C","Store2C",
-    "Load4I" ,"Load2I" ,"Load2L" ,"Load2D" ,"Load4F" ,"Load2F" ,"Load16B" ,
-    "Load8B" ,"Load4B" ,"Load8C" ,"Load4C" ,"Load2C" ,"Load8S", "Load4S","Load2S",
+    "LoadI", "LoadL", "LoadP" ,"LoadN", "LoadD" ,"LoadF"  ,
+    "LoadB" , "LoadUB", "LoadUS" ,"LoadS" ,"Load" ,
+    "StoreVector", "LoadVector",
     "LoadRange", "LoadKlass", "LoadNKlass", "LoadL_unaligned", "LoadD_unaligned",
-    "LoadPLocked", "LoadLLocked",
+    "LoadPLocked",
     "StorePConditional", "StoreIConditional", "StoreLConditional",
     "CompareAndSwapI", "CompareAndSwapL", "CompareAndSwapP", "CompareAndSwapN",
     "StoreCM",
-    "ClearArray"
+    "ClearArray",
+    "GetAndAddI", "GetAndSetI", "GetAndSetP",
+    "GetAndAddL", "GetAndSetL", "GetAndSetN",
   };
   int cnt = sizeof(needs_ideal_memory_list)/sizeof(char*);
   if( strcmp(_opType,"PrefetchRead")==0 ||
@@ -3822,6 +3870,10 @@
          strcmp(opType,"RegL")==0 ||
          strcmp(opType,"RegF")==0 ||
          strcmp(opType,"RegD")==0 ||
+         strcmp(opType,"VecS")==0 ||
+         strcmp(opType,"VecD")==0 ||
+         strcmp(opType,"VecX")==0 ||
+         strcmp(opType,"VecY")==0 ||
          strcmp(opType,"Reg" )==0) ) {
       return 1;
     }
@@ -3938,19 +3990,12 @@
         strcmp(opType,"ReverseBytesL")==0 ||
         strcmp(opType,"ReverseBytesUS")==0 ||
         strcmp(opType,"ReverseBytesS")==0 ||
-        strcmp(opType,"Replicate16B")==0 ||
-        strcmp(opType,"Replicate8B")==0 ||
-        strcmp(opType,"Replicate4B")==0 ||
-        strcmp(opType,"Replicate8C")==0 ||
-        strcmp(opType,"Replicate4C")==0 ||
-        strcmp(opType,"Replicate8S")==0 ||
-        strcmp(opType,"Replicate4S")==0 ||
-        strcmp(opType,"Replicate4I")==0 ||
-        strcmp(opType,"Replicate2I")==0 ||
-        strcmp(opType,"Replicate2L")==0 ||
-        strcmp(opType,"Replicate4F")==0 ||
-        strcmp(opType,"Replicate2F")==0 ||
-        strcmp(opType,"Replicate2D")==0 ||
+        strcmp(opType,"ReplicateB")==0 ||
+        strcmp(opType,"ReplicateS")==0 ||
+        strcmp(opType,"ReplicateI")==0 ||
+        strcmp(opType,"ReplicateL")==0 ||
+        strcmp(opType,"ReplicateF")==0 ||
+        strcmp(opType,"ReplicateD")==0 ||
         0 /* 0 to line up columns nicely */ )
       return 1;
   }
@@ -4034,6 +4079,33 @@
   return ideal_load;
 }
 
+bool MatchRule::is_vector() const {
+  static const char *vector_list[] = {
+    "AddVB","AddVS","AddVI","AddVL","AddVF","AddVD",
+    "SubVB","SubVS","SubVI","SubVL","SubVF","SubVD",
+    "MulVS","MulVI","MulVF","MulVD",
+    "DivVF","DivVD",
+    "AndV" ,"XorV" ,"OrV",
+    "LShiftCntV","RShiftCntV",
+    "LShiftVB","LShiftVS","LShiftVI","LShiftVL",
+    "RShiftVB","RShiftVS","RShiftVI","RShiftVL",
+    "URShiftVB","URShiftVS","URShiftVI","URShiftVL",
+    "ReplicateB","ReplicateS","ReplicateI","ReplicateL","ReplicateF","ReplicateD",
+    "LoadVector","StoreVector",
+    // Next are not supported currently.
+    "PackB","PackS","PackI","PackL","PackF","PackD","Pack2L","Pack2D",
+    "ExtractB","ExtractUB","ExtractC","ExtractS","ExtractI","ExtractL","ExtractF","ExtractD"
+  };
+  int cnt = sizeof(vector_list)/sizeof(char*);
+  if (_rChild) {
+    const char  *opType = _rChild->_opType;
+    for (int i=0; i<cnt; i++)
+      if (strcmp(opType,vector_list[i]) == 0)
+        return true;
+  }
+  return false;
+}
+
 
 bool MatchRule::skip_antidep_check() const {
   // Some loads operate on what is effectively immutable memory so we
@@ -4073,12 +4145,17 @@
   output(stderr);
 }
 
-void MatchRule::output(FILE *fp) {
+// Write just one line.
+void MatchRule::output_short(FILE *fp) {
   fprintf(fp,"MatchRule: ( %s",_name);
   if (_lChild) _lChild->output(fp);
   if (_rChild) _rChild->output(fp);
-  fprintf(fp," )\n");
-  fprintf(fp,"   nesting depth = %d\n", _depth);
+  fprintf(fp," )");
+}
+
+void MatchRule::output(FILE *fp) {
+  output_short(fp);
+  fprintf(fp,"\n   nesting depth = %d\n", _depth);
   if (_result) fprintf(fp,"   Result Type = %s", _result);
   fprintf(fp,"\n");
 }
diff --git a/hotspot/src/share/vm/adlc/formssel.hpp b/hotspot/src/share/vm/adlc/formssel.hpp
index b2d3ec7..6f2975f 100644
--- a/hotspot/src/share/vm/adlc/formssel.hpp
+++ b/hotspot/src/share/vm/adlc/formssel.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -76,7 +76,7 @@
 private:
   bool           _ideal_only;       // Not a user-defined instruction
   // Members used for tracking CISC-spilling
-  uint           _cisc_spill_operand;// Which operand may cisc-spill
+  int            _cisc_spill_operand;// Which operand may cisc-spill
   void           set_cisc_spill_operand(uint op_index) { _cisc_spill_operand = op_index; }
   bool           _is_cisc_alternate;
   InstructForm  *_cisc_spill_alternate;// cisc possible replacement
@@ -103,7 +103,7 @@
   RewriteRule   *_rewrule;         // Rewrite rule for this instruction
   FormatRule    *_format;          // Format for assembly generation
   Peephole      *_peephole;        // List of peephole rules for instruction
-  const char    *_ins_pipe;        // Instruction Scheduline description class
+  const char    *_ins_pipe;        // Instruction Scheduling description class
 
   uint          *_uniq_idx;        // Indexes of unique operands
   int            _uniq_idx_length; // Length of _uniq_idx array
@@ -160,6 +160,7 @@
   virtual bool        is_ideal_safepoint() const; // node matches 'SafePoint'
   virtual bool        is_ideal_nop() const;     // node matches 'Nop'
   virtual bool        is_ideal_control() const; // control node
+  virtual bool        is_vector() const;        // vector instruction
 
   virtual Form::CallType is_ideal_call() const; // matches ideal 'Call'
   virtual Form::DataType is_ideal_load() const; // node matches ideal 'LoadXNode'
@@ -197,6 +198,7 @@
 
   virtual const char *cost();      // Access ins_cost attribute
   virtual uint        num_opnds(); // Count of num_opnds for MachNode class
+                                   // Counts USE_DEF opnds twice.  See also num_unique_opnds().
   virtual uint        num_post_match_opnds();
   virtual uint        num_consts(FormDict &globals) const;// Constants in match rule
   // Constants in match rule with specified type
@@ -227,6 +229,7 @@
   // Return number of relocation entries needed for this instruction.
   virtual uint        reloc(FormDict &globals);
 
+  const char         *opnd_ident(int idx);  // Name of operand #idx.
   const char         *reduce_result();
   // Return the name of the operand on the right hand side of the binary match
   // Return NULL if there is no right hand side
@@ -239,7 +242,7 @@
   // Check if this instruction can cisc-spill to 'alternate'
   bool                cisc_spills_to(ArchDesc &AD, InstructForm *alternate);
   InstructForm       *cisc_spill_alternate() { return _cisc_spill_alternate; }
-  uint                cisc_spill_operand() const { return _cisc_spill_operand; }
+  int                 cisc_spill_operand() const { return _cisc_spill_operand; }
   bool                is_cisc_alternate() const { return _is_cisc_alternate; }
   void                set_cisc_alternate(bool val) { _is_cisc_alternate = val; }
   const char         *cisc_reg_mask_name() const { return _cisc_reg_mask_name; }
@@ -276,6 +279,7 @@
                           return idx;
                         }
   }
+  const char         *unique_opnd_ident(int idx);  // Name of operand at unique idx.
 
   // Operands which are only KILLs aren't part of the input array and
   // require special handling in some cases.  Their position in this
@@ -888,6 +892,7 @@
 
   void dump();                     // Debug printer
   void output(FILE *fp);           // Write to output files
+  const char* getUsedefName();
 
 public:
   // Implementation depends upon working bit intersection and union.
@@ -1011,6 +1016,7 @@
   bool       is_ideal_goto() const;    // node matches ideal 'Goto'
   bool       is_ideal_loopEnd() const; // node matches ideal 'LoopEnd'
   bool       is_ideal_bool() const;    // node matches ideal 'Bool'
+  bool       is_vector() const;        // vector instruction
   Form::DataType is_ideal_load() const;// node matches ideal 'LoadXNode'
   // Should antidep checks be disabled for this rule
   // See definition of MatchRule::skip_antidep_check
@@ -1028,6 +1034,7 @@
   void       matchrule_swap_commutative_op(const char* instr_ident, int count, int& match_rules_cnt);
 
   void dump();
+  void output_short(FILE *fp);
   void output(FILE *fp);
 };
 
diff --git a/hotspot/src/share/vm/adlc/main.cpp b/hotspot/src/share/vm/adlc/main.cpp
index 47e207a..bedfc20 100644
--- a/hotspot/src/share/vm/adlc/main.cpp
+++ b/hotspot/src/share/vm/adlc/main.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -250,6 +250,7 @@
   AD.addInclude(AD._HPP_file, "opto/node.hpp");
   AD.addInclude(AD._HPP_file, "opto/regalloc.hpp");
   AD.addInclude(AD._HPP_file, "opto/subnode.hpp");
+  AD.addInclude(AD._HPP_file, "opto/vectornode.hpp");
   AD.addInclude(AD._CPP_CLONE_file, "precompiled.hpp");
   AD.addInclude(AD._CPP_CLONE_file, "adfiles", get_basename(AD._HPP_file._name));
   AD.addInclude(AD._CPP_EXPAND_file, "precompiled.hpp");
@@ -340,14 +341,20 @@
 static void usage(ArchDesc& AD)
 {
   printf("Architecture Description Language Compiler\n\n");
-  printf("Usage: adl [-doqw] [-Dflag[=def]] [-Uflag] [-cFILENAME] [-hFILENAME] [-aDFAFILE] ADLFILE\n");
+  printf("Usage: adlc [-doqwTs] [-#]* [-D<FLAG>[=<DEF>]] [-U<FLAG>] [-c<CPP_FILE_NAME>] [-h<HPP_FILE_NAME>] [-a<DFA_FILE_NAME>] [-v<GLOBALS_FILE_NAME>] <ADL_FILE_NAME>\n");
   printf(" d  produce DFA debugging info\n");
   printf(" o  no output produced, syntax and semantic checking only\n");
   printf(" q  quiet mode, supresses all non-essential messages\n");
   printf(" w  suppress warning messages\n");
+  printf(" T  make DFA as many subroutine calls\n");
+  printf(" s  output which instructions are cisc-spillable\n");
+  printf(" D  define preprocessor symbol\n");
+  printf(" U  undefine preprocessor symbol\n");
   printf(" c  specify CPP file name (default: %s)\n", AD._CPP_file._name);
   printf(" h  specify HPP file name (default: %s)\n", AD._HPP_file._name);
   printf(" a  specify DFA output file name\n");
+  printf(" v  specify adGlobals output file name\n");
+  printf(" #  increment ADL debug level\n");
   printf("\n");
 }
 
@@ -449,22 +456,6 @@
   return fname;
 }
 
-//------------------------------strip_path_and_ext------------------------------
-static char *strip_path_and_ext(char *fname)
-{
-  char *ep;
-  char *sp;
-
-  if (fname) {
-    for (sp = fname; *sp; sp++)
-      if (*sp == '/')  fname = sp+1;
-    ep = fname;                    // start at first character and look for '.'
-    while (ep <= (fname + strlen(fname) - 1) && *ep != '.') ep++;
-    if (*ep == '.')     *ep = '\0'; // truncate string at '.'
-  }
-  return fname;
-}
-
 //------------------------------base_plus_suffix-------------------------------
 // New concatenated string
 static char *base_plus_suffix(const char* base, const char *suffix)
@@ -476,18 +467,6 @@
   return fname;
 }
 
-
-//------------------------------prefix_plus_base_plus_suffix-------------------
-// New concatenated string
-static char *prefix_plus_base_plus_suffix(const char* prefix, const char* base, const char *suffix)
-{
-  int len = (int)strlen(prefix) + (int)strlen(base) + (int)strlen(suffix) + 1;
-
-  char* fname = new char[len];
-  sprintf(fname,"%s%s%s",prefix,base,suffix);
-  return fname;
-}
-
 //------------------------------get_legal_text---------------------------------
 // Get pointer to legal text at the beginning of AD file.
 // This code assumes that a legal text starts at the beginning of .ad files,
diff --git a/hotspot/src/share/vm/adlc/output_c.cpp b/hotspot/src/share/vm/adlc/output_c.cpp
index c65a973..9644b71 100644
--- a/hotspot/src/share/vm/adlc/output_c.cpp
+++ b/hotspot/src/share/vm/adlc/output_c.cpp
@@ -518,6 +518,14 @@
 
     int cycles = piperesource->_cycles;
     uint stage          = pipeline->_stages.index(piperesource->_stage);
+    if (NameList::Not_in_list == stage) {
+      fprintf(stderr,
+              "pipeline_res_mask_initializer: "
+              "semantic error: "
+              "pipeline stage undeclared: %s\n",
+              piperesource->_stage);
+      exit(1);
+    }
     uint upper_limit    = stage+cycles-1;
     uint lower_limit    = stage-1;
     uint upper_idx      = upper_limit >> 5;
@@ -1000,7 +1008,7 @@
   }
   fprintf(fp_cpp, "};\n\n");
   fprintf(fp_cpp, "#ifndef PRODUCT\n");
-  fprintf(fp_cpp, "void Bundle::dump() const {\n");
+  fprintf(fp_cpp, "void Bundle::dump(outputStream *st) const {\n");
   fprintf(fp_cpp, "  static const char * bundle_flags[] = {\n");
   fprintf(fp_cpp, "    \"\",\n");
   fprintf(fp_cpp, "    \"use nop delay\",\n");
@@ -1019,22 +1027,22 @@
   // See if the same string is in the table
   fprintf(fp_cpp, "  bool needs_comma = false;\n\n");
   fprintf(fp_cpp, "  if (_flags) {\n");
-  fprintf(fp_cpp, "    tty->print(\"%%s\", bundle_flags[_flags]);\n");
+  fprintf(fp_cpp, "    st->print(\"%%s\", bundle_flags[_flags]);\n");
   fprintf(fp_cpp, "    needs_comma = true;\n");
   fprintf(fp_cpp, "  };\n");
   fprintf(fp_cpp, "  if (instr_count()) {\n");
-  fprintf(fp_cpp, "    tty->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n");
+  fprintf(fp_cpp, "    st->print(\"%%s%%d instr%%s\", needs_comma ? \", \" : \"\", instr_count(), instr_count() != 1 ? \"s\" : \"\");\n");
   fprintf(fp_cpp, "    needs_comma = true;\n");
   fprintf(fp_cpp, "  };\n");
   fprintf(fp_cpp, "  uint r = resources_used();\n");
   fprintf(fp_cpp, "  if (r) {\n");
-  fprintf(fp_cpp, "    tty->print(\"%%sresource%%s:\", needs_comma ? \", \" : \"\", (r & (r-1)) != 0 ? \"s\" : \"\");\n");
+  fprintf(fp_cpp, "    st->print(\"%%sresource%%s:\", needs_comma ? \", \" : \"\", (r & (r-1)) != 0 ? \"s\" : \"\");\n");
   fprintf(fp_cpp, "    for (uint i = 0; i < %d; i++)\n", _pipeline->_rescount);
   fprintf(fp_cpp, "      if ((r & (1 << i)) != 0)\n");
-  fprintf(fp_cpp, "        tty->print(\" %%s\", resource_names[i]);\n");
+  fprintf(fp_cpp, "        st->print(\" %%s\", resource_names[i]);\n");
   fprintf(fp_cpp, "    needs_comma = true;\n");
   fprintf(fp_cpp, "  };\n");
-  fprintf(fp_cpp, "  tty->print(\"\\n\");\n");
+  fprintf(fp_cpp, "  st->print(\"\\n\");\n");
   fprintf(fp_cpp, "}\n");
   fprintf(fp_cpp, "#endif\n");
 }
@@ -1048,39 +1056,6 @@
           node, regMask);
 }
 
-// Scan the peepmatch and output a test for each instruction
-static void check_peepmatch_instruction_tree(FILE *fp, PeepMatch *pmatch, PeepConstraint *pconstraint) {
-  int         parent        = -1;
-  int         inst_position = 0;
-  const char* inst_name     = NULL;
-  int         input         = 0;
-  fprintf(fp, "      // Check instruction sub-tree\n");
-  pmatch->reset();
-  for( pmatch->next_instruction( parent, inst_position, inst_name, input );
-       inst_name != NULL;
-       pmatch->next_instruction( parent, inst_position, inst_name, input ) ) {
-    // If this is not a placeholder
-    if( ! pmatch->is_placeholder() ) {
-      // Define temporaries 'inst#', based on parent and parent's input index
-      if( parent != -1 ) {                // root was initialized
-        fprintf(fp, "  inst%d = inst%d->in(%d);\n",
-                inst_position, parent, input);
-      }
-
-      // When not the root
-      // Test we have the correct instruction by comparing the rule
-      if( parent != -1 ) {
-        fprintf(fp, "  matches = matches &&  ( inst%d->rule() == %s_rule );",
-                inst_position, inst_name);
-      }
-    } else {
-      // Check that user did not try to constrain a placeholder
-      assert( ! pconstraint->constrains_instruction(inst_position),
-              "fatal(): Can not constrain a placeholder instruction");
-    }
-  }
-}
-
 static void print_block_index(FILE *fp, int inst_position) {
   assert( inst_position >= 0, "Instruction number less than zero");
   fprintf(fp, "block_index");
@@ -1242,7 +1217,7 @@
         if( left_op_index != 0 ) {
           assert( (left_index <= 9999) && (left_op_index <= 9999), "exceed string size");
           // Must have index into operands
-          sprintf(left_reg_index,",inst%d_idx%d", left_index, left_op_index);
+          sprintf(left_reg_index,",inst%d_idx%d", (int)left_index, left_op_index);
         } else {
           strcpy(left_reg_index, "");
         }
@@ -1255,7 +1230,7 @@
           if( right_op_index != 0 ) {
             assert( (right_index <= 9999) && (right_op_index <= 9999), "exceed string size");
             // Must have index into operands
-            sprintf(right_reg_index,",inst%d_idx%d", right_index, right_op_index);
+            sprintf(right_reg_index,",inst%d_idx%d", (int)right_index, right_op_index);
           } else {
             strcpy(right_reg_index, "");
           }
@@ -1606,6 +1581,12 @@
         fprintf(fp, "  ((MachFastLockNode*)n%d)->_counters = _counters;\n",cnt);
       }
 
+      // Fill in the bottom_type where requested
+      if (node->captures_bottom_type(_globalNames) &&
+          new_inst->captures_bottom_type(_globalNames)) {
+        fprintf(fp, "  ((MachTypeNode*)n%d)->_bottom_type = bottom_type();\n", cnt);
+      }
+
       const char *resultOper = new_inst->reduce_result();
       fprintf(fp,"  n%d->set_opnd_array(0, state->MachOperGenerator( %s, C ));\n",
               cnt, machOperEnum(resultOper));
@@ -1639,7 +1620,7 @@
           new_pos = new_inst->operand_position(parameter,Component::USE);
           exp_pos += node->num_opnds();
           // If there is no use of the created operand, just skip it
-          if (new_pos != -1) {
+          if (new_pos != NameList::Not_in_list) {
             //Copy the operand from the original made above
             fprintf(fp,"  n%d->set_opnd_array(%d, op%d->clone(C)); // %s\n",
                     cnt, new_pos, exp_pos-node->num_opnds(), opid);
@@ -1767,7 +1748,7 @@
         }
 
         fprintf(fp,"  kill = ");
-        fprintf(fp,"new (C, 1) MachProjNode( %s, %d, (%s), Op_%s );\n",
+        fprintf(fp,"new (C) MachProjNode( %s, %d, (%s), Op_%s );\n",
                 machNode, proj_no++, regmask, ideal_type);
         fprintf(fp,"  proj_list.push(kill);\n");
       }
@@ -1783,7 +1764,8 @@
       // Build mapping from num_edges to local variables
       fprintf(fp,"  unsigned num0 = 0;\n");
       for( i = 1; i < cur_num_opnds; i++ ) {
-        fprintf(fp,"  unsigned num%d = opnd_array(%d)->num_edges();\n",i,i);
+        fprintf(fp,"  unsigned num%d = opnd_array(%d)->num_edges();",i,i);
+        fprintf(fp, " \t// %s\n", node->opnd_ident(i));
       }
       // Build a mapping from operand index to input edges
       fprintf(fp,"  unsigned idx0 = oper_input_base();\n");
@@ -1930,6 +1912,7 @@
   }
 
   // Track necessary state when identifying a replacement variable
+  // @arg rep_var: The formal parameter of the encoding.
   void update_state(const char *rep_var) {
     // A replacement variable or one of its subfields
     // Obtain replacement variable from list
@@ -1951,7 +1934,7 @@
         }
       }
       else {
-        // Lookup its position in parameter list
+        // Lookup its position in (formal) parameter list of encoding
         int   param_no  = _encoding.rep_var_index(rep_var);
         if ( param_no == -1 ) {
           _AD.syntax_err( _encoding._linenum,
@@ -1960,6 +1943,7 @@
         }
 
         // Lookup the corresponding ins_encode parameter
+        // This is the argument (actual parameter) to the encoding.
         const char *inst_rep_var = _ins_encode.rep_var_name(_inst, param_no);
         if (inst_rep_var == NULL) {
           _AD.syntax_err( _ins_encode._linenum,
@@ -2332,6 +2316,7 @@
           // Add parameter for index position, if not result operand
           if( _operand_idx != 0 ) fprintf(_fp,",idx%d", _operand_idx);
           fprintf(_fp,")");
+          fprintf(_fp, "/* %s */", _operand_name);
         }
       } else {
         assert( _reg_status == LITERAL_OUTPUT, "should have output register literal in emit_rep_var");
@@ -2371,7 +2356,7 @@
         }
       } else {
         assert( _constant_status == LITERAL_OUTPUT, "should have output constant literal in emit_rep_var");
-        // Cosntant literal has already been sent to output file, nothing more needed
+        // Constant literal has already been sent to output file, nothing more needed
       }
     }
     else if ( strcmp(rep_var,"$disp") == 0 ) {
@@ -2390,6 +2375,8 @@
     }
     else {
       printf("emit_field: %s\n",rep_var);
+      globalAD->syntax_err(_inst._linenum, "Unknown replacement variable %s in format statement of %s.",
+                           rep_var, _inst._ident);
       assert( false, "UnImplemented()");
     }
   }
@@ -2487,14 +2474,14 @@
 
   //(1)
   // Output instruction's emit prototype
-  fprintf(fp,"uint  %sNode::size(PhaseRegAlloc *ra_) const {\n",
+  fprintf(fp,"uint %sNode::size(PhaseRegAlloc *ra_) const {\n",
           inst._ident);
 
-  fprintf(fp, " assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
+  fprintf(fp, "  assert(VerifyOops || MachNode::size(ra_) <= %s, \"bad fixed size\");\n", inst._size);
 
   //(2)
   // Print the size
-  fprintf(fp, " return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
+  fprintf(fp, "  return (VerifyOops ? MachNode::size(ra_) : %s);\n", inst._size);
 
   // (3) and (4)
   fprintf(fp,"}\n");
@@ -2582,7 +2569,7 @@
   }
 
   // (3) and (4)
-  fprintf(fp, "}\n");
+  fprintf(fp, "}\n\n");
 }
 
 // defineEvalConstant ---------------------------------------------------------
@@ -2730,12 +2717,12 @@
 // (2)  }
 //
 static void defineClone(FILE *fp, FormDict &globalNames, OperandForm &oper) {
-  fprintf(fp,"MachOper  *%sOper::clone(Compile* C) const {\n", oper._ident);
+  fprintf(fp,"MachOper *%sOper::clone(Compile* C) const {\n", oper._ident);
   // Check for constants that need to be copied over
   const int  num_consts    = oper.num_consts(globalNames);
   const bool is_ideal_bool = oper.is_ideal_bool();
   if( (num_consts > 0) ) {
-    fprintf(fp,"  return  new (C) %sOper(", oper._ident);
+    fprintf(fp,"  return new (C) %sOper(", oper._ident);
     // generate parameters for constants
     int i = 0;
     fprintf(fp,"_c%d", i);
@@ -2747,21 +2734,12 @@
   }
   else {
     assert( num_consts == 0, "Currently support zero or one constant per operand clone function");
-    fprintf(fp,"  return  new (C) %sOper();\n", oper._ident);
+    fprintf(fp,"  return new (C) %sOper();\n", oper._ident);
   }
   // finish method
   fprintf(fp,"}\n");
 }
 
-static void define_hash(FILE *fp, char *operand) {
-  fprintf(fp,"uint %sOper::hash() const { return 5; }\n", operand);
-}
-
-static void define_cmp(FILE *fp, char *operand) {
-  fprintf(fp,"uint %sOper::cmp( const MachOper &oper ) const { return opcode() == oper.opcode(); }\n", operand);
-}
-
-
 // Helper functions for bug 4796752, abstracted with minimal modification
 // from define_oper_interface()
 OperandForm *rep_var_to_operand(const char *encoding, OperandForm &oper, FormDict &globals) {
@@ -2855,14 +2833,14 @@
   } else if ( (strcmp(name,"disp") == 0) ) {
     fprintf(fp,"(PhaseRegAlloc *ra_, const Node *node, int idx) const { \n");
   } else {
-    fprintf(fp,"() const { ");
+    fprintf(fp,"() const { \n");
   }
 
   // Check for hexadecimal value OR replacement variable
   if( *encoding == '$' ) {
     // Replacement variable
     const char *rep_var = encoding + 1;
-    fprintf(fp,"// Replacement variable: %s\n", encoding+1);
+    fprintf(fp,"    // Replacement variable: %s\n", encoding+1);
     // Lookup replacement variable, rep_var, in operand's component list
     const Component *comp = oper._components.search(rep_var);
     assert( comp != NULL, "Replacement variable not found in components");
@@ -2883,10 +2861,10 @@
     } else if ( op->ideal_to_sReg_type(op->_ident) != Form::none ) {
       // StackSlot for an sReg comes either from input node or from self, when idx==0
       fprintf(fp,"    if( idx != 0 ) {\n");
-      fprintf(fp,"      // Access register number for input operand\n");
+      fprintf(fp,"      // Access stack offset (register number) for input operand\n");
       fprintf(fp,"      return ra_->reg2offset(ra_->get_reg_first(node->in(idx)));/* sReg */\n");
       fprintf(fp,"    }\n");
-      fprintf(fp,"    // Access register number from myself\n");
+      fprintf(fp,"    // Access stack offset (register number) from myself\n");
       fprintf(fp,"    return ra_->reg2offset(ra_->get_reg_first(node));/* sReg */\n");
     } else if (op->_matrule && op->_matrule->is_base_constant(globals)) {
       // Constant
@@ -2903,7 +2881,7 @@
   }
   else if( *encoding == '0' && *(encoding+1) == 'x' ) {
     // Hex value
-    fprintf(fp,"return %s;", encoding);
+    fprintf(fp,"    return %s;\n", encoding);
   } else {
     assert( false, "Do not support octal or decimal encode constants");
   }
@@ -3136,8 +3114,8 @@
     // Output the definition for number of relocation entries
     uint reloc_size = instr->reloc(_globalNames);
     if ( reloc_size != 0 ) {
-      fprintf(fp,"int  %sNode::reloc()   const {\n", instr->_ident);
-      fprintf(fp,  "  return  %d;\n", reloc_size );
+      fprintf(fp,"int %sNode::reloc() const {\n", instr->_ident);
+      fprintf(fp,"  return %d;\n", reloc_size);
       fprintf(fp,"}\n");
       fprintf(fp,"\n");
     }
@@ -3244,7 +3222,7 @@
 class OutputReduceOp : public OutputMap {
 public:
   OutputReduceOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
-    : OutputMap(hpp, cpp, globals, AD) {};
+    : OutputMap(hpp, cpp, globals, AD, "reduceOp") {};
 
   void declaration() { fprintf(_hpp, "extern const int   reduceOp[];\n"); }
   void definition()  { fprintf(_cpp, "const        int   reduceOp[] = {\n"); }
@@ -3279,7 +3257,7 @@
 class OutputLeftOp : public OutputMap {
 public:
   OutputLeftOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
-    : OutputMap(hpp, cpp, globals, AD) {};
+    : OutputMap(hpp, cpp, globals, AD, "leftOp") {};
 
   void declaration() { fprintf(_hpp, "extern const int   leftOp[];\n"); }
   void definition()  { fprintf(_cpp, "const        int   leftOp[] = {\n"); }
@@ -3309,7 +3287,7 @@
 class OutputRightOp : public OutputMap {
 public:
   OutputRightOp(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
-    : OutputMap(hpp, cpp, globals, AD) {};
+    : OutputMap(hpp, cpp, globals, AD, "rightOp") {};
 
   void declaration() { fprintf(_hpp, "extern const int   rightOp[];\n"); }
   void definition()  { fprintf(_cpp, "const        int   rightOp[] = {\n"); }
@@ -3339,11 +3317,11 @@
 class OutputRuleName : public OutputMap {
 public:
   OutputRuleName(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
-    : OutputMap(hpp, cpp, globals, AD) {};
+    : OutputMap(hpp, cpp, globals, AD, "ruleName") {};
 
   void declaration() { fprintf(_hpp, "extern const char *ruleName[];\n"); }
   void definition()  { fprintf(_cpp, "const char        *ruleName[] = {\n"); }
-  void closing()     { fprintf(_cpp, "  \"no trailing comma\"\n");
+  void closing()     { fprintf(_cpp, "  \"invalid rule name\" // no trailing comma\n");
                        OutputMap::closing();
   }
   void map(OpClassForm &opc)  { fprintf(_cpp, "  \"%s\"", _AD.machOperEnum(opc._ident) ); }
@@ -3357,7 +3335,7 @@
 class OutputSwallowed : public OutputMap {
 public:
   OutputSwallowed(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
-    : OutputMap(hpp, cpp, globals, AD) {};
+    : OutputMap(hpp, cpp, globals, AD, "swallowed") {};
 
   void declaration() { fprintf(_hpp, "extern const bool  swallowed[];\n"); }
   void definition()  { fprintf(_cpp, "const        bool  swallowed[] = {\n"); }
@@ -3378,7 +3356,7 @@
 class OutputInstChainRule : public OutputMap {
 public:
   OutputInstChainRule(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
-    : OutputMap(hpp, cpp, globals, AD) {};
+    : OutputMap(hpp, cpp, globals, AD, "instruction_chain_rule") {};
 
   void declaration() { fprintf(_hpp, "extern const bool  instruction_chain_rule[];\n"); }
   void definition()  { fprintf(_cpp, "const        bool  instruction_chain_rule[] = {\n"); }
@@ -3419,7 +3397,7 @@
     if ( op->ideal_only() )  continue;
 
     // Generate the entry for this opcode
-    map.map(*op);    fprintf(fp_cpp, ", // %d\n", idx);
+    fprintf(fp_cpp, "  /* %4d */", idx); map.map(*op); fprintf(fp_cpp, ",\n");
     ++idx;
   };
   fprintf(fp_cpp, "  // last operand\n");
@@ -3428,7 +3406,7 @@
   map.record_position(OutputMap::BEGIN_OPCLASSES, idx );
   _opclass.reset();
   for(; (opc = (OpClassForm*)_opclass.iter()) != NULL; ) {
-    map.map(*opc);    fprintf(fp_cpp, ", // %d\n", idx);
+    fprintf(fp_cpp, "  /* %4d */", idx); map.map(*opc); fprintf(fp_cpp, ",\n");
     ++idx;
   };
   fprintf(fp_cpp, "  // last operand class\n");
@@ -3438,7 +3416,7 @@
   _internalOpNames.reset();
   char *name = NULL;
   for(; (name = (char *)_internalOpNames.iter()) != NULL; ) {
-    map.map(name);    fprintf(fp_cpp, ", // %d\n", idx);
+    fprintf(fp_cpp, "  /* %4d */", idx); map.map(name); fprintf(fp_cpp, ",\n");
     ++idx;
   };
   fprintf(fp_cpp, "  // last internally defined operand\n");
@@ -3456,7 +3434,7 @@
         if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
         if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
 
-        map.map(*inst);      fprintf(fp_cpp, ", // %d\n", idx);
+        fprintf(fp_cpp, "  /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
         ++idx;
       };
       map.record_position(OutputMap::BEGIN_REMATERIALIZE, idx );
@@ -3467,7 +3445,7 @@
         if ( ! inst->is_simple_chain_rule(_globalNames) ) continue;
         if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
 
-        map.map(*inst);      fprintf(fp_cpp, ", // %d\n", idx);
+        fprintf(fp_cpp, "  /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
         ++idx;
       };
       map.record_position(OutputMap::END_INST_CHAIN_RULES, idx );
@@ -3481,7 +3459,7 @@
         if ( inst->is_simple_chain_rule(_globalNames) ) continue;
         if ( ! inst->rematerialize(_globalNames, get_registers()) ) continue;
 
-        map.map(*inst);      fprintf(fp_cpp, ", // %d\n", idx);
+        fprintf(fp_cpp, "  /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
         ++idx;
       };
       map.record_position(OutputMap::END_REMATERIALIZE, idx );
@@ -3492,7 +3470,7 @@
         if ( inst->is_simple_chain_rule(_globalNames) ) continue;
         if ( inst->rematerialize(_globalNames, get_registers()) ) continue;
 
-        map.map(*inst);      fprintf(fp_cpp, ", // %d\n", idx);
+        fprintf(fp_cpp, "  /* %4d */", idx); map.map(*inst); fprintf(fp_cpp, ",\n");
         ++idx;
       };
     }
@@ -3574,7 +3552,7 @@
     next              = _register->iter_RegDefs();
     char policy       = reg_save_policy(rdef->_callconv);
     const char *comma = (next != NULL) ? "," : " // no trailing comma";
-    fprintf(fp_cpp, "  '%c'%s\n", policy, comma);
+    fprintf(fp_cpp, "  '%c'%s // %s\n", policy, comma, rdef->_regname);
   }
   fprintf(fp_cpp, "};\n\n");
 
@@ -3586,7 +3564,7 @@
     next        = _register->iter_RegDefs();
     char policy = reg_save_policy(rdef->_c_conv);
     const char *comma = (next != NULL) ? "," : " // no trailing comma";
-    fprintf(fp_cpp, "  '%c'%s\n", policy, comma);
+    fprintf(fp_cpp, "  '%c'%s // %s\n", policy, comma, rdef->_regname);
   }
   fprintf(fp_cpp, "};\n\n");
 
@@ -3795,7 +3773,7 @@
       // For each operand not in the match rule, call MachOperGenerator
       // with the enum for the opcode that needs to be built.
       ComponentList clist = inst->_components;
-      int         index  = clist.operand_position(comp->_name, comp->_usedef);
+      int         index  = clist.operand_position(comp->_name, comp->_usedef, inst);
       const char *opcode = machOperEnum(comp->_type);
       fprintf(fp_cpp, "%s node->set_opnd_array(%d, ", indent, index);
       fprintf(fp_cpp, "MachOperGenerator(%s, C));\n", opcode);
@@ -3990,7 +3968,7 @@
     fprintf(fp_cpp, "  case %s_rule:", opClass);
 
     // Start local scope
-    fprintf(fp_cpp, "  {\n");
+    fprintf(fp_cpp, " {\n");
     // Generate code to construct the new MachNode
     buildMachNode(fp_cpp, inst, "     ");
     // Return result and exit scope
@@ -4140,6 +4118,9 @@
 // Get info for the CISC_oracle and MachNode::cisc_version()
 void ArchDesc::identify_cisc_spill_instructions() {
 
+  if (_frame == NULL)
+    return;
+
   // Find the user-defined operand for cisc-spilling
   if( _frame->_cisc_spilling_operand_name != NULL ) {
     const Form *form = _globalNames[_frame->_cisc_spilling_operand_name];
diff --git a/hotspot/src/share/vm/adlc/output_h.cpp b/hotspot/src/share/vm/adlc/output_h.cpp
index ea066eb..070c7df 100644
--- a/hotspot/src/share/vm/adlc/output_h.cpp
+++ b/hotspot/src/share/vm/adlc/output_h.cpp
@@ -25,6 +25,8 @@
 // output_h.cpp - Class HPP file output routines for architecture definition
 #include "adlc.hpp"
 
+// The comment delimiter used in format statements after assembler instructions.
+#define commentSeperator "!"
 
 // Generate the #define that describes the number of registers.
 static void defineRegCount(FILE *fp, RegisterForm *registers) {
@@ -79,10 +81,15 @@
     _register->reset_RegDefs();
     int i = 0;
     while( (reg_def = _register->iter_RegDefs()) != NULL ) {
-      fprintf(fp_hpp,"  %s_num,\t\t// %d\n", reg_def->_regname, i++);
+      fprintf(fp_hpp,"  %s_num,", reg_def->_regname);
+      for (int j = 0; j < 20-(int)strlen(reg_def->_regname); j++) fprintf(fp_hpp, " ");
+      fprintf(fp_hpp," // enum %3d, regnum %3d, reg encode %3s\n",
+              i++,
+              reg_def->register_num(),
+              reg_def->register_encode());
     }
     // Finish defining enumeration
-    fprintf(fp_hpp, "  _last_Mach_Reg\t// %d\n", i);
+    fprintf(fp_hpp, "  _last_Mach_Reg            // %d\n", i);
     fprintf(fp_hpp, "};\n");
   }
 
@@ -121,13 +128,24 @@
     fprintf(fp_hpp, "// in the order of occurrence in the alloc_class(es).\n");
     fprintf(fp_hpp, "enum MachRegisterEncodes {\n");
 
+    // Find max enum string length.
+    size_t maxlen = 0;
+    _register->reset_RegDefs();
+    reg_def = _register->iter_RegDefs();
+    while (reg_def != NULL) {
+      size_t len = strlen(reg_def->_regname);
+      if (len > maxlen) maxlen = len;
+      reg_def = _register->iter_RegDefs();
+    }
+
     // Output the register encoding for each register in the allocation classes
     _register->reset_RegDefs();
     reg_def_next = _register->iter_RegDefs();
     while( (reg_def = reg_def_next) != NULL ) {
       reg_def_next = _register->iter_RegDefs();
-      fprintf(fp_hpp,"  %s_enc = %s%s\n",
-              reg_def->_regname, reg_def->register_encode(), reg_def_next == NULL? "" : "," );
+      fprintf(fp_hpp,"  %s_enc", reg_def->_regname);
+      for (size_t i = strlen(reg_def->_regname); i < maxlen; i++) fprintf(fp_hpp, " ");
+      fprintf(fp_hpp," = %3s%s\n", reg_def->register_encode(), reg_def_next == NULL? "" : "," );
     }
     // Finish defining enumeration
     fprintf(fp_hpp, "};\n");
@@ -177,14 +195,6 @@
   fprintf(fp,"  virtual const RegMask *in_RegMask(int index) const;\n");
 }
 
-static void declare_hash(FILE *fp) {
-  fprintf(fp,"  virtual uint           hash() const;\n");
-}
-
-static void declare_cmp(FILE *fp) {
-  fprintf(fp,"  virtual uint           cmp( const MachOper &oper ) const;\n");
-}
-
 static void declareConstStorage(FILE *fp, FormDict &globals, OperandForm *oper) {
   int i = 0;
   Component *comp;
@@ -358,18 +368,19 @@
 static void defineCCodeDump(OperandForm* oper, FILE *fp, int i) {
   assert(oper != NULL, "what");
   CondInterface* cond = oper->_interface->is_CondInterface();
-  fprintf(fp, "         if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
-  fprintf(fp, "    else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
-  fprintf(fp, "    else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
-  fprintf(fp, "    else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
-  fprintf(fp, "    else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
-  fprintf(fp, "    else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
+  fprintf(fp, "       if( _c%d == BoolTest::eq ) st->print(\"%s\");\n",i,cond->_equal_format);
+  fprintf(fp, "  else if( _c%d == BoolTest::ne ) st->print(\"%s\");\n",i,cond->_not_equal_format);
+  fprintf(fp, "  else if( _c%d == BoolTest::le ) st->print(\"%s\");\n",i,cond->_less_equal_format);
+  fprintf(fp, "  else if( _c%d == BoolTest::ge ) st->print(\"%s\");\n",i,cond->_greater_equal_format);
+  fprintf(fp, "  else if( _c%d == BoolTest::lt ) st->print(\"%s\");\n",i,cond->_less_format);
+  fprintf(fp, "  else if( _c%d == BoolTest::gt ) st->print(\"%s\");\n",i,cond->_greater_format);
 }
 
 // Output code that dumps constant values, increment "i" if type is constant
 static uint dump_spec_constant(FILE *fp, const char *ideal_type, uint i, OperandForm* oper) {
   if (!strcmp(ideal_type, "ConI")) {
     fprintf(fp,"   st->print(\"#%%d\", _c%d);\n", i);
+    fprintf(fp,"   st->print(\"/0x%%08x\", _c%d);\n", i);
     ++i;
   }
   else if (!strcmp(ideal_type, "ConP")) {
@@ -382,14 +393,19 @@
   }
   else if (!strcmp(ideal_type, "ConL")) {
     fprintf(fp,"    st->print(\"#\" INT64_FORMAT, _c%d);\n", i);
+    fprintf(fp,"    st->print(\"/\" PTR64_FORMAT, _c%d);\n", i);
     ++i;
   }
   else if (!strcmp(ideal_type, "ConF")) {
     fprintf(fp,"    st->print(\"#%%f\", _c%d);\n", i);
+    fprintf(fp,"    jint _c%di = JavaValue(_c%d).get_jint();\n", i, i);
+    fprintf(fp,"    st->print(\"/0x%%x/\", _c%di);\n", i);
     ++i;
   }
   else if (!strcmp(ideal_type, "ConD")) {
     fprintf(fp,"    st->print(\"#%%f\", _c%d);\n", i);
+    fprintf(fp,"    jlong _c%dl = JavaValue(_c%d).get_jlong();\n", i, i);
+    fprintf(fp,"    st->print(\"/\" PTR64_FORMAT, _c%dl);\n", i);
     ++i;
   }
   else if (!strcmp(ideal_type, "Bool")) {
@@ -411,7 +427,7 @@
   }
 
   // Local pointer indicates remaining part of format rule
-  uint  idx = 0;                   // position of operand in match rule
+  int idx = 0;                   // position of operand in match rule
 
   // Generate internal format function, used when stored locally
   fprintf(fp, "\n#ifndef PRODUCT\n");
@@ -426,13 +442,12 @@
       oper._format->_rep_vars.reset();
       oper._format->_strings.reset();
       while ( (string = oper._format->_strings.iter()) != NULL ) {
-        fprintf(fp,"  ");
 
         // Check if this is a standard string or a replacement variable
         if ( string != NameList::_signal ) {
           // Normal string
           // Pass through to st->print
-          fprintf(fp,"st->print(\"%s\");\n", string);
+          fprintf(fp,"  st->print(\"%s\");\n", string);
         } else {
           // Replacement variable
           const char *rep_var = oper._format->_rep_vars.iter();
@@ -455,7 +470,7 @@
           }
 
           // output invocation of "$..."s format function
-          if ( op != NULL )   op->int_format(fp, globals, idx);
+          if ( op != NULL ) op->int_format(fp, globals, idx);
 
           if ( idx == -1 ) {
             fprintf(stderr,
@@ -498,13 +513,12 @@
       oper._format->_rep_vars.reset();
       oper._format->_strings.reset();
       while ( (string = oper._format->_strings.iter()) != NULL ) {
-        fprintf(fp,"  ");
 
         // Check if this is a standard string or a replacement variable
         if ( string != NameList::_signal ) {
           // Normal string
           // Pass through to st->print
-          fprintf(fp,"st->print(\"%s\");\n", string);
+          fprintf(fp,"  st->print(\"%s\");\n", string);
         } else {
           // Replacement variable
           const char *rep_var = oper._format->_rep_vars.iter();
@@ -529,7 +543,7 @@
           if ( op != NULL )   op->ext_format(fp, globals, idx);
 
           // Lookup the index position of the replacement variable
-          idx      = oper._components.operand_position_format(rep_var);
+          idx      = oper._components.operand_position_format(rep_var, &oper);
           if ( idx == -1 ) {
             fprintf(stderr,
                     "Using a name, %s, that isn't in match rule\n", rep_var);
@@ -583,7 +597,7 @@
     inst._format->_rep_vars.reset();
     inst._format->_strings.reset();
     while( (string = inst._format->_strings.iter()) != NULL ) {
-      fprintf(fp,"    ");
+      fprintf(fp,"  ");
       // Check if this is a standard string or a replacement variable
       if( string == NameList::_signal ) { // Replacement variable
         const char* rep_var =  inst._format->_rep_vars.iter();
@@ -640,11 +654,12 @@
   if( call_type != Form::invalid_type ) {
     switch( call_type ) {
     case Form::JAVA_DYNAMIC:
-      fprintf(fp,"    _method->print_short_name();\n");
+      fprintf(fp,"  _method->print_short_name(st);\n");
       break;
     case Form::JAVA_STATIC:
-      fprintf(fp,"    if( _method ) _method->print_short_name(st); else st->print(\" wrapper for: %%s\", _name);\n");
-      fprintf(fp,"    if( !_method ) dump_trap_args(st);\n");
+      fprintf(fp,"  if( _method ) _method->print_short_name(st);\n");
+      fprintf(fp,"  else st->print(\" wrapper for: %%s\", _name);\n");
+      fprintf(fp,"  if( !_method ) dump_trap_args(st);\n");
       break;
     case Form::JAVA_COMPILED:
     case Form::JAVA_INTERP:
@@ -652,49 +667,46 @@
     case Form::JAVA_RUNTIME:
     case Form::JAVA_LEAF:
     case Form::JAVA_NATIVE:
-      fprintf(fp,"    st->print(\" %%s\", _name);");
+      fprintf(fp,"  st->print(\" %%s\", _name);");
       break;
     default:
-      assert(0,"ShouldNotReacHere");
+      assert(0,"ShouldNotReachHere");
     }
-    fprintf(fp,  "    st->print_cr(\"\");\n" );
-    fprintf(fp,  "    if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\"        No JVM State Info\");\n" );
-    fprintf(fp,  "    st->print(\"        # \");\n" );
-    fprintf(fp,  "    if( _jvms ) _oop_map->print_on(st);\n");
+    fprintf(fp,  "  st->print_cr(\"\");\n" );
+    fprintf(fp,  "  if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\"        No JVM State Info\");\n" );
+    fprintf(fp,  "  st->print(\"        # \");\n" );
+    fprintf(fp,  "  if( _jvms && _oop_map ) _oop_map->print_on(st);\n");
   }
   else if(inst.is_ideal_safepoint()) {
-    fprintf(fp,  "    st->print(\"\");\n" );
-    fprintf(fp,  "    if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\"        No JVM State Info\");\n" );
-    fprintf(fp,  "    st->print(\"        # \");\n" );
-    fprintf(fp,  "    if( _jvms ) _oop_map->print_on(st);\n");
+    fprintf(fp,  "  st->print(\"\");\n" );
+    fprintf(fp,  "  if (_jvms) _jvms->format(ra, this, st); else st->print_cr(\"        No JVM State Info\");\n" );
+    fprintf(fp,  "  st->print(\"        # \");\n" );
+    fprintf(fp,  "  if( _jvms && _oop_map ) _oop_map->print_on(st);\n");
   }
   else if( inst.is_ideal_if() ) {
-    fprintf(fp,  "    st->print(\"  P=%%f C=%%f\",_prob,_fcnt);\n" );
+    fprintf(fp,  "  st->print(\"  P=%%f C=%%f\",_prob,_fcnt);\n" );
   }
   else if( inst.is_ideal_mem() ) {
     // Print out the field name if available to improve readability
-    fprintf(fp,  "    if (ra->C->alias_type(adr_type())->field() != NULL) {\n");
-    fprintf(fp,  "      st->print(\" ! Field \");\n");
-    fprintf(fp,  "      if( ra->C->alias_type(adr_type())->is_volatile() )\n");
-    fprintf(fp,  "        st->print(\" Volatile\");\n");
-    fprintf(fp,  "      ra->C->alias_type(adr_type())->field()->holder()->name()->print_symbol_on(st);\n");
-    fprintf(fp,  "      st->print(\".\");\n");
-    fprintf(fp,  "      ra->C->alias_type(adr_type())->field()->name()->print_symbol_on(st);\n");
-    fprintf(fp,  "    } else\n");
+    fprintf(fp,  "  if (ra->C->alias_type(adr_type())->field() != NULL) {\n");
+    fprintf(fp,  "    ciField* f = ra->C->alias_type(adr_type())->field();\n");
+    fprintf(fp,  "    st->print(\" %s Field: \");\n", commentSeperator);
+    fprintf(fp,  "    if (f->is_volatile())\n");
+    fprintf(fp,  "      st->print(\"volatile \");\n");
+    fprintf(fp,  "    f->holder()->name()->print_symbol_on(st);\n");
+    fprintf(fp,  "    st->print(\".\");\n");
+    fprintf(fp,  "    f->name()->print_symbol_on(st);\n");
+    fprintf(fp,  "    if (f->is_constant())\n");
+    fprintf(fp,  "      st->print(\" (constant)\");\n");
+    fprintf(fp,  "  } else {\n");
     // Make sure 'Volatile' gets printed out
-    fprintf(fp,  "    if( ra->C->alias_type(adr_type())->is_volatile() )\n");
-    fprintf(fp,  "      st->print(\" Volatile!\");\n");
+    fprintf(fp,  "    if (ra->C->alias_type(adr_type())->is_volatile())\n");
+    fprintf(fp,  "      st->print(\" volatile!\");\n");
+    fprintf(fp,  "  }\n");
   }
 
   // Complete the definition of the format function
-  fprintf(fp, "  }\n#endif\n");
-}
-
-static bool is_non_constant(char* x) {
-  // Tells whether the string (part of an operator interface) is non-constant.
-  // Simply detect whether there is an occurrence of a formal parameter,
-  // which will always begin with '$'.
-  return strchr(x, '$') == 0;
+  fprintf(fp, "}\n#endif\n");
 }
 
 void ArchDesc::declare_pipe_classes(FILE *fp_hpp) {
@@ -1086,7 +1098,7 @@
   fprintf(fp_hpp, "  static void initialize_nops(MachNode *nop_list[%d], Compile* C);\n\n",
     _pipeline->_nopcnt);
   fprintf(fp_hpp, "#ifndef PRODUCT\n");
-  fprintf(fp_hpp, "  void dump() const;\n");
+  fprintf(fp_hpp, "  void dump(outputStream *st = tty) const;\n");
   fprintf(fp_hpp, "#endif\n");
   fprintf(fp_hpp, "};\n\n");
 
@@ -1231,7 +1243,7 @@
       unsigned int position = 0;
       const char  *opret, *opname, *optype;
       oper->_matrule->base_operand(position,_globalNames,opret,opname,optype);
-      fprintf(fp,"  virtual const Type *type() const {");
+      fprintf(fp,"  virtual const Type    *type() const {");
       const char *type = getIdealType(optype);
       if( type != NULL ) {
         Form::DataType data_type = oper->is_base_constant(_globalNames);
@@ -1500,12 +1512,19 @@
       fprintf(fp, "  GrowableArray<Label*> _index2label;\n");
     }
     fprintf(fp,"public:\n");
-    fprintf(fp,"  MachOper *opnd_array(uint operand_index) const { assert(operand_index < _num_opnds, \"invalid _opnd_array index\"); return _opnd_array[operand_index]; }\n");
-    fprintf(fp,"  void      set_opnd_array(uint operand_index, MachOper *operand) { assert(operand_index < _num_opnds, \"invalid _opnd_array index\"); _opnd_array[operand_index] = operand; }\n");
+    fprintf(fp,"  MachOper *opnd_array(uint operand_index) const {\n");
+    fprintf(fp,"    assert(operand_index < _num_opnds, \"invalid _opnd_array index\");\n");
+    fprintf(fp,"    return _opnd_array[operand_index];\n");
+    fprintf(fp,"  }\n");
+    fprintf(fp,"  void      set_opnd_array(uint operand_index, MachOper *operand) {\n");
+    fprintf(fp,"    assert(operand_index < _num_opnds, \"invalid _opnd_array index\");\n");
+    fprintf(fp,"    _opnd_array[operand_index] = operand;\n");
+    fprintf(fp,"  }\n");
     fprintf(fp,"private:\n");
     if ( instr->is_ideal_jump() ) {
       fprintf(fp,"  virtual void           add_case_label(int index_num, Label* blockLabel) {\n");
-      fprintf(fp,"                                          _index2label.at_put_grow(index_num, blockLabel);}\n");
+      fprintf(fp,"    _index2label.at_put_grow(index_num, blockLabel);\n");
+      fprintf(fp,"  }\n");
     }
     if( can_cisc_spill() && (instr->cisc_spill_alternate() != NULL) ) {
       fprintf(fp,"  const RegMask  *_cisc_RegMask;\n");
@@ -1541,7 +1560,7 @@
     while (attr != NULL) {
       if (strcmp(attr->_ident,"ins_cost") &&
           strcmp(attr->_ident,"ins_short_branch")) {
-        fprintf(fp,"  int             %s() const { return %s; }\n",
+        fprintf(fp,"          int            %s() const { return %s; }\n",
                 attr->_ident, attr->_val);
       }
       // Check value for ins_avoid_back_to_back, and if it is true (1), set the flag
@@ -1625,12 +1644,12 @@
 
     // Output the declaration for number of relocation entries
     if ( instr->reloc(_globalNames) != 0 ) {
-      fprintf(fp,"  virtual int            reloc()   const;\n");
+      fprintf(fp,"  virtual int            reloc() const;\n");
     }
 
     if (instr->alignment() != 1) {
-      fprintf(fp,"  virtual int            alignment_required()   const { return %d; }\n", instr->alignment());
-      fprintf(fp,"  virtual int            compute_padding(int current_offset)   const;\n");
+      fprintf(fp,"  virtual int            alignment_required() const { return %d; }\n", instr->alignment());
+      fprintf(fp,"  virtual int            compute_padding(int current_offset) const;\n");
     }
 
     // Starting point for inputs matcher wants.
@@ -1800,7 +1819,7 @@
       // as is done for pointers
       //
       // Construct appropriate constant type containing the constant value.
-      fprintf(fp,"  virtual const class Type *bottom_type() const{\n");
+      fprintf(fp,"  virtual const class Type *bottom_type() const {\n");
       switch( data_type ) {
       case Form::idealI:
         fprintf(fp,"    return  TypeInt::make(opnd_array(1)->constant());\n");
@@ -1830,7 +1849,7 @@
       // !!!!! !!!!!
       // Provide explicit bottom type for conversions to int
       // On Intel the result operand is a stackSlot, untyped.
-      fprintf(fp,"  virtual const class Type *bottom_type() const{");
+      fprintf(fp,"  virtual const class Type *bottom_type() const {");
       fprintf(fp,   " return  TypeInt::INT;");
       fprintf(fp, " };\n");
     }*/
@@ -1851,7 +1870,7 @@
       // BoxNode provides the address of a stack slot.
       // Define its bottom type to be TypeRawPtr::BOTTOM instead of TypePtr::BOTTOM
       // This prevent s insert_anti_dependencies from complaining. It will
-      // complain if it see that the pointer base is TypePtr::BOTTOM since
+      // complain if it sees that the pointer base is TypePtr::BOTTOM since
       // it doesn't understand what that might alias.
       fprintf(fp,"  const Type            *bottom_type() const { return TypeRawPtr::BOTTOM; } // Box?\n");
     }
@@ -2014,7 +2033,7 @@
 class OutputMachOperands : public OutputMap {
 public:
   OutputMachOperands(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
-    : OutputMap(hpp, cpp, globals, AD) {};
+    : OutputMap(hpp, cpp, globals, AD, "MachOperands") {};
 
   void declaration() { }
   void definition()  { fprintf(_cpp, "enum MachOperands {\n"); }
@@ -2049,7 +2068,7 @@
   int end_instructions;
 public:
   OutputMachOpcodes(FILE *hpp, FILE *cpp, FormDict &globals, ArchDesc &AD)
-    : OutputMap(hpp, cpp, globals, AD),
+    : OutputMap(hpp, cpp, globals, AD, "MachOpcodes"),
       begin_inst_chain_rule(-1), end_inst_chain_rule(-1), end_instructions(-1)
   {};
 
diff --git a/hotspot/src/share/vm/asm/assembler.cpp b/hotspot/src/share/vm/asm/assembler.cpp
index 2bcdcbc..339b3a4 100644
--- a/hotspot/src/share/vm/asm/assembler.cpp
+++ b/hotspot/src/share/vm/asm/assembler.cpp
@@ -318,6 +318,16 @@
   }
 }
 
+RegisterOrConstant AbstractAssembler::delayed_value(int(*value_fn)(), Register tmp, int offset) {
+  intptr_t val = (intptr_t) (*value_fn)();
+  if (val != 0)  return val + offset;
+  return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
+}
+RegisterOrConstant AbstractAssembler::delayed_value(address(*value_fn)(), Register tmp, int offset) {
+  intptr_t val = (intptr_t) (*value_fn)();
+  if (val != 0)  return val + offset;
+  return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
+}
 intptr_t* AbstractAssembler::delayed_value_addr(int(*value_fn)()) {
   DelayedConstant* dcon = DelayedConstant::add(T_INT, (DelayedConstant::value_fn_t) value_fn);
   return &dcon->value;
diff --git a/hotspot/src/share/vm/asm/assembler.hpp b/hotspot/src/share/vm/asm/assembler.hpp
index c25aa3f..2fd2b80 100644
--- a/hotspot/src/share/vm/asm/assembler.hpp
+++ b/hotspot/src/share/vm/asm/assembler.hpp
@@ -406,12 +406,8 @@
   // offsets in code which must be generated before the object class is loaded.
   // Field offsets are never zero, since an object's header (mark word)
   // is located at offset zero.
-  RegisterOrConstant delayed_value(int(*value_fn)(), Register tmp, int offset = 0) {
-    return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
-  }
-  RegisterOrConstant delayed_value(address(*value_fn)(), Register tmp, int offset = 0) {
-    return delayed_value_impl(delayed_value_addr(value_fn), tmp, offset);
-  }
+  RegisterOrConstant delayed_value(int(*value_fn)(), Register tmp, int offset = 0);
+  RegisterOrConstant delayed_value(address(*value_fn)(), Register tmp, int offset = 0);
   virtual RegisterOrConstant delayed_value_impl(intptr_t* delayed_value_addr, Register tmp, int offset) = 0;
   // Last overloading is platform-dependent; look in assembler_<arch>.cpp.
   static intptr_t* delayed_value_addr(int(*constant_fn)());
diff --git a/hotspot/src/share/vm/asm/codeBuffer.cpp b/hotspot/src/share/vm/asm/codeBuffer.cpp
index f52b942..d1e21e5 100644
--- a/hotspot/src/share/vm/asm/codeBuffer.cpp
+++ b/hotspot/src/share/vm/asm/codeBuffer.cpp
@@ -261,7 +261,7 @@
 
 GrowableArray<int>* CodeBuffer::create_patch_overflow() {
   if (_overflow_arena == NULL) {
-    _overflow_arena = new Arena();
+    _overflow_arena = new (mtCode) Arena();
   }
   return new (_overflow_arena) GrowableArray<int>(_overflow_arena, 8, 0, 0);
 }
@@ -910,7 +910,7 @@
   _comments.add_comment(offset, comment);
 }
 
-class CodeComment: public CHeapObj {
+class CodeComment: public CHeapObj<mtCode> {
  private:
   friend class CodeComments;
   intptr_t     _offset;
@@ -919,13 +919,13 @@
 
   ~CodeComment() {
     assert(_next == NULL, "wrong interface for freeing list");
-    os::free((void*)_comment);
+    os::free((void*)_comment, mtCode);
   }
 
  public:
   CodeComment(intptr_t offset, const char * comment) {
     _offset = offset;
-    _comment = os::strdup(comment);
+    _comment = os::strdup(comment, mtCode);
     _next = NULL;
   }
 
@@ -942,25 +942,30 @@
     }
     return a;
   }
+
+  // Convenience for add_comment.
+  CodeComment* find_last(intptr_t offset) {
+    CodeComment* a = find(offset);
+    if (a != NULL) {
+      while ((a->_next != NULL) && (a->_next->_offset == offset)) {
+        a = a->_next;
+      }
+    }
+    return a;
+  }
 };
 
 
 void CodeComments::add_comment(intptr_t offset, const char * comment) {
-  CodeComment* c = new CodeComment(offset, comment);
-  CodeComment* insert = NULL;
-  if (_comments != NULL) {
-    CodeComment* c = _comments->find(offset);
-    insert = c;
-    while (c && c->offset() == offset) {
-      insert = c;
-      c = c->next();
-    }
-  }
-  if (insert) {
-    // insert after comments with same offset
-    c->set_next(insert->next());
-    insert->set_next(c);
+  CodeComment* c      = new CodeComment(offset, comment);
+  CodeComment* inspos = (_comments == NULL) ? NULL : _comments->find_last(offset);
+
+  if (inspos) {
+    // insert after already existing comments with same offset
+    c->set_next(inspos->next());
+    inspos->set_next(c);
   } else {
+    // no comments with such offset, yet. Insert before anything else.
     c->set_next(_comments);
     _comments = c;
   }
@@ -968,12 +973,11 @@
 
 
 void CodeComments::assign(CodeComments& other) {
-  assert(_comments == NULL, "don't overwrite old value");
   _comments = other._comments;
 }
 
 
-void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) {
+void CodeComments::print_block_comment(outputStream* stream, intptr_t offset) const {
   if (_comments != NULL) {
     CodeComment* c = _comments->find(offset);
     while (c && c->offset() == offset) {
@@ -1001,6 +1005,7 @@
 
 
 void CodeBuffer::decode() {
+  ttyLocker ttyl;
   Disassembler::decode(decode_begin(), insts_end());
   _decode_begin = insts_end();
 }
@@ -1012,6 +1017,7 @@
 
 
 void CodeBuffer::decode_all() {
+  ttyLocker ttyl;
   for (int n = 0; n < (int)SECT_LIMIT; n++) {
     // dump contents of each section
     CodeSection* cs = code_section(n);
diff --git a/hotspot/src/share/vm/asm/codeBuffer.hpp b/hotspot/src/share/vm/asm/codeBuffer.hpp
index 53c90c2..6e6e8b9 100644
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp
@@ -253,7 +253,7 @@
   }
 
   void add_comment(intptr_t offset, const char * comment) PRODUCT_RETURN;
-  void print_block_comment(outputStream* stream, intptr_t offset)  PRODUCT_RETURN;
+  void print_block_comment(outputStream* stream, intptr_t offset) const PRODUCT_RETURN;
   void assign(CodeComments& other)  PRODUCT_RETURN;
   void free() PRODUCT_RETURN;
 };
diff --git a/hotspot/src/share/vm/asm/register.hpp b/hotspot/src/share/vm/asm/register.hpp
index 4817921..5a94a0a 100644
--- a/hotspot/src/share/vm/asm/register.hpp
+++ b/hotspot/src/share/vm/asm/register.hpp
@@ -103,7 +103,8 @@
 ) {
   assert(
     a != b,
-    "registers must be different"
+    err_msg_res("registers must be different: a=%d, b=%d",
+                a, b)
   );
 }
 
@@ -116,7 +117,8 @@
   assert(
     a != b && a != c
            && b != c,
-    "registers must be different"
+    err_msg_res("registers must be different: a=%d, b=%d, c=%d",
+                a, b, c)
   );
 }
 
@@ -131,7 +133,8 @@
     a != b && a != c && a != d
            && b != c && b != d
                      && c != d,
-    "registers must be different"
+    err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d",
+                a, b, c, d)
   );
 }
 
@@ -148,7 +151,8 @@
            && b != c && b != d && b != e
                      && c != d && c != e
                                && d != e,
-    "registers must be different"
+    err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d",
+                a, b, c, d, e)
   );
 }
 
@@ -167,7 +171,8 @@
                      && c != d && c != e && c != f
                                && d != e && d != f
                                          && e != f,
-    "registers must be different"
+    err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d",
+                a, b, c, d, e, f)
   );
 }
 
@@ -188,7 +193,8 @@
                                && d != e && d != f && d != g
                                          && e != f && e != g
                                                    && f != g,
-    "registers must be different"
+    err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d",
+                a, b, c, d, e, f, g)
   );
 }
 
@@ -211,7 +217,34 @@
                                          && e != f && e != g && e != h
                                                    && f != g && f != h
                                                              && g != h,
-    "registers must be different"
+    err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d",
+                a, b, c, d, e, f, g, h)
+  );
+}
+
+
+inline void assert_different_registers(
+  AbstractRegister a,
+  AbstractRegister b,
+  AbstractRegister c,
+  AbstractRegister d,
+  AbstractRegister e,
+  AbstractRegister f,
+  AbstractRegister g,
+  AbstractRegister h,
+  AbstractRegister i
+) {
+  assert(
+    a != b && a != c && a != d && a != e && a != f && a != g && a != h && a != i
+           && b != c && b != d && b != e && b != f && b != g && b != h && b != i
+                     && c != d && c != e && c != f && c != g && c != h && c != i
+                               && d != e && d != f && d != g && d != h && d != i
+                                         && e != f && e != g && e != h && e != i
+                                                   && f != g && f != h && f != i
+                                                             && g != h && g != i
+                                                                       && h != i,
+    err_msg_res("registers must be different: a=%d, b=%d, c=%d, d=%d, e=%d, f=%d, g=%d, h=%d, i=%d",
+                a, b, c, d, e, f, g, h, i)
   );
 }
 
diff --git a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
index 4964ebd..66a7e22 100644
--- a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
+++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
@@ -33,7 +33,7 @@
 #ifndef PRODUCT
 
 
-class CFGPrinterOutput : public CHeapObj {
+class CFGPrinterOutput : public CHeapObj<mtCompiler> {
  private:
   outputStream* _output;
 
@@ -106,7 +106,7 @@
 
 
 CFGPrinterOutput::CFGPrinterOutput()
- : _output(new(ResourceObj::C_HEAP) fileStream("output.cfg"))
+ : _output(new(ResourceObj::C_HEAP, mtCompiler) fileStream("output.cfg"))
 {
 }
 
diff --git a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp
index c7a5198..1fcdd64 100644
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.cpp
@@ -42,6 +42,11 @@
   // the instruction stream (because the instruction list is embedded
   // in the instructions).
   if (canonical() != x) {
+#ifndef PRODUCT
+    if (!x->has_printable_bci()) {
+      x->set_printable_bci(bci());
+    }
+#endif
     if (PrintCanonicalization) {
       PrintValueVisitor do_print_value;
       canonical()->input_values_do(&do_print_value);
@@ -451,6 +456,28 @@
     }
     break;
   }
+  case vmIntrinsics::_isInstance          : {
+    assert(x->number_of_arguments() == 2, "wrong type");
+
+    InstanceConstant* c = x->argument_at(0)->type()->as_InstanceConstant();
+    if (c != NULL && !c->value()->is_null_object()) {
+      // ciInstance::java_mirror_type() returns non-NULL only for Java mirrors
+      ciType* t = c->value()->as_instance()->java_mirror_type();
+      if (t->is_klass()) {
+        // substitute cls.isInstance(obj) of a constant Class into
+        // an InstantOf instruction
+        InstanceOf* i = new InstanceOf(t->as_klass(), x->argument_at(1), x->state_before());
+        set_canonical(i);
+        // and try to canonicalize even further
+        do_InstanceOf(i);
+      } else {
+        assert(t->is_primitive_type(), "should be a primitive type");
+        // cls.isInstance(obj) always returns false for primitive classes
+        set_constant(0);
+      }
+    }
+    break;
+  }
   }
 }
 
@@ -540,6 +567,7 @@
   }
 }
 
+void Canonicalizer::do_TypeCast       (TypeCast*        x) {}
 void Canonicalizer::do_Invoke         (Invoke*          x) {}
 void Canonicalizer::do_NewInstance    (NewInstance*     x) {}
 void Canonicalizer::do_NewTypeArray   (NewTypeArray*    x) {}
@@ -677,8 +705,8 @@
                 return;
             }
           }
-          set_canonical(canon);
           set_bci(cmp->state_before()->bci());
+          set_canonical(canon);
         }
       }
     } else if (l->as_InstanceOf() != NULL) {
@@ -903,6 +931,7 @@
 void Canonicalizer::do_UnsafePutRaw(UnsafePutRaw* x) { if (OptimizeUnsafes) do_UnsafeRawOp(x); }
 void Canonicalizer::do_UnsafeGetObject(UnsafeGetObject* x) {}
 void Canonicalizer::do_UnsafePutObject(UnsafePutObject* x) {}
+void Canonicalizer::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {}
 void Canonicalizer::do_UnsafePrefetchRead (UnsafePrefetchRead*  x) {}
 void Canonicalizer::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
 void Canonicalizer::do_ProfileCall(ProfileCall* x) {}
diff --git a/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp b/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp
index 8ae3a21..b7c9f7e 100644
--- a/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp
+++ b/hotspot/src/share/vm/c1/c1_Canonicalizer.hpp
@@ -74,6 +74,7 @@
   virtual void do_IfInstanceOf   (IfInstanceOf*    x);
   virtual void do_Convert        (Convert*         x);
   virtual void do_NullCheck      (NullCheck*       x);
+  virtual void do_TypeCast       (TypeCast*        x);
   virtual void do_Invoke         (Invoke*          x);
   virtual void do_NewInstance    (NewInstance*     x);
   virtual void do_NewTypeArray   (NewTypeArray*    x);
@@ -99,6 +100,7 @@
   virtual void do_UnsafePutRaw   (UnsafePutRaw*    x);
   virtual void do_UnsafeGetObject(UnsafeGetObject* x);
   virtual void do_UnsafePutObject(UnsafePutObject* x);
+  virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);
   virtual void do_UnsafePrefetchRead (UnsafePrefetchRead*  x);
   virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
   virtual void do_ProfileCall    (ProfileCall*     x);
diff --git a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp
index 128a6d4..dad29b2 100644
--- a/hotspot/src/share/vm/c1/c1_CodeStubs.hpp
+++ b/hotspot/src/share/vm/c1/c1_CodeStubs.hpp
@@ -574,71 +574,6 @@
 #endif // PRODUCT
 };
 
-// This G1 barrier code stub is used in Unsafe.getObject.
-// It generates a sequence of guards around the SATB
-// barrier code that are used to detect when we have
-// the referent field of a Reference object.
-// The first check is assumed to have been generated
-// in the code generated for Unsafe.getObject().
-
-class G1UnsafeGetObjSATBBarrierStub: public CodeStub {
- private:
-  LIR_Opr _val;
-  LIR_Opr _src;
-
-  LIR_Opr _tmp;
-  LIR_Opr _thread;
-
-  bool _gen_src_check;
-
- public:
-  // A G1 barrier that is guarded by generated guards that determine whether
-  // val (which is the result of Unsafe.getObject() should be recorded in an
-  // SATB log buffer. We could be reading the referent field of a Reference object
-  // using Unsafe.getObject() and we need to record the referent.
-  //
-  // * val is the operand returned by the unsafe.getObject routine.
-  // * src is the base object
-  // * tmp is a temp used to load the klass of src, and then reference type
-  // * thread is the thread object.
-
-  G1UnsafeGetObjSATBBarrierStub(LIR_Opr val, LIR_Opr src,
-                                LIR_Opr tmp, LIR_Opr thread,
-                                bool gen_src_check) :
-    _val(val), _src(src),
-    _tmp(tmp), _thread(thread),
-    _gen_src_check(gen_src_check)
-  {
-    assert(_val->is_register(), "should have already been loaded");
-    assert(_src->is_register(), "should have already been loaded");
-
-    assert(_tmp->is_register(), "should be a temporary register");
-  }
-
-  LIR_Opr val() const { return _val; }
-  LIR_Opr src() const { return _src; }
-
-  LIR_Opr tmp() const { return _tmp; }
-  LIR_Opr thread() const { return _thread; }
-
-  bool gen_src_check() const { return _gen_src_check; }
-
-  virtual void emit_code(LIR_Assembler* e);
-
-  virtual void visit(LIR_OpVisitState* visitor) {
-    visitor->do_slow_case();
-    visitor->do_input(_val);
-    visitor->do_input(_src);
-    visitor->do_input(_thread);
-
-    visitor->do_temp(_tmp);
-  }
-
-#ifndef PRODUCT
-  virtual void print_name(outputStream* out) const { out->print("G1UnsafeGetObjSATBBarrierStub"); }
-#endif // PRODUCT
-};
-
 class G1PostBarrierStub: public CodeStub {
  private:
   LIR_Opr _addr;
diff --git a/hotspot/src/share/vm/c1/c1_Compilation.cpp b/hotspot/src/share/vm/c1/c1_Compilation.cpp
index ab3930c..987b00a 100644
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp
@@ -32,6 +32,7 @@
 #include "c1/c1_ValueMap.hpp"
 #include "c1/c1_ValueStack.hpp"
 #include "code/debugInfoRec.hpp"
+#include "compiler/compileLog.hpp"
 
 
 typedef enum {
@@ -67,10 +68,25 @@
 class PhaseTraceTime: public TraceTime {
  private:
   JavaThread* _thread;
+  CompileLog* _log;
 
  public:
-  PhaseTraceTime(TimerName timer):
-    TraceTime("", &timers[timer], CITime || CITimeEach, Verbose) {
+  PhaseTraceTime(TimerName timer)
+  : TraceTime("", &timers[timer], CITime || CITimeEach, Verbose), _log(NULL) {
+    if (Compilation::current() != NULL) {
+      _log = Compilation::current()->log();
+    }
+
+    if (_log != NULL) {
+      _log->begin_head("phase name='%s'", timer_name[timer]);
+      _log->stamp();
+      _log->end_head();
+    }
+  }
+
+  ~PhaseTraceTime() {
+    if (_log != NULL)
+      _log->done("phase");
   }
 };
 
@@ -346,7 +362,8 @@
     implicit_exception_table(),
     compiler(),
     _env->comp_level(),
-    has_unsafe_access()
+    has_unsafe_access(),
+    SharedRuntime::is_wide_vector(max_vector_size())
   );
 }
 
@@ -389,6 +406,10 @@
     PhaseTraceTime timeit(_t_codeinstall);
     install_code(frame_size);
   }
+
+  if (log() != NULL) // Print code cache state into compiler log
+    log()->code_cache_state();
+
   totalInstructionNodes += Instruction::number_of_instructions();
 }
 
@@ -455,6 +476,7 @@
                          int osr_bci, BufferBlob* buffer_blob)
 : _compiler(compiler)
 , _env(env)
+, _log(env->log())
 , _method(method)
 , _osr_bci(osr_bci)
 , _hir(NULL)
@@ -523,7 +545,7 @@
   assert(msg != NULL, "bailout message must exist");
   if (!bailed_out()) {
     // keep first bailout message
-    if (PrintBailouts) tty->print_cr("compilation bailout: %s", msg);
+    if (PrintCompilation || PrintBailouts) tty->print_cr("compilation bailout: %s", msg);
     _bailout_msg = msg;
   }
 }
diff --git a/hotspot/src/share/vm/c1/c1_Compilation.hpp b/hotspot/src/share/vm/c1/c1_Compilation.hpp
index 376b6f3..9a8ca61 100644
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp
@@ -66,6 +66,7 @@
   int _next_block_id;
   AbstractCompiler*  _compiler;
   ciEnv*             _env;
+  CompileLog*        _log;
   ciMethod*          _method;
   int                _osr_bci;
   IR*                _hir;
@@ -123,10 +124,12 @@
 
   // accessors
   ciEnv* env() const                             { return _env; }
+  CompileLog* log() const                        { return _log; }
   AbstractCompiler* compiler() const             { return _compiler; }
   bool has_exception_handlers() const            { return _has_exception_handlers; }
   bool has_fpu_code() const                      { return _has_fpu_code; }
   bool has_unsafe_access() const                 { return _has_unsafe_access; }
+  int max_vector_size() const                    { return 0; }
   ciMethod* method() const                       { return _method; }
   int osr_bci() const                            { return _osr_bci; }
   bool is_osr_compile() const                    { return osr_bci() >= 0; }
diff --git a/hotspot/src/share/vm/c1/c1_Compiler.cpp b/hotspot/src/share/vm/c1/c1_Compiler.cpp
index 41b5eb5..7e55ce3 100644
--- a/hotspot/src/share/vm/c1/c1_Compiler.cpp
+++ b/hotspot/src/share/vm/c1/c1_Compiler.cpp
@@ -55,7 +55,7 @@
 
 void Compiler::initialize_all() {
   BufferBlob* buffer_blob = CompilerThread::current()->get_buffer_blob();
-  Arena* arena = new Arena();
+  Arena* arena = new (mtCompiler) Arena();
   Runtime1::initialize(buffer_blob);
   FrameMap::initialize();
   // initialize data structures
diff --git a/hotspot/src/share/vm/c1/c1_FrameMap.cpp b/hotspot/src/share/vm/c1/c1_FrameMap.cpp
index ea50b27..8920dbe 100644
--- a/hotspot/src/share/vm/c1/c1_FrameMap.cpp
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.cpp
@@ -92,7 +92,6 @@
   for (i = 0; i < sizeargs;) {
     BasicType t = sig_bt[i];
     assert(t != T_VOID, "should be skipping these");
-
     LIR_Opr opr = map_to_opr(t, regs + i, outgoing);
     args->append(opr);
     if (opr->is_address()) {
diff --git a/hotspot/src/share/vm/c1/c1_FrameMap.hpp b/hotspot/src/share/vm/c1/c1_FrameMap.hpp
index 288fc5c..b1e1862 100644
--- a/hotspot/src/share/vm/c1/c1_FrameMap.hpp
+++ b/hotspot/src/share/vm/c1/c1_FrameMap.hpp
@@ -181,8 +181,8 @@
 
   // for outgoing calls, these also update the reserved area to
   // include space for arguments and any ABI area.
-  CallingConvention* c_calling_convention (const BasicTypeArray* signature);
-  CallingConvention* java_calling_convention (const BasicTypeArray* signature, bool outgoing);
+  CallingConvention* c_calling_convention(const BasicTypeArray* signature);
+  CallingConvention* java_calling_convention(const BasicTypeArray* signature, bool outgoing);
 
   // deopt support
   ByteSize sp_offset_for_orig_pc() { return sp_offset_for_monitor_base(_num_monitors); }
diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
index a59ae10..e6e3a26 100644
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.cpp
@@ -31,7 +31,7 @@
 #include "ci/ciCallSite.hpp"
 #include "ci/ciField.hpp"
 #include "ci/ciKlass.hpp"
-#include "ci/ciMethodHandle.hpp"
+#include "ci/ciMemberName.hpp"
 #include "compiler/compileBroker.hpp"
 #include "interpreter/bytecode.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -914,11 +914,11 @@
 
 void GraphBuilder::store_local(ValueType* type, int index) {
   Value x = pop(type);
-  store_local(state(), x, type, index);
+  store_local(state(), x, index);
 }
 
 
-void GraphBuilder::store_local(ValueStack* state, Value x, ValueType* type, int index) {
+void GraphBuilder::store_local(ValueStack* state, Value x, int index) {
   if (parsing_jsr()) {
     // We need to do additional tracking of the location of the return
     // address for jsrs since we don't handle arbitrary jsr/ret
@@ -1306,6 +1306,7 @@
       if (sw.dest_offset_at(i) < 0) has_bb = true;
     }
     // add default successor
+    if (sw.default_offset() < 0) has_bb = true;
     sux->at_put(i, block_at(bci() + sw.default_offset()));
     ValueStack* state_before = has_bb ? copy_state_before() : NULL;
     Instruction* res = append(new TableSwitch(ipop(), sux, sw.low_key(), state_before, has_bb));
@@ -1350,6 +1351,7 @@
       keys->at_put(i, pair.match());
     }
     // add default successor
+    if (sw.default_offset() < 0) has_bb = true;
     sux->at_put(i, block_at(bci() + sw.default_offset()));
     ValueStack* state_before = has_bb ? copy_state_before() : NULL;
     Instruction* res = append(new LookupSwitch(ipop(), sux, keys, state_before, has_bb));
@@ -1533,7 +1535,7 @@
         case T_ARRAY:
         case T_OBJECT:
           if (field_val.as_object()->should_be_constant()) {
-            constant =  new Constant(as_ValueType(field_val));
+            constant = new Constant(as_ValueType(field_val));
           }
           break;
 
@@ -1560,12 +1562,53 @@
         append(new StoreField(append(obj), offset, field, val, true, state_before, needs_patching));
       }
       break;
-    case Bytecodes::_getfield :
-      {
+    case Bytecodes::_getfield: {
+      // Check for compile-time constants, i.e., trusted final non-static fields.
+      Instruction* constant = NULL;
+      obj = apop();
+      ObjectType* obj_type = obj->type()->as_ObjectType();
+      if (obj_type->is_constant() && !PatchALot) {
+        ciObject* const_oop = obj_type->constant_value();
+        if (!const_oop->is_null_object()) {
+          if (field->is_constant()) {
+            ciConstant field_val = field->constant_value_of(const_oop);
+            BasicType field_type = field_val.basic_type();
+            switch (field_type) {
+            case T_ARRAY:
+            case T_OBJECT:
+              if (field_val.as_object()->should_be_constant()) {
+                constant = new Constant(as_ValueType(field_val));
+              }
+              break;
+            default:
+              constant = new Constant(as_ValueType(field_val));
+            }
+          } else {
+            // For CallSite objects treat the target field as a compile time constant.
+            if (const_oop->is_call_site()) {
+              ciCallSite* call_site = const_oop->as_call_site();
+              if (field->is_call_site_target()) {
+                ciMethodHandle* target = call_site->get_target();
+                if (target != NULL) {  // just in case
+                  ciConstant field_val(T_OBJECT, target);
+                  constant = new Constant(as_ValueType(field_val));
+                  // Add a dependence for invalidation of the optimization.
+                  if (!call_site->is_constant_call_site()) {
+                    dependency_recorder()->assert_call_site_target_value(call_site, target);
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+      if (constant != NULL) {
+        push(type, append(constant));
+      } else {
         if (state_before == NULL) {
           state_before = copy_state_for_exception();
         }
-        LoadField* load = new LoadField(apop(), offset, field, false, state_before, needs_patching);
+        LoadField* load = new LoadField(obj, offset, field, false, state_before, needs_patching);
         Value replacement = !needs_patching ? _memory->load(load) : load;
         if (replacement != load) {
           assert(replacement->is_linked() || !replacement->can_be_linked(), "should already by linked");
@@ -1573,22 +1616,23 @@
         } else {
           push(type, append(load));
         }
-        break;
-      }
-
-    case Bytecodes::_putfield :
-      { Value val = pop(type);
-        if (state_before == NULL) {
-          state_before = copy_state_for_exception();
-        }
-        StoreField* store = new StoreField(apop(), offset, field, val, false, state_before, needs_patching);
-        if (!needs_patching) store = _memory->store(store);
-        if (store != NULL) {
-          append(store);
-        }
       }
       break;
-    default                   :
+    }
+    case Bytecodes::_putfield: {
+      Value val = pop(type);
+      obj = apop();
+      if (state_before == NULL) {
+        state_before = copy_state_for_exception();
+      }
+      StoreField* store = new StoreField(obj, offset, field, val, false, state_before, needs_patching);
+      if (!needs_patching) store = _memory->store(store);
+      if (store != NULL) {
+        append(store);
+      }
+      break;
+    }
+    default:
       ShouldNotReachHere();
       break;
   }
@@ -1603,37 +1647,78 @@
 
 void GraphBuilder::invoke(Bytecodes::Code code) {
   bool will_link;
-  ciMethod* target = stream()->get_method(will_link);
+  ciSignature* declared_signature = NULL;
+  ciMethod*             target = stream()->get_method(will_link, &declared_signature);
+  ciKlass*              holder = stream()->get_declared_method_holder();
+  const Bytecodes::Code bc_raw = stream()->cur_bc_raw();
+  assert(declared_signature != NULL, "cannot be null");
+
+  // FIXME bail out for now
+  if (Bytecodes::has_optional_appendix(bc_raw) && !will_link) {
+    BAILOUT("unlinked call site (FIXME needs patching or recompile support)");
+  }
+
   // we have to make sure the argument size (incl. the receiver)
   // is correct for compilation (the call would fail later during
   // linkage anyway) - was bug (gri 7/28/99)
-  if (target->is_loaded() && target->is_static() != (code == Bytecodes::_invokestatic)) BAILOUT("will cause link error");
+  {
+    // Use raw to get rewritten bytecode.
+    const bool is_invokestatic = bc_raw == Bytecodes::_invokestatic;
+    const bool allow_static =
+          is_invokestatic ||
+          bc_raw == Bytecodes::_invokehandle ||
+          bc_raw == Bytecodes::_invokedynamic;
+    if (target->is_loaded()) {
+      if (( target->is_static() && !allow_static) ||
+          (!target->is_static() &&  is_invokestatic)) {
+        BAILOUT("will cause link error");
+      }
+    }
+  }
   ciInstanceKlass* klass = target->holder();
 
   // check if CHA possible: if so, change the code to invoke_special
   ciInstanceKlass* calling_klass = method()->holder();
-  ciKlass* holder = stream()->get_declared_method_holder();
   ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
   ciInstanceKlass* actual_recv = callee_holder;
 
-  // some methods are obviously bindable without any type checks so
-  // convert them directly to an invokespecial.
-  if (target->is_loaded() && !target->is_abstract() &&
-      target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
-    code = Bytecodes::_invokespecial;
+  CompileLog* log = compilation()->log();
+  if (log != NULL)
+      log->elem("call method='%d' instr='%s'",
+                log->identify(target),
+                Bytecodes::name(code));
+
+  // Some methods are obviously bindable without any type checks so
+  // convert them directly to an invokespecial or invokestatic.
+  if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
+    switch (bc_raw) {
+    case Bytecodes::_invokevirtual:
+      code = Bytecodes::_invokespecial;
+      break;
+    case Bytecodes::_invokehandle:
+      code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
+      break;
+    }
   }
 
-  bool is_invokedynamic = code == Bytecodes::_invokedynamic;
+  // Push appendix argument (MethodType, CallSite, etc.), if one.
+  if (stream()->has_appendix()) {
+    ciObject* appendix = stream()->get_appendix();
+    Value arg = append(new Constant(new ObjectConstant(appendix)));
+    apush(arg);
+  }
 
   // NEEDS_CLEANUP
-  // I've added the target-is_loaded() test below but I don't really understand
+  // I've added the target->is_loaded() test below but I don't really understand
   // how klass->is_loaded() can be true and yet target->is_loaded() is false.
   // this happened while running the JCK invokevirtual tests under doit.  TKR
   ciMethod* cha_monomorphic_target = NULL;
   ciMethod* exact_target = NULL;
   Value better_receiver = NULL;
   if (UseCHA && DeoptC1 && klass->is_loaded() && target->is_loaded() &&
-      !target->is_method_handle_invoke()) {
+      !(// %%% FIXME: Are both of these relevant?
+        target->is_method_handle_intrinsic() ||
+        target->is_compiled_lambda_form())) {
     Value receiver = NULL;
     ciInstanceKlass* receiver_klass = NULL;
     bool type_is_exact = false;
@@ -1692,7 +1777,9 @@
       // they are roughly equivalent to Object.
       ciInstanceKlass* singleton = NULL;
       if (target->holder()->nof_implementors() == 1) {
-        singleton = target->holder()->implementor(0);
+        singleton = target->holder()->implementor();
+        assert(singleton != NULL && singleton != target->holder(),
+               "just checking");
 
         assert(holder->is_interface(), "invokeinterface to non interface?");
         ciInstanceKlass* decl_interface = (ciInstanceKlass*)holder;
@@ -1745,6 +1832,7 @@
     }
     code = Bytecodes::_invokespecial;
   }
+
   // check if we could do inlining
   if (!PatchALot && Inline && klass->is_loaded() &&
       (klass->is_initialized() || klass->is_interface() && target->holder()->is_initialized())
@@ -1756,25 +1844,12 @@
         code == Bytecodes::_invokevirtual && target->is_final_method() ||
         code == Bytecodes::_invokedynamic) {
       ciMethod* inline_target = (cha_monomorphic_target != NULL) ? cha_monomorphic_target : target;
-      bool success = false;
-      if (target->is_method_handle_invoke()) {
-        // method handle invokes
-        success = !is_invokedynamic ? for_method_handle_inline(target) : for_invokedynamic_inline(target);
-      }
-      if (!success) {
-        // static binding => check if callee is ok
-        success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), better_receiver);
-      }
-      CHECK_BAILOUT();
+      // static binding => check if callee is ok
+      bool success = try_inline(inline_target, (cha_monomorphic_target != NULL) || (exact_target != NULL), code, better_receiver);
 
-#ifndef PRODUCT
-      // printing
-      if (PrintInlining && !success) {
-        // if it was successfully inlined, then it was already printed.
-        print_inline_result(inline_target, success);
-      }
-#endif
+      CHECK_BAILOUT();
       clear_inline_bailout();
+
       if (success) {
         // Register dependence if JVMTI has either breakpoint
         // setting or hotswapping of methods capabilities since they may
@@ -1784,8 +1859,13 @@
         }
         return;
       }
+    } else {
+      print_inlining(target, "no static binding", /*success*/ false);
     }
+  } else {
+    print_inlining(target, "not inlineable", /*success*/ false);
   }
+
   // If we attempted an inline which did not succeed because of a
   // bailout during construction of the callee graph, the entire
   // compilation has to be aborted. This is fairly rare and currently
@@ -1799,16 +1879,14 @@
 
   // inlining not successful => standard invoke
   bool is_loaded = target->is_loaded();
-  bool has_receiver =
+  ValueType* result_type = as_ValueType(declared_signature->return_type());
+  ValueStack* state_before = copy_state_exhandling();
+
+  // The bytecode (code) might change in this method so we are checking this very late.
+  const bool has_receiver =
     code == Bytecodes::_invokespecial   ||
     code == Bytecodes::_invokevirtual   ||
     code == Bytecodes::_invokeinterface;
-  ValueType* result_type = as_ValueType(target->return_type());
-
-  // We require the debug info to be the "state before" because
-  // invokedynamics may deoptimize.
-  ValueStack* state_before = is_invokedynamic ? copy_state_before() : copy_state_exhandling();
-
   Values* args = state()->pop_arguments(target->arg_size_no_receiver());
   Value recv = has_receiver ? apop() : NULL;
   int vtable_index = methodOopDesc::invalid_vtable_index;
@@ -1851,7 +1929,7 @@
       } else if (exact_target != NULL) {
         target_klass = exact_target->holder();
       }
-      profile_call(recv, target_klass);
+      profile_call(target, recv, target_klass);
     }
   }
 
@@ -2372,6 +2450,7 @@
 #endif
   _skip_block = false;
   assert(state() != NULL, "ValueStack missing!");
+  CompileLog* log = compilation()->log();
   ciBytecodeStream s(method());
   s.reset_to_bci(bci);
   int prev_bci = bci;
@@ -2390,6 +2469,9 @@
          (block_at(s.cur_bci()) == NULL || block_at(s.cur_bci()) == block())) {
     assert(state()->kind() == ValueStack::Parsing, "invalid state kind");
 
+    if (log != NULL)
+      log->set_context("bc code='%d' bci='%d'", (int)code, s.cur_bci());
+
     // Check for active jsr during OSR compilation
     if (compilation()->is_osr_compile()
         && scope()->is_top_scope()
@@ -2610,8 +2692,13 @@
       case Bytecodes::_breakpoint     : BAILOUT_("concurrent setting of breakpoint", NULL);
       default                         : ShouldNotReachHere(); break;
     }
+
+    if (log != NULL)
+      log->clear_context(); // skip marker if nothing was printed
+
     // save current bci to setup Goto at the end
     prev_bci = s.cur_bci();
+
   }
   CHECK_BAILOUT_(NULL);
   // stop processing of this block (see try_inline_full)
@@ -2945,6 +3032,8 @@
   case vmIntrinsics::_dtan          : // fall through
   case vmIntrinsics::_dlog          : // fall through
   case vmIntrinsics::_dlog10        : // fall through
+  case vmIntrinsics::_dexp          : // fall through
+  case vmIntrinsics::_dpow          : // fall through
     {
       // Compiles where the root method is an intrinsic need a special
       // compilation environment because the bytecodes for the method
@@ -2965,6 +3054,9 @@
       _state = start_block->state()->copy_for_parsing();
       _last  = start_block;
       load_local(doubleType, 0);
+      if (scope->method()->intrinsic_id() == vmIntrinsics::_dpow) {
+        load_local(doubleType, 2);
+      }
 
       // Emit the intrinsic node.
       bool result = try_inline_intrinsics(scope->method());
@@ -2979,7 +3071,7 @@
 
   case vmIntrinsics::_Reference_get:
     {
-      if (UseG1GC) {
+      {
         // With java.lang.ref.reference.get() we must go through the
         // intrinsic - when G1 is enabled - even when get() is the root
         // method of the compile so that, if necessary, the value in
@@ -2991,6 +3083,9 @@
         // object removed from the list of discovered references during
         // reference processing.
 
+        // Also we need intrinsic to prevent commoning reads from this field
+        // across safepoint since GC can change its value.
+
         // Set up a stream so that appending instructions works properly.
         ciBytecodeStream s(scope->method());
         s.reset_to_bci(0);
@@ -3088,35 +3183,70 @@
 }
 
 
-bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Value receiver) {
-  // Clear out any existing inline bailout condition
+bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
+  const char* msg = NULL;
+
+  // clear out any existing inline bailout condition
   clear_inline_bailout();
 
-  if (callee->should_exclude()) {
-    // callee is excluded
-    INLINE_BAILOUT("excluded by CompilerOracle")
-  } else if (callee->should_not_inline()) {
-    // callee is excluded
-    INLINE_BAILOUT("disallowed by CompilerOracle")
-  } else if (!callee->can_be_compiled()) {
-    // callee is not compilable (prob. has breakpoints)
-    INLINE_BAILOUT("not compilable (disabled)")
-  } else if (callee->intrinsic_id() != vmIntrinsics::_none && try_inline_intrinsics(callee)) {
-    // intrinsics can be native or not
-    return true;
-  } else if (callee->is_native()) {
-    // non-intrinsic natives cannot be inlined
-    INLINE_BAILOUT("non-intrinsic native")
-  } else if (callee->is_abstract()) {
-    INLINE_BAILOUT("abstract")
-  } else {
-    return try_inline_full(callee, holder_known, NULL, receiver);
+  // exclude methods we don't want to inline
+  msg = should_not_inline(callee);
+  if (msg != NULL) {
+    print_inlining(callee, msg, /*success*/ false);
+    return false;
   }
+
+  // method handle invokes
+  if (callee->is_method_handle_intrinsic()) {
+    return try_method_handle_inline(callee);
+  }
+
+  // handle intrinsics
+  if (callee->intrinsic_id() != vmIntrinsics::_none) {
+    if (try_inline_intrinsics(callee)) {
+      print_inlining(callee, "intrinsic");
+      return true;
+    }
+    // try normal inlining
+  }
+
+  // certain methods cannot be parsed at all
+  msg = check_can_parse(callee);
+  if (msg != NULL) {
+    print_inlining(callee, msg, /*success*/ false);
+    return false;
+  }
+
+  // If bytecode not set use the current one.
+  if (bc == Bytecodes::_illegal) {
+    bc = code();
+  }
+  if (try_inline_full(callee, holder_known, bc, receiver))
+    return true;
+  print_inlining(callee, _inline_bailout_msg, /*success*/ false);
+  return false;
+}
+
+
+const char* GraphBuilder::check_can_parse(ciMethod* callee) const {
+  // Certain methods cannot be parsed at all:
+  if ( callee->is_native())            return "native method";
+  if ( callee->is_abstract())          return "abstract method";
+  if (!callee->can_be_compiled())      return "not compilable (disabled)";
+  return NULL;
+}
+
+
+// negative filter: should callee NOT be inlined?  returns NULL, ok to inline, or rejection msg
+const char* GraphBuilder::should_not_inline(ciMethod* callee) const {
+  if ( callee->should_exclude())       return "excluded by CompilerOracle";
+  if ( callee->should_not_inline())    return "disallowed by CompilerOracle";
+  if ( callee->dont_inline())          return "don't inline by annotation";
+  return NULL;
 }
 
 
 bool GraphBuilder::try_inline_intrinsics(ciMethod* callee) {
-  if (!InlineNatives           ) INLINE_BAILOUT("intrinsic method inlining disabled");
   if (callee->is_synchronized()) {
     // We don't currently support any synchronized intrinsics
     return false;
@@ -3124,14 +3254,31 @@
 
   // callee seems like a good candidate
   // determine id
+  vmIntrinsics::ID id = callee->intrinsic_id();
+  if (!InlineNatives && id != vmIntrinsics::_Reference_get) {
+    // InlineNatives does not control Reference.get
+    INLINE_BAILOUT("intrinsic method inlining disabled");
+  }
   bool preserves_state = false;
   bool cantrap = true;
-  vmIntrinsics::ID id = callee->intrinsic_id();
   switch (id) {
-    case vmIntrinsics::_arraycopy     :
+    case vmIntrinsics::_arraycopy:
       if (!InlineArrayCopy) return false;
       break;
 
+#ifdef TRACE_HAVE_INTRINSICS
+    case vmIntrinsics::_classID:
+    case vmIntrinsics::_threadID:
+      preserves_state = true;
+      cantrap = true;
+      break;
+
+    case vmIntrinsics::_counterTime:
+      preserves_state = true;
+      cantrap = false;
+      break;
+#endif
+
     case vmIntrinsics::_currentTimeMillis:
     case vmIntrinsics::_nanoTime:
       preserves_state = true;
@@ -3148,6 +3295,7 @@
       break;
 
     case vmIntrinsics::_getClass      :
+    case vmIntrinsics::_isInstance    :
       if (!InlineClassNatives) return false;
       preserves_state = true;
       break;
@@ -3165,18 +3313,13 @@
     case vmIntrinsics::_dtan          : // fall through
     case vmIntrinsics::_dlog          : // fall through
     case vmIntrinsics::_dlog10        : // fall through
+    case vmIntrinsics::_dexp          : // fall through
+    case vmIntrinsics::_dpow          : // fall through
       if (!InlineMathNatives) return false;
       cantrap = false;
       preserves_state = true;
       break;
 
-    // sun/misc/AtomicLong.attemptUpdate
-    case vmIntrinsics::_attemptUpdate :
-      if (!VM_Version::supports_cx8()) return false;
-      if (!InlineAtomicLong) return false;
-      preserves_state = true;
-      break;
-
     // Use special nodes for Unsafe instructions so we can more easily
     // perform an address-mode optimization on the raw variants
     case vmIntrinsics::_getObject : return append_unsafe_get_obj(callee, T_OBJECT,  false);
@@ -3256,12 +3399,46 @@
       append_unsafe_CAS(callee);
       return true;
 
+    case vmIntrinsics::_getAndAddInt:
+      if (!VM_Version::supports_atomic_getadd4()) {
+        return false;
+      }
+      return append_unsafe_get_and_set_obj(callee, true);
+    case vmIntrinsics::_getAndAddLong:
+      if (!VM_Version::supports_atomic_getadd8()) {
+        return false;
+      }
+      return append_unsafe_get_and_set_obj(callee, true);
+    case vmIntrinsics::_getAndSetInt:
+      if (!VM_Version::supports_atomic_getset4()) {
+        return false;
+      }
+      return append_unsafe_get_and_set_obj(callee, false);
+    case vmIntrinsics::_getAndSetLong:
+      if (!VM_Version::supports_atomic_getset8()) {
+        return false;
+      }
+      return append_unsafe_get_and_set_obj(callee, false);
+    case vmIntrinsics::_getAndSetObject:
+#ifdef _LP64
+      if (!UseCompressedOops && !VM_Version::supports_atomic_getset8()) {
+        return false;
+      }
+      if (UseCompressedOops && !VM_Version::supports_atomic_getset4()) {
+        return false;
+      }
+#else
+      if (!VM_Version::supports_atomic_getset4()) {
+        return false;
+      }
+#endif
+      return append_unsafe_get_and_set_obj(callee, false);
+
     case vmIntrinsics::_Reference_get:
-      // It is only when G1 is enabled that we absolutely
-      // need to use the intrinsic version of Reference.get()
-      // so that the value in the referent field, if necessary,
-      // can be registered by the pre-barrier code.
-      if (!UseG1GC) return false;
+      // Use the intrinsic version of Reference.get() so that the value in
+      // the referent field can be registered by the G1 pre-barrier code.
+      // Also to prevent commoning reads from this field across safepoint
+      // since GC can change its value.
       preserves_state = true;
       break;
 
@@ -3286,7 +3463,7 @@
           recv = args->at(0);
           null_check(recv);
         }
-        profile_call(recv, NULL);
+        profile_call(callee, recv, NULL);
       }
     }
   }
@@ -3297,13 +3474,6 @@
   Value value = append_split(result);
   if (result_type != voidType) push(result_type, value);
 
-#ifndef PRODUCT
-  // printing
-  if (PrintInlining) {
-    print_inline_result(callee, true);
-  }
-#endif
-
   // done
   return true;
 }
@@ -3459,7 +3629,7 @@
 }
 
 
-bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, BlockBegin* cont_block, Value receiver) {
+bool GraphBuilder::try_inline_full(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {
   assert(!callee->is_native(), "callee must not be native");
   if (CompilationPolicy::policy()->should_not_inline(compilation()->env(), callee)) {
     INLINE_BAILOUT("inlining prohibited by policy");
@@ -3487,11 +3657,13 @@
   }
 
   // now perform tests that are based on flag settings
-  if (callee->should_inline()) {
+  if (callee->force_inline() || callee->should_inline()) {
     // ignore heuristic controls on inlining
+    if (callee->force_inline())
+      print_inlining(callee, "force inline by annotation");
   } else {
-    if (inline_level() > MaxInlineLevel                         ) INLINE_BAILOUT("too-deep inlining");
-    if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("too-deep recursive inlining");
+    if (inline_level() > MaxInlineLevel                         ) INLINE_BAILOUT("inlining too deep");
+    if (recursive_inline_level(callee) > MaxRecursiveInlineLevel) INLINE_BAILOUT("recursive inlining too deep");
     if (callee->code_size_for_inlining() > max_inline_size()    ) INLINE_BAILOUT("callee is too large");
 
     // don't inline throwable methods unless the inlining tree is rooted in a throwable class
@@ -3510,28 +3682,25 @@
     if (compilation()->env()->num_inlined_bytecodes() > DesiredMethodLimit) {
       INLINE_BAILOUT("total inlining greater than DesiredMethodLimit");
     }
+    // printing
+    print_inlining(callee);
   }
 
-#ifndef PRODUCT
-      // printing
-  if (PrintInlining) {
-    print_inline_result(callee, true);
-  }
-#endif
-
   // NOTE: Bailouts from this point on, which occur at the
   // GraphBuilder level, do not cause bailout just of the inlining but
   // in fact of the entire compilation.
 
   BlockBegin* orig_block = block();
 
+  const bool is_invokedynamic = bc == Bytecodes::_invokedynamic;
+  const bool has_receiver = (bc != Bytecodes::_invokestatic && !is_invokedynamic);
+
   const int args_base = state()->stack_size() - callee->arg_size();
   assert(args_base >= 0, "stack underflow during inlining");
 
   // Insert null check if necessary
   Value recv = NULL;
-  if (code() != Bytecodes::_invokestatic &&
-      code() != Bytecodes::_invokedynamic) {
+  if (has_receiver) {
     // note: null check must happen even if first instruction of callee does
     //       an implicit null check since the callee is in a different scope
     //       and we must make sure exception handling does the right thing
@@ -3547,7 +3716,7 @@
     compilation()->set_would_profile(true);
 
     if (profile_calls()) {
-      profile_call(recv, holder_known ? callee->holder() : NULL);
+      profile_call(callee, recv, holder_known ? callee->holder() : NULL);
     }
   }
 
@@ -3556,7 +3725,7 @@
   // fall-through of control flow, all return instructions of the
   // callee will need to be replaced by Goto's pointing to this
   // continuation point.
-  BlockBegin* cont = cont_block != NULL ? cont_block : block_at(next_bci());
+  BlockBegin* cont = block_at(next_bci());
   bool continuation_existed = true;
   if (cont == NULL) {
     cont = new BlockBegin(next_bci());
@@ -3589,17 +3758,10 @@
   // note: this will also ensure that all arguments are computed before being passed
   ValueStack* callee_state = state();
   ValueStack* caller_state = state()->caller_state();
-  { int i = args_base;
-    while (i < caller_state->stack_size()) {
-      const int par_no = i - args_base;
-      Value  arg = caller_state->stack_at_inc(i);
-      // NOTE: take base() of arg->type() to avoid problems storing
-      // constants
-      if (receiver != NULL && par_no == 0) {
-        arg = receiver;
-      }
-      store_local(callee_state, arg, arg->type()->base(), par_no);
-    }
+  for (int i = args_base; i < caller_state->stack_size(); ) {
+    const int arg_no = i - args_base;
+    Value arg = caller_state->stack_at_inc(i);
+    store_local(callee_state, arg, arg_no);
   }
 
   // Remove args from stack.
@@ -3675,29 +3837,27 @@
   // block merging. This allows load elimination and CSE to take place
   // across multiple callee scopes if they are relatively simple, and
   // is currently essential to making inlining profitable.
-  if (cont_block == NULL) {
-    if (num_returns() == 1
-        && block() == orig_block
-        && block() == inline_cleanup_block()) {
-      _last  = inline_cleanup_return_prev();
-      _state = inline_cleanup_state();
-    } else if (continuation_preds == cont->number_of_preds()) {
-      // Inlining caused that the instructions after the invoke in the
-      // caller are not reachable any more. So skip filling this block
-      // with instructions!
-      assert(cont == continuation(), "");
+  if (num_returns() == 1
+      && block() == orig_block
+      && block() == inline_cleanup_block()) {
+    _last  = inline_cleanup_return_prev();
+    _state = inline_cleanup_state();
+  } else if (continuation_preds == cont->number_of_preds()) {
+    // Inlining caused that the instructions after the invoke in the
+    // caller are not reachable any more. So skip filling this block
+    // with instructions!
+    assert(cont == continuation(), "");
+    assert(_last && _last->as_BlockEnd(), "");
+    _skip_block = true;
+  } else {
+    // Resume parsing in continuation block unless it was already parsed.
+    // Note that if we don't change _last here, iteration in
+    // iterate_bytecodes_for_block will stop when we return.
+    if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
+      // add continuation to work list instead of parsing it immediately
       assert(_last && _last->as_BlockEnd(), "");
+      scope_data()->parent()->add_to_work_list(continuation());
       _skip_block = true;
-    } else {
-      // Resume parsing in continuation block unless it was already parsed.
-      // Note that if we don't change _last here, iteration in
-      // iterate_bytecodes_for_block will stop when we return.
-      if (!continuation()->is_set(BlockBegin::was_visited_flag)) {
-        // add continuation to work list instead of parsing it immediately
-        assert(_last && _last->as_BlockEnd(), "");
-        scope_data()->parent()->add_to_work_list(continuation());
-        _skip_block = true;
-      }
     }
   }
 
@@ -3714,115 +3874,98 @@
 }
 
 
-bool GraphBuilder::for_method_handle_inline(ciMethod* callee) {
-  assert(!callee->is_static(), "change next line");
-  int index = state()->stack_size() - (callee->arg_size_no_receiver() + 1);
-  Value receiver = state()->stack_at(index);
-
-  if (receiver->type()->is_constant()) {
-    ciMethodHandle* method_handle = receiver->type()->as_ObjectType()->constant_value()->as_method_handle();
-
-    // Set the callee to have access to the class and signature in
-    // the MethodHandleCompiler.
-    method_handle->set_callee(callee);
-    method_handle->set_caller(method());
-
-    // Get an adapter for the MethodHandle.
-    ciMethod* method_handle_adapter = method_handle->get_method_handle_adapter();
-    if (method_handle_adapter != NULL) {
-      return try_inline(method_handle_adapter, /*holder_known=*/ true);
-    }
-  } else if (receiver->as_CheckCast()) {
-    // Match MethodHandle.selectAlternative idiom
-    Phi* phi = receiver->as_CheckCast()->obj()->as_Phi();
-
-    if (phi != NULL && phi->operand_count() == 2) {
-      // Get the two MethodHandle inputs from the Phi.
-      Value op1 = phi->operand_at(0);
-      Value op2 = phi->operand_at(1);
-      ObjectType* op1type = op1->type()->as_ObjectType();
-      ObjectType* op2type = op2->type()->as_ObjectType();
-
-      if (op1type->is_constant() && op2type->is_constant()) {
-        ciMethodHandle* mh1 = op1type->constant_value()->as_method_handle();
-        ciMethodHandle* mh2 = op2type->constant_value()->as_method_handle();
-
-        // Set the callee to have access to the class and signature in
-        // the MethodHandleCompiler.
-        mh1->set_callee(callee);
-        mh1->set_caller(method());
-        mh2->set_callee(callee);
-        mh2->set_caller(method());
-
-        // Get adapters for the MethodHandles.
-        ciMethod* mh1_adapter = mh1->get_method_handle_adapter();
-        ciMethod* mh2_adapter = mh2->get_method_handle_adapter();
-
-        if (mh1_adapter != NULL && mh2_adapter != NULL) {
-          set_inline_cleanup_info();
-
-          // Build the If guard
-          BlockBegin* one = new BlockBegin(next_bci());
-          BlockBegin* two = new BlockBegin(next_bci());
-          BlockBegin* end = new BlockBegin(next_bci());
-          Instruction* iff = append(new If(phi, If::eql, false, op1, one, two, NULL, false));
-          block()->set_end(iff->as_BlockEnd());
-
-          // Connect up the states
-          one->merge(block()->end()->state());
-          two->merge(block()->end()->state());
-
-          // Save the state for the second inlinee
-          ValueStack* state_before = copy_state_before();
-
-          // Parse first adapter
-          _last = _block = one;
-          if (!try_inline_full(mh1_adapter, /*holder_known=*/ true, end, NULL)) {
-            restore_inline_cleanup_info();
-            block()->clear_end();  // remove appended iff
-            return false;
+bool GraphBuilder::try_method_handle_inline(ciMethod* callee) {
+  ValueStack* state_before = state()->copy_for_parsing();
+  vmIntrinsics::ID iid = callee->intrinsic_id();
+  switch (iid) {
+  case vmIntrinsics::_invokeBasic:
+    {
+      // get MethodHandle receiver
+      const int args_base = state()->stack_size() - callee->arg_size();
+      ValueType* type = state()->stack_at(args_base)->type();
+      if (type->is_constant()) {
+        ciMethod* target = type->as_ObjectType()->constant_value()->as_method_handle()->get_vmtarget();
+        // We don't do CHA here so only inline static and statically bindable methods.
+        if (target->is_static() || target->can_be_statically_bound()) {
+          Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
+          if (try_inline(target, /*holder_known*/ true, bc)) {
+            return true;
           }
-
-          // Parse second adapter
-          _last = _block = two;
-          _state = state_before;
-          if (!try_inline_full(mh2_adapter, /*holder_known=*/ true, end, NULL)) {
-            restore_inline_cleanup_info();
-            block()->clear_end();  // remove appended iff
-            return false;
-          }
-
-          connect_to_end(end);
-          return true;
+        } else {
+          print_inlining(target, "not static or statically bindable", /*success*/ false);
         }
+      } else {
+        print_inlining(callee, "receiver not constant", /*success*/ false);
       }
     }
-  }
-  return false;
-}
+    break;
 
-
-bool GraphBuilder::for_invokedynamic_inline(ciMethod* callee) {
-  // Get the MethodHandle from the CallSite.
-  ciCallSite*     call_site     = stream()->get_call_site();
-  ciMethodHandle* method_handle = call_site->get_target();
-
-  // Set the callee to have access to the class and signature in the
-  // MethodHandleCompiler.
-  method_handle->set_callee(callee);
-  method_handle->set_caller(method());
-
-  // Get an adapter for the MethodHandle.
-  ciMethod* method_handle_adapter = method_handle->get_invokedynamic_adapter();
-  if (method_handle_adapter != NULL) {
-    if (try_inline(method_handle_adapter, /*holder_known=*/ true)) {
-      // Add a dependence for invalidation of the optimization.
-      if (!call_site->is_constant_call_site()) {
-        dependency_recorder()->assert_call_site_target_value(call_site, method_handle);
+  case vmIntrinsics::_linkToVirtual:
+  case vmIntrinsics::_linkToStatic:
+  case vmIntrinsics::_linkToSpecial:
+  case vmIntrinsics::_linkToInterface:
+    {
+      // pop MemberName argument
+      const int args_base = state()->stack_size() - callee->arg_size();
+      ValueType* type = apop()->type();
+      if (type->is_constant()) {
+        ciMethod* target = type->as_ObjectType()->constant_value()->as_member_name()->get_vmtarget();
+        // If the target is another method handle invoke try recursivly to get
+        // a better target.
+        if (target->is_method_handle_intrinsic()) {
+          if (try_method_handle_inline(target)) {
+            return true;
+          }
+        } else {
+          ciSignature* signature = target->signature();
+          const int receiver_skip = target->is_static() ? 0 : 1;
+          // Cast receiver to its type.
+          if (!target->is_static()) {
+            ciKlass* tk = signature->accessing_klass();
+            Value obj = state()->stack_at(args_base);
+            if (obj->exact_type() == NULL &&
+                obj->declared_type() != tk && tk != compilation()->env()->Object_klass()) {
+              TypeCast* c = new TypeCast(tk, obj, state_before);
+              append(c);
+              state()->stack_at_put(args_base, c);
+            }
+          }
+          // Cast reference arguments to its type.
+          for (int i = 0, j = 0; i < signature->count(); i++) {
+            ciType* t = signature->type_at(i);
+            if (t->is_klass()) {
+              ciKlass* tk = t->as_klass();
+              Value obj = state()->stack_at(args_base + receiver_skip + j);
+              if (obj->exact_type() == NULL &&
+                  obj->declared_type() != tk && tk != compilation()->env()->Object_klass()) {
+                TypeCast* c = new TypeCast(t, obj, state_before);
+                append(c);
+                state()->stack_at_put(args_base + receiver_skip + j, c);
+              }
+            }
+            j += t->size();  // long and double take two slots
+          }
+          // We don't do CHA here so only inline static and statically bindable methods.
+          if (target->is_static() || target->can_be_statically_bound()) {
+            Bytecodes::Code bc = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual;
+            if (try_inline(target, /*holder_known*/ true, bc)) {
+              return true;
+            }
+          } else {
+            print_inlining(target, "not static or statically bindable", /*success*/ false);
+          }
+        }
+      } else {
+        print_inlining(callee, "MemberName not constant", /*success*/ false);
       }
-      return true;
     }
+    break;
+
+  default:
+    fatal(err_msg("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+    break;
   }
+  set_state(state_before);
   return false;
 }
 
@@ -4014,22 +4157,51 @@
 }
 
 
-#ifndef PRODUCT
-void GraphBuilder::print_inline_result(ciMethod* callee, bool res) {
-  CompileTask::print_inlining(callee, scope()->level(), bci(), _inline_bailout_msg);
-  if (res && CIPrintMethodCodes) {
+void GraphBuilder::print_inlining(ciMethod* callee, const char* msg, bool success) {
+  CompileLog* log = compilation()->log();
+  if (log != NULL) {
+    if (success) {
+      if (msg != NULL)
+        log->inline_success(msg);
+      else
+        log->inline_success("receiver is statically known");
+    } else {
+      log->inline_fail(msg);
+    }
+  }
+
+  if (!PrintInlining)  return;
+  CompileTask::print_inlining(callee, scope()->level(), bci(), msg);
+  if (success && CIPrintMethodCodes) {
     callee->print_codes();
   }
 }
 
+bool GraphBuilder::append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add) {
+  if (InlineUnsafeOps) {
+    Values* args = state()->pop_arguments(callee->arg_size());
+    BasicType t = callee->return_type()->basic_type();
+    null_check(args->at(0));
+    Instruction* offset = args->at(2);
+#ifndef _LP64
+    offset = append(new Convert(Bytecodes::_l2i, offset, as_ValueType(T_INT)));
+#endif
+    Instruction* op = append(new UnsafeGetAndSetObject(t, args->at(1), offset, args->at(3), is_add));
+    compilation()->set_has_unsafe_access(true);
+    kill_all();
+    push(op->type(), op);
+  }
+  return InlineUnsafeOps;
+}
 
+#ifndef PRODUCT
 void GraphBuilder::print_stats() {
   vmap()->print();
 }
 #endif // PRODUCT
 
-void GraphBuilder::profile_call(Value recv, ciKlass* known_holder) {
-  append(new ProfileCall(method(), bci(), recv, known_holder));
+void GraphBuilder::profile_call(ciMethod* callee, Value recv, ciKlass* known_holder) {
+  append(new ProfileCall(method(), bci(), callee, recv, known_holder));
 }
 
 void GraphBuilder::profile_invocation(ciMethod* callee, ValueStack* state) {
diff --git a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp
index aa8f45f..5f9e407 100644
--- a/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp
+++ b/hotspot/src/share/vm/c1/c1_GraphBuilder.hpp
@@ -31,6 +31,7 @@
 #include "c1/c1_ValueStack.hpp"
 #include "ci/ciMethodData.hpp"
 #include "ci/ciStreams.hpp"
+#include "compiler/compileLog.hpp"
 
 class MemoryBuffer;
 
@@ -225,7 +226,7 @@
   void load_constant();
   void load_local(ValueType* type, int index);
   void store_local(ValueType* type, int index);
-  void store_local(ValueStack* state, Value value, ValueType* type, int index);
+  void store_local(ValueStack* state, Value value, int index);
   void load_indexed (BasicType type);
   void store_indexed(BasicType type);
   void stack_op(Bytecodes::Code code);
@@ -337,14 +338,16 @@
   void fill_sync_handler(Value lock, BlockBegin* sync_handler, bool default_handler = false);
 
   // inliners
-  bool try_inline(           ciMethod* callee, bool holder_known, Value receiver = NULL);
+  bool try_inline(           ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
   bool try_inline_intrinsics(ciMethod* callee);
-  bool try_inline_full(      ciMethod* callee, bool holder_known, BlockBegin* cont_block, Value receiver);
+  bool try_inline_full(      ciMethod* callee, bool holder_known, Bytecodes::Code bc = Bytecodes::_illegal, Value receiver = NULL);
   bool try_inline_jsr(int jsr_dest_bci);
 
+  const char* check_can_parse(ciMethod* callee) const;
+  const char* should_not_inline(ciMethod* callee) const;
+
   // JSR 292 support
-  bool for_method_handle_inline(ciMethod* callee);
-  bool for_invokedynamic_inline(ciMethod* callee);
+  bool try_method_handle_inline(ciMethod* callee);
 
   // helpers
   void inline_bailout(const char* msg);
@@ -365,10 +368,11 @@
   bool append_unsafe_put_raw(ciMethod* callee, BasicType t);
   bool append_unsafe_prefetch(ciMethod* callee, bool is_store, bool is_static);
   void append_unsafe_CAS(ciMethod* callee);
+  bool append_unsafe_get_and_set_obj(ciMethod* callee, bool is_add);
 
-  NOT_PRODUCT(void print_inline_result(ciMethod* callee, bool res);)
+  void print_inlining(ciMethod* callee, const char* msg = NULL, bool success = true);
 
-  void profile_call(Value recv, ciKlass* predicted_holder);
+  void profile_call(ciMethod* callee, Value recv, ciKlass* predicted_holder);
   void profile_invocation(ciMethod* inlinee, ValueStack* state);
 
   // Shortcuts to profiling control.
diff --git a/hotspot/src/share/vm/c1/c1_Instruction.cpp b/hotspot/src/share/vm/c1/c1_Instruction.cpp
index c723193..590f8ec 100644
--- a/hotspot/src/share/vm/c1/c1_Instruction.cpp
+++ b/hotspot/src/share/vm/c1/c1_Instruction.cpp
@@ -161,6 +161,12 @@
   return NULL;
 }
 
+ciType* Constant::exact_type() const {
+  if (type()->is_object()) {
+    return type()->as_ObjectType()->exact_type();
+  }
+  return NULL;
+}
 
 ciType* LoadIndexed::exact_type() const {
   ciType* array_type = array()->exact_type();
@@ -363,9 +369,6 @@
   _signature = new BasicTypeList(number_of_arguments() + (has_receiver() ? 1 : 0));
   if (has_receiver()) {
     _signature->append(as_BasicType(receiver()->type()));
-  } else if (is_invokedynamic()) {
-    // Add the synthetic MethodHandle argument to the signature.
-    _signature->append(T_OBJECT);
   }
   for (int i = 0; i < number_of_arguments(); i++) {
     ValueType* t = argument_at(i)->type();
diff --git a/hotspot/src/share/vm/c1/c1_Instruction.hpp b/hotspot/src/share/vm/c1/c1_Instruction.hpp
index 9cdef87..f2c28c1 100644
--- a/hotspot/src/share/vm/c1/c1_Instruction.hpp
+++ b/hotspot/src/share/vm/c1/c1_Instruction.hpp
@@ -66,6 +66,7 @@
 class     IfOp;
 class   Convert;
 class   NullCheck;
+class   TypeCast;
 class   OsrEntry;
 class   ExceptionObject;
 class   StateSplit;
@@ -101,6 +102,7 @@
 class     UnsafeObjectOp;
 class       UnsafeGetObject;
 class       UnsafePutObject;
+class         UnsafeGetAndSetObject;
 class       UnsafePrefetch;
 class         UnsafePrefetchRead;
 class         UnsafePrefetchWrite;
@@ -174,6 +176,7 @@
   virtual void do_IfOp           (IfOp*            x) = 0;
   virtual void do_Convert        (Convert*         x) = 0;
   virtual void do_NullCheck      (NullCheck*       x) = 0;
+  virtual void do_TypeCast       (TypeCast*        x) = 0;
   virtual void do_Invoke         (Invoke*          x) = 0;
   virtual void do_NewInstance    (NewInstance*     x) = 0;
   virtual void do_NewTypeArray   (NewTypeArray*    x) = 0;
@@ -200,6 +203,7 @@
   virtual void do_UnsafePutRaw   (UnsafePutRaw*    x) = 0;
   virtual void do_UnsafeGetObject(UnsafeGetObject* x) = 0;
   virtual void do_UnsafePutObject(UnsafePutObject* x) = 0;
+  virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) = 0;
   virtual void do_UnsafePrefetchRead (UnsafePrefetchRead*  x) = 0;
   virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) = 0;
   virtual void do_ProfileCall    (ProfileCall*     x) = 0;
@@ -302,9 +306,8 @@
 
   void update_exception_state(ValueStack* state);
 
-  bool has_printable_bci() const                 { return NOT_PRODUCT(_printable_bci != -99) PRODUCT_ONLY(false); }
-
- protected:
+ //protected:
+ public:
   void set_type(ValueType* type) {
     assert(type != NULL, "type must exist");
     _type = type;
@@ -392,8 +395,9 @@
   // accessors
   int id() const                                 { return _id; }
 #ifndef PRODUCT
+  bool has_printable_bci() const                 { return _printable_bci != -99; }
   int printable_bci() const                      { assert(has_printable_bci(), "_printable_bci should have been set"); return _printable_bci; }
-  void set_printable_bci(int bci)                { NOT_PRODUCT(_printable_bci = bci;) }
+  void set_printable_bci(int bci)                { _printable_bci = bci; }
 #endif
   int use_count() const                          { return _use_count; }
   int pin_state() const                          { return _pin_state; }
@@ -486,6 +490,7 @@
   virtual TypeCheck*        as_TypeCheck()       { return NULL; }
   virtual CheckCast*        as_CheckCast()       { return NULL; }
   virtual InstanceOf*       as_InstanceOf()      { return NULL; }
+  virtual TypeCast*         as_TypeCast()        { return NULL; }
   virtual AccessMonitor*    as_AccessMonitor()   { return NULL; }
   virtual MonitorEnter*     as_MonitorEnter()    { return NULL; }
   virtual MonitorExit*      as_MonitorExit()     { return NULL; }
@@ -576,6 +581,7 @@
   , _block(b)
   , _index(index)
   {
+    NOT_PRODUCT(set_printable_bci(Value(b)->printable_bci()));
     if (type->is_illegal()) {
       make_illegal();
     }
@@ -631,13 +637,15 @@
     : Instruction(type)
     , _java_index(index)
     , _declared_type(declared)
-  {}
+  {
+    NOT_PRODUCT(set_printable_bci(-1));
+  }
 
   // accessors
   int java_index() const                         { return _java_index; }
 
-  ciType* declared_type() const                  { return _declared_type; }
-  ciType* exact_type() const;
+  virtual ciType* declared_type() const          { return _declared_type; }
+  virtual ciType* exact_type() const;
 
   // generic
   virtual void input_values_do(ValueVisitor* f)   { /* no values */ }
@@ -648,13 +656,13 @@
  public:
   // creation
   Constant(ValueType* type):
-      Instruction(type, NULL, true)
+      Instruction(type, NULL, /*type_is_constant*/ true)
   {
     assert(type->is_constant(), "must be a constant");
   }
 
   Constant(ValueType* type, ValueStack* state_before):
-    Instruction(type, state_before, true)
+    Instruction(type, state_before, /*type_is_constant*/ true)
   {
     assert(state_before != NULL, "only used for constants which need patching");
     assert(type->is_constant(), "must be a constant");
@@ -668,6 +676,7 @@
   virtual intx hash() const;
   virtual bool is_equal(Value v) const;
 
+  virtual ciType* exact_type() const;
 
   enum CompareResult { not_comparable = -1, cond_false, cond_true };
 
@@ -1101,6 +1110,29 @@
 };
 
 
+// This node is supposed to cast the type of another node to a more precise
+// declared type.
+LEAF(TypeCast, Instruction)
+ private:
+  ciType* _declared_type;
+  Value   _obj;
+
+ public:
+  // The type of this node is the same type as the object type (and it might be constant).
+  TypeCast(ciType* type, Value obj, ValueStack* state_before)
+  : Instruction(obj->type(), state_before, obj->type()->is_constant()),
+    _declared_type(type),
+    _obj(obj) {}
+
+  // accessors
+  ciType* declared_type() const                  { return _declared_type; }
+  Value   obj() const                            { return _obj; }
+
+  // generic
+  virtual void input_values_do(ValueVisitor* f)  { f->visit(&_obj); }
+};
+
+
 BASE(StateSplit, Instruction)
  private:
   ValueStack* _state;
@@ -1164,6 +1196,7 @@
 
   // JSR 292 support
   bool is_invokedynamic() const                  { return code() == Bytecodes::_invokedynamic; }
+  bool is_method_handle_intrinsic() const        { return target()->is_method_handle_intrinsic(); }
 
   virtual bool needs_exception_state() const     { return false; }
 
@@ -2242,6 +2275,27 @@
                                                    f->visit(&_value); }
 };
 
+LEAF(UnsafeGetAndSetObject, UnsafeObjectOp)
+ private:
+  Value _value;                                  // Value to be stored
+  bool  _is_add;
+ public:
+  UnsafeGetAndSetObject(BasicType basic_type, Value object, Value offset, Value value, bool is_add)
+  : UnsafeObjectOp(basic_type, object, offset, false, false)
+    , _value(value)
+    , _is_add(is_add)
+  {
+    ASSERT_VALUES
+  }
+
+  // accessors
+  bool is_add() const                            { return _is_add; }
+  Value value()                                  { return _value; }
+
+  // generic
+  virtual void input_values_do(ValueVisitor* f)   { UnsafeObjectOp::input_values_do(f);
+                                                   f->visit(&_value); }
+};
 
 BASE(UnsafePrefetch, UnsafeObjectOp)
  public:
@@ -2275,14 +2329,16 @@
  private:
   ciMethod* _method;
   int       _bci_of_invoke;
+  ciMethod* _callee;         // the method that is called at the given bci
   Value     _recv;
   ciKlass*  _known_holder;
 
  public:
-  ProfileCall(ciMethod* method, int bci, Value recv, ciKlass* known_holder)
+  ProfileCall(ciMethod* method, int bci, ciMethod* callee, Value recv, ciKlass* known_holder)
     : Instruction(voidType)
     , _method(method)
     , _bci_of_invoke(bci)
+    , _callee(callee)
     , _recv(recv)
     , _known_holder(known_holder)
   {
@@ -2292,6 +2348,7 @@
 
   ciMethod* method()      { return _method; }
   int bci_of_invoke()     { return _bci_of_invoke; }
+  ciMethod* callee()      { return _callee; }
   Value recv()            { return _recv; }
   ciKlass* known_holder() { return _known_holder; }
 
diff --git a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp
index 88b0b3c..9a1b4dd 100644
--- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp
+++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.cpp
@@ -137,12 +137,16 @@
       ciMethod* m = (ciMethod*)value;
       output()->print("<method %s.%s>", m->holder()->name()->as_utf8(), m->name()->as_utf8());
     } else {
-      output()->print("<object " PTR_FORMAT ">", value->constant_encoding());
+      output()->print("<object " PTR_FORMAT " klass=", value->constant_encoding());
+      print_klass(value->klass());
+      output()->print(">");
     }
   } else if (type->as_InstanceConstant() != NULL) {
     ciInstance* value = type->as_InstanceConstant()->value();
     if (value->is_loaded()) {
-      output()->print("<instance " PTR_FORMAT ">", value->constant_encoding());
+      output()->print("<instance " PTR_FORMAT " klass=", value->constant_encoding());
+      print_klass(value->klass());
+      output()->print(">");
     } else {
       output()->print("<unloaded instance " PTR_FORMAT ">", value);
     }
@@ -453,6 +457,14 @@
 }
 
 
+void InstructionPrinter::do_TypeCast(TypeCast* x) {
+  output()->print("type_cast(");
+  print_value(x->obj());
+  output()->print(") ");
+  print_klass(x->declared_type()->klass());
+}
+
+
 void InstructionPrinter::do_Invoke(Invoke* x) {
   if (x->receiver() != NULL) {
     print_value(x->receiver());
@@ -816,6 +828,12 @@
   output()->put(')');
 }
 
+void InstructionPrinter::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {
+  print_unsafe_object_op(x, x->is_add()?"UnsafeGetAndSetObject (add)":"UnsafeGetAndSetObject");
+  output()->print(", value ");
+  print_value(x->value());
+  output()->put(')');
+}
 
 void InstructionPrinter::do_UnsafePrefetchRead(UnsafePrefetchRead* x) {
   print_unsafe_object_op(x, "UnsafePrefetchRead");
diff --git a/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp b/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp
index de6bff4..a89908c 100644
--- a/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp
+++ b/hotspot/src/share/vm/c1/c1_InstructionPrinter.hpp
@@ -101,6 +101,7 @@
   virtual void do_IfOp           (IfOp*            x);
   virtual void do_Convert        (Convert*         x);
   virtual void do_NullCheck      (NullCheck*       x);
+  virtual void do_TypeCast       (TypeCast*        x);
   virtual void do_Invoke         (Invoke*          x);
   virtual void do_NewInstance    (NewInstance*     x);
   virtual void do_NewTypeArray   (NewTypeArray*    x);
@@ -127,6 +128,7 @@
   virtual void do_UnsafePutRaw   (UnsafePutRaw*    x);
   virtual void do_UnsafeGetObject(UnsafeGetObject* x);
   virtual void do_UnsafePutObject(UnsafePutObject* x);
+  virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);
   virtual void do_UnsafePrefetchRead (UnsafePrefetchRead*  x);
   virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
   virtual void do_ProfileCall    (ProfileCall*     x);
diff --git a/hotspot/src/share/vm/c1/c1_LIR.cpp b/hotspot/src/share/vm/c1/c1_LIR.cpp
index 776a6a3..23d92f0 100644
--- a/hotspot/src/share/vm/c1/c1_LIR.cpp
+++ b/hotspot/src/share/vm/c1/c1_LIR.cpp
@@ -255,6 +255,7 @@
 #ifdef ASSERT
   switch (code()) {
     case lir_cmove:
+    case lir_xchg:
       break;
 
     default:
@@ -621,15 +622,26 @@
     case lir_shl:
     case lir_shr:
     case lir_ushr:
+    case lir_xadd:
+    case lir_xchg:
     {
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
+      assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+             op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
 
       if (op2->_info)                     do_info(op2->_info);
       if (op2->_opr1->is_valid())         do_input(op2->_opr1);
       if (op2->_opr2->is_valid())         do_input(op2->_opr2);
-      if (op2->_tmp->is_valid())          do_temp(op2->_tmp);
+      if (op2->_tmp1->is_valid())         do_temp(op2->_tmp1);
       if (op2->_result->is_valid())       do_output(op2->_result);
+      if (op->code() == lir_xchg || op->code() == lir_xadd) {
+        // on ARM and PPC, return value is loaded first so could
+        // destroy inputs. On other platforms that implement those
+        // (x86, sparc), the extra constrainsts are harmless.
+        if (op2->_opr1->is_valid())       do_temp(op2->_opr1);
+        if (op2->_opr2->is_valid())       do_temp(op2->_opr2);
+      }
 
       break;
     }
@@ -641,7 +653,8 @@
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
 
-      assert(op2->_info == NULL && op2->_tmp->is_illegal(), "not used");
+      assert(op2->_info == NULL && op2->_tmp1->is_illegal() && op2->_tmp2->is_illegal() &&
+             op2->_tmp3->is_illegal() && op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
       assert(op2->_opr1->is_valid() && op2->_opr2->is_valid() && op2->_result->is_valid(), "used");
 
       do_input(op2->_opr1);
@@ -665,10 +678,12 @@
       assert(op2->_opr1->is_valid(), "used");
       assert(op2->_opr2->is_valid(), "used");
       assert(op2->_result->is_valid(), "used");
+      assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+             op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
 
       do_input(op2->_opr1); do_temp(op2->_opr1);
       do_input(op2->_opr2); do_temp(op2->_opr2);
-      if (op2->_tmp->is_valid()) do_temp(op2->_tmp);
+      if (op2->_tmp1->is_valid()) do_temp(op2->_tmp1);
       do_output(op2->_result);
 
       break;
@@ -682,6 +697,8 @@
       if (op2->_opr1->is_valid())         do_temp(op2->_opr1);
       if (op2->_opr2->is_valid())         do_input(op2->_opr2); // exception object is input parameter
       assert(op2->_result->is_illegal(), "no result");
+      assert(op2->_tmp2->is_illegal() && op2->_tmp3->is_illegal() &&
+             op2->_tmp4->is_illegal() && op2->_tmp5->is_illegal(), "not used");
 
       break;
     }
@@ -702,7 +719,8 @@
     case lir_sin:
     case lir_cos:
     case lir_log:
-    case lir_log10: {
+    case lir_log10:
+    case lir_exp: {
       assert(op->as_Op2() != NULL, "must be");
       LIR_Op2* op2 = (LIR_Op2*)op;
 
@@ -711,16 +729,47 @@
       // Register input operand as temp to guarantee that it doesn't
       // overlap with the input.
       assert(op2->_info == NULL, "not used");
+      assert(op2->_tmp5->is_illegal(), "not used");
+      assert(op2->_tmp2->is_valid() == (op->code() == lir_exp), "not used");
+      assert(op2->_tmp3->is_valid() == (op->code() == lir_exp), "not used");
+      assert(op2->_tmp4->is_valid() == (op->code() == lir_exp), "not used");
       assert(op2->_opr1->is_valid(), "used");
       do_input(op2->_opr1); do_temp(op2->_opr1);
 
       if (op2->_opr2->is_valid())         do_temp(op2->_opr2);
-      if (op2->_tmp->is_valid())          do_temp(op2->_tmp);
+      if (op2->_tmp1->is_valid())         do_temp(op2->_tmp1);
+      if (op2->_tmp2->is_valid())         do_temp(op2->_tmp2);
+      if (op2->_tmp3->is_valid())         do_temp(op2->_tmp3);
+      if (op2->_tmp4->is_valid())         do_temp(op2->_tmp4);
       if (op2->_result->is_valid())       do_output(op2->_result);
 
       break;
     }
 
+    case lir_pow: {
+      assert(op->as_Op2() != NULL, "must be");
+      LIR_Op2* op2 = (LIR_Op2*)op;
+
+      // On x86 pow needs two temporary fpu stack slots: tmp1 and
+      // tmp2. Register input operands as temps to guarantee that it
+      // doesn't overlap with the temporary slots.
+      assert(op2->_info == NULL, "not used");
+      assert(op2->_opr1->is_valid() && op2->_opr2->is_valid(), "used");
+      assert(op2->_tmp1->is_valid() && op2->_tmp2->is_valid() && op2->_tmp3->is_valid()
+             && op2->_tmp4->is_valid() && op2->_tmp5->is_valid(), "used");
+      assert(op2->_result->is_valid(), "used");
+
+      do_input(op2->_opr1); do_temp(op2->_opr1);
+      do_input(op2->_opr2); do_temp(op2->_opr2);
+      do_temp(op2->_tmp1);
+      do_temp(op2->_tmp2);
+      do_temp(op2->_tmp3);
+      do_temp(op2->_tmp4);
+      do_temp(op2->_tmp5);
+      do_output(op2->_result);
+
+      break;
+    }
 
 // LIR_Op3
     case lir_idiv:
@@ -1670,6 +1719,8 @@
      case lir_tan:                   s = "tan";           break;
      case lir_log:                   s = "log";           break;
      case lir_log10:                 s = "log10";         break;
+     case lir_exp:                   s = "exp";           break;
+     case lir_pow:                   s = "pow";           break;
      case lir_logic_and:             s = "logic_and";     break;
      case lir_logic_or:              s = "logic_or";      break;
      case lir_logic_xor:             s = "logic_xor";     break;
@@ -1677,6 +1728,8 @@
      case lir_shr:                   s = "shift_right";   break;
      case lir_ushr:                  s = "ushift_right";  break;
      case lir_alloc_array:           s = "alloc_array";   break;
+     case lir_xadd:                  s = "xadd";          break;
+     case lir_xchg:                  s = "xchg";          break;
      // LIR_Op3
      case lir_idiv:                  s = "idiv";          break;
      case lir_irem:                  s = "irem";          break;
@@ -1892,7 +1945,11 @@
   }
   in_opr1()->print(out);    out->print(" ");
   in_opr2()->print(out);    out->print(" ");
-  if (tmp_opr()->is_valid()) { tmp_opr()->print(out);    out->print(" "); }
+  if (tmp1_opr()->is_valid()) { tmp1_opr()->print(out);    out->print(" "); }
+  if (tmp2_opr()->is_valid()) { tmp2_opr()->print(out);    out->print(" "); }
+  if (tmp3_opr()->is_valid()) { tmp3_opr()->print(out);    out->print(" "); }
+  if (tmp4_opr()->is_valid()) { tmp4_opr()->print(out);    out->print(" "); }
+  if (tmp5_opr()->is_valid()) { tmp5_opr()->print(out);    out->print(" "); }
   result_opr()->print(out);
 }
 
diff --git a/hotspot/src/share/vm/c1/c1_LIR.hpp b/hotspot/src/share/vm/c1/c1_LIR.hpp
index f8589c3..2f3acf0 100644
--- a/hotspot/src/share/vm/c1/c1_LIR.hpp
+++ b/hotspot/src/share/vm/c1/c1_LIR.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 #define SHARE_VM_C1_C1_LIR_HPP
 
 #include "c1/c1_ValueType.hpp"
+#include "oops/methodOop.hpp"
 
 class BlockBegin;
 class BlockList;
@@ -916,6 +917,8 @@
       , lir_tan
       , lir_log
       , lir_log10
+      , lir_exp
+      , lir_pow
       , lir_logic_and
       , lir_logic_or
       , lir_logic_xor
@@ -925,6 +928,8 @@
       , lir_alloc_array
       , lir_throw
       , lir_compare_to
+      , lir_xadd
+      , lir_xchg
   , end_op2
   , begin_op3
       , lir_idiv
@@ -1160,8 +1165,9 @@
     return
       is_invokedynamic()  // An invokedynamic is always a MethodHandle call site.
       ||
-      (method()->holder()->name() == ciSymbol::java_lang_invoke_MethodHandle() &&
-       methodOopDesc::is_method_handle_invoke_name(method()->name()->sid()));
+      method()->is_compiled_lambda_form()  // Java-generated adapter
+      ||
+      method()->is_method_handle_intrinsic();  // JVM-generated MH intrinsic
   }
 
   intptr_t vtable_offset() const {
@@ -1560,7 +1566,11 @@
   LIR_Opr   _opr1;
   LIR_Opr   _opr2;
   BasicType _type;
-  LIR_Opr   _tmp;
+  LIR_Opr   _tmp1;
+  LIR_Opr   _tmp2;
+  LIR_Opr   _tmp3;
+  LIR_Opr   _tmp4;
+  LIR_Opr   _tmp5;
   LIR_Condition _condition;
 
   void verify() const;
@@ -1573,7 +1583,11 @@
     , _type(T_ILLEGAL)
     , _condition(condition)
     , _fpu_stack_size(0)
-    , _tmp(LIR_OprFact::illegalOpr) {
+    , _tmp1(LIR_OprFact::illegalOpr)
+    , _tmp2(LIR_OprFact::illegalOpr)
+    , _tmp3(LIR_OprFact::illegalOpr)
+    , _tmp4(LIR_OprFact::illegalOpr)
+    , _tmp5(LIR_OprFact::illegalOpr) {
     assert(code == lir_cmp, "code check");
   }
 
@@ -1584,7 +1598,11 @@
     , _type(type)
     , _condition(condition)
     , _fpu_stack_size(0)
-    , _tmp(LIR_OprFact::illegalOpr) {
+    , _tmp1(LIR_OprFact::illegalOpr)
+    , _tmp2(LIR_OprFact::illegalOpr)
+    , _tmp3(LIR_OprFact::illegalOpr)
+    , _tmp4(LIR_OprFact::illegalOpr)
+    , _tmp5(LIR_OprFact::illegalOpr) {
     assert(code == lir_cmove, "code check");
     assert(type != T_ILLEGAL, "cmove should have type");
   }
@@ -1597,25 +1615,38 @@
     , _type(type)
     , _condition(lir_cond_unknown)
     , _fpu_stack_size(0)
-    , _tmp(LIR_OprFact::illegalOpr) {
+    , _tmp1(LIR_OprFact::illegalOpr)
+    , _tmp2(LIR_OprFact::illegalOpr)
+    , _tmp3(LIR_OprFact::illegalOpr)
+    , _tmp4(LIR_OprFact::illegalOpr)
+    , _tmp5(LIR_OprFact::illegalOpr) {
     assert(code != lir_cmp && is_in_range(code, begin_op2, end_op2), "code check");
   }
 
-  LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, LIR_Opr tmp)
+  LIR_Op2(LIR_Code code, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, LIR_Opr tmp1, LIR_Opr tmp2 = LIR_OprFact::illegalOpr,
+          LIR_Opr tmp3 = LIR_OprFact::illegalOpr, LIR_Opr tmp4 = LIR_OprFact::illegalOpr, LIR_Opr tmp5 = LIR_OprFact::illegalOpr)
     : LIR_Op(code, result, NULL)
     , _opr1(opr1)
     , _opr2(opr2)
     , _type(T_ILLEGAL)
     , _condition(lir_cond_unknown)
     , _fpu_stack_size(0)
-    , _tmp(tmp) {
+    , _tmp1(tmp1)
+    , _tmp2(tmp2)
+    , _tmp3(tmp3)
+    , _tmp4(tmp4)
+    , _tmp5(tmp5) {
     assert(code != lir_cmp && is_in_range(code, begin_op2, end_op2), "code check");
   }
 
   LIR_Opr in_opr1() const                        { return _opr1; }
   LIR_Opr in_opr2() const                        { return _opr2; }
   BasicType type()  const                        { return _type; }
-  LIR_Opr tmp_opr() const                        { return _tmp; }
+  LIR_Opr tmp1_opr() const                       { return _tmp1; }
+  LIR_Opr tmp2_opr() const                       { return _tmp2; }
+  LIR_Opr tmp3_opr() const                       { return _tmp3; }
+  LIR_Opr tmp4_opr() const                       { return _tmp4; }
+  LIR_Opr tmp5_opr() const                       { return _tmp5; }
   LIR_Condition condition() const  {
     assert(code() == lir_cmp || code() == lir_cmove, "only valid for cmp and cmove"); return _condition;
   }
@@ -1796,18 +1827,20 @@
 
  private:
   ciMethod* _profiled_method;
-  int _profiled_bci;
-  LIR_Opr _mdo;
-  LIR_Opr _recv;
-  LIR_Opr _tmp1;
-  ciKlass* _known_holder;
+  int       _profiled_bci;
+  ciMethod* _profiled_callee;
+  LIR_Opr   _mdo;
+  LIR_Opr   _recv;
+  LIR_Opr   _tmp1;
+  ciKlass*  _known_holder;
 
  public:
   // Destroys recv
-  LIR_OpProfileCall(LIR_Code code, ciMethod* profiled_method, int profiled_bci, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* known_holder)
+  LIR_OpProfileCall(LIR_Code code, ciMethod* profiled_method, int profiled_bci, ciMethod* profiled_callee, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* known_holder)
     : LIR_Op(code, LIR_OprFact::illegalOpr, NULL)  // no result, no info
     , _profiled_method(profiled_method)
     , _profiled_bci(profiled_bci)
+    , _profiled_callee(profiled_callee)
     , _mdo(mdo)
     , _recv(recv)
     , _tmp1(t1)
@@ -1815,6 +1848,7 @@
 
   ciMethod* profiled_method() const              { return _profiled_method;  }
   int       profiled_bci()    const              { return _profiled_bci;     }
+  ciMethod* profiled_callee() const              { return _profiled_callee;  }
   LIR_Opr   mdo()             const              { return _mdo;              }
   LIR_Opr   recv()            const              { return _recv;             }
   LIR_Opr   tmp1()            const              { return _tmp1;             }
@@ -2025,6 +2059,8 @@
   void sin (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_sin , from, tmp1, to, tmp2)); }
   void cos (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_cos , from, tmp1, to, tmp2)); }
   void tan (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2) { append(new LIR_Op2(lir_tan , from, tmp1, to, tmp2)); }
+  void exp (LIR_Opr from, LIR_Opr to, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, LIR_Opr tmp4, LIR_Opr tmp5)                { append(new LIR_Op2(lir_exp , from, tmp1, to, tmp2, tmp3, tmp4, tmp5)); }
+  void pow (LIR_Opr arg1, LIR_Opr arg2, LIR_Opr res, LIR_Opr tmp1, LIR_Opr tmp2, LIR_Opr tmp3, LIR_Opr tmp4, LIR_Opr tmp5) { append(new LIR_Op2(lir_pow, arg1, arg2, res, tmp1, tmp2, tmp3, tmp4, tmp5)); }
 
   void add (LIR_Opr left, LIR_Opr right, LIR_Opr res)      { append(new LIR_Op2(lir_add, left, right, res)); }
   void sub (LIR_Opr left, LIR_Opr right, LIR_Opr res, CodeEmitInfo* info = NULL) { append(new LIR_Op2(lir_sub, left, right, res, info)); }
@@ -2116,9 +2152,12 @@
                   CodeEmitInfo* info_for_exception, CodeEmitInfo* info_for_patch, CodeStub* stub,
                   ciMethod* profiled_method, int profiled_bci);
   // methodDataOop profiling
-  void profile_call(ciMethod* method, int bci, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* cha_klass) {
-    append(new LIR_OpProfileCall(lir_profile_call, method, bci, mdo, recv, t1, cha_klass));
+  void profile_call(ciMethod* method, int bci, ciMethod* callee, LIR_Opr mdo, LIR_Opr recv, LIR_Opr t1, ciKlass* cha_klass) {
+    append(new LIR_OpProfileCall(lir_profile_call, method, bci, callee, mdo, recv, t1, cha_klass));
   }
+
+  void xadd(LIR_Opr src, LIR_Opr add, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xadd, src, add, res, tmp)); }
+  void xchg(LIR_Opr src, LIR_Opr set, LIR_Opr res, LIR_Opr tmp) { append(new LIR_Op2(lir_xchg, src, set, res, tmp)); }
 };
 
 void print_LIR(BlockList* blocks);
@@ -2215,16 +2254,21 @@
       LIR_Address* address = opr->as_address_ptr();
       if (address != NULL) {
         // special handling for addresses: add base and index register of the address
-        // both are always input operands!
+        // both are always input operands or temp if we want to extend
+        // their liveness!
+        if (mode == outputMode) {
+          mode = inputMode;
+        }
+        assert (mode == inputMode || mode == tempMode, "input or temp only for addresses");
         if (address->_base->is_valid()) {
           assert(address->_base->is_register(), "must be");
-          assert(_oprs_len[inputMode] < maxNumberOfOperands, "array overflow");
-          _oprs_new[inputMode][_oprs_len[inputMode]++] = &address->_base;
+          assert(_oprs_len[mode] < maxNumberOfOperands, "array overflow");
+          _oprs_new[mode][_oprs_len[mode]++] = &address->_base;
         }
         if (address->_index->is_valid()) {
           assert(address->_index->is_register(), "must be");
-          assert(_oprs_len[inputMode] < maxNumberOfOperands, "array overflow");
-          _oprs_new[inputMode][_oprs_len[inputMode]++] = &address->_index;
+          assert(_oprs_len[mode] < maxNumberOfOperands, "array overflow");
+          _oprs_new[mode][_oprs_len[mode]++] = &address->_index;
         }
 
       } else {
diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
index 528f21e..842ce2c 100644
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.cpp
@@ -448,10 +448,10 @@
 
   switch (op->code()) {
   case lir_static_call:
+  case lir_dynamic_call:
     call(op, relocInfo::static_call_type);
     break;
   case lir_optvirtual_call:
-  case lir_dynamic_call:
     call(op, relocInfo::opt_virtual_call_type);
     break;
   case lir_icvirtual_call:
@@ -460,7 +460,9 @@
   case lir_virtual_call:
     vtable_call(op);
     break;
-  default: ShouldNotReachHere();
+  default:
+    fatal(err_msg_res("unexpected op code: %s", op->name()));
+    break;
   }
 
   // JSR 292
@@ -718,7 +720,7 @@
       if (op->in_opr2()->is_constant()) {
         shift_op(op->code(), op->in_opr1(), op->in_opr2()->as_constant_ptr()->as_jint(), op->result_opr());
       } else {
-        shift_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->tmp_opr());
+        shift_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->tmp1_opr());
       }
       break;
 
@@ -746,6 +748,8 @@
     case lir_cos:
     case lir_log:
     case lir_log10:
+    case lir_exp:
+    case lir_pow:
       intrinsic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op);
       break;
 
@@ -763,6 +767,11 @@
       throw_op(op->in_opr1(), op->in_opr2(), op->info());
       break;
 
+    case lir_xadd:
+    case lir_xchg:
+      atomic_op(op->code(), op->in_opr1(), op->in_opr2(), op->result_opr(), op->tmp1_opr());
+      break;
+
     default:
       Unimplemented();
       break;
diff --git a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp
index 58adf59..b6ee07a 100644
--- a/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp
+++ b/hotspot/src/share/vm/c1/c1_LIRAssembler.hpp
@@ -249,6 +249,8 @@
 
   void verify_oop_map(CodeEmitInfo* info);
 
+  void atomic_op(LIR_Code code, LIR_Opr src, LIR_Opr data, LIR_Opr dest, LIR_Opr tmp);
+
 #ifdef TARGET_ARCH_x86
 # include "c1_LIRAssembler_x86.hpp"
 #endif
diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
index ac525b0..056080a 100644
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -920,7 +920,8 @@
 
 
 LIR_Opr LIRGenerator::force_to_spill(LIR_Opr value, BasicType t) {
-  assert(type2size[t] == type2size[value->type()], "size mismatch");
+  assert(type2size[t] == type2size[value->type()],
+         err_msg_res("size mismatch: t=%s, value->type()=%s", type2name(t), type2name(value->type())));
   if (!value->is_register()) {
     // force into a register
     LIR_Opr r = new_register(value->type());
@@ -1242,6 +1243,36 @@
               NULL   /* info */);
 }
 
+// Example: clazz.isInstance(object)
+void LIRGenerator::do_isInstance(Intrinsic* x) {
+  assert(x->number_of_arguments() == 2, "wrong type");
+
+  // TODO could try to substitute this node with an equivalent InstanceOf
+  // if clazz is known to be a constant Class. This will pick up newly found
+  // constants after HIR construction. I'll leave this to a future change.
+
+  // as a first cut, make a simple leaf call to runtime to stay platform independent.
+  // could follow the aastore example in a future change.
+
+  LIRItem clazz(x->argument_at(0), this);
+  LIRItem object(x->argument_at(1), this);
+  clazz.load_item();
+  object.load_item();
+  LIR_Opr result = rlock_result(x);
+
+  // need to perform null check on clazz
+  if (x->needs_null_check()) {
+    CodeEmitInfo* info = state_for(x);
+    __ null_check(clazz.result(), info);
+  }
+
+  LIR_Opr call_result = call_runtime(clazz.value(), object.value(),
+                                     CAST_FROM_FN_PTR(address, Runtime1::is_instance_of),
+                                     x->type(),
+                                     NULL); // NULL CodeEmitInfo results in a leaf call
+  __ move(call_result, result);
+}
+
 // Example: object.getClass ()
 void LIRGenerator::do_getClass(Intrinsic* x) {
   assert(x->number_of_arguments() == 1, "wrong type");
@@ -1910,6 +1941,14 @@
 }
 
 
+void LIRGenerator::do_TypeCast(TypeCast* x) {
+  LIRItem value(x->obj(), this);
+  value.load_item();
+  // the result is the same as from the node we are casting
+  set_result(x, value.result());
+}
+
+
 void LIRGenerator::do_Throw(Throw* x) {
   LIRItem exception(x->exception(), this);
   exception.load_item();
@@ -2138,9 +2177,9 @@
   off.load_item();
   src.load_item();
 
-  LIR_Opr reg = rlock_result(x, x->basic_type());
+  LIR_Opr value = rlock_result(x, x->basic_type());
 
-  get_Object_unsafe(reg, src.result(), off.result(), type, x->is_volatile());
+  get_Object_unsafe(value, src.result(), off.result(), type, x->is_volatile());
 
 #ifndef SERIALGC
   // We might be reading the value of the referent field of a
@@ -2153,19 +2192,16 @@
   // if (offset == java_lang_ref_Reference::referent_offset) {
   //   if (src != NULL) {
   //     if (klass(src)->reference_type() != REF_NONE) {
-  //       pre_barrier(..., reg, ...);
+  //       pre_barrier(..., value, ...);
   //     }
   //   }
   // }
-  //
-  // The first non-constant check of either the offset or
-  // the src operand will be done here; the remainder
-  // will take place in the generated code stub.
 
   if (UseG1GC && type == T_OBJECT) {
-    bool gen_code_stub = true;       // Assume we need to generate the slow code stub.
-    bool gen_offset_check = true;       // Assume the code stub has to generate the offset guard.
-    bool gen_source_check = true;       // Assume the code stub has to check the src object for null.
+    bool gen_pre_barrier = true;     // Assume we need to generate pre_barrier.
+    bool gen_offset_check = true;    // Assume we need to generate the offset guard.
+    bool gen_source_check = true;    // Assume we need to check the src object for null.
+    bool gen_type_check = true;      // Assume we need to check the reference_type.
 
     if (off.is_constant()) {
       jlong off_con = (off.type()->is_int() ?
@@ -2177,7 +2213,7 @@
         // The constant offset is something other than referent_offset.
         // We can skip generating/checking the remaining guards and
         // skip generation of the code stub.
-        gen_code_stub = false;
+        gen_pre_barrier = false;
       } else {
         // The constant offset is the same as referent_offset -
         // we do not need to generate a runtime offset check.
@@ -2186,11 +2222,11 @@
     }
 
     // We don't need to generate stub if the source object is an array
-    if (gen_code_stub && src.type()->is_array()) {
-      gen_code_stub = false;
+    if (gen_pre_barrier && src.type()->is_array()) {
+      gen_pre_barrier = false;
     }
 
-    if (gen_code_stub) {
+    if (gen_pre_barrier) {
       // We still need to continue with the checks.
       if (src.is_constant()) {
         ciObject* src_con = src.get_jobject_constant();
@@ -2198,7 +2234,7 @@
         if (src_con->is_null_object()) {
           // The constant src object is null - We can skip
           // generating the code stub.
-          gen_code_stub = false;
+          gen_pre_barrier = false;
         } else {
           // Non-null constant source object. We still have to generate
           // the slow stub - but we don't need to generate the runtime
@@ -2207,20 +2243,28 @@
         }
       }
     }
+    if (gen_pre_barrier && !PatchALot) {
+      // Can the klass of object be statically determined to be
+      // a sub-class of Reference?
+      ciType* type = src.value()->declared_type();
+      if ((type != NULL) && type->is_loaded()) {
+        if (type->is_subtype_of(compilation()->env()->Reference_klass())) {
+          gen_type_check = false;
+        } else if (type->is_klass() &&
+                   !compilation()->env()->Object_klass()->is_subtype_of(type->as_klass())) {
+          // Not Reference and not Object klass.
+          gen_pre_barrier = false;
+        }
+      }
+    }
 
-    if (gen_code_stub) {
-      // Temoraries.
-      LIR_Opr src_klass = new_register(T_OBJECT);
-
-      // Get the thread pointer for the pre-barrier
-      LIR_Opr thread = getThreadPointer();
-
-      CodeStub* stub;
+    if (gen_pre_barrier) {
+      LabelObj* Lcont = new LabelObj();
 
       // We can have generate one runtime check here. Let's start with
       // the offset check.
       if (gen_offset_check) {
-        // if (offset == referent_offset) -> slow code stub
+        // if (offset != referent_offset) -> continue
         // If offset is an int then we can do the comparison with the
         // referent_offset constant; otherwise we need to move
         // referent_offset into a temporary register and generate
@@ -2235,43 +2279,36 @@
           referent_off = new_register(T_LONG);
           __ move(LIR_OprFact::longConst(java_lang_ref_Reference::referent_offset), referent_off);
         }
-
-        __ cmp(lir_cond_equal, off.result(), referent_off);
-
-        // Optionally generate "src == null" check.
-        stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
-                                                    src_klass, thread,
-                                                    gen_source_check);
-
-        __ branch(lir_cond_equal, as_BasicType(off.type()), stub);
-      } else {
-        if (gen_source_check) {
-          // offset is a const and equals referent offset
-          // if (source != null) -> slow code stub
-          __ cmp(lir_cond_notEqual, src.result(), LIR_OprFact::oopConst(NULL));
-
-          // Since we are generating the "if src == null" guard here,
-          // there is no need to generate the "src == null" check again.
-          stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
-                                                    src_klass, thread,
-                                                    false);
-
-          __ branch(lir_cond_notEqual, T_OBJECT, stub);
-        } else {
-          // We have statically determined that offset == referent_offset
-          // && src != null so we unconditionally branch to code stub
-          // to perform the guards and record reg in the SATB log buffer.
-
-          stub = new G1UnsafeGetObjSATBBarrierStub(reg, src.result(),
-                                                    src_klass, thread,
-                                                    false);
-
-          __ branch(lir_cond_always, T_ILLEGAL, stub);
-        }
+        __ cmp(lir_cond_notEqual, off.result(), referent_off);
+        __ branch(lir_cond_notEqual, as_BasicType(off.type()), Lcont->label());
       }
-
-      // Continuation point
-      __ branch_destination(stub->continuation());
+      if (gen_source_check) {
+        // offset is a const and equals referent offset
+        // if (source == null) -> continue
+        __ cmp(lir_cond_equal, src.result(), LIR_OprFact::oopConst(NULL));
+        __ branch(lir_cond_equal, T_OBJECT, Lcont->label());
+      }
+      LIR_Opr src_klass = new_register(T_OBJECT);
+      if (gen_type_check) {
+        // We have determined that offset == referent_offset && src != null.
+        // if (src->_klass->_reference_type == REF_NONE) -> continue
+        __ move(new LIR_Address(src.result(), oopDesc::klass_offset_in_bytes(), T_OBJECT), src_klass);
+        LIR_Address* reference_type_addr = new LIR_Address(src_klass, in_bytes(instanceKlass::reference_type_offset()), T_BYTE);
+        LIR_Opr reference_type = new_register(T_INT);
+        __ move(reference_type_addr, reference_type);
+        __ cmp(lir_cond_equal, reference_type, LIR_OprFact::intConst(REF_NONE));
+        __ branch(lir_cond_equal, T_INT, Lcont->label());
+      }
+      {
+        // We have determined that src->_klass->_reference_type != REF_NONE
+        // so register the value in the referent field with the pre-barrier.
+        pre_barrier(LIR_OprFact::illegalOpr /* addr_opr */,
+                    value  /* pre_val */,
+                    false  /* do_load */,
+                    false  /* patch */,
+                    NULL   /* info */);
+      }
+      __ branch_destination(Lcont->label());
     }
   }
 #endif // SERIALGC
@@ -2626,8 +2663,9 @@
 
 
 void LIRGenerator::invoke_load_arguments(Invoke* x, LIRItemList* args, const LIR_OprList* arg_list) {
-  int i = (x->has_receiver() || x->is_invokedynamic()) ? 1 : 0;
-  for (; i < args->length(); i++) {
+  assert(args->length() == arg_list->length(),
+         err_msg_res("args=%d, arg_list=%d", args->length(), arg_list->length()));
+  for (int i = x->has_receiver() ? 1 : 0; i < args->length(); i++) {
     LIRItem* param = args->at(i);
     LIR_Opr loc = arg_list->at(i);
     if (loc->is_register()) {
@@ -2667,15 +2705,9 @@
     LIRItem* receiver = new LIRItem(x->receiver(), this);
     argument_items->append(receiver);
   }
-  if (x->is_invokedynamic()) {
-    // Insert a dummy for the synthetic MethodHandle argument.
-    argument_items->append(NULL);
-  }
-  int idx = x->has_receiver() ? 1 : 0;
   for (int i = 0; i < x->number_of_arguments(); i++) {
     LIRItem* param = new LIRItem(x->argument_at(i), this);
     argument_items->append(param);
-    idx += (param->type()->is_double_word() ? 2 : 1);
   }
   return argument_items;
 }
@@ -2720,9 +2752,6 @@
 
   CodeEmitInfo* info = state_for(x, x->state());
 
-  // invokedynamics can deoptimize.
-  CodeEmitInfo* deopt_info = x->is_invokedynamic() ? state_for(x, x->state_before()) : NULL;
-
   invoke_load_arguments(x, args, arg_list);
 
   if (x->has_receiver()) {
@@ -2737,7 +2766,10 @@
   // JSR 292
   // Preserve the SP over MethodHandle call sites.
   ciMethod* target = x->target();
-  if (target->is_method_handle_invoke()) {
+  bool is_method_handle_invoke = (// %%% FIXME: Are both of these relevant?
+                                  target->is_method_handle_intrinsic() ||
+                                  target->is_compiled_lambda_form());
+  if (is_method_handle_invoke) {
     info->set_is_method_handle_invoke(true);
     __ move(FrameMap::stack_pointer(), FrameMap::method_handle_invoke_SP_save_opr());
   }
@@ -2768,41 +2800,8 @@
       }
       break;
     case Bytecodes::_invokedynamic: {
-      ciBytecodeStream bcs(x->scope()->method());
-      bcs.force_bci(x->state()->bci());
-      assert(bcs.cur_bc() == Bytecodes::_invokedynamic, "wrong stream");
-      ciCPCache* cpcache = bcs.get_cpcache();
-
-      // Get CallSite offset from constant pool cache pointer.
-      int index = bcs.get_method_index();
-      size_t call_site_offset = cpcache->get_f1_offset(index);
-
-      // Load CallSite object from constant pool cache.
-      LIR_Opr call_site = new_register(objectType);
-      __ oop2reg(cpcache->constant_encoding(), call_site);
-      __ move_wide(new LIR_Address(call_site, call_site_offset, T_OBJECT), call_site);
-
-      // If this invokedynamic call site hasn't been executed yet in
-      // the interpreter, the CallSite object in the constant pool
-      // cache is still null and we need to deoptimize.
-      if (cpcache->is_f1_null_at(index)) {
-        // Only deoptimize if the CallSite object is still null; we don't
-        // recompile methods in C1 after deoptimization so this call site
-        // might be resolved the next time we execute it after OSR.
-        DeoptimizeStub* deopt_stub = new DeoptimizeStub(deopt_info);
-        __ cmp(lir_cond_equal, call_site, LIR_OprFact::oopConst(NULL));
-        __ branch(lir_cond_equal, T_OBJECT, deopt_stub);
-      }
-
-      // Use the receiver register for the synthetic MethodHandle
-      // argument.
-      receiver = LIR_Assembler::receiverOpr();
-
-      // Load target MethodHandle from CallSite object.
-      __ load(new LIR_Address(call_site, java_lang_invoke_CallSite::target_offset_in_bytes(), T_OBJECT), receiver);
-
       __ call_dynamic(target, receiver, result_register,
-                      SharedRuntime::get_resolve_opt_virtual_call_stub(),
+                      SharedRuntime::get_resolve_static_call_stub(),
                       arg_list, info);
       break;
     }
@@ -2813,7 +2812,7 @@
 
   // JSR 292
   // Restore the SP after MethodHandle call sites.
-  if (target->is_method_handle_invoke()) {
+  if (is_method_handle_invoke) {
     __ move(FrameMap::method_handle_invoke_SP_save_opr(), FrameMap::stack_pointer());
   }
 
@@ -2877,6 +2876,50 @@
   __ cmove(lir_cond(x->cond()), t_val.result(), f_val.result(), reg, as_BasicType(x->x()->type()));
 }
 
+void LIRGenerator::do_RuntimeCall(address routine, int expected_arguments, Intrinsic* x) {
+    assert(x->number_of_arguments() == expected_arguments, "wrong type");
+    LIR_Opr reg = result_register_for(x->type());
+    __ call_runtime_leaf(routine, getThreadTemp(),
+                         reg, new LIR_OprList());
+    LIR_Opr result = rlock_result(x);
+    __ move(reg, result);
+}
+
+#ifdef TRACE_HAVE_INTRINSICS
+void LIRGenerator::do_ThreadIDIntrinsic(Intrinsic* x) {
+    LIR_Opr thread = getThreadPointer();
+    LIR_Opr osthread = new_pointer_register();
+    __ move(new LIR_Address(thread, in_bytes(JavaThread::osthread_offset()), osthread->type()), osthread);
+    size_t thread_id_size = OSThread::thread_id_size();
+    if (thread_id_size == (size_t) BytesPerLong) {
+      LIR_Opr id = new_register(T_LONG);
+      __ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_LONG), id);
+      __ convert(Bytecodes::_l2i, id, rlock_result(x));
+    } else if (thread_id_size == (size_t) BytesPerInt) {
+      __ move(new LIR_Address(osthread, in_bytes(OSThread::thread_id_offset()), T_INT), rlock_result(x));
+    } else {
+      ShouldNotReachHere();
+    }
+}
+
+void LIRGenerator::do_ClassIDIntrinsic(Intrinsic* x) {
+    CodeEmitInfo* info = state_for(x);
+    CodeEmitInfo* info2 = new CodeEmitInfo(info); // Clone for the second null check
+    assert(info != NULL, "must have info");
+    LIRItem arg(x->argument_at(1), this);
+    arg.load_item();
+    LIR_Opr klass = new_register(T_OBJECT);
+    __ move(new LIR_Address(arg.result(), java_lang_Class::klass_offset_in_bytes(), T_OBJECT), klass, info);
+    LIR_Opr id = new_register(T_LONG);
+    ByteSize offset = TRACE_ID_OFFSET;
+    LIR_Address* trace_id_addr = new LIR_Address(klass, in_bytes(offset), T_LONG);
+    __ move(trace_id_addr, id);
+    __ logical_or(id, LIR_OprFact::longConst(0x01l), id);
+    __ store(id, trace_id_addr);
+    __ logical_and(id, LIR_OprFact::longConst(~0x3l), id);
+    __ move(id, rlock_result(x));
+}
+#endif
 
 void LIRGenerator::do_Intrinsic(Intrinsic* x) {
   switch (x->id()) {
@@ -2888,27 +2931,24 @@
     break;
   }
 
-  case vmIntrinsics::_currentTimeMillis: {
-    assert(x->number_of_arguments() == 0, "wrong type");
-    LIR_Opr reg = result_register_for(x->type());
-    __ call_runtime_leaf(CAST_FROM_FN_PTR(address, os::javaTimeMillis), getThreadTemp(),
-                         reg, new LIR_OprList());
-    LIR_Opr result = rlock_result(x);
-    __ move(reg, result);
+#ifdef TRACE_HAVE_INTRINSICS
+  case vmIntrinsics::_threadID: do_ThreadIDIntrinsic(x); break;
+  case vmIntrinsics::_classID: do_ClassIDIntrinsic(x); break;
+  case vmIntrinsics::_counterTime:
+    do_RuntimeCall(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), 0, x);
     break;
-  }
+#endif
 
-  case vmIntrinsics::_nanoTime: {
-    assert(x->number_of_arguments() == 0, "wrong type");
-    LIR_Opr reg = result_register_for(x->type());
-    __ call_runtime_leaf(CAST_FROM_FN_PTR(address, os::javaTimeNanos), getThreadTemp(),
-                         reg, new LIR_OprList());
-    LIR_Opr result = rlock_result(x);
-    __ move(reg, result);
+  case vmIntrinsics::_currentTimeMillis:
+    do_RuntimeCall(CAST_FROM_FN_PTR(address, os::javaTimeMillis), 0, x);
     break;
-  }
+
+  case vmIntrinsics::_nanoTime:
+    do_RuntimeCall(CAST_FROM_FN_PTR(address, os::javaTimeNanos), 0, x);
+    break;
 
   case vmIntrinsics::_Object_init:    do_RegisterFinalizer(x); break;
+  case vmIntrinsics::_isInstance:     do_isInstance(x);    break;
   case vmIntrinsics::_getClass:       do_getClass(x);      break;
   case vmIntrinsics::_currentThread:  do_currentThread(x); break;
 
@@ -2918,7 +2958,9 @@
   case vmIntrinsics::_dsqrt:          // fall through
   case vmIntrinsics::_dtan:           // fall through
   case vmIntrinsics::_dsin :          // fall through
-  case vmIntrinsics::_dcos :          do_MathIntrinsic(x); break;
+  case vmIntrinsics::_dcos :          // fall through
+  case vmIntrinsics::_dexp :          // fall through
+  case vmIntrinsics::_dpow :          do_MathIntrinsic(x); break;
   case vmIntrinsics::_arraycopy:      do_ArrayCopy(x);     break;
 
   // java.nio.Buffer.checkIndex
@@ -2934,11 +2976,6 @@
     do_CompareAndSwap(x, longType);
     break;
 
-    // sun.misc.AtomicLongCSImpl.attemptUpdate
-  case vmIntrinsics::_attemptUpdate:
-    do_AttemptUpdate(x);
-    break;
-
   case vmIntrinsics::_Reference_get:
     do_Reference_get(x);
     break;
@@ -2959,7 +2996,7 @@
     recv = new_register(T_OBJECT);
     __ move(value.result(), recv);
   }
-  __ profile_call(x->method(), x->bci_of_invoke(), mdo, recv, tmp, x->known_holder());
+  __ profile_call(x->method(), x->bci_of_invoke(), x->callee(), mdo, recv, tmp, x->known_holder());
 }
 
 void LIRGenerator::do_ProfileInvoke(ProfileInvoke* x) {
@@ -3179,4 +3216,3 @@
     }
   }
 }
-
diff --git a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp
index 56b28e4..2e9e371 100644
--- a/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp
+++ b/hotspot/src/share/vm/c1/c1_LIRGenerator.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -238,12 +238,12 @@
   LIR_Opr getThreadPointer();
 
   void do_RegisterFinalizer(Intrinsic* x);
+  void do_isInstance(Intrinsic* x);
   void do_getClass(Intrinsic* x);
   void do_currentThread(Intrinsic* x);
   void do_MathIntrinsic(Intrinsic* x);
   void do_ArrayCopy(Intrinsic* x);
   void do_CompareAndSwap(Intrinsic* x, ValueType* type);
-  void do_AttemptUpdate(Intrinsic* x);
   void do_NIOCheckIndex(Intrinsic* x);
   void do_FPIntrinsics(Intrinsic* x);
   void do_Reference_get(Intrinsic* x);
@@ -426,6 +426,12 @@
   SwitchRangeArray* create_lookup_ranges(LookupSwitch* x);
   void do_SwitchRanges(SwitchRangeArray* x, LIR_Opr value, BlockBegin* default_sux);
 
+  void do_RuntimeCall(address routine, int expected_arguments, Intrinsic* x);
+#ifdef TRACE_HAVE_INTRINSICS
+  void do_ThreadIDIntrinsic(Intrinsic* x);
+  void do_ClassIDIntrinsic(Intrinsic* x);
+#endif
+
  public:
   Compilation*  compilation() const              { return _compilation; }
   FrameMap*     frame_map() const                { return _compilation->frame_map(); }
@@ -494,6 +500,7 @@
   virtual void do_IfOp           (IfOp*            x);
   virtual void do_Convert        (Convert*         x);
   virtual void do_NullCheck      (NullCheck*       x);
+  virtual void do_TypeCast       (TypeCast*        x);
   virtual void do_Invoke         (Invoke*          x);
   virtual void do_NewInstance    (NewInstance*     x);
   virtual void do_NewTypeArray   (NewTypeArray*    x);
@@ -520,6 +527,7 @@
   virtual void do_UnsafePutRaw   (UnsafePutRaw*    x);
   virtual void do_UnsafeGetObject(UnsafeGetObject* x);
   virtual void do_UnsafePutObject(UnsafePutObject* x);
+  virtual void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);
   virtual void do_UnsafePrefetchRead (UnsafePrefetchRead*  x);
   virtual void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
   virtual void do_ProfileCall    (ProfileCall*     x);
diff --git a/hotspot/src/share/vm/c1/c1_LinearScan.cpp b/hotspot/src/share/vm/c1/c1_LinearScan.cpp
index aaae71d46..bd4061e 100644
--- a/hotspot/src/share/vm/c1/c1_LinearScan.cpp
+++ b/hotspot/src/share/vm/c1/c1_LinearScan.cpp
@@ -1884,7 +1884,7 @@
 
   if (move_resolver.has_mappings()) {
     // insert moves after first instruction
-    move_resolver.set_insert_position(block->lir(), 1);
+    move_resolver.set_insert_position(block->lir(), 0);
     move_resolver.resolve_and_append_moves();
   }
 }
@@ -2467,12 +2467,12 @@
 // Allocate them with new so they are never destroyed (otherwise, a
 // forced exit could destroy these objects while they are still in
 // use).
-ConstantOopWriteValue* LinearScan::_oop_null_scope_value = new (ResourceObj::C_HEAP) ConstantOopWriteValue(NULL);
-ConstantIntValue*      LinearScan::_int_m1_scope_value = new (ResourceObj::C_HEAP) ConstantIntValue(-1);
-ConstantIntValue*      LinearScan::_int_0_scope_value =  new (ResourceObj::C_HEAP) ConstantIntValue(0);
-ConstantIntValue*      LinearScan::_int_1_scope_value =  new (ResourceObj::C_HEAP) ConstantIntValue(1);
-ConstantIntValue*      LinearScan::_int_2_scope_value =  new (ResourceObj::C_HEAP) ConstantIntValue(2);
-LocationValue*         _illegal_value = new (ResourceObj::C_HEAP) LocationValue(Location());
+ConstantOopWriteValue* LinearScan::_oop_null_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantOopWriteValue(NULL);
+ConstantIntValue*      LinearScan::_int_m1_scope_value = new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(-1);
+ConstantIntValue*      LinearScan::_int_0_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(0);
+ConstantIntValue*      LinearScan::_int_1_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(1);
+ConstantIntValue*      LinearScan::_int_2_scope_value =  new (ResourceObj::C_HEAP, mtCompiler) ConstantIntValue(2);
+LocationValue*         _illegal_value = new (ResourceObj::C_HEAP, mtCompiler) LocationValue(Location());
 
 void LinearScan::init_compute_debug_info() {
   // cache for frequently used scope values
@@ -6579,6 +6579,8 @@
         case lir_abs:
         case lir_log10:
         case lir_log:
+        case lir_pow:
+        case lir_exp:
         case lir_logic_and:
         case lir_logic_or:
         case lir_logic_xor:
diff --git a/hotspot/src/share/vm/c1/c1_Optimizer.cpp b/hotspot/src/share/vm/c1/c1_Optimizer.cpp
index ff05781..a80989d 100644
--- a/hotspot/src/share/vm/c1/c1_Optimizer.cpp
+++ b/hotspot/src/share/vm/c1/c1_Optimizer.cpp
@@ -29,6 +29,7 @@
 #include "c1/c1_ValueSet.hpp"
 #include "c1/c1_ValueStack.hpp"
 #include "utilities/bitMap.inline.hpp"
+#include "compiler/compileLog.hpp"
 
 define_array(ValueSetArray, ValueSet*);
 define_stack(ValueSetList, ValueSetArray);
@@ -54,7 +55,18 @@
       // substituted some ifops/phis, so resolve the substitution
       SubstitutionResolver sr(_hir);
     }
+
+    CompileLog* log = _hir->compilation()->log();
+    if (log != NULL)
+      log->set_context("optimize name='cee'");
   }
+
+  ~CE_Eliminator() {
+    CompileLog* log = _hir->compilation()->log();
+    if (log != NULL)
+      log->clear_context(); // skip marker if nothing was printed
+  }
+
   int cee_count() const                          { return _cee_count; }
   int ifop_count() const                         { return _ifop_count; }
 
@@ -306,6 +318,15 @@
   , _merge_count(0)
   {
     _hir->iterate_preorder(this);
+    CompileLog* log = _hir->compilation()->log();
+    if (log != NULL)
+      log->set_context("optimize name='eliminate_blocks'");
+  }
+
+  ~BlockMerger() {
+    CompileLog* log = _hir->compilation()->log();
+    if (log != NULL)
+      log->clear_context(); // skip marker if nothing was printed
   }
 
   bool try_merge(BlockBegin* block) {
@@ -478,6 +499,7 @@
   void do_IfOp           (IfOp*            x);
   void do_Convert        (Convert*         x);
   void do_NullCheck      (NullCheck*       x);
+  void do_TypeCast       (TypeCast*        x);
   void do_Invoke         (Invoke*          x);
   void do_NewInstance    (NewInstance*     x);
   void do_NewTypeArray   (NewTypeArray*    x);
@@ -504,6 +526,7 @@
   void do_UnsafePutRaw   (UnsafePutRaw*    x);
   void do_UnsafeGetObject(UnsafeGetObject* x);
   void do_UnsafePutObject(UnsafePutObject* x);
+  void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x);
   void do_UnsafePrefetchRead (UnsafePrefetchRead*  x);
   void do_UnsafePrefetchWrite(UnsafePrefetchWrite* x);
   void do_ProfileCall    (ProfileCall*     x);
@@ -572,6 +595,15 @@
     , _work_list(new BlockList()) {
     _visitable_instructions = new ValueSet();
     _visitor.set_eliminator(this);
+    CompileLog* log = _opt->ir()->compilation()->log();
+    if (log != NULL)
+      log->set_context("optimize name='null_check_elimination'");
+  }
+
+  ~NullCheckEliminator() {
+    CompileLog* log = _opt->ir()->compilation()->log();
+    if (log != NULL)
+      log->clear_context(); // skip marker if nothing was printed
   }
 
   Optimizer*  opt()                               { return _opt; }
@@ -648,6 +680,7 @@
 void NullCheckVisitor::do_IfOp           (IfOp*            x) {}
 void NullCheckVisitor::do_Convert        (Convert*         x) {}
 void NullCheckVisitor::do_NullCheck      (NullCheck*       x) { nce()->handle_NullCheck(x); }
+void NullCheckVisitor::do_TypeCast       (TypeCast*        x) {}
 void NullCheckVisitor::do_Invoke         (Invoke*          x) { nce()->handle_Invoke(x); }
 void NullCheckVisitor::do_NewInstance    (NewInstance*     x) { nce()->handle_NewInstance(x); }
 void NullCheckVisitor::do_NewTypeArray   (NewTypeArray*    x) { nce()->handle_NewArray(x); }
@@ -674,6 +707,7 @@
 void NullCheckVisitor::do_UnsafePutRaw   (UnsafePutRaw*    x) {}
 void NullCheckVisitor::do_UnsafeGetObject(UnsafeGetObject* x) {}
 void NullCheckVisitor::do_UnsafePutObject(UnsafePutObject* x) {}
+void NullCheckVisitor::do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) {}
 void NullCheckVisitor::do_UnsafePrefetchRead (UnsafePrefetchRead*  x) {}
 void NullCheckVisitor::do_UnsafePrefetchWrite(UnsafePrefetchWrite* x) {}
 void NullCheckVisitor::do_ProfileCall    (ProfileCall*     x) { nce()->clear_last_explicit_null_check(); }
diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.cpp b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
index 765dec4..d0b6abe 100644
--- a/hotspot/src/share/vm/c1/c1_Runtime1.cpp
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.cpp
@@ -294,7 +294,11 @@
   FUNCTION_CASE(entry, SharedRuntime::lrem);
   FUNCTION_CASE(entry, SharedRuntime::dtrace_method_entry);
   FUNCTION_CASE(entry, SharedRuntime::dtrace_method_exit);
+  FUNCTION_CASE(entry, is_instance_of);
   FUNCTION_CASE(entry, trace_block_entry);
+#ifdef TRACE_HAVE_INTRINSICS
+  FUNCTION_CASE(entry, TRACE_TIME_METHOD);
+#endif
 
 #undef FUNCTION_CASE
 
@@ -1267,6 +1271,19 @@
 JRT_END
 
 
+JRT_LEAF(int, Runtime1::is_instance_of(oopDesc* mirror, oopDesc* obj))
+  // had to return int instead of bool, otherwise there may be a mismatch
+  // between the C calling convention and the Java one.
+  // e.g., on x86, GCC may clear only %al when returning a bool false, but
+  // JVM takes the whole %eax as the return value, which may misinterpret
+  // the return value as a boolean true.
+
+  assert(mirror != NULL, "should null-check on mirror before calling");
+  klassOop k = java_lang_Class::as_klassOop(mirror);
+  return (k != NULL && obj != NULL && obj->is_a(k)) ? 1 : 0;
+JRT_END
+
+
 #ifndef PRODUCT
 void Runtime1::print_statistics() {
   tty->print_cr("C1 Runtime statistics:");
diff --git a/hotspot/src/share/vm/c1/c1_Runtime1.hpp b/hotspot/src/share/vm/c1/c1_Runtime1.hpp
index 2032564..fce5b2c 100644
--- a/hotspot/src/share/vm/c1/c1_Runtime1.hpp
+++ b/hotspot/src/share/vm/c1/c1_Runtime1.hpp
@@ -186,6 +186,7 @@
   static int  arraycopy(oopDesc* src, int src_pos, oopDesc* dst, int dst_pos, int length);
   static void primitive_arraycopy(HeapWord* src, HeapWord* dst, int length);
   static void oop_arraycopy(HeapWord* src, HeapWord* dst, int length);
+  static int  is_instance_of(oopDesc* mirror, oopDesc* obj);
 
   static void print_statistics()                 PRODUCT_RETURN;
 };
diff --git a/hotspot/src/share/vm/c1/c1_ValueMap.cpp b/hotspot/src/share/vm/c1/c1_ValueMap.cpp
index 1f31520..388c0dc 100644
--- a/hotspot/src/share/vm/c1/c1_ValueMap.cpp
+++ b/hotspot/src/share/vm/c1/c1_ValueMap.cpp
@@ -190,7 +190,7 @@
   LoadField* lf = value->as_LoadField();                                                 \
   bool must_kill = lf != NULL                                                            \
                    && lf->field()->holder() == field->holder()                           \
-                   && lf->field()->offset() == field->offset();
+                   && (all_offsets || lf->field()->offset() == field->offset());
 
 #define MUST_KILL_EXCEPTION(must_kill, entry, value)                                     \
   assert(entry->nesting() < nesting(), "must not find bigger nesting than current");     \
@@ -205,7 +205,7 @@
   GENERIC_KILL_VALUE(MUST_KILL_ARRAY);
 }
 
-void ValueMap::kill_field(ciField* field) {
+void ValueMap::kill_field(ciField* field, bool all_offsets) {
   GENERIC_KILL_VALUE(MUST_KILL_FIELD);
 }
 
@@ -280,9 +280,9 @@
   ValueMap* value_map_of(BlockBegin* block)      { return _gvn->value_map_of(block); }
 
   // implementation for abstract methods of ValueNumberingVisitor
-  void      kill_memory()                        { _too_complicated_loop = true; }
-  void      kill_field(ciField* field)           { current_map()->kill_field(field); };
-  void      kill_array(ValueType* type)          { current_map()->kill_array(type); };
+  void      kill_memory()                                 { _too_complicated_loop = true; }
+  void      kill_field(ciField* field, bool all_offsets)  { current_map()->kill_field(field, all_offsets); };
+  void      kill_array(ValueType* type)                   { current_map()->kill_array(type); };
 
  public:
   ShortLoopOptimizer(GlobalValueNumbering* gvn)
diff --git a/hotspot/src/share/vm/c1/c1_ValueMap.hpp b/hotspot/src/share/vm/c1/c1_ValueMap.hpp
index 5b38819..95fa732 100644
--- a/hotspot/src/share/vm/c1/c1_ValueMap.hpp
+++ b/hotspot/src/share/vm/c1/c1_ValueMap.hpp
@@ -114,7 +114,7 @@
   Value find_insert(Value x);
 
   void kill_memory();
-  void kill_field(ciField* field);
+  void kill_field(ciField* field, bool all_offsets);
   void kill_array(ValueType* type);
   void kill_exception();
   void kill_map(ValueMap* map);
@@ -136,7 +136,7 @@
  protected:
   // called by visitor functions for instructions that kill values
   virtual void kill_memory() = 0;
-  virtual void kill_field(ciField* field) = 0;
+  virtual void kill_field(ciField* field, bool all_offsets) = 0;
   virtual void kill_array(ValueType* type) = 0;
 
   // visitor functions
@@ -148,7 +148,7 @@
         x->field()->is_volatile()) {
       kill_memory();
     } else {
-      kill_field(x->field());
+      kill_field(x->field(), x->needs_patching());
     }
   }
   void do_StoreIndexed   (StoreIndexed*    x) { kill_array(x->type()); }
@@ -157,6 +157,7 @@
   void do_Invoke         (Invoke*          x) { kill_memory(); }
   void do_UnsafePutRaw   (UnsafePutRaw*    x) { kill_memory(); }
   void do_UnsafePutObject(UnsafePutObject* x) { kill_memory(); }
+  void do_UnsafeGetAndSetObject(UnsafeGetAndSetObject* x) { kill_memory(); }
   void do_Intrinsic      (Intrinsic*       x) { if (!x->preserves_state()) kill_memory(); }
 
   void do_Phi            (Phi*             x) { /* nothing to do */ }
@@ -178,6 +179,7 @@
   void do_IfOp           (IfOp*            x) { /* nothing to do */ }
   void do_Convert        (Convert*         x) { /* nothing to do */ }
   void do_NullCheck      (NullCheck*       x) { /* nothing to do */ }
+  void do_TypeCast       (TypeCast*        x) { /* nothing to do */ }
   void do_NewInstance    (NewInstance*     x) { /* nothing to do */ }
   void do_NewTypeArray   (NewTypeArray*    x) { /* nothing to do */ }
   void do_NewObjectArray (NewObjectArray*  x) { /* nothing to do */ }
@@ -213,9 +215,9 @@
 
  public:
   // implementation for abstract methods of ValueNumberingVisitor
-  void          kill_memory()                    { _map->kill_memory(); }
-  void          kill_field(ciField* field)       { _map->kill_field(field); }
-  void          kill_array(ValueType* type)      { _map->kill_array(type); }
+  void          kill_memory()                                 { _map->kill_memory(); }
+  void          kill_field(ciField* field, bool all_offsets)  { _map->kill_field(field, all_offsets); }
+  void          kill_array(ValueType* type)                   { _map->kill_array(type); }
 
   ValueNumberingEffects(ValueMap* map): _map(map) {}
 };
@@ -233,9 +235,9 @@
   void          set_value_map_of(BlockBegin* block, ValueMap* map)   { assert(value_map_of(block) == NULL, ""); _value_maps.at_put(block->linear_scan_number(), map); }
 
   // implementation for abstract methods of ValueNumberingVisitor
-  void          kill_memory()                    { current_map()->kill_memory(); }
-  void          kill_field(ciField* field)       { current_map()->kill_field(field); }
-  void          kill_array(ValueType* type)      { current_map()->kill_array(type); }
+  void          kill_memory()                                 { current_map()->kill_memory(); }
+  void          kill_field(ciField* field, bool all_offsets)  { current_map()->kill_field(field, all_offsets); }
+  void          kill_array(ValueType* type)                   { current_map()->kill_array(type); }
 
   // main entry point that performs global value numbering
   GlobalValueNumbering(IR* ir);
diff --git a/hotspot/src/share/vm/c1/c1_ValueStack.cpp b/hotspot/src/share/vm/c1/c1_ValueStack.cpp
index 1ffad1d..d17a3f6 100644
--- a/hotspot/src/share/vm/c1/c1_ValueStack.cpp
+++ b/hotspot/src/share/vm/c1/c1_ValueStack.cpp
@@ -195,6 +195,7 @@
 
 void ValueStack::print() {
   scope()->method()->print_name();
+  tty->cr();
   if (stack_is_empty()) {
     tty->print_cr("empty stack");
   } else {
diff --git a/hotspot/src/share/vm/c1/c1_ValueStack.hpp b/hotspot/src/share/vm/c1/c1_ValueStack.hpp
index a775eba..1dfd98d 100644
--- a/hotspot/src/share/vm/c1/c1_ValueStack.hpp
+++ b/hotspot/src/share/vm/c1/c1_ValueStack.hpp
@@ -142,6 +142,10 @@
     return x;
   }
 
+  void stack_at_put(int i, Value x) {
+    _stack.at_put(i, x);
+  }
+
   // pinning support
   void pin_stack_for_linear_scan();
 
diff --git a/hotspot/src/share/vm/c1/c1_ValueType.cpp b/hotspot/src/share/vm/c1/c1_ValueType.cpp
index c0c2ca6..e4b03c6 100644
--- a/hotspot/src/share/vm/c1/c1_ValueType.cpp
+++ b/hotspot/src/share/vm/c1/c1_ValueType.cpp
@@ -101,6 +101,23 @@
 ciObject* InstanceConstant::constant_value() const                 { return _value; }
 ciObject* ClassConstant::constant_value() const                    { return _value; }
 
+ciType* ObjectConstant::exact_type() const {
+  ciObject* c = constant_value();
+  return (c != NULL && !c->is_null_object()) ? c->klass() : NULL;
+}
+ciType* ArrayConstant::exact_type() const {
+  ciObject* c = constant_value();
+  return (c != NULL && !c->is_null_object()) ? c->klass() : NULL;
+}
+ciType* InstanceConstant::exact_type() const {
+  ciObject* c = constant_value();
+  return (c != NULL && !c->is_null_object()) ? c->klass() : NULL;
+}
+ciType* ClassConstant::exact_type() const {
+  ciObject* c = constant_value();
+  return (c != NULL && !c->is_null_object()) ? c->klass() : NULL;
+}
+
 
 ValueType* as_ValueType(BasicType type) {
   switch (type) {
diff --git a/hotspot/src/share/vm/c1/c1_ValueType.hpp b/hotspot/src/share/vm/c1/c1_ValueType.hpp
index d82eae6..db7ef49 100644
--- a/hotspot/src/share/vm/c1/c1_ValueType.hpp
+++ b/hotspot/src/share/vm/c1/c1_ValueType.hpp
@@ -297,7 +297,8 @@
   virtual const char tchar() const               { return 'a'; }
   virtual const char* name() const               { return "object"; }
   virtual ObjectType* as_ObjectType()            { return this; }
-  virtual ciObject* constant_value() const       { ShouldNotReachHere(); return NULL;  }
+  virtual ciObject* constant_value() const       { ShouldNotReachHere(); return NULL; }
+  virtual ciType* exact_type() const             { return NULL; }
   bool is_loaded() const;
   jobject encoding() const;
 };
@@ -315,6 +316,7 @@
   virtual bool is_constant() const               { return true; }
   virtual ObjectConstant* as_ObjectConstant()    { return this; }
   virtual ciObject* constant_value() const;
+  virtual ciType* exact_type() const;
 };
 
 
@@ -334,9 +336,9 @@
   ciArray* value() const                         { return _value; }
 
   virtual bool is_constant() const               { return true; }
-
   virtual ArrayConstant* as_ArrayConstant()      { return this; }
   virtual ciObject* constant_value() const;
+  virtual ciType* exact_type() const;
 };
 
 
@@ -356,9 +358,9 @@
   ciInstance* value() const                      { return _value; }
 
   virtual bool is_constant() const               { return true; }
-
   virtual InstanceConstant* as_InstanceConstant(){ return this; }
   virtual ciObject* constant_value() const;
+  virtual ciType* exact_type() const;
 };
 
 
@@ -378,9 +380,9 @@
   ciInstanceKlass* value() const                 { return _value; }
 
   virtual bool is_constant() const               { return true; }
-
   virtual ClassConstant* as_ClassConstant()      { return this; }
   virtual ciObject* constant_value() const;
+  virtual ciType* exact_type() const;
 };
 
 
diff --git a/hotspot/src/share/vm/c1/c1_globals.hpp b/hotspot/src/share/vm/c1/c1_globals.hpp
index 15f3cc1..ed7ea9a 100644
--- a/hotspot/src/share/vm/c1/c1_globals.hpp
+++ b/hotspot/src/share/vm/c1/c1_globals.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -156,18 +156,12 @@
   develop(bool, CanonicalizeNodes, true,                                    \
           "Canonicalize graph nodes")                                       \
                                                                             \
-  develop(bool, CanonicalizeExperimental, false,                            \
-          "Canonicalize graph nodes, experimental code")                    \
-                                                                            \
   develop(bool, PrintCanonicalization, false,                               \
           "Print graph node canonicalization")                              \
                                                                             \
   develop(bool, UseTableRanges, true,                                       \
           "Faster versions of lookup table using ranges")                   \
                                                                             \
-  develop(bool, UseFastExceptionHandling, true,                             \
-          "Faster handling of exceptions")                                  \
-                                                                            \
   develop_pd(bool, RoundFPResults,                                          \
           "Indicates whether rounding is needed for floating point results")\
                                                                             \
@@ -224,9 +218,6 @@
   develop(bool, PinAllInstructions, false,                                  \
           "All instructions are pinned")                                    \
                                                                             \
-  develop(bool, ValueStackPinStackAll, true,                                \
-          "Pinning in ValueStack pin everything")                           \
-                                                                            \
   develop(bool, UseFastNewInstance, true,                                   \
           "Use fast inlined instance allocation")                           \
                                                                             \
diff --git a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp
index 2037b49..31bd06c 100644
--- a/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp
+++ b/hotspot/src/share/vm/ci/bcEscapeAnalyzer.cpp
@@ -236,11 +236,17 @@
   ciInstanceKlass* callee_holder = ciEnv::get_instance_klass_for_declared_method_holder(holder);
   ciInstanceKlass* actual_recv = callee_holder;
 
-  // some methods are obviously bindable without any type checks so
-  // convert them directly to an invokespecial.
-  if (target->is_loaded() && !target->is_abstract() &&
-      target->can_be_statically_bound() && code == Bytecodes::_invokevirtual) {
-    code = Bytecodes::_invokespecial;
+  // Some methods are obviously bindable without any type checks so
+  // convert them directly to an invokespecial or invokestatic.
+  if (target->is_loaded() && !target->is_abstract() && target->can_be_statically_bound()) {
+    switch (code) {
+    case Bytecodes::_invokevirtual:
+      code = Bytecodes::_invokespecial;
+      break;
+    case Bytecodes::_invokehandle:
+      code = target->is_static() ? Bytecodes::_invokestatic : Bytecodes::_invokespecial;
+      break;
+    }
   }
 
   // compute size of arguments
@@ -824,8 +830,8 @@
         break;
       case Bytecodes::_getstatic:
       case Bytecodes::_getfield:
-        { bool will_link;
-          ciField* field = s.get_field(will_link);
+        { bool ignored_will_link;
+          ciField* field = s.get_field(ignored_will_link);
           BasicType field_type = field->type()->basic_type();
           if (s.cur_bc() != Bytecodes::_getstatic) {
             set_method_escape(state.apop());
@@ -863,11 +869,21 @@
       case Bytecodes::_invokestatic:
       case Bytecodes::_invokedynamic:
       case Bytecodes::_invokeinterface:
-        { bool will_link;
-          ciMethod* target = s.get_method(will_link);
-          ciKlass* holder = s.get_declared_method_holder();
-          invoke(state, s.cur_bc(), target, holder);
-          ciType* return_type = target->return_type();
+        { bool ignored_will_link;
+          ciSignature* declared_signature = NULL;
+          ciMethod* target = s.get_method(ignored_will_link, &declared_signature);
+          ciKlass*  holder = s.get_declared_method_holder();
+          assert(declared_signature != NULL, "cannot be null");
+          // Push appendix argument, if one.
+          if (s.has_appendix()) {
+            state.apush(unknown_obj);
+          }
+          // Pass in raw bytecode because we need to see invokehandle instructions.
+          invoke(state, s.cur_bc_raw(), target, holder);
+          // We are using the return type of the declared signature here because
+          // it might be a more concrete type than the one from the target (for
+          // e.g. invokedynamic and invokehandle).
+          ciType* return_type = declared_signature->return_type();
           if (!return_type->is_primitive_type()) {
             state.apush(unknown_obj);
           } else if (return_type->is_one_word()) {
diff --git a/hotspot/src/share/vm/ci/ciClassList.hpp b/hotspot/src/share/vm/ci/ciClassList.hpp
index 4d19439..a9dd10c 100644
--- a/hotspot/src/share/vm/ci/ciClassList.hpp
+++ b/hotspot/src/share/vm/ci/ciClassList.hpp
@@ -47,7 +47,9 @@
 class   ciNullObject;
 class   ciInstance;
 class     ciCallSite;
+class     ciMemberName;
 class     ciMethodHandle;
+class     ciMethodType;
 class   ciMethod;
 class   ciMethodData;
 class     ciReceiverTypeData;  // part of ciMethodData
@@ -100,9 +102,11 @@
 friend class ciObject;                 \
 friend class ciNullObject;             \
 friend class ciInstance;               \
+friend class ciMemberName;             \
 friend class ciMethod;                 \
 friend class ciMethodData;             \
 friend class ciMethodHandle;           \
+friend class ciMethodType;             \
 friend class ciReceiverTypeData;       \
 friend class ciSymbol;                 \
 friend class ciArray;                  \
diff --git a/hotspot/src/share/vm/ci/ciEnv.cpp b/hotspot/src/share/vm/ci/ciEnv.cpp
index 1366177..e20db5d 100644
--- a/hotspot/src/share/vm/ci/ciEnv.cpp
+++ b/hotspot/src/share/vm/ci/ciEnv.cpp
@@ -50,7 +50,6 @@
 #include "oops/oop.inline.hpp"
 #include "oops/oop.inline2.hpp"
 #include "prims/jvmtiExport.hpp"
-#include "prims/methodHandleWalk.hpp"
 #include "runtime/init.hpp"
 #include "runtime/reflection.hpp"
 #include "runtime/sharedRuntime.hpp"
@@ -582,7 +581,7 @@
     assert(index < 0, "only one kind of index at a time");
     ConstantPoolCacheEntry* cpc_entry = cpool->cache()->entry_at(cache_index);
     index = cpc_entry->constant_pool_index();
-    oop obj = cpc_entry->f1();
+    oop obj = cpc_entry->f1_as_instance();
     if (obj != NULL) {
       assert(obj->is_instance() || obj->is_array(), "must be a Java reference");
       ciObject* ciobj = get_object(obj);
@@ -739,88 +738,81 @@
 ciMethod* ciEnv::get_method_by_index_impl(constantPoolHandle cpool,
                                           int index, Bytecodes::Code bc,
                                           ciInstanceKlass* accessor) {
-  int holder_index = cpool->klass_ref_index_at(index);
-  bool holder_is_accessible;
-  ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
-  ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
-
-  // Get the method's name and signature.
-  Symbol* name_sym = cpool->name_ref_at(index);
-  Symbol* sig_sym  = cpool->signature_ref_at(index);
-
-  if (cpool->has_preresolution()
-      || (holder == ciEnv::MethodHandle_klass() &&
-          methodOopDesc::is_method_handle_invoke_name(name_sym))) {
-    // Short-circuit lookups for JSR 292-related call sites.
-    // That is, do not rely only on name-based lookups, because they may fail
-    // if the names are not resolvable in the boot class loader (7056328).
-    switch (bc) {
-    case Bytecodes::_invokevirtual:
-    case Bytecodes::_invokeinterface:
-    case Bytecodes::_invokespecial:
-    case Bytecodes::_invokestatic:
-      {
-        methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index, bc);
-        if (m != NULL) {
-          return get_object(m)->as_method();
-        }
-      }
-    }
-  }
-
-  if (holder_is_accessible) { // Our declared holder is loaded.
-    instanceKlass* lookup = declared_holder->get_instanceKlass();
-    methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
-    if (m != NULL &&
-        (bc == Bytecodes::_invokestatic
-         ?  instanceKlass::cast(m->method_holder())->is_not_initialized()
-         : !instanceKlass::cast(m->method_holder())->is_loaded())) {
-      m = NULL;
-    }
-    if (m != NULL) {
-      // We found the method.
-      return get_object(m)->as_method();
-    }
-  }
-
-  // Either the declared holder was not loaded, or the method could
-  // not be found.  Create a dummy ciMethod to represent the failed
-  // lookup.
-  ciSymbol* name      = get_symbol(name_sym);
-  ciSymbol* signature = get_symbol(sig_sym);
-  return get_unloaded_method(declared_holder, name, signature, accessor);
-}
-
-
-// ------------------------------------------------------------------
-// ciEnv::get_fake_invokedynamic_method_impl
-ciMethod* ciEnv::get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
-                                                    int index, Bytecodes::Code bc,
-                                                    ciInstanceKlass* accessor) {
-  // Compare the following logic with InterpreterRuntime::resolve_invokedynamic.
-  assert(bc == Bytecodes::_invokedynamic, "must be invokedynamic");
-
-  bool is_resolved = cpool->cache()->main_entry_at(index)->is_resolved(bc);
-  if (is_resolved && cpool->cache()->secondary_entry_at(index)->is_f1_null())
+  if (bc == Bytecodes::_invokedynamic) {
+    ConstantPoolCacheEntry* secondary_entry = cpool->cache()->secondary_entry_at(index);
+    const bool is_resolved = !secondary_entry->is_f1_null();
     // FIXME: code generation could allow for null (unlinked) call site
-    is_resolved = false;
+    // The call site could be made patchable as follows:
+    // Load the appendix argument from the constant pool.
+    // Test the appendix argument and jump to a known deopt routine if it is null.
+    // Jump through a patchable call site, which is initially a deopt routine.
+    // Patch the call site to the nmethod entry point of the static compiled lambda form.
+    // As with other two-component call sites, both values must be independently verified.
 
-  // Call site might not be resolved yet.  We could create a real invoker method from the
-  // compiler, but it is simpler to stop the code path here with an unlinked method.
-  if (!is_resolved) {
+    if (is_resolved) {
+      // Get the invoker methodOop and the extra argument from the constant pool.
+      methodOop adapter = secondary_entry->f2_as_vfinal_method();
+      return get_object(adapter)->as_method();
+    }
+
+    // Fake a method that is equivalent to a declared method.
     ciInstanceKlass* holder    = get_object(SystemDictionary::MethodHandle_klass())->as_instance_klass();
-    ciSymbol*        name      = ciSymbol::invokeExact_name();
+    ciSymbol*        name      = ciSymbol::invokeBasic_name();
     ciSymbol*        signature = get_symbol(cpool->signature_ref_at(index));
     return get_unloaded_method(holder, name, signature, accessor);
+  } else {
+    const int holder_index = cpool->klass_ref_index_at(index);
+    bool holder_is_accessible;
+    ciKlass* holder = get_klass_by_index_impl(cpool, holder_index, holder_is_accessible, accessor);
+    ciInstanceKlass* declared_holder = get_instance_klass_for_declared_method_holder(holder);
+
+    // Get the method's name and signature.
+    Symbol* name_sym = cpool->name_ref_at(index);
+    Symbol* sig_sym  = cpool->signature_ref_at(index);
+
+    if (cpool->has_preresolution()
+        || (holder == ciEnv::MethodHandle_klass() &&
+            MethodHandles::is_signature_polymorphic_name(holder->get_klassOop(), name_sym))) {
+      // Short-circuit lookups for JSR 292-related call sites.
+      // That is, do not rely only on name-based lookups, because they may fail
+      // if the names are not resolvable in the boot class loader (7056328).
+      switch (bc) {
+      case Bytecodes::_invokevirtual:
+      case Bytecodes::_invokeinterface:
+      case Bytecodes::_invokespecial:
+      case Bytecodes::_invokestatic:
+        {
+          methodOop m = constantPoolOopDesc::method_at_if_loaded(cpool, index);
+          if (m != NULL) {
+            return get_object(m)->as_method();
+          }
+        }
+        break;
+      }
+    }
+
+    if (holder_is_accessible) {  // Our declared holder is loaded.
+      instanceKlass* lookup = declared_holder->get_instanceKlass();
+      methodOop m = lookup_method(accessor->get_instanceKlass(), lookup, name_sym, sig_sym, bc);
+      if (m != NULL &&
+          (bc == Bytecodes::_invokestatic
+           ?  instanceKlass::cast(m->method_holder())->is_not_initialized()
+           : !instanceKlass::cast(m->method_holder())->is_loaded())) {
+        m = NULL;
+      }
+      if (m != NULL) {
+        // We found the method.
+        return get_object(m)->as_method();
+      }
+    }
+
+    // Either the declared holder was not loaded, or the method could
+    // not be found.  Create a dummy ciMethod to represent the failed
+    // lookup.
+    ciSymbol* name      = get_symbol(name_sym);
+    ciSymbol* signature = get_symbol(sig_sym);
+    return get_unloaded_method(declared_holder, name, signature, accessor);
   }
-
-  // Get the invoker methodOop from the constant pool.
-  oop f1_value = cpool->cache()->main_entry_at(index)->f1();
-  methodOop signature_invoker = (methodOop) f1_value;
-  assert(signature_invoker != NULL && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(),
-         "correct result from LinkResolver::resolve_invokedynamic");
-
-  return get_object(signature_invoker)->as_method();
 }
 
 
@@ -851,11 +843,7 @@
 ciMethod* ciEnv::get_method_by_index(constantPoolHandle cpool,
                                      int index, Bytecodes::Code bc,
                                      ciInstanceKlass* accessor) {
-  if (bc == Bytecodes::_invokedynamic) {
-    GUARDED_VM_ENTRY(return get_fake_invokedynamic_method_impl(cpool, index, bc, accessor);)
-  } else {
-    GUARDED_VM_ENTRY(return get_method_by_index_impl(          cpool, index, bc, accessor);)
-  }
+  GUARDED_VM_ENTRY(return get_method_by_index_impl(cpool, index, bc, accessor);)
 }
 
 
@@ -961,7 +949,8 @@
                             ImplicitExceptionTable* inc_table,
                             AbstractCompiler* compiler,
                             int comp_level,
-                            bool has_unsafe_access) {
+                            bool has_unsafe_access,
+                            bool has_wide_vectors) {
   VM_ENTRY_MARK;
   nmethod* nm = NULL;
   {
@@ -1056,6 +1045,7 @@
       }
     } else {
       nm->set_has_unsafe_access(has_unsafe_access);
+      nm->set_has_wide_vectors(has_wide_vectors);
 
       // Record successful registration.
       // (Put nm into the task handle *before* publishing to the Java heap.)
@@ -1131,7 +1121,7 @@
 // ------------------------------------------------------------------
 // ciEnv::notice_inlined_method()
 void ciEnv::notice_inlined_method(ciMethod* method) {
-  _num_inlined_bytecodes += method->code_size();
+  _num_inlined_bytecodes += method->code_size_for_inlining();
 }
 
 // ------------------------------------------------------------------
@@ -1164,7 +1154,8 @@
       if (all_tiers) {
         log()->elem("method_not_compilable");
       } else {
-        log()->elem("method_not_compilable_at_tier");
+        log()->elem("method_not_compilable_at_tier level='%d'",
+                    current()->task()->comp_level());
       }
     }
     _compilable = new_compilable;
diff --git a/hotspot/src/share/vm/ci/ciEnv.hpp b/hotspot/src/share/vm/ci/ciEnv.hpp
index d00c9f7..103e532 100644
--- a/hotspot/src/share/vm/ci/ciEnv.hpp
+++ b/hotspot/src/share/vm/ci/ciEnv.hpp
@@ -152,9 +152,6 @@
   ciMethod*  get_method_by_index_impl(constantPoolHandle cpool,
                                       int method_index, Bytecodes::Code bc,
                                       ciInstanceKlass* loading_klass);
-  ciMethod*  get_fake_invokedynamic_method_impl(constantPoolHandle cpool,
-                                                int index, Bytecodes::Code bc,
-                                                ciInstanceKlass* accessor);
 
   // Helper methods
   bool       check_klass_accessibility(ciKlass* accessing_klass,
@@ -333,7 +330,8 @@
                        ImplicitExceptionTable*   inc_table,
                        AbstractCompiler*         compiler,
                        int                       comp_level,
-                       bool                      has_unsafe_access);
+                       bool                      has_unsafe_access,
+                       bool                      has_wide_vectors);
 
 
   // Access to certain well known ciObjects.
diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
index b7c2ab7..be730a0 100644
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -59,10 +59,7 @@
   _has_nonstatic_fields = ik->has_nonstatic_fields();
   _nonstatic_fields = NULL; // initialized lazily by compute_nonstatic_fields:
 
-  _nof_implementors = ik->nof_implementors();
-  for (int i = 0; i < implementors_limit; i++) {
-    _implementors[i] = NULL;  // we will fill these lazily
-  }
+  _implementor = NULL; // we will fill these lazily
 
   Thread *thread = Thread::current();
   if (ciObjectFactory::is_initialized()) {
@@ -102,7 +99,6 @@
   _nonstatic_field_size = -1;
   _has_nonstatic_fields = false;
   _nonstatic_fields = NULL;
-  _nof_implementors = -1;
   _loader = loader;
   _protection_domain = protection_domain;
   _is_shared = false;
@@ -133,17 +129,6 @@
 }
 
 // ------------------------------------------------------------------
-// ciInstanceKlass::compute_shared_nof_implementors
-int ciInstanceKlass::compute_shared_nof_implementors() {
-  // We requery this property, since it is a very old ciObject.
-  GUARDED_VM_ENTRY(
-    instanceKlass* ik = get_instanceKlass();
-    _nof_implementors = ik->nof_implementors();
-    return _nof_implementors;
-  )
-}
-
-// ------------------------------------------------------------------
 // ciInstanceKlass::loader
 oop ciInstanceKlass::loader() {
   ASSERT_IN_VM;
@@ -540,7 +525,7 @@
   if (is_shared()) {
     return is_final();  // approximately correct
   } else {
-    return !_has_subklass && (_nof_implementors == 0);
+    return !_has_subklass && (nof_implementors() == 0);
   }
 }
 
@@ -548,35 +533,31 @@
 // ciInstanceKlass::implementor
 //
 // Report an implementor of this interface.
-// Returns NULL if exact information is not available.
 // Note that there are various races here, since my copy
 // of _nof_implementors might be out of date with respect
 // to results returned by instanceKlass::implementor.
 // This is OK, since any dependencies we decide to assert
 // will be checked later under the Compile_lock.
-ciInstanceKlass* ciInstanceKlass::implementor(int n) {
-  if (n >= implementors_limit) {
-    return NULL;
-  }
-  ciInstanceKlass* impl = _implementors[n];
+ciInstanceKlass* ciInstanceKlass::implementor() {
+  ciInstanceKlass* impl = _implementor;
   if (impl == NULL) {
-    if (_nof_implementors > implementors_limit) {
-      return NULL;
-    }
     // Go into the VM to fetch the implementor.
     {
       VM_ENTRY_MARK;
-      klassOop k = get_instanceKlass()->implementor(n);
+      klassOop k = get_instanceKlass()->implementor();
       if (k != NULL) {
-        impl = CURRENT_THREAD_ENV->get_object(k)->as_instance_klass();
+        if (k == get_instanceKlass()->as_klassOop()) {
+          // More than one implementors. Use 'this' in this case.
+          impl = this;
+        } else {
+          impl = CURRENT_THREAD_ENV->get_object(k)->as_instance_klass();
+        }
       }
     }
     // Memoize this result.
     if (!is_shared()) {
-      _implementors[n] = (impl == NULL)? this: impl;
+      _implementor = impl;
     }
-  } else if (impl == this) {
-    impl = NULL;  // memoized null result from a VM query
   }
   return impl;
 }
diff --git a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
index 05ecf87..f8d0a7b 100644
--- a/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
+++ b/hotspot/src/share/vm/ci/ciInstanceKlass.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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,9 +65,11 @@
   ciConstantPoolCache*   _field_cache;  // cached map index->field
   GrowableArray<ciField*>* _nonstatic_fields;
 
-  enum { implementors_limit = instanceKlass::implementors_limit };
-  ciInstanceKlass*       _implementors[implementors_limit];
-  jint                   _nof_implementors;
+  // The possible values of the _implementor fall into following three cases:
+  //   NULL: no implementor.
+  //   A ciInstanceKlass that's not itself: one implementor.
+  //   Itsef: more than one implementors.
+  ciInstanceKlass*       _implementor;
 
   GrowableArray<ciField*>* _non_static_fields;
 
@@ -97,7 +99,6 @@
 
   void compute_shared_init_state();
   bool compute_shared_has_subklass();
-  int  compute_shared_nof_implementors();
   int  compute_nonstatic_fields();
   GrowableArray<ciField*>* compute_nonstatic_fields_impl(GrowableArray<ciField*>* super_fields);
 
@@ -158,10 +159,17 @@
     assert(is_loaded(), "must be loaded");
     return _nonstatic_oop_map_size; }
   ciInstanceKlass*       super();
-  jint                   nof_implementors()  {
+  jint                   nof_implementors() {
+    ciInstanceKlass* impl;
     assert(is_loaded(), "must be loaded");
-    if (_is_shared)  return compute_shared_nof_implementors();
-    return _nof_implementors;
+    impl = implementor();
+    if (impl == NULL) {
+      return 0;
+    } else if (impl != this) {
+      return 1;
+    } else {
+      return 2;
+    }
   }
 
   ciInstanceKlass* get_canonical_holder(int offset);
@@ -207,7 +215,7 @@
   // but consider adding to vmSymbols.hpp instead.
 
   bool is_leaf_type();
-  ciInstanceKlass* implementor(int n);
+  ciInstanceKlass* implementor();
 
   // Is the defining class loader of this class the default loader?
   bool uses_default_loader();
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/hotspot/src/share/vm/ci/ciMemberName.cpp
similarity index 63%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to hotspot/src/share/vm/ci/ciMemberName.cpp
index 077886f..44e5d9b 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/hotspot/src/share/vm/ci/ciMemberName.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -22,14 +22,18 @@
  *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+#include "precompiled.hpp"
+#include "ci/ciClassList.hpp"
+#include "ci/ciMemberName.hpp"
+#include "ci/ciUtilities.hpp"
+#include "classfile/javaClasses.hpp"
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
-    }
+// ------------------------------------------------------------------
+// ciMemberName::get_vmtarget
+//
+// Return: MN.vmtarget
+ciMethod* ciMemberName::get_vmtarget() const {
+  VM_ENTRY_MARK;
+  oop vmtarget_oop = java_lang_invoke_MemberName::vmtarget(get_oop());
+  return CURRENT_ENV->get_object(vmtarget_oop)->as_method();
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/hotspot/src/share/vm/ci/ciMemberName.hpp
similarity index 63%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to hotspot/src/share/vm/ci/ciMemberName.hpp
index 077886f..fdb6bad 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/hotspot/src/share/vm/ci/ciMemberName.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -22,14 +22,23 @@
  *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+#ifndef SHARE_VM_CI_CIMEMBERNAME_HPP
+#define SHARE_VM_CI_CIMEMBERNAME_HPP
 
-    public FileFormatException() {
-        super();
-    }
+#include "ci/ciCallProfile.hpp"
+#include "ci/ciInstance.hpp"
 
-    public FileFormatException(String s) {
-        super(s);
-    }
-}
+// ciMemberName
+//
+// The class represents a java.lang.invoke.MemberName object.
+class ciMemberName : public ciInstance {
+public:
+  ciMemberName(instanceHandle h_i) : ciInstance(h_i) {}
+
+  // What kind of ciObject is this?
+  bool is_member_name() const { return true; }
+
+  ciMethod* get_vmtarget() const;
+};
+
+#endif // SHARE_VM_CI_CIMEMBERNAME_HPP
diff --git a/hotspot/src/share/vm/ci/ciMethod.cpp b/hotspot/src/share/vm/ci/ciMethod.cpp
index 6049d7b..fcadab7 100644
--- a/hotspot/src/share/vm/ci/ciMethod.cpp
+++ b/hotspot/src/share/vm/ci/ciMethod.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -79,7 +79,7 @@
   _max_locals         = h_m()->max_locals();
   _code_size          = h_m()->code_size();
   _intrinsic_id       = h_m()->intrinsic_id();
-  _handler_count      = h_m()->exception_table()->length() / 4;
+  _handler_count      = h_m()->exception_table_length();
   _uses_monitors      = h_m()->access_flags().has_monitor_bytecodes();
   _balanced_monitors  = !_uses_monitors || h_m()->access_flags().is_monitor_matching();
   _is_c1_compilable   = !h_m()->is_not_c1_compilable();
@@ -198,7 +198,7 @@
   }
 
   // And load the exception table.
-  typeArrayOop exc_table = me->exception_table();
+  ExceptionTable exc_table(me);
 
   // Allocate one extra spot in our list of exceptions.  This
   // last entry will be used to represent the possibility that
@@ -209,13 +209,12 @@
                                          * (_handler_count + 1));
   if (_handler_count > 0) {
     for (int i=0; i<_handler_count; i++) {
-      int base = i*4;
       _exception_handlers[i] = new (arena) ciExceptionHandler(
                                 holder(),
-            /* start    */      exc_table->int_at(base),
-            /* limit    */      exc_table->int_at(base+1),
-            /* goto pc  */      exc_table->int_at(base+2),
-            /* cp index */      exc_table->int_at(base+3));
+            /* start    */      exc_table.start_pc(i),
+            /* limit    */      exc_table.end_pc(i),
+            /* goto pc  */      exc_table.handler_pc(i),
+            /* cp index */      exc_table.catch_type_index(i));
     }
   }
 
@@ -770,39 +769,37 @@
 // invokedynamic support
 
 // ------------------------------------------------------------------
-// ciMethod::is_method_handle_invoke
+// ciMethod::is_method_handle_intrinsic
 //
-// Return true if the method is an instance of one of the two
-// signature-polymorphic MethodHandle methods, invokeExact or invokeGeneric.
-bool ciMethod::is_method_handle_invoke() const {
-  if (!is_loaded()) {
-    bool flag = (holder()->name() == ciSymbol::java_lang_invoke_MethodHandle() &&
-                 methodOopDesc::is_method_handle_invoke_name(name()->sid()));
-    return flag;
-  }
-  VM_ENTRY_MARK;
-  return get_methodOop()->is_method_handle_invoke();
+// Return true if the method is an instance of the JVM-generated
+// signature-polymorphic MethodHandle methods, _invokeBasic, _linkToVirtual, etc.
+bool ciMethod::is_method_handle_intrinsic() const {
+  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
+  return (MethodHandles::is_signature_polymorphic(iid) &&
+          MethodHandles::is_signature_polymorphic_intrinsic(iid));
 }
 
 // ------------------------------------------------------------------
-// ciMethod::is_method_handle_adapter
+// ciMethod::is_compiled_lambda_form
 //
 // Return true if the method is a generated MethodHandle adapter.
-// These are built by MethodHandleCompiler.
-bool ciMethod::is_method_handle_adapter() const {
-  if (!is_loaded())  return false;
-  VM_ENTRY_MARK;
-  return get_methodOop()->is_method_handle_adapter();
+// These are built by Java code.
+bool ciMethod::is_compiled_lambda_form() const {
+  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
+  return iid == vmIntrinsics::_compiledLambdaForm;
 }
 
-ciInstance* ciMethod::method_handle_type() {
-  check_is_loaded();
-  VM_ENTRY_MARK;
-  oop mtype = get_methodOop()->method_handle_type();
-  return CURRENT_THREAD_ENV->get_object(mtype)->as_instance();
+// ------------------------------------------------------------------
+// ciMethod::has_member_arg
+//
+// Return true if the method is a linker intrinsic like _linkToVirtual.
+// These are built by the JVM.
+bool ciMethod::has_member_arg() const {
+  vmIntrinsics::ID iid = _intrinsic_id;  // do not check if loaded
+  return (MethodHandles::is_signature_polymorphic(iid) &&
+          MethodHandles::has_member_arg(iid));
 }
 
-
 // ------------------------------------------------------------------
 // ciMethod::ensure_method_data
 //
@@ -1025,28 +1022,13 @@
 // ------------------------------------------------------------------
 // ciMethod::code_size_for_inlining
 //
-// Code size for inlining decisions.
-//
-// Don't fully count method handle adapters against inlining budgets:
-// the metric we use here is the number of call sites in the adapter
-// as they are probably the instructions which generate some code.
+// Code size for inlining decisions.  This method returns a code
+// size of 1 for methods which has the ForceInline annotation.
 int ciMethod::code_size_for_inlining() {
   check_is_loaded();
-
-  // Method handle adapters
-  if (is_method_handle_adapter()) {
-    // Count call sites
-    int call_site_count = 0;
-    ciBytecodeStream iter(this);
-    while (iter.next() != ciBytecodeStream::EOBC()) {
-      if (Bytecodes::is_invoke(iter.cur_bc())) {
-        call_site_count++;
-      }
-    }
-    return call_site_count;
+  if (get_methodOop()->force_inline()) {
+    return 1;
   }
-
-  // Normal method
   return code_size();
 }
 
@@ -1128,7 +1110,8 @@
     constantPoolHandle pool (THREAD, get_methodOop()->constants());
     methodHandle spec_method;
     KlassHandle  spec_klass;
-    LinkResolver::resolve_method(spec_method, spec_klass, pool, refinfo_index, THREAD);
+    Bytecodes::Code code = (is_static ? Bytecodes::_invokestatic : Bytecodes::_invokevirtual);
+    LinkResolver::resolve_method_statically(spec_method, spec_klass, code, pool, refinfo_index, THREAD);
     if (HAS_PENDING_EXCEPTION) {
       CLEAR_PENDING_EXCEPTION;
       return false;
@@ -1208,8 +1191,16 @@
 //
 // Print the name of this method, without signature.
 void ciMethod::print_short_name(outputStream* st) {
-  check_is_loaded();
-  GUARDED_VM_ENTRY(get_methodOop()->print_short_name(st);)
+  if (is_loaded()) {
+    GUARDED_VM_ENTRY(get_methodOop()->print_short_name(st););
+  } else {
+    // Fall back if method is not loaded.
+    holder()->print_name_on(st);
+    st->print("::");
+    name()->print_symbol_on(st);
+    if (WizardMode)
+      signature()->as_symbol()->print_symbol_on(st);
+  }
 }
 
 // ------------------------------------------------------------------
@@ -1225,7 +1216,9 @@
   st->print(" signature=");
   signature()->as_symbol()->print_symbol_on(st);
   if (is_loaded()) {
-    st->print(" loaded=true flags=");
+    st->print(" loaded=true");
+    st->print(" arg_size=%d", arg_size());
+    st->print(" flags=");
     flags().print_member_flags(st);
   } else {
     st->print(" loaded=false");
diff --git a/hotspot/src/share/vm/ci/ciMethod.hpp b/hotspot/src/share/vm/ci/ciMethod.hpp
index 98571ae..39ee81b 100644
--- a/hotspot/src/share/vm/ci/ciMethod.hpp
+++ b/hotspot/src/share/vm/ci/ciMethod.hpp
@@ -133,16 +133,20 @@
     return _signature->size() + (_flags.is_static() ? 0 : 1);
   }
   // Report the number of elements on stack when invoking this method.
-  // This is different than the regular arg_size because invokdynamic
+  // This is different than the regular arg_size because invokedynamic
   // has an implicit receiver.
   int invoke_arg_size(Bytecodes::Code code) const {
-    int arg_size = _signature->size();
-    // Add a receiver argument, maybe:
-    if (code != Bytecodes::_invokestatic &&
-        code != Bytecodes::_invokedynamic) {
-      arg_size++;
+    if (is_loaded()) {
+      return arg_size();
+    } else {
+      int arg_size = _signature->size();
+      // Add a receiver argument, maybe:
+      if (code != Bytecodes::_invokestatic &&
+          code != Bytecodes::_invokedynamic) {
+        arg_size++;
+      }
+      return arg_size;
     }
-    return arg_size;
   }
 
 
@@ -160,6 +164,9 @@
   // Code size for inlining decisions.
   int code_size_for_inlining();
 
+  bool force_inline() { return get_methodOop()->force_inline(); }
+  bool dont_inline()  { return get_methodOop()->dont_inline();  }
+
   int comp_level();
   int highest_osr_comp_level();
 
@@ -256,9 +263,9 @@
   int scale_count(int count, float prof_factor = 1.);  // make MDO count commensurate with IIC
 
   // JSR 292 support
-  bool is_method_handle_invoke()  const;
-  bool is_method_handle_adapter() const;
-  ciInstance* method_handle_type();
+  bool is_method_handle_intrinsic()  const;
+  bool is_compiled_lambda_form() const;
+  bool has_member_arg() const;
 
   // What kind of ciObject is this?
   bool is_method()                               { return true; }
diff --git a/hotspot/src/share/vm/ci/ciMethodHandle.cpp b/hotspot/src/share/vm/ci/ciMethodHandle.cpp
index 831c6a5..2d3bacf 100644
--- a/hotspot/src/share/vm/ci/ciMethodHandle.cpp
+++ b/hotspot/src/share/vm/ci/ciMethodHandle.cpp
@@ -24,84 +24,18 @@
 
 #include "precompiled.hpp"
 #include "ci/ciClassList.hpp"
-#include "ci/ciInstance.hpp"
-#include "ci/ciMethodData.hpp"
 #include "ci/ciMethodHandle.hpp"
 #include "ci/ciUtilities.hpp"
-#include "prims/methodHandleWalk.hpp"
-#include "prims/methodHandles.hpp"
-
-// ciMethodHandle
+#include "classfile/javaClasses.hpp"
 
 // ------------------------------------------------------------------
-// ciMethodHandle::get_adapter
+// ciMethodHandle::get_vmtarget
 //
-// Return an adapter for this MethodHandle.
-ciMethod* ciMethodHandle::get_adapter_impl(bool is_invokedynamic) {
+// Return: MH.form -> LF.vmentry -> MN.vmtarget
+ciMethod* ciMethodHandle::get_vmtarget() const {
   VM_ENTRY_MARK;
-  Handle h(get_oop());
-  methodHandle callee(_callee->get_methodOop());
-  assert(callee->is_method_handle_invoke(), "");
-  oop mt1 = callee->method_handle_type();
-  oop mt2 = java_lang_invoke_MethodHandle::type(h());
-  if (!java_lang_invoke_MethodType::equals(mt1, mt2)) {
-    if (PrintMiscellaneous && (Verbose || WizardMode)) {
-      tty->print_cr("ciMethodHandle::get_adapter: types not equal");
-      mt1->print(); mt2->print();
-    }
-    return NULL;
-  }
-  // We catch all exceptions here that could happen in the method
-  // handle compiler and stop the VM.
-  MethodHandleCompiler mhc(h, callee->name(), callee->signature(), _profile.count(), is_invokedynamic, THREAD);
-  if (!HAS_PENDING_EXCEPTION) {
-    methodHandle m = mhc.compile(THREAD);
-    if (!HAS_PENDING_EXCEPTION) {
-      return CURRENT_ENV->get_object(m())->as_method();
-    }
-  }
-  if (PrintMiscellaneous && (Verbose || WizardMode)) {
-    tty->print("*** ciMethodHandle::get_adapter => ");
-    PENDING_EXCEPTION->print();
-    tty->print("*** get_adapter (%s): ", is_invokedynamic ? "indy" : "mh"); ((ciObject*)this)->print();
-  }
-  CLEAR_PENDING_EXCEPTION;
-  return NULL;
+  oop form_oop     = java_lang_invoke_MethodHandle::form(get_oop());
+  oop vmentry_oop  = java_lang_invoke_LambdaForm::vmentry(form_oop);
+  oop vmtarget_oop = java_lang_invoke_MemberName::vmtarget(vmentry_oop);
+  return CURRENT_ENV->get_object(vmtarget_oop)->as_method();
 }
-
-// ------------------------------------------------------------------
-// ciMethodHandle::get_adapter
-//
-// Return an adapter for this MethodHandle.
-ciMethod* ciMethodHandle::get_adapter(bool is_invokedynamic) {
-  ciMethod* result = get_adapter_impl(is_invokedynamic);
-  if (result) {
-    // Fake up the MDO maturity.
-    ciMethodData* mdo = result->method_data();
-    if (mdo != NULL && _caller->method_data() != NULL && _caller->method_data()->is_mature()) {
-      mdo->set_mature();
-    }
-  }
-  return result;
-}
-
-
-#ifdef ASSERT
-// ------------------------------------------------------------------
-// ciMethodHandle::print_chain_impl
-//
-// Implementation of the print method.
-void ciMethodHandle::print_chain_impl() {
-  ASSERT_IN_VM;
-  MethodHandleChain::print(get_oop());
-}
-
-
-// ------------------------------------------------------------------
-// ciMethodHandle::print_chain
-//
-// Implementation of the print_chain method.
-void ciMethodHandle::print_chain() {
-  GUARDED_VM_ENTRY(print_chain_impl(););
-}
-#endif
diff --git a/hotspot/src/share/vm/ci/ciMethodHandle.hpp b/hotspot/src/share/vm/ci/ciMethodHandle.hpp
index 536ebef..3e1fc66 100644
--- a/hotspot/src/share/vm/ci/ciMethodHandle.hpp
+++ b/hotspot/src/share/vm/ci/ciMethodHandle.hpp
@@ -25,61 +25,20 @@
 #ifndef SHARE_VM_CI_CIMETHODHANDLE_HPP
 #define SHARE_VM_CI_CIMETHODHANDLE_HPP
 
-#include "ci/ciCallProfile.hpp"
+#include "ci/ciClassList.hpp"
 #include "ci/ciInstance.hpp"
-#include "prims/methodHandles.hpp"
 
 // ciMethodHandle
 //
 // The class represents a java.lang.invoke.MethodHandle object.
 class ciMethodHandle : public ciInstance {
-private:
-  ciMethod*      _callee;
-  ciMethod*      _caller;
-  ciCallProfile  _profile;
-  ciMethod*      _method_handle_adapter;
-  ciMethod*      _invokedynamic_adapter;
-
-  // Return an adapter for this MethodHandle.
-  ciMethod* get_adapter_impl(bool is_invokedynamic);
-  ciMethod* get_adapter(     bool is_invokedynamic);
-
-protected:
-  void print_chain_impl() NOT_DEBUG_RETURN;
-
 public:
-  ciMethodHandle(instanceHandle h_i) :
-    ciInstance(h_i),
-    _callee(NULL),
-    _caller(NULL),
-    _method_handle_adapter(NULL),
-    _invokedynamic_adapter(NULL)
-  {}
+  ciMethodHandle(instanceHandle h_i) : ciInstance(h_i) {}
 
   // What kind of ciObject is this?
   bool is_method_handle() const { return true; }
 
-  void set_callee(ciMethod* m)                  { _callee  = m;       }
-  void set_caller(ciMethod* m)                  { _caller  = m;       }
-  void set_call_profile(ciCallProfile profile)  { _profile = profile; }
-
-  // Return an adapter for a MethodHandle call.
-  ciMethod* get_method_handle_adapter() {
-    if (_method_handle_adapter == NULL) {
-      _method_handle_adapter = get_adapter(false);
-    }
-    return _method_handle_adapter;
-  }
-
-  // Return an adapter for an invokedynamic call.
-  ciMethod* get_invokedynamic_adapter() {
-    if (_invokedynamic_adapter == NULL) {
-      _invokedynamic_adapter = get_adapter(true);
-    }
-    return _invokedynamic_adapter;
-  }
-
-  void print_chain() NOT_DEBUG_RETURN;
+  ciMethod* get_vmtarget() const;
 };
 
 #endif // SHARE_VM_CI_CIMETHODHANDLE_HPP
diff --git a/hotspot/src/share/vm/ci/ciMethodType.hpp b/hotspot/src/share/vm/ci/ciMethodType.hpp
new file mode 100644
index 0000000..0a97855
--- /dev/null
+++ b/hotspot/src/share/vm/ci/ciMethodType.hpp
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_CI_CIMETHODTYPE_HPP
+#define SHARE_VM_CI_CIMETHODTYPE_HPP
+
+#include "ci/ciInstance.hpp"
+#include "ci/ciUtilities.hpp"
+#include "classfile/javaClasses.hpp"
+
+// ciMethodType
+//
+// The class represents a java.lang.invoke.MethodType object.
+class ciMethodType : public ciInstance {
+private:
+  ciType* class_to_citype(oop klass_oop) const {
+    if (java_lang_Class::is_primitive(klass_oop)) {
+      BasicType bt = java_lang_Class::primitive_type(klass_oop);
+      return ciType::make(bt);
+    } else {
+      klassOop k = java_lang_Class::as_klassOop(klass_oop);
+      return CURRENT_ENV->get_object(k)->as_klass();
+    }
+  }
+
+public:
+  ciMethodType(instanceHandle h_i) : ciInstance(h_i) {}
+
+  // What kind of ciObject is this?
+  bool is_method_type() const { return true; }
+
+  ciType* rtype() const {
+    GUARDED_VM_ENTRY(
+      oop rtype = java_lang_invoke_MethodType::rtype(get_oop());
+      return class_to_citype(rtype);
+    )
+  }
+
+  int ptype_count() const {
+    GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_count(get_oop());)
+  }
+
+  int ptype_slot_count() const {
+    GUARDED_VM_ENTRY(return java_lang_invoke_MethodType::ptype_slot_count(get_oop());)
+  }
+
+  ciType* ptype_at(int index) const {
+    GUARDED_VM_ENTRY(
+      oop ptype = java_lang_invoke_MethodType::ptype(get_oop(), index);
+      return class_to_citype(ptype);
+    )
+  }
+};
+
+#endif // SHARE_VM_CI_CIMETHODTYPE_HPP
diff --git a/hotspot/src/share/vm/ci/ciObject.hpp b/hotspot/src/share/vm/ci/ciObject.hpp
index be46103..0a56109 100644
--- a/hotspot/src/share/vm/ci/ciObject.hpp
+++ b/hotspot/src/share/vm/ci/ciObject.hpp
@@ -138,13 +138,15 @@
   jobject constant_encoding();
 
   // What kind of ciObject is this?
-  virtual bool is_null_object() const       { return false; }
-  virtual bool is_call_site() const         { return false; }
-  virtual bool is_cpcache() const           { return false; }
+  virtual bool is_null_object()       const { return false; }
+  virtual bool is_call_site()         const { return false; }
+  virtual bool is_cpcache()           const { return false; }
   virtual bool is_instance()                { return false; }
+  virtual bool is_member_name()       const { return false; }
   virtual bool is_method()                  { return false; }
   virtual bool is_method_data()             { return false; }
-  virtual bool is_method_handle() const     { return false; }
+  virtual bool is_method_handle()     const { return false; }
+  virtual bool is_method_type()       const { return false; }
   virtual bool is_array()                   { return false; }
   virtual bool is_obj_array()               { return false; }
   virtual bool is_type_array()              { return false; }
@@ -192,105 +194,114 @@
   }
 
   // Subclass casting with assertions.
-  ciNullObject*            as_null_object() {
+  ciNullObject* as_null_object() {
     assert(is_null_object(), "bad cast");
     return (ciNullObject*)this;
   }
-  ciCallSite*              as_call_site() {
+  ciCallSite* as_call_site() {
     assert(is_call_site(), "bad cast");
-    return (ciCallSite*) this;
+    return (ciCallSite*)this;
   }
-  ciCPCache*               as_cpcache() {
+  ciCPCache* as_cpcache() {
     assert(is_cpcache(), "bad cast");
-    return (ciCPCache*) this;
+    return (ciCPCache*)this;
   }
-  ciInstance*              as_instance() {
+  ciInstance* as_instance() {
     assert(is_instance(), "bad cast");
     return (ciInstance*)this;
   }
-  ciMethod*                as_method() {
+  ciMemberName* as_member_name() {
+    assert(is_member_name(), "bad cast");
+    return (ciMemberName*)this;
+  }
+  ciMethod* as_method() {
     assert(is_method(), "bad cast");
     return (ciMethod*)this;
   }
-  ciMethodData*            as_method_data() {
+  ciMethodData* as_method_data() {
     assert(is_method_data(), "bad cast");
     return (ciMethodData*)this;
   }
-  ciMethodHandle*          as_method_handle() {
+  ciMethodHandle* as_method_handle() {
     assert(is_method_handle(), "bad cast");
-    return (ciMethodHandle*) this;
+    return (ciMethodHandle*)this;
   }
-  ciArray*                 as_array() {
+  ciMethodType* as_method_type() {
+    assert(is_method_type(), "bad cast");
+    return (ciMethodType*)this;
+  }
+  ciArray* as_array() {
     assert(is_array(), "bad cast");
     return (ciArray*)this;
   }
-  ciObjArray*              as_obj_array() {
+  ciObjArray* as_obj_array() {
     assert(is_obj_array(), "bad cast");
     return (ciObjArray*)this;
   }
-  ciTypeArray*             as_type_array() {
+  ciTypeArray* as_type_array() {
     assert(is_type_array(), "bad cast");
     return (ciTypeArray*)this;
   }
-  ciSymbol*                as_symbol() {
+  ciSymbol* as_symbol() {
     assert(is_symbol(), "bad cast");
     return (ciSymbol*)this;
   }
-  ciType*                  as_type() {
+  ciType* as_type() {
     assert(is_type(), "bad cast");
     return (ciType*)this;
   }
-  ciReturnAddress*         as_return_address() {
+  ciReturnAddress* as_return_address() {
     assert(is_return_address(), "bad cast");
     return (ciReturnAddress*)this;
   }
-  ciKlass*                 as_klass() {
+  ciKlass* as_klass() {
     assert(is_klass(), "bad cast");
     return (ciKlass*)this;
   }
-  ciInstanceKlass*         as_instance_klass() {
+  ciInstanceKlass* as_instance_klass() {
     assert(is_instance_klass(), "bad cast");
     return (ciInstanceKlass*)this;
   }
-  ciMethodKlass*           as_method_klass() {
+  ciMethodKlass* as_method_klass() {
     assert(is_method_klass(), "bad cast");
     return (ciMethodKlass*)this;
   }
-  ciArrayKlass*            as_array_klass() {
+  ciArrayKlass* as_array_klass() {
     assert(is_array_klass(), "bad cast");
     return (ciArrayKlass*)this;
   }
-  ciObjArrayKlass*         as_obj_array_klass() {
+  ciObjArrayKlass* as_obj_array_klass() {
     assert(is_obj_array_klass(), "bad cast");
     return (ciObjArrayKlass*)this;
   }
-  ciTypeArrayKlass*        as_type_array_klass() {
+  ciTypeArrayKlass* as_type_array_klass() {
     assert(is_type_array_klass(), "bad cast");
     return (ciTypeArrayKlass*)this;
   }
-  ciKlassKlass*            as_klass_klass() {
+  ciKlassKlass* as_klass_klass() {
     assert(is_klass_klass(), "bad cast");
     return (ciKlassKlass*)this;
   }
-  ciInstanceKlassKlass*    as_instance_klass_klass() {
+  ciInstanceKlassKlass* as_instance_klass_klass() {
     assert(is_instance_klass_klass(), "bad cast");
     return (ciInstanceKlassKlass*)this;
   }
-  ciArrayKlassKlass*       as_array_klass_klass() {
+  ciArrayKlassKlass* as_array_klass_klass() {
     assert(is_array_klass_klass(), "bad cast");
     return (ciArrayKlassKlass*)this;
   }
-  ciObjArrayKlassKlass*    as_obj_array_klass_klass() {
+  ciObjArrayKlassKlass* as_obj_array_klass_klass() {
     assert(is_obj_array_klass_klass(), "bad cast");
     return (ciObjArrayKlassKlass*)this;
   }
-  ciTypeArrayKlassKlass*   as_type_array_klass_klass() {
+  ciTypeArrayKlassKlass* as_type_array_klass_klass() {
     assert(is_type_array_klass_klass(), "bad cast");
     return (ciTypeArrayKlassKlass*)this;
   }
 
   // Print debugging output about this ciObject.
-  void print(outputStream* st = tty);
+  void print(outputStream* st);
+  void print() { print(tty); }  // GDB cannot handle default arguments
 
   // Print debugging output about the oop this ciObject represents.
   void print_oop(outputStream* st = tty);
diff --git a/hotspot/src/share/vm/ci/ciObjectFactory.cpp b/hotspot/src/share/vm/ci/ciObjectFactory.cpp
index 9aa6b26..e0ab96b3 100644
--- a/hotspot/src/share/vm/ci/ciObjectFactory.cpp
+++ b/hotspot/src/share/vm/ci/ciObjectFactory.cpp
@@ -28,9 +28,11 @@
 #include "ci/ciInstance.hpp"
 #include "ci/ciInstanceKlass.hpp"
 #include "ci/ciInstanceKlassKlass.hpp"
+#include "ci/ciMemberName.hpp"
 #include "ci/ciMethod.hpp"
 #include "ci/ciMethodData.hpp"
 #include "ci/ciMethodHandle.hpp"
+#include "ci/ciMethodType.hpp"
 #include "ci/ciMethodKlass.hpp"
 #include "ci/ciNullObject.hpp"
 #include "ci/ciObjArray.hpp"
@@ -111,7 +113,7 @@
   // This Arena is long lived and exists in the resource mark of the
   // compiler thread that initializes the initial ciObjectFactory which
   // creates the shared ciObjects that all later ciObjectFactories use.
-  Arena* arena = new Arena();
+  Arena* arena = new (mtCompiler) Arena();
   ciEnv initial(arena);
   ciEnv* env = ciEnv::current();
   env->_factory->init_shared_objects();
@@ -344,8 +346,12 @@
     instanceHandle h_i(THREAD, (instanceOop)o);
     if (java_lang_invoke_CallSite::is_instance(o))
       return new (arena()) ciCallSite(h_i);
+    else if (java_lang_invoke_MemberName::is_instance(o))
+      return new (arena()) ciMemberName(h_i);
     else if (java_lang_invoke_MethodHandle::is_instance(o))
       return new (arena()) ciMethodHandle(h_i);
+    else if (java_lang_invoke_MethodType::is_instance(o))
+      return new (arena()) ciMethodType(h_i);
     else
       return new (arena()) ciInstance(h_i);
   } else if (o->is_objArray()) {
diff --git a/hotspot/src/share/vm/ci/ciSignature.cpp b/hotspot/src/share/vm/ci/ciSignature.cpp
index 229a904..d09cc2f 100644
--- a/hotspot/src/share/vm/ci/ciSignature.cpp
+++ b/hotspot/src/share/vm/ci/ciSignature.cpp
@@ -23,6 +23,7 @@
  */
 
 #include "precompiled.hpp"
+#include "ci/ciMethodType.hpp"
 #include "ci/ciSignature.hpp"
 #include "ci/ciUtilities.hpp"
 #include "memory/allocation.inline.hpp"
@@ -80,6 +81,24 @@
 }
 
 // ------------------------------------------------------------------
+// ciSignature::ciSignature
+ciSignature::ciSignature(ciKlass* accessing_klass, ciSymbol* symbol, ciMethodType* method_type) :
+  _symbol(symbol),
+  _accessing_klass(accessing_klass),
+  _size( method_type->ptype_slot_count()),
+  _count(method_type->ptype_count())
+{
+  ASSERT_IN_VM;
+  EXCEPTION_CONTEXT;
+  Arena* arena = CURRENT_ENV->arena();
+  _types = new (arena) GrowableArray<ciType*>(arena, _count + 1, 0, NULL);
+  for (int i = 0; i < _count; i++) {
+    _types->append(method_type->ptype_at(i));
+  }
+  _types->append(method_type->rtype());
+}
+
+// ------------------------------------------------------------------
 // ciSignature::return_type
 //
 // What is the return type of this signature?
diff --git a/hotspot/src/share/vm/ci/ciSignature.hpp b/hotspot/src/share/vm/ci/ciSignature.hpp
index 25ba097..96682eb 100644
--- a/hotspot/src/share/vm/ci/ciSignature.hpp
+++ b/hotspot/src/share/vm/ci/ciSignature.hpp
@@ -39,13 +39,15 @@
   ciKlass*  _accessing_klass;
 
   GrowableArray<ciType*>* _types;
-  int _size;
-  int _count;
+  int _size;   // number of stack slots required for arguments
+  int _count;  // number of parameter types in the signature
 
   friend class ciMethod;
+  friend class ciBytecodeStream;
   friend class ciObjectFactory;
 
   ciSignature(ciKlass* accessing_klass, constantPoolHandle cpool, ciSymbol* signature);
+  ciSignature(ciKlass* accessing_klass,                           ciSymbol* signature, ciMethodType* method_type);
 
   void get_all_klasses();
 
diff --git a/hotspot/src/share/vm/ci/ciStreams.cpp b/hotspot/src/share/vm/ci/ciStreams.cpp
index 2801c3e..242f6d9 100644
--- a/hotspot/src/share/vm/ci/ciStreams.cpp
+++ b/hotspot/src/share/vm/ci/ciStreams.cpp
@@ -355,12 +355,75 @@
 // ciBytecodeStream::get_method
 //
 // If this is a method invocation bytecode, get the invoked method.
-ciMethod* ciBytecodeStream::get_method(bool& will_link) {
+// Additionally return the declared signature to get more concrete
+// type information if required (Cf. invokedynamic and invokehandle).
+ciMethod* ciBytecodeStream::get_method(bool& will_link, ciSignature* *declared_signature_result) {
+  VM_ENTRY_MARK;
+  ciEnv* env = CURRENT_ENV;
+  constantPoolHandle cpool(_method->get_methodOop()->constants());
+  ciMethod* m = env->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
+  will_link = m->is_loaded();
+
+  // Use the MethodType stored in the CP cache to create a signature
+  // with correct types (in respect to class loaders).
+  if (has_method_type()) {
+    ciSymbol*     sig_sym     = env->get_symbol(cpool->symbol_at(get_method_signature_index()));
+    ciKlass*      pool_holder = env->get_object(cpool->pool_holder())->as_klass();
+    ciMethodType* method_type = get_method_type();
+    ciSignature* declared_signature = new (env->arena()) ciSignature(pool_holder, sig_sym, method_type);
+    (*declared_signature_result) = declared_signature;
+  } else {
+    (*declared_signature_result) = m->signature();
+  }
+  return m;
+}
+
+// ------------------------------------------------------------------
+// ciBytecodeStream::has_appendix
+//
+// Returns true if there is an appendix argument stored in the
+// constant pool cache at the current bci.
+bool ciBytecodeStream::has_appendix() {
   VM_ENTRY_MARK;
   constantPoolHandle cpool(_method->get_methodOop()->constants());
-  ciMethod* m = CURRENT_ENV->get_method_by_index(cpool, get_method_index(), cur_bc(), _holder);
-  will_link = m->is_loaded();
-  return m;
+  return constantPoolOopDesc::has_appendix_at_if_loaded(cpool, get_method_index());
+}
+
+// ------------------------------------------------------------------
+// ciBytecodeStream::get_appendix
+//
+// Return the appendix argument stored in the constant pool cache at
+// the current bci.
+ciObject* ciBytecodeStream::get_appendix() {
+  VM_ENTRY_MARK;
+  constantPoolHandle cpool(_method->get_methodOop()->constants());
+  oop appendix_oop = constantPoolOopDesc::appendix_at_if_loaded(cpool, get_method_index());
+  return CURRENT_ENV->get_object(appendix_oop);
+}
+
+// ------------------------------------------------------------------
+// ciBytecodeStream::has_method_type
+//
+// Returns true if there is a MethodType argument stored in the
+// constant pool cache at the current bci.
+bool ciBytecodeStream::has_method_type() {
+  GUARDED_VM_ENTRY(
+    constantPoolHandle cpool(_method->get_methodOop()->constants());
+    return constantPoolOopDesc::has_method_type_at_if_loaded(cpool, get_method_index());
+  )
+}
+
+// ------------------------------------------------------------------
+// ciBytecodeStream::get_method_type
+//
+// Return the MethodType stored in the constant pool cache at
+// the current bci.
+ciMethodType* ciBytecodeStream::get_method_type() {
+  GUARDED_VM_ENTRY(
+    constantPoolHandle cpool(_method->get_methodOop()->constants());
+    oop method_type_oop = constantPoolOopDesc::method_type_at_if_loaded(cpool, get_method_index());
+    return CURRENT_ENV->get_object(method_type_oop)->as_method_type();
+  )
 }
 
 // ------------------------------------------------------------------
@@ -378,9 +441,9 @@
   VM_ENTRY_MARK;
   constantPoolHandle cpool(_method->get_methodOop()->constants());
   bool ignore;
-  // report as InvokeDynamic for invokedynamic, which is syntactically classless
+  // report as MethodHandle for invokedynamic, which is syntactically classless
   if (cur_bc() == Bytecodes::_invokedynamic)
-    return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_lang_invoke_InvokeDynamic(), false);
+    return CURRENT_ENV->get_klass_by_name(_holder, ciSymbol::java_lang_invoke_MethodHandle(), false);
   return CURRENT_ENV->get_klass_by_index(cpool, get_method_holder_index(), ignore, _holder);
 }
 
@@ -402,11 +465,12 @@
 // referenced by the current bytecode.  Used for generating
 // deoptimization information.
 int ciBytecodeStream::get_method_signature_index() {
-  VM_ENTRY_MARK;
-  constantPoolOop cpool = _holder->get_instanceKlass()->constants();
-  int method_index = get_method_index();
-  int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
-  return cpool->signature_ref_index_at(name_and_type_index);
+  GUARDED_VM_ENTRY(
+    constantPoolOop cpool = _holder->get_instanceKlass()->constants();
+    const int method_index = get_method_index();
+    const int name_and_type_index = cpool->name_and_type_ref_index_at(method_index);
+    return cpool->signature_ref_index_at(name_and_type_index);
+  )
 }
 
 // ------------------------------------------------------------------
@@ -434,7 +498,7 @@
   // Get the CallSite from the constant pool cache.
   int method_index = get_method_index();
   ConstantPoolCacheEntry* cpcache_entry = cpcache->secondary_entry_at(method_index);
-  oop call_site_oop = cpcache_entry->f1();
+  oop call_site_oop = cpcache_entry->f1_as_instance();
 
   // Create a CallSite object and return it.
   return CURRENT_ENV->get_object(call_site_oop)->as_call_site();
diff --git a/hotspot/src/share/vm/ci/ciStreams.hpp b/hotspot/src/share/vm/ci/ciStreams.hpp
index b03642c..73bc9c5 100644
--- a/hotspot/src/share/vm/ci/ciStreams.hpp
+++ b/hotspot/src/share/vm/ci/ciStreams.hpp
@@ -151,6 +151,8 @@
   // Does this instruction contain an index which refes into the CP cache?
   bool has_cache_index() const { return Bytecodes::uses_cp_cache(cur_bc_raw()); }
 
+  bool has_optional_appendix() { return Bytecodes::has_optional_appendix(cur_bc_raw()); }
+
   int get_index_u1() const {
     return bytecode().get_index_u1(cur_bc_raw());
   }
@@ -257,11 +259,14 @@
   int      get_field_holder_index();
   int      get_field_signature_index();
 
-  // If this is a method invocation bytecode, get the invoked method.
-  ciMethod* get_method(bool& will_link);
-  ciKlass*  get_declared_method_holder();
-  int       get_method_holder_index();
-  int       get_method_signature_index();
+  ciMethod*     get_method(bool& will_link, ciSignature* *declared_signature_result);
+  bool          has_appendix();
+  ciObject*     get_appendix();
+  bool          has_method_type();
+  ciMethodType* get_method_type();
+  ciKlass*      get_declared_method_holder();
+  int           get_method_holder_index();
+  int           get_method_signature_index();
 
   ciCPCache*  get_cpcache() const;
   ciCallSite* get_call_site();
diff --git a/hotspot/src/share/vm/ci/ciSymbol.cpp b/hotspot/src/share/vm/ci/ciSymbol.cpp
index d253e59..e6987bf 100644
--- a/hotspot/src/share/vm/ci/ciSymbol.cpp
+++ b/hotspot/src/share/vm/ci/ciSymbol.cpp
@@ -83,6 +83,10 @@
   GUARDED_VM_ENTRY(return get_symbol()->starts_with(prefix, len);)
 }
 
+bool ciSymbol::is_signature_polymorphic_name()  const {
+  GUARDED_VM_ENTRY(return MethodHandles::is_signature_polymorphic_name(get_symbol());)
+}
+
 // ------------------------------------------------------------------
 // ciSymbol::index_of
 //
diff --git a/hotspot/src/share/vm/ci/ciSymbol.hpp b/hotspot/src/share/vm/ci/ciSymbol.hpp
index aae171a..90f2b7b 100644
--- a/hotspot/src/share/vm/ci/ciSymbol.hpp
+++ b/hotspot/src/share/vm/ci/ciSymbol.hpp
@@ -107,6 +107,8 @@
 
   // Are two ciSymbols equal?
   bool equals(ciSymbol* obj) { return this->_symbol == obj->get_symbol(); }
+
+  bool is_signature_polymorphic_name() const;
 };
 
 #endif // SHARE_VM_CI_CISYMBOL_HPP
diff --git a/hotspot/src/share/vm/ci/ciTypeFlow.cpp b/hotspot/src/share/vm/ci/ciTypeFlow.cpp
index 6678b4c..98e655e 100644
--- a/hotspot/src/share/vm/ci/ciTypeFlow.cpp
+++ b/hotspot/src/share/vm/ci/ciTypeFlow.cpp
@@ -645,7 +645,9 @@
 void ciTypeFlow::StateVector::do_invoke(ciBytecodeStream* str,
                                         bool has_receiver) {
   bool will_link;
-  ciMethod* method = str->get_method(will_link);
+  ciSignature* declared_signature = NULL;
+  ciMethod* callee = str->get_method(will_link, &declared_signature);
+  assert(declared_signature != NULL, "cannot be null");
   if (!will_link) {
     // We weren't able to find the method.
     if (str->cur_bc() == Bytecodes::_invokedynamic) {
@@ -654,14 +656,16 @@
            (Deoptimization::Reason_uninitialized,
             Deoptimization::Action_reinterpret));
     } else {
-      ciKlass* unloaded_holder = method->holder();
+      ciKlass* unloaded_holder = callee->holder();
       trap(str, unloaded_holder, str->get_method_holder_index());
     }
   } else {
-    ciSignature* signature = method->signature();
-    ciSignatureStream sigstr(signature);
-    int arg_size = signature->size();
-    int stack_base = stack_size() - arg_size;
+    // We are using the declared signature here because it might be
+    // different from the callee signature (Cf. invokedynamic and
+    // invokehandle).
+    ciSignatureStream sigstr(declared_signature);
+    const int arg_size = declared_signature->size();
+    const int stack_base = stack_size() - arg_size;
     int i = 0;
     for( ; !sigstr.at_return_type(); sigstr.next()) {
       ciType* type = sigstr.type();
@@ -2190,6 +2194,10 @@
     if (head->backedge_copy_count() != 0)
       continue;
 
+    // Don't clone head of OSR loop to get correct types in start block.
+    if (is_osr_flow() && head->start() == start_bci())
+      continue;
+
     // check _no_ shared head below us
     Loop* ch;
     for (ch = lp->child(); ch != NULL && ch->head() != head; ch = ch->sibling());
diff --git a/hotspot/src/share/vm/classfile/classFileParser.cpp b/hotspot/src/share/vm/classfile/classFileParser.cpp
index 83bd038..6665ef0 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.cpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -81,7 +81,7 @@
 #define JAVA_7_VERSION                    51
 
 
-void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS) {
+void ClassFileParser::parse_constant_pool_entries(Handle class_loader, constantPoolHandle cp, int length, TRAPS) {
   // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize
   // this function (_current can be allocated in a register, with scalar
   // replacement of aggregates). The _current pointer is copied back to
@@ -272,7 +272,7 @@
             indices[names_count] = index;
             hashValues[names_count++] = hash;
             if (names_count == SymbolTable::symbol_alloc_batch_size) {
-              SymbolTable::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK);
+              SymbolTable::new_symbols(class_loader, cp, names_count, names, lengths, indices, hashValues, CHECK);
               names_count = 0;
             }
           } else {
@@ -289,7 +289,7 @@
 
   // Allocate the remaining symbols
   if (names_count > 0) {
-    SymbolTable::new_symbols(cp, names_count, names, lengths, indices, hashValues, CHECK);
+    SymbolTable::new_symbols(class_loader, cp, names_count, names, lengths, indices, hashValues, CHECK);
   }
 
   // Copy _current pointer of local copy back to stream().
@@ -318,7 +318,14 @@
 
 bool inline valid_cp_range(int index, int length) { return (index > 0 && index < length); }
 
-constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
+inline Symbol* check_symbol_at(constantPoolHandle cp, int index) {
+  if (valid_cp_range(index, cp->length()) && cp->tag_at(index).is_utf8())
+    return cp->symbol_at(index);
+  else
+    return NULL;
+}
+
+constantPoolHandle ClassFileParser::parse_constant_pool(Handle class_loader, TRAPS) {
   ClassFileStream* cfs = stream();
   constantPoolHandle nullHandle;
 
@@ -337,7 +344,7 @@
   ConstantPoolCleaner cp_in_error(cp); // set constant pool to be cleaned up.
 
   // parsing constant pool entries
-  parse_constant_pool_entries(cp, length, CHECK_(nullHandle));
+  parse_constant_pool_entries(class_loader, cp, length, CHECK_(nullHandle));
 
   int index = 1;  // declared outside of loops for portability
 
@@ -818,9 +825,6 @@
                     unresolved_klass, class_loader, protection_domain,
                     false, CHECK_(nullHandle));
       interf = KlassHandle(THREAD, k);
-
-      if (LinkWellKnownClasses)  // my super type is well known to me
-        cp->klass_at_put(interface_index, interf()); // eagerly resolve
     }
 
     if (!Klass::cast(interf())->is_interface()) {
@@ -902,6 +906,7 @@
                                              bool* is_synthetic_addr,
                                              u2* generic_signature_index_addr,
                                              typeArrayHandle* field_annotations,
+                                             ClassFileParser::FieldAnnotationCollector* parsed_annotations,
                                              TRAPS) {
   ClassFileStream* cfs = stream();
   assert(attributes_count > 0, "length should be greater than 0");
@@ -1082,12 +1087,36 @@
 
   int num_injected = 0;
   InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected);
+  int total_fields = length + num_injected;
 
-  // Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index]
-  typeArrayOop new_fields = oopFactory::new_permanent_shortArray((length + num_injected) * FieldInfo::field_slots, CHECK_(nullHandle));
-  typeArrayHandle fields(THREAD, new_fields);
+  // The field array starts with tuples of shorts
+  // [access, name index, sig index, initial value index, byte offset].
+  // A generic signature slot only exists for field with generic
+  // signature attribute. And the access flag is set with
+  // JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE for that field. The generic
+  // signature slots are at the end of the field array and after all
+  // other fields data.
+  //
+  //   f1: [access, name index, sig index, initial value index, low_offset, high_offset]
+  //   f2: [access, name index, sig index, initial value index, low_offset, high_offset]
+  //       ...
+  //   fn: [access, name index, sig index, initial value index, low_offset, high_offset]
+  //       [generic signature index]
+  //       [generic signature index]
+  //       ...
+  //
+  // Allocate a temporary resource array for field data. For each field,
+  // a slot is reserved in the temporary array for the generic signature
+  // index. After parsing all fields, the data are copied to a permanent
+  // array and any unused slots will be discarded.
+  ResourceMark rm(THREAD);
+  u2* fa = NEW_RESOURCE_ARRAY_IN_THREAD(
+             THREAD, u2, total_fields * (FieldInfo::field_slots + 1));
 
   typeArrayHandle field_annotations;
+  // The generic signature slots start after all other fields' data.
+  int generic_signature_slot = total_fields * FieldInfo::field_slots;
+  int num_generic_signature = 0;
   for (int n = 0; n < length; n++) {
     cfs->guarantee_more(8, CHECK_(nullHandle));  // access_flags, name_index, descriptor_index, attributes_count
 
@@ -1118,12 +1147,14 @@
     bool is_synthetic = false;
     u2 generic_signature_index = 0;
     bool is_static = access_flags.is_static();
+    FieldAnnotationCollector parsed_annotations;
 
     u2 attributes_count = cfs->get_u2_fast();
     if (attributes_count > 0) {
       parse_field_attributes(cp, attributes_count, is_static, signature_index,
                              &constantvalue_index, &is_synthetic,
                              &generic_signature_index, &field_annotations,
+                             &parsed_annotations,
                              CHECK_(nullHandle));
       if (field_annotations.not_null()) {
         if (fields_annotations->is_null()) {
@@ -1135,15 +1166,22 @@
       if (is_synthetic) {
         access_flags.set_is_synthetic();
       }
+      if (generic_signature_index != 0) {
+        access_flags.set_field_has_generic_signature();
+        fa[generic_signature_slot] = generic_signature_index;
+        generic_signature_slot ++;
+        num_generic_signature ++;
+      }
     }
 
-    FieldInfo* field = FieldInfo::from_field_array(fields(), n);
+    FieldInfo* field = FieldInfo::from_field_array(fa, n);
     field->initialize(access_flags.as_short(),
                       name_index,
                       signature_index,
                       constantvalue_index,
-                      generic_signature_index,
                       0);
+    if (parsed_annotations.has_any_annotations())
+      parsed_annotations.apply_to(field);
 
     BasicType type = cp->basic_type_for_signature_at(signature_index);
 
@@ -1155,8 +1193,8 @@
     field->set_offset(atype);
   }
 
+  int index = length;
   if (num_injected != 0) {
-    int index = length;
     for (int n = 0; n < num_injected; n++) {
       // Check for duplicates
       if (injected[n].may_be_java) {
@@ -1164,7 +1202,7 @@
         Symbol* signature = injected[n].signature();
         bool duplicate = false;
         for (int i = 0; i < length; i++) {
-          FieldInfo* f = FieldInfo::from_field_array(fields(), i);
+          FieldInfo* f = FieldInfo::from_field_array(fa, i);
           if (name      == cp->symbol_at(f->name_index()) &&
               signature == cp->symbol_at(f->signature_index())) {
             // Symbol is desclared in Java so skip this one
@@ -1179,12 +1217,11 @@
       }
 
       // Injected field
-      FieldInfo* field = FieldInfo::from_field_array(fields(), index);
+      FieldInfo* field = FieldInfo::from_field_array(fa, index);
       field->initialize(JVM_ACC_FIELD_INTERNAL,
                         injected[n].name_index,
                         injected[n].signature_index,
                         0,
-                        0,
                         0);
 
       BasicType type = FieldType::basic_type(injected[n].signature());
@@ -1197,17 +1234,27 @@
       field->set_offset(atype);
       index++;
     }
+  }
 
-    if (index < length + num_injected) {
-      // sometimes injected fields already exist in the Java source so
-      // the fields array could be too long.  In that case trim the
-      // fields array.
-      new_fields = oopFactory::new_permanent_shortArray(index * FieldInfo::field_slots, CHECK_(nullHandle));
-      for (int i = 0; i < index * FieldInfo::field_slots; i++) {
-        new_fields->short_at_put(i, fields->short_at(i));
-      }
-      fields = new_fields;
+  // Now copy the fields' data from the temporary resource array.
+  // Sometimes injected fields already exist in the Java source so
+  // the fields array could be too long.  In that case the
+  // fields array is trimed. Also unused slots that were reserved
+  // for generic signature indexes are discarded.
+  typeArrayOop new_fields = oopFactory::new_permanent_shortArray(
+    index * FieldInfo::field_slots + num_generic_signature,
+    CHECK_(nullHandle));
+  typeArrayHandle fields(THREAD, new_fields);
+  {
+    int i = 0;
+    for (; i < index * FieldInfo::field_slots; i++) {
+      new_fields->short_at_put(i, fa[i]);
     }
+    for (int j = total_fields * FieldInfo::field_slots;
+         j < generic_signature_slot; j++) {
+      new_fields->short_at_put(i++, fa[j]);
+    }
+    assert(i == new_fields->length(), "");
   }
 
   if (_need_verify && length > 1) {
@@ -1246,42 +1293,38 @@
 }
 
 
-typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length,
-                                                       u4 exception_table_length,
-                                                       constantPoolHandle cp,
-                                                       TRAPS) {
+u2* ClassFileParser::parse_exception_table(u4 code_length,
+                                           u4 exception_table_length,
+                                           constantPoolHandle cp,
+                                           TRAPS) {
   ClassFileStream* cfs = stream();
-  typeArrayHandle nullHandle;
 
-  // 4-tuples of ints [start_pc, end_pc, handler_pc, catch_type index]
-  typeArrayOop eh = oopFactory::new_permanent_intArray(exception_table_length*4, CHECK_(nullHandle));
-  typeArrayHandle exception_handlers = typeArrayHandle(THREAD, eh);
-
-  int index = 0;
-  cfs->guarantee_more(8 * exception_table_length, CHECK_(nullHandle)); // start_pc, end_pc, handler_pc, catch_type_index
-  for (unsigned int i = 0; i < exception_table_length; i++) {
-    u2 start_pc = cfs->get_u2_fast();
-    u2 end_pc = cfs->get_u2_fast();
-    u2 handler_pc = cfs->get_u2_fast();
-    u2 catch_type_index = cfs->get_u2_fast();
-    // Will check legal target after parsing code array in verifier.
-    if (_need_verify) {
+  u2* exception_table_start = cfs->get_u2_buffer();
+  assert(exception_table_start != NULL, "null exception table");
+  cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc, end_pc, handler_pc, catch_type_index
+  // Will check legal target after parsing code array in verifier.
+  if (_need_verify) {
+    for (unsigned int i = 0; i < exception_table_length; i++) {
+      u2 start_pc = cfs->get_u2_fast();
+      u2 end_pc = cfs->get_u2_fast();
+      u2 handler_pc = cfs->get_u2_fast();
+      u2 catch_type_index = cfs->get_u2_fast();
       guarantee_property((start_pc < end_pc) && (end_pc <= code_length),
-                         "Illegal exception table range in class file %s", CHECK_(nullHandle));
+                         "Illegal exception table range in class file %s",
+                         CHECK_NULL);
       guarantee_property(handler_pc < code_length,
-                         "Illegal exception table handler in class file %s", CHECK_(nullHandle));
+                         "Illegal exception table handler in class file %s",
+                         CHECK_NULL);
       if (catch_type_index != 0) {
         guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
                            is_klass_reference(cp, catch_type_index),
-                           "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
+                           "Catch type in exception table has bad constant type in class file %s", CHECK_NULL);
       }
     }
-    exception_handlers->int_at_put(index++, start_pc);
-    exception_handlers->int_at_put(index++, end_pc);
-    exception_handlers->int_at_put(index++, handler_pc);
-    exception_handlers->int_at_put(index++, catch_type_index);
+  } else {
+    cfs->skip_u2_fast(exception_table_length * 4);
   }
-  return exception_handlers;
+  return exception_table_start;
 }
 
 void ClassFileParser::parse_linenumber_table(
@@ -1330,7 +1373,7 @@
 };
 
 
-class LVT_Hash: public CHeapObj {
+class LVT_Hash: public CHeapObj<mtClass> {
  public:
   LocalVariableTableElement  *_elem;  // element
   LVT_Hash*                   _next;  // Next entry in hash table
@@ -1600,12 +1643,173 @@
       name->as_C_string(), _class_name->as_C_string(), sig->as_C_string());
 }
 
+// Skip an annotation.  Return >=limit if there is any problem.
+int ClassFileParser::skip_annotation(u1* buffer, int limit, int index) {
+  // annotation := atype:u2 do(nmem:u2) {member:u2 value}
+  // value := switch (tag:u1) { ... }
+  index += 2;  // skip atype
+  if ((index += 2) >= limit)  return limit;  // read nmem
+  int nmem = Bytes::get_Java_u2(buffer+index-2);
+  while (--nmem >= 0 && index < limit) {
+    index += 2; // skip member
+    index = skip_annotation_value(buffer, limit, index);
+  }
+  return index;
+}
+
+// Skip an annotation value.  Return >=limit if there is any problem.
+int ClassFileParser::skip_annotation_value(u1* buffer, int limit, int index) {
+  // value := switch (tag:u1) {
+  //   case B, C, I, S, Z, D, F, J, c: con:u2;
+  //   case e: e_class:u2 e_name:u2;
+  //   case s: s_con:u2;
+  //   case [: do(nval:u2) {value};
+  //   case @: annotation;
+  //   case s: s_con:u2;
+  // }
+  if ((index += 1) >= limit)  return limit;  // read tag
+  u1 tag = buffer[index-1];
+  switch (tag) {
+  case 'B': case 'C': case 'I': case 'S': case 'Z':
+  case 'D': case 'F': case 'J': case 'c': case 's':
+    index += 2;  // skip con or s_con
+    break;
+  case 'e':
+    index += 4;  // skip e_class, e_name
+    break;
+  case '[':
+    {
+      if ((index += 2) >= limit)  return limit;  // read nval
+      int nval = Bytes::get_Java_u2(buffer+index-2);
+      while (--nval >= 0 && index < limit) {
+        index = skip_annotation_value(buffer, limit, index);
+      }
+    }
+    break;
+  case '@':
+    index = skip_annotation(buffer, limit, index);
+    break;
+  default:
+    assert(false, "annotation tag");
+    return limit;  //  bad tag byte
+  }
+  return index;
+}
+
+// Sift through annotations, looking for those significant to the VM:
+void ClassFileParser::parse_annotations(u1* buffer, int limit,
+                                        constantPoolHandle cp,
+                                        ClassFileParser::AnnotationCollector* coll,
+                                        TRAPS) {
+  // annotations := do(nann:u2) {annotation}
+  int index = 0;
+  if ((index += 2) >= limit)  return;  // read nann
+  int nann = Bytes::get_Java_u2(buffer+index-2);
+  enum {  // initial annotation layout
+    atype_off = 0,      // utf8 such as 'Ljava/lang/annotation/Retention;'
+    count_off = 2,      // u2   such as 1 (one value)
+    member_off = 4,     // utf8 such as 'value'
+    tag_off = 6,        // u1   such as 'c' (type) or 'e' (enum)
+    e_tag_val = 'e',
+      e_type_off = 7,   // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
+      e_con_off = 9,    // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
+      e_size = 11,     // end of 'e' annotation
+    c_tag_val = 'c',
+      c_con_off = 7,    // utf8 payload, such as 'I' or 'Ljava/lang/String;'
+      c_size = 9,       // end of 'c' annotation
+    min_size = 6        // smallest possible size (zero members)
+  };
+  while ((--nann) >= 0 && (index-2 + min_size <= limit)) {
+    int index0 = index;
+    index = skip_annotation(buffer, limit, index);
+    u1* abase = buffer + index0;
+    int atype = Bytes::get_Java_u2(abase + atype_off);
+    int count = Bytes::get_Java_u2(abase + count_off);
+    Symbol* aname = check_symbol_at(cp, atype);
+    if (aname == NULL)  break;  // invalid annotation name
+    Symbol* member = NULL;
+    if (count >= 1) {
+      int member_index = Bytes::get_Java_u2(abase + member_off);
+      member = check_symbol_at(cp, member_index);
+      if (member == NULL)  break;  // invalid member name
+    }
+
+    // Here is where parsing particular annotations will take place.
+    AnnotationCollector::ID id = coll->annotation_index(aname);
+    if (id == AnnotationCollector::_unknown)  continue;
+    coll->set_annotation(id);
+    // If there are no values, just set the bit and move on:
+    if (count == 0)   continue;
+
+    // For the record, here is how annotation payloads can be collected.
+    // Suppose we want to capture @Retention.value.  Here is how:
+    //if (id == AnnotationCollector::_class_Retention) {
+    //  Symbol* payload = NULL;
+    //  if (count == 1
+    //      && e_size == (index0 - index)  // match size
+    //      && e_tag_val == *(abase + tag_off)
+    //      && (check_symbol_at(cp, Bytes::get_Java_u2(abase + e_type_off))
+    //          == vmSymbols::RetentionPolicy_signature())
+    //      && member == vmSymbols::value_name()) {
+    //    payload = check_symbol_at(cp, Bytes::get_Java_u2(abase + e_con_off));
+    //  }
+    //  check_property(payload != NULL,
+    //                 "Invalid @Retention annotation at offset %u in class file %s",
+    //                 index0, CHECK);
+    //  if (payload != NULL) {
+    //      payload->increment_refcount();
+    //      coll->_class_RetentionPolicy = payload;
+    //  }
+    //}
+  }
+}
+
+ClassFileParser::AnnotationCollector::ID ClassFileParser::AnnotationCollector::annotation_index(Symbol* name) {
+  vmSymbols::SID sid = vmSymbols::find_sid(name);
+  switch (sid) {
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_ForceInline_signature):
+    if (_location != _in_method)  break;  // only allow for methods
+    return _method_ForceInline;
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_DontInline_signature):
+    if (_location != _in_method)  break;  // only allow for methods
+    return _method_DontInline;
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature):
+    if (_location != _in_method)  break;  // only allow for methods
+    return _method_LambdaForm_Compiled;
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Hidden_signature):
+    if (_location != _in_method)  break;  // only allow for methods
+    return _method_LambdaForm_Hidden;
+  default: break;
+  }
+  return AnnotationCollector::_unknown;
+}
+
+void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
+  fatal("no field annotations yet");
+}
+
+void ClassFileParser::MethodAnnotationCollector::apply_to(methodHandle m) {
+  if (has_annotation(_method_ForceInline))
+    m->set_force_inline(true);
+  if (has_annotation(_method_DontInline))
+    m->set_dont_inline(true);
+  if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none)
+    m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm);
+  if (has_annotation(_method_LambdaForm_Hidden))
+    m->set_hidden(true);
+}
+
+void ClassFileParser::ClassAnnotationCollector::apply_to(instanceKlassHandle k) {
+  fatal("no class annotations yet");
+}
+
+
 #define MAX_ARGS_SIZE 255
 #define MAX_CODE_SIZE 65535
 #define INITIAL_MAX_LVT_NUMBER 256
 
 // Note: the parse_method below is big and clunky because all parsing of the code and exceptions
-// attribute is inlined. This is curbersome to avoid since we inline most of the parts in the
+// attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the
 // methodOop to save footprint, so we only know the size of the resulting methodOop when the
 // entire method attribute is parsed.
 //
@@ -1674,6 +1878,7 @@
   u4 code_length = 0;
   u1* code_start = 0;
   u2 exception_table_length = 0;
+  u2* exception_table_start = NULL;
   typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
   u2 checked_exceptions_length = 0;
   u2* checked_exceptions_start = NULL;
@@ -1695,6 +1900,7 @@
   // stackmap attribute - JDK1.5
   typeArrayHandle stackmap_data;
   u2 generic_signature_index = 0;
+  MethodAnnotationCollector parsed_annotations;
   u1* runtime_visible_annotations = NULL;
   int runtime_visible_annotations_length = 0;
   u1* runtime_invisible_annotations = NULL;
@@ -1760,7 +1966,7 @@
       cfs->guarantee_more(2, CHECK_(nullHandle));  // exception_table_length
       exception_table_length = cfs->get_u2_fast();
       if (exception_table_length > 0) {
-        exception_handlers =
+        exception_table_start =
               parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle));
       }
 
@@ -1921,6 +2127,7 @@
         runtime_visible_annotations_length = method_attribute_length;
         runtime_visible_annotations = cfs->get_u1_buffer();
         assert(runtime_visible_annotations != NULL, "null visible annotations");
+        parse_annotations(runtime_visible_annotations, runtime_visible_annotations_length, cp, &parsed_annotations, CHECK_(nullHandle));
         cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
       } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
         runtime_invisible_annotations_length = method_attribute_length;
@@ -1964,9 +2171,13 @@
   }
 
   // All sizing information for a methodOop is finally available, now create it
-  methodOop m_oop  = oopFactory::new_method(code_length, access_flags, linenumber_table_length,
-                                            total_lvt_length, checked_exceptions_length,
-                                            oopDesc::IsSafeConc, CHECK_(nullHandle));
+  methodOop m_oop  = oopFactory::new_method(code_length, access_flags,
+                                            linenumber_table_length,
+                                            total_lvt_length,
+                                            exception_table_length,
+                                            checked_exceptions_length,
+                                            oopDesc::IsSafeConc,
+                                            CHECK_(nullHandle));
   methodHandle m (THREAD, m_oop);
 
   ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);
@@ -1997,16 +2208,15 @@
   // Fill in code attribute information
   m->set_max_stack(max_stack);
   m->set_max_locals(max_locals);
-  m->constMethod()->set_stackmap_data(stackmap_data());
 
   /**
-   * The exception_table field is the flag used to indicate
+   * The stackmap_data field is the flag used to indicate
    * that the methodOop and it's associated constMethodOop are partially
    * initialized and thus are exempt from pre/post GC verification.  Once
    * the field is set, the oops are considered fully initialized so make
    * sure that the oops can pass verification when this field is set.
    */
-  m->set_exception_table(exception_handlers());
+  m->constMethod()->set_stackmap_data(stackmap_data());
 
   // Copy byte codes
   m->set_code(code_start);
@@ -2017,6 +2227,14 @@
            linenumber_table->buffer(), linenumber_table_length);
   }
 
+  // Copy exception table
+  if (exception_table_length > 0) {
+    int size =
+      exception_table_length * sizeof(ExceptionTableElement) / sizeof(u2);
+    copy_u2_with_conversion((u2*) m->exception_table_start(),
+                             exception_table_start, size);
+  }
+
   // Copy checked exceptions
   if (checked_exceptions_length > 0) {
     int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2);
@@ -2098,6 +2316,8 @@
     clear_hashtable(lvt_Hash);
   }
 
+  if (parsed_annotations.has_any_annotations())
+    parsed_annotations.apply_to(m);
   *method_annotations = assemble_annotations(runtime_visible_annotations,
                                              runtime_visible_annotations_length,
                                              runtime_invisible_annotations,
@@ -2128,12 +2348,6 @@
     _has_vanilla_constructor = true;
   }
 
-  if (EnableInvokeDynamic && (m->is_method_handle_invoke() ||
-                              m->is_method_handle_adapter())) {
-    THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
-               "Method handle invokers must be defined internally to the VM", nullHandle);
-  }
-
   return m;
 }
 
@@ -2276,7 +2490,7 @@
 }
 
 
-void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS) {
   ClassFileStream* cfs = stream();
   cfs->guarantee_more(2, CHECK);  // sourcefile_index
   u2 sourcefile_index = cfs->get_u2_fast();
@@ -2285,13 +2499,12 @@
       cp->tag_at(sourcefile_index).is_utf8(),
     "Invalid SourceFile attribute at constant pool index %u in class file %s",
     sourcefile_index, CHECK);
-  k->set_source_file_name(cp->symbol_at(sourcefile_index));
+  set_class_sourcefile(cp->symbol_at(sourcefile_index));
 }
 
 
 
 void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
-                                                                       instanceKlassHandle k,
                                                                        int length, TRAPS) {
   ClassFileStream* cfs = stream();
   u1* sde_buffer = cfs->get_u1_buffer();
@@ -2299,12 +2512,13 @@
 
   // Don't bother storing it if there is no way to retrieve it
   if (JvmtiExport::can_get_source_debug_extension()) {
-    // Optimistically assume that only 1 byte UTF format is used
-    // (common case)
-    TempNewSymbol sde_symbol = SymbolTable::new_symbol((const char*)sde_buffer, length, CHECK);
-    k->set_source_debug_extension(sde_symbol);
-    // Note that set_source_debug_extension() increments the reference count
-    // for its copy of the Symbol*, so use a TempNewSymbol here.
+    assert((length+1) > length, "Overflow checking");
+    u1* sde = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, u1, length+1);
+    for (int i = 0; i < length; i++) {
+      sde[i] = sde_buffer[i];
+    }
+    sde[length] = '\0';
+    set_class_sde_buffer((char*)sde, length);
   }
   // Got utf8 string, set stream position forward
   cfs->skip_u1(length, CHECK);
@@ -2315,13 +2529,32 @@
 #define RECOGNIZED_INNER_CLASS_MODIFIERS (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_PRIVATE | JVM_ACC_PROTECTED | JVM_ACC_STATIC)
 
 // Return number of classes in the inner classes attribute table
-u2 ClassFileParser::parse_classfile_inner_classes_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
+                                                            bool parsed_enclosingmethod_attribute,
+                                                            u2 enclosing_method_class_index,
+                                                            u2 enclosing_method_method_index,
+                                                            constantPoolHandle cp,
+                                                            TRAPS) {
   ClassFileStream* cfs = stream();
-  cfs->guarantee_more(2, CHECK_0);  // length
-  u2 length = cfs->get_u2_fast();
+  u1* current_mark = cfs->current();
+  u2 length = 0;
+  if (inner_classes_attribute_start != NULL) {
+    cfs->set_current(inner_classes_attribute_start);
+    cfs->guarantee_more(2, CHECK_0);  // length
+    length = cfs->get_u2_fast();
+  }
 
-  // 4-tuples of shorts [inner_class_info_index, outer_class_info_index, inner_name_index, inner_class_access_flags]
-  typeArrayOop ic = oopFactory::new_permanent_shortArray(length*4, CHECK_0);
+  // 4-tuples of shorts of inner classes data and 2 shorts of enclosing
+  // method data:
+  //   [inner_class_info_index,
+  //    outer_class_info_index,
+  //    inner_name_index,
+  //    inner_class_access_flags,
+  //    ...
+  //    enclosing_method_class_index,
+  //    enclosing_method_method_index]
+  int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
+  typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0);
   typeArrayHandle inner_classes(THREAD, ic);
   int index = 0;
   int cp_size = cp->length();
@@ -2372,8 +2605,8 @@
 
   // 4347400: make sure there's no duplicate entry in the classes array
   if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
-    for(int i = 0; i < inner_classes->length(); i += 4) {
-      for(int j = i + 4; j < inner_classes->length(); j += 4) {
+    for(int i = 0; i < length * 4; i += 4) {
+      for(int j = i + 4; j < length * 4; j += 4) {
         guarantee_property((inner_classes->ushort_at(i)   != inner_classes->ushort_at(j) ||
                             inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
                             inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
@@ -2384,16 +2617,27 @@
     }
   }
 
+  // Set EnclosingMethod class and method indexes.
+  if (parsed_enclosingmethod_attribute) {
+    inner_classes->short_at_put(index++, enclosing_method_class_index);
+    inner_classes->short_at_put(index++, enclosing_method_method_index);
+  }
+  assert(index == size, "wrong size");
+
   // Update instanceKlass with inner class info.
-  k->set_inner_classes(inner_classes());
+  set_class_inner_classes(inner_classes);
+
+  // Restore buffer's current position.
+  cfs->set_current(current_mark);
+
   return length;
 }
 
-void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
-  k->set_is_synthetic();
+void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS) {
+  set_class_synthetic_flag(true);
 }
 
-void ClassFileParser::parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS) {
   ClassFileStream* cfs = stream();
   u2 signature_index = cfs->get_u2(CHECK);
   check_property(
@@ -2401,10 +2645,10 @@
       cp->tag_at(signature_index).is_utf8(),
     "Invalid constant pool index %u in Signature attribute in class file %s",
     signature_index, CHECK);
-  k->set_generic_signature(cp->symbol_at(signature_index));
+  set_class_generic_signature(cp->symbol_at(signature_index));
 }
 
-void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k,
+void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp,
                                                                   u4 attribute_byte_length, TRAPS) {
   ClassFileStream* cfs = stream();
   u1* current_start = cfs->current();
@@ -2476,10 +2720,12 @@
 }
 
 
-void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
+void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp,
+                                                 ClassFileParser::ClassAnnotationCollector* parsed_annotations,
+                                                 TRAPS) {
   ClassFileStream* cfs = stream();
   // Set inner classes attribute to default sentinel
-  k->set_inner_classes(Universe::the_empty_short_array());
+  set_class_inner_classes(typeArrayHandle(THREAD, Universe::the_empty_short_array()));
   cfs->guarantee_more(2, CHECK);  // attributes_count
   u2 attributes_count = cfs->get_u2_fast();
   bool parsed_sourcefile_attribute = false;
@@ -2490,6 +2736,10 @@
   int runtime_visible_annotations_length = 0;
   u1* runtime_invisible_annotations = NULL;
   int runtime_invisible_annotations_length = 0;
+  u1* inner_classes_attribute_start = NULL;
+  u4  inner_classes_attribute_length = 0;
+  u2  enclosing_method_class_index = 0;
+  u2  enclosing_method_method_index = 0;
   // Iterate over attributes
   while (attributes_count--) {
     cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
@@ -2511,10 +2761,10 @@
       } else {
         parsed_sourcefile_attribute = true;
       }
-      parse_classfile_sourcefile_attribute(cp, k, CHECK);
+      parse_classfile_sourcefile_attribute(cp, CHECK);
     } else if (tag == vmSymbols::tag_source_debug_extension()) {
       // Check for SourceDebugExtension tag
-      parse_classfile_source_debug_extension_attribute(cp, k, (int)attribute_length, CHECK);
+      parse_classfile_source_debug_extension_attribute(cp, (int)attribute_length, CHECK);
     } else if (tag == vmSymbols::tag_inner_classes()) {
       // Check for InnerClasses tag
       if (parsed_innerclasses_attribute) {
@@ -2522,11 +2772,9 @@
       } else {
         parsed_innerclasses_attribute = true;
       }
-      u2 num_of_classes = parse_classfile_inner_classes_attribute(cp, k, CHECK);
-      if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
-        guarantee_property(attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
-                          "Wrong InnerClasses attribute length in class file %s", CHECK);
-      }
+      inner_classes_attribute_start = cfs->get_u1_buffer();
+      inner_classes_attribute_length = attribute_length;
+      cfs->skip_u1(inner_classes_attribute_length, CHECK);
     } else if (tag == vmSymbols::tag_synthetic()) {
       // Check for Synthetic tag
       // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
@@ -2535,7 +2783,7 @@
           "Invalid Synthetic classfile attribute length %u in class file %s",
           attribute_length, CHECK);
       }
-      parse_classfile_synthetic_attribute(cp, k, CHECK);
+      parse_classfile_synthetic_attribute(cp, CHECK);
     } else if (tag == vmSymbols::tag_deprecated()) {
       // Check for Deprecatd tag - 4276120
       if (attribute_length != 0) {
@@ -2550,11 +2798,16 @@
             "Wrong Signature attribute length %u in class file %s",
             attribute_length, CHECK);
         }
-        parse_classfile_signature_attribute(cp, k, CHECK);
+        parse_classfile_signature_attribute(cp, CHECK);
       } else if (tag == vmSymbols::tag_runtime_visible_annotations()) {
         runtime_visible_annotations_length = attribute_length;
         runtime_visible_annotations = cfs->get_u1_buffer();
         assert(runtime_visible_annotations != NULL, "null visible annotations");
+        parse_annotations(runtime_visible_annotations,
+                          runtime_visible_annotations_length,
+                          cp,
+                          parsed_annotations,
+                          CHECK);
         cfs->skip_u1(runtime_visible_annotations_length, CHECK);
       } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) {
         runtime_invisible_annotations_length = attribute_length;
@@ -2568,28 +2821,27 @@
           parsed_enclosingmethod_attribute = true;
         }
         cfs->guarantee_more(4, CHECK);  // class_index, method_index
-        u2 class_index  = cfs->get_u2_fast();
-        u2 method_index = cfs->get_u2_fast();
-        if (class_index == 0) {
+        enclosing_method_class_index  = cfs->get_u2_fast();
+        enclosing_method_method_index = cfs->get_u2_fast();
+        if (enclosing_method_class_index == 0) {
           classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", CHECK);
         }
         // Validate the constant pool indices and types
-        if (!cp->is_within_bounds(class_index) ||
-            !is_klass_reference(cp, class_index)) {
+        if (!cp->is_within_bounds(enclosing_method_class_index) ||
+            !is_klass_reference(cp, enclosing_method_class_index)) {
           classfile_parse_error("Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
         }
-        if (method_index != 0 &&
-            (!cp->is_within_bounds(method_index) ||
-             !cp->tag_at(method_index).is_name_and_type())) {
+        if (enclosing_method_method_index != 0 &&
+            (!cp->is_within_bounds(enclosing_method_method_index) ||
+             !cp->tag_at(enclosing_method_method_index).is_name_and_type())) {
           classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", CHECK);
         }
-        k->set_enclosing_method_indices(class_index, method_index);
       } else if (tag == vmSymbols::tag_bootstrap_methods() &&
                  _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
         if (parsed_bootstrap_methods_attribute)
           classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", CHECK);
         parsed_bootstrap_methods_attribute = true;
-        parse_classfile_bootstrap_methods_attribute(cp, k, attribute_length, CHECK);
+        parse_classfile_bootstrap_methods_attribute(cp, attribute_length, CHECK);
       } else {
         // Unknown attribute
         cfs->skip_u1(attribute_length, CHECK);
@@ -2604,7 +2856,21 @@
                                                      runtime_invisible_annotations,
                                                      runtime_invisible_annotations_length,
                                                      CHECK);
-  k->set_class_annotations(annotations());
+  set_class_annotations(annotations);
+
+  if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
+    u2 num_of_classes = parse_classfile_inner_classes_attribute(
+                            inner_classes_attribute_start,
+                            parsed_innerclasses_attribute,
+                            enclosing_method_class_index,
+                            enclosing_method_method_index,
+                            cp, CHECK);
+    if (parsed_innerclasses_attribute &&_need_verify && _major_version >= JAVA_1_5_VERSION) {
+      guarantee_property(
+        inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
+        "Wrong InnerClasses attribute length in class file %s", CHECK);
+    }
+  }
 
   if (_max_bootstrap_specifier_index >= 0) {
     guarantee_property(parsed_bootstrap_methods_attribute,
@@ -2612,6 +2878,23 @@
   }
 }
 
+void ClassFileParser::apply_parsed_class_attributes(instanceKlassHandle k) {
+  if (_synthetic_flag)
+    k->set_is_synthetic();
+  if (_sourcefile != NULL) {
+    _sourcefile->increment_refcount();
+    k->set_source_file_name(_sourcefile);
+  }
+  if (_generic_signature != NULL) {
+    _generic_signature->increment_refcount();
+    k->set_generic_signature(_generic_signature);
+  }
+  if (_sde_buffer != NULL) {
+    k->set_source_debug_extension(_sde_buffer, _sde_length);
+  }
+  k->set_inner_classes(_inner_classes());
+  k->set_class_annotations(_annotations());
+}
 
 typeArrayHandle ClassFileParser::assemble_annotations(u1* runtime_visible_annotations,
                                                       int runtime_visible_annotations_length,
@@ -2662,8 +2945,7 @@
                             jt->get_thread_stat()->perf_timers_addr(),
                             PerfClassTraceTime::PARSE_CLASS);
 
-  _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
-  _max_bootstrap_specifier_index = -1;
+  init_parsed_class_attributes();
 
   if (JvmtiExport::should_post_class_file_load_hook()) {
     // Get the cached class file bytes (if any) from the class that
@@ -2758,7 +3040,7 @@
   _relax_verify = Verifier::relax_verify_for(class_loader());
 
   // Constant pool
-  constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));
+  constantPoolHandle cp = parse_constant_pool(class_loader, CHECK_(nullHandle));
   ConstantPoolCleaner error_handler(cp); // set constant pool to be cleaned up.
 
   int cp_size = cp->length();
@@ -2896,6 +3178,13 @@
     objArrayHandle methods_parameter_annotations(THREAD, methods_parameter_annotations_oop);
     objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);
 
+    // Additional attributes
+    ClassAnnotationCollector parsed_annotations;
+    parse_classfile_attributes(cp, &parsed_annotations, CHECK_(nullHandle));
+
+    // Make sure this is the end of class file stream
+    guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
+
     // We check super class after class file is parsed and format is checked
     if (super_class_index > 0 && super_klass.is_null()) {
       Symbol*  sk  = cp->klass_name_at(super_class_index);
@@ -2915,8 +3204,6 @@
 
       KlassHandle kh (THREAD, k);
       super_klass = instanceKlassHandle(THREAD, kh());
-      if (LinkWellKnownClasses)  // my super class is well known to me
-        cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
     }
     if (super_klass.not_null()) {
       if (super_klass->is_interface()) {
@@ -3309,7 +3596,9 @@
     klassOop ik = oopFactory::new_instanceKlass(name, vtable_size, itable_size,
                                                 static_field_size,
                                                 total_oop_map_count,
-                                                rt, CHECK_(nullHandle));
+                                                access_flags,
+                                                rt, host_klass,
+                                                CHECK_(nullHandle));
     instanceKlassHandle this_klass (THREAD, ik);
 
     assert(this_klass->static_field_size() == static_field_size, "sanity");
@@ -3317,7 +3606,6 @@
            "sanity");
 
     // Fill in information already parsed
-    this_klass->set_access_flags(access_flags);
     this_klass->set_should_verify_class(verify);
     jint lh = Klass::instance_layout_helper(instance_size, false);
     this_klass->set_layout_helper(lh);
@@ -3347,7 +3635,7 @@
     // has to be changed accordingly.
     this_klass->set_initial_method_idnum(methods->length());
     this_klass->set_name(cp->klass_name_at(this_class_index));
-    if (LinkWellKnownClasses || is_anonymous())  // I am well known to myself
+    if (is_anonymous())  // I am well known to myself
       cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
     this_klass->set_protection_domain(protection_domain());
     this_klass->set_fields_annotations(fields_annotations());
@@ -3383,11 +3671,10 @@
       this_klass->set_has_miranda_methods(); // then set a flag
     }
 
-    // Additional attributes
-    parse_classfile_attributes(cp, this_klass, CHECK_(nullHandle));
-
-    // Make sure this is the end of class file stream
-    guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));
+    // Fill in field values obtained by parse_classfile_attributes
+    if (parsed_annotations.has_any_annotations())
+      parsed_annotations.apply_to(this_klass);
+    apply_parsed_class_attributes(this_klass);
 
     // VerifyOops believes that once this has been set, the object is completely loaded.
     // Compute transitive closure of interfaces this class implements
@@ -3402,6 +3689,7 @@
     // Do final class setup
     fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts);
 
+    // Fill in has_finalizer, has_vanilla_constructor, and layout_helper
     set_precomputed_flags(this_klass);
 
     // reinitialize modifiers, using the InnerClasses attribute
diff --git a/hotspot/src/share/vm/classfile/classFileParser.hpp b/hotspot/src/share/vm/classfile/classFileParser.hpp
index fef48eb..314ec5e 100644
--- a/hotspot/src/share/vm/classfile/classFileParser.hpp
+++ b/hotspot/src/share/vm/classfile/classFileParser.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,8 +31,8 @@
 #include "oops/typeArrayOop.hpp"
 #include "runtime/handles.inline.hpp"
 #include "utilities/accessFlags.hpp"
+#include "classfile/symbolTable.hpp"
 
-class TempNewSymbol;
 class FieldAllocationCount;
 
 
@@ -50,11 +50,83 @@
   KlassHandle _host_klass;
   GrowableArray<Handle>* _cp_patches; // overrides for CP entries
 
+  // precomputed flags
   bool _has_finalizer;
   bool _has_empty_finalizer;
   bool _has_vanilla_constructor;
+  int _max_bootstrap_specifier_index;  // detects BSS values
 
-  int _max_bootstrap_specifier_index;
+  // class attributes parsed before the instance klass is created:
+  bool       _synthetic_flag;
+  Symbol*    _sourcefile;
+  Symbol*    _generic_signature;
+  char*      _sde_buffer;
+  int        _sde_length;
+  typeArrayHandle _inner_classes;
+  typeArrayHandle _annotations;
+
+  void set_class_synthetic_flag(bool x)           { _synthetic_flag = x; }
+  void set_class_sourcefile(Symbol* x)            { _sourcefile = x; }
+  void set_class_generic_signature(Symbol* x)     { _generic_signature = x; }
+  void set_class_sde_buffer(char* x, int len)     { _sde_buffer = x; _sde_length = len; }
+  void set_class_inner_classes(typeArrayHandle x) { _inner_classes = x; }
+  void set_class_annotations(typeArrayHandle x)   { _annotations = x; }
+  void init_parsed_class_attributes() {
+    _synthetic_flag = false;
+    _sourcefile = NULL;
+    _generic_signature = NULL;
+    _sde_buffer = NULL;
+    _sde_length = 0;
+    // initialize the other flags too:
+    _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
+    _max_bootstrap_specifier_index = -1;
+  }
+  void apply_parsed_class_attributes(instanceKlassHandle k);  // update k
+
+  class AnnotationCollector {
+  public:
+    enum Location { _in_field, _in_method, _in_class };
+    enum ID {
+      _unknown = 0,
+      _method_ForceInline,
+      _method_DontInline,
+      _method_LambdaForm_Compiled,
+      _method_LambdaForm_Hidden,
+      _annotation_LIMIT
+    };
+    const Location _location;
+    int _annotations_present;
+    AnnotationCollector(Location location)
+    : _location(location), _annotations_present(0)
+    {
+      assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
+    }
+    // If this annotation name has an ID, report it (or _none).
+    ID annotation_index(Symbol* name);
+    // Set the annotation name:
+    void set_annotation(ID id) {
+      assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
+      _annotations_present |= nth_bit((int)id);
+    }
+    // Report if the annotation is present.
+    bool has_any_annotations() { return _annotations_present != 0; }
+    bool has_annotation(ID id) { return (nth_bit((int)id) & _annotations_present) != 0; }
+  };
+  class FieldAnnotationCollector: public AnnotationCollector {
+  public:
+    FieldAnnotationCollector() : AnnotationCollector(_in_field) { }
+    void apply_to(FieldInfo* f);
+  };
+  class MethodAnnotationCollector: public AnnotationCollector {
+  public:
+    MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
+    void apply_to(methodHandle m);
+  };
+  class ClassAnnotationCollector: public AnnotationCollector {
+  public:
+    ClassAnnotationCollector() : AnnotationCollector(_in_class) { }
+    void apply_to(instanceKlassHandle k);
+  };
 
   enum { fixed_buffer_size = 128 };
   u_char linenumbertable_buffer[fixed_buffer_size];
@@ -68,9 +140,10 @@
   void set_stream(ClassFileStream* st)             { _stream = st; }
 
   // Constant pool parsing
-  void parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS);
+  void parse_constant_pool_entries(Handle class_loader,
+                                   constantPoolHandle cp, int length, TRAPS);
 
-  constantPoolHandle parse_constant_pool(TRAPS);
+  constantPoolHandle parse_constant_pool(Handle class_loader, TRAPS);
 
   // Interface parsing
   objArrayHandle parse_interfaces(constantPoolHandle cp,
@@ -86,7 +159,9 @@
                               u2* constantvalue_index_addr,
                               bool* is_synthetic_addr,
                               u2* generic_signature_index_addr,
-                              typeArrayHandle* field_annotations, TRAPS);
+                              typeArrayHandle* field_annotations,
+                              FieldAnnotationCollector* parsed_annotations,
+                              TRAPS);
   typeArrayHandle parse_fields(Symbol* class_name,
                                constantPoolHandle cp, bool is_interface,
                                FieldAllocationCount *fac,
@@ -112,8 +187,8 @@
                                 objArrayHandle methods_parameter_annotations,
                                 objArrayHandle methods_default_annotations,
                                 TRAPS);
-  typeArrayHandle parse_exception_table(u4 code_length, u4 exception_table_length,
-                                        constantPoolHandle cp, TRAPS);
+  u2* parse_exception_table(u4 code_length, u4 exception_table_length,
+                            constantPoolHandle cp, TRAPS);
   void parse_linenumber_table(
       u4 code_attribute_length, u4 code_length,
       CompressedLineNumberWriteStream** write_stream, TRAPS);
@@ -127,21 +202,32 @@
   typeArrayOop parse_stackmap_table(u4 code_attribute_length, TRAPS);
 
   // Classfile attribute parsing
-  void parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
-  void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
-                                                instanceKlassHandle k, int length, TRAPS);
-  u2   parse_classfile_inner_classes_attribute(constantPoolHandle cp,
-                                               instanceKlassHandle k, TRAPS);
-  void parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
-  void parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
-  void parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS);
-  void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k, u4 attribute_length, TRAPS);
+  void parse_classfile_sourcefile_attribute(constantPoolHandle cp, TRAPS);
+  void parse_classfile_source_debug_extension_attribute(constantPoolHandle cp, int length, TRAPS);
+  u2   parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
+                                               bool parsed_enclosingmethod_attribute,
+                                               u2 enclosing_method_class_index,
+                                               u2 enclosing_method_method_index,
+                                               constantPoolHandle cp,
+                                               TRAPS);
+  void parse_classfile_attributes(constantPoolHandle cp,
+                                  ClassAnnotationCollector* parsed_annotations,
+                                  TRAPS);
+  void parse_classfile_synthetic_attribute(constantPoolHandle cp, TRAPS);
+  void parse_classfile_signature_attribute(constantPoolHandle cp, TRAPS);
+  void parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, u4 attribute_length, TRAPS);
 
   // Annotations handling
   typeArrayHandle assemble_annotations(u1* runtime_visible_annotations,
                                        int runtime_visible_annotations_length,
                                        u1* runtime_invisible_annotations,
                                        int runtime_invisible_annotations_length, TRAPS);
+  int skip_annotation(u1* buffer, int limit, int index);
+  int skip_annotation_value(u1* buffer, int limit, int index);
+  void parse_annotations(u1* buffer, int limit, constantPoolHandle cp,
+                         /* Results (currently, only one result is supported): */
+                         AnnotationCollector* result,
+                         TRAPS);
 
   // Final setup
   unsigned int compute_oop_map_count(instanceKlassHandle super,
@@ -244,7 +330,7 @@
   // constant pool construction, but in later versions they can.
   // %%% Let's phase out the old is_klass_reference.
   bool is_klass_reference(constantPoolHandle cp, int index) {
-    return ((LinkWellKnownClasses || EnableInvokeDynamic)
+    return (EnableInvokeDynamic
             ? cp->tag_at(index).is_klass_or_reference()
             : cp->tag_at(index).is_klass_reference());
   }
diff --git a/hotspot/src/share/vm/classfile/classLoader.cpp b/hotspot/src/share/vm/classfile/classLoader.cpp
index df42dc7..a2e61a4 100644
--- a/hotspot/src/share/vm/classfile/classLoader.cpp
+++ b/hotspot/src/share/vm/classfile/classLoader.cpp
@@ -153,7 +153,7 @@
     _meta_package_names = NULL;
     _num_meta_package_names = 0;
   } else {
-    _meta_package_names = NEW_C_HEAP_ARRAY(char*, num_meta_package_names);
+    _meta_package_names = NEW_C_HEAP_ARRAY(char*, num_meta_package_names, mtClass);
     _num_meta_package_names = num_meta_package_names;
     memcpy(_meta_package_names, meta_package_names, num_meta_package_names * sizeof(char*));
   }
@@ -161,7 +161,7 @@
 
 
 MetaIndex::~MetaIndex() {
-  FREE_C_HEAP_ARRAY(char*, _meta_package_names);
+  FREE_C_HEAP_ARRAY(char*, _meta_package_names, mtClass);
 }
 
 
@@ -192,7 +192,7 @@
 }
 
 ClassPathDirEntry::ClassPathDirEntry(char* dir) : ClassPathEntry() {
-  _dir = NEW_C_HEAP_ARRAY(char, strlen(dir)+1);
+  _dir = NEW_C_HEAP_ARRAY(char, strlen(dir)+1, mtClass);
   strcpy(_dir, dir);
 }
 
@@ -229,7 +229,7 @@
 
 ClassPathZipEntry::ClassPathZipEntry(jzfile* zip, const char* zip_name) : ClassPathEntry() {
   _zip = zip;
-  _zip_name = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1);
+  _zip_name = NEW_C_HEAP_ARRAY(char, strlen(zip_name)+1, mtClass);
   strcpy(_zip_name, zip_name);
 }
 
@@ -237,7 +237,7 @@
   if (ZipClose != NULL) {
     (*ZipClose)(_zip);
   }
-  FREE_C_HEAP_ARRAY(char, _zip_name);
+  FREE_C_HEAP_ARRAY(char, _zip_name, mtClass);
 }
 
 ClassFileStream* ClassPathZipEntry::open_stream(const char* name) {
@@ -454,11 +454,11 @@
     while (sys_class_path[end] && sys_class_path[end] != os::path_separator()[0]) {
       end++;
     }
-    char* path = NEW_C_HEAP_ARRAY(char, end-start+1);
+    char* path = NEW_C_HEAP_ARRAY(char, end-start+1, mtClass);
     strncpy(path, &sys_class_path[start], end-start);
     path[end-start] = '\0';
     update_class_path_entry_list(path, false);
-    FREE_C_HEAP_ARRAY(char, path);
+    FREE_C_HEAP_ARRAY(char, path, mtClass);
     while (sys_class_path[end] == os::path_separator()[0]) {
       end++;
     }
@@ -652,13 +652,13 @@
 // in the classpath must be the same files, in the same order, even
 // though the exact name is not the same.
 
-class PackageInfo: public BasicHashtableEntry {
+class PackageInfo: public BasicHashtableEntry<mtClass> {
 public:
   const char* _pkgname;       // Package name
   int _classpath_index;       // Index of directory or JAR file loaded from
 
   PackageInfo* next() {
-    return (PackageInfo*)BasicHashtableEntry::next();
+    return (PackageInfo*)BasicHashtableEntry<mtClass>::next();
   }
 
   const char* pkgname()           { return _pkgname; }
@@ -674,7 +674,7 @@
 };
 
 
-class PackageHashtable : public BasicHashtable {
+class PackageHashtable : public BasicHashtable<mtClass> {
 private:
   inline unsigned int compute_hash(const char *s, int n) {
     unsigned int val = 0;
@@ -685,7 +685,7 @@
   }
 
   PackageInfo* bucket(int index) {
-    return (PackageInfo*)BasicHashtable::bucket(index);
+    return (PackageInfo*)BasicHashtable<mtClass>::bucket(index);
   }
 
   PackageInfo* get_entry(int index, unsigned int hash,
@@ -702,10 +702,10 @@
 
 public:
   PackageHashtable(int table_size)
-    : BasicHashtable(table_size, sizeof(PackageInfo)) {}
+    : BasicHashtable<mtClass>(table_size, sizeof(PackageInfo)) {}
 
-  PackageHashtable(int table_size, HashtableBucket* t, int number_of_entries)
-    : BasicHashtable(table_size, sizeof(PackageInfo), t, number_of_entries) {}
+  PackageHashtable(int table_size, HashtableBucket<mtClass>* t, int number_of_entries)
+    : BasicHashtable<mtClass>(table_size, sizeof(PackageInfo), t, number_of_entries) {}
 
   PackageInfo* get_entry(const char* pkgname, int n) {
     unsigned int hash = compute_hash(pkgname, n);
@@ -715,14 +715,14 @@
   PackageInfo* new_entry(char* pkgname, int n) {
     unsigned int hash = compute_hash(pkgname, n);
     PackageInfo* pp;
-    pp = (PackageInfo*)BasicHashtable::new_entry(hash);
+    pp = (PackageInfo*)BasicHashtable<mtClass>::new_entry(hash);
     pp->set_pkgname(pkgname);
     return pp;
   }
 
   void add_entry(PackageInfo* pp) {
     int index = hash_to_index(pp->hash());
-    BasicHashtable::add_entry(index, pp);
+    BasicHashtable<mtClass>::add_entry(index, pp);
   }
 
   void copy_pkgnames(const char** packages) {
@@ -742,7 +742,7 @@
 void PackageHashtable::copy_table(char** top, char* end,
                                   PackageHashtable* table) {
   // Copy (relocate) the table to the shared space.
-  BasicHashtable::copy_table(top, end);
+  BasicHashtable<mtClass>::copy_table(top, end);
 
   // Calculate the space needed for the package name strings.
   int i;
@@ -815,7 +815,7 @@
       // Package prefix found
       int n = cp - pkgname + 1;
 
-      char* new_pkgname = NEW_C_HEAP_ARRAY(char, n + 1);
+      char* new_pkgname = NEW_C_HEAP_ARRAY(char, n + 1, mtClass);
       if (new_pkgname == NULL) {
         return false;
       }
@@ -929,10 +929,10 @@
 }
 
 
-void ClassLoader::create_package_info_table(HashtableBucket *t, int length,
+void ClassLoader::create_package_info_table(HashtableBucket<mtClass> *t, int length,
                                             int number_of_entries) {
   assert(_package_hash_table == NULL, "One package info table allowed.");
-  assert(length == package_hash_table_size * sizeof(HashtableBucket),
+  assert(length == package_hash_table_size * sizeof(HashtableBucket<mtClass>),
          "bad shared package info size.");
   _package_hash_table = new PackageHashtable(package_hash_table_size, t,
                                              number_of_entries);
diff --git a/hotspot/src/share/vm/classfile/classLoader.hpp b/hotspot/src/share/vm/classfile/classLoader.hpp
index 6f81683..ee58550 100644
--- a/hotspot/src/share/vm/classfile/classLoader.hpp
+++ b/hotspot/src/share/vm/classfile/classLoader.hpp
@@ -33,7 +33,7 @@
 
 
 // Meta-index (optional, to be able to skip opening boot classpath jar files)
-class MetaIndex: public CHeapObj {
+class MetaIndex: public CHeapObj<mtClass> {
  private:
   char** _meta_package_names;
   int    _num_meta_package_names;
@@ -46,7 +46,7 @@
 
 // Class path entry (directory or zip file)
 
-class ClassPathEntry: public CHeapObj {
+class ClassPathEntry: public CHeapObj<mtClass> {
  private:
   ClassPathEntry* _next;
  public:
@@ -141,7 +141,7 @@
 
 class PackageHashtable;
 class PackageInfo;
-class HashtableBucket;
+template <MEMFLAGS F> class HashtableBucket;
 
 class ClassLoader: AllStatic {
  public:
@@ -299,7 +299,7 @@
   // Initialization
   static void initialize();
   static void create_package_info_table();
-  static void create_package_info_table(HashtableBucket *t, int length,
+  static void create_package_info_table(HashtableBucket<mtClass> *t, int length,
                                         int number_of_entries);
   static int compute_Object_vtable();
 
diff --git a/hotspot/src/share/vm/classfile/dictionary.cpp b/hotspot/src/share/vm/classfile/dictionary.cpp
index 4458f46..78e76cc 100644
--- a/hotspot/src/share/vm/classfile/dictionary.cpp
+++ b/hotspot/src/share/vm/classfile/dictionary.cpp
@@ -36,16 +36,16 @@
 
 
 Dictionary::Dictionary(int table_size)
-  : TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry)) {
+  : TwoOopHashtable<klassOop, mtClass>(table_size, sizeof(DictionaryEntry)) {
   _current_class_index = 0;
   _current_class_entry = NULL;
 };
 
 
 
-Dictionary::Dictionary(int table_size, HashtableBucket* t,
+Dictionary::Dictionary(int table_size, HashtableBucket<mtClass>* t,
                        int number_of_entries)
-  : TwoOopHashtable<klassOop>(table_size, sizeof(DictionaryEntry), t, number_of_entries) {
+  : TwoOopHashtable<klassOop, mtClass>(table_size, sizeof(DictionaryEntry), t, number_of_entries) {
   _current_class_index = 0;
   _current_class_entry = NULL;
 };
@@ -54,7 +54,7 @@
 DictionaryEntry* Dictionary::new_entry(unsigned int hash, klassOop klass,
                                        oop loader) {
   DictionaryEntry* entry;
-  entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(hash, klass);
+  entry = (DictionaryEntry*)Hashtable<klassOop, mtClass>::new_entry(hash, klass);
   entry->set_loader(loader);
   entry->set_pd_set(NULL);
   return entry;
@@ -62,7 +62,7 @@
 
 
 DictionaryEntry* Dictionary::new_entry() {
-  DictionaryEntry* entry = (DictionaryEntry*)Hashtable<klassOop>::new_entry(0L, NULL);
+  DictionaryEntry* entry = (DictionaryEntry*)Hashtable<klassOop, mtClass>::new_entry(0L, NULL);
   entry->set_loader(NULL);
   entry->set_pd_set(NULL);
   return entry;
@@ -76,7 +76,7 @@
     entry->set_pd_set(to_delete->next());
     delete to_delete;
   }
-  Hashtable<klassOop>::free_entry(entry);
+  Hashtable<klassOop, mtClass>::free_entry(entry);
 }
 
 
@@ -554,12 +554,12 @@
 }
 
 SymbolPropertyTable::SymbolPropertyTable(int table_size)
-  : Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry))
+  : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry))
 {
 }
-SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket* t,
+SymbolPropertyTable::SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t,
                                          int number_of_entries)
-  : Hashtable<Symbol*>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
+  : Hashtable<Symbol*, mtSymbol>(table_size, sizeof(SymbolPropertyEntry), t, number_of_entries)
 {
 }
 
@@ -584,7 +584,7 @@
   assert(find_entry(index, hash, sym, sym_mode) == NULL, "no double entry");
 
   SymbolPropertyEntry* p = new_entry(hash, sym, sym_mode);
-  Hashtable<Symbol*>::add_entry(index, p);
+  Hashtable<Symbol*, mtSymbol>::add_entry(index, p);
   return p;
 }
 
diff --git a/hotspot/src/share/vm/classfile/dictionary.hpp b/hotspot/src/share/vm/classfile/dictionary.hpp
index 98e0169..bd33760 100644
--- a/hotspot/src/share/vm/classfile/dictionary.hpp
+++ b/hotspot/src/share/vm/classfile/dictionary.hpp
@@ -36,7 +36,7 @@
 // The data structure for the system dictionary (and the shared system
 // dictionary).
 
-class Dictionary : public TwoOopHashtable<klassOop> {
+class Dictionary : public TwoOopHashtable<klassOop, mtClass> {
   friend class VMStructs;
 private:
   // current iteration index.
@@ -48,22 +48,22 @@
                              Symbol* name, Handle loader);
 
   DictionaryEntry* bucket(int i) {
-    return (DictionaryEntry*)Hashtable<klassOop>::bucket(i);
+    return (DictionaryEntry*)Hashtable<klassOop, mtClass>::bucket(i);
   }
 
   // The following method is not MT-safe and must be done under lock.
   DictionaryEntry** bucket_addr(int i) {
-    return (DictionaryEntry**)Hashtable<klassOop>::bucket_addr(i);
+    return (DictionaryEntry**)Hashtable<klassOop, mtClass>::bucket_addr(i);
   }
 
   void add_entry(int index, DictionaryEntry* new_entry) {
-    Hashtable<klassOop>::add_entry(index, (HashtableEntry<oop>*)new_entry);
+    Hashtable<klassOop, mtClass>::add_entry(index, (HashtableEntry<oop, mtClass>*)new_entry);
   }
 
 
 public:
   Dictionary(int table_size);
-  Dictionary(int table_size, HashtableBucket* t, int number_of_entries);
+  Dictionary(int table_size, HashtableBucket<mtClass>* t, int number_of_entries);
 
   DictionaryEntry* new_entry(unsigned int hash, klassOop klass, oop loader);
 
@@ -129,7 +129,7 @@
 // The following classes can be in dictionary.cpp, but we need these
 // to be in header file so that SA's vmStructs can access.
 
-class ProtectionDomainEntry :public CHeapObj {
+class ProtectionDomainEntry :public CHeapObj<mtClass> {
   friend class VMStructs;
  public:
   ProtectionDomainEntry* _next;
@@ -147,7 +147,7 @@
 // An entry in the system dictionary, this describes a class as
 // { klassOop, loader, protection_domain }.
 
-class DictionaryEntry : public HashtableEntry<klassOop> {
+class DictionaryEntry : public HashtableEntry<klassOop, mtClass> {
   friend class VMStructs;
  private:
   // Contains the set of approved protection domains that can access
@@ -166,11 +166,11 @@
   klassOop* klass_addr() { return (klassOop*)literal_addr(); }
 
   DictionaryEntry* next() const {
-    return (DictionaryEntry*)HashtableEntry<klassOop>::next();
+    return (DictionaryEntry*)HashtableEntry<klassOop, mtClass>::next();
   }
 
   DictionaryEntry** next_addr() {
-    return (DictionaryEntry**)HashtableEntry<klassOop>::next_addr();
+    return (DictionaryEntry**)HashtableEntry<klassOop, mtClass>::next_addr();
   }
 
   oop loader() const { return _loader; }
@@ -228,7 +228,7 @@
 
 // Entry in a SymbolPropertyTable, mapping a single Symbol*
 // to a managed and an unmanaged pointer.
-class SymbolPropertyEntry : public HashtableEntry<Symbol*> {
+class SymbolPropertyEntry : public HashtableEntry<Symbol*, mtSymbol> {
   friend class VMStructs;
  private:
   intptr_t _symbol_mode;  // secondary key
@@ -248,11 +248,11 @@
   void set_property_data(address p) { _property_data = p; }
 
   SymbolPropertyEntry* next() const {
-    return (SymbolPropertyEntry*)HashtableEntry<Symbol*>::next();
+    return (SymbolPropertyEntry*)HashtableEntry<Symbol*, mtSymbol>::next();
   }
 
   SymbolPropertyEntry** next_addr() {
-    return (SymbolPropertyEntry**)HashtableEntry<Symbol*>::next_addr();
+    return (SymbolPropertyEntry**)HashtableEntry<Symbol*, mtSymbol>::next_addr();
   }
 
   oop* property_oop_addr()          { return &_property_oop; }
@@ -278,16 +278,16 @@
 // A system-internal mapping of symbols to pointers, both managed
 // and unmanaged.  Used to record the auto-generation of each method
 // MethodHandle.invoke(S)T, for all signatures (S)T.
-class SymbolPropertyTable : public Hashtable<Symbol*> {
+class SymbolPropertyTable : public Hashtable<Symbol*, mtSymbol> {
   friend class VMStructs;
 private:
   SymbolPropertyEntry* bucket(int i) {
-    return (SymbolPropertyEntry*) Hashtable<Symbol*>::bucket(i);
+    return (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::bucket(i);
   }
 
   // The following method is not MT-safe and must be done under lock.
   SymbolPropertyEntry** bucket_addr(int i) {
-    return (SymbolPropertyEntry**) Hashtable<Symbol*>::bucket_addr(i);
+    return (SymbolPropertyEntry**) Hashtable<Symbol*, mtSymbol>::bucket_addr(i);
   }
 
   void add_entry(int index, SymbolPropertyEntry* new_entry) {
@@ -298,7 +298,7 @@
   }
 
   SymbolPropertyEntry* new_entry(unsigned int hash, Symbol* symbol, intptr_t symbol_mode) {
-    SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*>::new_entry(hash, symbol);
+    SymbolPropertyEntry* entry = (SymbolPropertyEntry*) Hashtable<Symbol*, mtSymbol>::new_entry(hash, symbol);
     // Hashtable with Symbol* literal must increment and decrement refcount.
     symbol->increment_refcount();
     entry->set_symbol_mode(symbol_mode);
@@ -309,17 +309,17 @@
 
 public:
   SymbolPropertyTable(int table_size);
-  SymbolPropertyTable(int table_size, HashtableBucket* t, int number_of_entries);
+  SymbolPropertyTable(int table_size, HashtableBucket<mtSymbol>* t, int number_of_entries);
 
   void free_entry(SymbolPropertyEntry* entry) {
     // decrement Symbol refcount here because hashtable doesn't.
     entry->literal()->decrement_refcount();
-    Hashtable<Symbol*>::free_entry(entry);
+    Hashtable<Symbol*, mtSymbol>::free_entry(entry);
   }
 
   unsigned int compute_hash(Symbol* sym, intptr_t symbol_mode) {
     // Use the regular identity_hash.
-    return Hashtable<Symbol*>::compute_hash(sym) ^ symbol_mode;
+    return Hashtable<Symbol*, mtSymbol>::compute_hash(sym) ^ symbol_mode;
   }
 
   int index_for(Symbol* name, intptr_t symbol_mode) {
diff --git a/hotspot/src/share/vm/classfile/javaAssertions.cpp b/hotspot/src/share/vm/classfile/javaAssertions.cpp
index 7884881..3e6a8ce 100644
--- a/hotspot/src/share/vm/classfile/javaAssertions.cpp
+++ b/hotspot/src/share/vm/classfile/javaAssertions.cpp
@@ -58,7 +58,7 @@
   // it is never freed, so will be leaked (along with other option strings -
   // e.g., bootclasspath) if a process creates/destroys multiple VMs.
   int len = (int)strlen(name);
-  char *name_copy = NEW_C_HEAP_ARRAY(char, len + 1);
+  char *name_copy = NEW_C_HEAP_ARRAY(char, len + 1, mtClass);
   strcpy(name_copy, name);
 
   // Figure out which list the new item should go on.  Names that end in "..."
diff --git a/hotspot/src/share/vm/classfile/javaAssertions.hpp b/hotspot/src/share/vm/classfile/javaAssertions.hpp
index b0fb21a..d06d901 100644
--- a/hotspot/src/share/vm/classfile/javaAssertions.hpp
+++ b/hotspot/src/share/vm/classfile/javaAssertions.hpp
@@ -68,7 +68,7 @@
   static OptionList*    _packages;      // Options for package trees.
 };
 
-class JavaAssertions::OptionList: public CHeapObj {
+class JavaAssertions::OptionList: public CHeapObj<mtClass> {
 public:
   inline OptionList(const char* name, bool enable, OptionList* next);
 
diff --git a/hotspot/src/share/vm/classfile/javaClasses.cpp b/hotspot/src/share/vm/classfile/javaClasses.cpp
index 0c452cf..0958092 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.cpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.cpp
@@ -126,6 +126,13 @@
   if (!find_field(ik, name_symbol, signature_symbol, &fd, allow_super)) {
     ResourceMark rm;
     tty->print_cr("Invalid layout of %s at %s", ik->external_name(), name_symbol->as_C_string());
+#ifndef PRODUCT
+    klass_oop->print();
+    tty->print_cr("all fields:");
+    for (AllFieldStream fs(instanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
+      tty->print_cr("  name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
+    }
+#endif //PRODUCT
     fatal("Invalid layout of preloaded class");
   }
   dest_offset = fd.offset();
@@ -1455,6 +1462,7 @@
   nmethod* nm = NULL;
   bool skip_fillInStackTrace_check = false;
   bool skip_throwableInit_check = false;
+  bool skip_hidden = !ShowHiddenFrames;
 
   for (frame fr = thread->last_frame(); max_depth != total_count;) {
     methodOop method = NULL;
@@ -1534,6 +1542,9 @@
         skip_throwableInit_check = true;
       }
     }
+    if (method->is_hidden()) {
+      if (skip_hidden)  continue;
+    }
     bt.push(method, bci, CHECK);
     total_count++;
   }
@@ -1724,6 +1735,8 @@
   java_lang_StackTraceElement::set_methodName(element(), methodname);
   // Fill in source file name
   Symbol* source = instanceKlass::cast(method->method_holder())->source_file_name();
+  if (ShowHiddenFrames && source == NULL)
+    source = vmSymbols::unknown_class_name();
   oop filename = StringTable::intern(source, CHECK_0);
   java_lang_StackTraceElement::set_fileName(element(), filename);
   // File in source line number
@@ -1736,6 +1749,9 @@
   } else {
     // Returns -1 if no LineNumberTable, and otherwise actual line number
     line_number = method->line_number_from_bci(bci);
+    if (line_number == -1 && ShowHiddenFrames) {
+      line_number = bci + 1000000;
+    }
   }
   java_lang_StackTraceElement::set_lineNumber(element(), line_number);
 
@@ -2377,8 +2393,7 @@
 // Support for java_lang_invoke_MethodHandle
 
 int java_lang_invoke_MethodHandle::_type_offset;
-int java_lang_invoke_MethodHandle::_vmtarget_offset;
-int java_lang_invoke_MethodHandle::_vmentry_offset;
+int java_lang_invoke_MethodHandle::_form_offset;
 
 int java_lang_invoke_MemberName::_clazz_offset;
 int java_lang_invoke_MemberName::_name_offset;
@@ -2387,21 +2402,16 @@
 int java_lang_invoke_MemberName::_vmtarget_offset;
 int java_lang_invoke_MemberName::_vmindex_offset;
 
-int java_lang_invoke_DirectMethodHandle::_vmindex_offset;
-
-int java_lang_invoke_BoundMethodHandle::_argument_offset;
-int java_lang_invoke_BoundMethodHandle::_vmargslot_offset;
-
-int java_lang_invoke_AdapterMethodHandle::_conversion_offset;
-
-int java_lang_invoke_CountingMethodHandle::_vmcount_offset;
+int java_lang_invoke_LambdaForm::_vmentry_offset;
 
 void java_lang_invoke_MethodHandle::compute_offsets() {
   klassOop klass_oop = SystemDictionary::MethodHandle_klass();
   if (klass_oop != NULL && EnableInvokeDynamic) {
-    bool allow_super = false;
-    compute_offset(_type_offset,      klass_oop, vmSymbols::type_name(),      vmSymbols::java_lang_invoke_MethodType_signature(), allow_super);
-    METHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
+    compute_offset(_type_offset, klass_oop, vmSymbols::type_name(), vmSymbols::java_lang_invoke_MethodType_signature());
+    compute_optional_offset(_form_offset, klass_oop, vmSymbols::form_name(), vmSymbols::java_lang_invoke_LambdaForm_signature());
+    if (_form_offset == 0) {
+      EnableInvokeDynamic = false;
+    }
   }
 }
 
@@ -2412,50 +2422,17 @@
     compute_offset(_name_offset,      klass_oop, vmSymbols::name_name(),      vmSymbols::string_signature());
     compute_offset(_type_offset,      klass_oop, vmSymbols::type_name(),      vmSymbols::object_signature());
     compute_offset(_flags_offset,     klass_oop, vmSymbols::flags_name(),     vmSymbols::int_signature());
-    compute_offset(_vmindex_offset,   klass_oop, vmSymbols::vmindex_name(),   vmSymbols::int_signature());
     MEMBERNAME_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
   }
 }
 
-void java_lang_invoke_DirectMethodHandle::compute_offsets() {
-  klassOop k = SystemDictionary::DirectMethodHandle_klass();
-  if (k != NULL && EnableInvokeDynamic) {
-    DIRECTMETHODHANDLE_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
+void java_lang_invoke_LambdaForm::compute_offsets() {
+  klassOop klass_oop = SystemDictionary::LambdaForm_klass();
+  if (klass_oop != NULL && EnableInvokeDynamic) {
+    compute_offset(_vmentry_offset, klass_oop, vmSymbols::vmentry_name(), vmSymbols::java_lang_invoke_MemberName_signature());
   }
 }
 
-void java_lang_invoke_BoundMethodHandle::compute_offsets() {
-  klassOop k = SystemDictionary::BoundMethodHandle_klass();
-  if (k != NULL && EnableInvokeDynamic) {
-    compute_offset(_vmargslot_offset, k, vmSymbols::vmargslot_name(), vmSymbols::int_signature(),    true);
-    compute_offset(_argument_offset,  k, vmSymbols::argument_name(),  vmSymbols::object_signature(), true);
-  }
-}
-
-void java_lang_invoke_AdapterMethodHandle::compute_offsets() {
-  klassOop k = SystemDictionary::AdapterMethodHandle_klass();
-  if (k != NULL && EnableInvokeDynamic) {
-    compute_offset(_conversion_offset, k, vmSymbols::conversion_name(), vmSymbols::int_signature(), true);
-  }
-}
-
-void java_lang_invoke_CountingMethodHandle::compute_offsets() {
-  klassOop k = SystemDictionary::CountingMethodHandle_klass();
-  if (k != NULL && EnableInvokeDynamic) {
-    compute_offset(_vmcount_offset, k, vmSymbols::vmcount_name(), vmSymbols::int_signature(), true);
-  }
-}
-
-int java_lang_invoke_CountingMethodHandle::vmcount(oop mh) {
-  assert(is_instance(mh), "CMH only");
-  return mh->int_field(_vmcount_offset);
-}
-
-void java_lang_invoke_CountingMethodHandle::set_vmcount(oop mh, int count) {
-  assert(is_instance(mh), "CMH only");
-  mh->int_field_put(_vmcount_offset, count);
-}
-
 oop java_lang_invoke_MethodHandle::type(oop mh) {
   return mh->obj_field(_type_offset);
 }
@@ -2464,31 +2441,14 @@
   mh->obj_field_put(_type_offset, mtype);
 }
 
-// fetch type.form.vmslots, which is the number of JVM stack slots
-// required to carry the arguments of this MH
-int java_lang_invoke_MethodHandle::vmslots(oop mh) {
-  oop mtype = type(mh);
-  if (mtype == NULL)  return 0;  // Java code would get NPE
-  oop form = java_lang_invoke_MethodType::form(mtype);
-  if (form == NULL)   return 0;  // Java code would get NPE
-  return java_lang_invoke_MethodTypeForm::vmslots(form);
+oop java_lang_invoke_MethodHandle::form(oop mh) {
+  assert(_form_offset != 0, "");
+  return mh->obj_field(_form_offset);
 }
 
-// fetch the low-level entry point for this mh
-MethodHandleEntry* java_lang_invoke_MethodHandle::vmentry(oop mh) {
-  return (MethodHandleEntry*) mh->address_field(_vmentry_offset);
-}
-
-void java_lang_invoke_MethodHandle::set_vmentry(oop mh, MethodHandleEntry* me) {
-  assert(_vmentry_offset != 0, "must be present");
-
-  // This is always the final step that initializes a valid method handle:
-  mh->release_address_field_put(_vmentry_offset, (address) me);
-
-  // There should be enough memory barriers on exit from native methods
-  // to ensure that the MH is fully initialized to all threads before
-  // Java code can publish it in global data structures.
-  // But just in case, we use release_address_field_put.
+void java_lang_invoke_MethodHandle::set_form(oop mh, oop lform) {
+  assert(_form_offset != 0, "");
+  mh->obj_field_put(_form_offset, lform);
 }
 
 /// MemberName accessors
@@ -2540,57 +2500,40 @@
 
 void java_lang_invoke_MemberName::set_vmtarget(oop mname, oop ref) {
   assert(is_instance(mname), "wrong type");
+#ifdef ASSERT
+  // check the type of the vmtarget
+  if (ref != NULL) {
+    switch (flags(mname) & (MN_IS_METHOD |
+                            MN_IS_CONSTRUCTOR |
+                            MN_IS_FIELD)) {
+    case MN_IS_METHOD:
+    case MN_IS_CONSTRUCTOR:
+      assert(ref->is_method(), "should be a method");
+      break;
+    case MN_IS_FIELD:
+      assert(ref->is_klass(), "should be a class");
+      break;
+    default:
+      ShouldNotReachHere();
+    }
+  }
+#endif //ASSERT
   mname->obj_field_put(_vmtarget_offset, ref);
 }
 
-int java_lang_invoke_MemberName::vmindex(oop mname) {
+intptr_t java_lang_invoke_MemberName::vmindex(oop mname) {
   assert(is_instance(mname), "wrong type");
-  return mname->int_field(_vmindex_offset);
+  return (intptr_t) mname->address_field(_vmindex_offset);
 }
 
-void java_lang_invoke_MemberName::set_vmindex(oop mname, int index) {
+void java_lang_invoke_MemberName::set_vmindex(oop mname, intptr_t index) {
   assert(is_instance(mname), "wrong type");
-  mname->int_field_put(_vmindex_offset, index);
+  mname->address_field_put(_vmindex_offset, (address) index);
 }
 
-oop java_lang_invoke_MethodHandle::vmtarget(oop mh) {
-  assert(is_instance(mh), "MH only");
-  return mh->obj_field(_vmtarget_offset);
-}
-
-void java_lang_invoke_MethodHandle::set_vmtarget(oop mh, oop ref) {
-  assert(is_instance(mh), "MH only");
-  mh->obj_field_put(_vmtarget_offset, ref);
-}
-
-int java_lang_invoke_DirectMethodHandle::vmindex(oop mh) {
-  assert(is_instance(mh), "DMH only");
-  return mh->int_field(_vmindex_offset);
-}
-
-void java_lang_invoke_DirectMethodHandle::set_vmindex(oop mh, int index) {
-  assert(is_instance(mh), "DMH only");
-  mh->int_field_put(_vmindex_offset, index);
-}
-
-int java_lang_invoke_BoundMethodHandle::vmargslot(oop mh) {
-  assert(is_instance(mh), "BMH only");
-  return mh->int_field(_vmargslot_offset);
-}
-
-oop java_lang_invoke_BoundMethodHandle::argument(oop mh) {
-  assert(is_instance(mh), "BMH only");
-  return mh->obj_field(_argument_offset);
-}
-
-int java_lang_invoke_AdapterMethodHandle::conversion(oop mh) {
-  assert(is_instance(mh), "AMH only");
-  return mh->int_field(_conversion_offset);
-}
-
-void java_lang_invoke_AdapterMethodHandle::set_conversion(oop mh, int conv) {
-  assert(is_instance(mh), "AMH only");
-  mh->int_field_put(_conversion_offset, conv);
+oop java_lang_invoke_LambdaForm::vmentry(oop lform) {
+  assert(is_instance(lform), "wrong type");
+  return lform->obj_field(_vmentry_offset);
 }
 
 
@@ -2598,14 +2541,12 @@
 
 int java_lang_invoke_MethodType::_rtype_offset;
 int java_lang_invoke_MethodType::_ptypes_offset;
-int java_lang_invoke_MethodType::_form_offset;
 
 void java_lang_invoke_MethodType::compute_offsets() {
   klassOop k = SystemDictionary::MethodType_klass();
   if (k != NULL) {
     compute_offset(_rtype_offset,  k, vmSymbols::rtype_name(),  vmSymbols::class_signature());
     compute_offset(_ptypes_offset, k, vmSymbols::ptypes_name(), vmSymbols::class_array_signature());
-    compute_offset(_form_offset,   k, vmSymbols::form_name(),   vmSymbols::java_lang_invoke_MethodTypeForm_signature());
   }
 }
 
@@ -2635,6 +2576,8 @@
 }
 
 bool java_lang_invoke_MethodType::equals(oop mt1, oop mt2) {
+  if (mt1 == mt2)
+    return true;
   if (rtype(mt1) != rtype(mt2))
     return false;
   if (ptype_count(mt1) != ptype_count(mt2))
@@ -2656,11 +2599,6 @@
   return (objArrayOop) mt->obj_field(_ptypes_offset);
 }
 
-oop java_lang_invoke_MethodType::form(oop mt) {
-  assert(is_instance(mt), "must be a MethodType");
-  return mt->obj_field(_form_offset);
-}
-
 oop java_lang_invoke_MethodType::ptype(oop mt, int idx) {
   return ptypes(mt)->obj_at(idx);
 }
@@ -2669,62 +2607,20 @@
   return ptypes(mt)->length();
 }
 
-
-
-// Support for java_lang_invoke_MethodTypeForm
-
-int java_lang_invoke_MethodTypeForm::_vmslots_offset;
-int java_lang_invoke_MethodTypeForm::_vmlayout_offset;
-int java_lang_invoke_MethodTypeForm::_erasedType_offset;
-int java_lang_invoke_MethodTypeForm::_genericInvoker_offset;
-
-void java_lang_invoke_MethodTypeForm::compute_offsets() {
-  klassOop k = SystemDictionary::MethodTypeForm_klass();
-  if (k != NULL) {
-    compute_optional_offset(_vmslots_offset,    k, vmSymbols::vmslots_name(),    vmSymbols::int_signature(), true);
-    compute_optional_offset(_vmlayout_offset,   k, vmSymbols::vmlayout_name(),   vmSymbols::object_signature());
-    compute_optional_offset(_erasedType_offset, k, vmSymbols::erasedType_name(), vmSymbols::java_lang_invoke_MethodType_signature(), true);
-    compute_optional_offset(_genericInvoker_offset, k, vmSymbols::genericInvoker_name(), vmSymbols::java_lang_invoke_MethodHandle_signature(), true);
-    if (_genericInvoker_offset == 0)  _genericInvoker_offset = -1;  // set to explicit "empty" value
-    METHODTYPEFORM_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET);
+int java_lang_invoke_MethodType::ptype_slot_count(oop mt) {
+  objArrayOop pts = ptypes(mt);
+  int count = pts->length();
+  int slots = 0;
+  for (int i = 0; i < count; i++) {
+    BasicType bt = java_lang_Class::as_BasicType(pts->obj_at(i));
+    slots += type2size[bt];
   }
+  return slots;
 }
 
-int java_lang_invoke_MethodTypeForm::vmslots(oop mtform) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  assert(_vmslots_offset > 0, "");
-  return mtform->int_field(_vmslots_offset);
-}
-
-oop java_lang_invoke_MethodTypeForm::vmlayout(oop mtform) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  assert(_vmlayout_offset > 0, "");
-  return mtform->obj_field(_vmlayout_offset);
-}
-
-oop java_lang_invoke_MethodTypeForm::init_vmlayout(oop mtform, oop cookie) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  oop previous = vmlayout(mtform);
-  if (previous != NULL) {
-    return previous;  // someone else beat us to it
-  }
-  HeapWord* cookie_addr = (HeapWord*) mtform->obj_field_addr<oop>(_vmlayout_offset);
-  OrderAccess::storestore();  // make sure our copy is fully committed
-  previous = oopDesc::atomic_compare_exchange_oop(cookie, cookie_addr, previous);
-  if (previous != NULL) {
-    return previous;  // someone else beat us to it
-  }
-  return cookie;
-}
-
-oop java_lang_invoke_MethodTypeForm::erasedType(oop mtform) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  return mtform->obj_field(_erasedType_offset);
-}
-
-oop java_lang_invoke_MethodTypeForm::genericInvoker(oop mtform) {
-  assert(mtform->klass() == SystemDictionary::MethodTypeForm_klass(), "MTForm only");
-  return mtform->obj_field(_genericInvoker_offset);
+int java_lang_invoke_MethodType::rtype_slot_count(oop mt) {
+  BasicType bt = java_lang_Class::as_BasicType(rtype(mt));
+  return type2size[bt];
 }
 
 
@@ -2738,17 +2634,6 @@
   if (k != NULL) {
     compute_offset(_target_offset, k, vmSymbols::target_name(), vmSymbols::java_lang_invoke_MethodHandle_signature());
   }
-
-  // Disallow compilation of CallSite.setTargetNormal and CallSite.setTargetVolatile
-  // (For C2:  keep this until we have throttling logic for uncommon traps.)
-  if (k != NULL) {
-    instanceKlass* ik = instanceKlass::cast(k);
-    methodOop m_normal   = ik->lookup_method(vmSymbols::setTargetNormal_name(),   vmSymbols::setTarget_signature());
-    methodOop m_volatile = ik->lookup_method(vmSymbols::setTargetVolatile_name(), vmSymbols::setTarget_signature());
-    guarantee(m_normal != NULL && m_volatile != NULL, "must exist");
-    m_normal->set_not_compilable_quietly();
-    m_volatile->set_not_compilable_quietly();
-  }
 }
 
 
@@ -2809,10 +2694,26 @@
 }
 
 oop java_lang_ClassLoader::parent(oop loader) {
-  assert(loader->is_oop(), "loader must be oop");
+  assert(is_instance(loader), "loader must be oop");
   return loader->obj_field(parent_offset);
 }
 
+bool java_lang_ClassLoader::isAncestor(oop loader, oop cl) {
+  assert(is_instance(loader), "loader must be oop");
+  assert(cl == NULL || is_instance(cl), "cl argument must be oop");
+  oop acl = loader;
+  debug_only(jint loop_count = 0);
+  // This loop taken verbatim from ClassLoader.java:
+  do {
+    acl = parent(acl);
+    if (cl == acl) {
+      return true;
+    }
+    assert(++loop_count > 0, "loop_count overflow");
+  } while (acl != NULL);
+  return false;
+}
+
 
 // For class loader classes, parallelCapable defined
 // based on non-null field
@@ -2933,7 +2834,6 @@
 int java_lang_AssertionStatusDirectives::packageEnabled_offset;
 int java_lang_AssertionStatusDirectives::deflt_offset;
 int java_nio_Buffer::_limit_offset;
-int sun_misc_AtomicLongCSImpl::_value_offset;
 int java_util_concurrent_locks_AbstractOwnableSynchronizer::_owner_offset = 0;
 int sun_reflect_ConstantPool::_cp_oop_offset;
 int sun_reflect_UnsafeStaticFieldAccessorImpl::_base_offset;
@@ -2993,21 +2893,6 @@
   compute_offset(_limit_offset, k, vmSymbols::limit_name(), vmSymbols::int_signature());
 }
 
-// Support for intrinsification of sun.misc.AtomicLongCSImpl.attemptUpdate
-int sun_misc_AtomicLongCSImpl::value_offset() {
-  assert(SystemDictionary::AtomicLongCSImpl_klass() != NULL, "can't call this");
-  return _value_offset;
-}
-
-
-void sun_misc_AtomicLongCSImpl::compute_offsets() {
-  klassOop k = SystemDictionary::AtomicLongCSImpl_klass();
-  // If this class is not present, its value field offset won't be referenced.
-  if (k != NULL) {
-    compute_offset(_value_offset, k, vmSymbols::value_name(), vmSymbols::long_signature());
-  }
-}
-
 void java_util_concurrent_locks_AbstractOwnableSynchronizer::initialize(TRAPS) {
   if (_owner_offset != 0) return;
 
@@ -3088,13 +2973,9 @@
   if (EnableInvokeDynamic) {
     java_lang_invoke_MethodHandle::compute_offsets();
     java_lang_invoke_MemberName::compute_offsets();
-    java_lang_invoke_DirectMethodHandle::compute_offsets();
-    java_lang_invoke_BoundMethodHandle::compute_offsets();
-    java_lang_invoke_AdapterMethodHandle::compute_offsets();
+    java_lang_invoke_LambdaForm::compute_offsets();
     java_lang_invoke_MethodType::compute_offsets();
-    java_lang_invoke_MethodTypeForm::compute_offsets();
     java_lang_invoke_CallSite::compute_offsets();
-    java_lang_invoke_CountingMethodHandle::compute_offsets();
   }
   java_security_AccessControlContext::compute_offsets();
   // Initialize reflection classes. The layouts of these classes
@@ -3112,7 +2993,6 @@
     sun_reflect_ConstantPool::compute_offsets();
     sun_reflect_UnsafeStaticFieldAccessorImpl::compute_offsets();
   }
-  sun_misc_AtomicLongCSImpl::compute_offsets();
 
   // generated interpreter code wants to know about the offsets we just computed:
   AbstractAssembler::update_delayed_values();
@@ -3323,7 +3203,14 @@
     }
   }
   ResourceMark rm;
-  tty->print_cr("Invalid layout of %s at %s", instanceKlass::cast(klass_oop)->external_name(), name()->as_C_string());
+  tty->print_cr("Invalid layout of %s at %s/%s%s", instanceKlass::cast(klass_oop)->external_name(), name()->as_C_string(), signature()->as_C_string(), may_be_java ? " (may_be_java)" : "");
+#ifndef PRODUCT
+  klass_oop->print();
+  tty->print_cr("all fields:");
+  for (AllFieldStream fs(instanceKlass::cast(klass_oop)); !fs.done(); fs.next()) {
+    tty->print_cr("  name: %s, sig: %s, flags: %08x", fs.name()->as_C_string(), fs.signature()->as_C_string(), fs.access_flags().as_int());
+  }
+#endif //PRODUCT
   fatal("Invalid layout of preloaded class");
   return -1;
 }
diff --git a/hotspot/src/share/vm/classfile/javaClasses.hpp b/hotspot/src/share/vm/classfile/javaClasses.hpp
index 9ada298..22e877c 100644
--- a/hotspot/src/share/vm/classfile/javaClasses.hpp
+++ b/hotspot/src/share/vm/classfile/javaClasses.hpp
@@ -883,19 +883,14 @@
 
 // Interface to java.lang.invoke.MethodHandle objects
 
-#define METHODHANDLE_INJECTED_FIELDS(macro)                               \
-  macro(java_lang_invoke_MethodHandle, vmentry,  intptr_signature, false) \
-  macro(java_lang_invoke_MethodHandle, vmtarget, object_signature, true)
-
 class MethodHandleEntry;
 
 class java_lang_invoke_MethodHandle: AllStatic {
   friend class JavaClasses;
 
  private:
-  static int _vmentry_offset;            // assembly code trampoline for MH
-  static int _vmtarget_offset;           // class-specific target reference
-  static int _type_offset;              // the MethodType of this MH
+  static int _type_offset;               // the MethodType of this MH
+  static int _form_offset;               // the LambdaForm of this MH
 
   static void compute_offsets();
 
@@ -904,13 +899,8 @@
   static oop            type(oop mh);
   static void       set_type(oop mh, oop mtype);
 
-  static oop            vmtarget(oop mh);
-  static void       set_vmtarget(oop mh, oop target);
-
-  static MethodHandleEntry* vmentry(oop mh);
-  static void       set_vmentry(oop mh, MethodHandleEntry* data);
-
-  static int            vmslots(oop mh);
+  static oop            form(oop mh);
+  static void       set_form(oop mh, oop lform);
 
   // Testers
   static bool is_subclass(klassOop klass) {
@@ -922,149 +912,45 @@
 
   // Accessors for code generation:
   static int type_offset_in_bytes()             { return _type_offset; }
-  static int vmtarget_offset_in_bytes()         { return _vmtarget_offset; }
+  static int form_offset_in_bytes()             { return _form_offset; }
+};
+
+// Interface to java.lang.invoke.LambdaForm objects
+// (These are a private interface for managing adapter code generation.)
+
+class java_lang_invoke_LambdaForm: AllStatic {
+  friend class JavaClasses;
+
+ private:
+  static int _vmentry_offset;  // type is MemberName
+
+  static void compute_offsets();
+
+ public:
+  // Accessors
+  static oop            vmentry(oop lform);
+  static void       set_vmentry(oop lform, oop invoker);
+
+  // Testers
+  static bool is_subclass(klassOop klass) {
+    return SystemDictionary::LambdaForm_klass() != NULL &&
+      Klass::cast(klass)->is_subclass_of(SystemDictionary::LambdaForm_klass());
+  }
+  static bool is_instance(oop obj) {
+    return obj != NULL && is_subclass(obj->klass());
+  }
+
+  // Accessors for code generation:
   static int vmentry_offset_in_bytes()          { return _vmentry_offset; }
 };
 
-#define DIRECTMETHODHANDLE_INJECTED_FIELDS(macro)                          \
-  macro(java_lang_invoke_DirectMethodHandle, vmindex, int_signature, true)
-
-class java_lang_invoke_DirectMethodHandle: public java_lang_invoke_MethodHandle {
-  friend class JavaClasses;
-
- private:
-  static int _vmindex_offset;           // negative or vtable idx or itable idx
-  static void compute_offsets();
-
- public:
-  // Accessors
-  static int            vmindex(oop mh);
-  static void       set_vmindex(oop mh, int index);
-
-  // Testers
-  static bool is_subclass(klassOop klass) {
-    return Klass::cast(klass)->is_subclass_of(SystemDictionary::DirectMethodHandle_klass());
-  }
-  static bool is_instance(oop obj) {
-    return obj != NULL && is_subclass(obj->klass());
-  }
-
-  // Accessors for code generation:
-  static int vmindex_offset_in_bytes()          { return _vmindex_offset; }
-};
-
-class java_lang_invoke_BoundMethodHandle: public java_lang_invoke_MethodHandle {
-  friend class JavaClasses;
-
- private:
-  static int _argument_offset;          // argument value bound into this MH
-  static int _vmargslot_offset;         // relevant argument slot (<= vmslots)
-  static void compute_offsets();
-
-public:
-  static oop            argument(oop mh);
-  static void       set_argument(oop mh, oop ref);
-
-  static jint           vmargslot(oop mh);
-  static void       set_vmargslot(oop mh, jint slot);
-
-  // Testers
-  static bool is_subclass(klassOop klass) {
-    return Klass::cast(klass)->is_subclass_of(SystemDictionary::BoundMethodHandle_klass());
-  }
-  static bool is_instance(oop obj) {
-    return obj != NULL && is_subclass(obj->klass());
-  }
-
-  static int argument_offset_in_bytes()         { return _argument_offset; }
-  static int vmargslot_offset_in_bytes()        { return _vmargslot_offset; }
-};
-
-class java_lang_invoke_AdapterMethodHandle: public java_lang_invoke_BoundMethodHandle {
-  friend class JavaClasses;
-
- private:
-  static int _conversion_offset;        // type of conversion to apply
-  static void compute_offsets();
-
- public:
-  static int            conversion(oop mh);
-  static void       set_conversion(oop mh, int conv);
-
-  // Testers
-  static bool is_subclass(klassOop klass) {
-    return Klass::cast(klass)->is_subclass_of(SystemDictionary::AdapterMethodHandle_klass());
-  }
-  static bool is_instance(oop obj) {
-    return obj != NULL && is_subclass(obj->klass());
-  }
-
-  // Relevant integer codes (keep these in synch. with MethodHandleNatives.Constants):
-  enum {
-    OP_RETYPE_ONLY   = 0x0, // no argument changes; straight retype
-    OP_RETYPE_RAW    = 0x1, // straight retype, trusted (void->int, Object->T)
-    OP_CHECK_CAST    = 0x2, // ref-to-ref conversion; requires a Class argument
-    OP_PRIM_TO_PRIM  = 0x3, // converts from one primitive to another
-    OP_REF_TO_PRIM   = 0x4, // unboxes a wrapper to produce a primitive
-    OP_PRIM_TO_REF   = 0x5, // boxes a primitive into a wrapper
-    OP_SWAP_ARGS     = 0x6, // swap arguments (vminfo is 2nd arg)
-    OP_ROT_ARGS      = 0x7, // rotate arguments (vminfo is displaced arg)
-    OP_DUP_ARGS      = 0x8, // duplicates one or more arguments (at TOS)
-    OP_DROP_ARGS     = 0x9, // remove one or more argument slots
-    OP_COLLECT_ARGS  = 0xA, // combine arguments using an auxiliary function
-    OP_SPREAD_ARGS   = 0xB, // expand in place a varargs array (of known size)
-    OP_FOLD_ARGS     = 0xC, // combine but do not remove arguments; prepend result
-    //OP_UNUSED_13   = 0xD, // unused code, perhaps for reified argument lists
-    CONV_OP_LIMIT    = 0xE, // limit of CONV_OP enumeration
-
-    CONV_OP_MASK     = 0xF00, // this nybble contains the conversion op field
-    CONV_TYPE_MASK   = 0x0F,  // fits T_ADDRESS and below
-    CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
-    CONV_VMINFO_SHIFT     =  0, // position of bits in CONV_VMINFO_MASK
-    CONV_OP_SHIFT         =  8, // position of bits in CONV_OP_MASK
-    CONV_DEST_TYPE_SHIFT  = 12, // byte 2 has the adapter BasicType (if needed)
-    CONV_SRC_TYPE_SHIFT   = 16, // byte 2 has the source BasicType (if needed)
-    CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change
-    CONV_STACK_MOVE_MASK  = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1
-  };
-
-  static int conversion_offset_in_bytes()       { return _conversion_offset; }
-};
-
-
-// A simple class that maintains an invocation count
-class java_lang_invoke_CountingMethodHandle: public java_lang_invoke_MethodHandle {
-  friend class JavaClasses;
-
- private:
-  static int _vmcount_offset;
-  static void compute_offsets();
-
- public:
-  // Accessors
-  static int            vmcount(oop mh);
-  static void       set_vmcount(oop mh, int count);
-
-  // Testers
-  static bool is_subclass(klassOop klass) {
-    return SystemDictionary::CountingMethodHandle_klass() != NULL &&
-      Klass::cast(klass)->is_subclass_of(SystemDictionary::CountingMethodHandle_klass());
-  }
-  static bool is_instance(oop obj) {
-    return obj != NULL && is_subclass(obj->klass());
-  }
-
-  // Accessors for code generation:
-  static int vmcount_offset_in_bytes()          { return _vmcount_offset; }
-};
-
-
 
 // Interface to java.lang.invoke.MemberName objects
 // (These are a private interface for Java code to query the class hierarchy.)
 
-#define MEMBERNAME_INJECTED_FIELDS(macro)                              \
-  macro(java_lang_invoke_MemberName, vmtarget, object_signature, true)
+#define MEMBERNAME_INJECTED_FIELDS(macro)                               \
+  macro(java_lang_invoke_MemberName, vmindex,  intptr_signature, false) \
+  macro(java_lang_invoke_MemberName, vmtarget, object_signature, false)
 
 class java_lang_invoke_MemberName: AllStatic {
   friend class JavaClasses;
@@ -1076,7 +962,7 @@
   //    private Object     type;        // may be null if not yet materialized
   //    private int        flags;       // modifier bits; see reflect.Modifier
   //    private Object     vmtarget;    // VM-specific target value
-  //    private int        vmindex;     // method index within class or interface
+  //    private intptr_t   vmindex;     // member index within class or interface
   static int _clazz_offset;
   static int _name_offset;
   static int _type_offset;
@@ -1100,15 +986,11 @@
   static int            flags(oop mname);
   static void       set_flags(oop mname, int flags);
 
-  static int            modifiers(oop mname) { return (u2) flags(mname); }
-  static void       set_modifiers(oop mname, int mods)
-                                { set_flags(mname, (flags(mname) &~ (u2)-1) | (u2)mods); }
-
   static oop            vmtarget(oop mname);
   static void       set_vmtarget(oop mname, oop target);
 
-  static int            vmindex(oop mname);
-  static void       set_vmindex(oop mname, int index);
+  static intptr_t       vmindex(oop mname);
+  static void       set_vmindex(oop mname, intptr_t index);
 
   // Testers
   static bool is_subclass(klassOop klass) {
@@ -1124,9 +1006,11 @@
     MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
     MN_IS_FIELD            = 0x00040000, // field
     MN_IS_TYPE             = 0x00080000, // nested type
-    MN_SEARCH_SUPERCLASSES = 0x00100000, // for MHN.getMembers
-    MN_SEARCH_INTERFACES   = 0x00200000, // for MHN.getMembers
-    VM_INDEX_UNINITIALIZED = -99
+    MN_REFERENCE_KIND_SHIFT = 24, // refKind
+    MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+    // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
+    MN_SEARCH_SUPERCLASSES = 0x00100000, // walk super classes
+    MN_SEARCH_INTERFACES   = 0x00200000  // walk implemented interfaces
   };
 
   // Accessors for code generation:
@@ -1147,7 +1031,6 @@
  private:
   static int _rtype_offset;
   static int _ptypes_offset;
-  static int _form_offset;
 
   static void compute_offsets();
 
@@ -1155,11 +1038,13 @@
   // Accessors
   static oop            rtype(oop mt);
   static objArrayOop    ptypes(oop mt);
-  static oop            form(oop mt);
 
   static oop            ptype(oop mt, int index);
   static int            ptype_count(oop mt);
 
+  static int            ptype_slot_count(oop mt);  // extra counts for long/double
+  static int            rtype_slot_count(oop mt);  // extra counts for long/double
+
   static Symbol*        as_signature(oop mt, bool intern_if_not_found, TRAPS);
   static void           print_signature(oop mt, outputStream* st);
 
@@ -1172,40 +1057,6 @@
   // Accessors for code generation:
   static int rtype_offset_in_bytes()            { return _rtype_offset; }
   static int ptypes_offset_in_bytes()           { return _ptypes_offset; }
-  static int form_offset_in_bytes()             { return _form_offset; }
-};
-
-#define METHODTYPEFORM_INJECTED_FIELDS(macro)                              \
-  macro(java_lang_invoke_MethodTypeForm, vmslots,  int_signature,    true) \
-  macro(java_lang_invoke_MethodTypeForm, vmlayout, object_signature, true)
-
-class java_lang_invoke_MethodTypeForm: AllStatic {
-  friend class JavaClasses;
-
- private:
-  static int _vmslots_offset;           // number of argument slots needed
-  static int _vmlayout_offset;          // object describing internal calling sequence
-  static int _erasedType_offset;        // erasedType = canonical MethodType
-  static int _genericInvoker_offset;    // genericInvoker = adapter for invokeGeneric
-
-  static void compute_offsets();
-
- public:
-  // Accessors
-  static int            vmslots(oop mtform);
-  static void       set_vmslots(oop mtform, int vmslots);
-
-  static oop            erasedType(oop mtform);
-  static oop            genericInvoker(oop mtform);
-
-  static oop            vmlayout(oop mtform);
-  static oop       init_vmlayout(oop mtform, oop cookie);
-
-  // Accessors for code generation:
-  static int vmslots_offset_in_bytes()          { return _vmslots_offset; }
-  static int vmlayout_offset_in_bytes()         { return _vmlayout_offset; }
-  static int erasedType_offset_in_bytes()       { return _erasedType_offset; }
-  static int genericInvoker_offset_in_bytes()   { return _genericInvoker_offset; }
 };
 
 
@@ -1275,6 +1126,7 @@
 
  public:
   static oop parent(oop loader);
+  static bool isAncestor(oop loader, oop cl);
 
   // Support for parallelCapable field
   static bool parallelCapable(oop the_class_mirror);
@@ -1284,6 +1136,14 @@
   // Fix for 4474172
   static oop  non_reflection_class_loader(oop loader);
 
+  // Testers
+  static bool is_subclass(klassOop klass) {
+    return Klass::cast(klass)->is_subclass_of(SystemDictionary::ClassLoader_klass());
+  }
+  static bool is_instance(oop obj) {
+    return obj != NULL && is_subclass(obj->klass());
+  }
+
   // Debugging
   friend class JavaClasses;
 };
@@ -1383,15 +1243,6 @@
   static void compute_offsets();
 };
 
-class sun_misc_AtomicLongCSImpl: AllStatic {
- private:
-  static int _value_offset;
-
- public:
-  static int  value_offset();
-  static void compute_offsets();
-};
-
 class java_util_concurrent_locks_AbstractOwnableSynchronizer : AllStatic {
  private:
   static int  _owner_offset;
@@ -1434,10 +1285,7 @@
 
 #define ALL_INJECTED_FIELDS(macro)          \
   CLASS_INJECTED_FIELDS(macro)              \
-  METHODHANDLE_INJECTED_FIELDS(macro)       \
-  DIRECTMETHODHANDLE_INJECTED_FIELDS(macro) \
-  MEMBERNAME_INJECTED_FIELDS(macro)         \
-  METHODTYPEFORM_INJECTED_FIELDS(macro)
+  MEMBERNAME_INJECTED_FIELDS(macro)
 
 // Interface to hard-coded offset checking
 
diff --git a/hotspot/src/share/vm/classfile/loaderConstraints.cpp b/hotspot/src/share/vm/classfile/loaderConstraints.cpp
index 5e25e4c..8650cd9 100644
--- a/hotspot/src/share/vm/classfile/loaderConstraints.cpp
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.cpp
@@ -31,7 +31,7 @@
 #include "utilities/hashtable.inline.hpp"
 
 LoaderConstraintTable::LoaderConstraintTable(int nof_buckets)
-  : Hashtable<klassOop>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
+  : Hashtable<klassOop, mtClass>(nof_buckets, sizeof(LoaderConstraintEntry)) {};
 
 
 LoaderConstraintEntry* LoaderConstraintTable::new_entry(
@@ -39,7 +39,7 @@
                                  klassOop klass, int num_loaders,
                                  int max_loaders) {
   LoaderConstraintEntry* entry;
-  entry = (LoaderConstraintEntry*)Hashtable<klassOop>::new_entry(hash, klass);
+  entry = (LoaderConstraintEntry*)Hashtable<klassOop, mtClass>::new_entry(hash, klass);
   entry->set_name(name);
   entry->set_num_loaders(num_loaders);
   entry->set_max_loaders(max_loaders);
@@ -49,7 +49,7 @@
 void LoaderConstraintTable::free_entry(LoaderConstraintEntry *entry) {
   // decrement name refcount before freeing
   entry->name()->decrement_refcount();
-  Hashtable<klassOop>::free_entry(entry);
+  Hashtable<klassOop, mtClass>::free_entry(entry);
 }
 
 
@@ -164,7 +164,7 @@
 
         // Purge entry
         *p = probe->next();
-        FREE_C_HEAP_ARRAY(oop, probe->loaders());
+        FREE_C_HEAP_ARRAY(oop, probe->loaders(), mtClass);
         free_entry(probe);
       } else {
 #ifdef ASSERT
@@ -224,7 +224,7 @@
         int index = hash_to_index(hash);
         LoaderConstraintEntry* p;
         p = new_entry(hash, class_name, klass, 2, 2);
-        p->set_loaders(NEW_C_HEAP_ARRAY(oop, 2));
+        p->set_loaders(NEW_C_HEAP_ARRAY(oop, 2, mtClass));
         p->set_loader(0, class_loader1());
         p->set_loader(1, class_loader2());
         p->set_klass(klass);
@@ -340,10 +340,10 @@
                                                     int nfree) {
     if (p->max_loaders() - p->num_loaders() < nfree) {
         int n = nfree + p->num_loaders();
-        oop* new_loaders = NEW_C_HEAP_ARRAY(oop, n);
+        oop* new_loaders = NEW_C_HEAP_ARRAY(oop, n, mtClass);
         memcpy(new_loaders, p->loaders(), sizeof(oop) * p->num_loaders());
         p->set_max_loaders(n);
-        FREE_C_HEAP_ARRAY(oop, p->loaders());
+        FREE_C_HEAP_ARRAY(oop, p->loaders(), mtClass);
         p->set_loaders(new_loaders);
     }
 }
@@ -425,7 +425,7 @@
   }
 
   *pp2 = p2->next();
-  FREE_C_HEAP_ARRAY(oop, p2->loaders());
+  FREE_C_HEAP_ARRAY(oop, p2->loaders(), mtClass);
   free_entry(p2);
   return;
 }
diff --git a/hotspot/src/share/vm/classfile/loaderConstraints.hpp b/hotspot/src/share/vm/classfile/loaderConstraints.hpp
index 60612f5..d01b2c4 100644
--- a/hotspot/src/share/vm/classfile/loaderConstraints.hpp
+++ b/hotspot/src/share/vm/classfile/loaderConstraints.hpp
@@ -31,7 +31,7 @@
 
 class LoaderConstraintEntry;
 
-class LoaderConstraintTable : public Hashtable<klassOop> {
+class LoaderConstraintTable : public Hashtable<klassOop, mtClass> {
   friend class VMStructs;
 private:
 
@@ -53,11 +53,11 @@
   void free_entry(LoaderConstraintEntry *entry);
 
   LoaderConstraintEntry* bucket(int i) {
-    return (LoaderConstraintEntry*)Hashtable<klassOop>::bucket(i);
+    return (LoaderConstraintEntry*)Hashtable<klassOop, mtClass>::bucket(i);
   }
 
   LoaderConstraintEntry** bucket_addr(int i) {
-    return (LoaderConstraintEntry**)Hashtable<klassOop>::bucket_addr(i);
+    return (LoaderConstraintEntry**)Hashtable<klassOop, mtClass>::bucket_addr(i);
   }
 
   // GC support
@@ -94,7 +94,7 @@
 #endif
 };
 
-class LoaderConstraintEntry : public HashtableEntry<klassOop> {
+class LoaderConstraintEntry : public HashtableEntry<klassOop, mtClass> {
   friend class VMStructs;
 private:
   Symbol*                _name;                   // class name
@@ -109,14 +109,14 @@
   void set_klass(klassOop k) { set_literal(k); }
 
   LoaderConstraintEntry* next() {
-    return (LoaderConstraintEntry*)HashtableEntry<klassOop>::next();
+    return (LoaderConstraintEntry*)HashtableEntry<klassOop, mtClass>::next();
   }
 
   LoaderConstraintEntry** next_addr() {
-    return (LoaderConstraintEntry**)HashtableEntry<klassOop>::next_addr();
+    return (LoaderConstraintEntry**)HashtableEntry<klassOop, mtClass>::next_addr();
   }
   void set_next(LoaderConstraintEntry* next) {
-    HashtableEntry<klassOop>::set_next(next);
+    HashtableEntry<klassOop, mtClass>::set_next(next);
   }
 
   Symbol* name() { return _name; }
diff --git a/hotspot/src/share/vm/classfile/placeholders.cpp b/hotspot/src/share/vm/classfile/placeholders.cpp
index ef877b1..d3f425b 100644
--- a/hotspot/src/share/vm/classfile/placeholders.cpp
+++ b/hotspot/src/share/vm/classfile/placeholders.cpp
@@ -34,7 +34,7 @@
 PlaceholderEntry* PlaceholderTable::new_entry(int hash, Symbol* name,
                                               oop loader, bool havesupername,
                                               Symbol* supername) {
-  PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*>::new_entry(hash, name);
+  PlaceholderEntry* entry = (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::new_entry(hash, name);
   // Hashtable with Symbol* literal must increment and decrement refcount.
   name->increment_refcount();
   entry->set_loader(loader);
@@ -52,7 +52,7 @@
   // decrement Symbol refcount here because Hashtable doesn't.
   entry->literal()->decrement_refcount();
   if (entry->supername() != NULL) entry->supername()->decrement_refcount();
-  Hashtable<Symbol*>::free_entry(entry);
+  Hashtable<Symbol*, mtClass>::free_entry(entry);
 }
 
 
@@ -166,7 +166,7 @@
   }
 
 PlaceholderTable::PlaceholderTable(int table_size)
-    : TwoOopHashtable<Symbol*>(table_size, sizeof(PlaceholderEntry)) {
+    : TwoOopHashtable<Symbol*, mtClass>(table_size, sizeof(PlaceholderEntry)) {
 }
 
 
diff --git a/hotspot/src/share/vm/classfile/placeholders.hpp b/hotspot/src/share/vm/classfile/placeholders.hpp
index 667c59b..4dea3a6 100644
--- a/hotspot/src/share/vm/classfile/placeholders.hpp
+++ b/hotspot/src/share/vm/classfile/placeholders.hpp
@@ -34,7 +34,7 @@
 // being loaded, as well as arrays of primitives.
 //
 
-class PlaceholderTable : public TwoOopHashtable<Symbol*> {
+class PlaceholderTable : public TwoOopHashtable<Symbol*, mtClass> {
   friend class VMStructs;
 
 public:
@@ -44,15 +44,15 @@
   void free_entry(PlaceholderEntry* entry);
 
   PlaceholderEntry* bucket(int i) {
-    return (PlaceholderEntry*)Hashtable<Symbol*>::bucket(i);
+    return (PlaceholderEntry*)Hashtable<Symbol*, mtClass>::bucket(i);
   }
 
   PlaceholderEntry** bucket_addr(int i) {
-    return (PlaceholderEntry**)Hashtable<Symbol*>::bucket_addr(i);
+    return (PlaceholderEntry**)Hashtable<Symbol*, mtClass>::bucket_addr(i);
   }
 
   void add_entry(int index, PlaceholderEntry* new_entry) {
-    Hashtable<Symbol*>::add_entry(index, (HashtableEntry<Symbol*>*)new_entry);
+    Hashtable<Symbol*, mtClass>::add_entry(index, (HashtableEntry<Symbol*, mtClass>*)new_entry);
   }
 
   void add_entry(int index, unsigned int hash, Symbol* name,
@@ -116,7 +116,7 @@
 // For DEFINE_CLASS, the head of the queue owns the
 // define token and the rest of the threads wait to return the
 // result the first thread gets.
-class SeenThread: public CHeapObj {
+class SeenThread: public CHeapObj<mtInternal> {
 private:
    Thread *_thread;
    SeenThread* _stnext;
@@ -152,7 +152,7 @@
 // on store ordering here.
 // The system dictionary is the only user of this class.
 
-class PlaceholderEntry : public HashtableEntry<Symbol*> {
+class PlaceholderEntry : public HashtableEntry<Symbol*, mtClass> {
   friend class VMStructs;
 
 
@@ -206,11 +206,11 @@
   void               set_defineThreadQ(SeenThread* SeenThread) { _defineThreadQ = SeenThread; }
 
   PlaceholderEntry* next() const {
-    return (PlaceholderEntry*)HashtableEntry<Symbol*>::next();
+    return (PlaceholderEntry*)HashtableEntry<Symbol*, mtClass>::next();
   }
 
   PlaceholderEntry** next_addr() {
-    return (PlaceholderEntry**)HashtableEntry<Symbol*>::next_addr();
+    return (PlaceholderEntry**)HashtableEntry<Symbol*, mtClass>::next_addr();
   }
 
   // Test for equality
diff --git a/hotspot/src/share/vm/classfile/resolutionErrors.cpp b/hotspot/src/share/vm/classfile/resolutionErrors.cpp
index ed31224..e94ffa2 100644
--- a/hotspot/src/share/vm/classfile/resolutionErrors.cpp
+++ b/hotspot/src/share/vm/classfile/resolutionErrors.cpp
@@ -67,7 +67,7 @@
 ResolutionErrorEntry* ResolutionErrorTable::new_entry(int hash, constantPoolOop pool,
                                                       int cp_index, Symbol* error)
 {
-  ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<constantPoolOop>::new_entry(hash, pool);
+  ResolutionErrorEntry* entry = (ResolutionErrorEntry*)Hashtable<constantPoolOop, mtClass>::new_entry(hash, pool);
   entry->set_cp_index(cp_index);
   NOT_PRODUCT(entry->set_error(NULL);)
   entry->set_error(error);
@@ -79,13 +79,13 @@
   // decrement error refcount
   assert(entry->error() != NULL, "error should be set");
   entry->error()->decrement_refcount();
-  Hashtable<constantPoolOop>::free_entry(entry);
+  Hashtable<constantPoolOop, mtClass>::free_entry(entry);
 }
 
 
 // create resolution error table
 ResolutionErrorTable::ResolutionErrorTable(int table_size)
-    : Hashtable<constantPoolOop>(table_size, sizeof(ResolutionErrorEntry)) {
+    : Hashtable<constantPoolOop, mtClass>(table_size, sizeof(ResolutionErrorEntry)) {
 }
 
 // GC support
diff --git a/hotspot/src/share/vm/classfile/resolutionErrors.hpp b/hotspot/src/share/vm/classfile/resolutionErrors.hpp
index 03fcf49..a18a55a 100644
--- a/hotspot/src/share/vm/classfile/resolutionErrors.hpp
+++ b/hotspot/src/share/vm/classfile/resolutionErrors.hpp
@@ -33,7 +33,7 @@
 // ResolutionError objects are used to record errors encountered during
 // constant pool resolution (JVMS 5.4.3).
 
-class ResolutionErrorTable : public Hashtable<constantPoolOop> {
+class ResolutionErrorTable : public Hashtable<constantPoolOop, mtClass> {
 
 public:
   ResolutionErrorTable(int table_size);
@@ -42,15 +42,16 @@
   void free_entry(ResolutionErrorEntry *entry);
 
   ResolutionErrorEntry* bucket(int i) {
-    return (ResolutionErrorEntry*)Hashtable<constantPoolOop>::bucket(i);
+    return (ResolutionErrorEntry*)Hashtable<constantPoolOop, mtClass>::bucket(i);
   }
 
   ResolutionErrorEntry** bucket_addr(int i) {
-    return (ResolutionErrorEntry**)Hashtable<constantPoolOop>::bucket_addr(i);
+    return (ResolutionErrorEntry**)Hashtable<constantPoolOop, mtClass>::bucket_addr(i);
   }
 
   void add_entry(int index, ResolutionErrorEntry* new_entry) {
-    Hashtable<constantPoolOop>::add_entry(index, (HashtableEntry<constantPoolOop>*)new_entry);
+    Hashtable<constantPoolOop, mtClass>::add_entry(index,
+      (HashtableEntry<constantPoolOop, mtClass>*)new_entry);
   }
 
   void add_entry(int index, unsigned int hash,
@@ -74,7 +75,7 @@
 };
 
 
-class ResolutionErrorEntry : public HashtableEntry<constantPoolOop> {
+class ResolutionErrorEntry : public HashtableEntry<constantPoolOop, mtClass> {
  private:
   int               _cp_index;
   Symbol*           _error;
@@ -90,11 +91,11 @@
   void               set_error(Symbol* e);
 
   ResolutionErrorEntry* next() const {
-    return (ResolutionErrorEntry*)HashtableEntry<constantPoolOop>::next();
+    return (ResolutionErrorEntry*)HashtableEntry<constantPoolOop, mtClass>::next();
   }
 
   ResolutionErrorEntry** next_addr() {
-    return (ResolutionErrorEntry**)HashtableEntry<constantPoolOop>::next_addr();
+    return (ResolutionErrorEntry**)HashtableEntry<constantPoolOop, mtClass>::next_addr();
   }
 
   // GC support
diff --git a/hotspot/src/share/vm/classfile/stackMapFrame.cpp b/hotspot/src/share/vm/classfile/stackMapFrame.cpp
index 01620c7..c3f6946 100644
--- a/hotspot/src/share/vm/classfile/stackMapFrame.cpp
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -32,9 +32,9 @@
 #include "utilities/globalDefinitions.hpp"
 
 StackMapFrame::StackMapFrame(u2 max_locals, u2 max_stack, ClassVerifier* v) :
-                      _offset(0), _locals_size(0), _stack_size(0), _flags(0),
-                      _max_locals(max_locals), _max_stack(max_stack),
-                      _verifier(v) {
+                      _offset(0), _locals_size(0), _stack_size(0),
+                      _stack_mark(0), _flags(0), _max_locals(max_locals),
+                      _max_stack(max_stack), _verifier(v) {
   Thread* thr = v->thread();
   _locals = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_locals);
   _stack = NEW_RESOURCE_ARRAY_IN_THREAD(thr, VerificationType, max_stack);
@@ -157,17 +157,17 @@
   }
 }
 
-
-bool StackMapFrame::is_assignable_to(
+// Returns the location of the first mismatch, or 'len' if there are no
+// mismatches
+int StackMapFrame::is_assignable_to(
     VerificationType* from, VerificationType* to, int32_t len, TRAPS) const {
-  for (int32_t i = 0; i < len; i++) {
-    bool subtype = to[i].is_assignable_from(
-      from[i], verifier(), THREAD);
-    if (!subtype) {
-      return false;
+  int32_t i = 0;
+  for (i = 0; i < len; i++) {
+    if (!to[i].is_assignable_from(from[i], verifier(), THREAD)) {
+      break;
     }
   }
-  return true;
+  return i;
 }
 
 bool StackMapFrame::has_flag_match_exception(
@@ -209,50 +209,84 @@
 }
 
 bool StackMapFrame::is_assignable_to(
-    const StackMapFrame* target, bool is_exception_handler, TRAPS) const {
-  if (_max_locals != target->max_locals() ||
-      _stack_size != target->stack_size()) {
+    const StackMapFrame* target, bool is_exception_handler,
+    ErrorContext* ctx, TRAPS) const {
+  if (_max_locals != target->max_locals()) {
+    *ctx = ErrorContext::locals_size_mismatch(
+        _offset, (StackMapFrame*)this, (StackMapFrame*)target);
+    return false;
+  }
+  if (_stack_size != target->stack_size()) {
+    *ctx = ErrorContext::stack_size_mismatch(
+        _offset, (StackMapFrame*)this, (StackMapFrame*)target);
     return false;
   }
   // Only need to compare type elements up to target->locals() or target->stack().
   // The remaining type elements in this state can be ignored because they are
   // assignable to bogus type.
-  bool match_locals = is_assignable_to(
-    _locals, target->locals(), target->locals_size(), CHECK_false);
-  bool match_stack = is_assignable_to(
-    _stack, target->stack(), _stack_size, CHECK_false);
-  bool match_flags = (_flags | target->flags()) == target->flags();
+  int mismatch_loc;
+  mismatch_loc = is_assignable_to(
+    _locals, target->locals(), target->locals_size(), THREAD);
+  if (mismatch_loc != target->locals_size()) {
+    *ctx = ErrorContext::bad_type(target->offset(),
+        TypeOrigin::local(mismatch_loc, (StackMapFrame*)this),
+        TypeOrigin::sm_local(mismatch_loc, (StackMapFrame*)target));
+    return false;
+  }
+  mismatch_loc = is_assignable_to(_stack, target->stack(), _stack_size, THREAD);
+  if (mismatch_loc != _stack_size) {
+    *ctx = ErrorContext::bad_type(target->offset(),
+        TypeOrigin::stack(mismatch_loc, (StackMapFrame*)this),
+        TypeOrigin::sm_stack(mismatch_loc, (StackMapFrame*)target));
+    return false;
+  }
 
-  return match_locals && match_stack &&
-    (match_flags || (is_exception_handler && has_flag_match_exception(target)));
+  bool match_flags = (_flags | target->flags()) == target->flags();
+  if (match_flags || is_exception_handler && has_flag_match_exception(target)) {
+    return true;
+  } else {
+    *ctx = ErrorContext::bad_flags(target->offset(),
+        (StackMapFrame*)this, (StackMapFrame*)target);
+    return false;
+  }
 }
 
 VerificationType StackMapFrame::pop_stack_ex(VerificationType type, TRAPS) {
   if (_stack_size <= 0) {
-    verifier()->verify_error(_offset, "Operand stack underflow");
+    verifier()->verify_error(
+        ErrorContext::stack_underflow(_offset, this),
+        "Operand stack underflow");
     return VerificationType::bogus_type();
   }
   VerificationType top = _stack[--_stack_size];
   bool subtype = type.is_assignable_from(
     top, verifier(), CHECK_(VerificationType::bogus_type()));
   if (!subtype) {
-    verifier()->verify_error(_offset, "Bad type on operand stack");
+    verifier()->verify_error(
+        ErrorContext::bad_type(_offset, stack_top_ctx(),
+            TypeOrigin::implicit(type)),
+        "Bad type on operand stack");
     return VerificationType::bogus_type();
   }
-  NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
   return top;
 }
 
 VerificationType StackMapFrame::get_local(
     int32_t index, VerificationType type, TRAPS) {
   if (index >= _max_locals) {
-    verifier()->verify_error(_offset, "Local variable table overflow");
+    verifier()->verify_error(
+        ErrorContext::bad_local_index(_offset, index),
+        "Local variable table overflow");
     return VerificationType::bogus_type();
   }
   bool subtype = type.is_assignable_from(_locals[index],
     verifier(), CHECK_(VerificationType::bogus_type()));
   if (!subtype) {
-    verifier()->verify_error(_offset, "Bad local variable type");
+    verifier()->verify_error(
+        ErrorContext::bad_type(_offset,
+          TypeOrigin::local(index, this),
+          TypeOrigin::implicit(type)),
+        "Bad local variable type");
     return VerificationType::bogus_type();
   }
   if(index >= _locals_size) { _locals_size = index + 1; }
@@ -264,23 +298,37 @@
   assert(type1.is_long() || type1.is_double(), "must be long/double");
   assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
   if (index >= _locals_size - 1) {
-    verifier()->verify_error(_offset, "get long/double overflows locals");
+    verifier()->verify_error(
+        ErrorContext::bad_local_index(_offset, index),
+        "get long/double overflows locals");
     return;
   }
-  bool subtype1 = type1.is_assignable_from(
-    _locals[index], verifier(), CHECK);
-  bool subtype2 = type2.is_assignable_from(
-    _locals[index+1], verifier(), CHECK);
-  if (!subtype1 || !subtype2) {
-    verifier()->verify_error(_offset, "Bad local variable type");
-    return;
+  bool subtype = type1.is_assignable_from(_locals[index], verifier(), CHECK);
+  if (!subtype) {
+    verifier()->verify_error(
+        ErrorContext::bad_type(_offset,
+            TypeOrigin::local(index, this), TypeOrigin::implicit(type1)),
+        "Bad local variable type");
+  } else {
+    subtype = type2.is_assignable_from(_locals[index + 1], verifier(), CHECK);
+    if (!subtype) {
+      /* Unreachable? All local store routines convert a split long or double
+       * into a TOP during the store.  So we should never end up seeing an
+       * orphaned half.  */
+      verifier()->verify_error(
+          ErrorContext::bad_type(_offset,
+              TypeOrigin::local(index + 1, this), TypeOrigin::implicit(type2)),
+          "Bad local variable type");
+    }
   }
 }
 
 void StackMapFrame::set_local(int32_t index, VerificationType type, TRAPS) {
   assert(!type.is_check(), "Must be a real type");
   if (index >= _max_locals) {
-    verifier()->verify_error("Local variable table overflow", _offset);
+    verifier()->verify_error(
+        ErrorContext::bad_local_index(_offset, index),
+        "Local variable table overflow");
     return;
   }
   // If type at index is double or long, set the next location to be unusable
@@ -310,7 +358,9 @@
   assert(type1.is_long() || type1.is_double(), "must be long/double");
   assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
   if (index >= _max_locals - 1) {
-    verifier()->verify_error("Local variable table overflow", _offset);
+    verifier()->verify_error(
+        ErrorContext::bad_local_index(_offset, index),
+        "Local variable table overflow");
     return;
   }
   // If type at index+1 is double or long, set the next location to be unusable
@@ -336,21 +386,30 @@
   }
 }
 
-#ifndef PRODUCT
-
-void StackMapFrame::print() const {
-  tty->print_cr("stackmap_frame[%d]:", _offset);
-  tty->print_cr("flags = 0x%x", _flags);
-  tty->print("locals[%d] = { ", _locals_size);
-  for (int32_t i = 0; i < _locals_size; i++) {
-    _locals[i].print_on(tty);
-  }
-  tty->print_cr(" }");
-  tty->print("stack[%d] = { ", _stack_size);
-  for (int32_t j = 0; j < _stack_size; j++) {
-    _stack[j].print_on(tty);
-  }
-  tty->print_cr(" }");
+TypeOrigin StackMapFrame::stack_top_ctx() {
+  return TypeOrigin::stack(_stack_size, this);
 }
 
-#endif
+void StackMapFrame::print_on(outputStream* str) const {
+  str->indent().print_cr("bci: @%d", _offset);
+  str->indent().print_cr("flags: {%s }",
+      flag_this_uninit() ? " flagThisUninit" : "");
+  str->indent().print("locals: {");
+  for (int32_t i = 0; i < _locals_size; ++i) {
+    str->print(" ");
+    _locals[i].print_on(str);
+    if (i != _locals_size - 1) {
+      str->print(",");
+    }
+  }
+  str->print_cr(" }");
+  str->indent().print("stack: {");
+  for (int32_t j = 0; j < _stack_size; ++j) {
+    str->print(" ");
+    _stack[j].print_on(str);
+    if (j != _stack_size - 1) {
+      str->print(",");
+    }
+  }
+  str->print_cr(" }");
+}
diff --git a/hotspot/src/share/vm/classfile/stackMapFrame.hpp b/hotspot/src/share/vm/classfile/stackMapFrame.hpp
index 1e4c130..977223d 100644
--- a/hotspot/src/share/vm/classfile/stackMapFrame.hpp
+++ b/hotspot/src/share/vm/classfile/stackMapFrame.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -34,6 +34,8 @@
 
 // A StackMapFrame represents one frame in the stack map attribute.
 
+class TypeContext;
+
 enum {
   FLAG_THIS_UNINIT = 0x01
 };
@@ -47,6 +49,10 @@
   int32_t _locals_size;  // number of valid type elements in _locals
   int32_t _stack_size;   // number of valid type elements in _stack
 
+  int32_t _stack_mark;   // Records the size of the stack prior to an
+                         // instruction modification, to allow rewinding
+                         // when/if an error occurs.
+
   int32_t _max_locals;
   int32_t _max_stack;
 
@@ -56,6 +62,31 @@
 
   ClassVerifier* _verifier;  // the verifier verifying this method
 
+  StackMapFrame(const StackMapFrame& cp) :
+      _offset(cp._offset), _locals_size(cp._locals_size),
+      _stack_size(cp._stack_size), _stack_mark(cp._stack_mark),
+      _max_locals(cp._max_locals), _max_stack(cp._max_stack),
+      _flags(cp._flags) {
+    _locals = NEW_RESOURCE_ARRAY(VerificationType, _max_locals);
+    for (int i = 0; i < _max_locals; ++i) {
+      if (i < _locals_size) {
+        _locals[i] = cp._locals[i];
+      } else {
+        _locals[i] = VerificationType::bogus_type();
+      }
+    }
+    int ss = MAX2(_stack_size, _stack_mark);
+    _stack = NEW_RESOURCE_ARRAY(VerificationType, _max_stack);
+    for (int i = 0; i < _max_stack; ++i) {
+      if (i < ss) {
+        _stack[i] = cp._stack[i];
+      } else {
+        _stack[i] = VerificationType::bogus_type();
+      }
+    }
+    _verifier = NULL;
+  }
+
  public:
   // constructors
 
@@ -77,16 +108,21 @@
                 ClassVerifier* v) : _offset(offset), _flags(flags),
                                     _locals_size(locals_size),
                                     _stack_size(stack_size),
+                                    _stack_mark(-1),
                                     _max_locals(max_locals),
                                     _max_stack(max_stack),
                                     _locals(locals), _stack(stack),
                                     _verifier(v) { }
 
+  static StackMapFrame* copy(StackMapFrame* smf) {
+    return new StackMapFrame(*smf);
+  }
+
   inline void set_offset(int32_t offset)      { _offset = offset; }
   inline void set_verifier(ClassVerifier* v)  { _verifier = v; }
   inline void set_flags(u1 flags)             { _flags = flags; }
   inline void set_locals_size(u2 locals_size) { _locals_size = locals_size; }
-  inline void set_stack_size(u2 stack_size)   { _stack_size = stack_size; }
+  inline void set_stack_size(u2 stack_size)   { _stack_size = _stack_mark = stack_size; }
   inline void clear_stack()                   { _stack_size = 0; }
   inline int32_t offset()   const             { return _offset; }
   inline ClassVerifier* verifier() const      { return _verifier; }
@@ -134,14 +170,37 @@
   void copy_stack(const StackMapFrame* src);
 
   // Return true if this stack map frame is assignable to target.
-  bool is_assignable_to(const StackMapFrame* target,
-                        bool is_exception_handler, TRAPS) const;
+  bool is_assignable_to(
+      const StackMapFrame* target, bool is_exception_handler,
+      ErrorContext* ctx, TRAPS) const;
+
+  inline void set_mark() {
+#ifdef DEBUG
+    // Put bogus type to indicate it's no longer valid.
+    if (_stack_mark != -1) {
+      for (int i = _stack_mark; i >= _stack_size; --i) {
+        _stack[i] = VerificationType::bogus_type();
+      }
+    }
+#endif // def DEBUG
+    _stack_mark = _stack_size;
+  }
+
+  // Used when an error occurs and we want to reset the stack to the state
+  // it was before operands were popped off.
+  void restore() {
+    if (_stack_mark != -1) {
+      _stack_size = _stack_mark;
+    }
+  }
 
   // Push type into stack type array.
   inline void push_stack(VerificationType type, TRAPS) {
     assert(!type.is_check(), "Must be a real type");
     if (_stack_size >= _max_stack) {
-      verifier()->verify_error(_offset, "Operand stack overflow");
+      verifier()->verify_error(
+          ErrorContext::stack_overflow(_offset, this),
+          "Operand stack overflow");
       return;
     }
     _stack[_stack_size++] = type;
@@ -152,7 +211,9 @@
     assert(type1.is_long() || type1.is_double(), "must be long/double");
     assert(type2.is_long2() || type2.is_double2(), "must be long/double_2");
     if (_stack_size >= _max_stack - 1) {
-      verifier()->verify_error(_offset, "Operand stack overflow");
+      verifier()->verify_error(
+          ErrorContext::stack_overflow(_offset, this),
+          "Operand stack overflow");
       return;
     }
     _stack[_stack_size++] = type1;
@@ -162,13 +223,12 @@
   // Pop and return the top type on stack without verifying.
   inline VerificationType pop_stack(TRAPS) {
     if (_stack_size <= 0) {
-      verifier()->verify_error(_offset, "Operand stack underflow");
+      verifier()->verify_error(
+          ErrorContext::stack_underflow(_offset, this),
+          "Operand stack underflow");
       return VerificationType::bogus_type();
     }
-    // Put bogus type to indicate it's no longer valid.
-    // Added to make it consistent with the other pop_stack method.
     VerificationType top = _stack[--_stack_size];
-    NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
     return top;
   }
 
@@ -180,8 +240,7 @@
       bool subtype = type.is_assignable_from(
         top, verifier(), CHECK_(VerificationType::bogus_type()));
       if (subtype) {
-        _stack_size --;
-        NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
+        --_stack_size;
         return top;
       }
     }
@@ -199,8 +258,6 @@
       bool subtype2 = type2.is_assignable_from(top2, verifier(), CHECK);
       if (subtype1 && subtype2) {
         _stack_size -= 2;
-        NOT_PRODUCT( _stack[_stack_size] = VerificationType::bogus_type(); )
-        NOT_PRODUCT( _stack[_stack_size+1] = VerificationType::bogus_type(); )
         return;
       }
     }
@@ -208,6 +265,14 @@
     pop_stack_ex(type2, THREAD);
   }
 
+  VerificationType local_at(int index) {
+    return _locals[index];
+  }
+
+  VerificationType stack_at(int index) {
+    return _stack[index];
+  }
+
   // Uncommon case that throws exceptions.
   VerificationType pop_stack_ex(VerificationType type, TRAPS);
 
@@ -226,13 +291,14 @@
 
   // Private auxiliary method used only in is_assignable_to(StackMapFrame).
   // Returns true if src is assignable to target.
-  bool is_assignable_to(
+  int is_assignable_to(
     VerificationType* src, VerificationType* target, int32_t len, TRAPS) const;
 
   bool has_flag_match_exception(const StackMapFrame* target) const;
 
-  // Debugging
-  void print() const PRODUCT_RETURN;
+  TypeOrigin stack_top_ctx();
+
+  void print_on(outputStream* str) const;
 };
 
 #endif // SHARE_VM_CLASSFILE_STACKMAPFRAME_HPP
diff --git a/hotspot/src/share/vm/classfile/stackMapTable.cpp b/hotspot/src/share/vm/classfile/stackMapTable.cpp
index 4d1f599..3db348f 100644
--- a/hotspot/src/share/vm/classfile/stackMapTable.cpp
+++ b/hotspot/src/share/vm/classfile/stackMapTable.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +46,9 @@
       _frame_array[i] = frame;
       int offset = frame->offset();
       if (offset >= code_len || code_data[offset] == 0) {
-        frame->verifier()->verify_error("StackMapTable error: bad offset");
+        frame->verifier()->verify_error(
+            ErrorContext::bad_stackmap(i, frame),
+            "StackMapTable error: bad offset");
         return;
       }
       pre_frame = frame;
@@ -68,12 +70,9 @@
 
 bool StackMapTable::match_stackmap(
     StackMapFrame* frame, int32_t target,
-    bool match, bool update, TRAPS) const {
+    bool match, bool update, ErrorContext* ctx, TRAPS) const {
   int index = get_index_from_offset(target);
-
-  return match_stackmap(
-    frame, target, index, match,
-    update, CHECK_VERIFY_(frame->verifier(), false));
+  return match_stackmap(frame, target, index, match, update, ctx, THREAD);
 }
 
 // Match and/or update current_frame to the frame in stackmap table with
@@ -88,23 +87,23 @@
 // unconditional branch:                                 true   true
 bool StackMapTable::match_stackmap(
     StackMapFrame* frame, int32_t target, int32_t frame_index,
-    bool match, bool update, TRAPS) const {
+    bool match, bool update, ErrorContext* ctx, TRAPS) const {
   if (frame_index < 0 || frame_index >= _frame_count) {
-    frame->verifier()->verify_error(frame->offset(),
-      "Expecting a stackmap frame at branch target %d", target);
+    *ctx = ErrorContext::missing_stackmap(frame->offset());
+    frame->verifier()->verify_error(
+        *ctx, "Expecting a stackmap frame at branch target %d", target);
     return false;
   }
 
-  bool result = true;
   StackMapFrame *stackmap_frame = _frame_array[frame_index];
+  bool result = true;
   if (match) {
     // when checking handler target, match == true && update == false
     bool is_exception_handler = !update;
     // Has direct control flow from last instruction, need to match the two
     // frames.
-    result = frame->is_assignable_to(
-      stackmap_frame, is_exception_handler,
-      CHECK_VERIFY_(frame->verifier(), false));
+    result = frame->is_assignable_to(stackmap_frame, is_exception_handler,
+        ctx, CHECK_VERIFY_(frame->verifier(), result));
   }
   if (update) {
     // Use the frame in stackmap table as current frame
@@ -125,11 +124,12 @@
 
 void StackMapTable::check_jump_target(
     StackMapFrame* frame, int32_t target, TRAPS) const {
+  ErrorContext ctx;
   bool match = match_stackmap(
-    frame, target, true, false, CHECK_VERIFY(frame->verifier()));
+    frame, target, true, false, &ctx, CHECK_VERIFY(frame->verifier()));
   if (!match || (target < 0 || target >= _code_length)) {
-    frame->verifier()->verify_error(frame->offset(),
-      "Inconsistent stackmap frames at branch target %d", target);
+    frame->verifier()->verify_error(ctx,
+        "Inconsistent stackmap frames at branch target %d", target);
     return;
   }
   // check if uninitialized objects exist on backward branches
@@ -139,25 +139,25 @@
 void StackMapTable::check_new_object(
     const StackMapFrame* frame, int32_t target, TRAPS) const {
   if (frame->offset() > target && frame->has_new_object()) {
-    frame->verifier()->verify_error(frame->offset(),
-      "Uninitialized object exists on backward branch %d", target);
+    frame->verifier()->verify_error(
+        ErrorContext::bad_code(frame->offset()),
+        "Uninitialized object exists on backward branch %d", target);
     return;
   }
 }
 
-#ifndef PRODUCT
-
-void StackMapTable::print() const {
-  tty->print_cr("StackMapTable: frame_count = %d", _frame_count);
-  tty->print_cr("table = { ");
-  for (int32_t i = 0; i < _frame_count; i++) {
-    _frame_array[i]->print();
+void StackMapTable::print_on(outputStream* str) const {
+  str->indent().print_cr("StackMapTable: frame_count = %d", _frame_count);
+  str->indent().print_cr("table = { ");
+  {
+    streamIndentor si(str);
+    for (int32_t i = 0; i < _frame_count; ++i) {
+      _frame_array[i]->print_on(str);
+    }
   }
-  tty->print_cr(" }");
+  str->print_cr(" }");
 }
 
-#endif
-
 int32_t StackMapReader::chop(
     VerificationType* locals, int32_t length, int32_t chops) {
   if (locals == NULL) return -1;
diff --git a/hotspot/src/share/vm/classfile/stackMapTable.hpp b/hotspot/src/share/vm/classfile/stackMapTable.hpp
index 08e9bd2..90ec8eb 100644
--- a/hotspot/src/share/vm/classfile/stackMapTable.hpp
+++ b/hotspot/src/share/vm/classfile/stackMapTable.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 #define SHARE_VM_CLASSFILE_STACKMAPTABLE_HPP
 
 #include "classfile/stackMapFrame.hpp"
+#include "classfile/verifier.hpp"
 #include "memory/allocation.hpp"
 #include "oops/constantPoolOop.hpp"
 #include "oops/methodOop.hpp"
@@ -73,12 +74,12 @@
   // specified offset. Return true if the two frames match.
   bool match_stackmap(
     StackMapFrame* current_frame, int32_t offset,
-    bool match, bool update, TRAPS) const;
+    bool match, bool update, ErrorContext* ctx, TRAPS) const;
   // Match and/or update current_frame to the frame in stackmap table with
   // specified offset and frame index. Return true if the two frames match.
   bool match_stackmap(
     StackMapFrame* current_frame, int32_t offset, int32_t frame_index,
-    bool match, bool update, TRAPS) const;
+    bool match, bool update, ErrorContext* ctx, TRAPS) const;
 
   // Check jump instructions. Make sure there are no uninitialized
   // instances on backward branch.
@@ -93,8 +94,7 @@
   void check_new_object(
     const StackMapFrame* frame, int32_t target, TRAPS) const;
 
-  // Debugging
-  void print() const PRODUCT_RETURN;
+  void print_on(outputStream* str) const;
 };
 
 class StackMapStream : StackObj {
diff --git a/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp b/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp
index b8a4b42..8bfa625 100644
--- a/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp
+++ b/hotspot/src/share/vm/classfile/stackMapTableFormat.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -135,7 +135,6 @@
                 !is_object() && !is_uninitialized()));
   }
 
-#ifdef ASSERT
   void print_on(outputStream* st) {
     switch (tag()) {
       case ITEM_Top: st->print("Top"); break;
@@ -154,14 +153,13 @@
         assert(false, "Bad verification_type_info");
     }
   }
-#endif
 };
 
 #define FOR_EACH_STACKMAP_FRAME_TYPE(macro, arg1, arg2) \
   macro(same_frame, arg1, arg2) \
   macro(same_frame_extended, arg1, arg2) \
-  macro(same_frame_1_stack_item_frame, arg1, arg2) \
-  macro(same_frame_1_stack_item_extended, arg1, arg2) \
+  macro(same_locals_1_stack_item_frame, arg1, arg2) \
+  macro(same_locals_1_stack_item_extended, arg1, arg2) \
   macro(chop_frame, arg1, arg2) \
   macro(append_frame, arg1, arg2) \
   macro(full_frame, arg1, arg2)
@@ -203,9 +201,8 @@
   // that we don't read past a particular memory limit.  It returns false
   // if any part of the data structure is outside the specified memory bounds.
   inline bool verify(address start, address end) const;
-#ifdef ASSERT
-  inline void print_on(outputStream* st) const;
-#endif
+
+  inline void print_on(outputStream* st, int current_offset) const;
 
   // Create as_xxx and is_xxx methods for the subtypes
 #define FRAME_TYPE_DECL(stackmap_frame_type, arg1, arg2) \
@@ -263,11 +260,9 @@
     return true;
   }
 
-#ifdef ASSERT
-  void print_on(outputStream* st) const {
-    st->print("same_frame(%d)", offset_delta());
+  void print_on(outputStream* st, int current_offset = -1) const {
+    st->print("same_frame(@%d)", offset_delta() + current_offset);
   }
-#endif
 };
 
 class same_frame_extended : public stack_map_frame {
@@ -311,14 +306,12 @@
     return frame_type_addr() + size() <= end;
   }
 
-#ifdef ASSERT
-  void print_on(outputStream* st) const {
-    st->print("same_frame_extended(%d)", offset_delta());
+  void print_on(outputStream* st, int current_offset = -1) const {
+    st->print("same_frame_extended(@%d)", offset_delta() + current_offset);
   }
-#endif
 };
 
-class same_frame_1_stack_item_frame : public stack_map_frame {
+class same_locals_1_stack_item_frame : public stack_map_frame {
  private:
   address type_addr() const { return frame_type_addr() + sizeof(u1); }
 
@@ -332,14 +325,14 @@
     return tag >= 64 && tag < 128;
   }
 
-  static same_frame_1_stack_item_frame* at(address addr) {
+  static same_locals_1_stack_item_frame* at(address addr) {
     assert(is_frame_type(*addr), "Wrong frame id");
-    return (same_frame_1_stack_item_frame*)addr;
+    return (same_locals_1_stack_item_frame*)addr;
   }
 
-  static same_frame_1_stack_item_frame* create_at(
+  static same_locals_1_stack_item_frame* create_at(
       address addr, int offset_delta, verification_type_info* vti) {
-    same_frame_1_stack_item_frame* sm = (same_frame_1_stack_item_frame*)addr;
+    same_locals_1_stack_item_frame* sm = (same_locals_1_stack_item_frame*)addr;
     sm->set_offset_delta(offset_delta);
     if (vti != NULL) {
       sm->set_type(vti);
@@ -382,16 +375,15 @@
     return types()->verify(start, end);
   }
 
-#ifdef ASSERT
-  void print_on(outputStream* st) const {
-    st->print("same_frame_1_stack_item_frame(%d,", offset_delta());
+  void print_on(outputStream* st, int current_offset = -1) const {
+    st->print("same_locals_1_stack_item_frame(@%d,",
+        offset_delta() + current_offset);
     types()->print_on(st);
     st->print(")");
   }
-#endif
 };
 
-class same_frame_1_stack_item_extended : public stack_map_frame {
+class same_locals_1_stack_item_extended : public stack_map_frame {
  private:
   address offset_delta_addr() const { return frame_type_addr() + sizeof(u1); }
   address type_addr() const { return offset_delta_addr() + sizeof(u2); }
@@ -403,15 +395,15 @@
     return tag == _frame_id;
   }
 
-  static same_frame_1_stack_item_extended* at(address addr) {
+  static same_locals_1_stack_item_extended* at(address addr) {
     assert(is_frame_type(*addr), "Wrong frame id");
-    return (same_frame_1_stack_item_extended*)addr;
+    return (same_locals_1_stack_item_extended*)addr;
   }
 
-  static same_frame_1_stack_item_extended* create_at(
+  static same_locals_1_stack_item_extended* create_at(
       address addr, int offset_delta, verification_type_info* vti) {
-    same_frame_1_stack_item_extended* sm =
-       (same_frame_1_stack_item_extended*)addr;
+    same_locals_1_stack_item_extended* sm =
+       (same_locals_1_stack_item_extended*)addr;
     sm->set_frame_type(_frame_id);
     sm->set_offset_delta(offset_delta);
     if (vti != NULL) {
@@ -448,13 +440,12 @@
     return type_addr() < end && types()->verify(start, end);
   }
 
-#ifdef ASSERT
-  void print_on(outputStream* st) const {
-    st->print("same_frame_1_stack_item_extended(%d,", offset_delta());
+  void print_on(outputStream* st, int current_offset = -1) const {
+    st->print("same_locals_1_stack_item_extended(@%d,",
+        offset_delta() + current_offset);
     types()->print_on(st);
     st->print(")");
   }
-#endif
 };
 
 class chop_frame : public stack_map_frame {
@@ -517,11 +508,9 @@
     return frame_type_addr() + size() <= end;
   }
 
-#ifdef ASSERT
-  void print_on(outputStream* st) const {
-    st->print("chop_frame(%d,%d)", offset_delta(), chops());
+  void print_on(outputStream* st, int current_offset = -1) const {
+    st->print("chop_frame(@%d,%d)", offset_delta() + current_offset, chops());
   }
-#endif
 };
 
 class append_frame : public stack_map_frame {
@@ -618,9 +607,8 @@
     return false;
   }
 
-#ifdef ASSERT
-  void print_on(outputStream* st) const {
-    st->print("append_frame(%d,", offset_delta());
+  void print_on(outputStream* st, int current_offset = -1) const {
+    st->print("append_frame(@%d,", offset_delta() + current_offset);
     verification_type_info* vti = types();
     for (int i = 0; i < number_of_types(); ++i) {
       vti->print_on(st);
@@ -631,7 +619,6 @@
     }
     st->print(")");
   }
-#endif
 };
 
 class full_frame : public stack_map_frame {
@@ -774,9 +761,8 @@
     return true;
   }
 
-#ifdef ASSERT
-  void print_on(outputStream* st) const {
-    st->print("full_frame(%d,{", offset_delta());
+  void print_on(outputStream* st, int current_offset = -1) const {
+    st->print("full_frame(@%d,{", offset_delta() + current_offset);
     verification_type_info* vti = locals();
     for (int i = 0; i < num_locals(); ++i) {
       vti->print_on(st);
@@ -798,7 +784,6 @@
     }
     st->print("})");
   }
-#endif
 };
 
 #define VIRTUAL_DISPATCH(stack_frame_type, func_name, args) \
@@ -852,11 +837,9 @@
   return false;
 }
 
-#ifdef ASSERT
-void stack_map_frame::print_on(outputStream* st) const {
-  FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st));
+void stack_map_frame::print_on(outputStream* st, int offs = -1) const {
+  FOR_EACH_STACKMAP_FRAME_TYPE(VOID_VIRTUAL_DISPATCH, print_on, (st, offs));
 }
-#endif
 
 #undef VIRTUAL_DISPATCH
 #undef VOID_VIRTUAL_DISPATCH
@@ -873,16 +856,46 @@
 FOR_EACH_STACKMAP_FRAME_TYPE(AS_SUBTYPE_DEF, x, x)
 #undef AS_SUBTYPE_DEF
 
+class stack_map_table {
+ private:
+  address number_of_entries_addr() const {
+    return (address)this;
+  }
+  address entries_addr() const {
+    return number_of_entries_addr() + sizeof(u2);
+  }
+
+ protected:
+  // No constructors  - should be 'private', but GCC issues a warning if it is
+  stack_map_table() {}
+  stack_map_table(const stack_map_table&) {}
+
+ public:
+
+  static stack_map_table* at(address addr) {
+    return (stack_map_table*)addr;
+  }
+
+  u2 number_of_entries() const {
+    return Bytes::get_Java_u2(number_of_entries_addr());
+  }
+  stack_map_frame* entries() const {
+    return stack_map_frame::at(entries_addr());
+  }
+
+  void set_number_of_entries(u2 num) {
+    Bytes::put_Java_u2(number_of_entries_addr(), num);
+  }
+};
+
 class stack_map_table_attribute {
  private:
   address name_index_addr() const {
       return (address)this; }
   address attribute_length_addr() const {
       return name_index_addr() + sizeof(u2); }
-  address number_of_entries_addr() const {
+  address stack_map_table_addr() const {
       return attribute_length_addr() + sizeof(u4); }
-  address entries_addr() const {
-      return number_of_entries_addr() + sizeof(u2); }
 
  protected:
   // No constructors  - should be 'private', but GCC issues a warning if it is
@@ -896,17 +909,11 @@
   }
 
   u2 name_index() const {
-       return Bytes::get_Java_u2(name_index_addr()); }
+    return Bytes::get_Java_u2(name_index_addr()); }
   u4 attribute_length() const {
-      return Bytes::get_Java_u4(attribute_length_addr()); }
-  u2 number_of_entries() const {
-      return Bytes::get_Java_u2(number_of_entries_addr()); }
-  stack_map_frame* entries() const {
-    return stack_map_frame::at(entries_addr());
-  }
-
-  static size_t header_size() {
-      return sizeof(u2) + sizeof(u4);
+    return Bytes::get_Java_u4(attribute_length_addr()); }
+  stack_map_table* table() const {
+    return stack_map_table::at(stack_map_table_addr());
   }
 
   void set_name_index(u2 idx) {
@@ -915,9 +922,8 @@
   void set_attribute_length(u4 len) {
     Bytes::put_Java_u4(attribute_length_addr(), len);
   }
-  void set_number_of_entries(u2 num) {
-    Bytes::put_Java_u2(number_of_entries_addr(), num);
-  }
 };
 
+#undef FOR_EACH_STACKMAP_FRAME_TYPE
+
 #endif // SHARE_VM_CLASSFILE_STACKMAPTABLEFORMAT_HPP
diff --git a/hotspot/src/share/vm/classfile/symbolTable.cpp b/hotspot/src/share/vm/classfile/symbolTable.cpp
index 7452108..dd52e81 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.cpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,7 @@
 #include "classfile/symbolTable.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "gc_interface/collectedHeap.inline.hpp"
+#include "memory/allocation.inline.hpp"
 #include "memory/filemap.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "oops/oop.inline.hpp"
@@ -39,22 +40,40 @@
 // --------------------------------------------------------------------------
 
 SymbolTable* SymbolTable::_the_table = NULL;
+// Static arena for symbols that are not deallocated
+Arena* SymbolTable::_arena = NULL;
 bool SymbolTable::_needs_rehashing = false;
 
-Symbol* SymbolTable::allocate_symbol(const u1* name, int len, TRAPS) {
+Symbol* SymbolTable::allocate_symbol(const u1* name, int len, bool c_heap, TRAPS) {
   assert (len <= Symbol::max_length(), "should be checked by caller");
 
-  Symbol* sym = new (len) Symbol(name, len);
+  Symbol* sym;
+  // Allocate symbols in the C heap when dumping shared spaces in case there
+  // are temporary symbols we can remove.
+  if (c_heap || DumpSharedSpaces) {
+    // refcount starts as 1
+    sym = new (len, THREAD) Symbol(name, len, 1);
+  } else {
+    sym = new (len, arena(), THREAD) Symbol(name, len, -1);
+  }
   assert(sym != NULL, "new should call vm_exit_out_of_memory if C_HEAP is exhausted");
   return sym;
 }
 
+void SymbolTable::initialize_symbols(int arena_alloc_size) {
+  // Initialize the arena for global symbols, size passed in depends on CDS.
+  if (arena_alloc_size == 0) {
+    _arena = new (mtSymbol) Arena();
+  } else {
+    _arena = new (mtSymbol) Arena(arena_alloc_size);
+  }
+}
 
 // Call function for all symbols in the symbol table.
 void SymbolTable::symbols_do(SymbolClosure *cl) {
   const int n = the_table()->table_size();
   for (int i = 0; i < n; i++) {
-    for (HashtableEntry<Symbol*>* p = the_table()->bucket(i);
+    for (HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
          p != NULL;
          p = p->next()) {
       cl->do_symbol(p->literal_addr());
@@ -66,15 +85,14 @@
 int SymbolTable::symbols_counted = 0;
 
 // Remove unreferenced symbols from the symbol table
-// This is done late during GC.  This doesn't use the hash table unlink because
-// it assumes that the literals are oops.
+// This is done late during GC.
 void SymbolTable::unlink() {
   int removed = 0;
   int total = 0;
   size_t memory_total = 0;
   for (int i = 0; i < the_table()->table_size(); ++i) {
-    HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i);
-    HashtableEntry<Symbol*>* entry = the_table()->bucket(i);
+    HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
+    HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
     while (entry != NULL) {
       // Shared entries are normally at the end of the bucket and if we run into
       // a shared entry, then there is nothing more to remove. However, if we
@@ -98,7 +116,7 @@
         p = entry->next_addr();
       }
       // get next entry
-      entry = (HashtableEntry<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p);
+      entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p);
     }
   }
   symbols_removed += removed;
@@ -135,7 +153,7 @@
 Symbol* SymbolTable::lookup(int index, const char* name,
                               int len, unsigned int hash) {
   int count = 0;
-  for (HashtableEntry<Symbol*>* e = bucket(index); e != NULL; e = e->next()) {
+  for (HashtableEntry<Symbol*, mtSymbol>* e = bucket(index); e != NULL; e = e->next()) {
     count++;  // count all entries in this bucket, not just ones with same hash
     if (e->hash() == hash) {
       Symbol* sym = e->literal();
@@ -147,7 +165,7 @@
     }
   }
   // If the bucket size is too deep check if this hash code is insufficient.
-  if (count >= BasicHashtable::rehash_count && !needs_rehashing()) {
+  if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) {
     _needs_rehashing = check_rehash_table(count);
   }
   return NULL;
@@ -181,7 +199,7 @@
   MutexLocker ml(SymbolTable_lock, THREAD);
 
   // Otherwise, add to symbol to table
-  return the_table()->basic_add(index, (u1*)name, len, hashValue, CHECK_NULL);
+  return the_table()->basic_add(index, (u1*)name, len, hashValue, true, CHECK_NULL);
 }
 
 Symbol* SymbolTable::lookup(const Symbol* sym, int begin, int end, TRAPS) {
@@ -217,10 +235,10 @@
   // We can't include the code in No_Safepoint_Verifier because of the
   // ResourceMark.
 
-  // Allocation must be done before grabbing the SymbolTable_lock lock
+  // Grab SymbolTable_lock first.
   MutexLocker ml(SymbolTable_lock, THREAD);
 
-  return the_table()->basic_add(index, (u1*)buffer, len, hashValue, CHECK_NULL);
+  return the_table()->basic_add(index, (u1*)buffer, len, hashValue, true, CHECK_NULL);
 }
 
 Symbol* SymbolTable::lookup_only(const char* name, int len,
@@ -239,7 +257,7 @@
   unsigned int hash = hash_symbol((char*)sym->bytes(), sym->utf8_length());
   int index = the_table()->hash_to_index(hash);
 
-  for (HashtableEntry<Symbol*>* e = the_table()->bucket(index); e != NULL; e = e->next()) {
+  for (HashtableEntry<Symbol*, mtSymbol>* e = the_table()->bucket(index); e != NULL; e = e->next()) {
     if (e->hash() == hash) {
       Symbol* literal_sym = e->literal();
       if (sym == literal_sym) {
@@ -284,28 +302,43 @@
   }
 }
 
-void SymbolTable::add(constantPoolHandle cp, int names_count,
+void SymbolTable::add(Handle class_loader, constantPoolHandle cp,
+                      int names_count,
                       const char** names, int* lengths, int* cp_indices,
                       unsigned int* hashValues, TRAPS) {
   // Grab SymbolTable_lock first.
   MutexLocker ml(SymbolTable_lock, THREAD);
 
   SymbolTable* table = the_table();
-  bool added = table->basic_add(cp, names_count, names, lengths,
+  bool added = table->basic_add(class_loader, cp, names_count, names, lengths,
                                 cp_indices, hashValues, CHECK);
   if (!added) {
     // do it the hard way
     for (int i=0; i<names_count; i++) {
       int index = table->hash_to_index(hashValues[i]);
-      Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i],
-                                       hashValues[i], CHECK);
+      bool c_heap = class_loader() != NULL;
+      Symbol* sym = table->basic_add(index, (u1*)names[i], lengths[i], hashValues[i], c_heap, CHECK);
       cp->symbol_at_put(cp_indices[i], sym);
     }
   }
 }
 
+Symbol* SymbolTable::new_permanent_symbol(const char* name, TRAPS) {
+  unsigned int hash;
+  Symbol* result = SymbolTable::lookup_only((char*)name, (int)strlen(name), hash);
+  if (result != NULL) {
+    return result;
+  }
+  // Grab SymbolTable_lock first.
+  MutexLocker ml(SymbolTable_lock, THREAD);
+
+  SymbolTable* table = the_table();
+  int index = table->hash_to_index(hash);
+  return table->basic_add(index, (u1*)name, (int)strlen(name), hash, false, THREAD);
+}
+
 Symbol* SymbolTable::basic_add(int index_arg, u1 *name, int len,
-                               unsigned int hashValue_arg, TRAPS) {
+                               unsigned int hashValue_arg, bool c_heap, TRAPS) {
   assert(!Universe::heap()->is_in_reserved(name) || GC_locker::is_active(),
          "proposed name of symbol must be stable");
 
@@ -340,16 +373,18 @@
   }
 
   // Create a new symbol.
-  Symbol* sym = allocate_symbol(name, len, CHECK_NULL);
+  Symbol* sym = allocate_symbol(name, len, c_heap, CHECK_NULL);
   assert(sym->equals((char*)name, len), "symbol must be properly initialized");
 
-  HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym);
-  sym->increment_refcount();  // increment refcount in external hashtable
+  HashtableEntry<Symbol*, mtSymbol>* entry = new_entry(hashValue, sym);
   add_entry(index, entry);
   return sym;
 }
 
-bool SymbolTable::basic_add(constantPoolHandle cp, int names_count,
+// This version of basic_add adds symbols in batch from the constant pool
+// parsing.
+bool SymbolTable::basic_add(Handle class_loader, constantPoolHandle cp,
+                            int names_count,
                             const char** names, int* lengths,
                             int* cp_indices, unsigned int* hashValues,
                             TRAPS) {
@@ -384,22 +419,23 @@
       cp->symbol_at_put(cp_indices[i], test);
       assert(test->refcount() != 0, "lookup should have incremented the count");
     } else {
-      Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], CHECK_(false));
+      // Create a new symbol.  The null class loader is never unloaded so these
+      // are allocated specially in a permanent arena.
+      bool c_heap = class_loader() != NULL;
+      Symbol* sym = allocate_symbol((const u1*)names[i], lengths[i], c_heap, CHECK_(false));
       assert(sym->equals(names[i], lengths[i]), "symbol must be properly initialized");  // why wouldn't it be???
-      HashtableEntry<Symbol*>* entry = new_entry(hashValue, sym);
-      sym->increment_refcount();  // increment refcount in external hashtable
+      HashtableEntry<Symbol*, mtSymbol>* entry = new_entry(hashValue, sym);
       add_entry(index, entry);
       cp->symbol_at_put(cp_indices[i], sym);
     }
   }
-
   return true;
 }
 
 
 void SymbolTable::verify() {
   for (int i = 0; i < the_table()->table_size(); ++i) {
-    HashtableEntry<Symbol*>* p = the_table()->bucket(i);
+    HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
     for ( ; p != NULL; p = p->next()) {
       Symbol* s = (Symbol*)(p->literal());
       guarantee(s != NULL, "symbol is NULL");
@@ -415,7 +451,7 @@
   NumberSeq summary;
   for (int i = 0; i < the_table()->table_size(); ++i) {
     int count = 0;
-    for (HashtableEntry<Symbol*>* e = the_table()->bucket(i);
+    for (HashtableEntry<Symbol*, mtSymbol>* e = the_table()->bucket(i);
        e != NULL; e = e->next()) {
       count++;
     }
@@ -452,7 +488,7 @@
   int memory_total = 0;
   int count = 0;
   for (i = 0; i < the_table()->table_size(); i++) {
-    HashtableEntry<Symbol*>* p = the_table()->bucket(i);
+    HashtableEntry<Symbol*, mtSymbol>* p = the_table()->bucket(i);
     for ( ; p != NULL; p = p->next()) {
       memory_total += p->literal()->object_size();
       count++;
@@ -477,6 +513,8 @@
           ((float)symbols_removed/(float)symbols_counted)* 100);
   }
   tty->print_cr("Reference counts         %5d", Symbol::_total_count);
+  tty->print_cr("Symbol arena size        %5d used %5d",
+                 arena()->size_in_bytes(), arena()->used());
   tty->print_cr("Histogram of symbol length:");
   tty->print_cr("%8s %5d", "Total  ", total);
   tty->print_cr("%8s %5d", "Maximum", max_symbols);
@@ -511,15 +549,15 @@
 
 void SymbolTable::print() {
   for (int i = 0; i < the_table()->table_size(); ++i) {
-    HashtableEntry<Symbol*>** p = the_table()->bucket_addr(i);
-    HashtableEntry<Symbol*>* entry = the_table()->bucket(i);
+    HashtableEntry<Symbol*, mtSymbol>** p = the_table()->bucket_addr(i);
+    HashtableEntry<Symbol*, mtSymbol>* entry = the_table()->bucket(i);
     if (entry != NULL) {
       while (entry != NULL) {
         tty->print(PTR_FORMAT " ", entry->literal());
         entry->literal()->print();
         tty->print(" %d", entry->literal()->refcount());
         p = entry->next_addr();
-        entry = (HashtableEntry<Symbol*>*)HashtableEntry<Symbol*>::make_ptr(*p);
+        entry = (HashtableEntry<Symbol*, mtSymbol>*)HashtableEntry<Symbol*, mtSymbol>::make_ptr(*p);
       }
       tty->cr();
     }
@@ -581,7 +619,7 @@
 oop StringTable::lookup(int index, jchar* name,
                         int len, unsigned int hash) {
   int count = 0;
-  for (HashtableEntry<oop>* l = bucket(index); l != NULL; l = l->next()) {
+  for (HashtableEntry<oop, mtSymbol>* l = bucket(index); l != NULL; l = l->next()) {
     count++;
     if (l->hash() == hash) {
       if (java_lang_String::equals(l->literal(), name, len)) {
@@ -590,7 +628,7 @@
     }
   }
   // If the bucket size is too deep check if this hash code is insufficient.
-  if (count >= BasicHashtable::rehash_count && !needs_rehashing()) {
+  if (count >= BasicHashtable<mtSymbol>::rehash_count && !needs_rehashing()) {
     _needs_rehashing = check_rehash_table(count);
   }
   return NULL;
@@ -626,7 +664,7 @@
     return test;
   }
 
-  HashtableEntry<oop>* entry = new_entry(hashValue, string());
+  HashtableEntry<oop, mtSymbol>* entry = new_entry(hashValue, string());
   add_entry(index, entry);
   return string();
 }
@@ -711,8 +749,8 @@
   // entries at a safepoint.
   assert(SafepointSynchronize::is_at_safepoint(), "must be at safepoint");
   for (int i = 0; i < the_table()->table_size(); ++i) {
-    HashtableEntry<oop>** p = the_table()->bucket_addr(i);
-    HashtableEntry<oop>* entry = the_table()->bucket(i);
+    HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
+    HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
     while (entry != NULL) {
       // Shared entries are normally at the end of the bucket and if we run into
       // a shared entry, then there is nothing more to remove. However, if we
@@ -728,15 +766,15 @@
         *p = entry->next();
         the_table()->free_entry(entry);
       }
-      entry = (HashtableEntry<oop>*)HashtableEntry<oop>::make_ptr(*p);
+      entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
     }
   }
 }
 
 void StringTable::oops_do(OopClosure* f) {
   for (int i = 0; i < the_table()->table_size(); ++i) {
-    HashtableEntry<oop>** p = the_table()->bucket_addr(i);
-    HashtableEntry<oop>* entry = the_table()->bucket(i);
+    HashtableEntry<oop, mtSymbol>** p = the_table()->bucket_addr(i);
+    HashtableEntry<oop, mtSymbol>* entry = the_table()->bucket(i);
     while (entry != NULL) {
       f->do_oop((oop*)entry->literal_addr());
 
@@ -748,14 +786,14 @@
       } else {
         p = entry->next_addr();
       }
-      entry = (HashtableEntry<oop>*)HashtableEntry<oop>::make_ptr(*p);
+      entry = (HashtableEntry<oop, mtSymbol>*)HashtableEntry<oop, mtSymbol>::make_ptr(*p);
     }
   }
 }
 
 void StringTable::verify() {
   for (int i = 0; i < the_table()->table_size(); ++i) {
-    HashtableEntry<oop>* p = the_table()->bucket(i);
+    HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
     for ( ; p != NULL; p = p->next()) {
       oop s = p->literal();
       guarantee(s != NULL, "interned string is NULL");
@@ -771,7 +809,7 @@
 void StringTable::dump(outputStream* st) {
   NumberSeq summary;
   for (int i = 0; i < the_table()->table_size(); ++i) {
-    HashtableEntry<oop>* p = the_table()->bucket(i);
+    HashtableEntry<oop, mtSymbol>* p = the_table()->bucket(i);
     int count = 0;
     for ( ; p != NULL; p = p->next()) {
       count++;
diff --git a/hotspot/src/share/vm/classfile/symbolTable.hpp b/hotspot/src/share/vm/classfile/symbolTable.hpp
index 636f2bc..aeb36d2 100644
--- a/hotspot/src/share/vm/classfile/symbolTable.hpp
+++ b/hotspot/src/share/vm/classfile/symbolTable.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -57,12 +57,15 @@
 
   // Operator= increments reference count.
   void operator=(const TempNewSymbol &s) {
+    //clear();  //FIXME
     _temp = s._temp;
     if (_temp !=NULL) _temp->increment_refcount();
   }
 
   // Decrement reference counter so it can go away if it's unique
-  ~TempNewSymbol() { if (_temp != NULL) _temp->decrement_refcount(); }
+  void clear() { if (_temp != NULL)  _temp->decrement_refcount();  _temp = NULL; }
+
+  ~TempNewSymbol() { clear(); }
 
   // Operators so they can be used like Symbols
   Symbol* operator -> () const                   { return _temp; }
@@ -71,7 +74,7 @@
   operator Symbol*()                             { return _temp; }
 };
 
-class SymbolTable : public Hashtable<Symbol*> {
+class SymbolTable : public Hashtable<Symbol*, mtSymbol> {
   friend class VMStructs;
   friend class ClassFileParser;
 
@@ -86,23 +89,24 @@
   static int symbols_removed;
   static int symbols_counted;
 
-  Symbol* allocate_symbol(const u1* name, int len, TRAPS);   // Assumes no characters larger than 0x7F
+  Symbol* allocate_symbol(const u1* name, int len, bool c_heap, TRAPS); // Assumes no characters larger than 0x7F
 
   // Adding elements
-  Symbol* basic_add(int index, u1* name, int len,
-                      unsigned int hashValue, TRAPS);
-  bool basic_add(constantPoolHandle cp, int names_count,
+  Symbol* basic_add(int index, u1* name, int len, unsigned int hashValue,
+                    bool c_heap, TRAPS);
+
+  bool basic_add(Handle class_loader, constantPoolHandle cp, int names_count,
                  const char** names, int* lengths, int* cp_indices,
                  unsigned int* hashValues, TRAPS);
 
-  static void new_symbols(constantPoolHandle cp, int names_count,
+  static void new_symbols(Handle class_loader, constantPoolHandle cp,
+                          int names_count,
                           const char** name, int* lengths,
                           int* cp_indices, unsigned int* hashValues,
                           TRAPS) {
-    add(cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
+    add(class_loader, cp, names_count, name, lengths, cp_indices, hashValues, THREAD);
   }
 
-
   // Table size
   enum {
     symbol_table_size = 20011
@@ -111,15 +115,22 @@
   Symbol* lookup(int index, const char* name, int len, unsigned int hash);
 
   SymbolTable()
-    : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>)) {}
+    : Hashtable<Symbol*, mtSymbol>(symbol_table_size, sizeof (HashtableEntry<Symbol*, mtSymbol>)) {}
 
-  SymbolTable(HashtableBucket* t, int number_of_entries)
-    : Hashtable<Symbol*>(symbol_table_size, sizeof (HashtableEntry<Symbol*>), t,
+  SymbolTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
+    : Hashtable<Symbol*, mtSymbol>(symbol_table_size, sizeof (HashtableEntry<Symbol*, mtSymbol>), t,
                 number_of_entries) {}
 
+  // Arena for permanent symbols (null class loader) that are never unloaded
+  static Arena*  _arena;
+  static Arena* arena() { return _arena; }  // called for statistics
+
+  static void initialize_symbols(int arena_alloc_size = 0);
 public:
   enum {
-    symbol_alloc_batch_size = 8
+    symbol_alloc_batch_size = 8,
+    // Pick initial size based on java -version size measurements
+    symbol_alloc_arena_size = 360*K
   };
 
   // The symbol table
@@ -128,14 +139,18 @@
   static void create_table() {
     assert(_the_table == NULL, "One symbol table allowed.");
     _the_table = new SymbolTable();
+    initialize_symbols(symbol_alloc_arena_size);
   }
 
-  static void create_table(HashtableBucket* t, int length,
+  static void create_table(HashtableBucket<mtSymbol>* t, int length,
                            int number_of_entries) {
     assert(_the_table == NULL, "One symbol table allowed.");
-    assert(length == symbol_table_size * sizeof(HashtableBucket),
+    assert(length == symbol_table_size * sizeof(HashtableBucket<mtSymbol>),
            "bad shared symbol size.");
     _the_table = new SymbolTable(t, number_of_entries);
+    // if CDS give symbol table a default arena size since most symbols
+    // are already allocated in the shared misc section.
+    initialize_symbols();
   }
 
   static unsigned int hash_symbol(const char* s, int len);
@@ -155,7 +170,7 @@
   static Symbol* lookup_unicode(const jchar* name, int len, TRAPS);
   static Symbol* lookup_only_unicode(const jchar* name, int len, unsigned int& hash);
 
-  static void add(constantPoolHandle cp, int names_count,
+  static void add(Handle class_loader, constantPoolHandle cp, int names_count,
                   const char** names, int* lengths, int* cp_indices,
                   unsigned int* hashValues, TRAPS);
 
@@ -178,6 +193,9 @@
     return lookup(sym, begin, end, THREAD);
   }
 
+  // Create a symbol in the arena for symbols that are not deleted
+  static Symbol* new_permanent_symbol(const char* name, TRAPS);
+
   // Symbol lookup
   static Symbol* lookup(int index, const char* name, int len, TRAPS);
 
@@ -203,13 +221,13 @@
 
   // Sharing
   static void copy_buckets(char** top, char*end) {
-    the_table()->Hashtable<Symbol*>::copy_buckets(top, end);
+    the_table()->Hashtable<Symbol*, mtSymbol>::copy_buckets(top, end);
   }
   static void copy_table(char** top, char*end) {
-    the_table()->Hashtable<Symbol*>::copy_table(top, end);
+    the_table()->Hashtable<Symbol*, mtSymbol>::copy_table(top, end);
   }
   static void reverse(void* boundary = NULL) {
-    the_table()->Hashtable<Symbol*>::reverse(boundary);
+    the_table()->Hashtable<Symbol*, mtSymbol>::reverse(boundary);
   }
 
   // Rehash the symbol table if it gets out of balance
@@ -217,8 +235,7 @@
   static bool needs_rehashing()         { return _needs_rehashing; }
 };
 
-
-class StringTable : public Hashtable<oop> {
+class StringTable : public Hashtable<oop, mtSymbol> {
   friend class VMStructs;
 
 private:
@@ -234,11 +251,11 @@
 
   oop lookup(int index, jchar* chars, int length, unsigned int hashValue);
 
-  StringTable() : Hashtable<oop>((int)StringTableSize,
-                                 sizeof (HashtableEntry<oop>)) {}
+  StringTable() : Hashtable<oop, mtSymbol>((int)StringTableSize,
+                              sizeof (HashtableEntry<oop, mtSymbol>)) {}
 
-  StringTable(HashtableBucket* t, int number_of_entries)
-    : Hashtable<oop>((int)StringTableSize, sizeof (HashtableEntry<oop>), t,
+  StringTable(HashtableBucket<mtSymbol>* t, int number_of_entries)
+    : Hashtable<oop, mtSymbol>((int)StringTableSize, sizeof (HashtableEntry<oop, mtSymbol>), t,
                      number_of_entries) {}
 public:
   // The string table
@@ -249,10 +266,10 @@
     _the_table = new StringTable();
   }
 
-  static void create_table(HashtableBucket* t, int length,
+  static void create_table(HashtableBucket<mtSymbol>* t, int length,
                            int number_of_entries) {
     assert(_the_table == NULL, "One string table allowed.");
-    assert((size_t)length == StringTableSize * sizeof(HashtableBucket),
+    assert((size_t)length == StringTableSize * sizeof(HashtableBucket<mtSymbol>),
            "bad shared string size.");
     _the_table = new StringTable(t, number_of_entries);
   }
@@ -286,13 +303,13 @@
 
   // Sharing
   static void copy_buckets(char** top, char*end) {
-    the_table()->Hashtable<oop>::copy_buckets(top, end);
+    the_table()->Hashtable<oop, mtSymbol>::copy_buckets(top, end);
   }
   static void copy_table(char** top, char*end) {
-    the_table()->Hashtable<oop>::copy_table(top, end);
+    the_table()->Hashtable<oop, mtSymbol>::copy_table(top, end);
   }
   static void reverse() {
-    the_table()->Hashtable<oop>::reverse();
+    the_table()->Hashtable<oop, mtSymbol>::reverse();
   }
 
   // Rehash the symbol table if it gets out of balance
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.cpp b/hotspot/src/share/vm/classfile/systemDictionary.cpp
index 0bdc16d..ba7049a 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.cpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.cpp
@@ -30,6 +30,7 @@
 #include "classfile/resolutionErrors.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "compiler/compileBroker.hpp"
 #include "interpreter/bytecodeStream.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/gcLocker.hpp"
@@ -193,7 +194,10 @@
 // Forwards to resolve_instance_class_or_null
 
 klassOop SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) {
-  assert(!THREAD->is_Compiler_thread(), "Can not load classes with the Compiler thread");
+  assert(!THREAD->is_Compiler_thread(),
+         err_msg("can not load classes with compiler thread: class=%s, classloader=%s",
+                 class_name->as_C_string(),
+                 class_loader.is_null() ? "null" : class_loader->klass()->klass_part()->name()->as_C_string()));
   if (FieldType::is_array(class_name)) {
     return resolve_array_class_or_null(class_name, class_loader, protection_domain, CHECK_NULL);
   } else if (FieldType::is_obj(class_name)) {
@@ -281,16 +285,6 @@
                                                  Handle protection_domain,
                                                  bool is_superclass,
                                                  TRAPS) {
-
-  // Try to get one of the well-known klasses.
-  // They are trusted, and do not participate in circularities.
-  if (LinkWellKnownClasses) {
-    klassOop k = find_well_known_klass(class_name);
-    if (k != NULL) {
-      return k;
-    }
-  }
-
   // Double-check, if child class is already loaded, just return super-class,interface
   // Don't add a placedholder if already loaded, i.e. already in system dictionary
   // Make sure there's a placeholder for the *child* before resolving.
@@ -912,14 +906,6 @@
   klassOop k = NULL;
   assert(class_name != NULL, "class name must be non NULL");
 
-  // Try to get one of the well-known klasses.
-  if (LinkWellKnownClasses) {
-    k = find_well_known_klass(class_name);
-    if (k != NULL) {
-      return k;
-    }
-  }
-
   if (FieldType::is_array(class_name)) {
     // The name refers to an array.  Parse the name.
     // dimension and object_key in FieldArrayInfo are assigned as a
@@ -940,38 +926,6 @@
   return k;
 }
 
-// Quick range check for names of well-known classes:
-static Symbol* wk_klass_name_limits[2] = {NULL, NULL};
-
-#ifndef PRODUCT
-static int find_wkk_calls, find_wkk_probes, find_wkk_wins;
-// counts for "hello world": 3983, 1616, 1075
-//  => 60% hit after limit guard, 25% total win rate
-#endif
-
-klassOop SystemDictionary::find_well_known_klass(Symbol* class_name) {
-  // A bounds-check on class_name will quickly get a negative result.
-  NOT_PRODUCT(find_wkk_calls++);
-  if (class_name >= wk_klass_name_limits[0] &&
-      class_name <= wk_klass_name_limits[1]) {
-    NOT_PRODUCT(find_wkk_probes++);
-    vmSymbols::SID sid = vmSymbols::find_sid(class_name);
-    if (sid != vmSymbols::NO_SID) {
-      klassOop k = NULL;
-      switch (sid) {
-        #define WK_KLASS_CASE(name, symbol, ignore_option) \
-        case vmSymbols::VM_SYMBOL_ENUM_NAME(symbol): \
-          k = WK_KLASS(name); break;
-        WK_KLASSES_DO(WK_KLASS_CASE)
-        #undef WK_KLASS_CASE
-      }
-      NOT_PRODUCT(if (k != NULL)  find_wkk_wins++);
-      return k;
-    }
-  }
-  return NULL;
-}
-
 // Note: this method is much like resolve_from_stream, but
 // updates no supplemental data structures.
 // TODO consolidate the two methods with a helper routine?
@@ -1168,9 +1122,9 @@
 }
 
 
-void SystemDictionary::set_shared_dictionary(HashtableBucket* t, int length,
+void SystemDictionary::set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
                                              int number_of_entries) {
-  assert(length == _nof_buckets * sizeof(HashtableBucket),
+  assert(length == _nof_buckets * sizeof(HashtableBucket<mtClass>),
          "bad shared dictionary size.");
   _shared_dictionary = new Dictionary(_nof_buckets, t, number_of_entries);
 }
@@ -1947,23 +1901,12 @@
     int opt  = (info & right_n_bits(CEIL_LG_OPTION_LIMIT));
 
     initialize_wk_klass((WKID)id, opt, CHECK);
-
-    // Update limits, so find_well_known_klass can be very fast:
-    Symbol* s = vmSymbols::symbol_at((vmSymbols::SID)sid);
-    if (wk_klass_name_limits[1] == NULL) {
-      wk_klass_name_limits[0] = wk_klass_name_limits[1] = s;
-    } else if (wk_klass_name_limits[1] < s) {
-      wk_klass_name_limits[1] = s;
-    } else if (wk_klass_name_limits[0] > s) {
-      wk_klass_name_limits[0] = s;
-    }
   }
 
   // move the starting value forward to the limit:
   start_id = limit_id;
 }
 
-
 void SystemDictionary::initialize_preloaded_classes(TRAPS) {
   assert(WK_KLASS(Object_klass) == NULL, "preloaded classes should only be initialized once");
   // Preload commonly used klasses
@@ -2358,72 +2301,136 @@
 }
 
 
-methodOop SystemDictionary::find_method_handle_invoke(Symbol* name,
-                                                      Symbol* signature,
-                                                      KlassHandle accessing_klass,
-                                                      TRAPS) {
-  if (!EnableInvokeDynamic)  return NULL;
-  vmSymbols::SID name_id = vmSymbols::find_sid(name);
-  assert(name_id != vmSymbols::NO_SID, "must be a known name");
-  unsigned int hash  = invoke_method_table()->compute_hash(signature, name_id);
+methodHandle SystemDictionary::find_method_handle_intrinsic(vmIntrinsics::ID iid,
+                                                            Symbol* signature,
+                                                            TRAPS) {
+  methodHandle empty;
+  assert(EnableInvokeDynamic, "");
+  assert(MethodHandles::is_signature_polymorphic(iid) &&
+         MethodHandles::is_signature_polymorphic_intrinsic(iid) &&
+         iid != vmIntrinsics::_invokeGeneric,
+         err_msg("must be a known MH intrinsic iid=%d: %s", iid, vmIntrinsics::name_at(iid)));
+
+  unsigned int hash  = invoke_method_table()->compute_hash(signature, iid);
   int          index = invoke_method_table()->hash_to_index(hash);
-  SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
-  methodHandle non_cached_result;
+  SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, iid);
+  methodHandle m;
   if (spe == NULL || spe->property_oop() == NULL) {
     spe = NULL;
     // Must create lots of stuff here, but outside of the SystemDictionary lock.
-    if (THREAD->is_Compiler_thread())
-      return NULL;              // do not attempt from within compiler
-    bool for_invokeGeneric = (name_id != vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name));
-    bool found_on_bcp = false;
-    Handle mt = find_method_handle_type(signature, accessing_klass,
-                                        for_invokeGeneric,
-                                        found_on_bcp, CHECK_NULL);
-    KlassHandle  mh_klass = SystemDictionaryHandles::MethodHandle_klass();
-    methodHandle m = methodOopDesc::make_invoke_method(mh_klass, name, signature,
-                                                       mt, CHECK_NULL);
+    m = methodOopDesc::make_method_handle_intrinsic(iid, signature, CHECK_(empty));
+    CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier,
+                                  methodHandle(), CompileThreshold, "MH", CHECK_(empty));
+
     // Now grab the lock.  We might have to throw away the new method,
     // if a racing thread has managed to install one at the same time.
-    if (found_on_bcp) {
-      MutexLocker ml(SystemDictionary_lock, Thread::current());
-      spe = invoke_method_table()->find_entry(index, hash, signature, name_id);
+    {
+      MutexLocker ml(SystemDictionary_lock, THREAD);
+      spe = invoke_method_table()->find_entry(index, hash, signature, iid);
       if (spe == NULL)
-        spe = invoke_method_table()->add_entry(index, hash, signature, name_id);
-      if (spe->property_oop() == NULL) {
+        spe = invoke_method_table()->add_entry(index, hash, signature, iid);
+      if (spe->property_oop() == NULL)
         spe->set_property_oop(m());
-        // Link m to his method type, if it is suitably generic.
-        oop mtform = java_lang_invoke_MethodType::form(mt());
-        if (mtform != NULL && mt() == java_lang_invoke_MethodTypeForm::erasedType(mtform)
-            // vmlayout must be an invokeExact:
-            && name_id == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name)
-            && java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) {
-          java_lang_invoke_MethodTypeForm::init_vmlayout(mtform, m());
-        }
-      }
-    } else {
-      non_cached_result = m;
     }
   }
-  if (spe != NULL && spe->property_oop() != NULL) {
-    assert(spe->property_oop()->is_method(), "");
-    return (methodOop) spe->property_oop();
-  } else {
-    return non_cached_result();
-  }
+
+  assert(spe != NULL && spe->property_oop() != NULL, "");
+  m = methodOop(spe->property_oop());
+  assert(m->is_method(), "");
+
+  return m;
 }
 
+// Helper for unpacking the return value from linkMethod and linkCallSite.
+static methodHandle unpack_method_and_appendix(Handle mname,
+                                               objArrayHandle appendix_box,
+                                               Handle* appendix_result,
+                                               TRAPS) {
+  methodHandle empty;
+  if (mname.not_null()) {
+    oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
+    if (vmtarget != NULL && vmtarget->is_method()) {
+      methodOop m = methodOop(vmtarget);
+      oop appendix = appendix_box->obj_at(0);
+      if (TraceMethodHandles) {
+    #ifndef PRODUCT
+        tty->print("Linked method="INTPTR_FORMAT": ", m);
+        m->print();
+        if (appendix != NULL) { tty->print("appendix = "); appendix->print(); }
+        tty->cr();
+    #endif //PRODUCT
+      }
+      (*appendix_result) = Handle(THREAD, appendix);
+      return methodHandle(THREAD, m);
+    }
+  }
+  THROW_MSG_(vmSymbols::java_lang_LinkageError(), "bad value from MethodHandleNatives", empty);
+  return empty;
+}
+
+methodHandle SystemDictionary::find_method_handle_invoker(Symbol* name,
+                                                          Symbol* signature,
+                                                          KlassHandle accessing_klass,
+                                                          Handle *appendix_result,
+                                                          Handle *method_type_result,
+                                                          TRAPS) {
+  methodHandle empty;
+  assert(EnableInvokeDynamic, "");
+  assert(!THREAD->is_Compiler_thread(), "");
+  Handle method_type =
+    SystemDictionary::find_method_handle_type(signature, accessing_klass, CHECK_(empty));
+  if (false) {  // FIXME: Decide if the Java upcall should resolve signatures.
+    method_type = java_lang_String::create_from_symbol(signature, CHECK_(empty));
+  }
+
+  KlassHandle  mh_klass = SystemDictionaryHandles::MethodHandle_klass();
+  int ref_kind = JVM_REF_invokeVirtual;
+  Handle name_str = StringTable::intern(name, CHECK_(empty));
+  objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty));
+  assert(appendix_box->obj_at(0) == NULL, "");
+
+  // call java.lang.invoke.MethodHandleNatives::linkMethod(... String, MethodType) -> MemberName
+  JavaCallArguments args;
+  args.push_oop(accessing_klass()->java_mirror());
+  args.push_int(ref_kind);
+  args.push_oop(mh_klass()->java_mirror());
+  args.push_oop(name_str());
+  args.push_oop(method_type());
+  args.push_oop(appendix_box());
+  JavaValue result(T_OBJECT);
+  JavaCalls::call_static(&result,
+                         SystemDictionary::MethodHandleNatives_klass(),
+                         vmSymbols::linkMethod_name(),
+                         vmSymbols::linkMethod_signature(),
+                         &args, CHECK_(empty));
+  Handle mname(THREAD, (oop) result.get_jobject());
+  (*method_type_result) = method_type;
+  return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD);
+}
+
+
 // Ask Java code to find or construct a java.lang.invoke.MethodType for the given
 // signature, as interpreted relative to the given class loader.
 // Because of class loader constraints, all method handle usage must be
 // consistent with this loader.
 Handle SystemDictionary::find_method_handle_type(Symbol* signature,
                                                  KlassHandle accessing_klass,
-                                                 bool for_invokeGeneric,
-                                                 bool& return_bcp_flag,
                                                  TRAPS) {
+  Handle empty;
+  vmIntrinsics::ID null_iid = vmIntrinsics::_none;  // distinct from all method handle invoker intrinsics
+  unsigned int hash  = invoke_method_table()->compute_hash(signature, null_iid);
+  int          index = invoke_method_table()->hash_to_index(hash);
+  SymbolPropertyEntry* spe = invoke_method_table()->find_entry(index, hash, signature, null_iid);
+  if (spe != NULL && spe->property_oop() != NULL) {
+    assert(java_lang_invoke_MethodType::is_instance(spe->property_oop()), "");
+    return Handle(THREAD, spe->property_oop());
+  } else if (THREAD->is_Compiler_thread()) {
+    warning("SystemDictionary::find_method_handle_type called from compiler thread");  // FIXME
+    return Handle();  // do not attempt from within compiler, unless it was cached
+  }
+
   Handle class_loader, protection_domain;
   bool is_on_bcp = true;  // keep this true as long as we can materialize from the boot classloader
-  Handle empty;
   int npts = ArgumentCount(signature).size();
   objArrayHandle pts = oopFactory::new_objArray(SystemDictionary::Class_klass(), npts, CHECK_(empty));
   int arg = 0;
@@ -2432,6 +2439,7 @@
   for (SignatureStream ss(signature); !ss.is_done(); ss.next()) {
     oop mirror = NULL;
     if (is_on_bcp) {
+      // Note:  class_loader & protection_domain are both null at this point.
       mirror = ss.as_java_mirror(class_loader, protection_domain,
                                  SignatureStream::ReturnNull, CHECK_(empty));
       if (mirror == NULL) {
@@ -2452,9 +2460,11 @@
       rt = Handle(THREAD, mirror);
     else
       pts->obj_at_put(arg++, mirror);
+
     // Check accessibility.
     if (ss.is_object() && accessing_klass.not_null()) {
       klassOop sel_klass = java_lang_Class::as_klassOop(mirror);
+      mirror = NULL;  // safety
       // Emulate constantPoolOopDesc::verify_constant_pool_resolve.
       if (Klass::cast(sel_klass)->oop_is_objArray())
         sel_klass = objArrayKlass::cast(sel_klass)->bottom_klass();
@@ -2477,23 +2487,18 @@
                          &args, CHECK_(empty));
   Handle method_type(THREAD, (oop) result.get_jobject());
 
-  if (for_invokeGeneric) {
-    // call java.lang.invoke.MethodHandleNatives::notifyGenericMethodType(MethodType) -> void
-    JavaCallArguments args(Handle(THREAD, method_type()));
-    JavaValue no_result(T_VOID);
-    JavaCalls::call_static(&no_result,
-                           SystemDictionary::MethodHandleNatives_klass(),
-                           vmSymbols::notifyGenericMethodType_name(),
-                           vmSymbols::notifyGenericMethodType_signature(),
-                           &args, THREAD);
-    if (HAS_PENDING_EXCEPTION) {
-      // If the notification fails, just kill it.
-      CLEAR_PENDING_EXCEPTION;
+  if (is_on_bcp) {
+    // We can cache this MethodType inside the JVM.
+    MutexLocker ml(SystemDictionary_lock, THREAD);
+    spe = invoke_method_table()->find_entry(index, hash, signature, null_iid);
+    if (spe == NULL)
+      spe = invoke_method_table()->add_entry(index, hash, signature, null_iid);
+    if (spe->property_oop() == NULL) {
+      spe->set_property_oop(method_type());
     }
   }
 
-  // report back to the caller with the MethodType and the "on_bcp" flag
-  return_bcp_flag = is_on_bcp;
+  // report back to the caller with the MethodType
   return method_type;
 }
 
@@ -2508,8 +2513,7 @@
   Handle name = java_lang_String::create_from_symbol(name_sym, CHECK_(empty));
   Handle type;
   if (signature->utf8_length() > 0 && signature->byte_at(0) == '(') {
-    bool ignore_is_on_bcp = false;
-    type = find_method_handle_type(signature, caller, false, ignore_is_on_bcp, CHECK_(empty));
+    type = find_method_handle_type(signature, caller, CHECK_(empty));
   } else {
     ResourceMark rm(THREAD);
     SignatureStream ss(signature, false);
@@ -2543,119 +2547,56 @@
 
 // Ask Java code to find or construct a java.lang.invoke.CallSite for the given
 // name and signature, as interpreted relative to the given class loader.
-Handle SystemDictionary::make_dynamic_call_site(Handle bootstrap_method,
-                                                Symbol* name,
-                                                methodHandle signature_invoker,
-                                                Handle info,
-                                                methodHandle caller_method,
-                                                int caller_bci,
-                                                TRAPS) {
-  Handle empty;
-  guarantee(bootstrap_method.not_null() &&
-            java_lang_invoke_MethodHandle::is_instance(bootstrap_method()),
+methodHandle SystemDictionary::find_dynamic_call_site_invoker(KlassHandle caller,
+                                                              Handle bootstrap_specifier,
+                                                              Symbol* name,
+                                                              Symbol* type,
+                                                              Handle *appendix_result,
+                                                              Handle *method_type_result,
+                                                              TRAPS) {
+  methodHandle empty;
+  Handle bsm, info;
+  if (java_lang_invoke_MethodHandle::is_instance(bootstrap_specifier())) {
+    bsm = bootstrap_specifier;
+  } else {
+    assert(bootstrap_specifier->is_objArray(), "");
+    objArrayHandle args(THREAD, (objArrayOop) bootstrap_specifier());
+    int len = args->length();
+    assert(len >= 1, "");
+    bsm = Handle(THREAD, args->obj_at(0));
+    if (len > 1) {
+      objArrayOop args1 = oopFactory::new_objArray(SystemDictionary::Object_klass(), len-1, CHECK_(empty));
+      for (int i = 1; i < len; i++)
+        args1->obj_at_put(i-1, args->obj_at(i));
+      info = Handle(THREAD, args1);
+    }
+  }
+  guarantee(java_lang_invoke_MethodHandle::is_instance(bsm()),
             "caller must supply a valid BSM");
 
-  Handle caller_mname = MethodHandles::new_MemberName(CHECK_(empty));
-  MethodHandles::init_MemberName(caller_mname(), caller_method());
+  Handle method_name = java_lang_String::create_from_symbol(name, CHECK_(empty));
+  Handle method_type = find_method_handle_type(type, caller, CHECK_(empty));
 
-  // call java.lang.invoke.MethodHandleNatives::makeDynamicCallSite(bootm, name, mtype, info, caller_mname, caller_pos)
-  oop name_str_oop = StringTable::intern(name, CHECK_(empty)); // not a handle!
-  JavaCallArguments args(Handle(THREAD, bootstrap_method()));
-  args.push_oop(name_str_oop);
-  args.push_oop(signature_invoker->method_handle_type());
+  objArrayHandle appendix_box = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1, CHECK_(empty));
+  assert(appendix_box->obj_at(0) == NULL, "");
+
+  // call java.lang.invoke.MethodHandleNatives::linkCallSite(caller, bsm, name, mtype, info, &appendix)
+  JavaCallArguments args;
+  args.push_oop(caller->java_mirror());
+  args.push_oop(bsm());
+  args.push_oop(method_name());
+  args.push_oop(method_type());
   args.push_oop(info());
-  args.push_oop(caller_mname());
-  args.push_int(caller_bci);
+  args.push_oop(appendix_box);
   JavaValue result(T_OBJECT);
   JavaCalls::call_static(&result,
                          SystemDictionary::MethodHandleNatives_klass(),
-                         vmSymbols::makeDynamicCallSite_name(),
-                         vmSymbols::makeDynamicCallSite_signature(),
+                         vmSymbols::linkCallSite_name(),
+                         vmSymbols::linkCallSite_signature(),
                          &args, CHECK_(empty));
-  oop call_site_oop = (oop) result.get_jobject();
-  assert(call_site_oop->is_oop()
-         /*&& java_lang_invoke_CallSite::is_instance(call_site_oop)*/, "must be sane");
-  if (TraceMethodHandles) {
-#ifndef PRODUCT
-    tty->print_cr("Linked invokedynamic bci=%d site="INTPTR_FORMAT":", caller_bci, call_site_oop);
-    call_site_oop->print();
-    tty->cr();
-#endif //PRODUCT
-  }
-  return call_site_oop;
-}
-
-Handle SystemDictionary::find_bootstrap_method(methodHandle caller_method, int caller_bci,
-                                               int cache_index,
-                                               Handle& argument_info_result,
-                                               TRAPS) {
-  Handle empty;
-
-  constantPoolHandle pool;
-  {
-    klassOop caller = caller_method->method_holder();
-    if (!Klass::cast(caller)->oop_is_instance())  return empty;
-    pool = constantPoolHandle(THREAD, instanceKlass::cast(caller)->constants());
-  }
-
-  int constant_pool_index = pool->cache()->entry_at(cache_index)->constant_pool_index();
-  constantTag tag = pool->tag_at(constant_pool_index);
-
-  if (tag.is_invoke_dynamic()) {
-    // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments
-    // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry.
-    int bsm_index = pool->invoke_dynamic_bootstrap_method_ref_index_at(constant_pool_index);
-    if (bsm_index != 0) {
-      int bsm_index_in_cache = pool->cache()->entry_at(cache_index)->bootstrap_method_index_in_cache();
-      DEBUG_ONLY(int bsm_index_2 = pool->cache()->entry_at(bsm_index_in_cache)->constant_pool_index());
-      assert(bsm_index == bsm_index_2, "BSM constant lifted to cache");
-      if (TraceMethodHandles) {
-        tty->print_cr("resolving bootstrap method for "PTR_FORMAT" at %d at cache[%d]CP[%d]...",
-                      (intptr_t) caller_method(), caller_bci, cache_index, constant_pool_index);
-      }
-      oop bsm_oop = pool->resolve_cached_constant_at(bsm_index_in_cache, CHECK_(empty));
-      if (TraceMethodHandles) {
-        tty->print_cr("bootstrap method for "PTR_FORMAT" at %d retrieved as "PTR_FORMAT":",
-                      (intptr_t) caller_method(), caller_bci, (intptr_t) bsm_oop);
-      }
-      assert(bsm_oop->is_oop(), "must be sane");
-      // caller must verify that it is of type MethodHandle
-      Handle bsm(THREAD, bsm_oop);
-      bsm_oop = NULL;  // safety
-
-      // Extract the optional static arguments.
-      Handle argument_info;  // either null, or one arg, or Object[]{arg...}
-      int argc = pool->invoke_dynamic_argument_count_at(constant_pool_index);
-      if (TraceInvokeDynamic) {
-        tty->print_cr("find_bootstrap_method: [%d/%d] CONSTANT_InvokeDynamic: %d[%d]",
-                      constant_pool_index, cache_index, bsm_index, argc);
-      }
-      if (argc > 0) {
-        objArrayHandle arg_array;
-        if (argc > 1) {
-          objArrayOop arg_array_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), argc, CHECK_(empty));
-          arg_array = objArrayHandle(THREAD, arg_array_oop);
-          argument_info = arg_array;
-        }
-        for (int arg_i = 0; arg_i < argc; arg_i++) {
-          int arg_index = pool->invoke_dynamic_argument_index_at(constant_pool_index, arg_i);
-          oop arg_oop = pool->resolve_possibly_cached_constant_at(arg_index, CHECK_(empty));
-          if (arg_array.is_null()) {
-            argument_info = Handle(THREAD, arg_oop);
-          } else {
-            arg_array->obj_at_put(arg_i, arg_oop);
-          }
-        }
-      }
-
-      argument_info_result = argument_info;  // return argument_info to caller
-      return bsm;
-    }
-  } else {
-    ShouldNotReachHere();  // verifier does not allow this
-  }
-
-  return empty;
+  Handle mname(THREAD, (oop) result.get_jobject());
+  (*method_type_result) = method_type;
+  return unpack_method_and_appendix(mname, appendix_box, appendix_result, THREAD);
 }
 
 // Since the identity hash code for symbols changes when the symbols are
@@ -2763,7 +2704,7 @@
       class_size += ik->local_interfaces()->size();
       class_size += ik->transitive_interfaces()->size();
       // We do not have to count implementors, since we only store one!
-      class_size += ik->all_fields_count() * FieldInfo::field_slots;
+      class_size += ik->fields()->length();
     }
   }
 
@@ -2771,7 +2712,6 @@
     nmethods++;
     method_size += m->size();
     // class loader uses same objArray for empty vectors, so don't count these
-    if (m->exception_table()->length() != 0)   method_size += m->exception_table()->size();
     if (m->has_stackmap_table()) {
       method_size += m->stackmap_data()->size();
     }
diff --git a/hotspot/src/share/vm/classfile/systemDictionary.hpp b/hotspot/src/share/vm/classfile/systemDictionary.hpp
index 3abc505..9a05b56 100644
--- a/hotspot/src/share/vm/classfile/systemDictionary.hpp
+++ b/hotspot/src/share/vm/classfile/systemDictionary.hpp
@@ -32,6 +32,7 @@
 #include "runtime/java.hpp"
 #include "runtime/reflectionUtils.hpp"
 #include "utilities/hashtable.hpp"
+#include "utilities/hashtable.inline.hpp"
 
 // The system dictionary stores all loaded classes and maps:
 //
@@ -72,7 +73,7 @@
 class Dictionary;
 class PlaceholderTable;
 class LoaderConstraintTable;
-class HashtableBucket;
+template <MEMFLAGS F> class HashtableBucket;
 class ResolutionErrorTable;
 class SymbolPropertyTable;
 
@@ -91,101 +92,93 @@
 // The order of these definitions is significant; it is the order in which
 // preloading is actually performed by initialize_preloaded_classes.
 
-#define WK_KLASSES_DO(template)                                               \
-  /* well-known classes */                                                    \
-  template(Object_klass,                 java_lang_Object,               Pre) \
-  template(String_klass,                 java_lang_String,               Pre) \
-  template(Class_klass,                  java_lang_Class,                Pre) \
-  template(Cloneable_klass,              java_lang_Cloneable,            Pre) \
-  template(ClassLoader_klass,            java_lang_ClassLoader,          Pre) \
-  template(Serializable_klass,           java_io_Serializable,           Pre) \
-  template(System_klass,                 java_lang_System,               Pre) \
-  template(Throwable_klass,              java_lang_Throwable,            Pre) \
-  template(Error_klass,                  java_lang_Error,                Pre) \
-  template(ThreadDeath_klass,            java_lang_ThreadDeath,          Pre) \
-  template(Exception_klass,              java_lang_Exception,            Pre) \
-  template(RuntimeException_klass,       java_lang_RuntimeException,     Pre) \
-  template(ProtectionDomain_klass,       java_security_ProtectionDomain, Pre) \
-  template(AccessControlContext_klass,   java_security_AccessControlContext, Pre) \
-  template(ClassNotFoundException_klass, java_lang_ClassNotFoundException, Pre) \
-  template(NoClassDefFoundError_klass,   java_lang_NoClassDefFoundError, Pre) \
-  template(LinkageError_klass,           java_lang_LinkageError,         Pre) \
-  template(ClassCastException_klass,     java_lang_ClassCastException,   Pre) \
-  template(ArrayStoreException_klass,    java_lang_ArrayStoreException,  Pre) \
-  template(VirtualMachineError_klass,    java_lang_VirtualMachineError,  Pre) \
-  template(OutOfMemoryError_klass,       java_lang_OutOfMemoryError,     Pre) \
-  template(StackOverflowError_klass,     java_lang_StackOverflowError,   Pre) \
-  template(IllegalMonitorStateException_klass, java_lang_IllegalMonitorStateException, Pre) \
-  template(Reference_klass,              java_lang_ref_Reference,        Pre) \
-                                                                              \
-  /* Preload ref klasses and set reference types */                           \
-  template(SoftReference_klass,          java_lang_ref_SoftReference,    Pre) \
-  template(WeakReference_klass,          java_lang_ref_WeakReference,    Pre) \
-  template(FinalReference_klass,         java_lang_ref_FinalReference,   Pre) \
-  template(PhantomReference_klass,       java_lang_ref_PhantomReference, Pre) \
-  template(Finalizer_klass,              java_lang_ref_Finalizer,        Pre) \
-                                                                              \
-  template(Thread_klass,                 java_lang_Thread,               Pre) \
-  template(ThreadGroup_klass,            java_lang_ThreadGroup,          Pre) \
-  template(Properties_klass,             java_util_Properties,           Pre) \
-  template(reflect_AccessibleObject_klass, java_lang_reflect_AccessibleObject, Pre) \
-  template(reflect_Field_klass,          java_lang_reflect_Field,        Pre) \
-  template(reflect_Method_klass,         java_lang_reflect_Method,       Pre) \
-  template(reflect_Constructor_klass,    java_lang_reflect_Constructor,  Pre) \
-                                                                              \
+#define WK_KLASSES_DO(do_klass)                                                                                          \
+  /* well-known classes */                                                                                               \
+  do_klass(Object_klass,                                java_lang_Object,                          Pre                 ) \
+  do_klass(String_klass,                                java_lang_String,                          Pre                 ) \
+  do_klass(Class_klass,                                 java_lang_Class,                           Pre                 ) \
+  do_klass(Cloneable_klass,                             java_lang_Cloneable,                       Pre                 ) \
+  do_klass(ClassLoader_klass,                           java_lang_ClassLoader,                     Pre                 ) \
+  do_klass(Serializable_klass,                          java_io_Serializable,                      Pre                 ) \
+  do_klass(System_klass,                                java_lang_System,                          Pre                 ) \
+  do_klass(Throwable_klass,                             java_lang_Throwable,                       Pre                 ) \
+  do_klass(Error_klass,                                 java_lang_Error,                           Pre                 ) \
+  do_klass(ThreadDeath_klass,                           java_lang_ThreadDeath,                     Pre                 ) \
+  do_klass(Exception_klass,                             java_lang_Exception,                       Pre                 ) \
+  do_klass(RuntimeException_klass,                      java_lang_RuntimeException,                Pre                 ) \
+  do_klass(ProtectionDomain_klass,                      java_security_ProtectionDomain,            Pre                 ) \
+  do_klass(AccessControlContext_klass,                  java_security_AccessControlContext,        Pre                 ) \
+  do_klass(ClassNotFoundException_klass,                java_lang_ClassNotFoundException,          Pre                 ) \
+  do_klass(NoClassDefFoundError_klass,                  java_lang_NoClassDefFoundError,            Pre                 ) \
+  do_klass(LinkageError_klass,                          java_lang_LinkageError,                    Pre                 ) \
+  do_klass(ClassCastException_klass,                    java_lang_ClassCastException,              Pre                 ) \
+  do_klass(ArrayStoreException_klass,                   java_lang_ArrayStoreException,             Pre                 ) \
+  do_klass(VirtualMachineError_klass,                   java_lang_VirtualMachineError,             Pre                 ) \
+  do_klass(OutOfMemoryError_klass,                      java_lang_OutOfMemoryError,                Pre                 ) \
+  do_klass(StackOverflowError_klass,                    java_lang_StackOverflowError,              Pre                 ) \
+  do_klass(IllegalMonitorStateException_klass,          java_lang_IllegalMonitorStateException,    Pre                 ) \
+  do_klass(Reference_klass,                             java_lang_ref_Reference,                   Pre                 ) \
+                                                                                                                         \
+  /* Preload ref klasses and set reference types */                                                                      \
+  do_klass(SoftReference_klass,                         java_lang_ref_SoftReference,               Pre                 ) \
+  do_klass(WeakReference_klass,                         java_lang_ref_WeakReference,               Pre                 ) \
+  do_klass(FinalReference_klass,                        java_lang_ref_FinalReference,              Pre                 ) \
+  do_klass(PhantomReference_klass,                      java_lang_ref_PhantomReference,            Pre                 ) \
+  do_klass(Finalizer_klass,                             java_lang_ref_Finalizer,                   Pre                 ) \
+                                                                                                                         \
+  do_klass(Thread_klass,                                java_lang_Thread,                          Pre                 ) \
+  do_klass(ThreadGroup_klass,                           java_lang_ThreadGroup,                     Pre                 ) \
+  do_klass(Properties_klass,                            java_util_Properties,                      Pre                 ) \
+  do_klass(reflect_AccessibleObject_klass,              java_lang_reflect_AccessibleObject,        Pre                 ) \
+  do_klass(reflect_Field_klass,                         java_lang_reflect_Field,                   Pre                 ) \
+  do_klass(reflect_Method_klass,                        java_lang_reflect_Method,                  Pre                 ) \
+  do_klass(reflect_Constructor_klass,                   java_lang_reflect_Constructor,             Pre                 ) \
+                                                                                                                         \
   /* NOTE: needed too early in bootstrapping process to have checks based on JDK version */                              \
   /* Universe::is_gte_jdk14x_version() is not set up by this point. */                                                   \
   /* It's okay if this turns out to be NULL in non-1.4 JDKs. */                                                          \
-  template(reflect_MagicAccessorImpl_klass,             sun_reflect_MagicAccessorImpl,             Opt)                  \
-  template(reflect_MethodAccessorImpl_klass,            sun_reflect_MethodAccessorImpl,            Opt_Only_JDK14NewRef) \
-  template(reflect_ConstructorAccessorImpl_klass,       sun_reflect_ConstructorAccessorImpl,       Opt_Only_JDK14NewRef) \
-  template(reflect_DelegatingClassLoader_klass,         sun_reflect_DelegatingClassLoader,         Opt)                  \
-  template(reflect_ConstantPool_klass,                  sun_reflect_ConstantPool,                  Opt_Only_JDK15)       \
-  template(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15)       \
-                                                                              \
-  /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */ \
-  template(MethodHandle_klass,             java_lang_invoke_MethodHandle,             Pre_JSR292) \
-  template(MemberName_klass,               java_lang_invoke_MemberName,               Pre_JSR292) \
-  template(MethodHandleNatives_klass,      java_lang_invoke_MethodHandleNatives,      Pre_JSR292) \
-  template(AdapterMethodHandle_klass,      java_lang_invoke_AdapterMethodHandle,      Pre_JSR292) \
-  template(BoundMethodHandle_klass,        java_lang_invoke_BoundMethodHandle,        Pre_JSR292) \
-  template(DirectMethodHandle_klass,       java_lang_invoke_DirectMethodHandle,       Pre_JSR292) \
-  template(MethodType_klass,               java_lang_invoke_MethodType,               Pre_JSR292) \
-  template(MethodTypeForm_klass,           java_lang_invoke_MethodTypeForm,           Pre_JSR292) \
-  template(BootstrapMethodError_klass,     java_lang_BootstrapMethodError,            Pre_JSR292) \
-  template(WrongMethodTypeException_klass, java_lang_invoke_WrongMethodTypeException, Pre_JSR292) \
-  template(CallSite_klass,                 java_lang_invoke_CallSite,                 Pre_JSR292) \
-  template(CountingMethodHandle_klass,     java_lang_invoke_CountingMethodHandle,     Opt)        \
-  template(ConstantCallSite_klass,         java_lang_invoke_ConstantCallSite,         Pre_JSR292) \
-  template(MutableCallSite_klass,          java_lang_invoke_MutableCallSite,          Pre_JSR292) \
-  template(VolatileCallSite_klass,         java_lang_invoke_VolatileCallSite,         Pre_JSR292) \
-  /* Note: MethodHandle must be first, and VolatileCallSite last in group */  \
-                                                                              \
-  template(StringBuffer_klass,           java_lang_StringBuffer,         Pre) \
-  template(StringBuilder_klass,          java_lang_StringBuilder,        Pre) \
-                                                                              \
-  /* It's NULL in non-1.4 JDKs. */                                            \
-  template(StackTraceElement_klass,      java_lang_StackTraceElement,    Opt) \
-  /* Universe::is_gte_jdk14x_version() is not set up by this point. */        \
-  /* It's okay if this turns out to be NULL in non-1.4 JDKs. */               \
-  template(nio_Buffer_klass,             java_nio_Buffer,                Opt) \
-                                                                              \
-  /* If this class isn't present, it won't be referenced. */                  \
-  template(AtomicLongCSImpl_klass,       sun_misc_AtomicLongCSImpl,   Opt)    \
-                                                                              \
-  template(DownloadManager_klass,        sun_jkernel_DownloadManager, Opt_Kernel) \
-                                                                              \
-  template(PostVMInitHook_klass,         sun_misc_PostVMInitHook, Opt)        \
-                                                                              \
-  /* Preload boxing klasses */                                                \
-  template(Boolean_klass,                java_lang_Boolean,              Pre) \
-  template(Character_klass,              java_lang_Character,            Pre) \
-  template(Float_klass,                  java_lang_Float,                Pre) \
-  template(Double_klass,                 java_lang_Double,               Pre) \
-  template(Byte_klass,                   java_lang_Byte,                 Pre) \
-  template(Short_klass,                  java_lang_Short,                Pre) \
-  template(Integer_klass,                java_lang_Integer,              Pre) \
-  template(Long_klass,                   java_lang_Long,                 Pre) \
+  do_klass(reflect_MagicAccessorImpl_klass,             sun_reflect_MagicAccessorImpl,             Opt                 ) \
+  do_klass(reflect_MethodAccessorImpl_klass,            sun_reflect_MethodAccessorImpl,            Opt_Only_JDK14NewRef) \
+  do_klass(reflect_ConstructorAccessorImpl_klass,       sun_reflect_ConstructorAccessorImpl,       Opt_Only_JDK14NewRef) \
+  do_klass(reflect_DelegatingClassLoader_klass,         sun_reflect_DelegatingClassLoader,         Opt                 ) \
+  do_klass(reflect_ConstantPool_klass,                  sun_reflect_ConstantPool,                  Opt_Only_JDK15      ) \
+  do_klass(reflect_UnsafeStaticFieldAccessorImpl_klass, sun_reflect_UnsafeStaticFieldAccessorImpl, Opt_Only_JDK15      ) \
+                                                                                                                         \
+  /* support for dynamic typing; it's OK if these are NULL in earlier JDKs */                                            \
+  do_klass(MethodHandle_klass,                          java_lang_invoke_MethodHandle,             Pre_JSR292          ) \
+  do_klass(MemberName_klass,                            java_lang_invoke_MemberName,               Pre_JSR292          ) \
+  do_klass(MethodHandleNatives_klass,                   java_lang_invoke_MethodHandleNatives,      Pre_JSR292          ) \
+  do_klass(LambdaForm_klass,                            java_lang_invoke_LambdaForm,               Opt                 ) \
+  do_klass(MethodType_klass,                            java_lang_invoke_MethodType,               Pre_JSR292          ) \
+  do_klass(BootstrapMethodError_klass,                  java_lang_BootstrapMethodError,            Pre_JSR292          ) \
+  do_klass(CallSite_klass,                              java_lang_invoke_CallSite,                 Pre_JSR292          ) \
+  do_klass(ConstantCallSite_klass,                      java_lang_invoke_ConstantCallSite,         Pre_JSR292          ) \
+  do_klass(MutableCallSite_klass,                       java_lang_invoke_MutableCallSite,          Pre_JSR292          ) \
+  do_klass(VolatileCallSite_klass,                      java_lang_invoke_VolatileCallSite,         Pre_JSR292          ) \
+  /* Note: MethodHandle must be first, and VolatileCallSite last in group */                                             \
+                                                                                                                         \
+  do_klass(StringBuffer_klass,                          java_lang_StringBuffer,                    Pre                 ) \
+  do_klass(StringBuilder_klass,                         java_lang_StringBuilder,                   Pre                 ) \
+                                                                                                                         \
+  /* It's NULL in non-1.4 JDKs. */                                                                                       \
+  do_klass(StackTraceElement_klass,                     java_lang_StackTraceElement,               Opt                 ) \
+  /* Universe::is_gte_jdk14x_version() is not set up by this point. */                                                   \
+  /* It's okay if this turns out to be NULL in non-1.4 JDKs. */                                                          \
+  do_klass(nio_Buffer_klass,                            java_nio_Buffer,                           Opt                 ) \
+                                                                                                                         \
+  do_klass(DownloadManager_klass,                       sun_jkernel_DownloadManager,               Opt_Kernel          ) \
+                                                                                                                         \
+  do_klass(PostVMInitHook_klass,                        sun_misc_PostVMInitHook,                   Opt                 ) \
+                                                                                                                         \
+  /* Preload boxing klasses */                                                                                           \
+  do_klass(Boolean_klass,                               java_lang_Boolean,                         Pre                 ) \
+  do_klass(Character_klass,                             java_lang_Character,                       Pre                 ) \
+  do_klass(Float_klass,                                 java_lang_Float,                           Pre                 ) \
+  do_klass(Double_klass,                                java_lang_Double,                          Pre                 ) \
+  do_klass(Byte_klass,                                  java_lang_Byte,                            Pre                 ) \
+  do_klass(Short_klass,                                 java_lang_Short,                           Pre                 ) \
+  do_klass(Integer_klass,                               java_lang_Integer,                         Pre                 ) \
+  do_klass(Long_klass,                                  java_lang_Long,                            Pre                 ) \
   /*end*/
 
 
@@ -289,9 +282,6 @@
                                                Handle protection_domain,
                                                TRAPS);
 
-  // If the given name is known to vmSymbols, return the well-know klass:
-  static klassOop find_well_known_klass(Symbol* class_name);
-
   // Lookup an instance or array class that has already been loaded
   // either into the given class loader, or else into another class
   // loader that is constrained (via loader constraints) to produce
@@ -366,7 +356,7 @@
   static void copy_buckets(char** top, char* end);
   static void copy_table(char** top, char* end);
   static void reverse();
-  static void set_shared_dictionary(HashtableBucket* t, int length,
+  static void set_shared_dictionary(HashtableBucket<mtClass>* t, int length,
                                     int number_of_entries);
   // Printing
   static void print()                   PRODUCT_RETURN;
@@ -406,9 +396,9 @@
     return k;
   }
 
-  static klassOop check_klass_Pre(klassOop k) { return check_klass(k); }
+  static klassOop check_klass_Pre(       klassOop k) { return check_klass(k); }
   static klassOop check_klass_Pre_JSR292(klassOop k) { return EnableInvokeDynamic ? check_klass(k) : k; }
-  static klassOop check_klass_Opt(klassOop k) { return k; }
+  static klassOop check_klass_Opt(       klassOop k) { return k; }
   static klassOop check_klass_Opt_Kernel(klassOop k) { return k; } //== Opt
   static klassOop check_klass_Opt_Only_JDK15(klassOop k) {
     assert(JDK_Version::is_gte_jdk15x_version(), "JDK 1.5 only");
@@ -487,17 +477,25 @@
                                        Handle loader2, bool is_method, TRAPS);
 
   // JSR 292
-  // find the java.lang.invoke.MethodHandles::invoke method for a given signature
-  static methodOop find_method_handle_invoke(Symbol* name,
-                                             Symbol* signature,
-                                             KlassHandle accessing_klass,
-                                             TRAPS);
-  // ask Java to compute a java.lang.invoke.MethodType object for a given signature
+  // find a java.lang.invoke.MethodHandle.invoke* method for a given signature
+  // (asks Java to compute it if necessary, except in a compiler thread)
+  static methodHandle find_method_handle_invoker(Symbol* name,
+                                                 Symbol* signature,
+                                                 KlassHandle accessing_klass,
+                                                 Handle *appendix_result,
+                                                 Handle *method_type_result,
+                                                 TRAPS);
+  // for a given signature, find the internal MethodHandle method (linkTo* or invokeBasic)
+  // (does not ask Java, since this is a low-level intrinsic defined by the JVM)
+  static methodHandle find_method_handle_intrinsic(vmIntrinsics::ID iid,
+                                                   Symbol* signature,
+                                                   TRAPS);
+  // find a java.lang.invoke.MethodType object for a given signature
+  // (asks Java to compute it if necessary, except in a compiler thread)
   static Handle    find_method_handle_type(Symbol* signature,
                                            KlassHandle accessing_klass,
-                                           bool for_invokeGeneric,
-                                           bool& return_bcp_flag,
                                            TRAPS);
+
   // ask Java to compute a java.lang.invoke.MethodHandle object for a given CP entry
   static Handle    link_method_handle_constant(KlassHandle caller,
                                                int ref_kind, //e.g., JVM_REF_invokeVirtual
@@ -505,23 +503,15 @@
                                                Symbol* name,
                                                Symbol* signature,
                                                TRAPS);
-  // ask Java to create a dynamic call site, while linking an invokedynamic op
-  static Handle    make_dynamic_call_site(Handle bootstrap_method,
-                                          // Callee information:
-                                          Symbol* name,
-                                          methodHandle signature_invoker,
-                                          Handle info,
-                                          // Caller information:
-                                          methodHandle caller_method,
-                                          int caller_bci,
-                                          TRAPS);
 
-  // coordinate with Java about bootstrap methods
-  static Handle    find_bootstrap_method(methodHandle caller_method,
-                                         int caller_bci,  // N.B. must be an invokedynamic
-                                         int cache_index, // must be corresponding main_entry
-                                         Handle &argument_info_result, // static BSM arguments, if any
-                                         TRAPS);
+  // ask Java to create a dynamic call site, while linking an invokedynamic op
+  static methodHandle find_dynamic_call_site_invoker(KlassHandle caller,
+                                                     Handle bootstrap_method,
+                                                     Symbol* name,
+                                                     Symbol* type,
+                                                     Handle *appendix_result,
+                                                     Handle *method_type_result,
+                                                     TRAPS);
 
   // Utility for printing loader "name" as part of tracing constraints
   static const char* loader_name(oop loader) {
diff --git a/hotspot/src/share/vm/classfile/verificationType.cpp b/hotspot/src/share/vm/classfile/verificationType.cpp
index 3e204f7..e8f80b0 100644
--- a/hotspot/src/share/vm/classfile/verificationType.cpp
+++ b/hotspot/src/share/vm/classfile/verificationType.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -110,34 +110,34 @@
   }
 }
 
-#ifndef PRODUCT
-
 void VerificationType::print_on(outputStream* st) const {
   switch (_u._data) {
-    case Bogus:            st->print(" bogus "); break;
-    case Category1:        st->print(" category1 "); break;
-    case Category2:        st->print(" category2 "); break;
-    case Category2_2nd:    st->print(" category2_2nd "); break;
-    case Boolean:          st->print(" boolean "); break;
-    case Byte:             st->print(" byte "); break;
-    case Short:            st->print(" short "); break;
-    case Char:             st->print(" char "); break;
-    case Integer:          st->print(" integer "); break;
-    case Float:            st->print(" float "); break;
-    case Long:             st->print(" long "); break;
-    case Double:           st->print(" double "); break;
-    case Long_2nd:         st->print(" long_2nd "); break;
-    case Double_2nd:       st->print(" double_2nd "); break;
-    case Null:             st->print(" null "); break;
+    case Bogus:            st->print("top"); break;
+    case Category1:        st->print("category1"); break;
+    case Category2:        st->print("category2"); break;
+    case Category2_2nd:    st->print("category2_2nd"); break;
+    case Boolean:          st->print("boolean"); break;
+    case Byte:             st->print("byte"); break;
+    case Short:            st->print("short"); break;
+    case Char:             st->print("char"); break;
+    case Integer:          st->print("integer"); break;
+    case Float:            st->print("float"); break;
+    case Long:             st->print("long"); break;
+    case Double:           st->print("double"); break;
+    case Long_2nd:         st->print("long_2nd"); break;
+    case Double_2nd:       st->print("double_2nd"); break;
+    case Null:             st->print("null"); break;
+    case ReferenceQuery:   st->print("reference type"); break;
+    case Category1Query:   st->print("category1 type"); break;
+    case Category2Query:   st->print("category2 type"); break;
+    case Category2_2ndQuery: st->print("category2_2nd type"); break;
     default:
       if (is_uninitialized_this()) {
-        st->print(" uninitializedThis ");
+        st->print("uninitializedThis");
       } else if (is_uninitialized()) {
-        st->print(" uninitialized %d ", bci());
+        st->print("uninitialized %d", bci());
       } else {
-        st->print(" class %s ", name()->as_klass_external_name());
+        name()->print_value_on(st);
       }
   }
 }
-
-#endif
diff --git a/hotspot/src/share/vm/classfile/verificationType.hpp b/hotspot/src/share/vm/classfile/verificationType.hpp
index 260d8ce..eec0bf3 100644
--- a/hotspot/src/share/vm/classfile/verificationType.hpp
+++ b/hotspot/src/share/vm/classfile/verificationType.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -157,7 +157,7 @@
 
   // For reference types, store the actual Symbol
   static VerificationType reference_type(Symbol* sh) {
-      assert(((uintptr_t)sh & 0x3) == 0, "Oops must be aligned");
+      assert(((uintptr_t)sh & 0x3) == 0, "Symbols must be aligned");
       // If the above assert fails in the future because oop* isn't aligned,
       // then this type encoding system will have to change to have a tag value
       // to descriminate between oops and primitives.
@@ -303,7 +303,7 @@
     return index;
   }
 
-  void print_on(outputStream* st) const PRODUCT_RETURN;
+  void print_on(outputStream* st) const;
 
  private:
 
diff --git a/hotspot/src/share/vm/classfile/verifier.cpp b/hotspot/src/share/vm/classfile/verifier.cpp
index 905456a..da188bb 100644
--- a/hotspot/src/share/vm/classfile/verifier.cpp
+++ b/hotspot/src/share/vm/classfile/verifier.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,12 @@
 #include "classfile/classFileStream.hpp"
 #include "classfile/javaClasses.hpp"
 #include "classfile/stackMapTable.hpp"
+#include "classfile/stackMapFrame.hpp"
+#include "classfile/stackMapTableFormat.hpp"
 #include "classfile/systemDictionary.hpp"
 #include "classfile/verifier.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "interpreter/bytecodes.hpp"
 #include "interpreter/bytecodeStream.hpp"
 #include "memory/oopFactory.hpp"
 #include "memory/resourceArea.hpp"
@@ -110,8 +113,11 @@
   Symbol* exception_name = NULL;
   const size_t message_buffer_len = klass->name()->utf8_length() + 1024;
   char* message_buffer = NEW_RESOURCE_ARRAY(char, message_buffer_len);
+  char* exception_message = message_buffer;
 
   const char* klassName = klass->external_name();
+  bool can_failover = FailOverToOldVerifier &&
+      klass->major_version() < NOFAILOVER_MAJOR_VERSION;
 
   // If the class should be verified, first see if we can use the split
   // verifier.  If not, or if verification fails and FailOverToOldVerifier
@@ -122,27 +128,28 @@
     }
     if (UseSplitVerifier &&
         klass->major_version() >= STACKMAP_ATTRIBUTE_MAJOR_VERSION) {
-        ClassVerifier split_verifier(
-          klass, message_buffer, message_buffer_len, THREAD);
-        split_verifier.verify_class(THREAD);
-        exception_name = split_verifier.result();
-      if (klass->major_version() < NOFAILOVER_MAJOR_VERSION &&
-          FailOverToOldVerifier && !HAS_PENDING_EXCEPTION &&
+      ClassVerifier split_verifier(klass, THREAD);
+      split_verifier.verify_class(THREAD);
+      exception_name = split_verifier.result();
+      if (can_failover && !HAS_PENDING_EXCEPTION &&
           (exception_name == vmSymbols::java_lang_VerifyError() ||
            exception_name == vmSymbols::java_lang_ClassFormatError())) {
-        if (TraceClassInitialization) {
+        if (TraceClassInitialization || VerboseVerification) {
           tty->print_cr(
             "Fail over class verification to old verifier for: %s", klassName);
         }
         exception_name = inference_verify(
           klass, message_buffer, message_buffer_len, THREAD);
       }
+      if (exception_name != NULL) {
+        exception_message = split_verifier.exception_message();
+      }
     } else {
       exception_name = inference_verify(
           klass, message_buffer, message_buffer_len, THREAD);
     }
 
-    if (TraceClassInitialization) {
+    if (TraceClassInitialization || VerboseVerification) {
       if (HAS_PENDING_EXCEPTION) {
         tty->print("Verification for %s has", klassName);
         tty->print_cr(" exception pending %s ",
@@ -173,7 +180,7 @@
       kls = kls->super();
     }
     message_buffer[message_buffer_len - 1] = '\0'; // just to be sure
-    THROW_MSG_(exception_name, message_buffer, false);
+    THROW_MSG_(exception_name, exception_message, false);
   }
 }
 
@@ -221,7 +228,7 @@
   }
 
   ResourceMark rm(THREAD);
-  if (ClassVerifier::_verify_verbose) {
+  if (VerboseVerification) {
     tty->print_cr("Verifying class %s with old format", klass->external_name());
   }
 
@@ -265,14 +272,252 @@
   }
 }
 
+TypeOrigin TypeOrigin::null() {
+  return TypeOrigin();
+}
+TypeOrigin TypeOrigin::local(u2 index, StackMapFrame* frame) {
+  assert(frame != NULL, "Must have a frame");
+  return TypeOrigin(CF_LOCALS, index, StackMapFrame::copy(frame),
+     frame->local_at(index));
+}
+TypeOrigin TypeOrigin::stack(u2 index, StackMapFrame* frame) {
+  assert(frame != NULL, "Must have a frame");
+  return TypeOrigin(CF_STACK, index, StackMapFrame::copy(frame),
+      frame->stack_at(index));
+}
+TypeOrigin TypeOrigin::sm_local(u2 index, StackMapFrame* frame) {
+  assert(frame != NULL, "Must have a frame");
+  return TypeOrigin(SM_LOCALS, index, StackMapFrame::copy(frame),
+      frame->local_at(index));
+}
+TypeOrigin TypeOrigin::sm_stack(u2 index, StackMapFrame* frame) {
+  assert(frame != NULL, "Must have a frame");
+  return TypeOrigin(SM_STACK, index, StackMapFrame::copy(frame),
+      frame->stack_at(index));
+}
+TypeOrigin TypeOrigin::bad_index(u2 index) {
+  return TypeOrigin(BAD_INDEX, index, NULL, VerificationType::bogus_type());
+}
+TypeOrigin TypeOrigin::cp(u2 index, VerificationType vt) {
+  return TypeOrigin(CONST_POOL, index, NULL, vt);
+}
+TypeOrigin TypeOrigin::signature(VerificationType vt) {
+  return TypeOrigin(SIG, 0, NULL, vt);
+}
+TypeOrigin TypeOrigin::implicit(VerificationType t) {
+  return TypeOrigin(IMPLICIT, 0, NULL, t);
+}
+TypeOrigin TypeOrigin::frame(StackMapFrame* frame) {
+  return TypeOrigin(FRAME_ONLY, 0, StackMapFrame::copy(frame),
+                    VerificationType::bogus_type());
+}
+
+void TypeOrigin::reset_frame() {
+  if (_frame != NULL) {
+    _frame->restore();
+  }
+}
+
+void TypeOrigin::details(outputStream* ss) const {
+  _type.print_on(ss);
+  switch (_origin) {
+    case CF_LOCALS:
+      ss->print(" (current frame, locals[%d])", _index);
+      break;
+    case CF_STACK:
+      ss->print(" (current frame, stack[%d])", _index);
+      break;
+    case SM_LOCALS:
+      ss->print(" (stack map, locals[%d])", _index);
+      break;
+    case SM_STACK:
+      ss->print(" (stack map, stack[%d])", _index);
+      break;
+    case CONST_POOL:
+      ss->print(" (constant pool %d)", _index);
+      break;
+    case SIG:
+      ss->print(" (from method signature)");
+      break;
+    case IMPLICIT:
+    case FRAME_ONLY:
+    case NONE:
+    default:
+      ;
+  }
+}
+
+#ifdef ASSERT
+void TypeOrigin::print_on(outputStream* str) const {
+  str->print("{%d,%d,%p:", _origin, _index, _frame);
+  if (_frame != NULL) {
+    _frame->print_on(str);
+  } else {
+    str->print("null");
+  }
+  str->print(",");
+  _type.print_on(str);
+  str->print("}");
+}
+#endif
+
+void ErrorContext::details(outputStream* ss, methodOop method) const {
+  if (is_valid()) {
+    ss->print_cr("");
+    ss->print_cr("Exception Details:");
+    location_details(ss, method);
+    reason_details(ss);
+    frame_details(ss);
+    bytecode_details(ss, method);
+    handler_details(ss, method);
+    stackmap_details(ss, method);
+  }
+}
+
+void ErrorContext::reason_details(outputStream* ss) const {
+  streamIndentor si(ss);
+  ss->indent().print_cr("Reason:");
+  streamIndentor si2(ss);
+  ss->indent().print("");
+  switch (_fault) {
+    case INVALID_BYTECODE:
+      ss->print("Error exists in the bytecode");
+      break;
+    case WRONG_TYPE:
+      if (_expected.is_valid()) {
+        ss->print("Type ");
+        _type.details(ss);
+        ss->print(" is not assignable to ");
+        _expected.details(ss);
+      } else {
+        ss->print("Invalid type: ");
+        _type.details(ss);
+      }
+      break;
+    case FLAGS_MISMATCH:
+      if (_expected.is_valid()) {
+        ss->print("Current frame's flags are not assignable "
+                  "to stack map frame's.");
+      } else {
+        ss->print("Current frame's flags are invalid in this context.");
+      }
+      break;
+    case BAD_CP_INDEX:
+      ss->print("Constant pool index %d is invalid", _type.index());
+      break;
+    case BAD_LOCAL_INDEX:
+      ss->print("Local index %d is invalid", _type.index());
+      break;
+    case LOCALS_SIZE_MISMATCH:
+      ss->print("Current frame's local size doesn't match stackmap.");
+      break;
+    case STACK_SIZE_MISMATCH:
+      ss->print("Current frame's stack size doesn't match stackmap.");
+      break;
+    case STACK_OVERFLOW:
+      ss->print("Exceeded max stack size.");
+      break;
+    case STACK_UNDERFLOW:
+      ss->print("Attempt to pop empty stack.");
+      break;
+    case MISSING_STACKMAP:
+      ss->print("Expected stackmap frame at this location.");
+      break;
+    case BAD_STACKMAP:
+      ss->print("Invalid stackmap specification.");
+      break;
+    case UNKNOWN:
+    default:
+      ShouldNotReachHere();
+      ss->print_cr("Unknown");
+  }
+  ss->print_cr("");
+}
+
+void ErrorContext::location_details(outputStream* ss, methodOop method) const {
+  if (_bci != -1 && method != NULL) {
+    streamIndentor si(ss);
+    const char* bytecode_name = "<invalid>";
+    if (method->validate_bci_from_bcx(_bci) != -1) {
+      Bytecodes::Code code = Bytecodes::code_or_bp_at(method->bcp_from(_bci));
+      if (Bytecodes::is_defined(code)) {
+          bytecode_name = Bytecodes::name(code);
+      } else {
+          bytecode_name = "<illegal>";
+      }
+    }
+    instanceKlass* ik = instanceKlass::cast(method->method_holder());
+    ss->indent().print_cr("Location:");
+    streamIndentor si2(ss);
+    ss->indent().print_cr("%s.%s%s @%d: %s",
+        ik->name()->as_C_string(), method->name()->as_C_string(),
+        method->signature()->as_C_string(), _bci, bytecode_name);
+  }
+}
+
+void ErrorContext::frame_details(outputStream* ss) const {
+  streamIndentor si(ss);
+  if (_type.is_valid() && _type.frame() != NULL) {
+    ss->indent().print_cr("Current Frame:");
+    streamIndentor si2(ss);
+    _type.frame()->print_on(ss);
+  }
+  if (_expected.is_valid() && _expected.frame() != NULL) {
+    ss->indent().print_cr("Stackmap Frame:");
+    streamIndentor si2(ss);
+    _expected.frame()->print_on(ss);
+  }
+}
+
+void ErrorContext::bytecode_details(outputStream* ss, methodOop method) const {
+  if (method != NULL) {
+    streamIndentor si(ss);
+    ss->indent().print_cr("Bytecode:");
+    streamIndentor si2(ss);
+    ss->print_data(method->code_base(), method->code_size(), false);
+  }
+}
+
+void ErrorContext::handler_details(outputStream* ss, methodOop method) const {
+  if (method != NULL) {
+    streamIndentor si(ss);
+    ExceptionTable table(method);
+    if (table.length() > 0) {
+      ss->indent().print_cr("Exception Handler Table:");
+      streamIndentor si2(ss);
+      for (int i = 0; i < table.length(); ++i) {
+        ss->indent().print_cr("bci [%d, %d] => handler: %d", table.start_pc(i),
+            table.end_pc(i), table.handler_pc(i));
+      }
+    }
+  }
+}
+
+void ErrorContext::stackmap_details(outputStream* ss, methodOop method) const {
+  if (method != NULL && method->has_stackmap_table()) {
+    streamIndentor si(ss);
+    ss->indent().print_cr("Stackmap Table:");
+    typeArrayOop data = method->stackmap_data();
+    stack_map_table* sm_table =
+        stack_map_table::at((address)data->byte_at_addr(0));
+    stack_map_frame* sm_frame = sm_table->entries();
+    streamIndentor si2(ss);
+    int current_offset = -1;
+    for (u2 i = 0; i < sm_table->number_of_entries(); ++i) {
+      ss->indent();
+      sm_frame->print_on(ss, current_offset);
+      ss->print_cr("");
+      current_offset += sm_frame->offset_delta();
+      sm_frame = sm_frame->next();
+    }
+  }
+}
+
 // Methods in ClassVerifier
 
-bool ClassVerifier::_verify_verbose = false;
-
 ClassVerifier::ClassVerifier(
-    instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS)
-    : _thread(THREAD), _exception_type(NULL), _message(msg),
-      _message_buffer_len(msg_len), _klass(klass) {
+    instanceKlassHandle klass, TRAPS)
+    : _thread(THREAD), _exception_type(NULL), _message(NULL), _klass(klass) {
   _this_type = VerificationType::reference_type(klass->name());
   // Create list to hold symbols in reference area.
   _symbols = new GrowableArray<Symbol*>(100, 0, NULL);
@@ -290,8 +535,14 @@
   return VerificationType::reference_type(vmSymbols::java_lang_Object());
 }
 
+TypeOrigin ClassVerifier::ref_ctx(const char* sig, TRAPS) {
+  VerificationType vt = VerificationType::reference_type(
+      create_temporary_symbol(sig, (int)strlen(sig), THREAD));
+  return TypeOrigin::implicit(vt);
+}
+
 void ClassVerifier::verify_class(TRAPS) {
-  if (_verify_verbose) {
+  if (VerboseVerification) {
     tty->print_cr("Verifying class %s with new format",
       _klass->external_name());
   }
@@ -312,7 +563,7 @@
     verify_method(methodHandle(THREAD, m), CHECK_VERIFY(this));
   }
 
-  if (_verify_verbose || TraceClassInitialization) {
+  if (VerboseVerification || TraceClassInitialization) {
     if (was_recursively_verified())
       tty->print_cr("Recursive verification detected for: %s",
           _klass->external_name());
@@ -321,13 +572,13 @@
 
 void ClassVerifier::verify_method(methodHandle m, TRAPS) {
   _method = m;   // initialize _method
-  if (_verify_verbose) {
+  if (VerboseVerification) {
     tty->print_cr("Verifying method %s", m->name_and_sig_as_C_string());
   }
 
   const char* bad_type_msg = "Bad type on operand stack in %s";
 
-  int32_t max_stack = m->max_stack();
+  int32_t max_stack = m->verifier_max_stack();
   int32_t max_locals = m->max_locals();
   constantPoolHandle cp(THREAD, m->constants());
 
@@ -368,8 +619,8 @@
   StackMapTable stackmap_table(&reader, &current_frame, max_locals, max_stack,
                                code_data, code_length, CHECK_VERIFY(this));
 
-  if (_verify_verbose) {
-    stackmap_table.print();
+  if (VerboseVerification) {
+    stackmap_table.print_on(tty);
   }
 
   RawBytecodeStream bcs(m);
@@ -388,6 +639,7 @@
 
     // Set current frame's offset to bci
     current_frame.set_offset(bci);
+    current_frame.set_mark();
 
     // Make sure every offset in stackmap table point to the beginning to
     // an instruction. Match current_frame to stackmap_table entry with
@@ -396,6 +648,7 @@
       stackmap_index, bci, &current_frame, &stackmap_table,
       no_control_flow, CHECK_VERIFY(this));
 
+
     bool this_uninit = false;  // Set to true when invokespecial <init> initialized 'this'
 
     // Merge with the next instruction
@@ -406,8 +659,8 @@
       VerificationType atype;
 
 #ifndef PRODUCT
-      if (_verify_verbose) {
-        current_frame.print();
+      if (VerboseVerification) {
+        current_frame.print_on(tty);
         tty->print_cr("offset = %d,  opcode = %s", bci, Bytecodes::name(opcode));
       }
 #endif
@@ -420,7 +673,10 @@
             opcode != Bytecodes::_lstore && opcode != Bytecodes::_fload  &&
             opcode != Bytecodes::_dload  && opcode != Bytecodes::_fstore &&
             opcode != Bytecodes::_dstore) {
-          verify_error(bci, "Bad wide instruction");
+          /* Unreachable?  RawBytecodeStream's raw_next() returns 'illegal'
+           * if we encounter a wide instruction that modifies an invalid
+           * opcode (not one of the ones listed above) */
+          verify_error(ErrorContext::bad_code(bci), "Bad wide instruction");
           return;
         }
       }
@@ -532,7 +788,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_int_array()) {
-            verify_error(bci, bad_type_msg, "iaload");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[I", THREAD)),
+                bad_type_msg, "iaload");
             return;
           }
           current_frame.push_stack(
@@ -544,7 +802,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_bool_array() && !atype.is_byte_array()) {
-            verify_error(bci, bad_type_msg, "baload");
+            verify_error(
+                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
+                bad_type_msg, "baload");
             return;
           }
           current_frame.push_stack(
@@ -556,7 +816,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_char_array()) {
-            verify_error(bci, bad_type_msg, "caload");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[C", THREAD)),
+                bad_type_msg, "caload");
             return;
           }
           current_frame.push_stack(
@@ -568,7 +830,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_short_array()) {
-            verify_error(bci, bad_type_msg, "saload");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[S", THREAD)),
+                bad_type_msg, "saload");
             return;
           }
           current_frame.push_stack(
@@ -580,7 +844,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_long_array()) {
-            verify_error(bci, bad_type_msg, "laload");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[J", THREAD)),
+                bad_type_msg, "laload");
             return;
           }
           current_frame.push_stack_2(
@@ -593,7 +859,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_float_array()) {
-            verify_error(bci, bad_type_msg, "faload");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[F", THREAD)),
+                bad_type_msg, "faload");
             return;
           }
           current_frame.push_stack(
@@ -605,7 +873,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_double_array()) {
-            verify_error(bci, bad_type_msg, "daload");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[D", THREAD)),
+                bad_type_msg, "daload");
             return;
           }
           current_frame.push_stack_2(
@@ -618,7 +888,10 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_reference_array()) {
-            verify_error(bci, bad_type_msg, "aaload");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(),
+                TypeOrigin::implicit(VerificationType::reference_check())),
+                bad_type_msg, "aaload");
             return;
           }
           if (atype.is_null()) {
@@ -689,7 +962,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_int_array()) {
-            verify_error(bci, bad_type_msg, "iastore");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[I", THREAD)),
+                bad_type_msg, "iastore");
             return;
           }
           no_control_flow = false; break;
@@ -701,7 +976,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_bool_array() && !atype.is_byte_array()) {
-            verify_error(bci, bad_type_msg, "bastore");
+            verify_error(
+                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
+                bad_type_msg, "bastore");
             return;
           }
           no_control_flow = false; break;
@@ -713,7 +990,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_char_array()) {
-            verify_error(bci, bad_type_msg, "castore");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[C", THREAD)),
+                bad_type_msg, "castore");
             return;
           }
           no_control_flow = false; break;
@@ -725,7 +1004,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_short_array()) {
-            verify_error(bci, bad_type_msg, "sastore");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[S", THREAD)),
+                bad_type_msg, "sastore");
             return;
           }
           no_control_flow = false; break;
@@ -738,7 +1019,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_long_array()) {
-            verify_error(bci, bad_type_msg, "lastore");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[J", THREAD)),
+                bad_type_msg, "lastore");
             return;
           }
           no_control_flow = false; break;
@@ -750,7 +1033,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_float_array()) {
-            verify_error(bci, bad_type_msg, "fastore");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[F", THREAD)),
+                bad_type_msg, "fastore");
             return;
           }
           no_control_flow = false; break;
@@ -763,7 +1048,9 @@
           atype = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!atype.is_double_array()) {
-            verify_error(bci, bad_type_msg, "dastore");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(), ref_ctx("[D", THREAD)),
+                bad_type_msg, "dastore");
             return;
           }
           no_control_flow = false; break;
@@ -775,7 +1062,10 @@
             VerificationType::reference_check(), CHECK_VERIFY(this));
           // more type-checking is done at runtime
           if (!atype.is_reference_array()) {
-            verify_error(bci, bad_type_msg, "aastore");
+            verify_error(ErrorContext::bad_type(bci,
+                current_frame.stack_top_ctx(),
+                TypeOrigin::implicit(VerificationType::reference_check())),
+                bad_type_msg, "aastore");
             return;
           }
           // 4938384: relaxed constraint in JVMS 3nd edition.
@@ -793,7 +1083,11 @@
             current_frame.pop_stack(
               VerificationType::category2_check(), CHECK_VERIFY(this));
           } else {
-            verify_error(bci, bad_type_msg, "pop2");
+            /* Unreachable? Would need a category2_1st on TOS
+             * which does not appear possible. */
+            verify_error(
+                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
+                bad_type_msg, "pop2");
             return;
           }
           no_control_flow = false; break;
@@ -825,7 +1119,10 @@
             type3 = current_frame.pop_stack(
               VerificationType::category2_check(), CHECK_VERIFY(this));
           } else {
-            verify_error(bci, bad_type_msg, "dup_x2");
+            /* Unreachable? Would need a category2_1st at stack depth 2 with
+             * a category1 on TOS which does not appear possible. */
+            verify_error(ErrorContext::bad_type(
+                bci, current_frame.stack_top_ctx()), bad_type_msg, "dup_x2");
             return;
           }
           current_frame.push_stack(type, CHECK_VERIFY(this));
@@ -843,7 +1140,11 @@
             type2 = current_frame.pop_stack(
               VerificationType::category2_check(), CHECK_VERIFY(this));
           } else {
-            verify_error(bci, bad_type_msg, "dup2");
+            /* Unreachable?  Would need a category2_1st on TOS which does not
+             * appear possible. */
+            verify_error(
+                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
+                bad_type_msg, "dup2");
             return;
           }
           current_frame.push_stack(type2, CHECK_VERIFY(this));
@@ -858,11 +1159,15 @@
           if (type.is_category1()) {
             type2 = current_frame.pop_stack(
               VerificationType::category1_check(), CHECK_VERIFY(this));
-          } else if(type.is_category2_2nd()) {
-            type2 = current_frame.pop_stack
-              (VerificationType::category2_check(), CHECK_VERIFY(this));
+          } else if (type.is_category2_2nd()) {
+            type2 = current_frame.pop_stack(
+              VerificationType::category2_check(), CHECK_VERIFY(this));
           } else {
-            verify_error(bci, bad_type_msg, "dup2_x1");
+            /* Unreachable?  Would need a category2_1st on TOS which does
+             * not appear possible. */
+            verify_error(
+                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
+                bad_type_msg, "dup2_x1");
             return;
           }
           type3 = current_frame.pop_stack(
@@ -885,7 +1190,11 @@
             type2 = current_frame.pop_stack(
               VerificationType::category2_check(), CHECK_VERIFY(this));
           } else {
-            verify_error(bci, bad_type_msg, "dup2_x2");
+            /* Unreachable?  Would need a category2_1st on TOS which does
+             * not appear possible. */
+            verify_error(
+                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
+                bad_type_msg, "dup2_x2");
             return;
           }
           type3 = current_frame.pop_stack(CHECK_VERIFY(this));
@@ -896,7 +1205,12 @@
             type4 = current_frame.pop_stack(
               VerificationType::category2_check(), CHECK_VERIFY(this));
           } else {
-            verify_error(bci, bad_type_msg, "dup2_x2");
+            /* Unreachable?  Would need a category2_1st on TOS after popping
+             * a long/double or two category 1's, which does not
+             * appear possible. */
+            verify_error(
+                ErrorContext::bad_type(bci, current_frame.stack_top_ctx()),
+                bad_type_msg, "dup2_x2");
             return;
           }
           current_frame.push_stack(type2, CHECK_VERIFY(this));
@@ -1176,43 +1490,50 @@
         case Bytecodes::_ireturn :
           type = current_frame.pop_stack(
             VerificationType::integer_type(), CHECK_VERIFY(this));
-          verify_return_value(return_type, type, bci, CHECK_VERIFY(this));
+          verify_return_value(return_type, type, bci,
+                              &current_frame, CHECK_VERIFY(this));
           no_control_flow = true; break;
         case Bytecodes::_lreturn :
           type2 = current_frame.pop_stack(
             VerificationType::long2_type(), CHECK_VERIFY(this));
           type = current_frame.pop_stack(
             VerificationType::long_type(), CHECK_VERIFY(this));
-          verify_return_value(return_type, type, bci, CHECK_VERIFY(this));
+          verify_return_value(return_type, type, bci,
+                              &current_frame, CHECK_VERIFY(this));
           no_control_flow = true; break;
         case Bytecodes::_freturn :
           type = current_frame.pop_stack(
             VerificationType::float_type(), CHECK_VERIFY(this));
-          verify_return_value(return_type, type, bci, CHECK_VERIFY(this));
+          verify_return_value(return_type, type, bci,
+                              &current_frame, CHECK_VERIFY(this));
           no_control_flow = true; break;
         case Bytecodes::_dreturn :
           type2 = current_frame.pop_stack(
             VerificationType::double2_type(),  CHECK_VERIFY(this));
           type = current_frame.pop_stack(
             VerificationType::double_type(), CHECK_VERIFY(this));
-          verify_return_value(return_type, type, bci, CHECK_VERIFY(this));
+          verify_return_value(return_type, type, bci,
+                              &current_frame, CHECK_VERIFY(this));
           no_control_flow = true; break;
         case Bytecodes::_areturn :
           type = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
-          verify_return_value(return_type, type, bci, CHECK_VERIFY(this));
+          verify_return_value(return_type, type, bci,
+                              &current_frame, CHECK_VERIFY(this));
           no_control_flow = true; break;
         case Bytecodes::_return :
           if (return_type != VerificationType::bogus_type()) {
-            verify_error(bci, "Method expects no return value");
+            verify_error(ErrorContext::bad_code(bci),
+                         "Method expects a return value");
             return;
           }
           // Make sure "this" has been initialized if current method is an
           // <init>
           if (_method->name() == vmSymbols::object_initializer_name() &&
               current_frame.flag_this_uninit()) {
-            verify_error(bci,
-              "Constructor must call super() or this() before return");
+            verify_error(ErrorContext::bad_code(bci),
+                         "Constructor must call super() or this() "
+                         "before return");
             return;
           }
           no_control_flow = true; break;
@@ -1239,11 +1560,13 @@
         case Bytecodes::_new :
         {
           index = bcs.get_index_u2();
-          verify_cp_class_type(index, cp, CHECK_VERIFY(this));
+          verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
           VerificationType new_class_type =
             cp_index_to_type(index, cp, CHECK_VERIFY(this));
           if (!new_class_type.is_object()) {
-            verify_error(bci, "Illegal new instruction");
+            verify_error(ErrorContext::bad_type(bci,
+                TypeOrigin::cp(index, new_class_type)),
+                "Illegal new instruction");
             return;
           }
           type = VerificationType::uninitialized_type(bci);
@@ -1258,13 +1581,15 @@
           no_control_flow = false; break;
         case Bytecodes::_anewarray :
           verify_anewarray(
-            bcs.get_index_u2(), cp, &current_frame, CHECK_VERIFY(this));
+            bci, bcs.get_index_u2(), cp, &current_frame, CHECK_VERIFY(this));
           no_control_flow = false; break;
         case Bytecodes::_arraylength :
           type = current_frame.pop_stack(
             VerificationType::reference_check(), CHECK_VERIFY(this));
           if (!(type.is_null() || type.is_array())) {
-            verify_error(bci, bad_type_msg, "arraylength");
+            verify_error(ErrorContext::bad_type(
+                bci, current_frame.stack_top_ctx()),
+                bad_type_msg, "arraylength");
           }
           current_frame.push_stack(
             VerificationType::integer_type(), CHECK_VERIFY(this));
@@ -1272,7 +1597,7 @@
         case Bytecodes::_checkcast :
         {
           index = bcs.get_index_u2();
-          verify_cp_class_type(index, cp, CHECK_VERIFY(this));
+          verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
           current_frame.pop_stack(object_type(), CHECK_VERIFY(this));
           VerificationType klass_type = cp_index_to_type(
             index, cp, CHECK_VERIFY(this));
@@ -1281,7 +1606,7 @@
         }
         case Bytecodes::_instanceof : {
           index = bcs.get_index_u2();
-          verify_cp_class_type(index, cp, CHECK_VERIFY(this));
+          verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
           current_frame.pop_stack(object_type(), CHECK_VERIFY(this));
           current_frame.push_stack(
             VerificationType::integer_type(), CHECK_VERIFY(this));
@@ -1296,17 +1621,18 @@
         {
           index = bcs.get_index_u2();
           u2 dim = *(bcs.bcp()+3);
-          verify_cp_class_type(index, cp, CHECK_VERIFY(this));
+          verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
           VerificationType new_array_type =
             cp_index_to_type(index, cp, CHECK_VERIFY(this));
           if (!new_array_type.is_array()) {
-            verify_error(bci,
-              "Illegal constant pool index in multianewarray instruction");
+            verify_error(ErrorContext::bad_type(bci,
+                TypeOrigin::cp(index, new_array_type)),
+                "Illegal constant pool index in multianewarray instruction");
             return;
           }
           if (dim < 1 || new_array_type.dimensions() < dim) {
-            verify_error(bci,
-              "Illegal dimension in multianewarray instruction");
+            verify_error(ErrorContext::bad_code(bci),
+                "Illegal dimension in multianewarray instruction: %d", dim);
             return;
           }
           for (int i = 0; i < dim; i++) {
@@ -1324,7 +1650,8 @@
         default:
           // We only need to check the valid bytecodes in class file.
           // And jsr and ret are not in the new class file format in JDK1.5.
-          verify_error(bci, "Bad instruction");
+          verify_error(ErrorContext::bad_code(bci),
+              "Bad instruction: %02x", opcode);
           no_control_flow = false;
           return;
       }  // end switch
@@ -1340,7 +1667,8 @@
 
   // Make sure that control flow does not fall through end of the method
   if (!no_control_flow) {
-    verify_error(code_length, "Control flow falls through code end");
+    verify_error(ErrorContext::bad_code(code_length),
+        "Control flow falls through code end");
     return;
   }
 }
@@ -1359,7 +1687,7 @@
         code_data[bci] = BYTECODE_OFFSET;
       }
     } else {
-      verify_error(bcs.bci(), "Bad instruction");
+      verify_error(ErrorContext::bad_code(bcs.bci()), "Bad instruction");
       return NULL;
     }
   }
@@ -1368,47 +1696,50 @@
 }
 
 void ClassVerifier::verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS) {
-  typeArrayHandle exhandlers (THREAD, _method->exception_table());
+  ExceptionTable exhandlers(_method());
+  int exlength = exhandlers.length();
   constantPoolHandle cp (THREAD, _method->constants());
 
-  if (exhandlers() != NULL) {
-    for(int i = 0; i < exhandlers->length();) {
-      u2 start_pc = exhandlers->int_at(i++);
-      u2 end_pc = exhandlers->int_at(i++);
-      u2 handler_pc = exhandlers->int_at(i++);
-      if (start_pc >= code_length || code_data[start_pc] == 0) {
-        class_format_error("Illegal exception table start_pc %d", start_pc);
-        return;
-      }
-      if (end_pc != code_length) {   // special case: end_pc == code_length
-        if (end_pc > code_length || code_data[end_pc] == 0) {
-          class_format_error("Illegal exception table end_pc %d", end_pc);
-          return;
-        }
-      }
-      if (handler_pc >= code_length || code_data[handler_pc] == 0) {
-        class_format_error("Illegal exception table handler_pc %d", handler_pc);
-        return;
-      }
-      int catch_type_index = exhandlers->int_at(i++);
-      if (catch_type_index != 0) {
-        VerificationType catch_type = cp_index_to_type(
-          catch_type_index, cp, CHECK_VERIFY(this));
-        VerificationType throwable =
-          VerificationType::reference_type(vmSymbols::java_lang_Throwable());
-        bool is_subclass = throwable.is_assignable_from(
-          catch_type, this, CHECK_VERIFY(this));
-        if (!is_subclass) {
-          // 4286534: should throw VerifyError according to recent spec change
-          verify_error(
-            "Catch type is not a subclass of Throwable in handler %d",
-            handler_pc);
-          return;
-        }
-      }
-      if (start_pc < min) min = start_pc;
-      if (end_pc > max) max = end_pc;
+  for(int i = 0; i < exlength; i++) {
+    //reacquire the table in case a GC happened
+    ExceptionTable exhandlers(_method());
+    u2 start_pc = exhandlers.start_pc(i);
+    u2 end_pc = exhandlers.end_pc(i);
+    u2 handler_pc = exhandlers.handler_pc(i);
+    if (start_pc >= code_length || code_data[start_pc] == 0) {
+      class_format_error("Illegal exception table start_pc %d", start_pc);
+      return;
     }
+    if (end_pc != code_length) {   // special case: end_pc == code_length
+      if (end_pc > code_length || code_data[end_pc] == 0) {
+        class_format_error("Illegal exception table end_pc %d", end_pc);
+        return;
+      }
+    }
+    if (handler_pc >= code_length || code_data[handler_pc] == 0) {
+      class_format_error("Illegal exception table handler_pc %d", handler_pc);
+      return;
+    }
+    int catch_type_index = exhandlers.catch_type_index(i);
+    if (catch_type_index != 0) {
+      VerificationType catch_type = cp_index_to_type(
+        catch_type_index, cp, CHECK_VERIFY(this));
+      VerificationType throwable =
+        VerificationType::reference_type(vmSymbols::java_lang_Throwable());
+      bool is_subclass = throwable.is_assignable_from(
+        catch_type, this, CHECK_VERIFY(this));
+      if (!is_subclass) {
+        // 4286534: should throw VerifyError according to recent spec change
+        verify_error(ErrorContext::bad_type(handler_pc,
+            TypeOrigin::cp(catch_type_index, catch_type),
+            TypeOrigin::implicit(throwable)),
+            "Catch type is not a subclass "
+            "of Throwable in exception handler %d", handler_pc);
+        return;
+      }
+    }
+    if (start_pc < min) min = start_pc;
+    if (end_pc > max) max = end_pc;
   }
 }
 
@@ -1443,19 +1774,21 @@
   if (stackmap_index < stackmap_table->get_frame_count()) {
     u2 this_offset = stackmap_table->get_offset(stackmap_index);
     if (no_control_flow && this_offset > bci) {
-      verify_error(bci, "Expecting a stack map frame");
+      verify_error(ErrorContext::missing_stackmap(bci),
+                   "Expecting a stack map frame");
       return 0;
     }
     if (this_offset == bci) {
+      ErrorContext ctx;
       // See if current stack map can be assigned to the frame in table.
       // current_frame is the stackmap frame got from the last instruction.
       // If matched, current_frame will be updated by this method.
-      bool match = stackmap_table->match_stackmap(
+      bool matches = stackmap_table->match_stackmap(
         current_frame, this_offset, stackmap_index,
-        !no_control_flow, true, CHECK_VERIFY_(this, 0));
-      if (!match) {
+        !no_control_flow, true, &ctx, CHECK_VERIFY_(this, 0));
+      if (!matches) {
         // report type error
-        verify_error(bci, "Instruction type does not match stack map");
+        verify_error(ctx, "Instruction type does not match stack map");
         return 0;
       }
       stackmap_index++;
@@ -1465,7 +1798,7 @@
       return 0;
     }
   } else if (no_control_flow) {
-    verify_error(bci, "Expecting a stack map frame");
+    verify_error(ErrorContext::bad_code(bci), "Expecting a stack map frame");
     return 0;
   }
   return stackmap_index;
@@ -1474,51 +1807,54 @@
 void ClassVerifier::verify_exception_handler_targets(u2 bci, bool this_uninit, StackMapFrame* current_frame,
                                                      StackMapTable* stackmap_table, TRAPS) {
   constantPoolHandle cp (THREAD, _method->constants());
-  typeArrayHandle exhandlers (THREAD, _method->exception_table());
-  if (exhandlers() != NULL) {
-    for(int i = 0; i < exhandlers->length();) {
-      u2 start_pc = exhandlers->int_at(i++);
-      u2 end_pc = exhandlers->int_at(i++);
-      u2 handler_pc = exhandlers->int_at(i++);
-      int catch_type_index = exhandlers->int_at(i++);
-      if(bci >= start_pc && bci < end_pc) {
-        u1 flags = current_frame->flags();
-        if (this_uninit) {  flags |= FLAG_THIS_UNINIT; }
-        StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
-        if (catch_type_index != 0) {
-          // We know that this index refers to a subclass of Throwable
-          VerificationType catch_type = cp_index_to_type(
-            catch_type_index, cp, CHECK_VERIFY(this));
-          new_frame->push_stack(catch_type, CHECK_VERIFY(this));
-        } else {
-          VerificationType throwable =
-            VerificationType::reference_type(vmSymbols::java_lang_Throwable());
-          new_frame->push_stack(throwable, CHECK_VERIFY(this));
-        }
-        bool match = stackmap_table->match_stackmap(
-          new_frame, handler_pc, true, false, CHECK_VERIFY(this));
-        if (!match) {
-          verify_error(bci,
-            "Stack map does not match the one at exception handler %d",
-            handler_pc);
-          return;
-        }
+  ExceptionTable exhandlers(_method());
+  int exlength = exhandlers.length();
+  for(int i = 0; i < exlength; i++) {
+    //reacquire the table in case a GC happened
+    ExceptionTable exhandlers(_method());
+    u2 start_pc = exhandlers.start_pc(i);
+    u2 end_pc = exhandlers.end_pc(i);
+    u2 handler_pc = exhandlers.handler_pc(i);
+    int catch_type_index = exhandlers.catch_type_index(i);
+    if(bci >= start_pc && bci < end_pc) {
+      u1 flags = current_frame->flags();
+      if (this_uninit) {  flags |= FLAG_THIS_UNINIT; }
+      StackMapFrame* new_frame = current_frame->frame_in_exception_handler(flags);
+      if (catch_type_index != 0) {
+        // We know that this index refers to a subclass of Throwable
+        VerificationType catch_type = cp_index_to_type(
+          catch_type_index, cp, CHECK_VERIFY(this));
+        new_frame->push_stack(catch_type, CHECK_VERIFY(this));
+      } else {
+        VerificationType throwable =
+          VerificationType::reference_type(vmSymbols::java_lang_Throwable());
+        new_frame->push_stack(throwable, CHECK_VERIFY(this));
+      }
+      ErrorContext ctx;
+      bool matches = stackmap_table->match_stackmap(
+        new_frame, handler_pc, true, false, &ctx, CHECK_VERIFY(this));
+      if (!matches) {
+        verify_error(ctx, "Stack map does not match the one at "
+            "exception handler %d", handler_pc);
+        return;
       }
     }
   }
 }
 
-void ClassVerifier::verify_cp_index(constantPoolHandle cp, int index, TRAPS) {
+void ClassVerifier::verify_cp_index(
+    u2 bci, constantPoolHandle cp, int index, TRAPS) {
   int nconstants = cp->length();
   if ((index <= 0) || (index >= nconstants)) {
-    verify_error("Illegal constant pool index %d in class %s",
-      index, instanceKlass::cast(cp->pool_holder())->external_name());
+    verify_error(ErrorContext::bad_cp_index(bci, index),
+        "Illegal constant pool index %d in class %s",
+        index, instanceKlass::cast(cp->pool_holder())->external_name());
     return;
   }
 }
 
 void ClassVerifier::verify_cp_type(
-    int index, constantPoolHandle cp, unsigned int types, TRAPS) {
+    u2 bci, int index, constantPoolHandle cp, unsigned int types, TRAPS) {
 
   // In some situations, bytecode rewriting may occur while we're verifying.
   // In this case, a constant pool cache exists and some indices refer to that
@@ -1526,10 +1862,10 @@
   // We must check was_recursively_verified() before we get here.
   guarantee(cp->cache() == NULL, "not rewritten yet");
 
-  verify_cp_index(cp, index, CHECK_VERIFY(this));
+  verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
   unsigned int tag = cp->tag_at(index).value();
   if ((types & (1 << tag)) == 0) {
-    verify_error(
+    verify_error(ErrorContext::bad_cp_index(bci, index),
       "Illegal type at constant pool entry %d in class %s",
       index, instanceKlass::cast(cp->pool_holder())->external_name());
     return;
@@ -1537,51 +1873,46 @@
 }
 
 void ClassVerifier::verify_cp_class_type(
-    int index, constantPoolHandle cp, TRAPS) {
-  verify_cp_index(cp, index, CHECK_VERIFY(this));
+    u2 bci, int index, constantPoolHandle cp, TRAPS) {
+  verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
   constantTag tag = cp->tag_at(index);
   if (!tag.is_klass() && !tag.is_unresolved_klass()) {
-    verify_error("Illegal type at constant pool entry %d in class %s",
-      index, instanceKlass::cast(cp->pool_holder())->external_name());
+    verify_error(ErrorContext::bad_cp_index(bci, index),
+        "Illegal type at constant pool entry %d in class %s",
+        index, instanceKlass::cast(cp->pool_holder())->external_name());
     return;
   }
 }
 
-void ClassVerifier::format_error_message(
-    const char* fmt, int offset, va_list va) {
-  ResourceMark rm(_thread);
-  stringStream message(_message, _message_buffer_len);
-  message.vprint(fmt, va);
-  if (!_method.is_null()) {
-    message.print(" in method %s", _method->name_and_sig_as_C_string());
-  }
-  if (offset != -1) {
-    message.print(" at offset %d", offset);
-  }
-}
+void ClassVerifier::verify_error(ErrorContext ctx, const char* msg, ...) {
+  stringStream ss;
 
-void ClassVerifier::verify_error(u2 offset, const char* fmt, ...) {
+  ctx.reset_frames();
   _exception_type = vmSymbols::java_lang_VerifyError();
+  _error_context = ctx;
   va_list va;
-  va_start(va, fmt);
-  format_error_message(fmt, offset, va);
+  va_start(va, msg);
+  ss.vprint(msg, va);
   va_end(va);
-}
-
-void ClassVerifier::verify_error(const char* fmt, ...) {
-  _exception_type = vmSymbols::java_lang_VerifyError();
-  va_list va;
-  va_start(va, fmt);
-  format_error_message(fmt, -1, va);
-  va_end(va);
+  _message = ss.as_string();
+#ifdef ASSERT
+  ResourceMark rm;
+  const char* exception_name = _exception_type->as_C_string();
+  Exceptions::debug_check_abort(exception_name, NULL);
+#endif // ndef ASSERT
 }
 
 void ClassVerifier::class_format_error(const char* msg, ...) {
+  stringStream ss;
   _exception_type = vmSymbols::java_lang_ClassFormatError();
   va_list va;
   va_start(va, msg);
-  format_error_message(msg, -1, va);
+  ss.vprint(msg, va);
   va_end(va);
+  if (!_method.is_null()) {
+    ss.print(" in method %s", _method->name_and_sig_as_C_string());
+  }
+  _message = ss.as_string();
 }
 
 klassOop ClassVerifier::load_class(Symbol* name, TRAPS) {
@@ -1617,7 +1948,7 @@
     }
   } else {
     klassOop member_klass = target_instance->find_field(field_name, field_sig, &fd);
-    if(member_klass != NULL && fd.is_protected()) {
+    if (member_klass != NULL && fd.is_protected()) {
       if (!this_class->is_same_class_package(member_klass)) {
         return true;
       }
@@ -1627,9 +1958,9 @@
 }
 
 void ClassVerifier::verify_ldc(
-    int opcode, u2 index, StackMapFrame *current_frame,
-     constantPoolHandle cp, u2 bci, TRAPS) {
-  verify_cp_index(cp, index, CHECK_VERIFY(this));
+    int opcode, u2 index, StackMapFrame* current_frame,
+    constantPoolHandle cp, u2 bci, TRAPS) {
+  verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
   constantTag tag = cp->tag_at(index);
   unsigned int types;
   if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) {
@@ -1639,12 +1970,12 @@
             | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType);
       // Note:  The class file parser already verified the legality of
       // MethodHandle and MethodType constants.
-      verify_cp_type(index, cp, types, CHECK_VERIFY(this));
+      verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this));
     }
   } else {
     assert(opcode == Bytecodes::_ldc2_w, "must be ldc2_w");
     types = (1 << JVM_CONSTANT_Double) | (1 << JVM_CONSTANT_Long);
-    verify_cp_type(index, cp, types, CHECK_VERIFY(this));
+    verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this));
   }
   if (tag.is_string() && cp->is_pseudo_string_at(index)) {
     current_frame->push_stack(object_type(), CHECK_VERIFY(this));
@@ -1679,7 +2010,9 @@
       VerificationType::reference_type(
         vmSymbols::java_lang_invoke_MethodType()), CHECK_VERIFY(this));
   } else {
-    verify_error(bci, "Invalid index in ldc");
+    /* Unreachable? verify_cp_type has already validated the cp type. */
+    verify_error(
+        ErrorContext::bad_cp_index(bci, index), "Invalid index in ldc");
     return;
   }
 }
@@ -1695,7 +2028,8 @@
   u2 padding_offset = 1;
   while ((bcp + padding_offset) < aligned_bcp) {
     if(*(bcp + padding_offset) != 0) {
-      verify_error(bci, "Nonzero padding byte in lookswitch or tableswitch");
+      verify_error(ErrorContext::bad_code(bci),
+                   "Nonzero padding byte in lookswitch or tableswitch");
       return;
     }
     padding_offset++;
@@ -1708,20 +2042,21 @@
     jint low = (jint)Bytes::get_Java_u4(aligned_bcp + jintSize);
     jint high = (jint)Bytes::get_Java_u4(aligned_bcp + 2*jintSize);
     if (low > high) {
-      verify_error(bci,
-        "low must be less than or equal to high in tableswitch");
+      verify_error(ErrorContext::bad_code(bci),
+          "low must be less than or equal to high in tableswitch");
       return;
     }
     keys = high - low + 1;
     if (keys < 0) {
-      verify_error(bci, "too many keys in tableswitch");
+      verify_error(ErrorContext::bad_code(bci), "too many keys in tableswitch");
       return;
     }
     delta = 1;
   } else {
     keys = (int)Bytes::get_Java_u4(aligned_bcp + jintSize);
     if (keys < 0) {
-      verify_error(bci, "number of keys in lookupswitch less than 0");
+      verify_error(ErrorContext::bad_code(bci),
+                   "number of keys in lookupswitch less than 0");
       return;
     }
     delta = 2;
@@ -1730,7 +2065,8 @@
       jint this_key = Bytes::get_Java_u4(aligned_bcp + (2+2*i)*jintSize);
       jint next_key = Bytes::get_Java_u4(aligned_bcp + (2+2*i+2)*jintSize);
       if (this_key >= next_key) {
-        verify_error(bci, "Bad lookupswitch instruction");
+        verify_error(ErrorContext::bad_code(bci),
+                     "Bad lookupswitch instruction");
         return;
       }
     }
@@ -1765,7 +2101,8 @@
                                               constantPoolHandle cp,
                                               TRAPS) {
   u2 index = bcs->get_index_u2();
-  verify_cp_type(index, cp, 1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this));
+  verify_cp_type(bcs->bci(), index, cp,
+      1 << JVM_CONSTANT_Fieldref, CHECK_VERIFY(this));
 
   // Get field name and signature
   Symbol* field_name = cp->name_ref_at(index);
@@ -1782,9 +2119,11 @@
   VerificationType ref_class_type = cp_ref_index_to_type(
     index, cp, CHECK_VERIFY(this));
   if (!ref_class_type.is_object()) {
-    verify_error(
-      "Expecting reference to class in class %s at constant pool index %d",
-      _klass->external_name(), index);
+    /* Unreachable?  Class file parser verifies Fieldref contents */
+    verify_error(ErrorContext::bad_type(bcs->bci(),
+        TypeOrigin::cp(index, ref_class_type)),
+        "Expecting reference to class in class %s at constant pool index %d",
+        _klass->external_name(), index);
     return;
   }
   VerificationType target_class_type = ref_class_type;
@@ -1842,7 +2181,10 @@
       is_assignable = target_class_type.is_assignable_from(
         stack_object_type, this, CHECK_VERIFY(this));
       if (!is_assignable) {
-        verify_error(bci, "Bad type on operand stack in putfield");
+        verify_error(ErrorContext::bad_type(bci,
+            current_frame->stack_top_ctx(),
+            TypeOrigin::cp(index, target_class_type)),
+            "Bad type on operand stack in putfield");
         return;
       }
     }
@@ -1866,7 +2208,10 @@
         is_assignable = current_type().is_assignable_from(
           stack_object_type, this, CHECK_VERIFY(this));
         if (!is_assignable) {
-          verify_error(bci, "Bad access to protected data in getfield");
+          verify_error(ErrorContext::bad_type(bci,
+              current_frame->stack_top_ctx(),
+              TypeOrigin::implicit(current_type())),
+              "Bad access to protected data in getfield");
           return;
         }
       }
@@ -1877,7 +2222,7 @@
 }
 
 void ClassVerifier::verify_invoke_init(
-    RawBytecodeStream* bcs, VerificationType ref_class_type,
+    RawBytecodeStream* bcs, u2 ref_class_index, VerificationType ref_class_type,
     StackMapFrame* current_frame, u4 code_length, bool *this_uninit,
     constantPoolHandle cp, TRAPS) {
   u2 bci = bcs->bci();
@@ -1888,7 +2233,10 @@
     klassOop superk = current_class()->super();
     if (ref_class_type.name() != current_class()->name() &&
         ref_class_type.name() != superk->klass_part()->name()) {
-      verify_error(bci, "Bad <init> method call");
+      verify_error(ErrorContext::bad_type(bci,
+          TypeOrigin::implicit(ref_class_type),
+          TypeOrigin::implicit(current_type())),
+          "Bad <init> method call");
       return;
     }
     current_frame->initialize_object(type, current_type());
@@ -1897,17 +2245,23 @@
     u2 new_offset = type.bci();
     address new_bcp = bcs->bcp() - bci + new_offset;
     if (new_offset > (code_length - 3) || (*new_bcp) != Bytecodes::_new) {
-      verify_error(new_offset, "Expecting new instruction");
+      /* Unreachable?  Stack map parsing ensures valid type and new
+       * instructions have a valid BCI. */
+      verify_error(ErrorContext::bad_code(new_offset),
+                   "Expecting new instruction");
       return;
     }
     u2 new_class_index = Bytes::get_Java_u2(new_bcp + 1);
-    verify_cp_class_type(new_class_index, cp, CHECK_VERIFY(this));
+    verify_cp_class_type(bci, new_class_index, cp, CHECK_VERIFY(this));
 
     // The method must be an <init> method of the indicated class
     VerificationType new_class_type = cp_index_to_type(
       new_class_index, cp, CHECK_VERIFY(this));
     if (!new_class_type.equals(ref_class_type)) {
-      verify_error(bci, "Call to wrong <init> method");
+      verify_error(ErrorContext::bad_type(bci,
+          TypeOrigin::cp(new_class_index, new_class_type),
+          TypeOrigin::cp(ref_class_index, ref_class_type)),
+          "Call to wrong <init> method");
       return;
     }
     // According to the VM spec, if the referent class is a superclass of the
@@ -1926,14 +2280,18 @@
         bool assignable = current_type().is_assignable_from(
           objectref_type, this, CHECK_VERIFY(this));
         if (!assignable) {
-          verify_error(bci, "Bad access to protected <init> method");
+          verify_error(ErrorContext::bad_type(bci,
+              TypeOrigin::cp(new_class_index, objectref_type),
+              TypeOrigin::implicit(current_type())),
+              "Bad access to protected <init> method");
           return;
         }
       }
     }
     current_frame->initialize_object(type, new_class_type);
   } else {
-    verify_error(bci, "Bad operand type when invoking <init>");
+    verify_error(ErrorContext::bad_type(bci, current_frame->stack_top_ctx()),
+        "Bad operand type when invoking <init>");
     return;
   }
 }
@@ -1950,7 +2308,7 @@
                       : opcode == Bytecodes::_invokedynamic
                                 ? 1 << JVM_CONSTANT_InvokeDynamic
                                 : 1 << JVM_CONSTANT_Methodref);
-  verify_cp_type(index, cp, types, CHECK_VERIFY(this));
+  verify_cp_type(bcs->bci(), index, cp, types, CHECK_VERIFY(this));
 
   // Get method name and signature
   Symbol* method_name = cp->name_ref_at(index);
@@ -2027,11 +2385,13 @@
     // the difference between the size of the operand stack before and after the instruction
     // executes.
     if (*(bcp+3) != (nargs+1)) {
-      verify_error(bci, "Inconsistent args count operand in invokeinterface");
+      verify_error(ErrorContext::bad_code(bci),
+          "Inconsistent args count operand in invokeinterface");
       return;
     }
     if (*(bcp+4) != 0) {
-      verify_error(bci, "Fourth operand byte of invokeinterface must be zero");
+      verify_error(ErrorContext::bad_code(bci),
+          "Fourth operand byte of invokeinterface must be zero");
       return;
     }
   }
@@ -2039,7 +2399,8 @@
   if (opcode == Bytecodes::_invokedynamic) {
     address bcp = bcs->bcp();
     if (*(bcp+3) != 0 || *(bcp+4) != 0) {
-      verify_error(bci, "Third and fourth operand bytes of invokedynamic must be zero");
+      verify_error(ErrorContext::bad_code(bci),
+          "Third and fourth operand bytes of invokedynamic must be zero");
       return;
     }
   }
@@ -2048,7 +2409,8 @@
     // Make sure <init> can only be invoked by invokespecial
     if (opcode != Bytecodes::_invokespecial ||
         method_name != vmSymbols::object_initializer_name()) {
-      verify_error(bci, "Illegal call to internal method");
+      verify_error(ErrorContext::bad_code(bci),
+          "Illegal call to internal method");
       return;
     }
   } else if (opcode == Bytecodes::_invokespecial
@@ -2058,7 +2420,8 @@
     bool subtype = ref_class_type.is_assignable_from(
       current_type(), this, CHECK_VERIFY(this));
     if (!subtype) {
-      verify_error(bci, "Bad invokespecial instruction: "
+      verify_error(ErrorContext::bad_code(bci),
+          "Bad invokespecial instruction: "
           "current class isn't assignable to reference class.");
        return;
     }
@@ -2071,7 +2434,7 @@
   if (opcode != Bytecodes::_invokestatic &&
       opcode != Bytecodes::_invokedynamic) {
     if (method_name == vmSymbols::object_initializer_name()) {  // <init> method
-      verify_invoke_init(bcs, ref_class_type, current_frame,
+      verify_invoke_init(bcs, index, ref_class_type, current_frame,
         code_length, this_uninit, cp, CHECK_VERIFY(this));
     } else {   // other methods
       // Ensures that target class is assignable to method class.
@@ -2101,8 +2464,10 @@
                   // Special case: arrays pretend to implement public Object
                   // clone().
                 } else {
-                  verify_error(bci,
-                    "Bad access to protected data in invokevirtual");
+                  verify_error(ErrorContext::bad_type(bci,
+                      current_frame->stack_top_ctx(),
+                      TypeOrigin::implicit(current_type())),
+                      "Bad access to protected data in invokevirtual");
                   return;
                 }
               }
@@ -2119,7 +2484,10 @@
   if (sig_stream.type() != T_VOID) {
     if (method_name == vmSymbols::object_initializer_name()) {
       // <init> method must have a void return type
-      verify_error(bci, "Return type must be void in <init> method");
+      /* Unreachable?  Class file parser verifies that methods with '<' have
+       * void return */
+      verify_error(ErrorContext::bad_code(bci),
+          "Return type must be void in <init> method");
       return;
     }
     VerificationType return_type[2];
@@ -2137,7 +2505,7 @@
     NULL, NULL, NULL, NULL, "[Z", "[C", "[F", "[D", "[B", "[S", "[I", "[J",
   };
   if (index < T_BOOLEAN || index > T_LONG) {
-    verify_error(bci, "Illegal newarray instruction");
+    verify_error(ErrorContext::bad_code(bci), "Illegal newarray instruction");
     return VerificationType::bogus_type();
   }
 
@@ -2148,8 +2516,9 @@
 }
 
 void ClassVerifier::verify_anewarray(
-    u2 index, constantPoolHandle cp, StackMapFrame* current_frame, TRAPS) {
-  verify_cp_class_type(index, cp, CHECK_VERIFY(this));
+    u2 bci, u2 index, constantPoolHandle cp,
+    StackMapFrame* current_frame, TRAPS) {
+  verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
   current_frame->pop_stack(
     VerificationType::integer_type(), CHECK_VERIFY(this));
 
@@ -2262,14 +2631,19 @@
 }
 
 void ClassVerifier::verify_return_value(
-    VerificationType return_type, VerificationType type, u2 bci, TRAPS) {
+    VerificationType return_type, VerificationType type, u2 bci,
+    StackMapFrame* current_frame, TRAPS) {
   if (return_type == VerificationType::bogus_type()) {
-    verify_error(bci, "Method expects a return value");
+    verify_error(ErrorContext::bad_type(bci,
+        current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
+        "Method expects a return value");
     return;
   }
   bool match = return_type.is_assignable_from(type, this, CHECK_VERIFY(this));
   if (!match) {
-    verify_error(bci, "Bad return type");
+    verify_error(ErrorContext::bad_type(bci,
+        current_frame->stack_top_ctx(), TypeOrigin::signature(return_type)),
+        "Bad return type");
     return;
   }
 }
diff --git a/hotspot/src/share/vm/classfile/verifier.hpp b/hotspot/src/share/vm/classfile/verifier.hpp
index 6686858..4457f4a 100644
--- a/hotspot/src/share/vm/classfile/verifier.hpp
+++ b/hotspot/src/share/vm/classfile/verifier.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -88,18 +88,178 @@
 #define CHECK_VERIFY_(verifier, result) \
   CHECK_(result)); if ((verifier)->has_error()) return (result); (0
 
+class TypeOrigin VALUE_OBJ_CLASS_SPEC {
+ private:
+  typedef enum {
+    CF_LOCALS,  // Comes from the current frame locals
+    CF_STACK,   // Comes from the current frame expression stack
+    SM_LOCALS,  // Comes from stackmap locals
+    SM_STACK,   // Comes from stackmap expression stack
+    CONST_POOL, // Comes from the constant pool
+    SIG,        // Comes from method signature
+    IMPLICIT,   // Comes implicitly from code or context
+    BAD_INDEX,  // No type, but the index is bad
+    FRAME_ONLY, // No type, context just contains the frame
+    NONE
+  } Origin;
+
+  Origin _origin;
+  u2 _index;              // local, stack, or constant pool index
+  StackMapFrame* _frame;  // source frame if CF or SM
+  VerificationType _type; // The actual type
+
+  TypeOrigin(
+      Origin origin, u2 index, StackMapFrame* frame, VerificationType type)
+      : _origin(origin), _index(index), _frame(frame), _type(type) {}
+
+ public:
+  TypeOrigin() : _origin(NONE), _index(0), _frame(NULL) {}
+
+  static TypeOrigin null();
+  static TypeOrigin local(u2 index, StackMapFrame* frame);
+  static TypeOrigin stack(u2 index, StackMapFrame* frame);
+  static TypeOrigin sm_local(u2 index, StackMapFrame* frame);
+  static TypeOrigin sm_stack(u2 index, StackMapFrame* frame);
+  static TypeOrigin cp(u2 index, VerificationType vt);
+  static TypeOrigin signature(VerificationType vt);
+  static TypeOrigin bad_index(u2 index);
+  static TypeOrigin implicit(VerificationType t);
+  static TypeOrigin frame(StackMapFrame* frame);
+
+  void reset_frame();
+  void details(outputStream* ss) const;
+  void print_frame(outputStream* ss) const;
+  const StackMapFrame* frame() const { return _frame; }
+  bool is_valid() const { return _origin != NONE; }
+  u2 index() const { return _index; }
+
+#ifdef ASSERT
+  void print_on(outputStream* str) const;
+#endif
+};
+
+class ErrorContext VALUE_OBJ_CLASS_SPEC {
+ private:
+  typedef enum {
+    INVALID_BYTECODE,     // There was a problem with the bytecode
+    WRONG_TYPE,           // Type value was not as expected
+    FLAGS_MISMATCH,       // Frame flags are not assignable
+    BAD_CP_INDEX,         // Invalid constant pool index
+    BAD_LOCAL_INDEX,      // Invalid local index
+    LOCALS_SIZE_MISMATCH, // Frames have differing local counts
+    STACK_SIZE_MISMATCH,  // Frames have different stack sizes
+    STACK_OVERFLOW,       // Attempt to push onto a full expression stack
+    STACK_UNDERFLOW,      // Attempt to pop and empty expression stack
+    MISSING_STACKMAP,     // No stackmap for this location and there should be
+    BAD_STACKMAP,         // Format error in stackmap
+    NO_FAULT,             // No error
+    UNKNOWN
+  } FaultType;
+
+  int _bci;
+  FaultType _fault;
+  TypeOrigin _type;
+  TypeOrigin _expected;
+
+  ErrorContext(int bci, FaultType fault) :
+      _bci(bci), _fault(fault)  {}
+  ErrorContext(int bci, FaultType fault, TypeOrigin type) :
+      _bci(bci), _fault(fault), _type(type)  {}
+  ErrorContext(int bci, FaultType fault, TypeOrigin type, TypeOrigin exp) :
+      _bci(bci), _fault(fault), _type(type), _expected(exp)  {}
+
+ public:
+  ErrorContext() : _bci(-1), _fault(NO_FAULT) {}
+
+  static ErrorContext bad_code(u2 bci) {
+    return ErrorContext(bci, INVALID_BYTECODE);
+  }
+  static ErrorContext bad_type(u2 bci, TypeOrigin type) {
+    return ErrorContext(bci, WRONG_TYPE, type);
+  }
+  static ErrorContext bad_type(u2 bci, TypeOrigin type, TypeOrigin exp) {
+    return ErrorContext(bci, WRONG_TYPE, type, exp);
+  }
+  static ErrorContext bad_flags(u2 bci, StackMapFrame* frame) {
+    return ErrorContext(bci, FLAGS_MISMATCH, TypeOrigin::frame(frame));
+  }
+  static ErrorContext bad_flags(u2 bci, StackMapFrame* cur, StackMapFrame* sm) {
+    return ErrorContext(bci, FLAGS_MISMATCH,
+                        TypeOrigin::frame(cur), TypeOrigin::frame(sm));
+  }
+  static ErrorContext bad_cp_index(u2 bci, u2 index) {
+    return ErrorContext(bci, BAD_CP_INDEX, TypeOrigin::bad_index(index));
+  }
+  static ErrorContext bad_local_index(u2 bci, u2 index) {
+    return ErrorContext(bci, BAD_LOCAL_INDEX, TypeOrigin::bad_index(index));
+  }
+  static ErrorContext locals_size_mismatch(
+      u2 bci, StackMapFrame* frame0, StackMapFrame* frame1) {
+    return ErrorContext(bci, LOCALS_SIZE_MISMATCH,
+        TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
+  }
+  static ErrorContext stack_size_mismatch(
+      u2 bci, StackMapFrame* frame0, StackMapFrame* frame1) {
+    return ErrorContext(bci, STACK_SIZE_MISMATCH,
+        TypeOrigin::frame(frame0), TypeOrigin::frame(frame1));
+  }
+  static ErrorContext stack_overflow(u2 bci, StackMapFrame* frame) {
+    return ErrorContext(bci, STACK_OVERFLOW, TypeOrigin::frame(frame));
+  }
+  static ErrorContext stack_underflow(u2 bci, StackMapFrame* frame) {
+    return ErrorContext(bci, STACK_UNDERFLOW, TypeOrigin::frame(frame));
+  }
+  static ErrorContext missing_stackmap(u2 bci) {
+    return ErrorContext(bci, MISSING_STACKMAP);
+  }
+  static ErrorContext bad_stackmap(int index, StackMapFrame* frame) {
+    return ErrorContext(0, BAD_STACKMAP, TypeOrigin::frame(frame));
+  }
+
+  bool is_valid() const { return _fault != NO_FAULT; }
+  int bci() const { return _bci; }
+
+  void reset_frames() {
+    _type.reset_frame();
+    _expected.reset_frame();
+  }
+
+  void details(outputStream* ss, methodOop method) const;
+
+#ifdef ASSERT
+  void print_on(outputStream* str) const {
+    str->print("error_context(%d, %d,", _bci, _fault);
+    _type.print_on(str);
+    str->print(",");
+    _expected.print_on(str);
+    str->print(")");
+  }
+#endif
+
+ private:
+  void location_details(outputStream* ss, methodOop method) const;
+  void reason_details(outputStream* ss) const;
+  void frame_details(outputStream* ss) const;
+  void bytecode_details(outputStream* ss, methodOop method) const;
+  void handler_details(outputStream* ss, methodOop method) const;
+  void stackmap_details(outputStream* ss, methodOop method) const;
+};
+
 // A new instance of this class is created for each class being verified
 class ClassVerifier : public StackObj {
  private:
   Thread* _thread;
+  GrowableArray<Symbol*>* _symbols;  // keep a list of symbols created
+
   Symbol* _exception_type;
   char* _message;
-  size_t _message_buffer_len;
-  GrowableArray<Symbol*>* _symbols;  // keep a list of symbols created
+
+  ErrorContext _error_context;  // contains information about an error
 
   void verify_method(methodHandle method, TRAPS);
   char* generate_code_data(methodHandle m, u4 code_length, TRAPS);
-  void verify_exception_handler_table(u4 code_length, char* code_data, int& min, int& max, TRAPS);
+  void verify_exception_handler_table(u4 code_length, char* code_data,
+                                      int& min, int& max, TRAPS);
   void verify_local_variable_table(u4 code_length, char* code_data, TRAPS);
 
   VerificationType cp_ref_index_to_type(
@@ -111,10 +271,10 @@
     instanceKlassHandle this_class, klassOop target_class,
     Symbol* field_name, Symbol* field_sig, bool is_method);
 
-  void verify_cp_index(constantPoolHandle cp, int index, TRAPS);
-  void verify_cp_type(
-    int index, constantPoolHandle cp, unsigned int types, TRAPS);
-  void verify_cp_class_type(int index, constantPoolHandle cp, TRAPS);
+  void verify_cp_index(u2 bci, constantPoolHandle cp, int index, TRAPS);
+  void verify_cp_type(u2 bci, int index, constantPoolHandle cp,
+      unsigned int types, TRAPS);
+  void verify_cp_class_type(u2 bci, int index, constantPoolHandle cp, TRAPS);
 
   u2 verify_stackmap_table(
     u2 stackmap_index, u2 bci, StackMapFrame* current_frame,
@@ -137,7 +297,7 @@
     constantPoolHandle cp, TRAPS);
 
   void verify_invoke_init(
-    RawBytecodeStream* bcs, VerificationType ref_class_type,
+    RawBytecodeStream* bcs, u2 ref_index, VerificationType ref_class_type,
     StackMapFrame* current_frame, u4 code_length, bool* this_uninit,
     constantPoolHandle cp, TRAPS);
 
@@ -147,10 +307,11 @@
     constantPoolHandle cp, TRAPS);
 
   VerificationType get_newarray_type(u2 index, u2 bci, TRAPS);
-  void verify_anewarray(
-    u2 index, constantPoolHandle cp, StackMapFrame* current_frame, TRAPS);
+  void verify_anewarray(u2 bci, u2 index, constantPoolHandle cp,
+      StackMapFrame* current_frame, TRAPS);
   void verify_return_value(
-    VerificationType return_type, VerificationType type, u2 offset, TRAPS);
+      VerificationType return_type, VerificationType type, u2 offset,
+      StackMapFrame* current_frame, TRAPS);
 
   void verify_iload (u2 index, StackMapFrame* current_frame, TRAPS);
   void verify_lload (u2 index, StackMapFrame* current_frame, TRAPS);
@@ -189,7 +350,7 @@
   };
 
   // constructor
-  ClassVerifier(instanceKlassHandle klass, char* msg, size_t msg_len, TRAPS);
+  ClassVerifier(instanceKlassHandle klass, TRAPS);
 
   // destructor
   ~ClassVerifier();
@@ -207,13 +368,17 @@
   // Return status modes
   Symbol* result() const { return _exception_type; }
   bool has_error() const { return result() != NULL; }
+  char* exception_message() {
+    stringStream ss;
+    ss.print(_message);
+    _error_context.details(&ss, _method());
+    return ss.as_string();
+  }
 
   // Called when verify or class format errors are encountered.
   // May throw an exception based upon the mode.
-  void verify_error(u2 offset, const char* fmt, ...);
-  void verify_error(const char* fmt, ...);
+  void verify_error(ErrorContext ctx, const char* fmt, ...);
   void class_format_error(const char* fmt, ...);
-  void format_error_message(const char* fmt, int offset, va_list args);
 
   klassOop load_class(Symbol* name, TRAPS);
 
@@ -228,10 +393,11 @@
   // their reference counts need to be decrememented when the verifier object
   // goes out of scope.  Since these symbols escape the scope in which they're
   // created, we can't use a TempNewSymbol.
-  Symbol* create_temporary_symbol(const Symbol* s, int begin, int end, TRAPS);
+  Symbol* create_temporary_symbol(
+      const Symbol* s, int begin, int end, TRAPS);
   Symbol* create_temporary_symbol(const char *s, int length, TRAPS);
 
-  static bool _verify_verbose;  // for debugging
+  TypeOrigin ref_ctx(const char* str, TRAPS);
 };
 
 inline int ClassVerifier::change_sig_to_verificationType(
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.cpp b/hotspot/src/share/vm/classfile/vmSymbols.cpp
index a0feab4..7dd5a2f 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.cpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -79,7 +79,7 @@
   if (!UseSharedSpaces) {
     const char* string = &vm_symbol_bodies[0];
     for (int index = (int)FIRST_SID; index < (int)SID_LIMIT; index++) {
-      Symbol* sym = SymbolTable::new_symbol(string, CHECK);
+      Symbol* sym = SymbolTable::new_permanent_symbol(string, CHECK);
       _symbols[index] = sym;
       string += strlen(string); // skip string body
       string += 1;              // skip trailing null
@@ -128,7 +128,7 @@
     // Spot-check correspondence between strings, symbols, and enums:
     assert(_symbols[NO_SID] == NULL, "must be");
     const char* str = "java/lang/Object";
-    TempNewSymbol jlo = SymbolTable::new_symbol(str, CHECK);
+    TempNewSymbol jlo = SymbolTable::new_permanent_symbol(str, CHECK);
     assert(strncmp(str, (char*)jlo->base(), jlo->utf8_length()) == 0, "");
     assert(jlo == java_lang_Object(), "");
     SID sid = VM_SYMBOL_ENUM_NAME(java_lang_Object);
@@ -147,7 +147,7 @@
     // The string "format" happens (at the moment) not to be a vmSymbol,
     // though it is a method name in java.lang.String.
     str = "format";
-    TempNewSymbol fmt = SymbolTable::new_symbol(str, CHECK);
+    TempNewSymbol fmt = SymbolTable::new_permanent_symbol(str, CHECK);
     sid = find_sid(fmt);
     assert(sid == NO_SID, "symbol index works (negative test)");
   }
@@ -324,17 +324,6 @@
   return vmIntrinsics::_none;
 }
 
-methodOop vmIntrinsics::method_for(vmIntrinsics::ID id) {
-  if (id == _none)  return NULL;
-  Symbol* cname = vmSymbols::symbol_at(class_for(id));
-  Symbol* mname = vmSymbols::symbol_at(name_for(id));
-  Symbol* msig  = vmSymbols::symbol_at(signature_for(id));
-  if (cname == NULL || mname == NULL || msig == NULL)  return NULL;
-  klassOop k = SystemDictionary::find_well_known_klass(cname);
-  if (k == NULL)  return NULL;
-  return instanceKlass::cast(k)->find_method(mname, msig);
-}
-
 
 #define VM_INTRINSIC_INITIALIZE(id, klass, name, sig, flags) #id "\0"
 static const char* vm_intrinsic_name_bodies =
diff --git a/hotspot/src/share/vm/classfile/vmSymbols.hpp b/hotspot/src/share/vm/classfile/vmSymbols.hpp
index d6beb93..16dd428 100644
--- a/hotspot/src/share/vm/classfile/vmSymbols.hpp
+++ b/hotspot/src/share/vm/classfile/vmSymbols.hpp
@@ -27,6 +27,7 @@
 
 #include "oops/symbol.hpp"
 #include "memory/iterator.hpp"
+#include "trace/traceMacros.hpp"
 
 // The class vmSymbols is a name space for fast lookup of
 // symbols commonly used in the VM.
@@ -109,6 +110,12 @@
   template(sun_jkernel_DownloadManager,               "sun/jkernel/DownloadManager")              \
   template(getBootClassPathEntryForClass_name,        "getBootClassPathEntryForClass")            \
   template(sun_misc_PostVMInitHook,                   "sun/misc/PostVMInitHook")                  \
+  template(sun_misc_Launcher_ExtClassLoader,          "sun/misc/Launcher$ExtClassLoader")         \
+                                                                                                  \
+  /* Java runtime version access */                                                               \
+  template(sun_misc_Version,                          "sun/misc/Version")                         \
+  template(java_runtime_name_name,                    "java_runtime_name")                        \
+  template(java_runtime_version_name,                 "java_runtime_version")                     \
                                                                                                   \
   /* class file format tags */                                                                    \
   template(tag_source_file,                           "SourceFile")                               \
@@ -155,6 +162,7 @@
   template(java_lang_NoSuchMethodException,           "java/lang/NoSuchMethodException")          \
   template(java_lang_NullPointerException,            "java/lang/NullPointerException")           \
   template(java_lang_StringIndexOutOfBoundsException, "java/lang/StringIndexOutOfBoundsException")\
+  template(java_lang_UnsupportedOperationException,   "java/lang/UnsupportedOperationException")  \
   template(java_lang_InvalidClassException,           "java/lang/InvalidClassException")          \
   template(java_lang_reflect_InvocationTargetException, "java/lang/reflect/InvocationTargetException") \
   template(java_lang_Exception,                       "java/lang/Exception")                      \
@@ -207,10 +215,12 @@
   template(newField_signature,                        "(Lsun/reflect/FieldInfo;)Ljava/lang/reflect/Field;") \
   template(newMethod_name,                            "newMethod")                                \
   template(newMethod_signature,                       "(Lsun/reflect/MethodInfo;)Ljava/lang/reflect/Method;") \
-  /* the following two names must be in order: */                                                 \
-  template(invokeExact_name,                          "invokeExact")                              \
-  template(invokeGeneric_name,                        "invokeGeneric")                            \
-  template(invokeVarargs_name,                        "invokeVarargs")                            \
+  template(invokeBasic_name,                          "invokeBasic")                              \
+  template(linkToVirtual_name,                        "linkToVirtual")                            \
+  template(linkToStatic_name,                         "linkToStatic")                             \
+  template(linkToSpecial_name,                        "linkToSpecial")                            \
+  template(linkToInterface_name,                      "linkToInterface")                          \
+  template(compiledLambdaForm_name,                   "<compiledLambdaForm>")  /*fake name*/      \
   template(star_name,                                 "*") /*not really a name*/                  \
   template(invoke_name,                               "invoke")                                   \
   template(override_name,                             "override")                                 \
@@ -231,36 +241,33 @@
   template(base_name,                                 "base")                                     \
                                                                                                   \
   /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */                                   \
-  template(java_lang_invoke_InvokeDynamic,            "java/lang/invoke/InvokeDynamic")           \
-  template(java_lang_invoke_Linkage,                  "java/lang/invoke/Linkage")                 \
   template(java_lang_invoke_CallSite,                 "java/lang/invoke/CallSite")                \
   template(java_lang_invoke_ConstantCallSite,         "java/lang/invoke/ConstantCallSite")        \
   template(java_lang_invoke_MutableCallSite,          "java/lang/invoke/MutableCallSite")         \
   template(java_lang_invoke_VolatileCallSite,         "java/lang/invoke/VolatileCallSite")        \
   template(java_lang_invoke_MethodHandle,             "java/lang/invoke/MethodHandle")            \
   template(java_lang_invoke_MethodType,               "java/lang/invoke/MethodType")              \
-  template(java_lang_invoke_WrongMethodTypeException, "java/lang/invoke/WrongMethodTypeException") \
   template(java_lang_invoke_MethodType_signature,     "Ljava/lang/invoke/MethodType;")            \
+  template(java_lang_invoke_MemberName_signature,     "Ljava/lang/invoke/MemberName;")            \
+  template(java_lang_invoke_LambdaForm_signature,     "Ljava/lang/invoke/LambdaForm;")            \
   template(java_lang_invoke_MethodHandle_signature,   "Ljava/lang/invoke/MethodHandle;")          \
   /* internal classes known only to the JVM: */                                                   \
-  template(java_lang_invoke_MethodTypeForm,           "java/lang/invoke/MethodTypeForm")          \
-  template(java_lang_invoke_MethodTypeForm_signature, "Ljava/lang/invoke/MethodTypeForm;")        \
   template(java_lang_invoke_MemberName,               "java/lang/invoke/MemberName")              \
   template(java_lang_invoke_MethodHandleNatives,      "java/lang/invoke/MethodHandleNatives")     \
-  template(java_lang_invoke_MethodHandleImpl,         "java/lang/invoke/MethodHandleImpl")        \
-  template(java_lang_invoke_AdapterMethodHandle,      "java/lang/invoke/AdapterMethodHandle")     \
-  template(java_lang_invoke_BoundMethodHandle,        "java/lang/invoke/BoundMethodHandle")       \
-  template(java_lang_invoke_DirectMethodHandle,       "java/lang/invoke/DirectMethodHandle")      \
-  template(java_lang_invoke_CountingMethodHandle,     "java/lang/invoke/CountingMethodHandle")    \
+  template(java_lang_invoke_LambdaForm,               "java/lang/invoke/LambdaForm")              \
+  template(java_lang_invoke_ForceInline_signature,    "Ljava/lang/invoke/ForceInline;")           \
+  template(java_lang_invoke_DontInline_signature,     "Ljava/lang/invoke/DontInline;")            \
+  template(java_lang_invoke_LambdaForm_Compiled_signature, "Ljava/lang/invoke/LambdaForm$Compiled;") \
+  template(java_lang_invoke_LambdaForm_Hidden_signature, "Ljava/lang/invoke/LambdaForm$Hidden;")  \
   /* internal up-calls made only by the JVM, via class sun.invoke.MethodHandleNatives: */         \
   template(findMethodHandleType_name,                 "findMethodHandleType")                     \
   template(findMethodHandleType_signature,       "(Ljava/lang/Class;[Ljava/lang/Class;)Ljava/lang/invoke/MethodType;") \
-  template(notifyGenericMethodType_name,              "notifyGenericMethodType")                  \
-  template(notifyGenericMethodType_signature,         "(Ljava/lang/invoke/MethodType;)V")         \
   template(linkMethodHandleConstant_name,             "linkMethodHandleConstant")                 \
   template(linkMethodHandleConstant_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;") \
-  template(makeDynamicCallSite_name,                  "makeDynamicCallSite")                      \
-  template(makeDynamicCallSite_signature, "(Ljava/lang/invoke/MethodHandle;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/Object;Ljava/lang/invoke/MemberName;I)Ljava/lang/invoke/CallSite;") \
+  template(linkMethod_name,                           "linkMethod")                               \
+  template(linkMethod_signature, "(Ljava/lang/Class;ILjava/lang/Class;Ljava/lang/String;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/invoke/MemberName;") \
+  template(linkCallSite_name,                         "linkCallSite")                             \
+  template(linkCallSite_signature, "(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/invoke/MemberName;") \
   template(setTargetNormal_name,                      "setTargetNormal")                          \
   template(setTargetVolatile_name,                    "setTargetVolatile")                        \
   template(setTarget_signature,                       "(Ljava/lang/invoke/MethodHandle;)V")       \
@@ -353,22 +360,15 @@
   template(toString_name,                             "toString")                                 \
   template(values_name,                               "values")                                   \
   template(receiver_name,                             "receiver")                                 \
-  template(vmmethod_name,                             "vmmethod")                                 \
   template(vmtarget_name,                             "vmtarget")                                 \
-  template(vmentry_name,                              "vmentry")                                  \
-  template(vmcount_name,                              "vmcount")                                  \
-  template(vmslots_name,                              "vmslots")                                  \
-  template(vmlayout_name,                             "vmlayout")                                 \
   template(vmindex_name,                              "vmindex")                                  \
-  template(vmargslot_name,                            "vmargslot")                                \
+  template(vmcount_name,                              "vmcount")                                  \
+  template(vmentry_name,                              "vmentry")                                  \
   template(flags_name,                                "flags")                                    \
-  template(argument_name,                             "argument")                                 \
-  template(conversion_name,                           "conversion")                               \
   template(rtype_name,                                "rtype")                                    \
   template(ptypes_name,                               "ptypes")                                   \
   template(form_name,                                 "form")                                     \
-  template(erasedType_name,                           "erasedType")                               \
-  template(genericInvoker_name,                       "genericInvoker")                           \
+  template(basicType_name,                            "basicType")                                \
   template(append_name,                               "append")                                   \
   template(klass_name,                                "klass")                                    \
   template(resolved_constructor_name,                 "resolved_constructor")                     \
@@ -427,6 +427,7 @@
   template(throwable_throwable_signature,             "(Ljava/lang/Throwable;)Ljava/lang/Throwable;")             \
   template(class_void_signature,                      "(Ljava/lang/Class;)V")                     \
   template(class_int_signature,                       "(Ljava/lang/Class;)I")                     \
+  template(class_long_signature,                      "(Ljava/lang/Class;)J")                     \
   template(class_boolean_signature,                   "(Ljava/lang/Class;)Z")                     \
   template(throwable_string_void_signature,           "(Ljava/lang/Throwable;Ljava/lang/String;)V")               \
   template(string_array_void_signature,               "([Ljava/lang/String;)V")                                   \
@@ -542,10 +543,12 @@
   template(serializePropertiesToByteArray_signature,   "()[B")                                                    \
   template(serializeAgentPropertiesToByteArray_name,   "serializeAgentPropertiesToByteArray")                     \
   template(classRedefinedCount_name,                   "classRedefinedCount")                                     \
+                                                                                                                  \
+  /* trace signatures */                                                                                          \
+  TRACE_TEMPLATES(template)                                                                                       \
+                                                                                                                  \
   /*end*/
 
-
-
 // Here are all the intrinsics known to the runtime and the CI.
 // Each intrinsic consists of a public enum name (like _hashCode),
 // followed by a specification of its klass, name, and signature:
@@ -651,6 +654,8 @@
   do_intrinsic(_nanoTime,                 java_lang_System,       nanoTime_name,          void_long_signature,   F_S)   \
    do_name(     nanoTime_name,                                   "nanoTime")                                            \
                                                                                                                         \
+  TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)                                             \
+                                                                                                                        \
   do_intrinsic(_arraycopy,                java_lang_System,       arraycopy_name, arraycopy_signature,           F_S)   \
    do_name(     arraycopy_name,                                  "arraycopy")                                           \
    do_signature(arraycopy_signature,                             "(Ljava/lang/Object;ILjava/lang/Object;II)V")          \
@@ -716,14 +721,20 @@
   /* java/lang/ref/Reference */                                                                                         \
   do_intrinsic(_Reference_get,            java_lang_ref_Reference, get_name,    void_object_signature, F_R)             \
                                                                                                                         \
+  /* support for com.sum.crypto.provider.AESCrypt and some of its callers */                                            \
+  do_class(com_sun_crypto_provider_aescrypt,      "com/sun/crypto/provider/AESCrypt")                                   \
+  do_intrinsic(_aescrypt_encryptBlock, com_sun_crypto_provider_aescrypt, encryptBlock_name, byteArray_int_byteArray_int_signature, F_R)   \
+  do_intrinsic(_aescrypt_decryptBlock, com_sun_crypto_provider_aescrypt, decryptBlock_name, byteArray_int_byteArray_int_signature, F_R)   \
+   do_name(     encryptBlock_name,                                 "encryptBlock")                                      \
+   do_name(     decryptBlock_name,                                 "decryptBlock")                                      \
+   do_signature(byteArray_int_byteArray_int_signature,             "([BI[BI)V")                                         \
                                                                                                                         \
-  do_class(sun_misc_AtomicLongCSImpl,     "sun/misc/AtomicLongCSImpl")                                                  \
-  do_intrinsic(_get_AtomicLong,           sun_misc_AtomicLongCSImpl, get_name, void_long_signature,              F_R)   \
-  /*   (symbols get_name and void_long_signature defined above) */                                                      \
-                                                                                                                        \
-  do_intrinsic(_attemptUpdate,            sun_misc_AtomicLongCSImpl, attemptUpdate_name, attemptUpdate_signature, F_R)  \
-   do_name(     attemptUpdate_name,                                 "attemptUpdate")                                    \
-   do_signature(attemptUpdate_signature,                            "(JJ)Z")                                            \
+  do_class(com_sun_crypto_provider_cipherBlockChaining,            "com/sun/crypto/provider/CipherBlockChaining")       \
+   do_intrinsic(_cipherBlockChaining_encryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, encrypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
+   do_intrinsic(_cipherBlockChaining_decryptAESCrypt, com_sun_crypto_provider_cipherBlockChaining, decrypt_name, byteArray_int_int_byteArray_int_signature, F_R)   \
+   do_name(     encrypt_name,                                      "encrypt")                                           \
+   do_name(     decrypt_name,                                      "decrypt")                                           \
+   do_signature(byteArray_int_int_byteArray_int_signature,         "([BII[BI)V")                                        \
                                                                                                                         \
   /* support for sun.misc.Unsafe */                                                                                     \
   do_class(sun_misc_Unsafe,               "sun/misc/Unsafe")                                                            \
@@ -875,6 +886,20 @@
    do_name(     putOrderedInt_name,                              "putOrderedInt")                                       \
    do_alias(    putOrderedInt_signature,                        /*(Ljava/lang/Object;JI)V*/ putInt_signature)           \
                                                                                                                         \
+  do_intrinsic(_getAndAddInt,             sun_misc_Unsafe,        getAndAddInt_name, getAndAddInt_signature, F_R)       \
+   do_name(     getAndAddInt_name,                                "getAndAddInt")                                       \
+   do_signature(getAndAddInt_signature,                           "(Ljava/lang/Object;JI)I" )                           \
+  do_intrinsic(_getAndAddLong,            sun_misc_Unsafe,        getAndAddLong_name, getAndAddLong_signature, F_R)     \
+   do_name(     getAndAddLong_name,                               "getAndAddLong")                                      \
+   do_signature(getAndAddLong_signature,                          "(Ljava/lang/Object;JJ)J" )                           \
+  do_intrinsic(_getAndSetInt,             sun_misc_Unsafe,        getAndSet_name, getAndSetInt_signature, F_R)          \
+   do_name(     getAndSet_name,                                   "getAndSet")                                          \
+   do_alias(    getAndSetInt_signature,                         /*"(Ljava/lang/Object;JI)I"*/ getAndAddInt_signature)   \
+  do_intrinsic(_getAndSetLong,            sun_misc_Unsafe,        getAndSet_name, getAndSetLong_signature, F_R)         \
+   do_alias(    getAndSetLong_signature,                        /*"(Ljava/lang/Object;JJ)J"*/ getAndAddLong_signature)  \
+  do_intrinsic(_getAndSetObject,          sun_misc_Unsafe,        getAndSet_name, getAndSetObject_signature,  F_R)      \
+   do_signature(getAndSetObject_signature,                        "(Ljava/lang/Object;JLjava/lang/Object;)Ljava/lang/Object;" ) \
+                                                                                                                        \
   /* prefetch_signature is shared by all prefetch variants */                                                           \
   do_signature( prefetch_signature,        "(Ljava/lang/Object;J)V")                                                    \
                                                                                                                         \
@@ -920,15 +945,15 @@
                                                                                                                           \
   do_intrinsic(_invoke,                   java_lang_reflect_Method, invoke_name, object_object_array_object_signature, F_R) \
   /*   (symbols invoke_name and invoke_signature defined above) */                                                      \
-  do_intrinsic(_checkSpreadArgument,      java_lang_invoke_MethodHandleNatives, checkSpreadArgument_name, checkSpreadArgument_signature, F_S) \
-   do_name(    checkSpreadArgument_name,       "checkSpreadArgument")                                                   \
-   do_name(    checkSpreadArgument_signature,  "(Ljava/lang/Object;I)V")                                                \
-  do_intrinsic(_invokeExact,              java_lang_invoke_MethodHandle, invokeExact_name,   object_array_object_signature, F_RN) \
-  do_intrinsic(_invokeGeneric,            java_lang_invoke_MethodHandle, invokeGeneric_name, object_array_object_signature, F_RN) \
-  do_intrinsic(_invokeVarargs,            java_lang_invoke_MethodHandle, invokeVarargs_name, object_array_object_signature, F_R)  \
-  do_intrinsic(_invokeDynamic,            java_lang_invoke_InvokeDynamic, star_name,         object_array_object_signature, F_SN) \
-                                                                                                                        \
-  do_intrinsic(_selectAlternative,        java_lang_invoke_MethodHandleImpl, selectAlternative_name, selectAlternative_signature, F_S)  \
+  /* the polymorphic MH intrinsics must be in compact order, with _invokeGeneric first and _linkToInterface last */     \
+  do_intrinsic(_invokeGeneric,            java_lang_invoke_MethodHandle, invoke_name,           star_name, F_RN)        \
+  do_intrinsic(_invokeBasic,              java_lang_invoke_MethodHandle, invokeBasic_name,      star_name, F_RN)        \
+  do_intrinsic(_linkToVirtual,            java_lang_invoke_MethodHandle, linkToVirtual_name,    star_name, F_SN)        \
+  do_intrinsic(_linkToStatic,             java_lang_invoke_MethodHandle, linkToStatic_name,     star_name, F_SN)        \
+  do_intrinsic(_linkToSpecial,            java_lang_invoke_MethodHandle, linkToSpecial_name,    star_name, F_SN)        \
+  do_intrinsic(_linkToInterface,          java_lang_invoke_MethodHandle, linkToInterface_name,  star_name, F_SN)        \
+  /* special marker for bytecode generated for the JVM from a LambdaForm: */                                            \
+  do_intrinsic(_compiledLambdaForm,       java_lang_invoke_MethodHandle, compiledLambdaForm_name, star_name, F_RN)      \
                                                                                                                         \
   /* unboxing methods: */                                                                                               \
   do_intrinsic(_booleanValue,             java_lang_Boolean,      booleanValue_name, void_boolean_signature, F_R)       \
@@ -1061,6 +1086,10 @@
 
     ID_LIMIT,
     LAST_COMPILER_INLINE = _prefetchWriteStatic,
+    FIRST_MH_SIG_POLY    = _invokeGeneric,
+    FIRST_MH_STATIC      = _linkToVirtual,
+    LAST_MH_SIG_POLY     = _linkToInterface,
+
     FIRST_ID = _none + 1
   };
 
@@ -1122,9 +1151,6 @@
 
   static const char* short_name_as_C_string(ID id, char* buf, int size);
 
-  // Access to intrinsic methods:
-  static methodOop method_for(ID id);
-
   // Wrapper object methods:
   static ID for_boxing(BasicType type);
   static ID for_unboxing(BasicType type);
diff --git a/hotspot/src/share/vm/code/codeBlob.cpp b/hotspot/src/share/vm/code/codeBlob.cpp
index 244c320..ea35735 100644
--- a/hotspot/src/share/vm/code/codeBlob.cpp
+++ b/hotspot/src/share/vm/code/codeBlob.cpp
@@ -144,7 +144,7 @@
   // chunk of memory, its your job to free it.
   if (p != NULL) {
     // We need to allocate a chunk big enough to hold the OopMapSet and all of its OopMaps
-    _oop_maps = (OopMapSet* )NEW_C_HEAP_ARRAY(unsigned char, p->heap_size());
+    _oop_maps = (OopMapSet* )NEW_C_HEAP_ARRAY(unsigned char, p->heap_size(), mtCode);
     p->copy_to((address)_oop_maps);
   } else {
     _oop_maps = NULL;
@@ -161,8 +161,10 @@
     assert(strlen(name1) + strlen(name2) < sizeof(stub_id), "");
     jio_snprintf(stub_id, sizeof(stub_id), "%s%s", name1, name2);
     if (PrintStubCode) {
+      ttyLocker ttyl;
       tty->print_cr("Decoding %s " INTPTR_FORMAT, stub_id, (intptr_t) stub);
       Disassembler::decode(stub->code_begin(), stub->code_end());
+      tty->cr();
     }
     Forte::register_stub(stub_id, stub->code_begin(), stub->code_end());
 
@@ -180,7 +182,7 @@
 
 void CodeBlob::flush() {
   if (_oop_maps) {
-    FREE_C_HEAP_ARRAY(unsigned char, _oop_maps);
+    FREE_C_HEAP_ARRAY(unsigned char, _oop_maps, mtCode);
     _oop_maps = NULL;
   }
   _comments.free();
@@ -359,43 +361,6 @@
 
 
 //----------------------------------------------------------------------------------------------------
-// Implementation of RicochetBlob
-
-RicochetBlob::RicochetBlob(
-  CodeBuffer* cb,
-  int         size,
-  int         bounce_offset,
-  int         exception_offset,
-  int         frame_size
-)
-: SingletonBlob("RicochetBlob", cb, sizeof(RicochetBlob), size, frame_size, (OopMapSet*) NULL)
-{
-  _bounce_offset = bounce_offset;
-  _exception_offset = exception_offset;
-}
-
-
-RicochetBlob* RicochetBlob::create(
-  CodeBuffer* cb,
-  int         bounce_offset,
-  int         exception_offset,
-  int         frame_size)
-{
-  RicochetBlob* blob = NULL;
-  ThreadInVMfromUnknown __tiv;  // get to VM state in case we block on CodeCache_lock
-  {
-    MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
-    unsigned int size = allocation_size(cb, sizeof(RicochetBlob));
-    blob = new (size) RicochetBlob(cb, size, bounce_offset, exception_offset, frame_size);
-  }
-
-  trace_new_stub(blob, "RicochetBlob");
-
-  return blob;
-}
-
-
-//----------------------------------------------------------------------------------------------------
 // Implementation of DeoptimizationBlob
 
 DeoptimizationBlob::DeoptimizationBlob(
@@ -584,6 +549,7 @@
 }
 
 void RuntimeStub::print_on(outputStream* st) const {
+  ttyLocker ttyl;
   CodeBlob::print_on(st);
   st->print("Runtime Stub (" INTPTR_FORMAT "): ", this);
   st->print_cr(name());
@@ -599,6 +565,7 @@
 }
 
 void SingletonBlob::print_on(outputStream* st) const {
+  ttyLocker ttyl;
   CodeBlob::print_on(st);
   st->print_cr(name());
   Disassembler::decode((CodeBlob*)this, st);
diff --git a/hotspot/src/share/vm/code/codeBlob.hpp b/hotspot/src/share/vm/code/codeBlob.hpp
index d653794..472387e 100644
--- a/hotspot/src/share/vm/code/codeBlob.hpp
+++ b/hotspot/src/share/vm/code/codeBlob.hpp
@@ -35,7 +35,6 @@
 // Suptypes are:
 //   nmethod            : Compiled Java methods (include method that calls to native code)
 //   RuntimeStub        : Call to VM runtime methods
-//   RicochetBlob       : Used for blocking MethodHandle adapters
 //   DeoptimizationBlob : Used for deoptimizatation
 //   ExceptionBlob      : Used for stack unrolling
 //   SafepointBlob      : Used to handle illegal instruction exceptions
@@ -99,7 +98,6 @@
   virtual bool is_buffer_blob() const            { return false; }
   virtual bool is_nmethod() const                { return false; }
   virtual bool is_runtime_stub() const           { return false; }
-  virtual bool is_ricochet_stub() const          { return false; }
   virtual bool is_deoptimization_stub() const    { return false; }
   virtual bool is_uncommon_trap_stub() const     { return false; }
   virtual bool is_exception_stub() const         { return false; }
@@ -188,7 +186,7 @@
   static void trace_new_stub(CodeBlob* blob, const char* name1, const char* name2 = "");
 
   // Print the comment associated with offset on stream, if there is one
-  virtual void print_block_comment(outputStream* stream, address block_begin) {
+  virtual void print_block_comment(outputStream* stream, address block_begin) const {
     intptr_t offset = (intptr_t)(block_begin - code_begin());
     _comments.print_block_comment(stream, offset);
   }
@@ -350,50 +348,6 @@
 
 
 //----------------------------------------------------------------------------------------------------
-// RicochetBlob
-// Holds an arbitrary argument list indefinitely while Java code executes recursively.
-
-class RicochetBlob: public SingletonBlob {
-  friend class VMStructs;
- private:
-
-  int _bounce_offset;
-  int _exception_offset;
-
-  // Creation support
-  RicochetBlob(
-    CodeBuffer* cb,
-    int         size,
-    int         bounce_offset,
-    int         exception_offset,
-    int         frame_size
-  );
-
- public:
-  // Creation
-  static RicochetBlob* create(
-    CodeBuffer* cb,
-    int         bounce_offset,
-    int         exception_offset,
-    int         frame_size
-  );
-
-  // Typing
-  bool is_ricochet_stub() const { return true; }
-
-  // GC for args
-  void preserve_callee_argument_oops(frame fr, const RegisterMap *reg_map, OopClosure* f) { /* Nothing to do */ }
-
-  address bounce_addr() const           { return code_begin() + _bounce_offset; }
-  address exception_addr() const        { return code_begin() + _exception_offset; }
-  bool returns_to_bounce_addr(address pc) const {
-    address bounce_pc = bounce_addr();
-    return (pc == bounce_pc || (pc + frame::pc_return_offset) == bounce_pc);
-  }
-};
-
-
-//----------------------------------------------------------------------------------------------------
 // DeoptimizationBlob
 
 class DeoptimizationBlob: public SingletonBlob {
diff --git a/hotspot/src/share/vm/code/codeCache.cpp b/hotspot/src/share/vm/code/codeCache.cpp
index 8e82aaa..200b6c6 100644
--- a/hotspot/src/share/vm/code/codeCache.cpp
+++ b/hotspot/src/share/vm/code/codeCache.cpp
@@ -796,7 +796,6 @@
   int nmethodCount = 0;
   int runtimeStubCount = 0;
   int adapterCount = 0;
-  int ricochetStubCount = 0;
   int deoptimizationStubCount = 0;
   int uncommonTrapStubCount = 0;
   int bufferBlobCount = 0;
@@ -841,8 +840,6 @@
       }
     } else if (cb->is_runtime_stub()) {
       runtimeStubCount++;
-    } else if (cb->is_ricochet_stub()) {
-      ricochetStubCount++;
     } else if (cb->is_deoptimization_stub()) {
       deoptimizationStubCount++;
     } else if (cb->is_uncommon_trap_stub()) {
@@ -856,7 +853,7 @@
 
   int bucketSize = 512;
   int bucketLimit = maxCodeSize / bucketSize + 1;
-  int *buckets = NEW_C_HEAP_ARRAY(int, bucketLimit);
+  int *buckets = NEW_C_HEAP_ARRAY(int, bucketLimit, mtCode);
   memset(buckets,0,sizeof(int) * bucketLimit);
 
   for (cb = first(); cb != NULL; cb = next(cb)) {
@@ -879,7 +876,6 @@
   tty->print_cr("runtime_stubs: %d",runtimeStubCount);
   tty->print_cr("adapters: %d",adapterCount);
   tty->print_cr("buffer blobs: %d",bufferBlobCount);
-  tty->print_cr("ricochet_stubs: %d",ricochetStubCount);
   tty->print_cr("deoptimization_stubs: %d",deoptimizationStubCount);
   tty->print_cr("uncommon_traps: %d",uncommonTrapStubCount);
   tty->print_cr("\nnmethod size distribution (non-zombie java)");
@@ -893,7 +889,7 @@
     }
   }
 
-  FREE_C_HEAP_ARRAY(int, buckets);
+  FREE_C_HEAP_ARRAY(int, buckets, mtCode);
 }
 
 void CodeCache::print() {
diff --git a/hotspot/src/share/vm/code/codeCache.hpp b/hotspot/src/share/vm/code/codeCache.hpp
index bdd128e..6c97cc7 100644
--- a/hotspot/src/share/vm/code/codeCache.hpp
+++ b/hotspot/src/share/vm/code/codeCache.hpp
@@ -88,6 +88,9 @@
   // Lookup that does not fail if you lookup a zombie method (if you call this, be sure to know
   // what you are doing)
   static CodeBlob* find_blob_unsafe(void* start) {
+    // NMT can walk the stack before code cache is created
+    if (_heap == NULL) return NULL;
+
     CodeBlob* result = (CodeBlob*)_heap->find_start(start);
     // this assert is too strong because the heap code will return the
     // heapblock containing start. That block can often be larger than
diff --git a/hotspot/src/share/vm/code/debugInfoRec.cpp b/hotspot/src/share/vm/code/debugInfoRec.cpp
index bc8bd55..130b317 100644
--- a/hotspot/src/share/vm/code/debugInfoRec.cpp
+++ b/hotspot/src/share/vm/code/debugInfoRec.cpp
@@ -311,6 +311,7 @@
   assert(method == NULL ||
          (method->is_native() && bci == 0) ||
          (!method->is_native() && 0 <= bci && bci < method->code_size()) ||
+         (method->is_compiled_lambda_form() && bci == -99) ||  // this might happen in C1
          bci == -1, "illegal bci");
 
   // serialize the locals/expressions/monitors
diff --git a/hotspot/src/share/vm/code/dependencies.cpp b/hotspot/src/share/vm/code/dependencies.cpp
index a3fd99e..fe3483d 100644
--- a/hotspot/src/share/vm/code/dependencies.cpp
+++ b/hotspot/src/share/vm/code/dependencies.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -622,7 +622,15 @@
 }
 
 oop Dependencies::DepStream::argument(int i) {
-  return recorded_oop_at(argument_index(i));
+  oop result = recorded_oop_at(argument_index(i));
+  if (result == NULL) { // Explicit context argument can be compressed
+    int ctxkj = dep_context_arg(type());  // -1 if no explicit context arg
+     if (ctxkj >= 0 && i == ctxkj && ctxkj+1 < argument_count()) {
+       result = ctxk_encoded_as_null(type(), argument(ctxkj+1));
+     }
+  }
+
+  return result;
 }
 
 klassOop Dependencies::DepStream::context_type() {
@@ -630,25 +638,21 @@
 
   // Most dependencies have an explicit context type argument.
   {
-    int ctxkj = dep_context_arg(_type);  // -1 if no explicit context arg
+    int ctxkj = dep_context_arg(type());  // -1 if no explicit context arg
     if (ctxkj >= 0) {
       oop k = argument(ctxkj);
-      if (k != NULL) {       // context type was not compressed away
-        assert(k->is_klass(), "type check");
-        return (klassOop) k;
-      }
-      // recompute "default" context type
-      return ctxk_encoded_as_null(_type, argument(ctxkj+1));
+      assert(k != NULL && k->is_klass(), "type check");
+      return (klassOop) k;
     }
   }
 
   // Some dependencies are using the klass of the first object
   // argument as implicit context type (e.g. call_site_target_value).
   {
-    int ctxkj = dep_implicit_context_arg(_type);
+    int ctxkj = dep_implicit_context_arg(type());
     if (ctxkj >= 0) {
       oop k = argument(ctxkj)->klass();
-      assert(k->is_klass(), "type check");
+      assert(k != NULL && k->is_klass(), "type check");
       return (klassOop) k;
     }
   }
@@ -1033,21 +1037,25 @@
     // (Old CHA had the same limitation.)
     return context_type;
   }
-  for (int i = 0; i < nof_impls; i++) {
-    klassOop impl = instanceKlass::cast(context_type)->implementor(i);
-    if (impl == NULL) {
-      // implementors array overflowed => no exact info.
+  if (nof_impls > 0) {
+    klassOop impl = instanceKlass::cast(context_type)->implementor();
+    assert(impl != NULL, "just checking");
+    // If impl is the same as the context_type, then more than one
+    // implementor has seen. No exact info in this case.
+    if (impl == context_type) {
       return context_type;  // report an inexact witness to this sad affair
     }
     if (do_counts)
       { NOT_PRODUCT(deps_find_witness_steps++); }
     if (is_participant(impl)) {
-      if (participants_hide_witnesses)  continue;
-      // else fall through to process this guy's subclasses
+      if (!participants_hide_witnesses) {
+        ADD_SUBCLASS_CHAIN(impl);
+      }
     } else if (is_witness(impl) && !ignore_witness(impl)) {
       return impl;
+    } else {
+      ADD_SUBCLASS_CHAIN(impl);
     }
-    ADD_SUBCLASS_CHAIN(impl);
   }
 
   // Recursively process each non-trivial sibling chain.
@@ -1174,8 +1182,9 @@
   } else if (ctx->nof_implementors() != 0) {
     // if it is an interface, it must be unimplemented
     // (if it is not an interface, nof_implementors is always zero)
-    klassOop impl = ctx->implementor(0);
-    return (impl != NULL)? impl: ctxk;
+    klassOop impl = ctx->implementor();
+    assert(impl != NULL, "must be set");
+    return impl;
   } else {
     return NULL;
   }
diff --git a/hotspot/src/share/vm/code/icBuffer.hpp b/hotspot/src/share/vm/code/icBuffer.hpp
index 9ab7d9c..4934c00 100644
--- a/hotspot/src/share/vm/code/icBuffer.hpp
+++ b/hotspot/src/share/vm/code/icBuffer.hpp
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_CODE_ICBUFFER_HPP
 #define SHARE_VM_CODE_ICBUFFER_HPP
 
+#include "asm/codeBuffer.hpp"
 #include "code/stubs.hpp"
 #include "interpreter/bytecodes.hpp"
 #include "memory/allocation.hpp"
@@ -48,7 +49,8 @@
  protected:
   friend class ICStubInterface;
   // This will be called only by ICStubInterface
-  void    initialize(int size) { _size = size; _ic_site = NULL; }
+  void    initialize(int size,
+                     CodeComments comments)      { _size = size; _ic_site = NULL; }
   void    finalize(); // called when a method is removed
 
   // General info
diff --git a/hotspot/src/share/vm/code/nmethod.cpp b/hotspot/src/share/vm/code/nmethod.cpp
index 65ee2b5..21c9413 100644
--- a/hotspot/src/share/vm/code/nmethod.cpp
+++ b/hotspot/src/share/vm/code/nmethod.cpp
@@ -463,6 +463,7 @@
   _has_unsafe_access          = 0;
   _has_method_handle_invokes  = 0;
   _lazy_critical_native       = 0;
+  _has_wide_vectors           = 0;
   _marked_for_deoptimization  = 0;
   _lock_count                 = 0;
   _stack_traversal_mark       = 0;
@@ -696,7 +697,9 @@
     // then print the requested information
     if (PrintNativeNMethods) {
       print_code();
-      oop_maps->print();
+      if (oop_maps != NULL) {
+        oop_maps->print();
+      }
     }
     if (PrintRelocations) {
       print_relocations();
@@ -945,8 +948,12 @@
 void nmethod::print_on(outputStream* st, const char* msg) const {
   if (st != NULL) {
     ttyLocker ttyl;
-    CompileTask::print_compilation(st, this, msg);
-    if (WizardMode) st->print(" (" INTPTR_FORMAT ")", this);
+    if (WizardMode) {
+      CompileTask::print_compilation(st, this, msg, /*short_form:*/ true);
+      st->print_cr(" (" INTPTR_FORMAT ")", this);
+    } else {
+      CompileTask::print_compilation(st, this, msg, /*short_form:*/ false);
+    }
   }
 }
 
@@ -964,7 +971,9 @@
   if (printmethod) {
     print_code();
     print_pcs();
-    oop_maps()->print();
+    if (oop_maps()) {
+      oop_maps()->print();
+    }
   }
   if (PrintDebugInfo) {
     print_scopes();
@@ -2549,7 +2558,7 @@
   return NULL;
 }
 
-void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) {
+void nmethod::print_nmethod_labels(outputStream* stream, address block_begin) const {
   if (block_begin == entry_point())             stream->print_cr("[Entry Point]");
   if (block_begin == verified_entry_point())    stream->print_cr("[Verified Entry Point]");
   if (block_begin == exception_begin())         stream->print_cr("[Exception Handler]");
diff --git a/hotspot/src/share/vm/code/nmethod.hpp b/hotspot/src/share/vm/code/nmethod.hpp
index cad0eed..8d76afb 100644
--- a/hotspot/src/share/vm/code/nmethod.hpp
+++ b/hotspot/src/share/vm/code/nmethod.hpp
@@ -31,7 +31,7 @@
 // This class is used internally by nmethods, to cache
 // exception/pc/handler information.
 
-class ExceptionCache : public CHeapObj {
+class ExceptionCache : public CHeapObj<mtCode> {
   friend class VMStructs;
  private:
   enum { cache_size = 16 };
@@ -176,6 +176,7 @@
   unsigned int _has_unsafe_access:1;         // May fault due to unsafe access.
   unsigned int _has_method_handle_invokes:1; // Has this method MethodHandle invokes?
   unsigned int _lazy_critical_native:1;      // Lazy JNI critical native
+  unsigned int _has_wide_vectors:1;          // Preserve wide vectors at safepoints
 
   // Protected by Patching_lock
   unsigned char _state;                      // {alive, not_entrant, zombie, unloaded}
@@ -436,6 +437,9 @@
   bool  is_lazy_critical_native() const           { return _lazy_critical_native; }
   void  set_lazy_critical_native(bool z)          { _lazy_critical_native = z; }
 
+  bool  has_wide_vectors() const                  { return _has_wide_vectors; }
+  void  set_has_wide_vectors(bool z)              { _has_wide_vectors = z; }
+
   int   comp_level() const                        { return _comp_level; }
 
   // Support for oops in scopes and relocs:
@@ -553,7 +557,7 @@
   static void oops_do_marking_prologue();
   static void oops_do_marking_epilogue();
   static bool oops_do_marking_is_active() { return _oops_do_mark_nmethods != NULL; }
-  DEBUG_ONLY(bool test_oops_do_mark() { return _oops_do_mark_link != NULL; })
+  bool test_oops_do_mark() { return _oops_do_mark_link != NULL; }
 
   // ScopeDesc for an instruction
   ScopeDesc* scope_desc_at(address pc);
@@ -630,11 +634,11 @@
   void log_state_change() const;
 
   // Prints block-level comments, including nmethod specific block labels:
-  virtual void print_block_comment(outputStream* stream, address block_begin) {
+  virtual void print_block_comment(outputStream* stream, address block_begin) const {
     print_nmethod_labels(stream, block_begin);
     CodeBlob::print_block_comment(stream, block_begin);
   }
-  void print_nmethod_labels(outputStream* stream, address block_begin);
+  void print_nmethod_labels(outputStream* stream, address block_begin) const;
 
   // Prints a comment for one native instruction (reloc info, pc desc)
   void print_code_comment_on(outputStream* st, int column, address begin, address end);
diff --git a/hotspot/src/share/vm/code/stubs.cpp b/hotspot/src/share/vm/code/stubs.cpp
index 124c0a6..0d5e61c 100644
--- a/hotspot/src/share/vm/code/stubs.cpp
+++ b/hotspot/src/share/vm/code/stubs.cpp
@@ -101,7 +101,8 @@
 
 Stub* StubQueue::request_committed(int code_size) {
   Stub* s = request(code_size);
-  if (s != NULL) commit(code_size);
+  CodeComments comments;
+  if (s != NULL) commit(code_size, comments);
   return s;
 }
 
@@ -118,7 +119,8 @@
       assert(_buffer_limit == _buffer_size, "buffer must be fully usable");
       if (_queue_end + requested_size <= _buffer_size) {
         // code fits in at the end => nothing to do
-        stub_initialize(s, requested_size);
+        CodeComments comments;
+        stub_initialize(s, requested_size, comments);
         return s;
       } else {
         // stub doesn't fit in at the queue end
@@ -135,7 +137,8 @@
     // Queue: |XXX|.......|XXXXXXX|.......|
     //        ^0  ^end    ^begin  ^limit  ^size
     s = current_stub();
-    stub_initialize(s, requested_size);
+    CodeComments comments;
+    stub_initialize(s, requested_size, comments);
     return s;
   }
   // Not enough space left
@@ -144,12 +147,12 @@
 }
 
 
-void StubQueue::commit(int committed_code_size) {
+void StubQueue::commit(int committed_code_size, CodeComments& comments) {
   assert(committed_code_size > 0, "committed_code_size must be > 0");
   int committed_size = round_to(stub_code_size_to_size(committed_code_size), CodeEntryAlignment);
   Stub* s = current_stub();
   assert(committed_size <= stub_size(s), "committed size must not exceed requested size");
-  stub_initialize(s, committed_size);
+  stub_initialize(s, committed_size, comments);
   _queue_end += committed_size;
   _number_of_stubs++;
   if (_mutex != NULL) _mutex->unlock();
diff --git a/hotspot/src/share/vm/code/stubs.hpp b/hotspot/src/share/vm/code/stubs.hpp
index 328ad8b..5701a45 100644
--- a/hotspot/src/share/vm/code/stubs.hpp
+++ b/hotspot/src/share/vm/code/stubs.hpp
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_CODE_STUBS_HPP
 #define SHARE_VM_CODE_STUBS_HPP
 
+#include "asm/codeBuffer.hpp"
 #include "memory/allocation.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
@@ -71,7 +72,8 @@
 class Stub VALUE_OBJ_CLASS_SPEC {
  public:
   // Initialization/finalization
-  void    initialize(int size)                   { ShouldNotCallThis(); }                // called to initialize/specify the stub's size
+  void    initialize(int size,
+                     CodeComments& comments)     { ShouldNotCallThis(); }                // called to initialize/specify the stub's size
   void    finalize()                             { ShouldNotCallThis(); }                // called before the stub is deallocated
 
   // General info/converters
@@ -101,10 +103,11 @@
 // of the concrete stub (see also macro below). There's exactly
 // one stub interface instance required per stub queue.
 
-class StubInterface: public CHeapObj {
+class StubInterface: public CHeapObj<mtCode> {
  public:
   // Initialization/finalization
-  virtual void    initialize(Stub* self, int size)         = 0; // called after creation (called twice if allocated via (request, commit))
+  virtual void    initialize(Stub* self, int size,
+                             CodeComments& comments)       = 0; // called after creation (called twice if allocated via (request, commit))
   virtual void    finalize(Stub* self)                     = 0; // called before deallocation
 
   // General info/converters
@@ -132,7 +135,8 @@
                                                            \
    public:                                                 \
     /* Initialization/finalization */                      \
-    virtual void    initialize(Stub* self, int size)       { cast(self)->initialize(size); }       \
+    virtual void    initialize(Stub* self, int size,       \
+                               CodeComments& comments)     { cast(self)->initialize(size, comments); } \
     virtual void    finalize(Stub* self)                   { cast(self)->finalize(); }             \
                                                            \
     /* General info */                                     \
@@ -152,7 +156,7 @@
 // A StubQueue maintains a queue of stubs.
 // Note: All sizes (spaces) are given in bytes.
 
-class StubQueue: public CHeapObj {
+class StubQueue: public CHeapObj<mtCode> {
   friend class VMStructs;
  private:
   StubInterface* _stub_interface;                // the interface prototype
@@ -171,7 +175,8 @@
   Stub* current_stub() const                     { return stub_at(_queue_end); }
 
   // Stub functionality accessed via interface
-  void  stub_initialize(Stub* s, int size)       { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size); }
+  void  stub_initialize(Stub* s, int size,
+                        CodeComments& comments)  { assert(size % CodeEntryAlignment == 0, "size not aligned"); _stub_interface->initialize(s, size, comments); }
   void  stub_finalize(Stub* s)                   { _stub_interface->finalize(s); }
   int   stub_size(Stub* s) const                 { return _stub_interface->size(s); }
   bool  stub_contains(Stub* s, address pc) const { return _stub_interface->code_begin(s) <= pc && pc < _stub_interface->code_end(s); }
@@ -200,7 +205,8 @@
   // Stub allocation (atomic transactions)
   Stub* request_committed(int code_size);        // request a stub that provides exactly code_size space for code
   Stub* request(int requested_code_size);        // request a stub with a (maximum) code space - locks the queue
-  void  commit (int committed_code_size);        // commit the previously requested stub - unlocks the queue
+  void  commit (int committed_code_size,
+                CodeComments& comments);         // commit the previously requested stub - unlocks the queue
 
   // Stub deallocation
   void  remove_first();                          // remove the first stub in the queue
diff --git a/hotspot/src/share/vm/code/vmreg.cpp b/hotspot/src/share/vm/code/vmreg.cpp
index dd59455..c56be87 100644
--- a/hotspot/src/share/vm/code/vmreg.cpp
+++ b/hotspot/src/share/vm/code/vmreg.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
 #include "code/vmreg.hpp"
 
 // First VMReg value that could refer to a stack slot
-VMReg VMRegImpl::stack0 = (VMReg)(intptr_t)((ConcreteRegisterImpl::number_of_registers + 1) & ~1);
+VMReg VMRegImpl::stack0 = (VMReg)(intptr_t)((ConcreteRegisterImpl::number_of_registers + 7) & ~7);
 
 // VMRegs are 4 bytes wide on all platforms
 const int VMRegImpl::stack_slot_size = 4;
diff --git a/hotspot/src/share/vm/code/vmreg.hpp b/hotspot/src/share/vm/code/vmreg.hpp
index d57e6f8..ef2bdce 100644
--- a/hotspot/src/share/vm/code/vmreg.hpp
+++ b/hotspot/src/share/vm/code/vmreg.hpp
@@ -131,6 +131,10 @@
     assert((is_reg() && value() < stack0->value() - 1) || is_stack(), "must be");
     return (VMReg)(intptr_t)(value() + 1);
   }
+  VMReg next(int i) {
+    assert((is_reg() && value() < stack0->value() - i) || is_stack(), "must be");
+    return (VMReg)(intptr_t)(value() + i);
+  }
   VMReg prev() {
     assert((is_stack() && value() > stack0->value()) || (is_reg() && value() != 0), "must be");
     return (VMReg)(intptr_t)(value() - 1);
diff --git a/hotspot/src/share/vm/code/vtableStubs.hpp b/hotspot/src/share/vm/code/vtableStubs.hpp
index 82caf11..ac6070b 100644
--- a/hotspot/src/share/vm/code/vtableStubs.hpp
+++ b/hotspot/src/share/vm/code/vtableStubs.hpp
@@ -55,6 +55,8 @@
   int index() const                              { return _index; }
   static VMReg receiver_location()               { return _receiver_location; }
   void set_next(VtableStub* n)                   { _next = n; }
+
+ public:
   address code_begin() const                     { return (address)(this + 1); }
   address code_end() const                       { return code_begin() + pd_code_size_limit(_is_vtable_stub); }
   address entry_point() const                    { return code_begin(); }
@@ -65,6 +67,7 @@
   }
   bool contains(address pc) const                { return code_begin() <= pc && pc < code_end(); }
 
+ private:
   void set_exception_points(address npe_addr, address ame_addr) {
     _npe_offset = npe_addr - code_begin();
     _ame_offset = ame_addr - code_begin();
diff --git a/hotspot/src/share/vm/compiler/abstractCompiler.hpp b/hotspot/src/share/vm/compiler/abstractCompiler.hpp
index 380dfe7..55303a0 100644
--- a/hotspot/src/share/vm/compiler/abstractCompiler.hpp
+++ b/hotspot/src/share/vm/compiler/abstractCompiler.hpp
@@ -29,7 +29,7 @@
 
 typedef void (*initializer)(void);
 
-class AbstractCompiler : public CHeapObj {
+class AbstractCompiler : public CHeapObj<mtCompiler> {
  private:
   bool _is_initialized; // Mark whether compiler object is initialized
 
diff --git a/hotspot/src/share/vm/compiler/compileBroker.cpp b/hotspot/src/share/vm/compiler/compileBroker.cpp
index 8729e05..a335479 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.cpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.cpp
@@ -197,9 +197,9 @@
 
   void log_compile(JavaThread* thread, CompileTask* task) {
     StringLogMessage lm;
-    stringStream msg = lm.stream();
+    stringStream sstr = lm.stream();
     // msg.time_stamp().update_to(tty->time_stamp().ticks());
-    task->print_compilation(&msg, true);
+    task->print_compilation(&sstr, NULL, true);
     log(thread, "%s", (const char*)lm);
   }
 
@@ -407,7 +407,10 @@
     if (is_osr_method) {
       st->print(" @ %d", osr_bci);
     }
-    st->print(" (%d bytes)", method->code_size());
+    if (method->is_native())
+      st->print(" (native)");
+    else
+      st->print(" (%d bytes)", method->code_size());
   }
 
   if (msg != NULL) {
@@ -427,12 +430,17 @@
   st->print("     ");        // print compilation number
 
   // method attributes
-  const char sync_char      = method->is_synchronized()        ? 's' : ' ';
-  const char exception_char = method->has_exception_handlers() ? '!' : ' ';
-  const char monitors_char  = method->has_monitor_bytecodes()  ? 'm' : ' ';
+  if (method->is_loaded()) {
+    const char sync_char      = method->is_synchronized()        ? 's' : ' ';
+    const char exception_char = method->has_exception_handlers() ? '!' : ' ';
+    const char monitors_char  = method->has_monitor_bytecodes()  ? 'm' : ' ';
 
-  // print method attributes
-  st->print(" %c%c%c  ", sync_char, exception_char, monitors_char);
+    // print method attributes
+    st->print(" %c%c%c  ", sync_char, exception_char, monitors_char);
+  } else {
+    //         %s!bn
+    st->print("      ");     // print method attributes
+  }
 
   if (TieredCompilation) {
     st->print("  ");
@@ -444,7 +452,10 @@
 
   st->print("@ %d  ", bci);  // print bci
   method->print_short_name(st);
-  st->print(" (%d bytes)", method->code_size());
+  if (method->is_loaded())
+    st->print(" (%d bytes)", method->code_size());
+  else
+    st->print(" (not loaded)");
 
   if (msg != NULL) {
     st->print("   %s", msg);
@@ -471,12 +482,12 @@
 
 // ------------------------------------------------------------------
 // CompileTask::print_compilation
-void CompileTask::print_compilation(outputStream* st, bool short_form) {
+void CompileTask::print_compilation(outputStream* st, const char* msg, bool short_form) {
   oop rem = JNIHandles::resolve(method_handle());
   assert(rem != NULL && rem->is_method(), "must be");
   methodOop method = (methodOop) rem;
   bool is_osr_method = osr_bci() != InvocationEntryBci;
-  print_compilation_impl(st, method, compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), NULL, short_form);
+  print_compilation_impl(st, method, compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form);
 }
 
 // ------------------------------------------------------------------
@@ -951,7 +962,7 @@
   int compiler_count = c1_compiler_count + c2_compiler_count;
 
   _method_threads =
-    new (ResourceObj::C_HEAP) GrowableArray<CompilerThread*>(compiler_count, true);
+    new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<CompilerThread*>(compiler_count, true);
 
   char name_buffer[256];
   for (int i = 0; i < c2_compiler_count; i++) {
@@ -1018,6 +1029,7 @@
          "sanity check");
   assert(!instanceKlass::cast(method->method_holder())->is_not_initialized(),
          "method holder must be initialized");
+  assert(!method->is_method_handle_intrinsic(), "do not enqueue these guys");
 
   if (CIPrintRequests) {
     tty->print("request: ");
@@ -1213,7 +1225,7 @@
     // We accept a higher level osr method
     nmethod* nm = method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
     if (nm != NULL) return nm;
-    if (method->is_not_osr_compilable()) return NULL;
+    if (method->is_not_osr_compilable(comp_level)) return NULL;
   }
 
   assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
@@ -1231,7 +1243,7 @@
   //
   // Note: A native method implies non-osr compilation which is
   //       checked with an assertion at the entry of this method.
-  if (method->is_native()) {
+  if (method->is_native() && !method->is_method_handle_intrinsic()) {
     bool in_base_library;
     address adr = NativeLookup::lookup(method, in_base_library, THREAD);
     if (HAS_PENDING_EXCEPTION) {
@@ -1264,7 +1276,7 @@
 
   // do the compilation
   if (method->is_native()) {
-    if (!PreferInterpreterNativeStubs) {
+    if (!PreferInterpreterNativeStubs || method->is_method_handle_intrinsic()) {
       // Acquire our lock.
       int compile_id;
       {
@@ -1294,7 +1306,7 @@
                                             int          comp_level) {
   bool is_osr = (osr_bci != standard_entry_bci);
   if (is_osr) {
-    if (method->is_not_osr_compilable()) {
+    if (method->is_not_osr_compilable(comp_level)) {
       return true;
     } else {
       nmethod* result = method->lookup_osr_nmethod_for(osr_bci, comp_level, true);
@@ -1345,7 +1357,7 @@
   // Some compilers may not support on stack replacement.
   if (is_osr &&
       (!CICompileOSR || !compiler(comp_level)->supports_osr())) {
-    method->set_not_osr_compilable();
+    method->set_not_osr_compilable(comp_level);
     return true;
   }
 
@@ -1535,7 +1547,8 @@
   }
   CompileLog* log = thread->log();
   if (log != NULL) {
-    log->begin_elem("start_compile_thread thread='" UINTX_FORMAT "' process='%d'",
+    log->begin_elem("start_compile_thread name='%s' thread='" UINTX_FORMAT "' process='%d'",
+                    thread->name(),
                     os::current_thread_id(),
                     os::current_process_id());
     log->stamp();
@@ -1627,7 +1640,7 @@
       }
       fp = fopen(fileBuf, "at");
       if (fp != NULL) {
-        file = NEW_C_HEAP_ARRAY(char, strlen(fileBuf)+1);
+        file = NEW_C_HEAP_ARRAY(char, strlen(fileBuf)+1, mtCompiler);
         strcpy(file, fileBuf);
         break;
       }
@@ -1637,7 +1650,7 @@
     } else {
       if (LogCompilation && Verbose)
         tty->print_cr("Opening compilation log %s", file);
-      CompileLog* log = new(ResourceObj::C_HEAP) CompileLog(file, fp, thread_id);
+      CompileLog* log = new(ResourceObj::C_HEAP, mtCompiler) CompileLog(file, fp, thread_id);
       thread->init_log(log);
 
       if (xtty != NULL) {
@@ -1775,11 +1788,10 @@
         _compilation_log->log_failure(thread, task, ci_env.failure_reason(), retry_message);
       }
       if (PrintCompilation) {
-        tty->print("%4d   COMPILE SKIPPED: %s", compile_id, ci_env.failure_reason());
-        if (retry_message != NULL) {
-          tty->print(" (%s)", retry_message);
-        }
-        tty->cr();
+        FormatBufferResource msg = retry_message != NULL ?
+            err_msg_res("COMPILE SKIPPED: %s (%s)", ci_env.failure_reason(), retry_message) :
+            err_msg_res("COMPILE SKIPPED: %s",      ci_env.failure_reason());
+        task->print_compilation(tty, msg);
       }
     } else {
       task->mark_success();
@@ -1809,14 +1821,20 @@
     tty->print_cr("size: %d time: %d inlined: %d bytes", code_size, (int)time.milliseconds(), task->num_inlined_bytecodes());
   }
 
-  if (compilable == ciEnv::MethodCompilable_never) {
-    if (is_osr) {
-      method->set_not_osr_compilable();
-    } else {
+  // Disable compilation, if required.
+  switch (compilable) {
+  case ciEnv::MethodCompilable_never:
+    if (is_osr)
+      method->set_not_osr_compilable_quietly();
+    else
       method->set_not_compilable_quietly();
-    }
-  } else if (compilable == ciEnv::MethodCompilable_not_at_tier) {
-    method->set_not_compilable_quietly(task->comp_level());
+    break;
+  case ciEnv::MethodCompilable_not_at_tier:
+    if (is_osr)
+      method->set_not_osr_compilable_quietly(task->comp_level());
+    else
+      method->set_not_compilable_quietly(task->comp_level());
+    break;
   }
 
   // Note that the queued_for_compilation bits are cleared without
diff --git a/hotspot/src/share/vm/compiler/compileBroker.hpp b/hotspot/src/share/vm/compiler/compileBroker.hpp
index 1ee2c54..99d1b2f 100644
--- a/hotspot/src/share/vm/compiler/compileBroker.hpp
+++ b/hotspot/src/share/vm/compiler/compileBroker.hpp
@@ -36,7 +36,7 @@
 //
 // An entry in the compile queue.  It represents a pending or current
 // compilation.
-class CompileTask : public CHeapObj {
+class CompileTask : public CHeapObj<mtCompiler> {
   friend class VMStructs;
 
  private:
@@ -103,11 +103,11 @@
                                       const char* msg = NULL, bool short_form = false);
 
 public:
-  void         print_compilation(outputStream* st = tty, bool short_form = false);
-  static void  print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL) {
+  void         print_compilation(outputStream* st = tty, const char* msg = NULL, bool short_form = false);
+  static void  print_compilation(outputStream* st, const nmethod* nm, const char* msg = NULL, bool short_form = false) {
     print_compilation_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),
                            nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false,
-                           msg);
+                           msg, short_form);
   }
 
   static void  print_inlining(outputStream* st, ciMethod* method, int inline_level, int bci, const char* msg = NULL);
@@ -131,7 +131,7 @@
 //
 // Per Compiler Performance Counters.
 //
-class CompilerCounters : public CHeapObj {
+class CompilerCounters : public CHeapObj<mtCompiler> {
 
   public:
     enum {
@@ -175,7 +175,7 @@
 // CompileQueue
 //
 // A list of CompileTasks.
-class CompileQueue : public CHeapObj {
+class CompileQueue : public CHeapObj<mtCompiler> {
  private:
   const char* _name;
   Monitor*    _lock;
diff --git a/hotspot/src/share/vm/compiler/compileLog.cpp b/hotspot/src/share/vm/compiler/compileLog.cpp
index a306117f..44b9a07 100644
--- a/hotspot/src/share/vm/compiler/compileLog.cpp
+++ b/hotspot/src/share/vm/compiler/compileLog.cpp
@@ -37,14 +37,14 @@
 CompileLog::CompileLog(const char* file, FILE* fp, intx thread_id)
   : _context(_context_buffer, sizeof(_context_buffer))
 {
-  initialize(new(ResourceObj::C_HEAP) fileStream(fp));
+  initialize(new(ResourceObj::C_HEAP, mtCompiler) fileStream(fp));
   _file = file;
   _file_end = 0;
   _thread_id = thread_id;
 
   _identities_limit = 0;
   _identities_capacity = 400;
-  _identities = NEW_C_HEAP_ARRAY(char, _identities_capacity);
+  _identities = NEW_C_HEAP_ARRAY(char, _identities_capacity, mtCompiler);
 
   // link into the global list
   { MutexLocker locker(CompileTaskAlloc_lock);
@@ -56,7 +56,7 @@
 CompileLog::~CompileLog() {
   delete _out;
   _out = NULL;
-  FREE_C_HEAP_ARRAY(char, _identities);
+  FREE_C_HEAP_ARRAY(char, _identities, mtCompiler);
 }
 
 
@@ -109,7 +109,7 @@
   if (id >= _identities_capacity) {
     int new_cap = _identities_capacity * 2;
     if (new_cap <= id)  new_cap = id + 100;
-    _identities = REALLOC_C_HEAP_ARRAY(char, _identities, new_cap);
+    _identities = REALLOC_C_HEAP_ARRAY(char, _identities, new_cap, mtCompiler);
     _identities_capacity = new_cap;
   }
   while (id >= _identities_limit) {
@@ -297,3 +297,48 @@
   char buf[4 * K];
   finish_log_on_error(file, buf, sizeof(buf));
 }
+
+// ------------------------------------------------------------------
+// CompileLog::inline_success
+//
+// Print about successful method inlining.
+void CompileLog::inline_success(const char* reason) {
+  begin_elem("inline_success reason='");
+  text(reason);
+  end_elem("'");
+}
+
+// ------------------------------------------------------------------
+// CompileLog::inline_fail
+//
+// Print about failed method inlining.
+void CompileLog::inline_fail(const char* reason) {
+  begin_elem("inline_fail reason='");
+  text(reason);
+  end_elem("'");
+}
+
+// ------------------------------------------------------------------
+// CompileLog::set_context
+//
+// Set XML tag as an optional marker - it is printed only if
+// there are other entries after until it is reset.
+void CompileLog::set_context(const char* format, ...) {
+  va_list ap;
+  va_start(ap, format);
+  clear_context();
+  _context.print("<");
+  _context.vprint(format, ap);
+  _context.print_cr("/>");
+  va_end(ap);
+}
+
+// ------------------------------------------------------------------
+// CompileLog::code_cache_state
+//
+// Print code cache state.
+void CompileLog::code_cache_state() {
+  begin_elem("code_cache");
+  CodeCache::log_state(this);
+  end_elem("");
+}
diff --git a/hotspot/src/share/vm/compiler/compileLog.hpp b/hotspot/src/share/vm/compiler/compileLog.hpp
index 0c997ce..672da85 100644
--- a/hotspot/src/share/vm/compiler/compileLog.hpp
+++ b/hotspot/src/share/vm/compiler/compileLog.hpp
@@ -60,7 +60,13 @@
 
   intx          thread_id()                      { return _thread_id; }
   const char*   file()                           { return _file; }
+
+  // Optional context marker, to help place actions that occur during
+  // parsing. If there is no log output until the next context string
+  // or reset, context string will be silently ignored
   stringStream* context()                        { return &_context; }
+  void    clear_context()                        { context()->reset(); }
+  void      set_context(const char* format, ...);
 
   void          name(ciSymbol* s);               // name='s'
   void          name(Symbol* s)                  { xmlStream::name(s); }
@@ -69,6 +75,9 @@
   int           identify(ciObject* obj);
   void          clear_identities();
 
+  void inline_fail   (const char* reason);
+  void inline_success(const char* reason);
+
   // virtuals
   virtual void see_tag(const char* tag, bool push);
   virtual void pop_tag(const char* tag);
@@ -76,6 +85,9 @@
   // make a provisional end of log mark
   void mark_file_end() { _file_end = out()->count(); }
 
+  // Print code cache statistics
+  void code_cache_state();
+
   // copy all logs to the given stream
   static void finish_log(outputStream* out);
   static void finish_log_on_error(outputStream* out, char *buf, int buflen);
diff --git a/hotspot/src/share/vm/compiler/compilerOracle.cpp b/hotspot/src/share/vm/compiler/compilerOracle.cpp
index 54e7a3e..197304b 100644
--- a/hotspot/src/share/vm/compiler/compilerOracle.cpp
+++ b/hotspot/src/share/vm/compiler/compilerOracle.cpp
@@ -34,7 +34,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/jniHandles.hpp"
 
-class MethodMatcher : public CHeapObj {
+class MethodMatcher : public CHeapObj<mtCompiler> {
  public:
   enum Mode {
     Exact,
@@ -554,9 +554,8 @@
 
 static const char* cc_file() {
 #ifdef ASSERT
-  if (CompileCommandFile == NULL) {
+  if (CompileCommandFile == NULL)
     return default_cc_file;
-  }
 #endif
   return CompileCommandFile;
 }
diff --git a/hotspot/src/share/vm/compiler/disassembler.cpp b/hotspot/src/share/vm/compiler/disassembler.cpp
index 9603e86..3be1533 100644
--- a/hotspot/src/share/vm/compiler/disassembler.cpp
+++ b/hotspot/src/share/vm/compiler/disassembler.cpp
@@ -148,6 +148,7 @@
  private:
   nmethod*      _nm;
   CodeBlob*     _code;
+  CodeComments  _comments;
   outputStream* _output;
   address       _start, _end;
 
@@ -187,7 +188,7 @@
   void print_address(address value);
 
  public:
-  decode_env(CodeBlob* code, outputStream* output);
+  decode_env(CodeBlob* code, outputStream* output, CodeComments c = CodeComments());
 
   address decode_instructions(address start, address end);
 
@@ -229,12 +230,13 @@
   const char* options() { return _option_buf; }
 };
 
-decode_env::decode_env(CodeBlob* code, outputStream* output) {
+decode_env::decode_env(CodeBlob* code, outputStream* output, CodeComments c) {
   memset(this, 0, sizeof(*this));
   _output = output ? output : tty;
   _code = code;
   if (code != NULL && code->is_nmethod())
     _nm = (nmethod*) code;
+  _comments.assign(c);
 
   // by default, output pc but not bytes:
   _print_pc       = true;
@@ -356,6 +358,7 @@
   if (cb != NULL) {
     cb->print_block_comment(st, p);
   }
+  _comments.print_block_comment(st, (intptr_t)(p - _start));
   if (_print_pc) {
     st->print("  " PTR_FORMAT ": ", p);
   }
@@ -467,10 +470,9 @@
   env.decode_instructions(cb->code_begin(), cb->code_end());
 }
 
-
-void Disassembler::decode(address start, address end, outputStream* st) {
+void Disassembler::decode(address start, address end, outputStream* st, CodeComments c) {
   if (!load_library())  return;
-  decode_env env(CodeCache::find_blob_unsafe(start), st);
+  decode_env env(CodeCache::find_blob_unsafe(start), st, c);
   env.decode_instructions(start, end);
 }
 
diff --git a/hotspot/src/share/vm/compiler/disassembler.hpp b/hotspot/src/share/vm/compiler/disassembler.hpp
index a70b8cc..0d05514 100644
--- a/hotspot/src/share/vm/compiler/disassembler.hpp
+++ b/hotspot/src/share/vm/compiler/disassembler.hpp
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_COMPILER_DISASSEMBLER_HPP
 #define SHARE_VM_COMPILER_DISASSEMBLER_HPP
 
+#include "asm/codeBuffer.hpp"
 #include "runtime/globals.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
@@ -87,7 +88,7 @@
   }
   static void decode(CodeBlob *cb,               outputStream* st = NULL);
   static void decode(nmethod* nm,                outputStream* st = NULL);
-  static void decode(address begin, address end, outputStream* st = NULL);
+  static void decode(address begin, address end, outputStream* st = NULL, CodeComments c = CodeComments());
 };
 
 #endif // SHARE_VM_COMPILER_DISASSEMBLER_HPP
diff --git a/hotspot/src/share/vm/compiler/oopMap.cpp b/hotspot/src/share/vm/compiler/oopMap.cpp
index 9c1195c..2cd212d 100644
--- a/hotspot/src/share/vm/compiler/oopMap.cpp
+++ b/hotspot/src/share/vm/compiler/oopMap.cpp
@@ -599,7 +599,7 @@
 
 #ifdef COMPILER2
 
-class DerivedPointerEntry : public CHeapObj {
+class DerivedPointerEntry : public CHeapObj<mtCompiler> {
  private:
   oop*     _location; // Location of derived pointer (also pointing to the base)
   intptr_t _offset;   // Offset from base pointer
@@ -621,7 +621,7 @@
   assert (!_active, "should not be active");
   assert(_list == NULL || _list->length() == 0, "table not empty");
   if (_list == NULL) {
-    _list = new (ResourceObj::C_HEAP) GrowableArray<DerivedPointerEntry*>(10, true); // Allocated on C heap
+    _list = new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<DerivedPointerEntry*>(10, true); // Allocated on C heap
   }
   _active = true;
 }
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp
deleted file mode 100644
index 63afa40..0000000
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.cpp
+++ /dev/null
@@ -1,1257 +0,0 @@
-/*
- * 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp"
-#include "gc_implementation/shared/allocationStats.hpp"
-#include "gc_implementation/shared/spaceDecorator.hpp"
-#include "memory/space.inline.hpp"
-#include "runtime/globals.hpp"
-#include "utilities/ostream.hpp"
-
-////////////////////////////////////////////////////////////////////////////////
-// A binary tree based search structure for free blocks.
-// This is currently used in the Concurrent Mark&Sweep implementation.
-////////////////////////////////////////////////////////////////////////////////
-
-TreeChunk* TreeChunk::as_TreeChunk(FreeChunk* fc) {
-  // Do some assertion checking here.
-  return (TreeChunk*) fc;
-}
-
-void TreeChunk::verifyTreeChunkList() const {
-  TreeChunk* nextTC = (TreeChunk*)next();
-  if (prev() != NULL) { // interior list node shouldn'r have tree fields
-    guarantee(embedded_list()->parent() == NULL && embedded_list()->left() == NULL &&
-              embedded_list()->right()  == NULL, "should be clear");
-  }
-  if (nextTC != NULL) {
-    guarantee(as_TreeChunk(nextTC->prev()) == this, "broken chain");
-    guarantee(nextTC->size() == size(), "wrong size");
-    nextTC->verifyTreeChunkList();
-  }
-}
-
-
-TreeList* TreeList::as_TreeList(TreeChunk* tc) {
-  // This first free chunk in the list will be the tree list.
-  assert(tc->size() >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk");
-  TreeList* tl = tc->embedded_list();
-  tc->set_list(tl);
-#ifdef ASSERT
-  tl->set_protecting_lock(NULL);
-#endif
-  tl->set_hint(0);
-  tl->set_size(tc->size());
-  tl->link_head(tc);
-  tl->link_tail(tc);
-  tl->set_count(1);
-  tl->init_statistics(true /* split_birth */);
-  tl->setParent(NULL);
-  tl->setLeft(NULL);
-  tl->setRight(NULL);
-  return tl;
-}
-
-TreeList* TreeList::as_TreeList(HeapWord* addr, size_t size) {
-  TreeChunk* tc = (TreeChunk*) addr;
-  assert(size >= sizeof(TreeChunk), "Chunk is too small for a TreeChunk");
-  // The space in the heap will have been mangled initially but
-  // is not remangled when a free chunk is returned to the free list
-  // (since it is used to maintain the chunk on the free list).
-  assert((ZapUnusedHeapArea &&
-          SpaceMangler::is_mangled((HeapWord*) tc->size_addr()) &&
-          SpaceMangler::is_mangled((HeapWord*) tc->prev_addr()) &&
-          SpaceMangler::is_mangled((HeapWord*) tc->next_addr())) ||
-          (tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL),
-    "Space should be clear or mangled");
-  tc->setSize(size);
-  tc->linkPrev(NULL);
-  tc->linkNext(NULL);
-  TreeList* tl = TreeList::as_TreeList(tc);
-  return tl;
-}
-
-TreeList* TreeList::removeChunkReplaceIfNeeded(TreeChunk* tc) {
-
-  TreeList* retTL = this;
-  FreeChunk* list = head();
-  assert(!list || list != list->next(), "Chunk on list twice");
-  assert(tc != NULL, "Chunk being removed is NULL");
-  assert(parent() == NULL || this == parent()->left() ||
-    this == parent()->right(), "list is inconsistent");
-  assert(tc->isFree(), "Header is not marked correctly");
-  assert(head() == NULL || head()->prev() == NULL, "list invariant");
-  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
-
-  FreeChunk* prevFC = tc->prev();
-  TreeChunk* nextTC = TreeChunk::as_TreeChunk(tc->next());
-  assert(list != NULL, "should have at least the target chunk");
-
-  // Is this the first item on the list?
-  if (tc == list) {
-    // The "getChunk..." functions for a TreeList will not return the
-    // first chunk in the list unless it is the last chunk in the list
-    // because the first chunk is also acting as the tree node.
-    // When coalescing happens, however, the first chunk in the a tree
-    // list can be the start of a free range.  Free ranges are removed
-    // from the free lists so that they are not available to be
-    // allocated when the sweeper yields (giving up the free list lock)
-    // to allow mutator activity.  If this chunk is the first in the
-    // list and is not the last in the list, do the work to copy the
-    // TreeList from the first chunk to the next chunk and update all
-    // the TreeList pointers in the chunks in the list.
-    if (nextTC == NULL) {
-      assert(prevFC == NULL, "Not last chunk in the list");
-      set_tail(NULL);
-      set_head(NULL);
-    } else {
-      // copy embedded list.
-      nextTC->set_embedded_list(tc->embedded_list());
-      retTL = nextTC->embedded_list();
-      // Fix the pointer to the list in each chunk in the list.
-      // This can be slow for a long list.  Consider having
-      // an option that does not allow the first chunk on the
-      // list to be coalesced.
-      for (TreeChunk* curTC = nextTC; curTC != NULL;
-          curTC = TreeChunk::as_TreeChunk(curTC->next())) {
-        curTC->set_list(retTL);
-      }
-      // Fix the parent to point to the new TreeList.
-      if (retTL->parent() != NULL) {
-        if (this == retTL->parent()->left()) {
-          retTL->parent()->setLeft(retTL);
-        } else {
-          assert(this == retTL->parent()->right(), "Parent is incorrect");
-          retTL->parent()->setRight(retTL);
-        }
-      }
-      // Fix the children's parent pointers to point to the
-      // new list.
-      assert(right() == retTL->right(), "Should have been copied");
-      if (retTL->right() != NULL) {
-        retTL->right()->setParent(retTL);
-      }
-      assert(left() == retTL->left(), "Should have been copied");
-      if (retTL->left() != NULL) {
-        retTL->left()->setParent(retTL);
-      }
-      retTL->link_head(nextTC);
-      assert(nextTC->isFree(), "Should be a free chunk");
-    }
-  } else {
-    if (nextTC == NULL) {
-      // Removing chunk at tail of list
-      link_tail(prevFC);
-    }
-    // Chunk is interior to the list
-    prevFC->linkAfter(nextTC);
-  }
-
-  // Below this point the embeded TreeList being used for the
-  // tree node may have changed. Don't use "this"
-  // TreeList*.
-  // chunk should still be a free chunk (bit set in _prev)
-  assert(!retTL->head() || retTL->size() == retTL->head()->size(),
-    "Wrong sized chunk in list");
-  debug_only(
-    tc->linkPrev(NULL);
-    tc->linkNext(NULL);
-    tc->set_list(NULL);
-    bool prev_found = false;
-    bool next_found = false;
-    for (FreeChunk* curFC = retTL->head();
-         curFC != NULL; curFC = curFC->next()) {
-      assert(curFC != tc, "Chunk is still in list");
-      if (curFC == prevFC) {
-        prev_found = true;
-      }
-      if (curFC == nextTC) {
-        next_found = true;
-      }
-    }
-    assert(prevFC == NULL || prev_found, "Chunk was lost from list");
-    assert(nextTC == NULL || next_found, "Chunk was lost from list");
-    assert(retTL->parent() == NULL ||
-           retTL == retTL->parent()->left() ||
-           retTL == retTL->parent()->right(),
-           "list is inconsistent");
-  )
-  retTL->decrement_count();
-
-  assert(tc->isFree(), "Should still be a free chunk");
-  assert(retTL->head() == NULL || retTL->head()->prev() == NULL,
-    "list invariant");
-  assert(retTL->tail() == NULL || retTL->tail()->next() == NULL,
-    "list invariant");
-  return retTL;
-}
-void TreeList::returnChunkAtTail(TreeChunk* chunk) {
-  assert(chunk != NULL, "returning NULL chunk");
-  assert(chunk->list() == this, "list should be set for chunk");
-  assert(tail() != NULL, "The tree list is embedded in the first chunk");
-  // which means that the list can never be empty.
-  assert(!verifyChunkInFreeLists(chunk), "Double entry");
-  assert(head() == NULL || head()->prev() == NULL, "list invariant");
-  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
-
-  FreeChunk* fc = tail();
-  fc->linkAfter(chunk);
-  link_tail(chunk);
-
-  assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list");
-  increment_count();
-  debug_only(increment_returnedBytes_by(chunk->size()*sizeof(HeapWord));)
-  assert(head() == NULL || head()->prev() == NULL, "list invariant");
-  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
-}
-
-// Add this chunk at the head of the list.  "At the head of the list"
-// is defined to be after the chunk pointer to by head().  This is
-// because the TreeList is embedded in the first TreeChunk in the
-// list.  See the definition of TreeChunk.
-void TreeList::returnChunkAtHead(TreeChunk* chunk) {
-  assert(chunk->list() == this, "list should be set for chunk");
-  assert(head() != NULL, "The tree list is embedded in the first chunk");
-  assert(chunk != NULL, "returning NULL chunk");
-  assert(!verifyChunkInFreeLists(chunk), "Double entry");
-  assert(head() == NULL || head()->prev() == NULL, "list invariant");
-  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
-
-  FreeChunk* fc = head()->next();
-  if (fc != NULL) {
-    chunk->linkAfter(fc);
-  } else {
-    assert(tail() == NULL, "List is inconsistent");
-    link_tail(chunk);
-  }
-  head()->linkAfter(chunk);
-  assert(!head() || size() == head()->size(), "Wrong sized chunk in list");
-  increment_count();
-  debug_only(increment_returnedBytes_by(chunk->size()*sizeof(HeapWord));)
-  assert(head() == NULL || head()->prev() == NULL, "list invariant");
-  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
-}
-
-TreeChunk* TreeList::head_as_TreeChunk() {
-  assert(head() == NULL || TreeChunk::as_TreeChunk(head())->list() == this,
-    "Wrong type of chunk?");
-  return TreeChunk::as_TreeChunk(head());
-}
-
-TreeChunk* TreeList::first_available() {
-  assert(head() != NULL, "The head of the list cannot be NULL");
-  FreeChunk* fc = head()->next();
-  TreeChunk* retTC;
-  if (fc == NULL) {
-    retTC = head_as_TreeChunk();
-  } else {
-    retTC = TreeChunk::as_TreeChunk(fc);
-  }
-  assert(retTC->list() == this, "Wrong type of chunk.");
-  return retTC;
-}
-
-// Returns the block with the largest heap address amongst
-// those in the list for this size; potentially slow and expensive,
-// use with caution!
-TreeChunk* TreeList::largest_address() {
-  assert(head() != NULL, "The head of the list cannot be NULL");
-  FreeChunk* fc = head()->next();
-  TreeChunk* retTC;
-  if (fc == NULL) {
-    retTC = head_as_TreeChunk();
-  } else {
-    // walk down the list and return the one with the highest
-    // heap address among chunks of this size.
-    FreeChunk* last = fc;
-    while (fc->next() != NULL) {
-      if ((HeapWord*)last < (HeapWord*)fc) {
-        last = fc;
-      }
-      fc = fc->next();
-    }
-    retTC = TreeChunk::as_TreeChunk(last);
-  }
-  assert(retTC->list() == this, "Wrong type of chunk.");
-  return retTC;
-}
-
-BinaryTreeDictionary::BinaryTreeDictionary(MemRegion mr, bool splay):
-  _splay(splay)
-{
-  assert(mr.byte_size() > MIN_TREE_CHUNK_SIZE, "minimum chunk size");
-
-  reset(mr);
-  assert(root()->left() == NULL, "reset check failed");
-  assert(root()->right() == NULL, "reset check failed");
-  assert(root()->head()->next() == NULL, "reset check failed");
-  assert(root()->head()->prev() == NULL, "reset check failed");
-  assert(totalSize() == root()->size(), "reset check failed");
-  assert(totalFreeBlocks() == 1, "reset check failed");
-}
-
-void BinaryTreeDictionary::inc_totalSize(size_t inc) {
-  _totalSize = _totalSize + inc;
-}
-
-void BinaryTreeDictionary::dec_totalSize(size_t dec) {
-  _totalSize = _totalSize - dec;
-}
-
-void BinaryTreeDictionary::reset(MemRegion mr) {
-  assert(mr.byte_size() > MIN_TREE_CHUNK_SIZE, "minimum chunk size");
-  set_root(TreeList::as_TreeList(mr.start(), mr.word_size()));
-  set_totalSize(mr.word_size());
-  set_totalFreeBlocks(1);
-}
-
-void BinaryTreeDictionary::reset(HeapWord* addr, size_t byte_size) {
-  MemRegion mr(addr, heap_word_size(byte_size));
-  reset(mr);
-}
-
-void BinaryTreeDictionary::reset() {
-  set_root(NULL);
-  set_totalSize(0);
-  set_totalFreeBlocks(0);
-}
-
-// Get a free block of size at least size from tree, or NULL.
-// If a splay step is requested, the removal algorithm (only) incorporates
-// a splay step as follows:
-// . the search proceeds down the tree looking for a possible
-//   match. At the (closest) matching location, an appropriate splay step is applied
-//   (zig, zig-zig or zig-zag). A chunk of the appropriate size is then returned
-//   if available, and if it's the last chunk, the node is deleted. A deteleted
-//   node is replaced in place by its tree successor.
-TreeChunk*
-BinaryTreeDictionary::getChunkFromTree(size_t size, Dither dither, bool splay)
-{
-  TreeList *curTL, *prevTL;
-  TreeChunk* retTC = NULL;
-  assert(size >= MIN_TREE_CHUNK_SIZE, "minimum chunk size");
-  if (FLSVerifyDictionary) {
-    verifyTree();
-  }
-  // starting at the root, work downwards trying to find match.
-  // Remember the last node of size too great or too small.
-  for (prevTL = curTL = root(); curTL != NULL;) {
-    if (curTL->size() == size) {        // exact match
-      break;
-    }
-    prevTL = curTL;
-    if (curTL->size() < size) {        // proceed to right sub-tree
-      curTL = curTL->right();
-    } else {                           // proceed to left sub-tree
-      assert(curTL->size() > size, "size inconsistency");
-      curTL = curTL->left();
-    }
-  }
-  if (curTL == NULL) { // couldn't find exact match
-    // try and find the next larger size by walking back up the search path
-    for (curTL = prevTL; curTL != NULL;) {
-      if (curTL->size() >= size) break;
-      else curTL = curTL->parent();
-    }
-    assert(curTL == NULL || curTL->count() > 0,
-      "An empty list should not be in the tree");
-  }
-  if (curTL != NULL) {
-    assert(curTL->size() >= size, "size inconsistency");
-    if (UseCMSAdaptiveFreeLists) {
-
-      // A candidate chunk has been found.  If it is already under
-      // populated, get a chunk associated with the hint for this
-      // chunk.
-      if (curTL->surplus() <= 0) {
-        /* Use the hint to find a size with a surplus, and reset the hint. */
-        TreeList* hintTL = curTL;
-        while (hintTL->hint() != 0) {
-          assert(hintTL->hint() == 0 || hintTL->hint() > hintTL->size(),
-            "hint points in the wrong direction");
-          hintTL = findList(hintTL->hint());
-          assert(curTL != hintTL, "Infinite loop");
-          if (hintTL == NULL ||
-              hintTL == curTL /* Should not happen but protect against it */ ) {
-            // No useful hint.  Set the hint to NULL and go on.
-            curTL->set_hint(0);
-            break;
-          }
-          assert(hintTL->size() > size, "hint is inconsistent");
-          if (hintTL->surplus() > 0) {
-            // The hint led to a list that has a surplus.  Use it.
-            // Set the hint for the candidate to an overpopulated
-            // size.
-            curTL->set_hint(hintTL->size());
-            // Change the candidate.
-            curTL = hintTL;
-            break;
-          }
-          // The evm code reset the hint of the candidate as
-          // at an interim point.  Why?  Seems like this leaves
-          // the hint pointing to a list that didn't work.
-          // curTL->set_hint(hintTL->size());
-        }
-      }
-    }
-    // don't waste time splaying if chunk's singleton
-    if (splay && curTL->head()->next() != NULL) {
-      semiSplayStep(curTL);
-    }
-    retTC = curTL->first_available();
-    assert((retTC != NULL) && (curTL->count() > 0),
-      "A list in the binary tree should not be NULL");
-    assert(retTC->size() >= size,
-      "A chunk of the wrong size was found");
-    removeChunkFromTree(retTC);
-    assert(retTC->isFree(), "Header is not marked correctly");
-  }
-
-  if (FLSVerifyDictionary) {
-    verify();
-  }
-  return retTC;
-}
-
-TreeList* BinaryTreeDictionary::findList(size_t size) const {
-  TreeList* curTL;
-  for (curTL = root(); curTL != NULL;) {
-    if (curTL->size() == size) {        // exact match
-      break;
-    }
-
-    if (curTL->size() < size) {        // proceed to right sub-tree
-      curTL = curTL->right();
-    } else {                           // proceed to left sub-tree
-      assert(curTL->size() > size, "size inconsistency");
-      curTL = curTL->left();
-    }
-  }
-  return curTL;
-}
-
-
-bool BinaryTreeDictionary::verifyChunkInFreeLists(FreeChunk* tc) const {
-  size_t size = tc->size();
-  TreeList* tl = findList(size);
-  if (tl == NULL) {
-    return false;
-  } else {
-    return tl->verifyChunkInFreeLists(tc);
-  }
-}
-
-FreeChunk* BinaryTreeDictionary::findLargestDict() const {
-  TreeList *curTL = root();
-  if (curTL != NULL) {
-    while(curTL->right() != NULL) curTL = curTL->right();
-    return curTL->largest_address();
-  } else {
-    return NULL;
-  }
-}
-
-// Remove the current chunk from the tree.  If it is not the last
-// chunk in a list on a tree node, just unlink it.
-// If it is the last chunk in the list (the next link is NULL),
-// remove the node and repair the tree.
-TreeChunk*
-BinaryTreeDictionary::removeChunkFromTree(TreeChunk* tc) {
-  assert(tc != NULL, "Should not call with a NULL chunk");
-  assert(tc->isFree(), "Header is not marked correctly");
-
-  TreeList *newTL, *parentTL;
-  TreeChunk* retTC;
-  TreeList* tl = tc->list();
-  debug_only(
-    bool removing_only_chunk = false;
-    if (tl == _root) {
-      if ((_root->left() == NULL) && (_root->right() == NULL)) {
-        if (_root->count() == 1) {
-          assert(_root->head() == tc, "Should only be this one chunk");
-          removing_only_chunk = true;
-        }
-      }
-    }
-  )
-  assert(tl != NULL, "List should be set");
-  assert(tl->parent() == NULL || tl == tl->parent()->left() ||
-         tl == tl->parent()->right(), "list is inconsistent");
-
-  bool complicatedSplice = false;
-
-  retTC = tc;
-  // Removing this chunk can have the side effect of changing the node
-  // (TreeList*) in the tree.  If the node is the root, update it.
-  TreeList* replacementTL = tl->removeChunkReplaceIfNeeded(tc);
-  assert(tc->isFree(), "Chunk should still be free");
-  assert(replacementTL->parent() == NULL ||
-         replacementTL == replacementTL->parent()->left() ||
-         replacementTL == replacementTL->parent()->right(),
-         "list is inconsistent");
-  if (tl == root()) {
-    assert(replacementTL->parent() == NULL, "Incorrectly replacing root");
-    set_root(replacementTL);
-  }
-  debug_only(
-    if (tl != replacementTL) {
-      assert(replacementTL->head() != NULL,
-        "If the tree list was replaced, it should not be a NULL list");
-      TreeList* rhl = replacementTL->head_as_TreeChunk()->list();
-      TreeList* rtl = TreeChunk::as_TreeChunk(replacementTL->tail())->list();
-      assert(rhl == replacementTL, "Broken head");
-      assert(rtl == replacementTL, "Broken tail");
-      assert(replacementTL->size() == tc->size(),  "Broken size");
-    }
-  )
-
-  // Does the tree need to be repaired?
-  if (replacementTL->count() == 0) {
-    assert(replacementTL->head() == NULL &&
-           replacementTL->tail() == NULL, "list count is incorrect");
-    // Find the replacement node for the (soon to be empty) node being removed.
-    // if we have a single (or no) child, splice child in our stead
-    if (replacementTL->left() == NULL) {
-      // left is NULL so pick right.  right may also be NULL.
-      newTL = replacementTL->right();
-      debug_only(replacementTL->clearRight();)
-    } else if (replacementTL->right() == NULL) {
-      // right is NULL
-      newTL = replacementTL->left();
-      debug_only(replacementTL->clearLeft();)
-    } else {  // we have both children, so, by patriarchal convention,
-              // my replacement is least node in right sub-tree
-      complicatedSplice = true;
-      newTL = removeTreeMinimum(replacementTL->right());
-      assert(newTL != NULL && newTL->left() == NULL &&
-             newTL->right() == NULL, "sub-tree minimum exists");
-    }
-    // newTL is the replacement for the (soon to be empty) node.
-    // newTL may be NULL.
-    // should verify; we just cleanly excised our replacement
-    if (FLSVerifyDictionary) {
-      verifyTree();
-    }
-    // first make newTL my parent's child
-    if ((parentTL = replacementTL->parent()) == NULL) {
-      // newTL should be root
-      assert(tl == root(), "Incorrectly replacing root");
-      set_root(newTL);
-      if (newTL != NULL) {
-        newTL->clearParent();
-      }
-    } else if (parentTL->right() == replacementTL) {
-      // replacementTL is a right child
-      parentTL->setRight(newTL);
-    } else {                                // replacementTL is a left child
-      assert(parentTL->left() == replacementTL, "should be left child");
-      parentTL->setLeft(newTL);
-    }
-    debug_only(replacementTL->clearParent();)
-    if (complicatedSplice) {  // we need newTL to get replacementTL's
-                              // two children
-      assert(newTL != NULL &&
-             newTL->left() == NULL && newTL->right() == NULL,
-            "newTL should not have encumbrances from the past");
-      // we'd like to assert as below:
-      // assert(replacementTL->left() != NULL && replacementTL->right() != NULL,
-      //       "else !complicatedSplice");
-      // ... however, the above assertion is too strong because we aren't
-      // guaranteed that replacementTL->right() is still NULL.
-      // Recall that we removed
-      // the right sub-tree minimum from replacementTL.
-      // That may well have been its right
-      // child! So we'll just assert half of the above:
-      assert(replacementTL->left() != NULL, "else !complicatedSplice");
-      newTL->setLeft(replacementTL->left());
-      newTL->setRight(replacementTL->right());
-      debug_only(
-        replacementTL->clearRight();
-        replacementTL->clearLeft();
-      )
-    }
-    assert(replacementTL->right() == NULL &&
-           replacementTL->left() == NULL &&
-           replacementTL->parent() == NULL,
-        "delete without encumbrances");
-  }
-
-  assert(totalSize() >= retTC->size(), "Incorrect total size");
-  dec_totalSize(retTC->size());     // size book-keeping
-  assert(totalFreeBlocks() > 0, "Incorrect total count");
-  set_totalFreeBlocks(totalFreeBlocks() - 1);
-
-  assert(retTC != NULL, "null chunk?");
-  assert(retTC->prev() == NULL && retTC->next() == NULL,
-         "should return without encumbrances");
-  if (FLSVerifyDictionary) {
-    verifyTree();
-  }
-  assert(!removing_only_chunk || _root == NULL, "root should be NULL");
-  return TreeChunk::as_TreeChunk(retTC);
-}
-
-// Remove the leftmost node (lm) in the tree and return it.
-// If lm has a right child, link it to the left node of
-// the parent of lm.
-TreeList* BinaryTreeDictionary::removeTreeMinimum(TreeList* tl) {
-  assert(tl != NULL && tl->parent() != NULL, "really need a proper sub-tree");
-  // locate the subtree minimum by walking down left branches
-  TreeList* curTL = tl;
-  for (; curTL->left() != NULL; curTL = curTL->left());
-  // obviously curTL now has at most one child, a right child
-  if (curTL != root()) {  // Should this test just be removed?
-    TreeList* parentTL = curTL->parent();
-    if (parentTL->left() == curTL) { // curTL is a left child
-      parentTL->setLeft(curTL->right());
-    } else {
-      // If the list tl has no left child, then curTL may be
-      // the right child of parentTL.
-      assert(parentTL->right() == curTL, "should be a right child");
-      parentTL->setRight(curTL->right());
-    }
-  } else {
-    // The only use of this method would not pass the root of the
-    // tree (as indicated by the assertion above that the tree list
-    // has a parent) but the specification does not explicitly exclude the
-    // passing of the root so accomodate it.
-    set_root(NULL);
-  }
-  debug_only(
-    curTL->clearParent();  // Test if this needs to be cleared
-    curTL->clearRight();    // recall, above, left child is already null
-  )
-  // we just excised a (non-root) node, we should still verify all tree invariants
-  if (FLSVerifyDictionary) {
-    verifyTree();
-  }
-  return curTL;
-}
-
-// Based on a simplification of the algorithm by Sleator and Tarjan (JACM 1985).
-// The simplifications are the following:
-// . we splay only when we delete (not when we insert)
-// . we apply a single spay step per deletion/access
-// By doing such partial splaying, we reduce the amount of restructuring,
-// while getting a reasonably efficient search tree (we think).
-// [Measurements will be needed to (in)validate this expectation.]
-
-void BinaryTreeDictionary::semiSplayStep(TreeList* tc) {
-  // apply a semi-splay step at the given node:
-  // . if root, norting needs to be done
-  // . if child of root, splay once
-  // . else zig-zig or sig-zag depending on path from grandparent
-  if (root() == tc) return;
-  warning("*** Splaying not yet implemented; "
-          "tree operations may be inefficient ***");
-}
-
-void BinaryTreeDictionary::insertChunkInTree(FreeChunk* fc) {
-  TreeList *curTL, *prevTL;
-  size_t size = fc->size();
-
-  assert(size >= MIN_TREE_CHUNK_SIZE, "too small to be a TreeList");
-  if (FLSVerifyDictionary) {
-    verifyTree();
-  }
-  // XXX: do i need to clear the FreeChunk fields, let me do it just in case
-  // Revisit this later
-
-  fc->clearNext();
-  fc->linkPrev(NULL);
-
-  // work down from the _root, looking for insertion point
-  for (prevTL = curTL = root(); curTL != NULL;) {
-    if (curTL->size() == size)  // exact match
-      break;
-    prevTL = curTL;
-    if (curTL->size() > size) { // follow left branch
-      curTL = curTL->left();
-    } else {                    // follow right branch
-      assert(curTL->size() < size, "size inconsistency");
-      curTL = curTL->right();
-    }
-  }
-  TreeChunk* tc = TreeChunk::as_TreeChunk(fc);
-  // This chunk is being returned to the binary tree.  Its embedded
-  // TreeList should be unused at this point.
-  tc->initialize();
-  if (curTL != NULL) {          // exact match
-    tc->set_list(curTL);
-    curTL->returnChunkAtTail(tc);
-  } else {                     // need a new node in tree
-    tc->clearNext();
-    tc->linkPrev(NULL);
-    TreeList* newTL = TreeList::as_TreeList(tc);
-    assert(((TreeChunk*)tc)->list() == newTL,
-      "List was not initialized correctly");
-    if (prevTL == NULL) {      // we are the only tree node
-      assert(root() == NULL, "control point invariant");
-      set_root(newTL);
-    } else {                   // insert under prevTL ...
-      if (prevTL->size() < size) {   // am right child
-        assert(prevTL->right() == NULL, "control point invariant");
-        prevTL->setRight(newTL);
-      } else {                       // am left child
-        assert(prevTL->size() > size && prevTL->left() == NULL, "cpt pt inv");
-        prevTL->setLeft(newTL);
-      }
-    }
-  }
-  assert(tc->list() != NULL, "Tree list should be set");
-
-  inc_totalSize(size);
-  // Method 'totalSizeInTree' walks through the every block in the
-  // tree, so it can cause significant performance loss if there are
-  // many blocks in the tree
-  assert(!FLSVerifyDictionary || totalSizeInTree(root()) == totalSize(), "_totalSize inconsistency");
-  set_totalFreeBlocks(totalFreeBlocks() + 1);
-  if (FLSVerifyDictionary) {
-    verifyTree();
-  }
-}
-
-size_t BinaryTreeDictionary::maxChunkSize() const {
-  verify_par_locked();
-  TreeList* tc = root();
-  if (tc == NULL) return 0;
-  for (; tc->right() != NULL; tc = tc->right());
-  return tc->size();
-}
-
-size_t BinaryTreeDictionary::totalListLength(TreeList* tl) const {
-  size_t res;
-  res = tl->count();
-#ifdef ASSERT
-  size_t cnt;
-  FreeChunk* tc = tl->head();
-  for (cnt = 0; tc != NULL; tc = tc->next(), cnt++);
-  assert(res == cnt, "The count is not being maintained correctly");
-#endif
-  return res;
-}
-
-size_t BinaryTreeDictionary::totalSizeInTree(TreeList* tl) const {
-  if (tl == NULL)
-    return 0;
-  return (tl->size() * totalListLength(tl)) +
-         totalSizeInTree(tl->left())    +
-         totalSizeInTree(tl->right());
-}
-
-double BinaryTreeDictionary::sum_of_squared_block_sizes(TreeList* const tl) const {
-  if (tl == NULL) {
-    return 0.0;
-  }
-  double size = (double)(tl->size());
-  double curr = size * size * totalListLength(tl);
-  curr += sum_of_squared_block_sizes(tl->left());
-  curr += sum_of_squared_block_sizes(tl->right());
-  return curr;
-}
-
-size_t BinaryTreeDictionary::totalFreeBlocksInTree(TreeList* tl) const {
-  if (tl == NULL)
-    return 0;
-  return totalListLength(tl) +
-         totalFreeBlocksInTree(tl->left()) +
-         totalFreeBlocksInTree(tl->right());
-}
-
-size_t BinaryTreeDictionary::numFreeBlocks() const {
-  assert(totalFreeBlocksInTree(root()) == totalFreeBlocks(),
-         "_totalFreeBlocks inconsistency");
-  return totalFreeBlocks();
-}
-
-size_t BinaryTreeDictionary::treeHeightHelper(TreeList* tl) const {
-  if (tl == NULL)
-    return 0;
-  return 1 + MAX2(treeHeightHelper(tl->left()),
-                  treeHeightHelper(tl->right()));
-}
-
-size_t BinaryTreeDictionary::treeHeight() const {
-  return treeHeightHelper(root());
-}
-
-size_t BinaryTreeDictionary::totalNodesHelper(TreeList* tl) const {
-  if (tl == NULL) {
-    return 0;
-  }
-  return 1 + totalNodesHelper(tl->left()) +
-    totalNodesHelper(tl->right());
-}
-
-size_t BinaryTreeDictionary::totalNodesInTree(TreeList* tl) const {
-  return totalNodesHelper(root());
-}
-
-void BinaryTreeDictionary::dictCensusUpdate(size_t size, bool split, bool birth){
-  TreeList* nd = findList(size);
-  if (nd) {
-    if (split) {
-      if (birth) {
-        nd->increment_splitBirths();
-        nd->increment_surplus();
-      }  else {
-        nd->increment_splitDeaths();
-        nd->decrement_surplus();
-      }
-    } else {
-      if (birth) {
-        nd->increment_coalBirths();
-        nd->increment_surplus();
-      } else {
-        nd->increment_coalDeaths();
-        nd->decrement_surplus();
-      }
-    }
-  }
-  // A list for this size may not be found (nd == 0) if
-  //   This is a death where the appropriate list is now
-  //     empty and has been removed from the list.
-  //   This is a birth associated with a LinAB.  The chunk
-  //     for the LinAB is not in the dictionary.
-}
-
-bool BinaryTreeDictionary::coalDictOverPopulated(size_t size) {
-  if (FLSAlwaysCoalesceLarge) return true;
-
-  TreeList* list_of_size = findList(size);
-  // None of requested size implies overpopulated.
-  return list_of_size == NULL || list_of_size->coalDesired() <= 0 ||
-         list_of_size->count() > list_of_size->coalDesired();
-}
-
-// Closures for walking the binary tree.
-//   do_list() walks the free list in a node applying the closure
-//     to each free chunk in the list
-//   do_tree() walks the nodes in the binary tree applying do_list()
-//     to each list at each node.
-
-class TreeCensusClosure : public StackObj {
- protected:
-  virtual void do_list(FreeList* fl) = 0;
- public:
-  virtual void do_tree(TreeList* tl) = 0;
-};
-
-class AscendTreeCensusClosure : public TreeCensusClosure {
- public:
-  void do_tree(TreeList* tl) {
-    if (tl != NULL) {
-      do_tree(tl->left());
-      do_list(tl);
-      do_tree(tl->right());
-    }
-  }
-};
-
-class DescendTreeCensusClosure : public TreeCensusClosure {
- public:
-  void do_tree(TreeList* tl) {
-    if (tl != NULL) {
-      do_tree(tl->right());
-      do_list(tl);
-      do_tree(tl->left());
-    }
-  }
-};
-
-// For each list in the tree, calculate the desired, desired
-// coalesce, count before sweep, and surplus before sweep.
-class BeginSweepClosure : public AscendTreeCensusClosure {
-  double _percentage;
-  float _inter_sweep_current;
-  float _inter_sweep_estimate;
-  float _intra_sweep_estimate;
-
- public:
-  BeginSweepClosure(double p, float inter_sweep_current,
-                              float inter_sweep_estimate,
-                              float intra_sweep_estimate) :
-   _percentage(p),
-   _inter_sweep_current(inter_sweep_current),
-   _inter_sweep_estimate(inter_sweep_estimate),
-   _intra_sweep_estimate(intra_sweep_estimate) { }
-
-  void do_list(FreeList* fl) {
-    double coalSurplusPercent = _percentage;
-    fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate, _intra_sweep_estimate);
-    fl->set_coalDesired((ssize_t)((double)fl->desired() * coalSurplusPercent));
-    fl->set_beforeSweep(fl->count());
-    fl->set_bfrSurp(fl->surplus());
-  }
-};
-
-// Used to search the tree until a condition is met.
-// Similar to TreeCensusClosure but searches the
-// tree and returns promptly when found.
-
-class TreeSearchClosure : public StackObj {
- protected:
-  virtual bool do_list(FreeList* fl) = 0;
- public:
-  virtual bool do_tree(TreeList* tl) = 0;
-};
-
-#if 0 //  Don't need this yet but here for symmetry.
-class AscendTreeSearchClosure : public TreeSearchClosure {
- public:
-  bool do_tree(TreeList* tl) {
-    if (tl != NULL) {
-      if (do_tree(tl->left())) return true;
-      if (do_list(tl)) return true;
-      if (do_tree(tl->right())) return true;
-    }
-    return false;
-  }
-};
-#endif
-
-class DescendTreeSearchClosure : public TreeSearchClosure {
- public:
-  bool do_tree(TreeList* tl) {
-    if (tl != NULL) {
-      if (do_tree(tl->right())) return true;
-      if (do_list(tl)) return true;
-      if (do_tree(tl->left())) return true;
-    }
-    return false;
-  }
-};
-
-// Searches the tree for a chunk that ends at the
-// specified address.
-class EndTreeSearchClosure : public DescendTreeSearchClosure {
-  HeapWord* _target;
-  FreeChunk* _found;
-
- public:
-  EndTreeSearchClosure(HeapWord* target) : _target(target), _found(NULL) {}
-  bool do_list(FreeList* fl) {
-    FreeChunk* item = fl->head();
-    while (item != NULL) {
-      if (item->end() == _target) {
-        _found = item;
-        return true;
-      }
-      item = item->next();
-    }
-    return false;
-  }
-  FreeChunk* found() { return _found; }
-};
-
-FreeChunk* BinaryTreeDictionary::find_chunk_ends_at(HeapWord* target) const {
-  EndTreeSearchClosure etsc(target);
-  bool found_target = etsc.do_tree(root());
-  assert(found_target || etsc.found() == NULL, "Consistency check");
-  assert(!found_target || etsc.found() != NULL, "Consistency check");
-  return etsc.found();
-}
-
-void BinaryTreeDictionary::beginSweepDictCensus(double coalSurplusPercent,
-  float inter_sweep_current, float inter_sweep_estimate, float intra_sweep_estimate) {
-  BeginSweepClosure bsc(coalSurplusPercent, inter_sweep_current,
-                                            inter_sweep_estimate,
-                                            intra_sweep_estimate);
-  bsc.do_tree(root());
-}
-
-// Closures and methods for calculating total bytes returned to the
-// free lists in the tree.
-NOT_PRODUCT(
-  class InitializeDictReturnedBytesClosure : public AscendTreeCensusClosure {
-   public:
-    void do_list(FreeList* fl) {
-      fl->set_returnedBytes(0);
-    }
-  };
-
-  void BinaryTreeDictionary::initializeDictReturnedBytes() {
-    InitializeDictReturnedBytesClosure idrb;
-    idrb.do_tree(root());
-  }
-
-  class ReturnedBytesClosure : public AscendTreeCensusClosure {
-    size_t _dictReturnedBytes;
-   public:
-    ReturnedBytesClosure() { _dictReturnedBytes = 0; }
-    void do_list(FreeList* fl) {
-      _dictReturnedBytes += fl->returnedBytes();
-    }
-    size_t dictReturnedBytes() { return _dictReturnedBytes; }
-  };
-
-  size_t BinaryTreeDictionary::sumDictReturnedBytes() {
-    ReturnedBytesClosure rbc;
-    rbc.do_tree(root());
-
-    return rbc.dictReturnedBytes();
-  }
-
-  // Count the number of entries in the tree.
-  class treeCountClosure : public DescendTreeCensusClosure {
-   public:
-    uint count;
-    treeCountClosure(uint c) { count = c; }
-    void do_list(FreeList* fl) {
-      count++;
-    }
-  };
-
-  size_t BinaryTreeDictionary::totalCount() {
-    treeCountClosure ctc(0);
-    ctc.do_tree(root());
-    return ctc.count;
-  }
-)
-
-// Calculate surpluses for the lists in the tree.
-class setTreeSurplusClosure : public AscendTreeCensusClosure {
-  double percentage;
- public:
-  setTreeSurplusClosure(double v) { percentage = v; }
-  void do_list(FreeList* fl) {
-    double splitSurplusPercent = percentage;
-    fl->set_surplus(fl->count() -
-                   (ssize_t)((double)fl->desired() * splitSurplusPercent));
-  }
-};
-
-void BinaryTreeDictionary::setTreeSurplus(double splitSurplusPercent) {
-  setTreeSurplusClosure sts(splitSurplusPercent);
-  sts.do_tree(root());
-}
-
-// Set hints for the lists in the tree.
-class setTreeHintsClosure : public DescendTreeCensusClosure {
-  size_t hint;
- public:
-  setTreeHintsClosure(size_t v) { hint = v; }
-  void do_list(FreeList* fl) {
-    fl->set_hint(hint);
-    assert(fl->hint() == 0 || fl->hint() > fl->size(),
-      "Current hint is inconsistent");
-    if (fl->surplus() > 0) {
-      hint = fl->size();
-    }
-  }
-};
-
-void BinaryTreeDictionary::setTreeHints(void) {
-  setTreeHintsClosure sth(0);
-  sth.do_tree(root());
-}
-
-// Save count before previous sweep and splits and coalesces.
-class clearTreeCensusClosure : public AscendTreeCensusClosure {
-  void do_list(FreeList* fl) {
-    fl->set_prevSweep(fl->count());
-    fl->set_coalBirths(0);
-    fl->set_coalDeaths(0);
-    fl->set_splitBirths(0);
-    fl->set_splitDeaths(0);
-  }
-};
-
-void BinaryTreeDictionary::clearTreeCensus(void) {
-  clearTreeCensusClosure ctc;
-  ctc.do_tree(root());
-}
-
-// Do reporting and post sweep clean up.
-void BinaryTreeDictionary::endSweepDictCensus(double splitSurplusPercent) {
-  // Does walking the tree 3 times hurt?
-  setTreeSurplus(splitSurplusPercent);
-  setTreeHints();
-  if (PrintGC && Verbose) {
-    reportStatistics();
-  }
-  clearTreeCensus();
-}
-
-// Print summary statistics
-void BinaryTreeDictionary::reportStatistics() const {
-  verify_par_locked();
-  gclog_or_tty->print("Statistics for BinaryTreeDictionary:\n"
-         "------------------------------------\n");
-  size_t totalSize = totalChunkSize(debug_only(NULL));
-  size_t    freeBlocks = numFreeBlocks();
-  gclog_or_tty->print("Total Free Space: %d\n", totalSize);
-  gclog_or_tty->print("Max   Chunk Size: %d\n", maxChunkSize());
-  gclog_or_tty->print("Number of Blocks: %d\n", freeBlocks);
-  if (freeBlocks > 0) {
-    gclog_or_tty->print("Av.  Block  Size: %d\n", totalSize/freeBlocks);
-  }
-  gclog_or_tty->print("Tree      Height: %d\n", treeHeight());
-}
-
-// Print census information - counts, births, deaths, etc.
-// for each list in the tree.  Also print some summary
-// information.
-class PrintTreeCensusClosure : public AscendTreeCensusClosure {
-  int _print_line;
-  size_t _totalFree;
-  FreeList _total;
-
- public:
-  PrintTreeCensusClosure() {
-    _print_line = 0;
-    _totalFree = 0;
-  }
-  FreeList* total() { return &_total; }
-  size_t totalFree() { return _totalFree; }
-  void do_list(FreeList* fl) {
-    if (++_print_line >= 40) {
-      FreeList::print_labels_on(gclog_or_tty, "size");
-      _print_line = 0;
-    }
-    fl->print_on(gclog_or_tty);
-    _totalFree +=            fl->count()            * fl->size()        ;
-    total()->set_count(      total()->count()       + fl->count()      );
-    total()->set_bfrSurp(    total()->bfrSurp()     + fl->bfrSurp()    );
-    total()->set_surplus(    total()->splitDeaths() + fl->surplus()    );
-    total()->set_desired(    total()->desired()     + fl->desired()    );
-    total()->set_prevSweep(  total()->prevSweep()   + fl->prevSweep()  );
-    total()->set_beforeSweep(total()->beforeSweep() + fl->beforeSweep());
-    total()->set_coalBirths( total()->coalBirths()  + fl->coalBirths() );
-    total()->set_coalDeaths( total()->coalDeaths()  + fl->coalDeaths() );
-    total()->set_splitBirths(total()->splitBirths() + fl->splitBirths());
-    total()->set_splitDeaths(total()->splitDeaths() + fl->splitDeaths());
-  }
-};
-
-void BinaryTreeDictionary::printDictCensus(void) const {
-
-  gclog_or_tty->print("\nBinaryTree\n");
-  FreeList::print_labels_on(gclog_or_tty, "size");
-  PrintTreeCensusClosure ptc;
-  ptc.do_tree(root());
-
-  FreeList* total = ptc.total();
-  FreeList::print_labels_on(gclog_or_tty, " ");
-  total->print_on(gclog_or_tty, "TOTAL\t");
-  gclog_or_tty->print(
-              "totalFree(words): " SIZE_FORMAT_W(16)
-              " growth: %8.5f  deficit: %8.5f\n",
-              ptc.totalFree(),
-              (double)(total->splitBirths() + total->coalBirths()
-                     - total->splitDeaths() - total->coalDeaths())
-              /(total->prevSweep() != 0 ? (double)total->prevSweep() : 1.0),
-             (double)(total->desired() - total->count())
-             /(total->desired() != 0 ? (double)total->desired() : 1.0));
-}
-
-class PrintFreeListsClosure : public AscendTreeCensusClosure {
-  outputStream* _st;
-  int _print_line;
-
- public:
-  PrintFreeListsClosure(outputStream* st) {
-    _st = st;
-    _print_line = 0;
-  }
-  void do_list(FreeList* fl) {
-    if (++_print_line >= 40) {
-      FreeList::print_labels_on(_st, "size");
-      _print_line = 0;
-    }
-    fl->print_on(gclog_or_tty);
-    size_t sz = fl->size();
-    for (FreeChunk* fc = fl->head(); fc != NULL;
-         fc = fc->next()) {
-      _st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ")  %s",
-                    fc, (HeapWord*)fc + sz,
-                    fc->cantCoalesce() ? "\t CC" : "");
-    }
-  }
-};
-
-void BinaryTreeDictionary::print_free_lists(outputStream* st) const {
-
-  FreeList::print_labels_on(st, "size");
-  PrintFreeListsClosure pflc(st);
-  pflc.do_tree(root());
-}
-
-// Verify the following tree invariants:
-// . _root has no parent
-// . parent and child point to each other
-// . each node's key correctly related to that of its child(ren)
-void BinaryTreeDictionary::verifyTree() const {
-  guarantee(root() == NULL || totalFreeBlocks() == 0 ||
-    totalSize() != 0, "_totalSize should't be 0?");
-  guarantee(root() == NULL || root()->parent() == NULL, "_root shouldn't have parent");
-  verifyTreeHelper(root());
-}
-
-size_t BinaryTreeDictionary::verifyPrevFreePtrs(TreeList* tl) {
-  size_t ct = 0;
-  for (FreeChunk* curFC = tl->head(); curFC != NULL; curFC = curFC->next()) {
-    ct++;
-    assert(curFC->prev() == NULL || curFC->prev()->isFree(),
-      "Chunk should be free");
-  }
-  return ct;
-}
-
-// Note: this helper is recursive rather than iterative, so use with
-// caution on very deep trees; and watch out for stack overflow errors;
-// In general, to be used only for debugging.
-void BinaryTreeDictionary::verifyTreeHelper(TreeList* tl) const {
-  if (tl == NULL)
-    return;
-  guarantee(tl->size() != 0, "A list must has a size");
-  guarantee(tl->left()  == NULL || tl->left()->parent()  == tl,
-         "parent<-/->left");
-  guarantee(tl->right() == NULL || tl->right()->parent() == tl,
-         "parent<-/->right");;
-  guarantee(tl->left() == NULL  || tl->left()->size()    <  tl->size(),
-         "parent !> left");
-  guarantee(tl->right() == NULL || tl->right()->size()   >  tl->size(),
-         "parent !< left");
-  guarantee(tl->head() == NULL || tl->head()->isFree(), "!Free");
-  guarantee(tl->head() == NULL || tl->head_as_TreeChunk()->list() == tl,
-    "list inconsistency");
-  guarantee(tl->count() > 0 || (tl->head() == NULL && tl->tail() == NULL),
-    "list count is inconsistent");
-  guarantee(tl->count() > 1 || tl->head() == tl->tail(),
-    "list is incorrectly constructed");
-  size_t count = verifyPrevFreePtrs(tl);
-  guarantee(count == (size_t)tl->count(), "Node count is incorrect");
-  if (tl->head() != NULL) {
-    tl->head_as_TreeChunk()->verifyTreeChunkList();
-  }
-  verifyTreeHelper(tl->left());
-  verifyTreeHelper(tl->right());
-}
-
-void BinaryTreeDictionary::verify() const {
-  verifyTree();
-  guarantee(totalSize() == totalSizeInTree(root()), "Total Size inconsistency");
-}
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp
deleted file mode 100644
index f06f8d3..0000000
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp
+++ /dev/null
@@ -1,296 +0,0 @@
-/*
- * 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
- * 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.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_BINARYTREEDICTIONARY_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_BINARYTREEDICTIONARY_HPP
-
-#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp"
-#include "gc_implementation/concurrentMarkSweep/freeList.hpp"
-
-/*
- * A binary tree based search structure for free blocks.
- * This is currently used in the Concurrent Mark&Sweep implementation.
- */
-
-// A TreeList is a FreeList which can be used to maintain a
-// binary tree of free lists.
-
-class TreeChunk;
-class BinaryTreeDictionary;
-class AscendTreeCensusClosure;
-class DescendTreeCensusClosure;
-class DescendTreeSearchClosure;
-
-class TreeList: public FreeList {
-  friend class TreeChunk;
-  friend class BinaryTreeDictionary;
-  friend class AscendTreeCensusClosure;
-  friend class DescendTreeCensusClosure;
-  friend class DescendTreeSearchClosure;
-
- protected:
-  TreeList* parent() const { return _parent; }
-  TreeList* left()   const { return _left;   }
-  TreeList* right()  const { return _right;  }
-
-  // Accessors for links in tree.
-
-  void setLeft(TreeList* tl) {
-    _left   = tl;
-    if (tl != NULL)
-      tl->setParent(this);
-  }
-  void setRight(TreeList* tl) {
-    _right  = tl;
-    if (tl != NULL)
-      tl->setParent(this);
-  }
-  void setParent(TreeList* tl)  { _parent = tl;   }
-
-  void clearLeft()               { _left = NULL;   }
-  void clearRight()              { _right = NULL;  }
-  void clearParent()             { _parent = NULL; }
-  void initialize()              { clearLeft(); clearRight(), clearParent(); }
-
-  // For constructing a TreeList from a Tree chunk or
-  // address and size.
-  static TreeList* as_TreeList(TreeChunk* tc);
-  static TreeList* as_TreeList(HeapWord* addr, size_t size);
-
-  // Returns the head of the free list as a pointer to a TreeChunk.
-  TreeChunk* head_as_TreeChunk();
-
-  // Returns the first available chunk in the free list as a pointer
-  // to a TreeChunk.
-  TreeChunk* first_available();
-
-  // Returns the block with the largest heap address amongst
-  // those in the list for this size; potentially slow and expensive,
-  // use with caution!
-  TreeChunk* largest_address();
-
-  // removeChunkReplaceIfNeeded() removes the given "tc" from the TreeList.
-  // If "tc" is the first chunk in the list, it is also the
-  // TreeList that is the node in the tree.  removeChunkReplaceIfNeeded()
-  // returns the possibly replaced TreeList* for the node in
-  // the tree.  It also updates the parent of the original
-  // node to point to the new node.
-  TreeList* removeChunkReplaceIfNeeded(TreeChunk* tc);
-  // See FreeList.
-  void returnChunkAtHead(TreeChunk* tc);
-  void returnChunkAtTail(TreeChunk* tc);
-};
-
-// A TreeChunk is a subclass of a FreeChunk that additionally
-// maintains a pointer to the free list on which it is currently
-// linked.
-// A TreeChunk is also used as a node in the binary tree.  This
-// allows the binary tree to be maintained without any additional
-// storage (the free chunks are used).  In a binary tree the first
-// chunk in the free list is also the tree node.  Note that the
-// TreeChunk has an embedded TreeList for this purpose.  Because
-// the first chunk in the list is distinguished in this fashion
-// (also is the node in the tree), it is the last chunk to be found
-// on the free list for a node in the tree and is only removed if
-// it is the last chunk on the free list.
-
-class TreeChunk : public FreeChunk {
-  friend class TreeList;
-  TreeList* _list;
-  TreeList _embedded_list;  // if non-null, this chunk is on _list
- protected:
-  TreeList* embedded_list() const { return (TreeList*) &_embedded_list; }
-  void set_embedded_list(TreeList* v) { _embedded_list = *v; }
- public:
-  TreeList* list() { return _list; }
-  void set_list(TreeList* v) { _list = v; }
-  static TreeChunk* as_TreeChunk(FreeChunk* fc);
-  // Initialize fields in a TreeChunk that should be
-  // initialized when the TreeChunk is being added to
-  // a free list in the tree.
-  void initialize() { embedded_list()->initialize(); }
-
-  // debugging
-  void verifyTreeChunkList() const;
-};
-
-const size_t MIN_TREE_CHUNK_SIZE  = sizeof(TreeChunk)/HeapWordSize;
-
-class BinaryTreeDictionary: public FreeBlockDictionary {
-  friend class VMStructs;
-  bool       _splay;
-  size_t     _totalSize;
-  size_t     _totalFreeBlocks;
-  TreeList* _root;
-
-  // private accessors
-  bool splay() const { return _splay; }
-  void set_splay(bool v) { _splay = v; }
-  size_t totalSize() const { return _totalSize; }
-  void set_totalSize(size_t v) { _totalSize = v; }
-  virtual void inc_totalSize(size_t v);
-  virtual void dec_totalSize(size_t v);
-  size_t totalFreeBlocks() const { return _totalFreeBlocks; }
-  void set_totalFreeBlocks(size_t v) { _totalFreeBlocks = v; }
-  TreeList* root() const { return _root; }
-  void set_root(TreeList* v) { _root = v; }
-
-  // Remove a chunk of size "size" or larger from the tree and
-  // return it.  If the chunk
-  // is the last chunk of that size, remove the node for that size
-  // from the tree.
-  TreeChunk* getChunkFromTree(size_t size, Dither dither, bool splay);
-  // Return a list of the specified size or NULL from the tree.
-  // The list is not removed from the tree.
-  TreeList* findList (size_t size) const;
-  // Remove this chunk from the tree.  If the removal results
-  // in an empty list in the tree, remove the empty list.
-  TreeChunk* removeChunkFromTree(TreeChunk* tc);
-  // Remove the node in the trees starting at tl that has the
-  // minimum value and return it.  Repair the tree as needed.
-  TreeList* removeTreeMinimum(TreeList* tl);
-  void       semiSplayStep(TreeList* tl);
-  // Add this free chunk to the tree.
-  void       insertChunkInTree(FreeChunk* freeChunk);
- public:
-  void       verifyTree() const;
-  // verify that the given chunk is in the tree.
-  bool       verifyChunkInFreeLists(FreeChunk* tc) const;
- private:
-  void          verifyTreeHelper(TreeList* tl) const;
-  static size_t verifyPrevFreePtrs(TreeList* tl);
-
-  // Returns the total number of chunks in the list.
-  size_t     totalListLength(TreeList* tl) const;
-  // Returns the total number of words in the chunks in the tree
-  // starting at "tl".
-  size_t     totalSizeInTree(TreeList* tl) const;
-  // Returns the sum of the square of the size of each block
-  // in the tree starting at "tl".
-  double     sum_of_squared_block_sizes(TreeList* const tl) const;
-  // Returns the total number of free blocks in the tree starting
-  // at "tl".
-  size_t     totalFreeBlocksInTree(TreeList* tl) const;
-  size_t     numFreeBlocks() const;
-  size_t     treeHeight() const;
-  size_t     treeHeightHelper(TreeList* tl) const;
-  size_t     totalNodesInTree(TreeList* tl) const;
-  size_t     totalNodesHelper(TreeList* tl) const;
-
- public:
-  // Constructor
-  BinaryTreeDictionary(MemRegion mr, bool splay = false);
-
-  // Reset the dictionary to the initial conditions with
-  // a single free chunk.
-  void       reset(MemRegion mr);
-  void       reset(HeapWord* addr, size_t size);
-  // Reset the dictionary to be empty.
-  void       reset();
-
-  // Return a chunk of size "size" or greater from
-  // the tree.
-  // want a better dynamic splay strategy for the future.
-  FreeChunk* getChunk(size_t size, Dither dither) {
-    verify_par_locked();
-    FreeChunk* res = getChunkFromTree(size, dither, splay());
-    assert(res == NULL || res->isFree(),
-           "Should be returning a free chunk");
-    return res;
-  }
-
-  void returnChunk(FreeChunk* chunk) {
-    verify_par_locked();
-    insertChunkInTree(chunk);
-  }
-
-  void removeChunk(FreeChunk* chunk) {
-    verify_par_locked();
-    removeChunkFromTree((TreeChunk*)chunk);
-    assert(chunk->isFree(), "Should still be a free chunk");
-  }
-
-  size_t     maxChunkSize() const;
-  size_t     totalChunkSize(debug_only(const Mutex* lock)) const {
-    debug_only(
-      if (lock != NULL && lock->owned_by_self()) {
-        assert(totalSizeInTree(root()) == totalSize(),
-               "_totalSize inconsistency");
-      }
-    )
-    return totalSize();
-  }
-
-  size_t     minSize() const {
-    return MIN_TREE_CHUNK_SIZE;
-  }
-
-  double     sum_of_squared_block_sizes() const {
-    return sum_of_squared_block_sizes(root());
-  }
-
-  FreeChunk* find_chunk_ends_at(HeapWord* target) const;
-
-  // Find the list with size "size" in the binary tree and update
-  // the statistics in the list according to "split" (chunk was
-  // split or coalesce) and "birth" (chunk was added or removed).
-  void       dictCensusUpdate(size_t size, bool split, bool birth);
-  // Return true if the dictionary is overpopulated (more chunks of
-  // this size than desired) for size "size".
-  bool       coalDictOverPopulated(size_t size);
-  // Methods called at the beginning of a sweep to prepare the
-  // statistics for the sweep.
-  void       beginSweepDictCensus(double coalSurplusPercent,
-                                  float inter_sweep_current,
-                                  float inter_sweep_estimate,
-                                  float intra_sweep_estimate);
-  // Methods called after the end of a sweep to modify the
-  // statistics for the sweep.
-  void       endSweepDictCensus(double splitSurplusPercent);
-  // Return the largest free chunk in the tree.
-  FreeChunk* findLargestDict() const;
-  // Accessors for statistics
-  void       setTreeSurplus(double splitSurplusPercent);
-  void       setTreeHints(void);
-  // Reset statistics for all the lists in the tree.
-  void       clearTreeCensus(void);
-  // Print the statistcis for all the lists in the tree.  Also may
-  // print out summaries.
-  void       printDictCensus(void) const;
-  void       print_free_lists(outputStream* st) const;
-
-  // For debugging.  Returns the sum of the _returnedBytes for
-  // all lists in the tree.
-  size_t     sumDictReturnedBytes()     PRODUCT_RETURN0;
-  // Sets the _returnedBytes for all the lists in the tree to zero.
-  void       initializeDictReturnedBytes()      PRODUCT_RETURN;
-  // For debugging.  Return the total number of chunks in the dictionary.
-  size_t     totalCount()       PRODUCT_RETURN0;
-
-  void       reportStatistics() const;
-
-  void       verify() const;
-};
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_BINARYTREEDICTIONARY_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp
index bdcbb46..1c479e5 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.cpp
@@ -38,7 +38,7 @@
 
 CMSPermGen::CMSPermGen(ReservedSpace rs, size_t initial_byte_size,
              CardTableRS* ct,
-             FreeBlockDictionary::DictionaryChoice dictionaryChoice) {
+             FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) {
   CMSPermGenGen* g =
     new CMSPermGenGen(rs, initial_byte_size, -1, ct);
   if (g == NULL) {
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp
index 6d464f7..5151975 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/cmsPermGen.hpp
@@ -45,7 +45,7 @@
 
  public:
   CMSPermGen(ReservedSpace rs, size_t initial_byte_size,
-             CardTableRS* ct, FreeBlockDictionary::DictionaryChoice);
+             CardTableRS* ct, FreeBlockDictionary<FreeChunk>::DictionaryChoice);
 
   HeapWord* mem_allocate(size_t size);
 
@@ -65,7 +65,7 @@
     // regarding not using adaptive free lists for a perm gen.
     ConcurrentMarkSweepGeneration(rs, initial_byte_size, // MinPermHeapExapnsion
       level, ct, false /* use adaptive freelists */,
-      (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice)
+      (FreeBlockDictionary<FreeChunk>::DictionaryChoice)CMSDictionaryChoice)
   {}
 
   void initialize_performance_counters();
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
index 2cb5e2f..6ba15a2 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -58,8 +58,11 @@
 void CompactibleFreeListSpace::set_cms_values() {
   // Set CMS global values
   assert(MinChunkSize == 0, "already set");
-  #define numQuanta(x,y) ((x+y-1)/y)
-  MinChunkSize = numQuanta(sizeof(FreeChunk), MinObjAlignmentInBytes) * MinObjAlignment;
+
+  // MinChunkSize should be a multiple of MinObjAlignment and be large enough
+  // for chunks to contain a FreeChunk.
+  size_t min_chunk_size_in_bytes = align_size_up(sizeof(FreeChunk), MinObjAlignmentInBytes);
+  MinChunkSize = min_chunk_size_in_bytes / BytesPerWord;
 
   assert(IndexSetStart == 0 && IndexSetStride == 0, "already set");
   IndexSetStart  = MinChunkSize;
@@ -69,7 +72,7 @@
 // Constructor
 CompactibleFreeListSpace::CompactibleFreeListSpace(BlockOffsetSharedArray* bs,
   MemRegion mr, bool use_adaptive_freelists,
-  FreeBlockDictionary::DictionaryChoice dictionaryChoice) :
+  FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
   _dictionaryChoice(dictionaryChoice),
   _adaptive_freelists(use_adaptive_freelists),
   _bt(bs, mr),
@@ -87,6 +90,8 @@
                     CMSConcMarkMultiple),
   _collector(NULL)
 {
+  assert(sizeof(FreeChunk) / BytesPerWord <= MinChunkSize,
+    "FreeChunk is larger than expected");
   _bt.set_space(this);
   initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
   // We have all of "mr", all of which we place in the dictionary
@@ -96,13 +101,13 @@
   // implementation, namely, the simple binary tree (splaying
   // temporarily disabled).
   switch (dictionaryChoice) {
-    case FreeBlockDictionary::dictionarySplayTree:
-    case FreeBlockDictionary::dictionarySkipList:
+    case FreeBlockDictionary<FreeChunk>::dictionarySplayTree:
+    case FreeBlockDictionary<FreeChunk>::dictionarySkipList:
     default:
       warning("dictionaryChoice: selected option not understood; using"
               " default BinaryTreeDictionary implementation instead.");
-    case FreeBlockDictionary::dictionaryBinaryTree:
-      _dictionary = new BinaryTreeDictionary(mr);
+    case FreeBlockDictionary<FreeChunk>::dictionaryBinaryTree:
+      _dictionary = new BinaryTreeDictionary<FreeChunk>(mr, use_adaptive_freelists);
       break;
   }
   assert(_dictionary != NULL, "CMS dictionary initialization");
@@ -117,7 +122,7 @@
   // moved to its new location before the klass is moved.
   // Set the _refillSize for the linear allocation blocks
   if (!use_adaptive_freelists) {
-    FreeChunk* fc = _dictionary->getChunk(mr.word_size());
+    FreeChunk* fc = _dictionary->get_chunk(mr.word_size());
     // The small linAB initially has all the space and will allocate
     // a chunk of any size.
     HeapWord* addr = (HeapWord*) fc;
@@ -273,12 +278,12 @@
     assert(mr.word_size() >= MinChunkSize, "Chunk size is too small");
     _bt.single_block(mr.start(), mr.word_size());
     FreeChunk* fc = (FreeChunk*) mr.start();
-    fc->setSize(mr.word_size());
+    fc->set_size(mr.word_size());
     if (mr.word_size() >= IndexSetSize ) {
       returnChunkToDictionary(fc);
     } else {
       _bt.verify_not_unallocated((HeapWord*)fc, fc->size());
-      _indexedFreeList[mr.word_size()].returnChunkAtHead(fc);
+      _indexedFreeList[mr.word_size()].return_chunk_at_head(fc);
     }
   }
   _promoInfo.reset();
@@ -296,7 +301,7 @@
   } else {
     // Place as much of mr in the linAB as we can get,
     // provided it was big enough to go into the dictionary.
-    FreeChunk* fc = dictionary()->findLargestDict();
+    FreeChunk* fc = dictionary()->find_largest_dict();
     if (fc != NULL) {
       assert(fc->size() == mr.word_size(),
              "Why was the chunk broken up?");
@@ -323,14 +328,14 @@
 #ifndef PRODUCT
 void CompactibleFreeListSpace::initializeIndexedFreeListArrayReturnedBytes() {
   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
-    _indexedFreeList[i].allocation_stats()->set_returnedBytes(0);
+    _indexedFreeList[i].allocation_stats()->set_returned_bytes(0);
   }
 }
 
 size_t CompactibleFreeListSpace::sumIndexedFreeListArrayReturnedBytes() {
   size_t sum = 0;
   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
-    sum += _indexedFreeList[i].allocation_stats()->returnedBytes();
+    sum += _indexedFreeList[i].allocation_stats()->returned_bytes();
   }
   return sum;
 }
@@ -354,7 +359,7 @@
 
 size_t CompactibleFreeListSpace::totalCount() {
   size_t num = totalCountInIndexedFreeLists();
-  num +=  dictionary()->totalCount();
+  num +=  dictionary()->total_count();
   if (_smallLinearAllocBlock._word_size != 0) {
     num++;
   }
@@ -364,7 +369,7 @@
 
 bool CompactibleFreeListSpace::is_free_block(const HeapWord* p) const {
   FreeChunk* fc = (FreeChunk*) p;
-  return fc->isFree();
+  return fc->is_free();
 }
 
 size_t CompactibleFreeListSpace::used() const {
@@ -391,7 +396,7 @@
   // that supports jvmstat, and you are apt to see the values
   // flicker in such cases.
   assert(_dictionary != NULL, "No _dictionary?");
-  return (_dictionary->totalChunkSize(DEBUG_ONLY(freelistLock())) +
+  return (_dictionary->total_chunk_size(DEBUG_ONLY(freelistLock())) +
           totalSizeInIndexedFreeLists() +
           _smallLinearAllocBlock._word_size) * HeapWordSize;
 }
@@ -399,7 +404,7 @@
 size_t CompactibleFreeListSpace::max_alloc_in_words() const {
   assert(_dictionary != NULL, "No _dictionary?");
   assert_locked();
-  size_t res = _dictionary->maxChunkSize();
+  size_t res = _dictionary->max_chunk_size();
   res = MAX2(res, MIN2(_smallLinearAllocBlock._word_size,
                        (size_t) SmallForLinearAlloc - 1));
   // XXX the following could potentially be pretty slow;
@@ -448,7 +453,7 @@
   reportIndexedFreeListStatistics();
   gclog_or_tty->print_cr("Layout of Indexed Freelists");
   gclog_or_tty->print_cr("---------------------------");
-  FreeList::print_labels_on(st, "size");
+  FreeList<FreeChunk>::print_labels_on(st, "size");
   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
     _indexedFreeList[i].print_on(gclog_or_tty);
     for (FreeChunk* fc = _indexedFreeList[i].head(); fc != NULL;
@@ -467,7 +472,7 @@
 
 void CompactibleFreeListSpace::print_dictionary_free_lists(outputStream* st)
 const {
-  _dictionary->reportStatistics();
+  _dictionary->report_statistics();
   st->print_cr("Layout of Freelists in Tree");
   st->print_cr("---------------------------");
   _dictionary->print_free_lists(st);
@@ -545,12 +550,12 @@
 void CompactibleFreeListSpace::reportFreeListStatistics() const {
   assert_lock_strong(&_freelistLock);
   assert(PrintFLSStatistics != 0, "Reporting error");
-  _dictionary->reportStatistics();
+  _dictionary->report_statistics();
   if (PrintFLSStatistics > 1) {
     reportIndexedFreeListStatistics();
-    size_t totalSize = totalSizeInIndexedFreeLists() +
-                       _dictionary->totalChunkSize(DEBUG_ONLY(freelistLock()));
-    gclog_or_tty->print(" free=%ld frag=%1.4f\n", totalSize, flsFrag());
+    size_t total_size = totalSizeInIndexedFreeLists() +
+                       _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
+    gclog_or_tty->print(" free=%ld frag=%1.4f\n", total_size, flsFrag());
   }
 }
 
@@ -558,13 +563,13 @@
   assert_lock_strong(&_freelistLock);
   gclog_or_tty->print("Statistics for IndexedFreeLists:\n"
                       "--------------------------------\n");
-  size_t totalSize = totalSizeInIndexedFreeLists();
-  size_t   freeBlocks = numFreeBlocksInIndexedFreeLists();
-  gclog_or_tty->print("Total Free Space: %d\n", totalSize);
+  size_t total_size = totalSizeInIndexedFreeLists();
+  size_t   free_blocks = numFreeBlocksInIndexedFreeLists();
+  gclog_or_tty->print("Total Free Space: %d\n", total_size);
   gclog_or_tty->print("Max   Chunk Size: %d\n", maxChunkSizeInIndexedFreeLists());
-  gclog_or_tty->print("Number of Blocks: %d\n", freeBlocks);
-  if (freeBlocks != 0) {
-    gclog_or_tty->print("Av.  Block  Size: %d\n", totalSize/freeBlocks);
+  gclog_or_tty->print("Number of Blocks: %d\n", free_blocks);
+  if (free_blocks != 0) {
+    gclog_or_tty->print("Av.  Block  Size: %d\n", total_size/free_blocks);
   }
 }
 
@@ -911,7 +916,7 @@
   for (addr = bottom(), last  = end();
        addr < last; addr += size) {
     FreeChunk* fc = (FreeChunk*)addr;
-    if (fc->isFree()) {
+    if (fc->is_free()) {
       // Since we hold the free list lock, which protects direct
       // allocation in this generation by mutators, a free object
       // will remain free throughout this iteration code.
@@ -953,7 +958,7 @@
   for (addr = block_start_careful(mr.start()), end  = mr.end();
        addr < end; addr += size) {
     FreeChunk* fc = (FreeChunk*)addr;
-    if (fc->isFree()) {
+    if (fc->is_free()) {
       // Since we hold the free list lock, which protects direct
       // allocation in this generation by mutators, a free object
       // will remain free throughout this iteration code.
@@ -1069,7 +1074,7 @@
   NOT_PRODUCT(verify_objects_initialized());
   assert(MemRegion(bottom(), end()).contains(p), "p not in space");
   FreeChunk* fc = (FreeChunk*)p;
-  if (fc->isFree()) {
+  if (fc->is_free()) {
     return fc->size();
   } else {
     // Ignore mark word because this may be a recently promoted
@@ -1160,7 +1165,7 @@
   FreeChunk* fc = (FreeChunk*)p;
   assert(is_in_reserved(p), "Should be in space");
   assert(_bt.block_start(p) == p, "Should be a block boundary");
-  if (!fc->isFree()) {
+  if (!fc->is_free()) {
     // Ignore mark word because it may have been used to
     // chain together promoted objects (the last one
     // would have a null value).
@@ -1222,7 +1227,7 @@
 
     FreeChunk* fc = (FreeChunk*)res;
     fc->markNotFree();
-    assert(!fc->isFree(), "shouldn't be marked free");
+    assert(!fc->is_free(), "shouldn't be marked free");
     assert(oop(fc)->klass_or_null() == NULL, "should look uninitialized");
     // Verify that the block offset table shows this to
     // be a single block, but not one which is unallocated.
@@ -1331,10 +1336,10 @@
   size_t currSize = numWords + MinChunkSize;
   assert(currSize % MinObjAlignment == 0, "currSize should be aligned");
   for (i = currSize; i < IndexSetSize; i += IndexSetStride) {
-    FreeList* fl = &_indexedFreeList[i];
+    FreeList<FreeChunk>* fl = &_indexedFreeList[i];
     if (fl->head()) {
       ret = getFromListGreater(fl, numWords);
-      assert(ret == NULL || ret->isFree(), "Should be returning a free chunk");
+      assert(ret == NULL || ret->is_free(), "Should be returning a free chunk");
       return ret;
     }
   }
@@ -1345,7 +1350,7 @@
   /* Try to get a chunk that satisfies request, while avoiding
      fragmentation that can't be handled. */
   {
-    ret =  dictionary()->getChunk(currSize);
+    ret =  dictionary()->get_chunk(currSize);
     if (ret != NULL) {
       assert(ret->size() - numWords >= MinChunkSize,
              "Chunk is too small");
@@ -1353,10 +1358,10 @@
       /* Carve returned chunk. */
       (void) splitChunkAndReturnRemainder(ret, numWords);
       /* Label this as no longer a free chunk. */
-      assert(ret->isFree(), "This chunk should be free");
-      ret->linkPrev(NULL);
+      assert(ret->is_free(), "This chunk should be free");
+      ret->link_prev(NULL);
     }
-    assert(ret == NULL || ret->isFree(), "Should be returning a free chunk");
+    assert(ret == NULL || ret->is_free(), "Should be returning a free chunk");
     return ret;
   }
   ShouldNotReachHere();
@@ -1364,7 +1369,7 @@
 
 bool CompactibleFreeListSpace::verifyChunkInIndexedFreeLists(FreeChunk* fc) const {
   assert(fc->size() < IndexSetSize, "Size of chunk is too large");
-  return _indexedFreeList[fc->size()].verifyChunkInFreeLists(fc);
+  return _indexedFreeList[fc->size()].verify_chunk_in_free_list(fc);
 }
 
 bool CompactibleFreeListSpace::verify_chunk_is_linear_alloc_block(FreeChunk* fc) const {
@@ -1378,13 +1383,13 @@
 // Check if the purported free chunk is present either as a linear
 // allocation block, the size-indexed table of (smaller) free blocks,
 // or the larger free blocks kept in the binary tree dictionary.
-bool CompactibleFreeListSpace::verifyChunkInFreeLists(FreeChunk* fc) const {
+bool CompactibleFreeListSpace::verify_chunk_in_free_list(FreeChunk* fc) const {
   if (verify_chunk_is_linear_alloc_block(fc)) {
     return true;
   } else if (fc->size() < IndexSetSize) {
     return verifyChunkInIndexedFreeLists(fc);
   } else {
-    return dictionary()->verifyChunkInFreeLists(fc);
+    return dictionary()->verify_chunk_in_free_list(fc);
   }
 }
 
@@ -1412,7 +1417,7 @@
   }
   if (fc != NULL) {
     fc->dontCoalesce();
-    assert(fc->isFree(), "Should be free, but not coalescable");
+    assert(fc->is_free(), "Should be free, but not coalescable");
     // Verify that the block offset table shows this to
     // be a single block, but not one which is unallocated.
     _bt.verify_single_block((HeapWord*)fc, fc->size());
@@ -1492,7 +1497,7 @@
     }
     // Return the chunk that isn't big enough, and then refill below.
     addChunkToFreeLists(blk->_ptr, sz);
-    splitBirth(sz);
+    split_birth(sz);
     // Don't keep statistics on adding back chunk from a LinAB.
   } else {
     // A refilled block would not satisfy the request.
@@ -1504,14 +1509,14 @@
   assert(blk->_ptr == NULL || blk->_word_size >= size + MinChunkSize,
          "block was replenished");
   if (res != NULL) {
-    splitBirth(size);
+    split_birth(size);
     repairLinearAllocBlock(blk);
   } else if (blk->_ptr != NULL) {
     res = blk->_ptr;
     size_t blk_size = blk->_word_size;
     blk->_word_size -= size;
     blk->_ptr  += size;
-    splitBirth(size);
+    split_birth(size);
     repairLinearAllocBlock(blk);
     // Update BOT last so that other (parallel) GC threads see a consistent
     // view of the BOT and free blocks.
@@ -1540,7 +1545,7 @@
     size_t blk_size = blk->_word_size;
     blk->_word_size -= size;
     blk->_ptr  += size;
-    splitBirth(size);
+    split_birth(size);
     repairLinearAllocBlock(blk);
     // Update BOT last so that other (parallel) GC threads see a consistent
     // view of the BOT and free blocks.
@@ -1557,7 +1562,7 @@
   assert_locked();
   assert(size < SmallForDictionary, "just checking");
   FreeChunk* res;
-  res = _indexedFreeList[size].getChunkAtHead();
+  res = _indexedFreeList[size].get_chunk_at_head();
   if (res == NULL) {
     res = getChunkFromIndexedFreeListHelper(size);
   }
@@ -1591,7 +1596,7 @@
         // Do not replenish from an underpopulated size.
         if (_indexedFreeList[replenish_size].surplus() > 0 &&
             _indexedFreeList[replenish_size].head() != NULL) {
-          newFc = _indexedFreeList[replenish_size].getChunkAtHead();
+          newFc = _indexedFreeList[replenish_size].get_chunk_at_head();
         } else if (bestFitFirst()) {
           newFc = bestFitSmall(replenish_size);
         }
@@ -1624,13 +1629,13 @@
                i < (num_blk - 1);
                curFc = nextFc, nextFc = (FreeChunk*)((HeapWord*)nextFc + size),
                i++) {
-            curFc->setSize(size);
+            curFc->set_size(size);
             // Don't record this as a return in order to try and
             // determine the "returns" from a GC.
             _bt.verify_not_unallocated((HeapWord*) fc, size);
-            _indexedFreeList[size].returnChunkAtTail(curFc, false);
+            _indexedFreeList[size].return_chunk_at_tail(curFc, false);
             _bt.mark_block((HeapWord*)curFc, size);
-            splitBirth(size);
+            split_birth(size);
             // Don't record the initial population of the indexed list
             // as a split birth.
           }
@@ -1638,9 +1643,9 @@
           // check that the arithmetic was OK above
           assert((HeapWord*)nextFc == (HeapWord*)newFc + num_blk*size,
             "inconsistency in carving newFc");
-          curFc->setSize(size);
+          curFc->set_size(size);
           _bt.mark_block((HeapWord*)curFc, size);
-          splitBirth(size);
+          split_birth(size);
           fc = curFc;
         } else {
           // Return entire block to caller
@@ -1653,14 +1658,14 @@
     // replenish the indexed free list.
     fc = getChunkFromDictionaryExact(size);
   }
-  // assert(fc == NULL || fc->isFree(), "Should be returning a free chunk");
+  // assert(fc == NULL || fc->is_free(), "Should be returning a free chunk");
   return fc;
 }
 
 FreeChunk*
 CompactibleFreeListSpace::getChunkFromDictionary(size_t size) {
   assert_locked();
-  FreeChunk* fc = _dictionary->getChunk(size);
+  FreeChunk* fc = _dictionary->get_chunk(size);
   if (fc == NULL) {
     return NULL;
   }
@@ -1677,7 +1682,7 @@
 FreeChunk*
 CompactibleFreeListSpace::getChunkFromDictionaryExact(size_t size) {
   assert_locked();
-  FreeChunk* fc = _dictionary->getChunk(size);
+  FreeChunk* fc = _dictionary->get_chunk(size);
   if (fc == NULL) {
     return fc;
   }
@@ -1686,11 +1691,11 @@
     _bt.verify_single_block((HeapWord*)fc, size);
     return fc;
   }
-  assert(fc->size() > size, "getChunk() guarantee");
+  assert(fc->size() > size, "get_chunk() guarantee");
   if (fc->size() < size + MinChunkSize) {
     // Return the chunk to the dictionary and go get a bigger one.
     returnChunkToDictionary(fc);
-    fc = _dictionary->getChunk(size + MinChunkSize);
+    fc = _dictionary->get_chunk(size + MinChunkSize);
     if (fc == NULL) {
       return NULL;
     }
@@ -1711,10 +1716,10 @@
   _bt.verify_single_block((HeapWord*)chunk, size);
   // adjust _unallocated_block downward, as necessary
   _bt.freed((HeapWord*)chunk, size);
-  _dictionary->returnChunk(chunk);
+  _dictionary->return_chunk(chunk);
 #ifndef PRODUCT
   if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
-    TreeChunk::as_TreeChunk(chunk)->list()->verify_stats();
+    TreeChunk<FreeChunk>::as_TreeChunk(chunk)->list()->verify_stats();
   }
 #endif // PRODUCT
 }
@@ -1726,9 +1731,9 @@
   _bt.verify_single_block((HeapWord*) fc, size);
   _bt.verify_not_unallocated((HeapWord*) fc, size);
   if (_adaptive_freelists) {
-    _indexedFreeList[size].returnChunkAtTail(fc);
+    _indexedFreeList[size].return_chunk_at_tail(fc);
   } else {
-    _indexedFreeList[size].returnChunkAtHead(fc);
+    _indexedFreeList[size].return_chunk_at_head(fc);
   }
 #ifndef PRODUCT
   if (CMSCollector::abstract_state() != CMSCollector::Sweeping) {
@@ -1756,7 +1761,7 @@
   FreeChunk* ec;
   {
     MutexLockerEx x(lock, Mutex::_no_safepoint_check_flag);
-    ec = dictionary()->findLargestDict();  // get largest block
+    ec = dictionary()->find_largest_dict();  // get largest block
     if (ec != NULL && ec->end() == chunk) {
       // It's a coterminal block - we can coalesce.
       size_t old_size = ec->size();
@@ -1767,7 +1772,7 @@
       ec = (FreeChunk*)chunk;
     }
   }
-  ec->setSize(size);
+  ec->set_size(size);
   debug_only(ec->mangleFreed(size));
   if (size < SmallForDictionary) {
     lock = _indexedFreeListParLocks[size];
@@ -1790,7 +1795,7 @@
   _bt.verify_single_block(chunk, size);
 
   FreeChunk* fc = (FreeChunk*) chunk;
-  fc->setSize(size);
+  fc->set_size(size);
   debug_only(fc->mangleFreed(size));
   if (size < SmallForDictionary) {
     returnChunkToFreeList(fc);
@@ -1833,7 +1838,7 @@
   assert_locked();
   assert(fc != NULL, "null chunk");
   _bt.verify_single_block((HeapWord*)fc, size);
-  _dictionary->removeChunk(fc);
+  _dictionary->remove_chunk(fc);
   // adjust _unallocated_block upward, as necessary
   _bt.allocated((HeapWord*)fc, size);
 }
@@ -1848,7 +1853,7 @@
       verifyIndexedFreeList(size);
     }
   )
-  _indexedFreeList[size].removeChunk(fc);
+  _indexedFreeList[size].remove_chunk(fc);
   NOT_PRODUCT(
     if (FLSVerifyIndexTable) {
       verifyIndexedFreeList(size);
@@ -1862,17 +1867,17 @@
      the excess is >= MIN_CHUNK. */
   size_t start = align_object_size(numWords + MinChunkSize);
   if (start < IndexSetSize) {
-    FreeList* it   = _indexedFreeList;
+    FreeList<FreeChunk>* it   = _indexedFreeList;
     size_t    hint = _indexedFreeList[start].hint();
     while (hint < IndexSetSize) {
       assert(hint % MinObjAlignment == 0, "hint should be aligned");
-      FreeList *fl = &_indexedFreeList[hint];
+      FreeList<FreeChunk> *fl = &_indexedFreeList[hint];
       if (fl->surplus() > 0 && fl->head() != NULL) {
         // Found a list with surplus, reset original hint
         // and split out a free chunk which is returned.
         _indexedFreeList[start].set_hint(hint);
         FreeChunk* res = getFromListGreater(fl, numWords);
-        assert(res == NULL || res->isFree(),
+        assert(res == NULL || res->is_free(),
           "Should be returning a free chunk");
         return res;
       }
@@ -1885,7 +1890,7 @@
 }
 
 /* Requires fl->size >= numWords + MinChunkSize */
-FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList* fl,
+FreeChunk* CompactibleFreeListSpace::getFromListGreater(FreeList<FreeChunk>* fl,
   size_t numWords) {
   FreeChunk *curr = fl->head();
   size_t oldNumWords = curr->size();
@@ -1894,13 +1899,13 @@
   assert(oldNumWords >= numWords + MinChunkSize,
         "Size of chunks in the list is too small");
 
-  fl->removeChunk(curr);
+  fl->remove_chunk(curr);
   // recorded indirectly by splitChunkAndReturnRemainder -
   // smallSplit(oldNumWords, numWords);
   FreeChunk* new_chunk = splitChunkAndReturnRemainder(curr, numWords);
   // Does anything have to be done for the remainder in terms of
   // fixing the card table?
-  assert(new_chunk == NULL || new_chunk->isFree(),
+  assert(new_chunk == NULL || new_chunk->is_free(),
     "Should be returning a free chunk");
   return new_chunk;
 }
@@ -1918,13 +1923,13 @@
   assert(rem_size >= MinChunkSize, "Free chunk smaller than minimum");
   FreeChunk* ffc = (FreeChunk*)((HeapWord*)chunk + new_size);
   assert(is_aligned(ffc), "alignment problem");
-  ffc->setSize(rem_size);
-  ffc->linkNext(NULL);
-  ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
+  ffc->set_size(rem_size);
+  ffc->link_next(NULL);
+  ffc->link_prev(NULL); // Mark as a free block for other (parallel) GC threads.
   // Above must occur before BOT is updated below.
   // adjust block offset table
   OrderAccess::storestore();
-  assert(chunk->isFree() && ffc->isFree(), "Error");
+  assert(chunk->is_free() && ffc->is_free(), "Error");
   _bt.split_block((HeapWord*)chunk, chunk->size(), new_size);
   if (rem_size < SmallForDictionary) {
     bool is_par = (SharedHeap::heap()->n_par_threads() > 0);
@@ -1939,7 +1944,7 @@
     returnChunkToDictionary(ffc);
     split(size ,rem_size);
   }
-  chunk->setSize(new_size);
+  chunk->set_size(new_size);
   return chunk;
 }
 
@@ -2046,10 +2051,10 @@
     assert(blk->_word_size != 0 && blk->_word_size >= MinChunkSize,
            "Minimum block size requirement");
     FreeChunk* fc = (FreeChunk*)(blk->_ptr);
-    fc->setSize(blk->_word_size);
-    fc->linkPrev(NULL);   // mark as free
+    fc->set_size(blk->_word_size);
+    fc->link_prev(NULL);   // mark as free
     fc->dontCoalesce();
-    assert(fc->isFree(), "just marked it free");
+    assert(fc->is_free(), "just marked it free");
     assert(fc->cantCoalesce(), "just marked it uncoalescable");
   }
 }
@@ -2149,7 +2154,7 @@
   }
 
   double totFree = itabFree +
-                   _dictionary->totalChunkSize(DEBUG_ONLY(freelistLock()));
+                   _dictionary->total_chunk_size(DEBUG_ONLY(freelistLock()));
   if (totFree > 0) {
     frag = ((frag + _dictionary->sum_of_squared_block_sizes()) /
             (totFree * totFree));
@@ -2167,16 +2172,16 @@
   assert_locked();
   size_t i;
   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
-    FreeList* fl    = &_indexedFreeList[i];
+    FreeList<FreeChunk>* fl = &_indexedFreeList[i];
     if (PrintFLSStatistics > 1) {
       gclog_or_tty->print("size[%d] : ", i);
     }
     fl->compute_desired(inter_sweep_current, inter_sweep_estimate, intra_sweep_estimate);
-    fl->set_coalDesired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
-    fl->set_beforeSweep(fl->count());
-    fl->set_bfrSurp(fl->surplus());
+    fl->set_coal_desired((ssize_t)((double)fl->desired() * CMSSmallCoalSurplusPercent));
+    fl->set_before_sweep(fl->count());
+    fl->set_bfr_surp(fl->surplus());
   }
-  _dictionary->beginSweepDictCensus(CMSLargeCoalSurplusPercent,
+  _dictionary->begin_sweep_dict_census(CMSLargeCoalSurplusPercent,
                                     inter_sweep_current,
                                     inter_sweep_estimate,
                                     intra_sweep_estimate);
@@ -2186,7 +2191,7 @@
   assert_locked();
   size_t i;
   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
-    FreeList *fl = &_indexedFreeList[i];
+    FreeList<FreeChunk> *fl = &_indexedFreeList[i];
     fl->set_surplus(fl->count() -
                     (ssize_t)((double)fl->desired() * CMSSmallSplitSurplusPercent));
   }
@@ -2197,7 +2202,7 @@
   size_t i;
   size_t h = IndexSetSize;
   for (i = IndexSetSize - 1; i != 0; i -= IndexSetStride) {
-    FreeList *fl = &_indexedFreeList[i];
+    FreeList<FreeChunk> *fl = &_indexedFreeList[i];
     fl->set_hint(h);
     if (fl->surplus() > 0) {
       h = i;
@@ -2209,18 +2214,18 @@
   assert_locked();
   size_t i;
   for (i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
-    FreeList *fl = &_indexedFreeList[i];
-    fl->set_prevSweep(fl->count());
-    fl->set_coalBirths(0);
-    fl->set_coalDeaths(0);
-    fl->set_splitBirths(0);
-    fl->set_splitDeaths(0);
+    FreeList<FreeChunk> *fl = &_indexedFreeList[i];
+    fl->set_prev_sweep(fl->count());
+    fl->set_coal_births(0);
+    fl->set_coal_deaths(0);
+    fl->set_split_births(0);
+    fl->set_split_deaths(0);
   }
 }
 
 void CompactibleFreeListSpace::endSweepFLCensus(size_t sweep_count) {
   if (PrintFLSStatistics > 0) {
-    HeapWord* largestAddr = (HeapWord*) dictionary()->findLargestDict();
+    HeapWord* largestAddr = (HeapWord*) dictionary()->find_largest_dict();
     gclog_or_tty->print_cr("CMS: Large block " PTR_FORMAT,
                            largestAddr);
   }
@@ -2231,30 +2236,30 @@
   }
   clearFLCensus();
   assert_locked();
-  _dictionary->endSweepDictCensus(CMSLargeSplitSurplusPercent);
+  _dictionary->end_sweep_dict_census(CMSLargeSplitSurplusPercent);
 }
 
 bool CompactibleFreeListSpace::coalOverPopulated(size_t size) {
   if (size < SmallForDictionary) {
-    FreeList *fl = &_indexedFreeList[size];
-    return (fl->coalDesired() < 0) ||
-           ((int)fl->count() > fl->coalDesired());
+    FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+    return (fl->coal_desired() < 0) ||
+           ((int)fl->count() > fl->coal_desired());
   } else {
-    return dictionary()->coalDictOverPopulated(size);
+    return dictionary()->coal_dict_over_populated(size);
   }
 }
 
 void CompactibleFreeListSpace::smallCoalBirth(size_t size) {
   assert(size < SmallForDictionary, "Size too large for indexed list");
-  FreeList *fl = &_indexedFreeList[size];
-  fl->increment_coalBirths();
+  FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+  fl->increment_coal_births();
   fl->increment_surplus();
 }
 
 void CompactibleFreeListSpace::smallCoalDeath(size_t size) {
   assert(size < SmallForDictionary, "Size too large for indexed list");
-  FreeList *fl = &_indexedFreeList[size];
-  fl->increment_coalDeaths();
+  FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+  fl->increment_coal_deaths();
   fl->decrement_surplus();
 }
 
@@ -2262,7 +2267,7 @@
   if (size  < SmallForDictionary) {
     smallCoalBirth(size);
   } else {
-    dictionary()->dictCensusUpdate(size,
+    dictionary()->dict_census_udpate(size,
                                    false /* split */,
                                    true /* birth */);
   }
@@ -2272,7 +2277,7 @@
   if(size  < SmallForDictionary) {
     smallCoalDeath(size);
   } else {
-    dictionary()->dictCensusUpdate(size,
+    dictionary()->dict_census_udpate(size,
                                    false /* split */,
                                    false /* birth */);
   }
@@ -2280,23 +2285,23 @@
 
 void CompactibleFreeListSpace::smallSplitBirth(size_t size) {
   assert(size < SmallForDictionary, "Size too large for indexed list");
-  FreeList *fl = &_indexedFreeList[size];
-  fl->increment_splitBirths();
+  FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+  fl->increment_split_births();
   fl->increment_surplus();
 }
 
 void CompactibleFreeListSpace::smallSplitDeath(size_t size) {
   assert(size < SmallForDictionary, "Size too large for indexed list");
-  FreeList *fl = &_indexedFreeList[size];
-  fl->increment_splitDeaths();
+  FreeList<FreeChunk> *fl = &_indexedFreeList[size];
+  fl->increment_split_deaths();
   fl->decrement_surplus();
 }
 
-void CompactibleFreeListSpace::splitBirth(size_t size) {
+void CompactibleFreeListSpace::split_birth(size_t size) {
   if (size  < SmallForDictionary) {
     smallSplitBirth(size);
   } else {
-    dictionary()->dictCensusUpdate(size,
+    dictionary()->dict_census_udpate(size,
                                    true /* split */,
                                    true /* birth */);
   }
@@ -2306,7 +2311,7 @@
   if (size  < SmallForDictionary) {
     smallSplitDeath(size);
   } else {
-    dictionary()->dictCensusUpdate(size,
+    dictionary()->dict_census_udpate(size,
                                    true /* split */,
                                    false /* birth */);
   }
@@ -2315,8 +2320,8 @@
 void CompactibleFreeListSpace::split(size_t from, size_t to1) {
   size_t to2 = from - to1;
   splitDeath(from);
-  splitBirth(to1);
-  splitBirth(to2);
+  split_birth(to1);
+  split_birth(to2);
 }
 
 void CompactibleFreeListSpace::print() const {
@@ -2362,7 +2367,7 @@
       FreeChunk* fc = (FreeChunk*)addr;
       res = fc->size();
       if (FLSVerifyLists && !fc->cantCoalesce()) {
-        guarantee(_sp->verifyChunkInFreeLists(fc),
+        guarantee(_sp->verify_chunk_in_free_list(fc),
                   "Chunk should be on a free list");
       }
     }
@@ -2444,7 +2449,7 @@
   virtual void do_oop(narrowOop* p) { VerifyAllOopsClosure::do_oop_work(p); }
 };
 
-void CompactibleFreeListSpace::verify(bool ignored) const {
+void CompactibleFreeListSpace::verify() const {
   assert_lock_strong(&_freelistLock);
   verify_objects_initialized();
   MemRegion span = _collector->_span;
@@ -2518,7 +2523,7 @@
             "Slot should have been empty");
   for (; fc != NULL; fc = fc->next(), n++) {
     guarantee(fc->size() == size, "Size inconsistency");
-    guarantee(fc->isFree(), "!free?");
+    guarantee(fc->is_free(), "!free?");
     guarantee(fc->next() == NULL || fc->next()->prev() == fc, "Broken list");
     guarantee((fc->next() == NULL) == (fc == tail), "Incorrect tail");
   }
@@ -2527,52 +2532,48 @@
 
 #ifndef PRODUCT
 void CompactibleFreeListSpace::check_free_list_consistency() const {
-  assert(_dictionary->minSize() <= IndexSetSize,
+  assert(_dictionary->min_size() <= IndexSetSize,
     "Some sizes can't be allocated without recourse to"
     " linear allocation buffers");
-  assert(MIN_TREE_CHUNK_SIZE*HeapWordSize == sizeof(TreeChunk),
+  assert(BinaryTreeDictionary<FreeChunk>::min_tree_chunk_size*HeapWordSize == sizeof(TreeChunk<FreeChunk>),
     "else MIN_TREE_CHUNK_SIZE is wrong");
-  assert((IndexSetStride == 2 && IndexSetStart == 4) ||                   // 32-bit
-         (IndexSetStride == 1 && IndexSetStart == 3), "just checking");   // 64-bit
-  assert((IndexSetStride != 2) || (IndexSetStart % 2 == 0),
-      "Some for-loops may be incorrectly initialized");
-  assert((IndexSetStride != 2) || (IndexSetSize % 2 == 1),
-      "For-loops that iterate over IndexSet with stride 2 may be wrong");
+  assert(IndexSetStart != 0, "IndexSetStart not initialized");
+  assert(IndexSetStride != 0, "IndexSetStride not initialized");
 }
 #endif
 
 void CompactibleFreeListSpace::printFLCensus(size_t sweep_count) const {
   assert_lock_strong(&_freelistLock);
-  FreeList total;
+  FreeList<FreeChunk> total;
   gclog_or_tty->print("end sweep# " SIZE_FORMAT "\n", sweep_count);
-  FreeList::print_labels_on(gclog_or_tty, "size");
-  size_t totalFree = 0;
+  FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
+  size_t total_free = 0;
   for (size_t i = IndexSetStart; i < IndexSetSize; i += IndexSetStride) {
-    const FreeList *fl = &_indexedFreeList[i];
-    totalFree += fl->count() * fl->size();
+    const FreeList<FreeChunk> *fl = &_indexedFreeList[i];
+    total_free += fl->count() * fl->size();
     if (i % (40*IndexSetStride) == 0) {
-      FreeList::print_labels_on(gclog_or_tty, "size");
+      FreeList<FreeChunk>::print_labels_on(gclog_or_tty, "size");
     }
     fl->print_on(gclog_or_tty);
-    total.set_bfrSurp(    total.bfrSurp()     + fl->bfrSurp()    );
+    total.set_bfr_surp(    total.bfr_surp()     + fl->bfr_surp()    );
     total.set_surplus(    total.surplus()     + fl->surplus()    );
     total.set_desired(    total.desired()     + fl->desired()    );
-    total.set_prevSweep(  total.prevSweep()   + fl->prevSweep()  );
-    total.set_beforeSweep(total.beforeSweep() + fl->beforeSweep());
+    total.set_prev_sweep(  total.prev_sweep()   + fl->prev_sweep()  );
+    total.set_before_sweep(total.before_sweep() + fl->before_sweep());
     total.set_count(      total.count()       + fl->count()      );
-    total.set_coalBirths( total.coalBirths()  + fl->coalBirths() );
-    total.set_coalDeaths( total.coalDeaths()  + fl->coalDeaths() );
-    total.set_splitBirths(total.splitBirths() + fl->splitBirths());
-    total.set_splitDeaths(total.splitDeaths() + fl->splitDeaths());
+    total.set_coal_births( total.coal_births()  + fl->coal_births() );
+    total.set_coal_deaths( total.coal_deaths()  + fl->coal_deaths() );
+    total.set_split_births(total.split_births() + fl->split_births());
+    total.set_split_deaths(total.split_deaths() + fl->split_deaths());
   }
   total.print_on(gclog_or_tty, "TOTAL");
   gclog_or_tty->print_cr("Total free in indexed lists "
-                         SIZE_FORMAT " words", totalFree);
+                         SIZE_FORMAT " words", total_free);
   gclog_or_tty->print("growth: %8.5f  deficit: %8.5f\n",
-    (double)(total.splitBirths()+total.coalBirths()-total.splitDeaths()-total.coalDeaths())/
-            (total.prevSweep() != 0 ? (double)total.prevSweep() : 1.0),
+    (double)(total.split_births()+total.coal_births()-total.split_deaths()-total.coal_deaths())/
+            (total.prev_sweep() != 0 ? (double)total.prev_sweep() : 1.0),
     (double)(total.desired() - total.count())/(total.desired() != 0 ? (double)total.desired() : 1.0));
-  _dictionary->printDictCensus();
+  _dictionary->print_dict_census();
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -2634,18 +2635,18 @@
     res = _cfls->getChunkFromDictionaryExact(word_sz);
     if (res == NULL) return NULL;
   } else {
-    FreeList* fl = &_indexedFreeList[word_sz];
+    FreeList<FreeChunk>* fl = &_indexedFreeList[word_sz];
     if (fl->count() == 0) {
       // Attempt to refill this local free list.
       get_from_global_pool(word_sz, fl);
       // If it didn't work, give up.
       if (fl->count() == 0) return NULL;
     }
-    res = fl->getChunkAtHead();
+    res = fl->get_chunk_at_head();
     assert(res != NULL, "Why was count non-zero?");
   }
   res->markNotFree();
-  assert(!res->isFree(), "shouldn't be marked free");
+  assert(!res->is_free(), "shouldn't be marked free");
   assert(oop(res)->klass_or_null() == NULL, "should look uninitialized");
   // mangle a just allocated object with a distinct pattern.
   debug_only(res->mangleAllocated(word_sz));
@@ -2654,7 +2655,7 @@
 
 // Get a chunk of blocks of the right size and update related
 // book-keeping stats
-void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList* fl) {
+void CFLS_LAB::get_from_global_pool(size_t word_sz, FreeList<FreeChunk>* fl) {
   // Get the #blocks we want to claim
   size_t n_blks = (size_t)_blocks_to_claim[word_sz].average();
   assert(n_blks > 0, "Error");
@@ -2736,7 +2737,7 @@
         if (num_retire > 0) {
           _cfls->_indexedFreeList[i].prepend(&_indexedFreeList[i]);
           // Reset this list.
-          _indexedFreeList[i] = FreeList();
+          _indexedFreeList[i] = FreeList<FreeChunk>();
           _indexedFreeList[i].set_size(i);
         }
       }
@@ -2750,7 +2751,7 @@
   }
 }
 
-void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl) {
+void CompactibleFreeListSpace:: par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList<FreeChunk>* fl) {
   assert(fl->count() == 0, "Precondition.");
   assert(word_sz < CompactibleFreeListSpace::IndexSetSize,
          "Precondition");
@@ -2766,12 +2767,12 @@
          (cur_sz < CompactibleFreeListSpace::IndexSetSize) &&
          (CMSSplitIndexedFreeListBlocks || k <= 1);
          k++, cur_sz = k * word_sz) {
-      FreeList fl_for_cur_sz;  // Empty.
+      FreeList<FreeChunk> fl_for_cur_sz;  // Empty.
       fl_for_cur_sz.set_size(cur_sz);
       {
         MutexLockerEx x(_indexedFreeListParLocks[cur_sz],
                         Mutex::_no_safepoint_check_flag);
-        FreeList* gfl = &_indexedFreeList[cur_sz];
+        FreeList<FreeChunk>* gfl = &_indexedFreeList[cur_sz];
         if (gfl->count() != 0) {
           // nn is the number of chunks of size cur_sz that
           // we'd need to split k-ways each, in order to create
@@ -2784,9 +2785,9 @@
             // we increment the split death count by the number of blocks
             // we just took from the cur_sz-size blocks list and which
             // we will be splitting below.
-            ssize_t deaths = gfl->splitDeaths() +
+            ssize_t deaths = gfl->split_deaths() +
                              fl_for_cur_sz.count();
-            gfl->set_splitDeaths(deaths);
+            gfl->set_split_deaths(deaths);
           }
         }
       }
@@ -2797,21 +2798,21 @@
         } else {
           // Divide each block on fl_for_cur_sz up k ways.
           FreeChunk* fc;
-          while ((fc = fl_for_cur_sz.getChunkAtHead()) != NULL) {
+          while ((fc = fl_for_cur_sz.get_chunk_at_head()) != NULL) {
             // Must do this in reverse order, so that anybody attempting to
             // access the main chunk sees it as a single free block until we
             // change it.
             size_t fc_size = fc->size();
-            assert(fc->isFree(), "Error");
+            assert(fc->is_free(), "Error");
             for (int i = k-1; i >= 0; i--) {
               FreeChunk* ffc = (FreeChunk*)((HeapWord*)fc + i * word_sz);
               assert((i != 0) ||
-                        ((fc == ffc) && ffc->isFree() &&
+                        ((fc == ffc) && ffc->is_free() &&
                          (ffc->size() == k*word_sz) && (fc_size == word_sz)),
                         "Counting error");
-              ffc->setSize(word_sz);
-              ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
-              ffc->linkNext(NULL);
+              ffc->set_size(word_sz);
+              ffc->link_prev(NULL); // Mark as a free block for other (parallel) GC threads.
+              ffc->link_next(NULL);
               // Above must occur before BOT is updated below.
               OrderAccess::storestore();
               // splitting from the right, fc_size == i * word_sz
@@ -2822,7 +2823,7 @@
               _bt.verify_single_block((HeapWord*)fc, fc_size);
               _bt.verify_single_block((HeapWord*)ffc, word_sz);
               // Push this on "fl".
-              fl->returnChunkAtHead(ffc);
+              fl->return_chunk_at_head(ffc);
             }
             // TRAP
             assert(fl->tail()->next() == NULL, "List invariant.");
@@ -2832,8 +2833,8 @@
         size_t num = fl->count();
         MutexLockerEx x(_indexedFreeListParLocks[word_sz],
                         Mutex::_no_safepoint_check_flag);
-        ssize_t births = _indexedFreeList[word_sz].splitBirths() + num;
-        _indexedFreeList[word_sz].set_splitBirths(births);
+        ssize_t births = _indexedFreeList[word_sz].split_births() + num;
+        _indexedFreeList[word_sz].set_split_births(births);
         return;
       }
     }
@@ -2846,12 +2847,12 @@
     MutexLockerEx x(parDictionaryAllocLock(),
                     Mutex::_no_safepoint_check_flag);
     while (n > 0) {
-      fc = dictionary()->getChunk(MAX2(n * word_sz,
-                                  _dictionary->minSize()),
-                                  FreeBlockDictionary::atLeast);
+      fc = dictionary()->get_chunk(MAX2(n * word_sz,
+                                  _dictionary->min_size()),
+                                  FreeBlockDictionary<FreeChunk>::atLeast);
       if (fc != NULL) {
         _bt.allocated((HeapWord*)fc, fc->size(), true /* reducing */);  // update _unallocated_blk
-        dictionary()->dictCensusUpdate(fc->size(),
+        dictionary()->dict_census_udpate(fc->size(),
                                        true /*split*/,
                                        false /*birth*/);
         break;
@@ -2862,7 +2863,7 @@
     if (fc == NULL) return;
     // Otherwise, split up that block.
     assert((ssize_t)n >= 1, "Control point invariant");
-    assert(fc->isFree(), "Error: should be a free block");
+    assert(fc->is_free(), "Error: should be a free block");
     _bt.verify_single_block((HeapWord*)fc, fc->size());
     const size_t nn = fc->size() / word_sz;
     n = MIN2(nn, n);
@@ -2893,18 +2894,18 @@
     if (rem > 0) {
       size_t prefix_size = n * word_sz;
       rem_fc = (FreeChunk*)((HeapWord*)fc + prefix_size);
-      rem_fc->setSize(rem);
-      rem_fc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
-      rem_fc->linkNext(NULL);
+      rem_fc->set_size(rem);
+      rem_fc->link_prev(NULL); // Mark as a free block for other (parallel) GC threads.
+      rem_fc->link_next(NULL);
       // Above must occur before BOT is updated below.
       assert((ssize_t)n > 0 && prefix_size > 0 && rem_fc > fc, "Error");
       OrderAccess::storestore();
       _bt.split_block((HeapWord*)fc, fc->size(), prefix_size);
-      assert(fc->isFree(), "Error");
-      fc->setSize(prefix_size);
+      assert(fc->is_free(), "Error");
+      fc->set_size(prefix_size);
       if (rem >= IndexSetSize) {
         returnChunkToDictionary(rem_fc);
-        dictionary()->dictCensusUpdate(rem, true /*split*/, true /*birth*/);
+        dictionary()->dict_census_udpate(rem, true /*split*/, true /*birth*/);
         rem_fc = NULL;
       }
       // Otherwise, return it to the small list below.
@@ -2914,7 +2915,7 @@
     MutexLockerEx x(_indexedFreeListParLocks[rem],
                     Mutex::_no_safepoint_check_flag);
     _bt.verify_not_unallocated((HeapWord*)rem_fc, rem_fc->size());
-    _indexedFreeList[rem].returnChunkAtHead(rem_fc);
+    _indexedFreeList[rem].return_chunk_at_head(rem_fc);
     smallSplitBirth(rem);
   }
   assert((ssize_t)n > 0 && fc != NULL, "Consistency");
@@ -2926,9 +2927,9 @@
   // All but first chunk in this loop
   for (ssize_t i = n-1; i > 0; i--) {
     FreeChunk* ffc = (FreeChunk*)((HeapWord*)fc + i * word_sz);
-    ffc->setSize(word_sz);
-    ffc->linkPrev(NULL); // Mark as a free block for other (parallel) GC threads.
-    ffc->linkNext(NULL);
+    ffc->set_size(word_sz);
+    ffc->link_prev(NULL); // Mark as a free block for other (parallel) GC threads.
+    ffc->link_next(NULL);
     // Above must occur before BOT is updated below.
     OrderAccess::storestore();
     // splitting from the right, fc_size == (n - i + 1) * wordsize
@@ -2938,25 +2939,25 @@
     _bt.verify_single_block((HeapWord*)ffc, ffc->size());
     _bt.verify_single_block((HeapWord*)fc, fc_size);
     // Push this on "fl".
-    fl->returnChunkAtHead(ffc);
+    fl->return_chunk_at_head(ffc);
   }
   // First chunk
-  assert(fc->isFree() && fc->size() == n*word_sz, "Error: should still be a free block");
+  assert(fc->is_free() && fc->size() == n*word_sz, "Error: should still be a free block");
   // The blocks above should show their new sizes before the first block below
-  fc->setSize(word_sz);
-  fc->linkPrev(NULL);    // idempotent wrt free-ness, see assert above
-  fc->linkNext(NULL);
+  fc->set_size(word_sz);
+  fc->link_prev(NULL);    // idempotent wrt free-ness, see assert above
+  fc->link_next(NULL);
   _bt.verify_not_unallocated((HeapWord*)fc, fc->size());
   _bt.verify_single_block((HeapWord*)fc, fc->size());
-  fl->returnChunkAtHead(fc);
+  fl->return_chunk_at_head(fc);
 
   assert((ssize_t)n > 0 && (ssize_t)n == fl->count(), "Incorrect number of blocks");
   {
     // Update the stats for this block size.
     MutexLockerEx x(_indexedFreeListParLocks[word_sz],
                     Mutex::_no_safepoint_check_flag);
-    const ssize_t births = _indexedFreeList[word_sz].splitBirths() + n;
-    _indexedFreeList[word_sz].set_splitBirths(births);
+    const ssize_t births = _indexedFreeList[word_sz].split_births() + n;
+    _indexedFreeList[word_sz].set_split_births(births);
     // ssize_t new_surplus = _indexedFreeList[word_sz].surplus() + n;
     // _indexedFreeList[word_sz].set_surplus(new_surplus);
   }
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
index 90d2f5f..3b7bb9a 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,10 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_COMPACTIBLEFREELISTSPACE_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_COMPACTIBLEFREELISTSPACE_HPP
 
-#include "gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp"
-#include "gc_implementation/concurrentMarkSweep/freeList.hpp"
 #include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp"
+#include "memory/binaryTreeDictionary.hpp"
 #include "memory/blockOffsetTable.inline.hpp"
+#include "memory/freeList.hpp"
 #include "memory/space.hpp"
 
 // Classes in support of keeping track of promotions into a non-Contiguous
@@ -129,10 +129,10 @@
   // Linear allocation blocks
   LinearAllocBlock _smallLinearAllocBlock;
 
-  FreeBlockDictionary::DictionaryChoice _dictionaryChoice;
-  FreeBlockDictionary* _dictionary;    // ptr to dictionary for large size blocks
+  FreeBlockDictionary<FreeChunk>::DictionaryChoice _dictionaryChoice;
+  FreeBlockDictionary<FreeChunk>* _dictionary;    // ptr to dictionary for large size blocks
 
-  FreeList _indexedFreeList[IndexSetSize];
+  FreeList<FreeChunk> _indexedFreeList[IndexSetSize];
                                        // indexed array for small size blocks
   // allocation stategy
   bool       _fitStrategy;      // Use best fit strategy.
@@ -169,7 +169,7 @@
   // If the count of "fl" is negative, it's absolute value indicates a
   // number of free chunks that had been previously "borrowed" from global
   // list of size "word_sz", and must now be decremented.
-  void par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList* fl);
+  void par_get_chunk_of_blocks(size_t word_sz, size_t n, FreeList<FreeChunk>* fl);
 
   // Allocation helper functions
   // Allocate using a strategy that takes from the indexed free lists
@@ -215,7 +215,7 @@
   // and return it.  The split off remainder is returned to
   // the free lists.  The old name for getFromListGreater
   // was lookInListGreater.
-  FreeChunk* getFromListGreater(FreeList* fl, size_t numWords);
+  FreeChunk* getFromListGreater(FreeList<FreeChunk>* fl, size_t numWords);
   // Get a chunk in the indexed free list or dictionary,
   // by considering a larger chunk and splitting it.
   FreeChunk* getChunkFromGreater(size_t numWords);
@@ -286,10 +286,10 @@
   // Constructor...
   CompactibleFreeListSpace(BlockOffsetSharedArray* bs, MemRegion mr,
                            bool use_adaptive_freelists,
-                           FreeBlockDictionary::DictionaryChoice);
+                           FreeBlockDictionary<FreeChunk>::DictionaryChoice);
   // accessors
   bool bestFitFirst() { return _fitStrategy == FreeBlockBestFitFirst; }
-  FreeBlockDictionary* dictionary() const { return _dictionary; }
+  FreeBlockDictionary<FreeChunk>* dictionary() const { return _dictionary; }
   HeapWord* nearLargestChunk() const { return _nearLargestChunk; }
   void set_nearLargestChunk(HeapWord* v) { _nearLargestChunk = v; }
 
@@ -492,14 +492,14 @@
   void print()                            const;
   void print_on(outputStream* st)         const;
   void prepare_for_verify();
-  void verify(bool allow_dirty)           const;
+  void verify()                           const;
   void verifyFreeLists()                  const PRODUCT_RETURN;
   void verifyIndexedFreeLists()           const;
   void verifyIndexedFreeList(size_t size) const;
   // Verify that the given chunk is in the free lists:
   // i.e. either the binary tree dictionary, the indexed free lists
   // or the linear allocation block.
-  bool verifyChunkInFreeLists(FreeChunk* fc) const;
+  bool verify_chunk_in_free_list(FreeChunk* fc) const;
   // Verify that the given chunk is the linear allocation block
   bool verify_chunk_is_linear_alloc_block(FreeChunk* fc) const;
   // Do some basic checks on the the free lists.
@@ -608,7 +608,7 @@
   void coalDeath(size_t size);
   void smallSplitBirth(size_t size);
   void smallSplitDeath(size_t size);
-  void splitBirth(size_t size);
+  void split_birth(size_t size);
   void splitDeath(size_t size);
   void split(size_t from, size_t to1);
 
@@ -617,12 +617,12 @@
 
 // A parallel-GC-thread-local allocation buffer for allocation into a
 // CompactibleFreeListSpace.
-class CFLS_LAB : public CHeapObj {
+class CFLS_LAB : public CHeapObj<mtGC> {
   // The space that this buffer allocates into.
   CompactibleFreeListSpace* _cfls;
 
   // Our local free lists.
-  FreeList _indexedFreeList[CompactibleFreeListSpace::IndexSetSize];
+  FreeList<FreeChunk> _indexedFreeList[CompactibleFreeListSpace::IndexSetSize];
 
   // Initialized from a command-line arg.
 
@@ -635,7 +635,7 @@
   size_t        _num_blocks        [CompactibleFreeListSpace::IndexSetSize];
 
   // Internal work method
-  void get_from_global_pool(size_t word_sz, FreeList* fl);
+  void get_from_global_pool(size_t word_sz, FreeList<FreeChunk>* fl);
 
 public:
   CFLS_LAB(CompactibleFreeListSpace* cfls);
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
index ac8ac93..7f52bca 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp
@@ -174,7 +174,7 @@
 
 // This struct contains per-thread things necessary to support parallel
 // young-gen collection.
-class CMSParGCThreadState: public CHeapObj {
+class CMSParGCThreadState: public CHeapObj<mtGC> {
  public:
   CFLS_LAB lab;
   PromotionInfo promo;
@@ -188,7 +188,7 @@
 ConcurrentMarkSweepGeneration::ConcurrentMarkSweepGeneration(
      ReservedSpace rs, size_t initial_byte_size, int level,
      CardTableRS* ct, bool use_adaptive_freelists,
-     FreeBlockDictionary::DictionaryChoice dictionaryChoice) :
+     FreeBlockDictionary<FreeChunk>::DictionaryChoice dictionaryChoice) :
   CardGeneration(rs, initial_byte_size, level, ct),
   _dilatation_factor(((double)MinChunkSize)/((double)(CollectedHeap::min_fill_size()))),
   _debug_collection_type(Concurrent_collection_type)
@@ -229,7 +229,7 @@
   if (CollectedHeap::use_parallel_gc_threads()) {
     typedef CMSParGCThreadState* CMSParGCThreadStatePtr;
     _par_gc_thread_states =
-      NEW_C_HEAP_ARRAY(CMSParGCThreadStatePtr, ParallelGCThreads);
+      NEW_C_HEAP_ARRAY(CMSParGCThreadStatePtr, ParallelGCThreads, mtGC);
     if (_par_gc_thread_states == NULL) {
       vm_exit_during_initialization("Could not allocate par gc structs");
     }
@@ -687,7 +687,7 @@
         warning("task_queues allocation failure.");
         return;
       }
-      _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues);
+      _hash_seed = NEW_C_HEAP_ARRAY(int, num_queues, mtGC);
       if (_hash_seed == NULL) {
         warning("_hash_seed array allocation failure");
         return;
@@ -737,7 +737,7 @@
     assert(_young_gen != NULL, "no _young_gen");
     _eden_chunk_index = 0;
     _eden_chunk_capacity = (_young_gen->max_capacity()+CMSSamplingGrain)/CMSSamplingGrain;
-    _eden_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, _eden_chunk_capacity);
+    _eden_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, _eden_chunk_capacity, mtGC);
     if (_eden_chunk_array == NULL) {
       _eden_chunk_capacity = 0;
       warning("GC/CMS: _eden_chunk_array allocation failure");
@@ -750,35 +750,35 @@
     const size_t max_plab_samples =
       ((DefNewGeneration*)_young_gen)->max_survivor_size()/MinTLABSize;
 
-    _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads);
-    _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples);
-    _cursor               = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads);
+    _survivor_plab_array  = NEW_C_HEAP_ARRAY(ChunkArray, ParallelGCThreads, mtGC);
+    _survivor_chunk_array = NEW_C_HEAP_ARRAY(HeapWord*, 2*max_plab_samples, mtGC);
+    _cursor               = NEW_C_HEAP_ARRAY(size_t, ParallelGCThreads, mtGC);
     if (_survivor_plab_array == NULL || _survivor_chunk_array == NULL
         || _cursor == NULL) {
       warning("Failed to allocate survivor plab/chunk array");
       if (_survivor_plab_array  != NULL) {
-        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
+        FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array, mtGC);
         _survivor_plab_array = NULL;
       }
       if (_survivor_chunk_array != NULL) {
-        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
+        FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array, mtGC);
         _survivor_chunk_array = NULL;
       }
       if (_cursor != NULL) {
-        FREE_C_HEAP_ARRAY(size_t, _cursor);
+        FREE_C_HEAP_ARRAY(size_t, _cursor, mtGC);
         _cursor = NULL;
       }
     } else {
       _survivor_chunk_capacity = 2*max_plab_samples;
       for (uint i = 0; i < ParallelGCThreads; i++) {
-        HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples);
+        HeapWord** vec = NEW_C_HEAP_ARRAY(HeapWord*, max_plab_samples, mtGC);
         if (vec == NULL) {
           warning("Failed to allocate survivor plab array");
           for (int j = i; j > 0; j--) {
-            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array());
+            FREE_C_HEAP_ARRAY(HeapWord*, _survivor_plab_array[j-1].array(), mtGC);
           }
-          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array);
-          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array);
+          FREE_C_HEAP_ARRAY(ChunkArray, _survivor_plab_array, mtGC);
+          FREE_C_HEAP_ARRAY(HeapWord*, _survivor_chunk_array, mtGC);
           _survivor_plab_array = NULL;
           _survivor_chunk_array = NULL;
           _survivor_chunk_capacity = 0;
@@ -813,14 +813,6 @@
   _gc_counters = new CollectorCounters("CMS", 1);
   _completed_initialization = true;
   _inter_sweep_timer.start();  // start of time
-#ifdef SPARC
-  // Issue a stern warning, but allow use for experimentation and debugging.
-  if (VM_Version::is_sun4v() && UseMemSetInBOT) {
-    assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error");
-    warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability"
-            " on sun4v; please understand that you are using at your own risk!");
-  }
-#endif
 }
 
 const char* ConcurrentMarkSweepGeneration::name() const {
@@ -1026,7 +1018,7 @@
     // its mark-bit or P-bits not yet set. Such objects need
     // to be safely navigable by block_start().
     assert(oop(res)->klass_or_null() == NULL, "Object should be uninitialized here.");
-    assert(!((FreeChunk*)res)->isFree(), "Error, block will look free but show wrong size");
+    assert(!((FreeChunk*)res)->is_free(), "Error, block will look free but show wrong size");
     collector()->direct_allocated(res, adjustedSize);
     _direct_allocated_words += adjustedSize;
     // allocation counters
@@ -1391,7 +1383,7 @@
   oop obj = oop(obj_ptr);
   OrderAccess::storestore();
   assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
-  assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
+  assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size");
   // IMPORTANT: See note on object initialization for CMS above.
   // Otherwise, copy the object.  Here we must be careful to insert the
   // klass pointer last, since this marks the block as an allocated object.
@@ -1400,7 +1392,7 @@
   // Restore the mark word copied above.
   obj->set_mark(m);
   assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
-  assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
+  assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size");
   OrderAccess::storestore();
 
   if (UseCompressedOops) {
@@ -1421,7 +1413,7 @@
     promoInfo->track((PromotedObject*)obj, old->klass());
   }
   assert(obj->klass_or_null() == NULL, "Object should be uninitialized here.");
-  assert(!((FreeChunk*)obj_ptr)->isFree(), "Error, block will look free but show wrong size");
+  assert(!((FreeChunk*)obj_ptr)->is_free(), "Error, block will look free but show wrong size");
   assert(old->is_oop(), "Will use and dereference old klass ptr below");
 
   // Finally, install the klass pointer (this should be volatile).
@@ -2034,7 +2026,7 @@
            pointer_delta(cms_space->end(), cms_space->compaction_top())
            * HeapWordSize,
       "All the free space should be compacted into one chunk at top");
-    assert(cms_space->dictionary()->totalChunkSize(
+    assert(cms_space->dictionary()->total_chunk_size(
                                       debug_only(cms_space->freelistLock())) == 0 ||
            cms_space->totalSizeInIndexedFreeLists() == 0,
       "All the free space should be in a single chunk");
@@ -2429,7 +2421,7 @@
 
   if (VerifyBeforeGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-    Universe::verify(true);
+    Universe::verify();
   }
 
   // Snapshot the soft reference policy to be used in this collection cycle.
@@ -2453,7 +2445,7 @@
         if (VerifyDuringGC &&
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
           gclog_or_tty->print("Verify before initial mark: ");
-          Universe::verify(true);
+          Universe::verify();
         }
         {
           bool res = markFromRoots(false);
@@ -2465,7 +2457,7 @@
         if (VerifyDuringGC &&
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
           gclog_or_tty->print("Verify before re-mark: ");
-          Universe::verify(true);
+          Universe::verify();
         }
         checkpointRootsFinal(false, clear_all_soft_refs,
                              init_mark_was_synchronous);
@@ -2477,7 +2469,7 @@
         if (VerifyDuringGC &&
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
           gclog_or_tty->print("Verify before sweep: ");
-          Universe::verify(true);
+          Universe::verify();
         }
         sweep(false);
         assert(_collectorState == Resizing, "Incorrect state");
@@ -2493,7 +2485,7 @@
         if (VerifyDuringGC &&
             GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
           gclog_or_tty->print("Verify before reset: ");
-          Universe::verify(true);
+          Universe::verify();
         }
         reset(false);
         assert(_collectorState == Idling, "Collector state should "
@@ -2520,7 +2512,7 @@
 
   if (VerifyAfterGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
-    Universe::verify(true);
+    Universe::verify();
   }
   if (TraceCMSState) {
     gclog_or_tty->print_cr("CMS Thread " INTPTR_FORMAT
@@ -3109,21 +3101,21 @@
 }
 
 void
-ConcurrentMarkSweepGeneration::verify(bool allow_dirty /* ignored */) {
+ConcurrentMarkSweepGeneration::verify() {
   // Locks are normally acquired/released in gc_prologue/gc_epilogue, but those
   // are not called when the heap is verified during universe initialization and
   // at vm shutdown.
   if (freelistLock()->owned_by_self()) {
-    cmsSpace()->verify(false /* ignored */);
+    cmsSpace()->verify();
   } else {
     MutexLockerEx fll(freelistLock(), Mutex::_no_safepoint_check_flag);
-    cmsSpace()->verify(false /* ignored */);
+    cmsSpace()->verify();
   }
 }
 
-void CMSCollector::verify(bool allow_dirty /* ignored */) {
-  _cmsGen->verify(allow_dirty);
-  _permGen->verify(allow_dirty);
+void CMSCollector::verify() {
+  _cmsGen->verify();
+  _permGen->verify();
 }
 
 #ifndef PRODUCT
@@ -3455,10 +3447,7 @@
   _wallclock.stop();
   if (PrintGCDetails) {
     gclog_or_tty->date_stamp(PrintGCDateStamps);
-    if (PrintGCTimeStamps) {
-      gclog_or_tty->stamp();
-      gclog_or_tty->print(": ");
-    }
+    gclog_or_tty->stamp(PrintGCTimeStamps);
     gclog_or_tty->print("[%s-concurrent-%s: %3.3f/%3.3f secs]",
                  _collector->cmsGen()->short_name(),
                  _phase, _collector->timerValue(), _wallclock.seconds());
@@ -5673,7 +5662,7 @@
   if (VerifyDuringGC &&
       GenCollectedHeap::heap()->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
-    Universe::verify(true);
+    Universe::verify();
   }
   {
     TraceTime t("root rescan", PrintGCDetails, false, gclog_or_tty);
@@ -6131,7 +6120,7 @@
   double nearLargestPercent = FLSLargestBlockCoalesceProximity;
   HeapWord*  minAddr        = _cmsSpace->bottom();
   HeapWord*  largestAddr    =
-    (HeapWord*) _cmsSpace->dictionary()->findLargestDict();
+    (HeapWord*) _cmsSpace->dictionary()->find_largest_dict();
   if (largestAddr == NULL) {
     // The dictionary appears to be empty.  In this case
     // try to coalesce at the end of the heap.
@@ -6332,10 +6321,10 @@
   )
 }
 
-void CMSCollector::do_CMS_operation(CMS_op_type op) {
+void CMSCollector::do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause) {
   gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
   TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-  TraceTime t("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
+  TraceTime t(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
   TraceCollectorStats tcs(counters());
 
   switch (op) {
@@ -7906,7 +7895,7 @@
     _last_fc = NULL;
 
     _sp->initializeIndexedFreeListArrayReturnedBytes();
-    _sp->dictionary()->initializeDictReturnedBytes();
+    _sp->dictionary()->initialize_dict_returned_bytes();
   )
   assert(_limit >= _sp->bottom() && _limit <= _sp->end(),
          "sweep _limit out of bounds");
@@ -7954,13 +7943,13 @@
 
     if (PrintCMSStatistics && CMSVerifyReturnedBytes) {
       size_t indexListReturnedBytes = _sp->sumIndexedFreeListArrayReturnedBytes();
-      size_t dictReturnedBytes = _sp->dictionary()->sumDictReturnedBytes();
-      size_t returnedBytes = indexListReturnedBytes + dictReturnedBytes;
-      gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returnedBytes);
+      size_t dict_returned_bytes = _sp->dictionary()->sum_dict_returned_bytes();
+      size_t returned_bytes = indexListReturnedBytes + dict_returned_bytes;
+      gclog_or_tty->print("Returned "SIZE_FORMAT" bytes", returned_bytes);
       gclog_or_tty->print("   Indexed List Returned "SIZE_FORMAT" bytes",
         indexListReturnedBytes);
       gclog_or_tty->print_cr("        Dictionary Returned "SIZE_FORMAT" bytes",
-        dictReturnedBytes);
+        dict_returned_bytes);
     }
   }
   if (CMSTraceSweeper) {
@@ -7985,9 +7974,9 @@
   if (CMSTestInFreeList) {
     if (freeRangeInFreeLists) {
       FreeChunk* fc = (FreeChunk*) freeFinger;
-      assert(fc->isFree(), "A chunk on the free list should be free.");
+      assert(fc->is_free(), "A chunk on the free list should be free.");
       assert(fc->size() > 0, "Free range should have a size");
-      assert(_sp->verifyChunkInFreeLists(fc), "Chunk is not in free lists");
+      assert(_sp->verify_chunk_in_free_list(fc), "Chunk is not in free lists");
     }
   }
 }
@@ -8057,7 +8046,7 @@
   assert(addr < _limit, "sweep invariant");
   // check if we should yield
   do_yield_check(addr);
-  if (fc->isFree()) {
+  if (fc->is_free()) {
     // Chunk that is already free
     res = fc->size();
     do_already_free_chunk(fc);
@@ -8145,7 +8134,7 @@
   // Chunks that cannot be coalesced are not in the
   // free lists.
   if (CMSTestInFreeList && !fc->cantCoalesce()) {
-    assert(_sp->verifyChunkInFreeLists(fc),
+    assert(_sp->verify_chunk_in_free_list(fc),
       "free chunk should be in free lists");
   }
   // a chunk that is already free, should not have been
@@ -8171,7 +8160,7 @@
         FreeChunk* nextChunk = (FreeChunk*)(addr + size);
         assert((HeapWord*)nextChunk <= _sp->end(), "Chunk size out of bounds?");
         if ((HeapWord*)nextChunk < _sp->end() &&     // There is another free chunk to the right ...
-            nextChunk->isFree()               &&     // ... which is free...
+            nextChunk->is_free()               &&     // ... which is free...
             nextChunk->cantCoalesce()) {             // ... but can't be coalesced
           // nothing to do
         } else {
@@ -8203,7 +8192,7 @@
           assert(ffc->size() == pointer_delta(addr, freeFinger()),
             "Size of free range is inconsistent with chunk size.");
           if (CMSTestInFreeList) {
-            assert(_sp->verifyChunkInFreeLists(ffc),
+            assert(_sp->verify_chunk_in_free_list(ffc),
               "free range is not in free lists");
           }
           _sp->removeFreeChunkFromFreeLists(ffc);
@@ -8262,7 +8251,7 @@
         assert(ffc->size() == pointer_delta(addr, freeFinger()),
           "Size of free range is inconsistent with chunk size.");
         if (CMSTestInFreeList) {
-          assert(_sp->verifyChunkInFreeLists(ffc),
+          assert(_sp->verify_chunk_in_free_list(ffc),
             "free range is not in free lists");
         }
         _sp->removeFreeChunkFromFreeLists(ffc);
@@ -8351,11 +8340,11 @@
                                                  size_t chunkSize) {
   // do_post_free_or_garbage_chunk() should only be called in the case
   // of the adaptive free list allocator.
-  const bool fcInFreeLists = fc->isFree();
+  const bool fcInFreeLists = fc->is_free();
   assert(_sp->adaptive_freelists(), "Should only be used in this case.");
   assert((HeapWord*)fc <= _limit, "sweep invariant");
   if (CMSTestInFreeList && fcInFreeLists) {
-    assert(_sp->verifyChunkInFreeLists(fc), "free chunk is not in free lists");
+    assert(_sp->verify_chunk_in_free_list(fc), "free chunk is not in free lists");
   }
 
   if (CMSTraceSweeper) {
@@ -8410,7 +8399,7 @@
       assert(ffc->size() == pointer_delta(fc_addr, freeFinger()),
         "Size of free range is inconsistent with chunk size.");
       if (CMSTestInFreeList) {
-        assert(_sp->verifyChunkInFreeLists(ffc),
+        assert(_sp->verify_chunk_in_free_list(ffc),
           "Chunk is not in free lists");
       }
       _sp->coalDeath(ffc->size());
@@ -8459,7 +8448,7 @@
                  " when examining fc = " PTR_FORMAT "(" SIZE_FORMAT ")",
                  _limit, _sp->bottom(), _sp->end(), fc, chunk_size));
   if (eob >= _limit) {
-    assert(eob == _limit || fc->isFree(), "Only a free chunk should allow us to cross over the limit");
+    assert(eob == _limit || fc->is_free(), "Only a free chunk should allow us to cross over the limit");
     if (CMSTraceSweeper) {
       gclog_or_tty->print_cr("_limit " PTR_FORMAT " reached or crossed by block "
                              "[" PTR_FORMAT "," PTR_FORMAT ") in space "
@@ -8482,8 +8471,8 @@
   if (!freeRangeInFreeLists()) {
     if (CMSTestInFreeList) {
       FreeChunk* fc = (FreeChunk*) chunk;
-      fc->setSize(size);
-      assert(!_sp->verifyChunkInFreeLists(fc),
+      fc->set_size(size);
+      assert(!_sp->verify_chunk_in_free_list(fc),
         "chunk should not be in free lists yet");
     }
     if (CMSTraceSweeper) {
@@ -8557,8 +8546,8 @@
 // This is actually very useful in a product build if it can
 // be called from the debugger.  Compile it into the product
 // as needed.
-bool debug_verifyChunkInFreeLists(FreeChunk* fc) {
-  return debug_cms_space->verifyChunkInFreeLists(fc);
+bool debug_verify_chunk_in_free_list(FreeChunk* fc) {
+  return debug_cms_space->verify_chunk_in_free_list(fc);
 }
 #endif
 
@@ -9255,7 +9244,7 @@
       size_t chunk_at_end_old_size = chunk_at_end->size();
       assert(chunk_at_end_old_size >= word_size_change,
         "Shrink is too large");
-      chunk_at_end->setSize(chunk_at_end_old_size -
+      chunk_at_end->set_size(chunk_at_end_old_size -
                           word_size_change);
       _cmsSpace->freed((HeapWord*) chunk_at_end->end(),
         word_size_change);
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
index 4406774..3db4f11 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,10 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_CONCURRENTMARKSWEEPGENERATION_HPP
 
-#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp"
 #include "gc_implementation/shared/gSpaceCounters.hpp"
 #include "gc_implementation/shared/gcStats.hpp"
 #include "gc_implementation/shared/generationCounters.hpp"
+#include "memory/freeBlockDictionary.hpp"
 #include "memory/generation.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/virtualspace.hpp"
@@ -161,7 +161,7 @@
 
 // Represents a marking stack used by the CMS collector.
 // Ideally this should be GrowableArray<> just like MSC's marking stack(s).
-class CMSMarkStack: public CHeapObj  {
+class CMSMarkStack: public CHeapObj<mtGC>  {
   //
   friend class CMSCollector;   // to get at expasion stats further below
   //
@@ -265,7 +265,7 @@
 
 // Survivor Chunk Array in support of parallelization of
 // Survivor Space rescan.
-class ChunkArray: public CHeapObj {
+class ChunkArray: public CHeapObj<mtGC> {
   size_t _index;
   size_t _capacity;
   size_t _overflows;
@@ -506,7 +506,7 @@
 };
 
 
-class CMSCollector: public CHeapObj {
+class CMSCollector: public CHeapObj<mtGC> {
   friend class VMStructs;
   friend class ConcurrentMarkSweepThread;
   friend class ConcurrentMarkSweepGeneration;
@@ -553,8 +553,8 @@
   // The following array-pair keeps track of mark words
   // displaced for accomodating overflow list above.
   // This code will likely be revisited under RFE#4922830.
-  Stack<oop>     _preserved_oop_stack;
-  Stack<markOop> _preserved_mark_stack;
+  Stack<oop, mtGC>     _preserved_oop_stack;
+  Stack<markOop, mtGC> _preserved_mark_stack;
 
   int*             _hash_seed;
 
@@ -717,7 +717,7 @@
     CMS_op_checkpointRootsFinal
   };
 
-  void do_CMS_operation(CMS_op_type op);
+  void do_CMS_operation(CMS_op_type op, GCCause::Cause gc_cause);
   bool stop_world_and_do(CMS_op_type op);
 
   OopTaskQueueSet* task_queues() { return _task_queues; }
@@ -988,7 +988,7 @@
   CMSGCAdaptivePolicyCounters* gc_adaptive_policy_counters();
 
   // debugging
-  void verify(bool);
+  void verify();
   bool verify_after_remark();
   void verify_ok_to_terminate() const PRODUCT_RETURN;
   void verify_work_stacks_empty() const PRODUCT_RETURN;
@@ -1106,7 +1106,7 @@
   ConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size,
                                 int level, CardTableRS* ct,
                                 bool use_adaptive_freelists,
-                                FreeBlockDictionary::DictionaryChoice);
+                                FreeBlockDictionary<FreeChunk>::DictionaryChoice);
 
   // Accessors
   CMSCollector* collector() const { return _collector; }
@@ -1279,7 +1279,7 @@
 
   // Debugging
   void prepare_for_verify();
-  void verify(bool allow_dirty);
+  void verify();
   void print_statistics()               PRODUCT_RETURN;
 
   // Performance Counters support
@@ -1328,7 +1328,7 @@
   ASConcurrentMarkSweepGeneration(ReservedSpace rs, size_t initial_byte_size,
                                   int level, CardTableRS* ct,
                                   bool use_adaptive_freelists,
-                                  FreeBlockDictionary::DictionaryChoice
+                                  FreeBlockDictionary<FreeChunk>::DictionaryChoice
                                     dictionaryChoice) :
     ConcurrentMarkSweepGeneration(rs, initial_byte_size, level, ct,
       use_adaptive_freelists, dictionaryChoice) {}
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp
deleted file mode 100644
index 5386620..0000000
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * 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
- * 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.
- *
- */
-
-#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREEBLOCKDICTIONARY_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREEBLOCKDICTIONARY_HPP
-
-#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
-#include "memory/allocation.hpp"
-#include "memory/memRegion.hpp"
-#include "runtime/mutex.hpp"
-#include "utilities/debug.hpp"
-#include "utilities/globalDefinitions.hpp"
-#include "utilities/ostream.hpp"
-
-// A FreeBlockDictionary is an abstract superclass that will allow
-// a number of alternative implementations in the future.
-class FreeBlockDictionary: public CHeapObj {
- public:
-  enum Dither {
-    atLeast,
-    exactly,
-    roughly
-  };
-  enum DictionaryChoice {
-    dictionaryBinaryTree = 0,
-    dictionarySplayTree  = 1,
-    dictionarySkipList   = 2
-  };
-
- private:
-  NOT_PRODUCT(Mutex* _lock;)
-
- public:
-  virtual void       removeChunk(FreeChunk* fc) = 0;
-  virtual FreeChunk* getChunk(size_t size, Dither dither = atLeast) = 0;
-  virtual void       returnChunk(FreeChunk* chunk) = 0;
-  virtual size_t     totalChunkSize(debug_only(const Mutex* lock)) const = 0;
-  virtual size_t     maxChunkSize()   const = 0;
-  virtual size_t     minSize()        const = 0;
-  // Reset the dictionary to the initial conditions for a single
-  // block.
-  virtual void       reset(HeapWord* addr, size_t size) = 0;
-  virtual void       reset() = 0;
-
-  virtual void       dictCensusUpdate(size_t size, bool split, bool birth) = 0;
-  virtual bool       coalDictOverPopulated(size_t size) = 0;
-  virtual void       beginSweepDictCensus(double coalSurplusPercent,
-                       float inter_sweep_current, float inter_sweep_estimate,
-                       float intra__sweep_current) = 0;
-  virtual void       endSweepDictCensus(double splitSurplusPercent) = 0;
-  virtual FreeChunk* findLargestDict() const = 0;
-  // verify that the given chunk is in the dictionary.
-  virtual bool verifyChunkInFreeLists(FreeChunk* tc) const = 0;
-
-  // Sigma_{all_free_blocks} (block_size^2)
-  virtual double sum_of_squared_block_sizes() const = 0;
-
-  virtual FreeChunk* find_chunk_ends_at(HeapWord* target) const = 0;
-  virtual void inc_totalSize(size_t v) = 0;
-  virtual void dec_totalSize(size_t v) = 0;
-
-  NOT_PRODUCT (
-    virtual size_t   sumDictReturnedBytes() = 0;
-    virtual void     initializeDictReturnedBytes() = 0;
-    virtual size_t   totalCount() = 0;
-  )
-
-  virtual void       reportStatistics() const {
-    gclog_or_tty->print("No statistics available");
-  }
-
-  virtual void       printDictCensus() const = 0;
-  virtual void       print_free_lists(outputStream* st) const = 0;
-
-  virtual void       verify()         const = 0;
-
-  Mutex* par_lock()                const PRODUCT_RETURN0;
-  void   set_par_lock(Mutex* lock)       PRODUCT_RETURN;
-  void   verify_par_locked()       const PRODUCT_RETURN;
-};
-
-#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREEBLOCKDICTIONARY_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp
index 84702b6..d0693ab 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.cpp
@@ -23,7 +23,8 @@
  */
 
 #include "precompiled.hpp"
-#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp"
+#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
+#include "memory/freeBlockDictionary.hpp"
 #include "utilities/copy.hpp"
 
 #ifndef PRODUCT
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp
index 70a11b7..582fe9e 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeChunk.hpp
@@ -75,20 +75,20 @@
     // calls.  We really want the read of _mark and _prev from this pointer
     // to be volatile but making the fields volatile causes all sorts of
     // compilation errors.
-    return ((volatile FreeChunk*)addr)->isFree();
+    return ((volatile FreeChunk*)addr)->is_free();
   }
 
-  bool isFree() const volatile {
+  bool is_free() const volatile {
     LP64_ONLY(if (UseCompressedOops) return mark()->is_cms_free_chunk(); else)
     return (((intptr_t)_prev) & 0x1) == 0x1;
   }
   bool cantCoalesce() const {
-    assert(isFree(), "can't get coalesce bit on not free");
+    assert(is_free(), "can't get coalesce bit on not free");
     return (((intptr_t)_prev) & 0x2) == 0x2;
   }
   void dontCoalesce() {
     // the block should be free
-    assert(isFree(), "Should look like a free block");
+    assert(is_free(), "Should look like a free block");
     _prev = (FreeChunk*)(((intptr_t)_prev) | 0x2);
   }
   FreeChunk* prev() const {
@@ -103,23 +103,23 @@
     LP64_ONLY(if (UseCompressedOops) return mark()->get_size(); else )
     return _size;
   }
-  void setSize(size_t sz) {
+  void set_size(size_t sz) {
     LP64_ONLY(if (UseCompressedOops) set_mark(markOopDesc::set_size_and_free(sz)); else )
     _size = sz;
   }
 
   FreeChunk* next()   const { return _next; }
 
-  void linkAfter(FreeChunk* ptr) {
-    linkNext(ptr);
-    if (ptr != NULL) ptr->linkPrev(this);
+  void link_after(FreeChunk* ptr) {
+    link_next(ptr);
+    if (ptr != NULL) ptr->link_prev(this);
   }
-  void linkNext(FreeChunk* ptr) { _next = ptr; }
-  void linkPrev(FreeChunk* ptr) {
+  void link_next(FreeChunk* ptr) { _next = ptr; }
+  void link_prev(FreeChunk* ptr) {
     LP64_ONLY(if (UseCompressedOops) _prev = ptr; else)
     _prev = (FreeChunk*)((intptr_t)ptr | 0x1);
   }
-  void clearNext()              { _next = NULL; }
+  void clear_next()              { _next = NULL; }
   void markNotFree() {
     // Set _prev (klass) to null before (if) clearing the mark word below
     _prev = NULL;
@@ -129,7 +129,7 @@
       set_mark(markOopDesc::prototype());
     }
 #endif
-    assert(!isFree(), "Error");
+    assert(!is_free(), "Error");
   }
 
   // Return the address past the end of this chunk
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp
index 6fa109a..ffb119c 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.cpp
@@ -121,7 +121,7 @@
 void PromotionInfo::track(PromotedObject* trackOop, klassOop klassOfOop) {
   // make a copy of header as it may need to be spooled
   markOop mark = oop(trackOop)->mark();
-  trackOop->clearNext();
+  trackOop->clear_next();
   if (mark->must_be_preserved_for_cms_scavenge(klassOfOop)) {
     // save non-prototypical header, and mark oop
     saveDisplacedHeader(mark);
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp
index 463c33b..27a455f 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/promotionInfo.hpp
@@ -43,7 +43,7 @@
   // whose position will depend on endian-ness of the platform.
   // This is so that there is no interference with the
   // cms_free_bit occupying bit position 7 (lsb == 0)
-  // when we are using compressed oops; see FreeChunk::isFree().
+  // when we are using compressed oops; see FreeChunk::is_free().
   // We cannot move the cms_free_bit down because currently
   // biased locking code assumes that age bits are contiguous
   // with the lock bits. Even if that assumption were relaxed,
@@ -65,7 +65,7 @@
   };
  public:
   inline PromotedObject* next() const {
-    assert(!((FreeChunk*)this)->isFree(), "Error");
+    assert(!((FreeChunk*)this)->is_free(), "Error");
     PromotedObject* res;
     if (UseCompressedOops) {
       // The next pointer is a compressed oop stored in the top 32 bits
@@ -85,27 +85,27 @@
     } else {
       _next |= (intptr_t)x;
     }
-    assert(!((FreeChunk*)this)->isFree(), "Error");
+    assert(!((FreeChunk*)this)->is_free(), "Error");
   }
   inline void setPromotedMark() {
     _next |= promoted_mask;
-    assert(!((FreeChunk*)this)->isFree(), "Error");
+    assert(!((FreeChunk*)this)->is_free(), "Error");
   }
   inline bool hasPromotedMark() const {
-    assert(!((FreeChunk*)this)->isFree(), "Error");
+    assert(!((FreeChunk*)this)->is_free(), "Error");
     return (_next & promoted_mask) == promoted_mask;
   }
   inline void setDisplacedMark() {
     _next |= displaced_mark;
-    assert(!((FreeChunk*)this)->isFree(), "Error");
+    assert(!((FreeChunk*)this)->is_free(), "Error");
   }
   inline bool hasDisplacedMark() const {
-    assert(!((FreeChunk*)this)->isFree(), "Error");
+    assert(!((FreeChunk*)this)->is_free(), "Error");
     return (_next & displaced_mark) != 0;
   }
-  inline void clearNext()        {
+  inline void clear_next()        {
     _next = 0;
-    assert(!((FreeChunk*)this)->isFree(), "Error");
+    assert(!((FreeChunk*)this)->is_free(), "Error");
   }
   debug_only(void *next_addr() { return (void *) &_next; })
 };
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp
index c3b9d54..7b5f44a 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmCMSOperations.cpp
@@ -64,7 +64,7 @@
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
     Universe::heap()->prepare_for_verify();
-    Universe::verify(true);
+    Universe::verify();
   }
 }
 
@@ -74,7 +74,7 @@
     HandleMark hm;
     FreelistLocker x(_collector);
     MutexLockerEx  y(_collector->bitMapLock(), Mutex::_no_safepoint_check_flag);
-    Universe::verify(true);
+    Universe::verify();
   }
 }
 
@@ -146,7 +146,7 @@
   VM_CMS_Operation::verify_before_gc();
 
   IsGCActiveMark x; // stop-world GC active
-  _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial);
+  _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsInitial, gch->gc_cause());
 
   VM_CMS_Operation::verify_after_gc();
 #ifndef USDT2
@@ -178,7 +178,7 @@
   VM_CMS_Operation::verify_before_gc();
 
   IsGCActiveMark x; // stop-world GC active
-  _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal);
+  _collector->do_CMS_operation(CMSCollector::CMS_op_checkpointRootsFinal, gch->gc_cause());
 
   VM_CMS_Operation::verify_after_gc();
 #ifndef USDT2
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
index 34460c1..c64e0eb 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/vmStructs_cms.hpp
@@ -44,11 +44,11 @@
   nonstatic_field(FreeChunk,                   _next,                                         FreeChunk*)                            \
   nonstatic_field(FreeChunk,                   _prev,                                         FreeChunk*)                            \
   nonstatic_field(LinearAllocBlock,            _word_size,                                    size_t)                                \
-  nonstatic_field(FreeList,                    _size,                                         size_t)                                \
-  nonstatic_field(FreeList,                    _count,                                        ssize_t)                               \
-  nonstatic_field(BinaryTreeDictionary,        _totalSize,                                    size_t)                                \
-  nonstatic_field(CompactibleFreeListSpace,    _dictionary,                                   FreeBlockDictionary*)                  \
-  nonstatic_field(CompactibleFreeListSpace,    _indexedFreeList[0],                           FreeList)                              \
+  nonstatic_field(FreeList<FreeChunk>,         _size,                                         size_t)                                \
+  nonstatic_field(FreeList<FreeChunk>,         _count,                                        ssize_t)                               \
+  nonstatic_field(BinaryTreeDictionary<FreeChunk>,_total_size,                                 size_t)                                \
+  nonstatic_field(CompactibleFreeListSpace,    _dictionary,                                   FreeBlockDictionary<FreeChunk>*)       \
+  nonstatic_field(CompactibleFreeListSpace,    _indexedFreeList[0],                           FreeList<FreeChunk>)                   \
   nonstatic_field(CompactibleFreeListSpace,    _smallLinearAllocBlock,                        LinearAllocBlock)
 
 
@@ -70,13 +70,13 @@
   declare_toplevel_type(CompactibleFreeListSpace*)                        \
   declare_toplevel_type(CMSCollector*)                                    \
   declare_toplevel_type(FreeChunk*)                                       \
-  declare_toplevel_type(BinaryTreeDictionary*)                            \
-  declare_toplevel_type(FreeBlockDictionary*)                             \
-  declare_toplevel_type(FreeList*)                                        \
-  declare_toplevel_type(FreeList)                                         \
+  declare_toplevel_type(BinaryTreeDictionary<FreeChunk>*)                 \
+  declare_toplevel_type(FreeBlockDictionary<FreeChunk>*)                  \
+  declare_toplevel_type(FreeList<FreeChunk>*)                             \
+  declare_toplevel_type(FreeList<FreeChunk>)                              \
   declare_toplevel_type(LinearAllocBlock)                                 \
-  declare_toplevel_type(FreeBlockDictionary)                              \
-            declare_type(BinaryTreeDictionary,        FreeBlockDictionary)
+  declare_toplevel_type(FreeBlockDictionary<FreeChunk>)                   \
+            declare_type(BinaryTreeDictionary<FreeChunk>, FreeBlockDictionary<FreeChunk>)
 
 #define VM_INT_CONSTANTS_CMS(declare_constant)                            \
   declare_constant(Generation::ConcurrentMarkSweep)                       \
diff --git a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp
index fb587ea..663011a 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.cpp
@@ -29,102 +29,6 @@
 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
 #include "memory/space.inline.hpp"
 
-CSetChooserCache::CSetChooserCache() {
-  for (int i = 0; i < CacheLength; ++i)
-    _cache[i] = NULL;
-  clear();
-}
-
-void CSetChooserCache::clear() {
-  _occupancy = 0;
-  _first = 0;
-  for (int i = 0; i < CacheLength; ++i) {
-    HeapRegion *hr = _cache[i];
-    if (hr != NULL)
-      hr->set_sort_index(-1);
-    _cache[i] = NULL;
-  }
-}
-
-#ifndef PRODUCT
-bool CSetChooserCache::verify() {
-  guarantee(false, "CSetChooserCache::verify(): don't call this any more");
-
-  int index = _first;
-  HeapRegion *prev = NULL;
-  for (int i = 0; i < _occupancy; ++i) {
-    guarantee(_cache[index] != NULL, "cache entry should not be empty");
-    HeapRegion *hr = _cache[index];
-    guarantee(!hr->is_young(), "should not be young!");
-    if (prev != NULL) {
-      guarantee(prev->gc_efficiency() >= hr->gc_efficiency(),
-                "cache should be correctly ordered");
-    }
-    guarantee(hr->sort_index() == get_sort_index(index),
-              "sort index should be correct");
-    index = trim_index(index + 1);
-    prev = hr;
-  }
-
-  for (int i = 0; i < (CacheLength - _occupancy); ++i) {
-    guarantee(_cache[index] == NULL, "cache entry should be empty");
-    index = trim_index(index + 1);
-  }
-
-  guarantee(index == _first, "we should have reached where we started from");
-  return true;
-}
-#endif // PRODUCT
-
-void CSetChooserCache::insert(HeapRegion *hr) {
-  guarantee(false, "CSetChooserCache::insert(): don't call this any more");
-
-  assert(!is_full(), "cache should not be empty");
-  hr->calc_gc_efficiency();
-
-  int empty_index;
-  if (_occupancy == 0) {
-    empty_index = _first;
-  } else {
-    empty_index = trim_index(_first + _occupancy);
-    assert(_cache[empty_index] == NULL, "last slot should be empty");
-    int last_index = trim_index(empty_index - 1);
-    HeapRegion *last = _cache[last_index];
-    assert(last != NULL,"as the cache is not empty, last should not be empty");
-    while (empty_index != _first &&
-           last->gc_efficiency() < hr->gc_efficiency()) {
-      _cache[empty_index] = last;
-      last->set_sort_index(get_sort_index(empty_index));
-      empty_index = last_index;
-      last_index = trim_index(last_index - 1);
-      last = _cache[last_index];
-    }
-  }
-  _cache[empty_index] = hr;
-  hr->set_sort_index(get_sort_index(empty_index));
-
-  ++_occupancy;
-  assert(verify(), "cache should be consistent");
-}
-
-HeapRegion *CSetChooserCache::remove_first() {
-  guarantee(false, "CSetChooserCache::remove_first(): "
-                   "don't call this any more");
-
-  if (_occupancy > 0) {
-    assert(_cache[_first] != NULL, "cache should have at least one region");
-    HeapRegion *ret = _cache[_first];
-    _cache[_first] = NULL;
-    ret->set_sort_index(-1);
-    --_occupancy;
-    _first = trim_index(_first + 1);
-    assert(verify(), "cache should be consistent");
-    return ret;
-  } else {
-    return NULL;
-  }
-}
-
 // Even though we don't use the GC efficiency in our heuristics as
 // much as we used to, we still order according to GC efficiency. This
 // will cause regions with a lot of live objects and large RSets to
@@ -134,7 +38,7 @@
 // the ones we'll skip are ones with both large RSets and a lot of
 // live objects, not the ones with just a lot of live objects if we
 // ordered according to the amount of reclaimable bytes per region.
-static int orderRegions(HeapRegion* hr1, HeapRegion* hr2) {
+static int order_regions(HeapRegion* hr1, HeapRegion* hr2) {
   if (hr1 == NULL) {
     if (hr2 == NULL) {
       return 0;
@@ -156,8 +60,8 @@
   }
 }
 
-static int orderRegions(HeapRegion** hr1p, HeapRegion** hr2p) {
-  return orderRegions(*hr1p, *hr2p);
+static int order_regions(HeapRegion** hr1p, HeapRegion** hr2p) {
+  return order_regions(*hr1p, *hr2p);
 }
 
 CollectionSetChooser::CollectionSetChooser() :
@@ -175,105 +79,74 @@
   //
   // Note: containing object is allocated on C heap since it is CHeapObj.
   //
-  _markedRegions((ResourceObj::set_allocation_type((address)&_markedRegions,
+  _regions((ResourceObj::set_allocation_type((address) &_regions,
                                              ResourceObj::C_HEAP),
                   100), true /* C_Heap */),
-    _curr_index(0), _length(0),
-    _regionLiveThresholdBytes(0), _remainingReclaimableBytes(0),
-    _first_par_unreserved_idx(0) {
-  _regionLiveThresholdBytes =
+    _curr_index(0), _length(0), _first_par_unreserved_idx(0),
+    _region_live_threshold_bytes(0), _remaining_reclaimable_bytes(0) {
+  _region_live_threshold_bytes =
     HeapRegion::GrainBytes * (size_t) G1OldCSetRegionLiveThresholdPercent / 100;
 }
 
 #ifndef PRODUCT
-bool CollectionSetChooser::verify() {
-  guarantee(_length >= 0, err_msg("_length: %d", _length));
-  guarantee(0 <= _curr_index && _curr_index <= _length,
-            err_msg("_curr_index: %d _length: %d", _curr_index, _length));
-  int index = 0;
+void CollectionSetChooser::verify() {
+  guarantee(_length <= regions_length(),
+         err_msg("_length: %u regions length: %u", _length, regions_length()));
+  guarantee(_curr_index <= _length,
+            err_msg("_curr_index: %u _length: %u", _curr_index, _length));
+  uint index = 0;
   size_t sum_of_reclaimable_bytes = 0;
   while (index < _curr_index) {
-    guarantee(_markedRegions.at(index) == NULL,
+    guarantee(regions_at(index) == NULL,
               "all entries before _curr_index should be NULL");
     index += 1;
   }
   HeapRegion *prev = NULL;
   while (index < _length) {
-    HeapRegion *curr = _markedRegions.at(index++);
-    guarantee(curr != NULL, "Regions in _markedRegions array cannot be NULL");
-    int si = curr->sort_index();
+    HeapRegion *curr = regions_at(index++);
+    guarantee(curr != NULL, "Regions in _regions array cannot be NULL");
     guarantee(!curr->is_young(), "should not be young!");
     guarantee(!curr->isHumongous(), "should not be humongous!");
-    guarantee(si > -1 && si == (index-1), "sort index invariant");
     if (prev != NULL) {
-      guarantee(orderRegions(prev, curr) != 1,
+      guarantee(order_regions(prev, curr) != 1,
                 err_msg("GC eff prev: %1.4f GC eff curr: %1.4f",
                         prev->gc_efficiency(), curr->gc_efficiency()));
     }
     sum_of_reclaimable_bytes += curr->reclaimable_bytes();
     prev = curr;
   }
-  guarantee(sum_of_reclaimable_bytes == _remainingReclaimableBytes,
+  guarantee(sum_of_reclaimable_bytes == _remaining_reclaimable_bytes,
             err_msg("reclaimable bytes inconsistent, "
                     "remaining: "SIZE_FORMAT" sum: "SIZE_FORMAT,
-                    _remainingReclaimableBytes, sum_of_reclaimable_bytes));
-  return true;
+                    _remaining_reclaimable_bytes, sum_of_reclaimable_bytes));
 }
-#endif
+#endif // !PRODUCT
 
-void CollectionSetChooser::fillCache() {
-  guarantee(false, "fillCache: don't call this any more");
-
-  while (!_cache.is_full() && (_curr_index < _length)) {
-    HeapRegion* hr = _markedRegions.at(_curr_index);
-    assert(hr != NULL,
-           err_msg("Unexpected NULL hr in _markedRegions at index %d",
-                   _curr_index));
-    _curr_index += 1;
-    assert(!hr->is_young(), "should not be young!");
-    assert(hr->sort_index() == _curr_index-1, "sort_index invariant");
-    _markedRegions.at_put(hr->sort_index(), NULL);
-    _cache.insert(hr);
-    assert(!_cache.is_empty(), "cache should not be empty");
-  }
-  assert(verify(), "cache should be consistent");
-}
-
-void CollectionSetChooser::sortMarkedHeapRegions() {
+void CollectionSetChooser::sort_regions() {
   // First trim any unused portion of the top in the parallel case.
   if (_first_par_unreserved_idx > 0) {
-    if (G1PrintParCleanupStats) {
-      gclog_or_tty->print("     Truncating _markedRegions from %d to %d.\n",
-                          _markedRegions.length(), _first_par_unreserved_idx);
-    }
-    assert(_first_par_unreserved_idx <= _markedRegions.length(),
+    assert(_first_par_unreserved_idx <= regions_length(),
            "Or we didn't reserved enough length");
-    _markedRegions.trunc_to(_first_par_unreserved_idx);
+    regions_trunc_to(_first_par_unreserved_idx);
   }
-  _markedRegions.sort(orderRegions);
-  assert(_length <= _markedRegions.length(), "Requirement");
-  assert(_length == 0 || _markedRegions.at(_length - 1) != NULL,
-         "Testing _length");
-  assert(_length == _markedRegions.length() ||
-                        _markedRegions.at(_length) == NULL, "Testing _length");
-  if (G1PrintParCleanupStats) {
-    gclog_or_tty->print_cr("     Sorted %d marked regions.", _length);
+  _regions.sort(order_regions);
+  assert(_length <= regions_length(), "Requirement");
+#ifdef ASSERT
+  for (uint i = 0; i < _length; i++) {
+    assert(regions_at(i) != NULL, "Should be true by sorting!");
   }
-  for (int i = 0; i < _length; i++) {
-    assert(_markedRegions.at(i) != NULL, "Should be true by sorting!");
-    _markedRegions.at(i)->set_sort_index(i);
-  }
+#endif // ASSERT
   if (G1PrintRegionLivenessInfo) {
     G1PrintRegionLivenessInfoClosure cl(gclog_or_tty, "Post-Sorting");
-    for (int i = 0; i < _length; ++i) {
-      HeapRegion* r = _markedRegions.at(i);
+    for (uint i = 0; i < _length; ++i) {
+      HeapRegion* r = regions_at(i);
       cl.doHeapRegion(r);
     }
   }
-  assert(verify(), "CSet chooser verification");
+  verify();
 }
 
-size_t CollectionSetChooser::calcMinOldCSetLength() {
+uint CollectionSetChooser::calc_min_old_cset_length() {
   // The min old CSet region bound is based on the maximum desired
   // number of mixed GCs after a cycle. I.e., even if some old regions
   // look expensive, we should add them to the CSet anyway to make
@@ -285,16 +158,16 @@
   // that the result is the same during all mixed GCs that follow a cycle.
 
   const size_t region_num = (size_t) _length;
-  const size_t gc_num = (size_t) G1MaxMixedGCNum;
+  const size_t gc_num = (size_t) G1MixedGCCountTarget;
   size_t result = region_num / gc_num;
   // emulate ceiling
   if (result * gc_num < region_num) {
     result += 1;
   }
-  return result;
+  return (uint) result;
 }
 
-size_t CollectionSetChooser::calcMaxOldCSetLength() {
+uint CollectionSetChooser::calc_max_old_cset_length() {
   // The max old CSet region bound is based on the threshold expressed
   // as a percentage of the heap size. I.e., it should bound the
   // number of old regions added to the CSet irrespective of how many
@@ -308,23 +181,23 @@
   if (100 * result < region_num * perc) {
     result += 1;
   }
-  return result;
+  return (uint) result;
 }
 
-void CollectionSetChooser::addMarkedHeapRegion(HeapRegion* hr) {
+void CollectionSetChooser::add_region(HeapRegion* hr) {
   assert(!hr->isHumongous(),
          "Humongous regions shouldn't be added to the collection set");
   assert(!hr->is_young(), "should not be young!");
-  _markedRegions.append(hr);
+  _regions.append(hr);
   _length++;
-  _remainingReclaimableBytes += hr->reclaimable_bytes();
+  _remaining_reclaimable_bytes += hr->reclaimable_bytes();
   hr->calc_gc_efficiency();
 }
 
-void CollectionSetChooser::prepareForAddMarkedHeapRegionsPar(size_t n_regions,
-                                                             size_t chunkSize) {
+void CollectionSetChooser::prepare_for_par_region_addition(uint n_regions,
+                                                           uint chunk_size) {
   _first_par_unreserved_idx = 0;
-  int n_threads = ParallelGCThreads;
+  uint n_threads = (uint) ParallelGCThreads;
   if (UseDynamicNumberOfGCThreads) {
     assert(G1CollectedHeap::heap()->workers()->active_workers() > 0,
       "Should have been set earlier");
@@ -335,57 +208,46 @@
     n_threads = MAX2(G1CollectedHeap::heap()->workers()->active_workers(),
                      1U);
   }
-  size_t max_waste = n_threads * chunkSize;
-  // it should be aligned with respect to chunkSize
-  size_t aligned_n_regions =
-                     (n_regions + (chunkSize - 1)) / chunkSize * chunkSize;
-  assert( aligned_n_regions % chunkSize == 0, "should be aligned" );
-  _markedRegions.at_put_grow((int)(aligned_n_regions + max_waste - 1), NULL);
+  uint max_waste = n_threads * chunk_size;
+  // it should be aligned with respect to chunk_size
+  uint aligned_n_regions = (n_regions + chunk_size - 1) / chunk_size * chunk_size;
+  assert(aligned_n_regions % chunk_size == 0, "should be aligned");
+  regions_at_put_grow(aligned_n_regions + max_waste - 1, NULL);
 }
 
-jint CollectionSetChooser::getParMarkedHeapRegionChunk(jint n_regions) {
-  // Don't do this assert because this can be called at a point
-  // where the loop up stream will not execute again but might
-  // try to claim more chunks (loop test has not been done yet).
-  // assert(_markedRegions.length() > _first_par_unreserved_idx,
-  //  "Striding beyond the marked regions");
-  jint res = Atomic::add(n_regions, &_first_par_unreserved_idx);
-  assert(_markedRegions.length() > res + n_regions - 1,
+uint CollectionSetChooser::claim_array_chunk(uint chunk_size) {
+  uint res = (uint) Atomic::add((jint) chunk_size,
+                                (volatile jint*) &_first_par_unreserved_idx);
+  assert(regions_length() > res + chunk_size - 1,
          "Should already have been expanded");
-  return res - n_regions;
+  return res - chunk_size;
 }
 
-void CollectionSetChooser::setMarkedHeapRegion(jint index, HeapRegion* hr) {
-  assert(_markedRegions.at(index) == NULL, "precondition");
+void CollectionSetChooser::set_region(uint index, HeapRegion* hr) {
+  assert(regions_at(index) == NULL, "precondition");
   assert(!hr->is_young(), "should not be young!");
-  _markedRegions.at_put(index, hr);
+  regions_at_put(index, hr);
   hr->calc_gc_efficiency();
 }
 
-void CollectionSetChooser::updateTotals(jint region_num,
-                                        size_t reclaimable_bytes) {
+void CollectionSetChooser::update_totals(uint region_num,
+                                         size_t reclaimable_bytes) {
   // Only take the lock if we actually need to update the totals.
   if (region_num > 0) {
     assert(reclaimable_bytes > 0, "invariant");
     // We could have just used atomics instead of taking the
     // lock. However, we currently don't have an atomic add for size_t.
     MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
-    _length += (int) region_num;
-    _remainingReclaimableBytes += reclaimable_bytes;
+    _length += region_num;
+    _remaining_reclaimable_bytes += reclaimable_bytes;
   } else {
     assert(reclaimable_bytes == 0, "invariant");
   }
 }
 
-void CollectionSetChooser::clearMarkedHeapRegions() {
-  for (int i = 0; i < _markedRegions.length(); i++) {
-    HeapRegion* r = _markedRegions.at(i);
-    if (r != NULL) {
-      r->set_sort_index(-1);
-    }
-  }
-  _markedRegions.clear();
+void CollectionSetChooser::clear() {
+  _regions.clear();
   _curr_index = 0;
   _length = 0;
-  _remainingReclaimableBytes = 0;
+  _remaining_reclaimable_bytes = 0;
 };
diff --git a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp
index 3bf90eb..1a147b8 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/collectionSetChooser.hpp
@@ -28,77 +28,42 @@
 #include "gc_implementation/g1/heapRegion.hpp"
 #include "utilities/growableArray.hpp"
 
-class CSetChooserCache VALUE_OBJ_CLASS_SPEC {
-private:
-  enum {
-    CacheLength = 16
-  } PrivateConstants;
+class CollectionSetChooser: public CHeapObj<mtGC> {
 
-  HeapRegion*  _cache[CacheLength];
-  int          _occupancy; // number of regions in cache
-  int          _first;     // (index of) "first" region in the cache
+  GrowableArray<HeapRegion*> _regions;
 
-  // adding CacheLength to deal with negative values
-  inline int trim_index(int index) {
-    return (index + CacheLength) % CacheLength;
+  // Unfortunately, GrowableArray uses ints for length and indexes. To
+  // avoid excessive casting in the rest of the class the following
+  // wrapper methods are provided that use uints.
+
+  uint regions_length()          { return (uint) _regions.length(); }
+  HeapRegion* regions_at(uint i) { return _regions.at((int) i);     }
+  void regions_at_put(uint i, HeapRegion* hr) {
+    _regions.at_put((int) i, hr);
   }
-
-  inline int get_sort_index(int index) {
-    return -index-2;
+  void regions_at_put_grow(uint i, HeapRegion* hr) {
+    _regions.at_put_grow((int) i, hr);
   }
-  inline int get_index(int sort_index) {
-    return -sort_index-2;
-  }
-
-public:
-  CSetChooserCache(void);
-
-  inline int occupancy(void) { return _occupancy; }
-  inline bool is_full()      { return _occupancy == CacheLength; }
-  inline bool is_empty()     { return _occupancy == 0; }
-
-  void clear(void);
-  void insert(HeapRegion *hr);
-  HeapRegion *remove_first(void);
-  inline HeapRegion *get_first(void) {
-    return _cache[_first];
-  }
-
-#ifndef PRODUCT
-  bool verify (void);
-  bool region_in_cache(HeapRegion *hr) {
-    int sort_index = hr->sort_index();
-    if (sort_index < -1) {
-      int index = get_index(sort_index);
-      guarantee(index < CacheLength, "should be within bounds");
-      return _cache[index] == hr;
-    } else
-      return 0;
-  }
-#endif // PRODUCT
-};
-
-class CollectionSetChooser: public CHeapObj {
-
-  GrowableArray<HeapRegion*> _markedRegions;
+  void regions_trunc_to(uint i)  { _regions.trunc_to((uint) i); }
 
   // The index of the next candidate old region to be considered for
   // addition to the CSet.
-  int _curr_index;
+  uint _curr_index;
 
   // The number of candidate old regions added to the CSet chooser.
-  int _length;
+  uint _length;
 
-  CSetChooserCache _cache;
-  jint _first_par_unreserved_idx;
+  // Keeps track of the start of the next array chunk to be claimed by
+  // parallel GC workers.
+  uint _first_par_unreserved_idx;
 
   // If a region has more live bytes than this threshold, it will not
   // be added to the CSet chooser and will not be a candidate for
   // collection.
-  size_t _regionLiveThresholdBytes;
+  size_t _region_live_threshold_bytes;
 
   // The sum of reclaimable bytes over all the regions in the CSet chooser.
-  size_t _remainingReclaimableBytes;
+  size_t _remaining_reclaimable_bytes;
 
 public:
 
@@ -107,9 +72,9 @@
   HeapRegion* peek() {
     HeapRegion* res = NULL;
     if (_curr_index < _length) {
-      res = _markedRegions.at(_curr_index);
+      res = regions_at(_curr_index);
       assert(res != NULL,
-             err_msg("Unexpected NULL hr in _markedRegions at index %d",
+             err_msg("Unexpected NULL hr in _regions at index %u",
                      _curr_index));
     }
     return res;
@@ -121,90 +86,114 @@
   void remove_and_move_to_next(HeapRegion* hr) {
     assert(hr != NULL, "pre-condition");
     assert(_curr_index < _length, "pre-condition");
-    assert(_markedRegions.at(_curr_index) == hr, "pre-condition");
-    hr->set_sort_index(-1);
-    _markedRegions.at_put(_curr_index, NULL);
-    assert(hr->reclaimable_bytes() <= _remainingReclaimableBytes,
+    assert(regions_at(_curr_index) == hr, "pre-condition");
+    regions_at_put(_curr_index, NULL);
+    assert(hr->reclaimable_bytes() <= _remaining_reclaimable_bytes,
            err_msg("remaining reclaimable bytes inconsistent "
                    "from region: "SIZE_FORMAT" remaining: "SIZE_FORMAT,
-                   hr->reclaimable_bytes(), _remainingReclaimableBytes));
-    _remainingReclaimableBytes -= hr->reclaimable_bytes();
+                   hr->reclaimable_bytes(), _remaining_reclaimable_bytes));
+    _remaining_reclaimable_bytes -= hr->reclaimable_bytes();
     _curr_index += 1;
   }
 
   CollectionSetChooser();
 
-  void sortMarkedHeapRegions();
-  void fillCache();
+  void sort_regions();
 
   // Determine whether to add the given region to the CSet chooser or
   // not. Currently, we skip humongous regions (we never add them to
   // the CSet, we only reclaim them during cleanup) and regions whose
   // live bytes are over the threshold.
-  bool shouldAdd(HeapRegion* hr) {
+  bool should_add(HeapRegion* hr) {
     assert(hr->is_marked(), "pre-condition");
     assert(!hr->is_young(), "should never consider young regions");
     return !hr->isHumongous() &&
-            hr->live_bytes() < _regionLiveThresholdBytes;
+            hr->live_bytes() < _region_live_threshold_bytes;
   }
 
   // Calculate the minimum number of old regions we'll add to the CSet
   // during a mixed GC.
-  size_t calcMinOldCSetLength();
+  uint calc_min_old_cset_length();
 
   // Calculate the maximum number of old regions we'll add to the CSet
   // during a mixed GC.
-  size_t calcMaxOldCSetLength();
+  uint calc_max_old_cset_length();
 
   // Serial version.
-  void addMarkedHeapRegion(HeapRegion *hr);
+  void add_region(HeapRegion *hr);
 
-  // Must be called before calls to getParMarkedHeapRegionChunk.
-  // "n_regions" is the number of regions, "chunkSize" the chunk size.
-  void prepareForAddMarkedHeapRegionsPar(size_t n_regions, size_t chunkSize);
-  // Returns the first index in a contiguous chunk of "n_regions" indexes
+  // Must be called before calls to claim_array_chunk().
+  // n_regions is the number of regions, chunk_size the chunk size.
+  void prepare_for_par_region_addition(uint n_regions, uint chunk_size);
+  // Returns the first index in a contiguous chunk of chunk_size indexes
   // that the calling thread has reserved.  These must be set by the
-  // calling thread using "setMarkedHeapRegion" (to NULL if necessary).
-  jint getParMarkedHeapRegionChunk(jint n_regions);
+  // calling thread using set_region() (to NULL if necessary).
+  uint claim_array_chunk(uint chunk_size);
   // Set the marked array entry at index to hr.  Careful to claim the index
   // first if in parallel.
-  void setMarkedHeapRegion(jint index, HeapRegion* hr);
+  void set_region(uint index, HeapRegion* hr);
   // Atomically increment the number of added regions by region_num
   // and the amount of reclaimable bytes by reclaimable_bytes.
-  void updateTotals(jint region_num, size_t reclaimable_bytes);
+  void update_totals(uint region_num, size_t reclaimable_bytes);
 
-  void clearMarkedHeapRegions();
+  void clear();
 
   // Return the number of candidate regions that remain to be collected.
-  size_t remainingRegions() { return _length - _curr_index; }
+  uint remaining_regions() { return _length - _curr_index; }
 
   // Determine whether the CSet chooser has more candidate regions or not.
-  bool isEmpty() { return remainingRegions() == 0; }
+  bool is_empty() { return remaining_regions() == 0; }
 
   // Return the reclaimable bytes that remain to be collected on
   // all the candidate regions in the CSet chooser.
-  size_t remainingReclaimableBytes () { return _remainingReclaimableBytes; }
+  size_t remaining_reclaimable_bytes() { return _remaining_reclaimable_bytes; }
 
-  // Returns true if the used portion of "_markedRegions" is properly
+  // Returns true if the used portion of "_regions" is properly
   // sorted, otherwise asserts false.
-#ifndef PRODUCT
-  bool verify(void);
-  bool regionProperlyOrdered(HeapRegion* r) {
-    int si = r->sort_index();
-    if (si > -1) {
-      guarantee(_curr_index <= si && si < _length,
-                err_msg("curr: %d sort index: %d: length: %d",
-                        _curr_index, si, _length));
-      guarantee(_markedRegions.at(si) == r,
-                err_msg("sort index: %d at: "PTR_FORMAT" r: "PTR_FORMAT,
-                        si, _markedRegions.at(si), r));
-    } else {
-      guarantee(si == -1, err_msg("sort index: %d", si));
-    }
-    return true;
-  }
-#endif
+  void verify() PRODUCT_RETURN;
+};
 
+class CSetChooserParUpdater : public StackObj {
+private:
+  CollectionSetChooser* _chooser;
+  bool _parallel;
+  uint _chunk_size;
+  uint _cur_chunk_idx;
+  uint _cur_chunk_end;
+  uint _regions_added;
+  size_t _reclaimable_bytes_added;
+
+public:
+  CSetChooserParUpdater(CollectionSetChooser* chooser,
+                        bool parallel, uint chunk_size) :
+    _chooser(chooser), _parallel(parallel), _chunk_size(chunk_size),
+    _cur_chunk_idx(0), _cur_chunk_end(0),
+    _regions_added(0), _reclaimable_bytes_added(0) { }
+
+  ~CSetChooserParUpdater() {
+    if (_parallel && _regions_added > 0) {
+      _chooser->update_totals(_regions_added, _reclaimable_bytes_added);
+    }
+  }
+
+  void add_region(HeapRegion* hr) {
+    if (_parallel) {
+      if (_cur_chunk_idx == _cur_chunk_end) {
+        _cur_chunk_idx = _chooser->claim_array_chunk(_chunk_size);
+        _cur_chunk_end = _cur_chunk_idx + _chunk_size;
+      }
+      assert(_cur_chunk_idx < _cur_chunk_end, "invariant");
+      _chooser->set_region(_cur_chunk_idx, hr);
+      _cur_chunk_idx += 1;
+    } else {
+      _chooser->add_region(hr);
+    }
+    _regions_added += 1;
+    _reclaimable_bytes_added += hr->reclaimable_bytes();
+  }
+
+  bool should_add(HeapRegion* hr) { return _chooser->should_add(hr); }
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_COLLECTIONSETCHOOSER_HPP
+
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
index a7b2460..3eab85e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 #include "gc_implementation/g1/concurrentG1RefineThread.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "memory/space.inline.hpp"
@@ -79,7 +80,7 @@
   _n_threads = _n_worker_threads + 1;
   reset_threshold_step();
 
-  _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads);
+  _threads = NEW_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _n_threads, mtGC);
   int worker_id_offset = (int)DirtyCardQueueSet::num_par_ids();
   ConcurrentG1RefineThread *next = NULL;
   for (int i = _n_threads - 1; i >= 0; i--) {
@@ -157,7 +158,7 @@
     _def_use_cache = true;
     _use_cache = true;
     _hot_cache_size = (1 << G1ConcRSLogCacheSize);
-    _hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size);
+    _hot_cache = NEW_C_HEAP_ARRAY(jbyte*, _hot_cache_size, mtGC);
     _n_hot = 0;
     _hot_cache_idx = 0;
 
@@ -191,18 +192,18 @@
     // Please see the comment in allocate_card_count_cache
     // for why we call os::malloc() and os::free() directly.
     assert(_card_counts != NULL, "Logic");
-    os::free(_card_counts);
+    os::free(_card_counts, mtGC);
     assert(_card_epochs != NULL, "Logic");
-    os::free(_card_epochs);
+    os::free(_card_epochs, mtGC);
 
     assert(_hot_cache != NULL, "Logic");
-    FREE_C_HEAP_ARRAY(jbyte*, _hot_cache);
+    FREE_C_HEAP_ARRAY(jbyte*, _hot_cache, mtGC);
   }
   if (_threads != NULL) {
     for (int i = 0; i < _n_threads; i++) {
       delete _threads[i];
     }
-    FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads);
+    FREE_C_HEAP_ARRAY(ConcurrentG1RefineThread*, _threads, mtGC);
   }
 }
 
@@ -436,17 +437,17 @@
   size_t counts_size = n * sizeof(CardCountCacheEntry);
   size_t epochs_size = n * sizeof(CardEpochCacheEntry);
 
-  *counts = (CardCountCacheEntry*) os::malloc(counts_size);
+  *counts = (CardCountCacheEntry*) os::malloc(counts_size, mtGC);
   if (*counts == NULL) {
     // allocation was unsuccessful
     return false;
   }
 
-  *epochs = (CardEpochCacheEntry*) os::malloc(epochs_size);
+  *epochs = (CardEpochCacheEntry*) os::malloc(epochs_size, mtGC);
   if (*epochs == NULL) {
     // allocation was unsuccessful - free counts array
     assert(*counts != NULL, "must be");
-    os::free(*counts);
+    os::free(*counts, mtGC);
     *counts = NULL;
     return false;
   }
@@ -479,8 +480,8 @@
         // Allocation was successful.
         // We can just free the old arrays; we're
         // not interested in preserving the contents
-        if (_card_counts != NULL) os::free(_card_counts);
-        if (_card_epochs != NULL) os::free(_card_epochs);
+        if (_card_counts != NULL) os::free(_card_counts, mtGC);
+        if (_card_epochs != NULL) os::free(_card_epochs, mtGC);
 
         // Cache the size of the arrays and the index that got us there.
         _n_card_counts = cache_size;
@@ -500,11 +501,11 @@
 }
 
 void ConcurrentG1Refine::clear_and_record_card_counts() {
-  if (G1ConcRSLogCacheSize == 0) return;
+  if (G1ConcRSLogCacheSize == 0) {
+    return;
+  }
 
-#ifndef PRODUCT
   double start = os::elapsedTime();
-#endif
 
   if (_expand_card_counts) {
     int new_idx = _cache_size_index + 1;
@@ -523,11 +524,8 @@
   assert((this_epoch+1) <= max_jint, "to many periods");
   // Update epoch
   _n_periods++;
-
-#ifndef PRODUCT
-  double elapsed = os::elapsedTime() - start;
-  _g1h->g1_policy()->record_cc_clear_time(elapsed * 1000.0);
-#endif
+  double cc_clear_time_ms = (os::elapsedTime() - start) * 1000;
+  _g1h->g1_policy()->phase_times()->record_cc_clear_time_ms(cc_clear_time_ms);
 }
 
 void ConcurrentG1Refine::print_worker_threads_on(outputStream* st) const {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
index 2379e18..46a7d30 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentG1Refine.hpp
@@ -34,7 +34,7 @@
 class ConcurrentG1RefineThread;
 class G1RemSet;
 
-class ConcurrentG1Refine: public CHeapObj {
+class ConcurrentG1Refine: public CHeapObj<mtGC> {
   ConcurrentG1RefineThread** _threads;
   int _n_threads;
   int _n_worker_threads;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
index 001f94e..5e68221 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.cpp
@@ -29,6 +29,7 @@
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
 #include "gc_implementation/g1/heapRegion.inline.hpp"
@@ -41,6 +42,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
+#include "services/memTracker.hpp"
 
 // Concurrent marking bit map wrapper
 
@@ -52,6 +54,8 @@
   ReservedSpace brs(ReservedSpace::allocation_align_size_up(
                      (_bmWordSize >> (_shifter + LogBitsPerByte)) + 1));
 
+  MemTracker::record_virtual_memory_type((address)brs.base(), mtGC);
+
   guarantee(brs.is_reserved(), "couldn't allocate concurrent marking bit map");
   // For now we'll just commit all of the bit map up fromt.
   // Later on we'll try to be more parsimonious with swap.
@@ -103,20 +107,10 @@
   return (int) (diff >> _shifter);
 }
 
-void CMBitMapRO::mostly_disjoint_range_union(BitMap*   from_bitmap,
-                                             size_t    from_start_index,
-                                             HeapWord* to_start_word,
-                                             size_t    word_num) {
-  _bm.mostly_disjoint_range_union(from_bitmap,
-                                  from_start_index,
-                                  heapWordToOffset(to_start_word),
-                                  word_num);
-}
-
 #ifndef PRODUCT
 bool CMBitMapRO::covers(ReservedSpace rs) const {
   // assert(_bm.map() == _virtual_space.low(), "map inconsistency");
-  assert(((size_t)_bm.size() * (size_t)(1 << _shifter)) == _bmWordSize,
+  assert(((size_t)_bm.size() * ((size_t)1 << _shifter)) == _bmWordSize,
          "size inconsistency");
   return _bmStartWord == (HeapWord*)(rs.base()) &&
          _bmWordSize  == rs.size()>>LogHeapWordSize;
@@ -170,7 +164,7 @@
 {}
 
 void CMMarkStack::allocate(size_t size) {
-  _base = NEW_C_HEAP_ARRAY(oop, size);
+  _base = NEW_C_HEAP_ARRAY(oop, size, mtGC);
   if (_base == NULL) {
     vm_exit_during_initialization("Failed to allocate CM region mark stack");
   }
@@ -182,7 +176,7 @@
 
 CMMarkStack::~CMMarkStack() {
   if (_base != NULL) {
-    FREE_C_HEAP_ARRAY(oop, _base);
+    FREE_C_HEAP_ARRAY(oop, _base, mtGC);
   }
 }
 
@@ -271,140 +265,6 @@
   }
 }
 
-CMRegionStack::CMRegionStack() : _base(NULL) {}
-
-void CMRegionStack::allocate(size_t size) {
-  _base = NEW_C_HEAP_ARRAY(MemRegion, size);
-  if (_base == NULL) {
-    vm_exit_during_initialization("Failed to allocate CM region mark stack");
-  }
-  _index = 0;
-  _capacity = (jint) size;
-}
-
-CMRegionStack::~CMRegionStack() {
-  if (_base != NULL) {
-    FREE_C_HEAP_ARRAY(oop, _base);
-  }
-}
-
-void CMRegionStack::push_lock_free(MemRegion mr) {
-  guarantee(false, "push_lock_free(): don't call this any more");
-
-  assert(mr.word_size() > 0, "Precondition");
-  while (true) {
-    jint index = _index;
-
-    if (index >= _capacity) {
-      _overflow = true;
-      return;
-    }
-    // Otherwise...
-    jint next_index = index+1;
-    jint res = Atomic::cmpxchg(next_index, &_index, index);
-    if (res == index) {
-      _base[index] = mr;
-      return;
-    }
-    // Otherwise, we need to try again.
-  }
-}
-
-// Lock-free pop of the region stack. Called during the concurrent
-// marking / remark phases. Should only be called in tandem with
-// other lock-free pops.
-MemRegion CMRegionStack::pop_lock_free() {
-  guarantee(false, "pop_lock_free(): don't call this any more");
-
-  while (true) {
-    jint index = _index;
-
-    if (index == 0) {
-      return MemRegion();
-    }
-    // Otherwise...
-    jint next_index = index-1;
-    jint res = Atomic::cmpxchg(next_index, &_index, index);
-    if (res == index) {
-      MemRegion mr = _base[next_index];
-      if (mr.start() != NULL) {
-        assert(mr.end() != NULL, "invariant");
-        assert(mr.word_size() > 0, "invariant");
-        return mr;
-      } else {
-        // that entry was invalidated... let's skip it
-        assert(mr.end() == NULL, "invariant");
-      }
-    }
-    // Otherwise, we need to try again.
-  }
-}
-
-#if 0
-// The routines that manipulate the region stack with a lock are
-// not currently used. They should be retained, however, as a
-// diagnostic aid.
-
-void CMRegionStack::push_with_lock(MemRegion mr) {
-  assert(mr.word_size() > 0, "Precondition");
-  MutexLockerEx x(CMRegionStack_lock, Mutex::_no_safepoint_check_flag);
-
-  if (isFull()) {
-    _overflow = true;
-    return;
-  }
-
-  _base[_index] = mr;
-  _index += 1;
-}
-
-MemRegion CMRegionStack::pop_with_lock() {
-  MutexLockerEx x(CMRegionStack_lock, Mutex::_no_safepoint_check_flag);
-
-  while (true) {
-    if (_index == 0) {
-      return MemRegion();
-    }
-    _index -= 1;
-
-    MemRegion mr = _base[_index];
-    if (mr.start() != NULL) {
-      assert(mr.end() != NULL, "invariant");
-      assert(mr.word_size() > 0, "invariant");
-      return mr;
-    } else {
-      // that entry was invalidated... let's skip it
-      assert(mr.end() == NULL, "invariant");
-    }
-  }
-}
-#endif
-
-bool CMRegionStack::invalidate_entries_into_cset() {
-  guarantee(false, "invalidate_entries_into_cset(): don't call this any more");
-
-  bool result = false;
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  for (int i = 0; i < _oops_do_bound; ++i) {
-    MemRegion mr = _base[i];
-    if (mr.start() != NULL) {
-      assert(mr.end() != NULL, "invariant");
-      assert(mr.word_size() > 0, "invariant");
-      HeapRegion* hr = g1h->heap_region_containing(mr.start());
-      assert(hr != NULL, "invariant");
-      if (hr->in_collection_set()) {
-        // The region points into the collection set
-        _base[i] = MemRegion();
-        result = true;
-      }
-    } else {
-      // that entry was invalidated... let's skip it
-      assert(mr.end() == NULL, "invariant");
-    }
-  }
-  return result;
-}
-
 template<class OopClosureClass>
 bool CMMarkStack::drain(OopClosureClass* cl, CMBitMap* bm, bool yield_after) {
   assert(!_drain_in_progress || !_drain_in_progress_yields || yield_after
@@ -546,8 +406,7 @@
   return MAX2((n_par_threads + 2) / 4, 1U);
 }
 
-ConcurrentMark::ConcurrentMark(ReservedSpace rs,
-                               int max_regions) :
+ConcurrentMark::ConcurrentMark(ReservedSpace rs, uint max_regions) :
   _markBitMap1(rs, MinObjAlignment - 1),
   _markBitMap2(rs, MinObjAlignment - 1),
 
@@ -558,17 +417,15 @@
   _cleanup_sleep_factor(0.0),
   _cleanup_task_overhead(1.0),
   _cleanup_list("Cleanup List"),
-  _region_bm(max_regions, false /* in_resource_area*/),
+  _region_bm((BitMap::idx_t) max_regions, false /* in_resource_area*/),
   _card_bm((rs.size() + CardTableModRefBS::card_size - 1) >>
            CardTableModRefBS::card_shift,
            false /* in_resource_area*/),
 
   _prevMarkBitMap(&_markBitMap1),
   _nextMarkBitMap(&_markBitMap2),
-  _at_least_one_mark_complete(false),
 
   _markStack(this),
-  _regionStack(),
   // _finger set in set_non_marking_state
 
   _max_task_num(MAX2((uint)ParallelGCThreads, 1U)),
@@ -582,7 +439,6 @@
   _has_aborted(false),
   _restart_for_overflow(false),
   _concurrent_marking_in_progress(false),
-  _should_gray_objects(false),
 
   // _verbose_level set below
 
@@ -611,7 +467,6 @@
   }
 
   _markStack.allocate(MarkStackSize);
-  _regionStack.allocate(G1MarkRegionStackSize);
 
   // Create & start a ConcurrentMark thread.
   _cmThread = new ConcurrentMarkThread(this);
@@ -628,11 +483,11 @@
 
   _root_regions.init(_g1h, this);
 
-  _tasks = NEW_C_HEAP_ARRAY(CMTask*, _max_task_num);
-  _accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_task_num);
+  _tasks = NEW_C_HEAP_ARRAY(CMTask*, _max_task_num, mtGC);
+  _accum_task_vtime = NEW_C_HEAP_ARRAY(double, _max_task_num, mtGC);
 
-  _count_card_bitmaps = NEW_C_HEAP_ARRAY(BitMap,  _max_task_num);
-  _count_marked_bytes = NEW_C_HEAP_ARRAY(size_t*, _max_task_num);
+  _count_card_bitmaps = NEW_C_HEAP_ARRAY(BitMap,  _max_task_num, mtGC);
+  _count_marked_bytes = NEW_C_HEAP_ARRAY(size_t*, _max_task_num, mtGC);
 
   BitMap::idx_t card_bm_size = _card_bm.size();
 
@@ -644,7 +499,7 @@
     _task_queues->register_queue(i, task_queue);
 
     _count_card_bitmaps[i] = BitMap(card_bm_size, false);
-    _count_marked_bytes[i] = NEW_C_HEAP_ARRAY(size_t, max_regions);
+    _count_marked_bytes[i] = NEW_C_HEAP_ARRAY(size_t, (size_t) max_regions, mtGC);
 
     _tasks[i] = new CMTask(i, this,
                            _count_marked_bytes[i],
@@ -744,15 +599,7 @@
 
 void ConcurrentMark::update_g1_committed(bool force) {
   // If concurrent marking is not in progress, then we do not need to
-  // update _heap_end. This has a subtle and important
-  // side-effect. Imagine that two evacuation pauses happen between
-  // marking completion and remark. The first one can grow the
-  // heap (hence now the finger is below the heap end). Then, the
-  // second one could unnecessarily push regions on the region
-  // stack. This causes the invariant that the region stack is empty
-  // at the beginning of remark to be false. By ensuring that we do
-  // not observe heap expansions after marking is complete, then we do
-  // not have this problem.
+  // update _heap_end.
   if (!concurrent_marking_in_progress() && !force) return;
 
   MemRegion committed = _g1h->g1_committed();
@@ -1002,7 +849,7 @@
     clear_marking_state(concurrent() /* clear_overflow */);
     force_overflow()->update();
 
-    if (PrintGC) {
+    if (G1Log::fine()) {
       gclog_or_tty->date_stamp(PrintGCDateStamps);
       gclog_or_tty->stamp(PrintGCTimeStamps);
       gclog_or_tty->print_cr("[GC concurrent-mark-reset-for-overflow]");
@@ -1058,86 +905,6 @@
 }
 #endif // !PRODUCT
 
-void ConcurrentMark::grayRegionIfNecessary(MemRegion mr) {
-  guarantee(false, "grayRegionIfNecessary(): don't call this any more");
-
-  // The objects on the region have already been marked "in bulk" by
-  // the caller. We only need to decide whether to push the region on
-  // the region stack or not.
-
-  if (!concurrent_marking_in_progress() || !_should_gray_objects) {
-    // We're done with marking and waiting for remark. We do not need to
-    // push anything else on the region stack.
-    return;
-  }
-
-  HeapWord* finger = _finger;
-
-  if (verbose_low()) {
-    gclog_or_tty->print_cr("[global] attempting to push "
-                           "region ["PTR_FORMAT", "PTR_FORMAT"), finger is at "
-                           PTR_FORMAT, mr.start(), mr.end(), finger);
-  }
-
-  if (mr.start() < finger) {
-    // The finger is always heap region aligned and it is not possible
-    // for mr to span heap regions.
-    assert(mr.end() <= finger, "invariant");
-
-    // Separated the asserts so that we know which one fires.
-    assert(mr.start() <= mr.end(),
-           "region boundaries should fall within the committed space");
-    assert(_heap_start <= mr.start(),
-           "region boundaries should fall within the committed space");
-    assert(mr.end() <= _heap_end,
-           "region boundaries should fall within the committed space");
-    if (verbose_low()) {
-      gclog_or_tty->print_cr("[global] region ["PTR_FORMAT", "PTR_FORMAT") "
-                             "below the finger, pushing it",
-                             mr.start(), mr.end());
-    }
-
-    if (!region_stack_push_lock_free(mr)) {
-      if (verbose_low()) {
-        gclog_or_tty->print_cr("[global] region stack has overflown.");
-      }
-    }
-  }
-}
-
-void ConcurrentMark::markAndGrayObjectIfNecessary(oop p) {
-  guarantee(false, "markAndGrayObjectIfNecessary(): don't call this any more");
-
-  // The object is not marked by the caller. We need to at least mark
-  // it and maybe push in on the stack.
-
-  HeapWord* addr = (HeapWord*)p;
-  if (!_nextMarkBitMap->isMarked(addr)) {
-    // We definitely need to mark it, irrespective whether we bail out
-    // because we're done with marking.
-    if (_nextMarkBitMap->parMark(addr)) {
-      if (!concurrent_marking_in_progress() || !_should_gray_objects) {
-        // If we're done with concurrent marking and we're waiting for
-        // remark, then we're not pushing anything on the stack.
-        return;
-      }
-
-      // No OrderAccess:store_load() is needed. It is implicit in the
-      // CAS done in parMark(addr) above
-      HeapWord* finger = _finger;
-
-      if (addr < finger) {
-        if (!mark_stack_push(oop(addr))) {
-          if (verbose_low()) {
-            gclog_or_tty->print_cr("[global] global stack overflow "
-                                   "during parMark");
-          }
-        }
-      }
-    }
-  }
-}
-
 class CMConcurrentMarkingTask: public AbstractGangTask {
 private:
   ConcurrentMark*       _cm;
@@ -1355,9 +1122,8 @@
     HandleMark hm;  // handle scope
     gclog_or_tty->print(" VerifyDuringGC:(before)");
     Universe::heap()->prepare_for_verify();
-    Universe::verify(/* allow dirty */ true,
-                     /* silent      */ false,
-                     /* option      */ VerifyOption_G1UsePrevMarking);
+    Universe::verify(/* silent */ false,
+                     /* option */ VerifyOption_G1UsePrevMarking);
   }
 
   G1CollectorPolicy* g1p = g1h->g1_policy();
@@ -1395,9 +1161,8 @@
       HandleMark hm;  // handle scope
       gclog_or_tty->print(" VerifyDuringGC:(after)");
       Universe::heap()->prepare_for_verify();
-      Universe::verify(/* allow dirty */ true,
-                       /* silent      */ false,
-                       /* option      */ VerifyOption_G1UseNextMarking);
+      Universe::verify(/* silent */ false,
+                       /* option */ VerifyOption_G1UseNextMarking);
     }
     assert(!restart_for_overflow(), "sanity");
   }
@@ -1421,43 +1186,18 @@
   g1p->record_concurrent_mark_remark_end();
 }
 
-// Used to calculate the # live objects per region
-// for verification purposes
-class CalcLiveObjectsClosure: public HeapRegionClosure {
-
-  CMBitMapRO* _bm;
+// Base class of the closures that finalize and verify the
+// liveness counting data.
+class CMCountDataClosureBase: public HeapRegionClosure {
+protected:
+  G1CollectedHeap* _g1h;
   ConcurrentMark* _cm;
+  CardTableModRefBS* _ct_bs;
+
   BitMap* _region_bm;
   BitMap* _card_bm;
 
-  // Debugging
-  size_t _tot_words_done;
-  size_t _tot_live;
-  size_t _tot_used;
-
-  size_t _region_marked_bytes;
-
-  intptr_t _bottom_card_num;
-
-  void mark_card_num_range(intptr_t start_card_num, intptr_t last_card_num) {
-    assert(start_card_num <= last_card_num, "sanity");
-    BitMap::idx_t start_idx = start_card_num - _bottom_card_num;
-    BitMap::idx_t last_idx = last_card_num - _bottom_card_num;
-
-    for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
-      _card_bm->par_at_put(i, 1);
-    }
-  }
-
-public:
-  CalcLiveObjectsClosure(CMBitMapRO *bm, ConcurrentMark *cm,
-                         BitMap* region_bm, BitMap* card_bm) :
-    _bm(bm), _cm(cm), _region_bm(region_bm), _card_bm(card_bm),
-    _region_marked_bytes(0), _tot_words_done(0),
-    _tot_live(0), _tot_used(0),
-    _bottom_card_num(cm->heap_bottom_card_num()) { }
-
-  // It takes a region that's not empty (i.e., it has at least one
+  // Takes a region that's not empty (i.e., it has at least one
   // live object in it and sets its corresponding bit on the region
   // bitmap to 1. If the region is "starts humongous" it will also set
   // to 1 the bits on the region bitmap that correspond to its
@@ -1465,21 +1205,38 @@
   void set_bit_for_region(HeapRegion* hr) {
     assert(!hr->continuesHumongous(), "should have filtered those out");
 
-    size_t index = hr->hrs_index();
+    BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index();
     if (!hr->startsHumongous()) {
       // Normal (non-humongous) case: just set the bit.
-      _region_bm->par_at_put((BitMap::idx_t) index, true);
+      _region_bm->par_at_put(index, true);
     } else {
       // Starts humongous case: calculate how many regions are part of
       // this humongous region and then set the bit range.
-      G1CollectedHeap* g1h = G1CollectedHeap::heap();
-      HeapRegion *last_hr = g1h->heap_region_containing_raw(hr->end() - 1);
-      size_t end_index = last_hr->hrs_index() + 1;
-      _region_bm->par_at_put_range((BitMap::idx_t) index,
-                                   (BitMap::idx_t) end_index, true);
+      BitMap::idx_t end_index = (BitMap::idx_t) hr->last_hc_index();
+      _region_bm->par_at_put_range(index, end_index, true);
     }
   }
 
+public:
+  CMCountDataClosureBase(G1CollectedHeap* g1h,
+                         BitMap* region_bm, BitMap* card_bm):
+    _g1h(g1h), _cm(g1h->concurrent_mark()),
+    _ct_bs((CardTableModRefBS*) (g1h->barrier_set())),
+    _region_bm(region_bm), _card_bm(card_bm) { }
+};
+
+// Closure that calculates the # live objects per region. Used
+// for verification purposes during the cleanup pause.
+class CalcLiveObjectsClosure: public CMCountDataClosureBase {
+  CMBitMapRO* _bm;
+  size_t _region_marked_bytes;
+
+public:
+  CalcLiveObjectsClosure(CMBitMapRO *bm, G1CollectedHeap* g1h,
+                         BitMap* region_bm, BitMap* card_bm) :
+    CMCountDataClosureBase(g1h, region_bm, card_bm),
+    _bm(bm), _region_marked_bytes(0) { }
+
   bool doHeapRegion(HeapRegion* hr) {
 
     if (hr->continuesHumongous()) {
@@ -1493,81 +1250,63 @@
       return false;
     }
 
-    HeapWord* nextTop = hr->next_top_at_mark_start();
-    HeapWord* start   = hr->bottom();
+    HeapWord* ntams = hr->next_top_at_mark_start();
+    HeapWord* start = hr->bottom();
 
-    assert(start <= hr->end() && start <= nextTop && nextTop <= hr->end(),
+    assert(start <= hr->end() && start <= ntams && ntams <= hr->end(),
            err_msg("Preconditions not met - "
-                   "start: "PTR_FORMAT", nextTop: "PTR_FORMAT", end: "PTR_FORMAT,
-                   start, nextTop, hr->end()));
-
-    // Record the number of word's we'll examine.
-    size_t words_done = (nextTop - start);
+                   "start: "PTR_FORMAT", ntams: "PTR_FORMAT", end: "PTR_FORMAT,
+                   start, ntams, hr->end()));
 
     // Find the first marked object at or after "start".
-    start = _bm->getNextMarkedWordAddress(start, nextTop);
+    start = _bm->getNextMarkedWordAddress(start, ntams);
 
     size_t marked_bytes = 0;
 
-    // Below, the term "card num" means the result of shifting an address
-    // by the card shift -- address 0 corresponds to card number 0.  One
-    // must subtract the card num of the bottom of the heap to obtain a
-    // card table index.
-
-    // The first card num of the sequence of live cards currently being
-    // constructed.  -1 ==> no sequence.
-    intptr_t start_card_num = -1;
-
-    // The last card num of the sequence of live cards currently being
-    // constructed.  -1 ==> no sequence.
-    intptr_t last_card_num = -1;
-
-    while (start < nextTop) {
+    while (start < ntams) {
       oop obj = oop(start);
       int obj_sz = obj->size();
+      HeapWord* obj_end = start + obj_sz;
 
-      // The card num of the start of the current object.
-      intptr_t obj_card_num =
-        intptr_t(uintptr_t(start) >> CardTableModRefBS::card_shift);
-      HeapWord* obj_last = start + obj_sz - 1;
-      intptr_t obj_last_card_num =
-        intptr_t(uintptr_t(obj_last) >> CardTableModRefBS::card_shift);
+      BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
+      BitMap::idx_t end_idx = _cm->card_bitmap_index_for(obj_end);
 
-      if (obj_card_num != last_card_num) {
-        if (start_card_num == -1) {
-          assert(last_card_num == -1, "Both or neither.");
-          start_card_num = obj_card_num;
-        } else {
-          assert(last_card_num != -1, "Both or neither.");
-          assert(obj_card_num >= last_card_num, "Inv");
-          if ((obj_card_num - last_card_num) > 1) {
-            // Mark the last run, and start a new one.
-            mark_card_num_range(start_card_num, last_card_num);
-            start_card_num = obj_card_num;
-          }
-        }
+      // Note: if we're looking at the last region in heap - obj_end
+      // could be actually just beyond the end of the heap; end_idx
+      // will then correspond to a (non-existent) card that is also
+      // just beyond the heap.
+      if (_g1h->is_in_g1_reserved(obj_end) && !_ct_bs->is_card_aligned(obj_end)) {
+        // end of object is not card aligned - increment to cover
+        // all the cards spanned by the object
+        end_idx += 1;
       }
-      // In any case, we set the last card num.
-      last_card_num = obj_last_card_num;
 
+      // Set the bits in the card BM for the cards spanned by this object.
+      _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
+
+      // Add the size of this object to the number of marked bytes.
       marked_bytes += (size_t)obj_sz * HeapWordSize;
 
       // Find the next marked object after this one.
-      start = _bm->getNextMarkedWordAddress(start + 1, nextTop);
-    }
-
-    // Handle the last range, if any.
-    if (start_card_num != -1) {
-      mark_card_num_range(start_card_num, last_card_num);
+      start = _bm->getNextMarkedWordAddress(obj_end, ntams);
     }
 
     // Mark the allocated-since-marking portion...
     HeapWord* top = hr->top();
-    if (nextTop < top) {
-      start_card_num = intptr_t(uintptr_t(nextTop) >> CardTableModRefBS::card_shift);
-      last_card_num = intptr_t(uintptr_t(top) >> CardTableModRefBS::card_shift);
+    if (ntams < top) {
+      BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
+      BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top);
 
-      mark_card_num_range(start_card_num, last_card_num);
+      // Note: if we're looking at the last region in heap - top
+      // could be actually just beyond the end of the heap; end_idx
+      // will then correspond to a (non-existent) card that is also
+      // just beyond the heap.
+      if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) {
+        // end of object is not card aligned - increment to cover
+        // all the cards spanned by the object
+        end_idx += 1;
+      }
+      _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
 
       // This definitely means the region has live objects.
       set_bit_for_region(hr);
@@ -1582,19 +1321,10 @@
     // it can be queried by a calling verificiation routine
     _region_marked_bytes = marked_bytes;
 
-    _tot_live += hr->next_live_bytes();
-    _tot_used += hr->used();
-    _tot_words_done = words_done;
-
     return false;
   }
 
   size_t region_marked_bytes() const { return _region_marked_bytes; }
-
-  // Debugging
-  size_t tot_words_done() const      { return _tot_words_done; }
-  size_t tot_live() const            { return _tot_live; }
-  size_t tot_used() const            { return _tot_used; }
 };
 
 // Heap region closure used for verifying the counting data
@@ -1603,6 +1333,7 @@
 // regions during the STW cleanup pause.
 
 class VerifyLiveObjectDataHRClosure: public HeapRegionClosure {
+  G1CollectedHeap* _g1h;
   ConcurrentMark* _cm;
   CalcLiveObjectsClosure _calc_cl;
   BitMap* _region_bm;   // Region BM to be verified
@@ -1615,14 +1346,14 @@
   int _failures;
 
 public:
-  VerifyLiveObjectDataHRClosure(ConcurrentMark* cm,
+  VerifyLiveObjectDataHRClosure(G1CollectedHeap* g1h,
                                 BitMap* region_bm,
                                 BitMap* card_bm,
                                 BitMap* exp_region_bm,
                                 BitMap* exp_card_bm,
                                 bool verbose) :
-    _cm(cm),
-    _calc_cl(_cm->nextMarkBitMap(), _cm, exp_region_bm, exp_card_bm),
+    _g1h(g1h), _cm(g1h->concurrent_mark()),
+    _calc_cl(_cm->nextMarkBitMap(), g1h, exp_region_bm, exp_card_bm),
     _region_bm(region_bm), _card_bm(card_bm), _verbose(verbose),
     _exp_region_bm(exp_region_bm), _exp_card_bm(exp_card_bm),
     _failures(0) { }
@@ -1652,17 +1383,6 @@
     MutexLockerEx x((_verbose ? ParGCRareEvent_lock : NULL),
                     Mutex::_no_safepoint_check_flag);
 
-    // Verify that _top_at_conc_count == ntams
-    if (hr->top_at_conc_mark_count() != hr->next_top_at_mark_start()) {
-      if (_verbose) {
-        gclog_or_tty->print_cr("Region " SIZE_FORMAT ": top at conc count incorrect: "
-                               "expected " PTR_FORMAT ", actual: " PTR_FORMAT,
-                               hr->hrs_index(), hr->next_top_at_mark_start(),
-                               hr->top_at_conc_mark_count());
-      }
-      failures += 1;
-    }
-
     // Verify the marked bytes for this region.
     size_t exp_marked_bytes = _calc_cl.region_marked_bytes();
     size_t act_marked_bytes = hr->next_marked_bytes();
@@ -1671,7 +1391,7 @@
     // we have missed accounting some objects during the actual marking.
     if (exp_marked_bytes > act_marked_bytes) {
       if (_verbose) {
-        gclog_or_tty->print_cr("Region " SIZE_FORMAT ": marked bytes mismatch: "
+        gclog_or_tty->print_cr("Region %u: marked bytes mismatch: "
                                "expected: " SIZE_FORMAT ", actual: " SIZE_FORMAT,
                                hr->hrs_index(), exp_marked_bytes, act_marked_bytes);
       }
@@ -1682,15 +1402,16 @@
     // (which was just calculated) region bit maps.
     // We're not OK if the bit in the calculated expected region
     // bitmap is set and the bit in the actual region bitmap is not.
-    BitMap::idx_t index = (BitMap::idx_t)hr->hrs_index();
+    BitMap::idx_t index = (BitMap::idx_t) hr->hrs_index();
 
     bool expected = _exp_region_bm->at(index);
     bool actual = _region_bm->at(index);
     if (expected && !actual) {
       if (_verbose) {
-        gclog_or_tty->print_cr("Region " SIZE_FORMAT ": region bitmap mismatch: "
-                               "expected: %d, actual: %d",
-                               hr->hrs_index(), expected, actual);
+        gclog_or_tty->print_cr("Region %u: region bitmap mismatch: "
+                               "expected: %s, actual: %s",
+                               hr->hrs_index(),
+                               BOOL_TO_STR(expected), BOOL_TO_STR(actual));
       }
       failures += 1;
     }
@@ -1708,9 +1429,10 @@
 
       if (expected && !actual) {
         if (_verbose) {
-          gclog_or_tty->print_cr("Region " SIZE_FORMAT ": card bitmap mismatch at " SIZE_FORMAT ": "
-                                 "expected: %d, actual: %d",
-                                 hr->hrs_index(), i, expected, actual);
+          gclog_or_tty->print_cr("Region %u: card bitmap mismatch at " SIZE_FORMAT ": "
+                                 "expected: %s, actual: %s",
+                                 hr->hrs_index(), i,
+                                 BOOL_TO_STR(expected), BOOL_TO_STR(actual));
         }
         failures += 1;
       }
@@ -1726,7 +1448,7 @@
     _failures += failures;
 
     // We could stop iteration over the heap when we
-    // find the first voilating region by returning true.
+    // find the first violating region by returning true.
     return false;
   }
 };
@@ -1778,7 +1500,7 @@
   void work(uint worker_id) {
     assert(worker_id < _n_workers, "invariant");
 
-    VerifyLiveObjectDataHRClosure verify_cl(_cm,
+    VerifyLiveObjectDataHRClosure verify_cl(_g1h,
                                             _actual_region_bm, _actual_card_bm,
                                             _expected_region_bm,
                                             _expected_card_bm,
@@ -1799,68 +1521,19 @@
   int failures() const { return _failures; }
 };
 
-// Final update of count data (during cleanup).
-// Adds [top_at_count, NTAMS) to the marked bytes for each
-// region. Sets the bits in the card bitmap corresponding
-// to the interval [top_at_count, top], and sets the
-// liveness bit for each region containing live data
-// in the region bitmap.
+// Closure that finalizes the liveness counting data.
+// Used during the cleanup pause.
+// Sets the bits corresponding to the interval [NTAMS, top]
+// (which contains the implicitly live objects) in the
+// card liveness bitmap. Also sets the bit for each region,
+// containing live data, in the region liveness bitmap.
 
-class FinalCountDataUpdateClosure: public HeapRegionClosure {
-  ConcurrentMark* _cm;
-  BitMap* _region_bm;
-  BitMap* _card_bm;
-
-  size_t _total_live_bytes;
-  size_t _total_used_bytes;
-  size_t _total_words_done;
-
-  void set_card_bitmap_range(BitMap::idx_t start_idx, BitMap::idx_t last_idx) {
-    assert(start_idx <= last_idx, "sanity");
-
-    // Set the inclusive bit range [start_idx, last_idx].
-    // For small ranges (up to 8 cards) use a simple loop; otherwise
-    // use par_at_put_range.
-    if ((last_idx - start_idx) <= 8) {
-      for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
-        _card_bm->par_set_bit(i);
-      }
-    } else {
-      assert(last_idx < _card_bm->size(), "sanity");
-      // Note BitMap::par_at_put_range() is exclusive.
-      _card_bm->par_at_put_range(start_idx, last_idx+1, true);
-    }
-  }
-
-  // It takes a region that's not empty (i.e., it has at least one
-  // live object in it and sets its corresponding bit on the region
-  // bitmap to 1. If the region is "starts humongous" it will also set
-  // to 1 the bits on the region bitmap that correspond to its
-  // associated "continues humongous" regions.
-  void set_bit_for_region(HeapRegion* hr) {
-    assert(!hr->continuesHumongous(), "should have filtered those out");
-
-    size_t index = hr->hrs_index();
-    if (!hr->startsHumongous()) {
-      // Normal (non-humongous) case: just set the bit.
-      _region_bm->par_set_bit((BitMap::idx_t) index);
-    } else {
-      // Starts humongous case: calculate how many regions are part of
-      // this humongous region and then set the bit range.
-      G1CollectedHeap* g1h = G1CollectedHeap::heap();
-      HeapRegion *last_hr = g1h->heap_region_containing_raw(hr->end() - 1);
-      size_t end_index = last_hr->hrs_index() + 1;
-      _region_bm->par_at_put_range((BitMap::idx_t) index,
-                                   (BitMap::idx_t) end_index, true);
-    }
-  }
-
+class FinalCountDataUpdateClosure: public CMCountDataClosureBase {
  public:
-  FinalCountDataUpdateClosure(ConcurrentMark* cm,
+  FinalCountDataUpdateClosure(G1CollectedHeap* g1h,
                               BitMap* region_bm,
                               BitMap* card_bm) :
-    _cm(cm), _region_bm(region_bm), _card_bm(card_bm),
-    _total_words_done(0), _total_live_bytes(0), _total_used_bytes(0) { }
+    CMCountDataClosureBase(g1h, region_bm, card_bm) { }
 
   bool doHeapRegion(HeapRegion* hr) {
 
@@ -1875,55 +1548,47 @@
       return false;
     }
 
-    HeapWord* start = hr->top_at_conc_mark_count();
     HeapWord* ntams = hr->next_top_at_mark_start();
     HeapWord* top   = hr->top();
 
-    assert(hr->bottom() <= start && start <= hr->end() &&
-           hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions.");
-
-    size_t words_done = ntams - hr->bottom();
-
-    if (start < ntams) {
-      // Region was changed between remark and cleanup pauses
-      // We need to add (ntams - start) to the marked bytes
-      // for this region, and set bits for the range
-      // [ card_idx(start), card_idx(ntams) ) in the card bitmap.
-      size_t live_bytes = (ntams - start) * HeapWordSize;
-      hr->add_to_marked_bytes(live_bytes);
-
-      // Record the new top at conc count
-      hr->set_top_at_conc_mark_count(ntams);
-
-      // The setting of the bits in the card bitmap takes place below
-    }
+    assert(hr->bottom() <= ntams && ntams <= hr->end(), "Preconditions.");
 
     // Mark the allocated-since-marking portion...
     if (ntams < top) {
       // This definitely means the region has live objects.
       set_bit_for_region(hr);
-    }
 
-    // Now set the bits for [start, top]
-    BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
-    BitMap::idx_t last_idx = _cm->card_bitmap_index_for(top);
-    set_card_bitmap_range(start_idx, last_idx);
+      // Now set the bits in the card bitmap for [ntams, top)
+      BitMap::idx_t start_idx = _cm->card_bitmap_index_for(ntams);
+      BitMap::idx_t end_idx = _cm->card_bitmap_index_for(top);
+
+      // Note: if we're looking at the last region in heap - top
+      // could be actually just beyond the end of the heap; end_idx
+      // will then correspond to a (non-existent) card that is also
+      // just beyond the heap.
+      if (_g1h->is_in_g1_reserved(top) && !_ct_bs->is_card_aligned(top)) {
+        // end of object is not card aligned - increment to cover
+        // all the cards spanned by the object
+        end_idx += 1;
+      }
+
+      assert(end_idx <= _card_bm->size(),
+             err_msg("oob: end_idx=  "SIZE_FORMAT", bitmap size= "SIZE_FORMAT,
+                     end_idx, _card_bm->size()));
+      assert(start_idx < _card_bm->size(),
+             err_msg("oob: start_idx=  "SIZE_FORMAT", bitmap size= "SIZE_FORMAT,
+                     start_idx, _card_bm->size()));
+
+      _cm->set_card_bitmap_range(_card_bm, start_idx, end_idx, true /* is_par */);
+     }
 
     // Set the bit for the region if it contains live data
     if (hr->next_marked_bytes() > 0) {
       set_bit_for_region(hr);
     }
 
-    _total_words_done += words_done;
-    _total_used_bytes += hr->used();
-    _total_live_bytes += hr->next_marked_bytes();
-
     return false;
   }
-
-  size_t total_words_done() const { return _total_words_done; }
-  size_t total_live_bytes() const { return _total_live_bytes; }
-  size_t total_used_bytes() const { return _total_used_bytes; }
 };
 
 class G1ParFinalCountTask: public AbstractGangTask {
@@ -1935,9 +1600,6 @@
 
   uint    _n_workers;
 
-  size_t *_live_bytes;
-  size_t *_used_bytes;
-
 public:
   G1ParFinalCountTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm)
     : AbstractGangTask("G1 final counting"),
@@ -1945,8 +1607,7 @@
       _actual_region_bm(region_bm), _actual_card_bm(card_bm),
       _n_workers(0) {
     // Use the value already set as the number of active threads
-    // in the call to run_task().  Needed for the allocation of
-    // _live_bytes and _used_bytes.
+    // in the call to run_task().
     if (G1CollectedHeap::use_parallel_gc_threads()) {
       assert( _g1h->workers()->active_workers() > 0,
         "Should have been previously set");
@@ -1954,20 +1615,12 @@
     } else {
       _n_workers = 1;
     }
-
-    _live_bytes = NEW_C_HEAP_ARRAY(size_t, _n_workers);
-    _used_bytes = NEW_C_HEAP_ARRAY(size_t, _n_workers);
-  }
-
-  ~G1ParFinalCountTask() {
-    FREE_C_HEAP_ARRAY(size_t, _live_bytes);
-    FREE_C_HEAP_ARRAY(size_t, _used_bytes);
   }
 
   void work(uint worker_id) {
     assert(worker_id < _n_workers, "invariant");
 
-    FinalCountDataUpdateClosure final_update_cl(_cm,
+    FinalCountDataUpdateClosure final_update_cl(_g1h,
                                                 _actual_region_bm,
                                                 _actual_card_bm);
 
@@ -1979,23 +1632,6 @@
     } else {
       _g1h->heap_region_iterate(&final_update_cl);
     }
-
-    _live_bytes[worker_id] = final_update_cl.total_live_bytes();
-    _used_bytes[worker_id] = final_update_cl.total_used_bytes();
-  }
-
-  size_t live_bytes()  {
-    size_t live_bytes = 0;
-    for (uint i = 0; i < _n_workers; ++i)
-      live_bytes += _live_bytes[i];
-    return live_bytes;
-  }
-
-  size_t used_bytes()  {
-    size_t used_bytes = 0;
-    for (uint i = 0; i < _n_workers; ++i)
-      used_bytes += _used_bytes[i];
-    return used_bytes;
   }
 };
 
@@ -2005,7 +1641,7 @@
   G1CollectedHeap* _g1;
   int _worker_num;
   size_t _max_live_bytes;
-  size_t _regions_claimed;
+  uint _regions_claimed;
   size_t _freed_bytes;
   FreeRegionList* _local_cleanup_list;
   OldRegionSet* _old_proxy_set;
@@ -2033,32 +1669,33 @@
   size_t freed_bytes() { return _freed_bytes; }
 
   bool doHeapRegion(HeapRegion *hr) {
+    if (hr->continuesHumongous()) {
+      return false;
+    }
     // We use a claim value of zero here because all regions
     // were claimed with value 1 in the FinalCount task.
-    hr->reset_gc_time_stamp();
-    if (!hr->continuesHumongous()) {
-      double start = os::elapsedTime();
-      _regions_claimed++;
-      hr->note_end_of_marking();
-      _max_live_bytes += hr->max_live_bytes();
-      _g1->free_region_if_empty(hr,
-                                &_freed_bytes,
-                                _local_cleanup_list,
-                                _old_proxy_set,
-                                _humongous_proxy_set,
-                                _hrrs_cleanup_task,
-                                true /* par */);
-      double region_time = (os::elapsedTime() - start);
-      _claimed_region_time += region_time;
-      if (region_time > _max_region_time) {
-        _max_region_time = region_time;
-      }
+    _g1->reset_gc_time_stamps(hr);
+    double start = os::elapsedTime();
+    _regions_claimed++;
+    hr->note_end_of_marking();
+    _max_live_bytes += hr->max_live_bytes();
+    _g1->free_region_if_empty(hr,
+                              &_freed_bytes,
+                              _local_cleanup_list,
+                              _old_proxy_set,
+                              _humongous_proxy_set,
+                              _hrrs_cleanup_task,
+                              true /* par */);
+    double region_time = (os::elapsedTime() - start);
+    _claimed_region_time += region_time;
+    if (region_time > _max_region_time) {
+      _max_region_time = region_time;
     }
     return false;
   }
 
   size_t max_live_bytes() { return _max_live_bytes; }
-  size_t regions_claimed() { return _regions_claimed; }
+  uint regions_claimed() { return _regions_claimed; }
   double claimed_region_time_sec() { return _claimed_region_time; }
   double max_region_time_sec() { return _max_region_time; }
 };
@@ -2130,15 +1767,6 @@
 
       HeapRegionRemSet::finish_cleanup_task(&hrrs_cleanup_task);
     }
-    double end = os::elapsedTime();
-    if (G1PrintParCleanupStats) {
-      gclog_or_tty->print("     Worker thread %d [%8.3f..%8.3f = %8.3f ms] "
-                          "claimed %u regions (tot = %8.3f ms, max = %8.3f ms).\n",
-                          worker_id, start, end, (end-start)*1000.0,
-                          g1_note_end.regions_claimed(),
-                          g1_note_end.claimed_region_time_sec()*1000.0,
-                          g1_note_end.max_region_time_sec()*1000.0);
-    }
   }
   size_t max_live_bytes() { return _max_live_bytes; }
   size_t freed_bytes() { return _freed_bytes; }
@@ -2185,9 +1813,8 @@
     HandleMark hm;  // handle scope
     gclog_or_tty->print(" VerifyDuringGC:(before)");
     Universe::heap()->prepare_for_verify();
-    Universe::verify(/* allow dirty */ true,
-                     /* silent      */ false,
-                     /* option      */ VerifyOption_G1UsePrevMarking);
+    Universe::verify(/* silent */ false,
+                     /* option */ VerifyOption_G1UsePrevMarking);
   }
 
   G1CollectorPolicy* g1p = G1CollectedHeap::heap()->g1_policy();
@@ -2250,30 +1877,11 @@
     guarantee(g1_par_verify_task.failures() == 0, "Unexpected accounting failures");
   }
 
-  size_t known_garbage_bytes =
-    g1_par_count_task.used_bytes() - g1_par_count_task.live_bytes();
-  g1p->set_known_garbage_bytes(known_garbage_bytes);
-
   size_t start_used_bytes = g1h->used();
-  _at_least_one_mark_complete = true;
   g1h->set_marking_complete();
 
-  ergo_verbose4(ErgoConcCycles,
-           "finish cleanup",
-           ergo_format_byte("occupancy")
-           ergo_format_byte("capacity")
-           ergo_format_byte_perc("known garbage"),
-           start_used_bytes, g1h->capacity(),
-           known_garbage_bytes,
-           ((double) known_garbage_bytes / (double) g1h->capacity()) * 100.0);
-
   double count_end = os::elapsedTime();
   double this_final_counting_time = (count_end - start);
-  if (G1PrintParCleanupStats) {
-    gclog_or_tty->print_cr("Cleanup:");
-    gclog_or_tty->print_cr("  Finalize counting: %8.3f ms",
-                           this_final_counting_time*1000.0);
-  }
   _total_counting_time += this_final_counting_time;
 
   if (G1PrintRegionLivenessInfo) {
@@ -2287,7 +1895,6 @@
   g1h->reset_gc_time_stamp();
 
   // Note end of marking in all heap regions.
-  double note_end_start = os::elapsedTime();
   G1ParNoteEndTask g1_par_note_end_task(g1h, &_cleanup_list);
   if (G1CollectedHeap::use_parallel_gc_threads()) {
     g1h->set_par_threads((int)n_workers);
@@ -2299,6 +1906,7 @@
   } else {
     g1_par_note_end_task.work(0);
   }
+  g1h->check_gc_time_stamps();
 
   if (!cleanup_list_is_empty()) {
     // The cleanup list is not empty, so we'll have to process it
@@ -2306,11 +1914,6 @@
     // regions that there will be more free regions coming soon.
     g1h->set_free_regions_coming();
   }
-  double note_end_end = os::elapsedTime();
-  if (G1PrintParCleanupStats) {
-    gclog_or_tty->print_cr("  note end of marking: %8.3f ms.",
-                           (note_end_end - note_end_start)*1000.0);
-  }
 
   // call below, since it affects the metric by which we sort the heap
   // regions.
@@ -2342,16 +1945,13 @@
   double end = os::elapsedTime();
   _cleanup_times.add((end - start) * 1000.0);
 
-  if (PrintGC || PrintGCDetails) {
+  if (G1Log::fine()) {
     g1h->print_size_transition(gclog_or_tty,
                                start_used_bytes,
                                g1h->used(),
                                g1h->capacity());
   }
 
-  size_t cleaned_up_bytes = start_used_bytes - g1h->used();
-  g1p->decrease_known_garbage_bytes(cleaned_up_bytes);
-
   // Clean up will have freed any regions completely full of garbage.
   // Update the soft reference policy with the new heap occupancy.
   Universe::update_heap_info_at_gc();
@@ -2368,9 +1968,8 @@
     HandleMark hm;  // handle scope
     gclog_or_tty->print(" VerifyDuringGC:(after)");
     Universe::heap()->prepare_for_verify();
-    Universe::verify(/* allow dirty */ true,
-                     /* silent      */ false,
-                     /* option      */ VerifyOption_G1UsePrevMarking);
+    Universe::verify(/* silent */ false,
+                     /* option */ VerifyOption_G1UsePrevMarking);
   }
 
   g1h->verify_region_sets_optional();
@@ -2386,7 +1985,7 @@
 
   if (G1ConcRegionFreeingVerbose) {
     gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
-                           "cleanup list has "SIZE_FORMAT" entries",
+                           "cleanup list has %u entries",
                            _cleanup_list.length());
   }
 
@@ -2408,9 +2007,8 @@
         _cleanup_list.is_empty()) {
       if (G1ConcRegionFreeingVerbose) {
         gclog_or_tty->print_cr("G1ConcRegionFreeing [complete cleanup] : "
-                               "appending "SIZE_FORMAT" entries to the "
-                               "secondary_free_list, clean list still has "
-                               SIZE_FORMAT" entries",
+                               "appending %u entries to the secondary_free_list, "
+                               "cleanup list still has %u entries",
                                tmp_free_list.length(),
                                _cleanup_list.length());
       }
@@ -2683,11 +2281,10 @@
   // Inner scope to exclude the cleaning of the string and symbol
   // tables from the displayed time.
   {
-    bool verbose = PrintGC && PrintGCDetails;
-    if (verbose) {
+    if (G1Log::finer()) {
       gclog_or_tty->put(' ');
     }
-    TraceTime t("GC ref-proc", verbose, false, gclog_or_tty);
+    TraceTime t("GC ref-proc", G1Log::finer(), false, gclog_or_tty);
 
     ReferenceProcessor* rp = g1h->ref_processor_cm();
 
@@ -2878,24 +2475,8 @@
     } else {
       HeapRegion* hr  = _g1h->heap_region_containing(obj);
       guarantee(hr != NULL, "invariant");
-      bool over_tams = false;
-      bool marked = false;
-
-      switch (_vo) {
-        case VerifyOption_G1UsePrevMarking:
-          over_tams = hr->obj_allocated_since_prev_marking(obj);
-          marked = _g1h->isMarkedPrev(obj);
-          break;
-        case VerifyOption_G1UseNextMarking:
-          over_tams = hr->obj_allocated_since_next_marking(obj);
-          marked = _g1h->isMarkedNext(obj);
-          break;
-        case VerifyOption_G1UseMarkWord:
-          marked = obj->is_gc_marked();
-          break;
-        default:
-          ShouldNotReachHere();
-      }
+      bool over_tams = _g1h->allocated_since_marking(obj, hr, _vo);
+      bool marked = _g1h->is_marked(obj, _vo);
 
       if (over_tams) {
         str = " >";
@@ -2931,24 +2512,8 @@
     _out(out), _vo(vo), _all(all), _hr(hr) { }
 
   void do_object(oop o) {
-    bool over_tams = false;
-    bool marked = false;
-
-    switch (_vo) {
-      case VerifyOption_G1UsePrevMarking:
-        over_tams = _hr->obj_allocated_since_prev_marking(o);
-        marked = _g1h->isMarkedPrev(o);
-        break;
-      case VerifyOption_G1UseNextMarking:
-        over_tams = _hr->obj_allocated_since_next_marking(o);
-        marked = _g1h->isMarkedNext(o);
-        break;
-      case VerifyOption_G1UseMarkWord:
-        marked = o->is_gc_marked();
-        break;
-      default:
-        ShouldNotReachHere();
-    }
+    bool over_tams = _g1h->allocated_since_marking(o, _hr, _vo);
+    bool marked = _g1h->is_marked(o, _vo);
     bool print_it = _all || over_tams || marked;
 
     if (print_it) {
@@ -2962,32 +2527,17 @@
 
 class PrintReachableRegionClosure : public HeapRegionClosure {
 private:
-  outputStream* _out;
-  VerifyOption  _vo;
-  bool          _all;
+  G1CollectedHeap* _g1h;
+  outputStream*    _out;
+  VerifyOption     _vo;
+  bool             _all;
 
 public:
   bool doHeapRegion(HeapRegion* hr) {
     HeapWord* b = hr->bottom();
     HeapWord* e = hr->end();
     HeapWord* t = hr->top();
-    HeapWord* p = NULL;
-
-    switch (_vo) {
-      case VerifyOption_G1UsePrevMarking:
-        p = hr->prev_top_at_mark_start();
-        break;
-      case VerifyOption_G1UseNextMarking:
-        p = hr->next_top_at_mark_start();
-        break;
-      case VerifyOption_G1UseMarkWord:
-        // When we are verifying marking using the mark word
-        // TAMS has no relevance.
-        assert(p == NULL, "post-condition");
-        break;
-      default:
-        ShouldNotReachHere();
-    }
+    HeapWord* p = _g1h->top_at_mark_start(hr, _vo);
     _out->print_cr("** ["PTR_FORMAT", "PTR_FORMAT"] top: "PTR_FORMAT" "
                    "TAMS: "PTR_FORMAT, b, e, t, p);
     _out->cr();
@@ -3009,20 +2559,9 @@
   PrintReachableRegionClosure(outputStream* out,
                               VerifyOption  vo,
                               bool          all) :
-    _out(out), _vo(vo), _all(all) { }
+    _g1h(G1CollectedHeap::heap()), _out(out), _vo(vo), _all(all) { }
 };
 
-static const char* verify_option_to_tams(VerifyOption vo) {
-  switch (vo) {
-    case VerifyOption_G1UsePrevMarking:
-      return "PTAMS";
-    case VerifyOption_G1UseNextMarking:
-      return "NTAMS";
-    default:
-      return "NONE";
-  }
-}
-
 void ConcurrentMark::print_reachable(const char* str,
                                      VerifyOption vo,
                                      bool all) {
@@ -3051,7 +2590,7 @@
   }
 
   outputStream* out = &fout;
-  out->print_cr("-- USING %s", verify_option_to_tams(vo));
+  out->print_cr("-- USING %s", _g1h->top_at_mark_start_str(vo));
   out->cr();
 
   out->print_cr("--- ITERATING OVER REGIONS");
@@ -3066,89 +2605,6 @@
 
 #endif // PRODUCT
 
-// This note is for drainAllSATBBuffers and the code in between.
-// In the future we could reuse a task to do this work during an
-// evacuation pause (since now tasks are not active and can be claimed
-// during an evacuation pause). This was a late change to the code and
-// is currently not being taken advantage of.
-
-void ConcurrentMark::deal_with_reference(oop obj) {
-  if (verbose_high()) {
-    gclog_or_tty->print_cr("[global] we're dealing with reference "PTR_FORMAT,
-                           (void*) obj);
-  }
-
-  HeapWord* objAddr = (HeapWord*) obj;
-  assert(obj->is_oop_or_null(true /* ignore mark word */), "Error");
-  if (_g1h->is_in_g1_reserved(objAddr)) {
-    assert(obj != NULL, "null check is implicit");
-    if (!_nextMarkBitMap->isMarked(objAddr)) {
-      // Only get the containing region if the object is not marked on the
-      // bitmap (otherwise, it's a waste of time since we won't do
-      // anything with it).
-      HeapRegion* hr = _g1h->heap_region_containing_raw(obj);
-      if (!hr->obj_allocated_since_next_marking(obj)) {
-        if (verbose_high()) {
-          gclog_or_tty->print_cr("[global] "PTR_FORMAT" is not considered "
-                                 "marked", (void*) obj);
-        }
-
-        // we need to mark it first
-        if (_nextMarkBitMap->parMark(objAddr)) {
-          // No OrderAccess:store_load() is needed. It is implicit in the
-          // CAS done in parMark(objAddr) above
-          HeapWord* finger = _finger;
-          if (objAddr < finger) {
-            if (verbose_high()) {
-              gclog_or_tty->print_cr("[global] below the global finger "
-                                     "("PTR_FORMAT"), pushing it", finger);
-            }
-            if (!mark_stack_push(obj)) {
-              if (verbose_low()) {
-                gclog_or_tty->print_cr("[global] global stack overflow during "
-                                       "deal_with_reference");
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-}
-
-class CMGlobalObjectClosure : public ObjectClosure {
-private:
-  ConcurrentMark* _cm;
-
-public:
-  void do_object(oop obj) {
-    _cm->deal_with_reference(obj);
-  }
-
-  CMGlobalObjectClosure(ConcurrentMark* cm) : _cm(cm) { }
-};
-
-void ConcurrentMark::drainAllSATBBuffers() {
-  guarantee(false, "drainAllSATBBuffers(): don't call this any more");
-
-  CMGlobalObjectClosure oc(this);
-  SATBMarkQueueSet& satb_mq_set = JavaThread::satb_mark_queue_set();
-  satb_mq_set.set_closure(&oc);
-
-  while (satb_mq_set.apply_closure_to_completed_buffer()) {
-    if (verbose_medium()) {
-      gclog_or_tty->print_cr("[global] processed an SATB buffer");
-    }
-  }
-
-  // no need to check whether we should do this, as this is only
-  // called during an evacuation pause
-  satb_mq_set.iterate_closure_all_threads();
-
-  satb_mq_set.set_closure(NULL);
-  assert(satb_mq_set.completed_buffers_num() == 0, "invariant");
-}
-
 void ConcurrentMark::clearRangePrevBitmap(MemRegion mr) {
   // Note we are overriding the read-only view of the prev map here, via
   // the cast.
@@ -3257,63 +2713,6 @@
   return NULL;
 }
 
-bool ConcurrentMark::invalidate_aborted_regions_in_cset() {
-  guarantee(false, "invalidate_aborted_regions_in_cset(): "
-                   "don't call this any more");
-
-  bool result = false;
-  for (int i = 0; i < (int)_max_task_num; ++i) {
-    CMTask* the_task = _tasks[i];
-    MemRegion mr = the_task->aborted_region();
-    if (mr.start() != NULL) {
-      assert(mr.end() != NULL, "invariant");
-      assert(mr.word_size() > 0, "invariant");
-      HeapRegion* hr = _g1h->heap_region_containing(mr.start());
-      assert(hr != NULL, "invariant");
-      if (hr->in_collection_set()) {
-        // The region points into the collection set
-        the_task->set_aborted_region(MemRegion());
-        result = true;
-      }
-    }
-  }
-  return result;
-}
-
-bool ConcurrentMark::has_aborted_regions() {
-  for (int i = 0; i < (int)_max_task_num; ++i) {
-    CMTask* the_task = _tasks[i];
-    MemRegion mr = the_task->aborted_region();
-    if (mr.start() != NULL) {
-      assert(mr.end() != NULL, "invariant");
-      assert(mr.word_size() > 0, "invariant");
-      return true;
-    }
-  }
-  return false;
-}
-
-void ConcurrentMark::oops_do(OopClosure* cl) {
-  if (_markStack.size() > 0 && verbose_low()) {
-    gclog_or_tty->print_cr("[global] scanning the global marking stack, "
-                           "size = %d", _markStack.size());
-  }
-  // we first iterate over the contents of the mark stack...
-  _markStack.oops_do(cl);
-
-  for (int i = 0; i < (int)_max_task_num; ++i) {
-    OopTaskQueue* queue = _task_queues->queue((int)i);
-
-    if (queue->size() > 0 && verbose_low()) {
-      gclog_or_tty->print_cr("[global] scanning task queue of task %d, "
-                             "size = %d", i, queue->size());
-    }
-
-    // ...then over the contents of the all the task queues.
-    queue->oops_do(cl);
-  }
-}
-
 #ifndef PRODUCT
 enum VerifyNoCSetOopsPhase {
   VerifyNoCSetOopsStack,
@@ -3445,8 +2844,6 @@
 void ConcurrentMark::clear_marking_state(bool clear_overflow) {
   _markStack.setEmpty();
   _markStack.clear_overflow();
-  _regionStack.setEmpty();
-  _regionStack.clear_overflow();
   if (clear_overflow) {
     clear_has_overflown();
   } else {
@@ -3457,28 +2854,25 @@
   for (int i = 0; i < (int)_max_task_num; ++i) {
     OopTaskQueue* queue = _task_queues->queue(i);
     queue->set_empty();
-    // Clear any partial regions from the CMTasks
-    _tasks[i]->clear_aborted_region();
   }
 }
 
 // Aggregate the counting data that was constructed concurrently
 // with marking.
 class AggregateCountDataHRClosure: public HeapRegionClosure {
+  G1CollectedHeap* _g1h;
   ConcurrentMark* _cm;
+  CardTableModRefBS* _ct_bs;
   BitMap* _cm_card_bm;
   size_t _max_task_num;
 
  public:
-  AggregateCountDataHRClosure(ConcurrentMark *cm,
+  AggregateCountDataHRClosure(G1CollectedHeap* g1h,
                               BitMap* cm_card_bm,
                               size_t max_task_num) :
-    _cm(cm), _cm_card_bm(cm_card_bm),
-    _max_task_num(max_task_num) { }
-
-  bool is_card_aligned(HeapWord* p) {
-    return ((uintptr_t(p) & (CardTableModRefBS::card_size - 1)) == 0);
-  }
+    _g1h(g1h), _cm(g1h->concurrent_mark()),
+    _ct_bs((CardTableModRefBS*) (g1h->barrier_set())),
+    _cm_card_bm(cm_card_bm), _max_task_num(max_task_num) { }
 
   bool doHeapRegion(HeapRegion* hr) {
     if (hr->continuesHumongous()) {
@@ -3509,23 +2903,30 @@
       return false;
     }
 
-    assert(is_card_aligned(start), "sanity");
-    assert(is_card_aligned(end), "sanity");
+    // 'start' should be in the heap.
+    assert(_g1h->is_in_g1_reserved(start) && _ct_bs->is_card_aligned(start), "sanity");
+    // 'end' *may* be just beyone the end of the heap (if hr is the last region)
+    assert(!_g1h->is_in_g1_reserved(end) || _ct_bs->is_card_aligned(end), "sanity");
 
     BitMap::idx_t start_idx = _cm->card_bitmap_index_for(start);
     BitMap::idx_t limit_idx = _cm->card_bitmap_index_for(limit);
     BitMap::idx_t end_idx = _cm->card_bitmap_index_for(end);
 
-    // If ntams is not card aligned then we bump the index for
-    // limit so that we get the card spanning ntams.
-    if (!is_card_aligned(limit)) {
+    // If ntams is not card aligned then we bump card bitmap index
+    // for limit so that we get the all the cards spanned by
+    // the object ending at ntams.
+    // Note: if this is the last region in the heap then ntams
+    // could be actually just beyond the end of the the heap;
+    // limit_idx will then  correspond to a (non-existent) card
+    // that is also outside the heap.
+    if (_g1h->is_in_g1_reserved(limit) && !_ct_bs->is_card_aligned(limit)) {
       limit_idx += 1;
     }
 
     assert(limit_idx <= end_idx, "or else use atomics");
 
     // Aggregate the "stripe" in the count data associated with hr.
-    size_t hrs_index = hr->hrs_index();
+    uint hrs_index = hr->hrs_index();
     size_t marked_bytes = 0;
 
     for (int i = 0; (size_t)i < _max_task_num; i += 1) {
@@ -3547,7 +2948,7 @@
 
         // BitMap::get_next_one_offset() can handle the case when
         // its left_offset parameter is greater than its right_offset
-        // parameter. If does, however, have an early exit if
+        // parameter. It does, however, have an early exit if
         // left_offset == right_offset. So let's limit the value
         // passed in for left offset here.
         BitMap::idx_t next_idx = MIN2(scan_idx + 1, limit_idx);
@@ -3558,9 +2959,6 @@
     // Update the marked bytes for this region.
     hr->add_to_marked_bytes(marked_bytes);
 
-    // Now set the top at count to NTAMS.
-    hr->set_top_at_conc_mark_count(limit);
-
     // Next heap region
     return false;
   }
@@ -3586,7 +2984,7 @@
     _active_workers(n_workers) { }
 
   void work(uint worker_id) {
-    AggregateCountDataHRClosure cl(_cm, _cm_card_bm, _max_task_num);
+    AggregateCountDataHRClosure cl(_g1h, _cm_card_bm, _max_task_num);
 
     if (G1CollectedHeap::use_parallel_gc_threads()) {
       _g1h->heap_region_par_iterate_chunked(&cl, worker_id,
@@ -3633,7 +3031,7 @@
   // of the final counting task.
   _region_bm.clear();
 
-  size_t max_regions = _g1h->max_regions();
+  uint max_regions = _g1h->max_regions();
   assert(_max_task_num != 0, "unitialized");
 
   for (int i = 0; (size_t) i < _max_task_num; i += 1) {
@@ -3643,7 +3041,7 @@
     assert(task_card_bm->size() == _card_bm.size(), "size mismatch");
     assert(marked_bytes_array != NULL, "uninitialized");
 
-    memset(marked_bytes_array, 0, (max_regions * sizeof(size_t)));
+    memset(marked_bytes_array, 0, (size_t) max_regions * sizeof(size_t));
     task_card_bm->clear();
   }
 }
@@ -3658,327 +3056,6 @@
   }
 }
 
-// Closures used by ConcurrentMark::complete_marking_in_collection_set().
-
-class CSetMarkOopClosure: public OopClosure {
-  friend class CSetMarkBitMapClosure;
-
-  G1CollectedHeap* _g1h;
-  CMBitMap*        _bm;
-  ConcurrentMark*  _cm;
-  oop*             _ms;
-  jint*            _array_ind_stack;
-  int              _ms_size;
-  int              _ms_ind;
-  int              _array_increment;
-  uint             _worker_id;
-
-  bool push(oop obj, int arr_ind = 0) {
-    if (_ms_ind == _ms_size) {
-      gclog_or_tty->print_cr("Mark stack is full.");
-      return false;
-    }
-    _ms[_ms_ind] = obj;
-    if (obj->is_objArray()) {
-      _array_ind_stack[_ms_ind] = arr_ind;
-    }
-    _ms_ind++;
-    return true;
-  }
-
-  oop pop() {
-    if (_ms_ind == 0) {
-      return NULL;
-    } else {
-      _ms_ind--;
-      return _ms[_ms_ind];
-    }
-  }
-
-  template <class T> bool drain() {
-    while (_ms_ind > 0) {
-      oop obj = pop();
-      assert(obj != NULL, "Since index was non-zero.");
-      if (obj->is_objArray()) {
-        jint arr_ind = _array_ind_stack[_ms_ind];
-        objArrayOop aobj = objArrayOop(obj);
-        jint len = aobj->length();
-        jint next_arr_ind = arr_ind + _array_increment;
-        if (next_arr_ind < len) {
-          push(obj, next_arr_ind);
-        }
-        // Now process this portion of this one.
-        int lim = MIN2(next_arr_ind, len);
-        for (int j = arr_ind; j < lim; j++) {
-          do_oop(aobj->objArrayOopDesc::obj_at_addr<T>(j));
-        }
-      } else {
-        obj->oop_iterate(this);
-      }
-      if (abort()) return false;
-    }
-    return true;
-  }
-
-public:
-  CSetMarkOopClosure(ConcurrentMark* cm, int ms_size, uint worker_id) :
-    _g1h(G1CollectedHeap::heap()),
-    _cm(cm),
-    _bm(cm->nextMarkBitMap()),
-    _ms_size(ms_size), _ms_ind(0),
-    _ms(NEW_C_HEAP_ARRAY(oop, ms_size)),
-    _array_ind_stack(NEW_C_HEAP_ARRAY(jint, ms_size)),
-    _array_increment(MAX2(ms_size/8, 16)),
-    _worker_id(worker_id) { }
-
-  ~CSetMarkOopClosure() {
-    FREE_C_HEAP_ARRAY(oop, _ms);
-    FREE_C_HEAP_ARRAY(jint, _array_ind_stack);
-  }
-
-  virtual void do_oop(narrowOop* p) { do_oop_work(p); }
-  virtual void do_oop(      oop* p) { do_oop_work(p); }
-
-  template <class T> void do_oop_work(T* p) {
-    T heap_oop = oopDesc::load_heap_oop(p);
-    if (oopDesc::is_null(heap_oop)) return;
-    oop obj = oopDesc::decode_heap_oop_not_null(heap_oop);
-    if (obj->is_forwarded()) {
-      // If the object has already been forwarded, we have to make sure
-      // that it's marked.  So follow the forwarding pointer.  Note that
-      // this does the right thing for self-forwarding pointers in the
-      // evacuation failure case.
-      obj = obj->forwardee();
-    }
-    HeapRegion* hr = _g1h->heap_region_containing(obj);
-    if (hr != NULL) {
-      if (hr->in_collection_set()) {
-        if (_g1h->is_obj_ill(obj)) {
-          if (_bm->parMark((HeapWord*)obj)) {
-            if (!push(obj)) {
-              gclog_or_tty->print_cr("Setting abort in CSetMarkOopClosure because push failed.");
-              set_abort();
-            }
-          }
-        }
-      } else {
-        // Outside the collection set; we need to gray it
-        _cm->deal_with_reference(obj);
-      }
-    }
-  }
-};
-
-class CSetMarkBitMapClosure: public BitMapClosure {
-  G1CollectedHeap*   _g1h;
-  CMBitMap*          _bitMap;
-  ConcurrentMark*    _cm;
-  CSetMarkOopClosure _oop_cl;
-  uint               _worker_id;
-
-public:
-  CSetMarkBitMapClosure(ConcurrentMark* cm, int ms_size, int worker_id) :
-    _g1h(G1CollectedHeap::heap()),
-    _bitMap(cm->nextMarkBitMap()),
-    _oop_cl(cm, ms_size, worker_id),
-    _worker_id(worker_id) { }
-
-  bool do_bit(size_t offset) {
-    // convert offset into a HeapWord*
-    HeapWord* addr = _bitMap->offsetToHeapWord(offset);
-    assert(_bitMap->endWord() && addr < _bitMap->endWord(),
-           "address out of range");
-    assert(_bitMap->isMarked(addr), "tautology");
-    oop obj = oop(addr);
-    if (!obj->is_forwarded()) {
-      if (!_oop_cl.push(obj)) return false;
-      if (UseCompressedOops) {
-        if (!_oop_cl.drain<narrowOop>()) return false;
-      } else {
-        if (!_oop_cl.drain<oop>()) return false;
-      }
-    }
-    // Otherwise...
-    return true;
-  }
-};
-
-class CompleteMarkingInCSetHRClosure: public HeapRegionClosure {
-  CMBitMap*             _bm;
-  CSetMarkBitMapClosure _bit_cl;
-  uint                  _worker_id;
-
-  enum SomePrivateConstants {
-    MSSize = 1000
-  };
-
-public:
-  CompleteMarkingInCSetHRClosure(ConcurrentMark* cm, int worker_id) :
-    _bm(cm->nextMarkBitMap()),
-    _bit_cl(cm, MSSize, worker_id),
-    _worker_id(worker_id) { }
-
-  bool doHeapRegion(HeapRegion* hr) {
-    if (hr->claimHeapRegion(HeapRegion::CompleteMarkCSetClaimValue)) {
-      // The current worker has successfully claimed the region.
-      if (!hr->evacuation_failed()) {
-        MemRegion mr = MemRegion(hr->bottom(), hr->next_top_at_mark_start());
-        if (!mr.is_empty()) {
-          bool done = false;
-          while (!done) {
-            done = _bm->iterate(&_bit_cl, mr);
-          }
-        }
-      }
-    }
-    return false;
-  }
-};
-
-class G1ParCompleteMarkInCSetTask: public AbstractGangTask {
-protected:
-  G1CollectedHeap* _g1h;
-  ConcurrentMark*  _cm;
-
-public:
-  G1ParCompleteMarkInCSetTask(G1CollectedHeap* g1h,
-                              ConcurrentMark* cm) :
-    AbstractGangTask("Complete Mark in CSet"),
-    _g1h(g1h), _cm(cm) { }
-
-  void work(uint worker_id) {
-    CompleteMarkingInCSetHRClosure cmplt(_cm, worker_id);
-    HeapRegion* hr = _g1h->start_cset_region_for_worker(worker_id);
-    _g1h->collection_set_iterate_from(hr, &cmplt);
-  }
-};
-
-void ConcurrentMark::complete_marking_in_collection_set() {
-  guarantee(false, "complete_marking_in_collection_set(): "
-                   "don't call this any more");
-
-  G1CollectedHeap* g1h =  G1CollectedHeap::heap();
-
-  if (!g1h->mark_in_progress()) {
-    g1h->g1_policy()->record_mark_closure_time(0.0);
-    return;
-  }
-
-  double start = os::elapsedTime();
-  G1ParCompleteMarkInCSetTask complete_mark_task(g1h, this);
-
-  assert(g1h->check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
-
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    int n_workers = g1h->workers()->active_workers();
-    g1h->set_par_threads(n_workers);
-    g1h->workers()->run_task(&complete_mark_task);
-    g1h->set_par_threads(0);
-  } else {
-    complete_mark_task.work(0);
-  }
-
-  assert(g1h->check_cset_heap_region_claim_values(HeapRegion::CompleteMarkCSetClaimValue), "sanity");
-
-  // Reset the claim values in the regions in the collection set.
-  g1h->reset_cset_heap_region_claim_values();
-
-  assert(g1h->check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
-
-  double end_time = os::elapsedTime();
-  double elapsed_time_ms = (end_time - start) * 1000.0;
-  g1h->g1_policy()->record_mark_closure_time(elapsed_time_ms);
-}
-
-// The next two methods deal with the following optimisation. Some
-// objects are gray by being marked and located above the finger. If
-// they are copied, during an evacuation pause, below the finger then
-// the need to be pushed on the stack. The observation is that, if
-// there are no regions in the collection set located above the
-// finger, then the above cannot happen, hence we do not need to
-// explicitly gray any objects when copying them to below the
-// finger. The global stack will be scanned to ensure that, if it
-// points to objects being copied, it will update their
-// location. There is a tricky situation with the gray objects in
-// region stack that are being coped, however. See the comment in
-// newCSet().
-
-void ConcurrentMark::newCSet() {
-  guarantee(false, "newCSet(): don't call this any more");
-
-  if (!concurrent_marking_in_progress()) {
-    // nothing to do if marking is not in progress
-    return;
-  }
-
-  // find what the lowest finger is among the global and local fingers
-  _min_finger = _finger;
-  for (int i = 0; i < (int)_max_task_num; ++i) {
-    CMTask* task = _tasks[i];
-    HeapWord* task_finger = task->finger();
-    if (task_finger != NULL && task_finger < _min_finger) {
-      _min_finger = task_finger;
-    }
-  }
-
-  _should_gray_objects = false;
-
-  // This fixes a very subtle and fustrating bug. It might be the case
-  // that, during en evacuation pause, heap regions that contain
-  // objects that are gray (by being in regions contained in the
-  // region stack) are included in the collection set. Since such gray
-  // objects will be moved, and because it's not easy to redirect
-  // region stack entries to point to a new location (because objects
-  // in one region might be scattered to multiple regions after they
-  // are copied), one option is to ensure that all marked objects
-  // copied during a pause are pushed on the stack. Notice, however,
-  // that this problem can only happen when the region stack is not
-  // empty during an evacuation pause. So, we make the fix a bit less
-  // conservative and ensure that regions are pushed on the stack,
-  // irrespective whether all collection set regions are below the
-  // finger, if the region stack is not empty. This is expected to be
-  // a rare case, so I don't think it's necessary to be smarted about it.
-  if (!region_stack_empty() || has_aborted_regions()) {
-    _should_gray_objects = true;
-  }
-}
-
-void ConcurrentMark::registerCSetRegion(HeapRegion* hr) {
-  guarantee(false, "registerCSetRegion(): don't call this any more");
-
-  if (!concurrent_marking_in_progress()) return;
-
-  HeapWord* region_end = hr->end();
-  if (region_end > _min_finger) {
-    _should_gray_objects = true;
-  }
-}
-
-// Resets the region fields of active CMTasks whose values point
-// into the collection set.
-void ConcurrentMark::reset_active_task_region_fields_in_cset() {
-  guarantee(false, "reset_active_task_region_fields_in_cset(): "
-                   "don't call this any more");
-
-  assert(SafepointSynchronize::is_at_safepoint(), "should be in STW");
-  assert(parallel_marking_threads() <= _max_task_num, "sanity");
-
-  for (int i = 0; i < (int)parallel_marking_threads(); i += 1) {
-    CMTask* task = _tasks[i];
-    HeapWord* task_finger = task->finger();
-    if (task_finger != NULL) {
-      assert(_g1h->is_in_g1_reserved(task_finger), "not in heap");
-      HeapRegion* finger_region = _g1h->heap_region_containing(task_finger);
-      if (finger_region->in_collection_set()) {
-        // The task's current region is in the collection set.
-        // This region will be evacuated in the current GC and
-        // the region fields in the task will be stale.
-        task->giveup_current_region();
-      }
-    }
-  }
-}
-
 // abandon current marking iteration due to a Full GC
 void ConcurrentMark::abort() {
   // Clear all marks to force marking thread to do nothing
@@ -4053,9 +3130,6 @@
       _g1h->g1_policy()->record_concurrent_pause();
     }
     cmThread()->yield();
-    if (worker_id == 0) {
-      _g1h->g1_policy()->record_concurrent_pause_end();
-    }
     return true;
   } else {
     return false;
@@ -4112,36 +3186,21 @@
   CMBitMap*                   _nextMarkBitMap;
   ConcurrentMark*             _cm;
   CMTask*                     _task;
-  // true if we're scanning a heap region claimed by the task (so that
-  // we move the finger along), false if we're not, i.e. currently when
-  // scanning a heap region popped from the region stack (so that we
-  // do not move the task finger along; it'd be a mistake if we did so).
-  bool                        _scanning_heap_region;
 
 public:
-  CMBitMapClosure(CMTask *task,
-                  ConcurrentMark* cm,
-                  CMBitMap* nextMarkBitMap)
-    :  _task(task), _cm(cm), _nextMarkBitMap(nextMarkBitMap) { }
-
-  void set_scanning_heap_region(bool scanning_heap_region) {
-    _scanning_heap_region = scanning_heap_region;
-  }
+  CMBitMapClosure(CMTask *task, ConcurrentMark* cm, CMBitMap* nextMarkBitMap) :
+    _task(task), _cm(cm), _nextMarkBitMap(nextMarkBitMap) { }
 
   bool do_bit(size_t offset) {
     HeapWord* addr = _nextMarkBitMap->offsetToHeapWord(offset);
     assert(_nextMarkBitMap->isMarked(addr), "invariant");
     assert( addr < _cm->finger(), "invariant");
 
-    if (_scanning_heap_region) {
-      statsOnly( _task->increase_objs_found_on_bitmap() );
-      assert(addr >= _task->finger(), "invariant");
-      // We move that task's local finger along.
-      _task->move_finger_to(addr);
-    } else {
-      // We move the task's region finger along.
-      _task->move_region_finger_to(addr);
-    }
+    statsOnly( _task->increase_objs_found_on_bitmap() );
+    assert(addr >= _task->finger(), "invariant");
+
+    // We move that task's local finger along.
+    _task->move_finger_to(addr);
 
     _task->scan_object(oop(addr));
     // we only partially drain the local queue and global stack
@@ -4249,8 +3308,6 @@
   _curr_region   = NULL;
   _finger        = NULL;
   _region_limit  = NULL;
-
-  _region_finger = NULL;
 }
 
 void CMTask::set_cm_oop_closure(G1CMOopClosure* cm_oop_closure) {
@@ -4271,7 +3328,6 @@
 
   _nextMarkBitMap                = nextMarkBitMap;
   clear_region_fields();
-  assert(_aborted_region.is_empty(), "should have been cleared");
 
   _calls                         = 0;
   _elapsed_time_ms               = 0.0;
@@ -4288,7 +3344,6 @@
   _global_max_size               = 0;
   _global_transfers_to           = 0;
   _global_transfers_from         = 0;
-  _region_stack_pops             = 0;
   _regions_claimed               = 0;
   _objs_found_on_bitmap          = 0;
   _satb_buffers_processed        = 0;
@@ -4663,110 +3718,6 @@
   decrease_limits();
 }
 
-void CMTask::drain_region_stack(BitMapClosure* bc) {
-  assert(_cm->region_stack_empty(), "region stack should be empty");
-  assert(_aborted_region.is_empty(), "aborted region should be empty");
-  return;
-
-  if (has_aborted()) return;
-
-  assert(_region_finger == NULL,
-         "it should be NULL when we're not scanning a region");
-
-  if (!_cm->region_stack_empty() || !_aborted_region.is_empty()) {
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%d] draining region stack, size = %d",
-                             _task_id, _cm->region_stack_size());
-    }
-
-    MemRegion mr;
-
-    if (!_aborted_region.is_empty()) {
-      mr = _aborted_region;
-      _aborted_region = MemRegion();
-
-      if (_cm->verbose_low()) {
-        gclog_or_tty->print_cr("[%d] scanning aborted region "
-                               "[ " PTR_FORMAT ", " PTR_FORMAT " )",
-                               _task_id, mr.start(), mr.end());
-      }
-    } else {
-      mr = _cm->region_stack_pop_lock_free();
-      // it returns MemRegion() if the pop fails
-      statsOnly(if (mr.start() != NULL) ++_region_stack_pops );
-    }
-
-    while (mr.start() != NULL) {
-      if (_cm->verbose_medium()) {
-        gclog_or_tty->print_cr("[%d] we are scanning region "
-                               "["PTR_FORMAT", "PTR_FORMAT")",
-                               _task_id, mr.start(), mr.end());
-      }
-
-      assert(mr.end() <= _cm->finger(),
-             "otherwise the region shouldn't be on the stack");
-      assert(!mr.is_empty(), "Only non-empty regions live on the region stack");
-      if (_nextMarkBitMap->iterate(bc, mr)) {
-        assert(!has_aborted(),
-               "cannot abort the task without aborting the bitmap iteration");
-
-        // We finished iterating over the region without aborting.
-        regular_clock_call();
-        if (has_aborted()) {
-          mr = MemRegion();
-        } else {
-          mr = _cm->region_stack_pop_lock_free();
-          // it returns MemRegion() if the pop fails
-          statsOnly(if (mr.start() != NULL) ++_region_stack_pops );
-        }
-      } else {
-        assert(has_aborted(), "currently the only way to do so");
-
-        // The only way to abort the bitmap iteration is to return
-        // false from the do_bit() method. However, inside the
-        // do_bit() method we move the _region_finger to point to the
-        // object currently being looked at. So, if we bail out, we
-        // have definitely set _region_finger to something non-null.
-        assert(_region_finger != NULL, "invariant");
-
-        // Make sure that any previously aborted region has been
-        // cleared.
-        assert(_aborted_region.is_empty(), "aborted region not cleared");
-
-        // The iteration was actually aborted. So now _region_finger
-        // points to the address of the object we last scanned. If we
-        // leave it there, when we restart this task, we will rescan
-        // the object. It is easy to avoid this. We move the finger by
-        // enough to point to the next possible object header (the
-        // bitmap knows by how much we need to move it as it knows its
-        // granularity).
-        MemRegion newRegion =
-          MemRegion(_nextMarkBitMap->nextWord(_region_finger), mr.end());
-
-        if (!newRegion.is_empty()) {
-          if (_cm->verbose_low()) {
-            gclog_or_tty->print_cr("[%d] recording unscanned region"
-                                   "[" PTR_FORMAT "," PTR_FORMAT ") in CMTask",
-                                   _task_id,
-                                   newRegion.start(), newRegion.end());
-          }
-          // Now record the part of the region we didn't scan to
-          // make sure this task scans it later.
-          _aborted_region = newRegion;
-        }
-        // break from while
-        mr = MemRegion();
-      }
-      _region_finger = NULL;
-    }
-
-    if (_cm->verbose_low()) {
-      gclog_or_tty->print_cr("[%d] drained region stack, size = %d",
-                             _task_id, _cm->region_stack_size());
-    }
-  }
-}
-
 void CMTask::print_stats() {
   gclog_or_tty->print_cr("Marking Stats, task = %d, calls = %d",
                          _task_id, _calls);
@@ -4795,8 +3746,7 @@
                          _global_pushes, _global_pops, _global_max_size);
   gclog_or_tty->print_cr("                transfers to = %d, transfers from = %d",
                          _global_transfers_to,_global_transfers_from);
-  gclog_or_tty->print_cr("  Regions: claimed = %d, Region Stack: pops = %d",
-                         _regions_claimed, _region_stack_pops);
+  gclog_or_tty->print_cr("  Regions: claimed = %d", _regions_claimed);
   gclog_or_tty->print_cr("  SATB buffers: processed = %d", _satb_buffers_processed);
   gclog_or_tty->print_cr("  Steals: attempts = %d, successes = %d",
                          _steal_attempts, _steals);
@@ -4855,15 +3805,7 @@
       popping by other tasks. Only when there is no more work, tasks
       will totally drain the global mark stack.
 
-      (4) Global Region Stack. Entries on it correspond to areas of
-      the bitmap that need to be scanned since they contain gray
-      objects. Pushes on the region stack only happen during
-      evacuation pauses and typically correspond to areas covered by
-      GC LABS. If it overflows, then the marking phase should restart
-      and iterate over the bitmap to identify gray objects. Tasks will
-      try to totally drain the region stack as soon as possible.
-
-      (5) SATB Buffer Queue. This is where completed SATB buffers are
+      (4) SATB Buffer Queue. This is where completed SATB buffers are
       made available. Buffers are regularly removed from this queue
       and scanned for roots, so that the queue doesn't get too
       long. During remark, all completed buffers are processed, as
@@ -4875,12 +3817,12 @@
 
       (1) When the marking phase has been aborted (after a Full GC).
 
-      (2) When a global overflow (either on the global stack or the
-      region stack) has been triggered. Before the task aborts, it
-      will actually sync up with the other tasks to ensure that all
-      the marking data structures (local queues, stacks, fingers etc.)
-      are re-initialised so that when do_marking_step() completes,
-      the marking phase can immediately restart.
+      (2) When a global overflow (on the global stack) has been
+      triggered. Before the task aborts, it will actually sync up with
+      the other tasks to ensure that all the marking data structures
+      (local queues, stacks, fingers etc.)  are re-initialised so that
+      when do_marking_step() completes, the marking phase can
+      immediately restart.
 
       (3) When enough completed SATB buffers are available. The
       do_marking_step() method only tries to drain SATB buffers right
@@ -4923,13 +3865,6 @@
   assert(time_target_ms >= 1.0, "minimum granularity is 1ms");
   assert(concurrent() == _cm->concurrent(), "they should be the same");
 
-  assert(concurrent() || _cm->region_stack_empty(),
-         "the region stack should have been cleared before remark");
-  assert(concurrent() || !_cm->has_aborted_regions(),
-         "aborted regions should have been cleared before remark");
-  assert(_region_finger == NULL,
-         "this should be non-null only when a region is being scanned");
-
   G1CollectorPolicy* g1_policy = _g1h->g1_policy();
   assert(_task_queues != NULL, "invariant");
   assert(_task_queue != NULL, "invariant");
@@ -4978,10 +3913,10 @@
   set_cm_oop_closure(&cm_oop_closure);
 
   if (_cm->has_overflown()) {
-    // This can happen if the region stack or the mark stack overflows
-    // during a GC pause and this task, after a yield point,
-    // restarts. We have to abort as we need to get into the overflow
-    // protocol which happens right at the end of this task.
+    // This can happen if the mark stack overflows during a GC pause
+    // and this task, after a yield point, restarts. We have to abort
+    // as we need to get into the overflow protocol which happens
+    // right at the end of this task.
     set_has_aborted();
   }
 
@@ -4994,17 +3929,6 @@
   drain_local_queue(true);
   drain_global_stack(true);
 
-  // Then totally drain the region stack.  We will not look at
-  // it again before the next invocation of this method. Entries on
-  // the region stack are only added during evacuation pauses, for
-  // which we have to yield. When we do, we abort the task anyway so
-  // it will look at the region stack again when it restarts.
-  bitmap_closure.set_scanning_heap_region(false);
-  drain_region_stack(&bitmap_closure);
-  // ...then partially drain the local queue and the global stack
-  drain_local_queue(true);
-  drain_global_stack(true);
-
   do {
     if (!has_aborted() && _curr_region != NULL) {
       // This means that we're already holding on to a region.
@@ -5034,9 +3958,7 @@
 
       // Let's iterate over the bitmap of the part of the
       // region that is left.
-      bitmap_closure.set_scanning_heap_region(true);
-      if (mr.is_empty() ||
-          _nextMarkBitMap->iterate(&bitmap_closure, mr)) {
+      if (mr.is_empty() || _nextMarkBitMap->iterate(&bitmap_closure, mr)) {
         // We successfully completed iterating over the region. Now,
         // let's give up the region.
         giveup_current_region();
@@ -5061,9 +3983,9 @@
         HeapWord* new_finger = _nextMarkBitMap->nextWord(_finger);
         // Check if bitmap iteration was aborted while scanning the last object
         if (new_finger >= _region_limit) {
-            giveup_current_region();
+          giveup_current_region();
         } else {
-            move_finger_to(new_finger);
+          move_finger_to(new_finger);
         }
       }
     }
@@ -5119,9 +4041,7 @@
 
   if (!has_aborted()) {
     // We cannot check whether the global stack is empty, since other
-    // tasks might be pushing objects to it concurrently. We also cannot
-    // check if the region stack is empty because if a thread is aborting
-    // it can push a partially done region back.
+    // tasks might be pushing objects to it concurrently.
     assert(_cm->out_of_regions(),
            "at this point we should be out of regions");
 
@@ -5145,9 +4065,7 @@
     // we could. Let's try to do some stealing...
 
     // We cannot check whether the global stack is empty, since other
-    // tasks might be pushing objects to it concurrently. We also cannot
-    // check if the region stack is empty because if a thread is aborting
-    // it can push a partially done region back.
+    // tasks might be pushing objects to it concurrently.
     assert(_cm->out_of_regions() && _task_queue->size() == 0,
            "only way to reach here");
 
@@ -5194,9 +4112,7 @@
   // termination protocol.
   if (do_termination && !has_aborted()) {
     // We cannot check whether the global stack is empty, since other
-    // tasks might be concurrently pushing objects on it. We also cannot
-    // check if the region stack is empty because if a thread is aborting
-    // it can push a partially done region back.
+    // tasks might be concurrently pushing objects on it.
     // Separated the asserts so that we know which one fires.
     assert(_cm->out_of_regions(), "only way to reach here");
     assert(_task_queue->size() == 0, "only way to reach here");
@@ -5233,13 +4149,10 @@
       // that, if a condition is false, we can immediately find out
       // which one.
       guarantee(_cm->out_of_regions(), "only way to reach here");
-      guarantee(_aborted_region.is_empty(), "only way to reach here");
-      guarantee(_cm->region_stack_empty(), "only way to reach here");
       guarantee(_cm->mark_stack_empty(), "only way to reach here");
       guarantee(_task_queue->size() == 0, "only way to reach here");
       guarantee(!_cm->has_overflown(), "only way to reach here");
       guarantee(!_cm->mark_stack_overflow(), "only way to reach here");
-      guarantee(!_cm->region_stack_overflow(), "only way to reach here");
 
       if (_cm->verbose_low()) {
         gclog_or_tty->print_cr("[%d] all tasks terminated", _task_id);
@@ -5342,7 +4255,6 @@
     _task_queue(task_queue),
     _task_queues(task_queues),
     _cm_oop_closure(NULL),
-    _aborted_region(MemRegion()),
     _marked_bytes_array(marked_bytes),
     _card_bm(card_bm) {
   guarantee(task_queue != NULL, "invariant");
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
index e8795d6..abb46e1 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.hpp
@@ -30,8 +30,8 @@
 
 class G1CollectedHeap;
 class CMTask;
-typedef GenericTaskQueue<oop>            CMTaskQueue;
-typedef GenericTaskQueueSet<CMTaskQueue> CMTaskQueueSet;
+typedef GenericTaskQueue<oop, mtGC>            CMTaskQueue;
+typedef GenericTaskQueueSet<CMTaskQueue, mtGC> CMTaskQueueSet;
 
 // Closure used by CM during concurrent reference discovery
 // and reference processing (during remarking) to determine
@@ -42,9 +42,7 @@
 class G1CMIsAliveClosure: public BoolObjectClosure {
   G1CollectedHeap* _g1;
  public:
-  G1CMIsAliveClosure(G1CollectedHeap* g1) :
-    _g1(g1)
-  {}
+  G1CMIsAliveClosure(G1CollectedHeap* g1) : _g1(g1) { }
 
   void do_object(oop obj) {
     ShouldNotCallThis();
@@ -111,11 +109,6 @@
     return offsetToHeapWord(heapWordToOffset(addr) + 1);
   }
 
-  void mostly_disjoint_range_union(BitMap*   from_bitmap,
-                                   size_t    from_start_index,
-                                   HeapWord* to_start_word,
-                                   size_t    word_num);
-
   // debugging
   NOT_PRODUCT(bool covers(ReservedSpace rs) const;)
 };
@@ -258,60 +251,6 @@
   void oops_do(OopClosure* f);
 };
 
-class CMRegionStack VALUE_OBJ_CLASS_SPEC {
-  MemRegion* _base;
-  jint _capacity;
-  jint _index;
-  jint _oops_do_bound;
-  bool _overflow;
-public:
-  CMRegionStack();
-  ~CMRegionStack();
-  void allocate(size_t size);
-
-  // This is lock-free; assumes that it will only be called in parallel
-  // with other "push" operations (no pops).
-  void push_lock_free(MemRegion mr);
-
-  // Lock-free; assumes that it will only be called in parallel
-  // with other "pop" operations (no pushes).
-  MemRegion pop_lock_free();
-
-#if 0
-  // The routines that manipulate the region stack with a lock are
-  // not currently used. They should be retained, however, as a
-  // diagnostic aid.
-
-  // These two are the implementations that use a lock. They can be
-  // called concurrently with each other but they should not be called
-  // concurrently with the lock-free versions (push() / pop()).
-  void push_with_lock(MemRegion mr);
-  MemRegion pop_with_lock();
-#endif
-
-  bool isEmpty()    { return _index == 0; }
-  bool isFull()     { return _index == _capacity; }
-
-  bool overflow() { return _overflow; }
-  void clear_overflow() { _overflow = false; }
-
-  int  size() { return _index; }
-
-  // It iterates over the entries in the region stack and it
-  // invalidates (i.e. assigns MemRegion()) the ones that point to
-  // regions in the collection set.
-  bool invalidate_entries_into_cset();
-
-  // This gives an upper bound up to which the iteration in
-  // invalidate_entries_into_cset() will reach. This prevents
-  // newly-added entries to be unnecessarily scanned.
-  void set_oops_do_bound() {
-    _oops_do_bound = _index;
-  }
-
-  void setEmpty()   { _index = 0; clear_overflow(); }
-};
-
 class ForceOverflowSettings VALUE_OBJ_CLASS_SPEC {
 private:
 #ifndef PRODUCT
@@ -404,11 +343,10 @@
 
 class ConcurrentMarkThread;
 
-class ConcurrentMark : public CHeapObj {
+class ConcurrentMark: public CHeapObj<mtGC> {
   friend class ConcurrentMarkThread;
   friend class CMTask;
   friend class CMBitMapClosure;
-  friend class CSetMarkOopClosure;
   friend class CMGlobalObjectClosure;
   friend class CMRemarkTask;
   friend class CMConcurrentMarkingTask;
@@ -443,7 +381,6 @@
   CMBitMap                _markBitMap2;
   CMBitMapRO*             _prevMarkBitMap; // completed mark bitmap
   CMBitMap*               _nextMarkBitMap; // under-construction mark bitmap
-  bool                    _at_least_one_mark_complete;
 
   BitMap                  _region_bm;
   BitMap                  _card_bm;
@@ -457,7 +394,6 @@
 
   // For gray objects
   CMMarkStack             _markStack; // Grey objects behind global finger.
-  CMRegionStack           _regionStack; // Grey regions behind global finger.
   HeapWord* volatile      _finger;  // the global finger, region aligned,
                                     // always points to the end of the
                                     // last claimed region
@@ -502,18 +438,6 @@
   // verbose level
   CMVerboseLevel          _verbose_level;
 
-  // These two fields are used to implement the optimisation that
-  // avoids pushing objects on the global/region stack if there are
-  // no collection set regions above the lowest finger.
-
-  // This is the lowest finger (among the global and local fingers),
-  // which is calculated before a new collection set is chosen.
-  HeapWord* _min_finger;
-  // If this flag is true, objects/regions that are marked below the
-  // finger should be pushed on the stack(s). If this is flag is
-  // false, it is safe not to push them on the stack(s).
-  bool      _should_gray_objects;
-
   // All of these times are in ms.
   NumberSeq _init_times;
   NumberSeq _remark_times;
@@ -604,7 +528,7 @@
   CMTaskQueueSet* task_queues()  { return _task_queues; }
 
   // Access / manipulation of the overflow flag which is set to
-  // indicate that the global stack or region stack has overflown
+  // indicate that the global stack has overflown
   bool has_overflown()           { return _has_overflown; }
   void set_has_overflown()       { _has_overflown = true; }
   void clear_has_overflown()     { _has_overflown = false; }
@@ -684,68 +608,6 @@
   bool mark_stack_overflow()              { return _markStack.overflow(); }
   bool mark_stack_empty()                 { return _markStack.isEmpty(); }
 
-  // (Lock-free) Manipulation of the region stack
-  bool region_stack_push_lock_free(MemRegion mr) {
-    // Currently we only call the lock-free version during evacuation
-    // pauses.
-    assert(SafepointSynchronize::is_at_safepoint(), "world should be stopped");
-
-    _regionStack.push_lock_free(mr);
-    if (_regionStack.overflow()) {
-      set_has_overflown();
-      return false;
-    }
-    return true;
-  }
-
-  // Lock-free version of region-stack pop. Should only be
-  // called in tandem with other lock-free pops.
-  MemRegion region_stack_pop_lock_free() {
-    return _regionStack.pop_lock_free();
-  }
-
-#if 0
-  // The routines that manipulate the region stack with a lock are
-  // not currently used. They should be retained, however, as a
-  // diagnostic aid.
-
-  bool region_stack_push_with_lock(MemRegion mr) {
-    // Currently we only call the lock-based version during either
-    // concurrent marking or remark.
-    assert(!SafepointSynchronize::is_at_safepoint() || !concurrent(),
-           "if we are at a safepoint it should be the remark safepoint");
-
-    _regionStack.push_with_lock(mr);
-    if (_regionStack.overflow()) {
-      set_has_overflown();
-      return false;
-    }
-    return true;
-  }
-
-  MemRegion region_stack_pop_with_lock() {
-    // Currently we only call the lock-based version during either
-    // concurrent marking or remark.
-    assert(!SafepointSynchronize::is_at_safepoint() || !concurrent(),
-           "if we are at a safepoint it should be the remark safepoint");
-
-    return _regionStack.pop_with_lock();
-  }
-#endif
-
-  int region_stack_size()               { return _regionStack.size(); }
-  bool region_stack_overflow()          { return _regionStack.overflow(); }
-  bool region_stack_empty()             { return _regionStack.isEmpty(); }
-
-  // Iterate over any regions that were aborted while draining the
-  // region stack (any such regions are saved in the corresponding
-  // CMTask) and invalidate (i.e. assign to the empty MemRegion())
-  // any regions that point into the collection set.
-  bool invalidate_aborted_regions_in_cset();
-
-  // Returns true if there are any aborted memory regions.
-  bool has_aborted_regions();
-
   CMRootRegions* root_regions() { return &_root_regions; }
 
   bool concurrent_marking_in_progress() {
@@ -774,11 +636,7 @@
     return _task_queues->steal(task_num, hash_seed, obj);
   }
 
-  // It grays an object by first marking it. Then, if it's behind the
-  // global finger, it also pushes it on the global stack.
-  void deal_with_reference(oop obj);
-
-  ConcurrentMark(ReservedSpace rs, int max_regions);
+  ConcurrentMark(ReservedSpace rs, uint max_regions);
   ~ConcurrentMark();
 
   ConcurrentMarkThread* cmThread() { return _cmThread; }
@@ -810,22 +668,6 @@
   inline void grayRoot(oop obj, size_t word_size,
                        uint worker_id, HeapRegion* hr = NULL);
 
-  // It's used during evacuation pauses to gray a region, if
-  // necessary, and it's MT-safe. It assumes that the caller has
-  // marked any objects on that region. If _should_gray_objects is
-  // true and we're still doing concurrent marking, the region is
-  // pushed on the region stack, if it is located below the global
-  // finger, otherwise we do nothing.
-  void grayRegionIfNecessary(MemRegion mr);
-
-  // It's used during evacuation pauses to mark and, if necessary,
-  // gray a single object and it's MT-safe. It assumes the caller did
-  // not mark the object. If _should_gray_objects is true and we're
-  // still doing concurrent marking, the objects is pushed on the
-  // global stack, if it is located below the global finger, otherwise
-  // we do nothing.
-  void markAndGrayObjectIfNecessary(oop p);
-
   // It iterates over the heap and for each object it comes across it
   // will dump the contents of its reference fields, as well as
   // liveness information for the object and its referents. The dump
@@ -869,10 +711,6 @@
   // Do concurrent phase of marking, to a tentative transitive closure.
   void markFromRoots();
 
-  // Process all unprocessed SATB buffers. It is called at the
-  // beginning of an evacuation pause.
-  void drainAllSATBBuffers();
-
   void checkpointRootsFinal(bool clear_all_soft_refs);
   void checkpointRootsFinalWork();
   void cleanup();
@@ -899,10 +737,6 @@
     _markStack.note_end_of_gc();
   }
 
-  // Iterate over the oops in the mark stack and all local queues. It
-  // also calls invalidate_entries_into_cset() on the region stack.
-  void oops_do(OopClosure* f);
-
   // Verify that there are no CSet oops on the stacks (taskqueues /
   // global mark stack), enqueued SATB buffers, per-thread SATB
   // buffers, and fingers (global / per-task). The boolean parameters
@@ -919,40 +753,6 @@
   // unless the force parameter is true.
   void update_g1_committed(bool force = false);
 
-  void complete_marking_in_collection_set();
-
-  // It indicates that a new collection set is being chosen.
-  void newCSet();
-
-  // It registers a collection set heap region with CM. This is used
-  // to determine whether any heap regions are located above the finger.
-  void registerCSetRegion(HeapRegion* hr);
-
-  // Resets the region fields of any active CMTask whose region fields
-  // are in the collection set (i.e. the region currently claimed by
-  // the CMTask will be evacuated and may be used, subsequently, as
-  // an alloc region). When this happens the region fields in the CMTask
-  // are stale and, hence, should be cleared causing the worker thread
-  // to claim a new region.
-  void reset_active_task_region_fields_in_cset();
-
-  // Registers the maximum region-end associated with a set of
-  // regions with CM. Again this is used to determine whether any
-  // heap regions are located above the finger.
-  void register_collection_set_finger(HeapWord* max_finger) {
-    // max_finger is the highest heap region end of the regions currently
-    // contained in the collection set. If this value is larger than
-    // _min_finger then we need to gray objects.
-    // This routine is like registerCSetRegion but for an entire
-    // collection of regions.
-    if (max_finger > _min_finger) {
-      _should_gray_objects = true;
-    }
-  }
-
-  // Returns "true" if at least one mark has been completed.
-  bool at_least_one_mark_complete() { return _at_least_one_mark_complete; }
-
   bool isMarked(oop p) const {
     assert(p != NULL && p->is_oop(), "expected an oop");
     HeapWord* addr = (HeapWord*)p;
@@ -1006,7 +806,14 @@
     return _MARKING_VERBOSE_ && _verbose_level >= high_verbose;
   }
 
-  // Counting data structure accessors
+  // Liveness counting
+
+  // Utility routine to set an exclusive range of cards on the given
+  // card liveness bitmap
+  inline void set_card_bitmap_range(BitMap* card_bm,
+                                    BitMap::idx_t start_idx,
+                                    BitMap::idx_t end_idx,
+                                    bool is_par);
 
   // Returns the card number of the bottom of the G1 heap.
   // Used in biasing indices into accounting card bitmaps.
@@ -1164,23 +971,6 @@
   // limit of the region this task is scanning, NULL if we're not scanning one
   HeapWord*                   _region_limit;
 
-  // This is used only when we scan regions popped from the region
-  // stack. It records what the last object on such a region we
-  // scanned was. It is used to ensure that, if we abort region
-  // iteration, we do not rescan the first part of the region. This
-  // should be NULL when we're not scanning a region from the region
-  // stack.
-  HeapWord*                   _region_finger;
-
-  // If we abort while scanning a region we record the remaining
-  // unscanned portion and check this field when marking restarts.
-  // This avoids having to push on the region stack while other
-  // marking threads may still be popping regions.
-  // If we were to push the unscanned portion directly to the
-  // region stack then we would need to using locking versions
-  // of the push and pop operations.
-  MemRegion                   _aborted_region;
-
   // the number of words this task has scanned
   size_t                      _words_scanned;
   // When _words_scanned reaches this limit, the regular clock is
@@ -1268,8 +1058,6 @@
   int                         _global_transfers_to;
   int                         _global_transfers_from;
 
-  int                         _region_stack_pops;
-
   int                         _regions_claimed;
   int                         _objs_found_on_bitmap;
 
@@ -1347,15 +1135,6 @@
   bool has_timed_out()          { return _has_timed_out; }
   bool claimed()                { return _claimed; }
 
-  // Support routines for the partially scanned region that may be
-  // recorded as a result of aborting while draining the CMRegionStack
-  MemRegion aborted_region()    { return _aborted_region; }
-  void set_aborted_region(MemRegion mr)
-                                { _aborted_region = mr; }
-
-  // Clears any recorded partially scanned region
-  void clear_aborted_region()   { set_aborted_region(MemRegion()); }
-
   void set_cm_oop_closure(G1CMOopClosure* cm_oop_closure);
 
   // It grays the object by marking it and, if necessary, pushing it
@@ -1385,22 +1164,12 @@
   // buffers are available.
   void drain_satb_buffers();
 
-  // It keeps popping regions from the region stack and processing
-  // them until the region stack is empty.
-  void drain_region_stack(BitMapClosure* closure);
-
   // moves the local finger to a new location
   inline void move_finger_to(HeapWord* new_finger) {
     assert(new_finger >= _finger && new_finger < _region_limit, "invariant");
     _finger = new_finger;
   }
 
-  // moves the region finger to a new location
-  inline void move_region_finger_to(HeapWord* new_finger) {
-    assert(new_finger < _cm->finger(), "invariant");
-    _region_finger = new_finger;
-  }
-
   CMTask(int task_num, ConcurrentMark *cm,
          size_t* marked_bytes, BitMap* card_bm,
          CMTaskQueue* task_queue, CMTaskQueueSet* task_queues);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp
index 27c3411..7f69234 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMark.inline.hpp
@@ -28,6 +28,42 @@
 #include "gc_implementation/g1/concurrentMark.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 
+// Utility routine to set an exclusive range of cards on the given
+// card liveness bitmap
+inline void ConcurrentMark::set_card_bitmap_range(BitMap* card_bm,
+                                                  BitMap::idx_t start_idx,
+                                                  BitMap::idx_t end_idx,
+                                                  bool is_par) {
+
+  // Set the exclusive bit range [start_idx, end_idx).
+  assert((end_idx - start_idx) > 0, "at least one card");
+  assert(end_idx <= card_bm->size(), "sanity");
+
+  // Silently clip the end index
+  end_idx = MIN2(end_idx, card_bm->size());
+
+  // For small ranges use a simple loop; otherwise use set_range or
+  // use par_at_put_range (if parallel). The range is made up of the
+  // cards that are spanned by an object/mem region so 8 cards will
+  // allow up to object sizes up to 4K to be handled using the loop.
+  if ((end_idx - start_idx) <= 8) {
+    for (BitMap::idx_t i = start_idx; i < end_idx; i += 1) {
+      if (is_par) {
+        card_bm->par_set_bit(i);
+      } else {
+        card_bm->set_bit(i);
+      }
+    }
+  } else {
+    // Note BitMap::par_at_put_range() and BitMap::set_range() are exclusive.
+    if (is_par) {
+      card_bm->par_at_put_range(start_idx, end_idx, true);
+    } else {
+      card_bm->set_range(start_idx, end_idx);
+    }
+  }
+}
+
 // Returns the index in the liveness accounting card bitmap
 // for the given address
 inline BitMap::idx_t ConcurrentMark::card_bitmap_index_for(HeapWord* addr) {
@@ -35,7 +71,6 @@
   // by the card shift -- address 0 corresponds to card number 0.  One
   // must subtract the card num of the bottom of the heap to obtain a
   // card table index.
-
   intptr_t card_num = intptr_t(uintptr_t(addr) >> CardTableModRefBS::card_shift);
   return card_num - heap_bottom_card_num();
 }
@@ -46,10 +81,12 @@
                                          size_t* marked_bytes_array,
                                          BitMap* task_card_bm) {
   G1CollectedHeap* g1h = _g1h;
+  CardTableModRefBS* ct_bs = (CardTableModRefBS*) (g1h->barrier_set());
+
   HeapWord* start = mr.start();
-  HeapWord* last = mr.last();
+  HeapWord* end = mr.end();
   size_t region_size_bytes = mr.byte_size();
-  size_t index = hr->hrs_index();
+  uint index = hr->hrs_index();
 
   assert(!hr->continuesHumongous(), "should not be HC region");
   assert(hr == g1h->heap_region_containing(start), "sanity");
@@ -61,24 +98,21 @@
   marked_bytes_array[index] += region_size_bytes;
 
   BitMap::idx_t start_idx = card_bitmap_index_for(start);
-  BitMap::idx_t last_idx = card_bitmap_index_for(last);
+  BitMap::idx_t end_idx = card_bitmap_index_for(end);
 
-  // The card bitmap is task/worker specific => no need to use 'par' routines.
-  // Set bits in the inclusive bit range [start_idx, last_idx].
-  //
-  // For small ranges use a simple loop; otherwise use set_range
-  // The range are the cards that are spanned by the object/region
-  // so 8 cards will allow objects/regions up to 4K to be handled
-  // using the loop.
-  if ((last_idx - start_idx) <= 8) {
-    for (BitMap::idx_t i = start_idx; i <= last_idx; i += 1) {
-     task_card_bm->set_bit(i);
-    }
-  } else {
-    assert(last_idx < task_card_bm->size(), "sanity");
-    // Note: BitMap::set_range() is exclusive.
-    task_card_bm->set_range(start_idx, last_idx+1);
+  // Note: if we're looking at the last region in heap - end
+  // could be actually just beyond the end of the heap; end_idx
+  // will then correspond to a (non-existent) card that is also
+  // just beyond the heap.
+  if (g1h->is_in_g1_reserved(end) && !ct_bs->is_card_aligned(end)) {
+    // end of region is not card aligned - incremement to cover
+    // all the cards spanned by the region.
+    end_idx += 1;
   }
+  // The card bitmap is task/worker specific => no need to use
+  // the 'par' BitMap routines.
+  // Set bits in the exclusive bit range [start_idx, end_idx).
+  set_card_bitmap_range(task_card_bm, start_idx, end_idx, false /* is_par */);
 }
 
 // Counts the given memory region in the task/worker counting
diff --git a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
index 9dcb124..40d2aec 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/concurrentMarkThread.cpp
@@ -26,6 +26,7 @@
 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1MMUTracker.hpp"
 #include "gc_implementation/g1/vm_operations_g1.hpp"
 #include "memory/resourceArea.hpp"
@@ -104,7 +105,7 @@
 
       double scan_start = os::elapsedTime();
       if (!cm()->has_aborted()) {
-        if (PrintGC) {
+        if (G1Log::fine()) {
           gclog_or_tty->date_stamp(PrintGCDateStamps);
           gclog_or_tty->stamp(PrintGCTimeStamps);
           gclog_or_tty->print_cr("[GC concurrent-root-region-scan-start]");
@@ -113,7 +114,7 @@
         _cm->scanRootRegions();
 
         double scan_end = os::elapsedTime();
-        if (PrintGC) {
+        if (G1Log::fine()) {
           gclog_or_tty->date_stamp(PrintGCDateStamps);
           gclog_or_tty->stamp(PrintGCTimeStamps);
           gclog_or_tty->print_cr("[GC concurrent-root-region-scan-end, %1.7lf]",
@@ -122,7 +123,7 @@
       }
 
       double mark_start_sec = os::elapsedTime();
-      if (PrintGC) {
+      if (G1Log::fine()) {
         gclog_or_tty->date_stamp(PrintGCDateStamps);
         gclog_or_tty->stamp(PrintGCTimeStamps);
         gclog_or_tty->print_cr("[GC concurrent-mark-start]");
@@ -146,7 +147,7 @@
             os::sleep(current_thread, sleep_time_ms, false);
           }
 
-          if (PrintGC) {
+          if (G1Log::fine()) {
             gclog_or_tty->date_stamp(PrintGCDateStamps);
             gclog_or_tty->stamp(PrintGCTimeStamps);
             gclog_or_tty->print_cr("[GC concurrent-mark-end, %1.7lf sec]",
@@ -165,7 +166,7 @@
         }
 
         if (cm()->restart_for_overflow()) {
-          if (PrintGC) {
+          if (G1Log::fine()) {
             gclog_or_tty->date_stamp(PrintGCDateStamps);
             gclog_or_tty->stamp(PrintGCTimeStamps);
             gclog_or_tty->print_cr("[GC concurrent-mark-restart-for-overflow]");
@@ -211,7 +212,7 @@
         // reclaimed by cleanup.
 
         double cleanup_start_sec = os::elapsedTime();
-        if (PrintGC) {
+        if (G1Log::fine()) {
           gclog_or_tty->date_stamp(PrintGCDateStamps);
           gclog_or_tty->stamp(PrintGCTimeStamps);
           gclog_or_tty->print_cr("[GC concurrent-cleanup-start]");
@@ -232,7 +233,7 @@
         g1h->reset_free_regions_coming();
 
         double cleanup_end_sec = os::elapsedTime();
-        if (PrintGC) {
+        if (G1Log::fine()) {
           gclog_or_tty->date_stamp(PrintGCDateStamps);
           gclog_or_tty->stamp(PrintGCTimeStamps);
           gclog_or_tty->print_cr("[GC concurrent-cleanup-end, %1.7lf]",
@@ -273,7 +274,7 @@
       _sts.leave();
 
       if (cm()->has_aborted()) {
-        if (PrintGC) {
+        if (G1Log::fine()) {
           gclog_or_tty->date_stamp(PrintGCDateStamps);
           gclog_or_tty->stamp(PrintGCTimeStamps);
           gclog_or_tty->print_cr("[GC concurrent-mark-abort]");
@@ -292,7 +293,7 @@
     // Java thread is waiting for a full GC to happen (e.g., it
     // called System.gc() with +ExplicitGCInvokesConcurrent).
     _sts.join();
-    g1h->increment_full_collections_completed(true /* concurrent */);
+    g1h->increment_old_marking_cycles_completed(true /* concurrent */);
     _sts.leave();
   }
   assert(_should_terminate, "just checking");
diff --git a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
index 88d47db..7a0b713 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/dirtyCardQueue.hpp
@@ -32,7 +32,7 @@
 
 // A closure class for processing card table entries.  Note that we don't
 // require these closure objects to be stack-allocated.
-class CardTableEntryClosure: public CHeapObj {
+class CardTableEntryClosure: public CHeapObj<mtGC> {
 public:
   // Process the card whose card table entry is "card_ptr".  If returns
   // "false", terminate the iteration early.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp
index ca31817..bb02d6a 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -140,7 +140,7 @@
 }
 
 void G1AllocRegion::fill_in_ext_msg(ar_ext_msg* msg, const char* message) {
-  msg->append("[%s] %s c: "SIZE_FORMAT" b: %s r: "PTR_FORMAT" u: "SIZE_FORMAT,
+  msg->append("[%s] %s c: %u b: %s r: "PTR_FORMAT" u: "SIZE_FORMAT,
               _name, message, _count, BOOL_TO_STR(_bot_updates),
               _alloc_region, _used_bytes_before);
 }
@@ -215,7 +215,7 @@
       jio_snprintf(rest_buffer, buffer_length, "");
     }
 
-    tty->print_cr("[%s] "SIZE_FORMAT" %s : %s %s",
+    tty->print_cr("[%s] %u %s : %s %s",
                   _name, _count, hr_buffer, str, rest_buffer);
   }
 }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp
index caf7ff9..1f2c6cb 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1AllocRegion.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -64,7 +64,7 @@
   // the region that is re-used using the set() method. This count can
   // be used in any heuristics that might want to bound how many
   // distinct regions this object can used during an active interval.
-  size_t _count;
+  uint _count;
 
   // When we set up a new active region we save its used bytes in this
   // field so that, when we retire it, we can calculate how much space
@@ -136,7 +136,7 @@
     return (_alloc_region == _dummy_region) ? NULL : _alloc_region;
   }
 
-  size_t count() { return _count; }
+  uint count() { return _count; }
 
   // The following two are the building blocks for the allocation method.
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp
index d16685a..4dd4da6 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 #include "memory/space.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
+#include "services/memTracker.hpp"
 
 //////////////////////////////////////////////////////////////////////
 // G1BlockOffsetSharedArray
@@ -44,6 +45,9 @@
   if (!_vs.initialize(rs, 0)) {
     vm_exit_during_initialization("Could not reserve enough space for heap offset array");
   }
+
+  MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
+
   _offset_array = (u_char*)_vs.low_boundary();
   resize(init_word_size);
   if (TraceBlockOffsetTable) {
@@ -298,16 +302,28 @@
   for (size_t c = start_card + 1; c <= end_card; c++ /* yeah! */) {
     u_char entry = _array->offset_array(c);
     if (c - start_card > BlockOffsetArray::power_to_cards_back(1)) {
-      guarantee(entry > N_words, "Should be in logarithmic region");
+      guarantee(entry > N_words,
+                err_msg("Should be in logarithmic region - "
+                        "entry: " UINT32_FORMAT ", "
+                        "_array->offset_array(c): " UINT32_FORMAT ", "
+                        "N_words: " UINT32_FORMAT,
+                        entry, _array->offset_array(c), N_words));
     }
     size_t backskip = BlockOffsetArray::entry_to_cards_back(entry);
     size_t landing_card = c - backskip;
     guarantee(landing_card >= (start_card - 1), "Inv");
     if (landing_card >= start_card) {
-      guarantee(_array->offset_array(landing_card) <= entry, "monotonicity");
+      guarantee(_array->offset_array(landing_card) <= entry,
+                err_msg("Monotonicity - landing_card offset: " UINT32_FORMAT ", "
+                        "entry: " UINT32_FORMAT,
+                        _array->offset_array(landing_card), entry));
     } else {
       guarantee(landing_card == start_card - 1, "Tautology");
-      guarantee(_array->offset_array(landing_card) <= N_words, "Offset value");
+      // Note that N_words is the maximum offset value
+      guarantee(_array->offset_array(landing_card) <= N_words,
+                err_msg("landing card offset: " UINT32_FORMAT ", "
+                        "N_words: " UINT32_FORMAT,
+                        _array->offset_array(landing_card), N_words));
     }
   }
 }
@@ -524,17 +540,27 @@
   // The offset can be 0 if the block starts on a boundary.  That
   // is checked by an assertion above.
   size_t start_index = _array->index_for(blk_start);
-  HeapWord* boundary    = _array->address_for_index(start_index);
+  HeapWord* boundary = _array->address_for_index(start_index);
   assert((_array->offset_array(orig_index) == 0 &&
           blk_start == boundary) ||
           (_array->offset_array(orig_index) > 0 &&
          _array->offset_array(orig_index) <= N_words),
-         "offset array should have been set");
+         err_msg("offset array should have been set - "
+                  "orig_index offset: " UINT32_FORMAT ", "
+                  "blk_start: " PTR_FORMAT ", "
+                  "boundary: " PTR_FORMAT,
+                  _array->offset_array(orig_index),
+                  blk_start, boundary));
   for (size_t j = orig_index + 1; j <= end_index; j++) {
     assert(_array->offset_array(j) > 0 &&
            _array->offset_array(j) <=
              (u_char) (N_words+BlockOffsetArray::N_powers-1),
-           "offset array should have been set");
+           err_msg("offset array should have been set - "
+                   UINT32_FORMAT " not > 0 OR "
+                   UINT32_FORMAT " not <= " UINT32_FORMAT,
+                   _array->offset_array(j),
+                   _array->offset_array(j),
+                   (u_char) (N_words+BlockOffsetArray::N_powers-1)));
   }
 #endif
 }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp
index b6a42c7..655ab69 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -78,7 +78,9 @@
   virtual void resize(size_t new_word_size) = 0;
 
   virtual void set_bottom(HeapWord* new_bottom) {
-    assert(new_bottom <= _end, "new_bottom > _end");
+    assert(new_bottom <= _end,
+           err_msg("new_bottom (" PTR_FORMAT ") > _end (" PTR_FORMAT ")",
+                   new_bottom, _end));
     _bottom = new_bottom;
     resize(pointer_delta(_end, _bottom));
   }
@@ -117,7 +119,7 @@
 
 // Here is the shared array type.
 
-class G1BlockOffsetSharedArray: public CHeapObj {
+class G1BlockOffsetSharedArray: public CHeapObj<mtGC> {
   friend class G1BlockOffsetArray;
   friend class G1BlockOffsetArrayContigSpace;
   friend class VMStructs;
@@ -134,47 +136,75 @@
   VirtualSpace _vs;
   u_char* _offset_array;          // byte array keeping backwards offsets
 
+  void check_index(size_t index, const char* msg) const {
+    assert(index < _vs.committed_size(),
+           err_msg("%s - "
+                   "index: " SIZE_FORMAT ", _vs.committed_size: " SIZE_FORMAT,
+                   msg, index, _vs.committed_size()));
+  }
+
+  void check_offset(size_t offset, const char* msg) const {
+    assert(offset <= N_words,
+           err_msg("%s - "
+                   "offset: " UINT32_FORMAT", N_words: " UINT32_FORMAT,
+                   msg, offset, N_words));
+  }
+
   // Bounds checking accessors:
   // For performance these have to devolve to array accesses in product builds.
   u_char offset_array(size_t index) const {
-    assert(index < _vs.committed_size(), "index out of range");
+    check_index(index, "index out of range");
     return _offset_array[index];
   }
 
   void set_offset_array(size_t index, u_char offset) {
-    assert(index < _vs.committed_size(), "index out of range");
-    assert(offset <= N_words, "offset too large");
+    check_index(index, "index out of range");
+    check_offset(offset, "offset too large");
     _offset_array[index] = offset;
   }
 
   void set_offset_array(size_t index, HeapWord* high, HeapWord* low) {
-    assert(index < _vs.committed_size(), "index out of range");
+    check_index(index, "index out of range");
     assert(high >= low, "addresses out of order");
-    assert(pointer_delta(high, low) <= N_words, "offset too large");
+    check_offset(pointer_delta(high, low), "offset too large");
     _offset_array[index] = (u_char) pointer_delta(high, low);
   }
 
   void set_offset_array(HeapWord* left, HeapWord* right, u_char offset) {
-    assert(index_for(right - 1) < _vs.committed_size(),
-           "right address out of range");
+    check_index(index_for(right - 1), "right address out of range");
     assert(left  < right, "Heap addresses out of order");
     size_t num_cards = pointer_delta(right, left) >> LogN_words;
-    memset(&_offset_array[index_for(left)], offset, num_cards);
+    if (UseMemSetInBOT) {
+      memset(&_offset_array[index_for(left)], offset, num_cards);
+    } else {
+      size_t i = index_for(left);
+      const size_t end = i + num_cards;
+      for (; i < end; i++) {
+        _offset_array[i] = offset;
+      }
+    }
   }
 
   void set_offset_array(size_t left, size_t right, u_char offset) {
-    assert(right < _vs.committed_size(), "right address out of range");
-    assert(left  <= right, "indexes out of order");
+    check_index(right, "right index out of range");
+    assert(left <= right, "indexes out of order");
     size_t num_cards = right - left + 1;
-    memset(&_offset_array[left], offset, num_cards);
+    if (UseMemSetInBOT) {
+      memset(&_offset_array[left], offset, num_cards);
+    } else {
+      size_t i = left;
+      const size_t end = i + num_cards;
+      for (; i < end; i++) {
+        _offset_array[i] = offset;
+      }
+    }
   }
 
   void check_offset_array(size_t index, HeapWord* high, HeapWord* low) const {
-    assert(index < _vs.committed_size(), "index out of range");
+    check_index(index, "index out of range");
     assert(high >= low, "addresses out of order");
-    assert(pointer_delta(high, low) <= N_words, "offset too large");
-    assert(_offset_array[index] == pointer_delta(high, low),
-           "Wrong offset");
+    check_offset(pointer_delta(high, low), "offset too large");
+    assert(_offset_array[index] == pointer_delta(high, low), "Wrong offset");
   }
 
   bool is_card_boundary(HeapWord* p) const;
@@ -465,7 +495,6 @@
                       blk_start, blk_end);
   }
 
-
  public:
   G1BlockOffsetArrayContigSpace(G1BlockOffsetSharedArray* array, MemRegion mr);
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
index e246e93..0dd5680 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1BlockOffsetTable.inline.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -49,16 +49,17 @@
   char* pc = (char*)p;
   assert(pc >= (char*)_reserved.start() &&
          pc <  (char*)_reserved.end(),
-         "p not in range.");
+         err_msg("p (" PTR_FORMAT ") not in reserved [" PTR_FORMAT ", " PTR_FORMAT ")",
+                 p, (char*)_reserved.start(), (char*)_reserved.end()));
   size_t delta = pointer_delta(pc, _reserved.start(), sizeof(char));
   size_t result = delta >> LogN;
-  assert(result < _vs.committed_size(), "bad index from address");
+  check_index(result, "bad index from address");
   return result;
 }
 
 inline HeapWord*
 G1BlockOffsetSharedArray::address_for_index(size_t index) const {
-  assert(index < _vs.committed_size(), "bad index");
+  check_index(index, "index out of range");
   HeapWord* result = _reserved.start() + (index << LogN_words);
   assert(result >= _reserved.start() && result < _reserved.end(),
          "bad address from index");
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
index 55290cc..a299d77 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp
@@ -33,6 +33,8 @@
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
 #include "gc_implementation/g1/g1EvacFailure.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1MarkSweep.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
@@ -233,7 +235,7 @@
 bool YoungList::check_list_well_formed() {
   bool ret = true;
 
-  size_t length = 0;
+  uint length = 0;
   HeapRegion* curr = _head;
   HeapRegion* last = NULL;
   while (curr != NULL) {
@@ -252,7 +254,7 @@
 
   if (!ret) {
     gclog_or_tty->print_cr("### YOUNG LIST seems not well formed!");
-    gclog_or_tty->print_cr("###   list has %d entries, _length is %d",
+    gclog_or_tty->print_cr("###   list has %u entries, _length is %u",
                            length, _length);
   }
 
@@ -263,7 +265,7 @@
   bool ret = true;
 
   if (_length != 0) {
-    gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %d",
+    gclog_or_tty->print_cr("### YOUNG LIST should have 0 length, not %u",
                   _length);
     ret = false;
   }
@@ -336,8 +338,7 @@
     _g1h->g1_policy()->add_region_to_incremental_cset_rhs(curr);
     young_index_in_cset += 1;
   }
-  assert((size_t) young_index_in_cset == _survivor_length,
-         "post-condition");
+  assert((uint) young_index_in_cset == _survivor_length, "post-condition");
   _g1h->g1_policy()->note_stop_adding_survivor_regions();
 
   _head   = _survivor_head;
@@ -368,16 +369,11 @@
     if (curr == NULL)
       gclog_or_tty->print_cr("  empty");
     while (curr != NULL) {
-      gclog_or_tty->print_cr("  [%08x-%08x], t: %08x, P: %08x, N: %08x, C: %08x, "
-                             "age: %4d, y: %d, surv: %d",
-                             curr->bottom(), curr->end(),
-                             curr->top(),
+      gclog_or_tty->print_cr("  "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
+                             HR_FORMAT_PARAMS(curr),
                              curr->prev_top_at_mark_start(),
                              curr->next_top_at_mark_start(),
-                             curr->top_at_conc_mark_count(),
-                             curr->age_in_surv_rate_group_cond(),
-                             curr->is_young(),
-                             curr->is_survivor());
+                             curr->age_in_surv_rate_group_cond());
       curr = curr->get_next_young_region();
     }
   }
@@ -532,7 +528,7 @@
     if (!_secondary_free_list.is_empty()) {
       if (G1ConcRegionFreeingVerbose) {
         gclog_or_tty->print_cr("G1ConcRegionFreeing [region alloc] : "
-                               "secondary_free_list has "SIZE_FORMAT" entries",
+                               "secondary_free_list has %u entries",
                                _secondary_free_list.length());
       }
       // It looks as if there are free regions available on the
@@ -618,12 +614,12 @@
   return res;
 }
 
-size_t G1CollectedHeap::humongous_obj_allocate_find_first(size_t num_regions,
-                                                          size_t word_size) {
+uint G1CollectedHeap::humongous_obj_allocate_find_first(uint num_regions,
+                                                        size_t word_size) {
   assert(isHumongous(word_size), "word_size should be humongous");
   assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
 
-  size_t first = G1_NULL_HRS_INDEX;
+  uint first = G1_NULL_HRS_INDEX;
   if (num_regions == 1) {
     // Only one region to allocate, no need to go through the slower
     // path. The caller will attempt the expasion if this fails, so
@@ -649,7 +645,7 @@
     if (free_regions() >= num_regions) {
       first = _hrs.find_contiguous(num_regions);
       if (first != G1_NULL_HRS_INDEX) {
-        for (size_t i = first; i < first + num_regions; ++i) {
+        for (uint i = first; i < first + num_regions; ++i) {
           HeapRegion* hr = region_at(i);
           assert(hr->is_empty(), "sanity");
           assert(is_on_master_free_list(hr), "sanity");
@@ -663,15 +659,15 @@
 }
 
 HeapWord*
-G1CollectedHeap::humongous_obj_allocate_initialize_regions(size_t first,
-                                                           size_t num_regions,
+G1CollectedHeap::humongous_obj_allocate_initialize_regions(uint first,
+                                                           uint num_regions,
                                                            size_t word_size) {
   assert(first != G1_NULL_HRS_INDEX, "pre-condition");
   assert(isHumongous(word_size), "word_size should be humongous");
   assert(num_regions * HeapRegion::GrainWords >= word_size, "pre-condition");
 
   // Index of last region in the series + 1.
-  size_t last = first + num_regions;
+  uint last = first + num_regions;
 
   // We need to initialize the region(s) we just discovered. This is
   // a bit tricky given that it can happen concurrently with
@@ -682,7 +678,7 @@
   // a specific order.
 
   // The word size sum of all the regions we will allocate.
-  size_t word_size_sum = num_regions * HeapRegion::GrainWords;
+  size_t word_size_sum = (size_t) num_regions * HeapRegion::GrainWords;
   assert(word_size <= word_size_sum, "sanity");
 
   // This will be the "starts humongous" region.
@@ -721,7 +717,7 @@
   // Then, if there are any, we will set up the "continues
   // humongous" regions.
   HeapRegion* hr = NULL;
-  for (size_t i = first + 1; i < last; ++i) {
+  for (uint i = first + 1; i < last; ++i) {
     hr = region_at(i);
     hr->set_continuesHumongous(first_hr);
   }
@@ -767,7 +763,7 @@
   // last one) is actually used when we will free up the humongous
   // region in free_humongous_region().
   hr = NULL;
-  for (size_t i = first + 1; i < last; ++i) {
+  for (uint i = first + 1; i < last; ++i) {
     hr = region_at(i);
     if ((i + 1) == last) {
       // last continues humongous region
@@ -803,14 +799,14 @@
 
   verify_region_sets_optional();
 
-  size_t num_regions =
-         round_to(word_size, HeapRegion::GrainWords) / HeapRegion::GrainWords;
-  size_t x_size = expansion_regions();
-  size_t fs = _hrs.free_suffix();
-  size_t first = humongous_obj_allocate_find_first(num_regions, word_size);
+  size_t word_size_rounded = round_to(word_size, HeapRegion::GrainWords);
+  uint num_regions = (uint) (word_size_rounded / HeapRegion::GrainWords);
+  uint x_num = expansion_regions();
+  uint fs = _hrs.free_suffix();
+  uint first = humongous_obj_allocate_find_first(num_regions, word_size);
   if (first == G1_NULL_HRS_INDEX) {
     // The only thing we can do now is attempt expansion.
-    if (fs + x_size >= num_regions) {
+    if (fs + x_num >= num_regions) {
       // If the number of regions we're trying to allocate for this
       // object is at most the number of regions in the free suffix,
       // then the call to humongous_obj_allocate_find_first() above
@@ -957,9 +953,18 @@
         }
         should_try_gc = false;
       } else {
-        // Read the GC count while still holding the Heap_lock.
-        gc_count_before = total_collections();
-        should_try_gc = true;
+        // The GCLocker may not be active but the GCLocker initiated
+        // GC may not yet have been performed (GCLocker::needs_gc()
+        // returns true). In this case we do not try this GC and
+        // wait until the GCLocker initiated GC is performed, and
+        // then retry the allocation.
+        if (GC_locker::needs_gc()) {
+          should_try_gc = false;
+        } else {
+          // Read the GC count while still holding the Heap_lock.
+          gc_count_before = total_collections();
+          should_try_gc = true;
+        }
       }
     }
 
@@ -980,6 +985,9 @@
         return NULL;
       }
     } else {
+      // The GCLocker is either active or the GCLocker initiated
+      // GC has not yet been performed. Stall until it is and
+      // then retry the allocation.
       GC_locker::stall_until_clear();
     }
 
@@ -1059,9 +1067,18 @@
       if (GC_locker::is_active_and_needs_gc()) {
         should_try_gc = false;
       } else {
-        // Read the GC count while still holding the Heap_lock.
-        gc_count_before = total_collections();
-        should_try_gc = true;
+         // The GCLocker may not be active but the GCLocker initiated
+        // GC may not yet have been performed (GCLocker::needs_gc()
+        // returns true). In this case we do not try this GC and
+        // wait until the GCLocker initiated GC is performed, and
+        // then retry the allocation.
+        if (GC_locker::needs_gc()) {
+          should_try_gc = false;
+        } else {
+          // Read the GC count while still holding the Heap_lock.
+          gc_count_before = total_collections();
+          should_try_gc = true;
+        }
       }
     }
 
@@ -1086,6 +1103,9 @@
         return NULL;
       }
     } else {
+      // The GCLocker is either active or the GCLocker initiated
+      // GC has not yet been performed. Stall until it is and
+      // then retry the allocation.
       GC_locker::stall_until_clear();
     }
 
@@ -1129,13 +1149,16 @@
 }
 
 class PostMCRemSetClearClosure: public HeapRegionClosure {
+  G1CollectedHeap* _g1h;
   ModRefBarrierSet* _mr_bs;
 public:
-  PostMCRemSetClearClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {}
+  PostMCRemSetClearClosure(G1CollectedHeap* g1h, ModRefBarrierSet* mr_bs) :
+    _g1h(g1h), _mr_bs(mr_bs) { }
   bool doHeapRegion(HeapRegion* r) {
-    r->reset_gc_time_stamp();
-    if (r->continuesHumongous())
+    if (r->continuesHumongous()) {
       return false;
+    }
+    _g1h->reset_gc_time_stamps(r);
     HeapRegionRemSet* hrrs = r->rem_set();
     if (hrrs != NULL) hrrs->clear();
     // You might think here that we could clear just the cards
@@ -1148,19 +1171,10 @@
   }
 };
 
-
-class PostMCRemSetInvalidateClosure: public HeapRegionClosure {
-  ModRefBarrierSet* _mr_bs;
-public:
-  PostMCRemSetInvalidateClosure(ModRefBarrierSet* mr_bs) : _mr_bs(mr_bs) {}
-  bool doHeapRegion(HeapRegion* r) {
-    if (r->continuesHumongous()) return false;
-    if (r->used_region().word_size() != 0) {
-      _mr_bs->invalidate(r->used_region(), true /*whole heap*/);
-    }
-    return false;
-  }
-};
+void G1CollectedHeap::clear_rsets_post_compaction() {
+  PostMCRemSetClearClosure rs_clear(this, mr_bs());
+  heap_region_iterate(&rs_clear);
+}
 
 class RebuildRSOutOfRegionClosure: public HeapRegionClosure {
   G1CollectedHeap*   _g1h;
@@ -1209,7 +1223,7 @@
       if (!hr->isHumongous()) {
         _hr_printer->post_compaction(hr, G1HRPrinter::Old);
       } else if (hr->startsHumongous()) {
-        if (hr->capacity() == HeapRegion::GrainBytes) {
+        if (hr->region_num() == 1) {
           // single humongous region
           _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
         } else {
@@ -1227,6 +1241,36 @@
     : _hr_printer(hr_printer) { }
 };
 
+void G1CollectedHeap::print_hrs_post_compaction() {
+  PostCompactionPrinterClosure cl(hr_printer());
+  heap_region_iterate(&cl);
+}
+
+double G1CollectedHeap::verify(bool guard, const char* msg) {
+  double verify_time_ms = 0.0;
+
+  if (guard && total_collections() >= VerifyGCStartAt) {
+    double verify_start = os::elapsedTime();
+    HandleMark hm;  // Discard invalid handles created during verification
+    gclog_or_tty->print(msg);
+    prepare_for_verify();
+    Universe::verify(false /* silent */, VerifyOption_G1UsePrevMarking);
+    verify_time_ms = (os::elapsedTime() - verify_start) * 1000;
+  }
+
+  return verify_time_ms;
+}
+
+void G1CollectedHeap::verify_before_gc() {
+  double verify_time_ms = verify(VerifyBeforeGC, " VerifyBeforeGC:");
+  g1_policy()->phase_times()->record_verify_before_time_ms(verify_time_ms);
+}
+
+void G1CollectedHeap::verify_after_gc() {
+  double verify_time_ms = verify(VerifyAfterGC, " VerifyAfterGC:");
+  g1_policy()->phase_times()->record_verify_after_time_ms(verify_time_ms);
+}
+
 bool G1CollectedHeap::do_collection(bool explicit_gc,
                                     bool clear_all_soft_refs,
                                     size_t word_size) {
@@ -1253,13 +1297,11 @@
     IsGCActiveMark x;
 
     // Timing
-    bool system_gc = (gc_cause() == GCCause::_java_lang_system_gc);
-    assert(!system_gc || explicit_gc, "invariant");
-    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t(system_gc ? "Full GC (System.gc())" : "Full GC",
-                PrintGC, true, gclog_or_tty);
+    assert(gc_cause() != GCCause::_java_lang_system_gc || explicit_gc, "invariant");
+    gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
+    TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
+    TraceTime t(GCCauseString("Full GC", gc_cause()), G1Log::fine(), true, gclog_or_tty);
     TraceCollectorStats tcs(g1mm()->full_collection_counters());
     TraceMemoryManagerStats tms(true /* fullGC */, gc_cause());
 
@@ -1282,19 +1324,13 @@
 
     gc_prologue(true);
     increment_total_collections(true /* full gc */);
+    increment_old_marking_cycles_started();
 
     size_t g1h_prev_used = used();
     assert(used() == recalculate_used(), "Should be equal");
 
-    if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) {
-      HandleMark hm;  // Discard invalid handles created during verification
-      gclog_or_tty->print(" VerifyBeforeGC:");
-      prepare_for_verify();
-      Universe::verify(/* allow dirty */ true,
-                       /* silent      */ false,
-                       /* option      */ VerifyOption_G1UsePrevMarking);
+    verify_before_gc();
 
-    }
     pre_full_gc_dump();
 
     COMPILER2_PRESENT(DerivedPointerTable::clear());
@@ -1361,15 +1397,7 @@
 
     MemoryService::track_memory_usage();
 
-    if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
-      HandleMark hm;  // Discard invalid handles created during verification
-      gclog_or_tty->print(" VerifyAfterGC:");
-      prepare_for_verify();
-      Universe::verify(/* allow dirty */ false,
-                       /* silent      */ false,
-                       /* option      */ VerifyOption_G1UsePrevMarking);
-
-    }
+    verify_after_gc();
 
     assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
     ref_processor_stw()->verify_no_references_recorded();
@@ -1385,8 +1413,8 @@
     // Since everything potentially moved, we will clear all remembered
     // sets, and clear all cards.  Later we will rebuild remebered
     // sets. We will also reset the GC time stamps of the regions.
-    PostMCRemSetClearClosure rs_clear(mr_bs());
-    heap_region_iterate(&rs_clear);
+    clear_rsets_post_compaction();
+    check_gc_time_stamps();
 
     // Resize the heap if necessary.
     resize_if_necessary_after_full_collection(explicit_gc ? 0 : word_size);
@@ -1396,9 +1424,7 @@
       // that all the COMMIT / UNCOMMIT events are generated before
       // the end GC event.
 
-      PostCompactionPrinterClosure cl(hr_printer());
-      heap_region_iterate(&cl);
-
+      print_hrs_post_compaction();
       _hr_printer.end_gc(true /* full */, (size_t) total_collections());
     }
 
@@ -1444,7 +1470,7 @@
       heap_region_iterate(&rebuild_rs);
     }
 
-    if (PrintGC) {
+    if (G1Log::fine()) {
       print_size_transition(gclog_or_tty, g1h_prev_used, used(), capacity());
     }
 
@@ -1477,22 +1503,28 @@
     JavaThread::dirty_card_queue_set().abandon_logs();
     assert(!G1DeferredRSUpdate
            || (G1DeferredRSUpdate && (dirty_card_queue_set().completed_buffers_num() == 0)), "Should not be any");
+
+    _young_list->reset_sampled_info();
+    // At this point there should be no regions in the
+    // entire heap tagged as young.
+    assert( check_young_list_empty(true /* check_heap */),
+      "young list should be empty at this point");
+
+    // Update the number of full collections that have been completed.
+    increment_old_marking_cycles_completed(false /* concurrent */);
+
+    _hrs.verify_optional();
+    verify_region_sets_optional();
+
+    print_heap_after_gc();
+
+    // We must call G1MonitoringSupport::update_sizes() in the same scoping level
+    // as an active TraceMemoryManagerStats object (i.e. before the destructor for the
+    // TraceMemoryManagerStats is called) so that the G1 memory pools are updated
+    // before any GC notifications are raised.
+    g1mm()->update_sizes();
   }
 
-  _young_list->reset_sampled_info();
-  // At this point there should be no regions in the
-  // entire heap tagged as young.
-  assert( check_young_list_empty(true /* check_heap */),
-    "young list should be empty at this point");
-
-  // Update the number of full collections that have been completed.
-  increment_full_collections_completed(false /* concurrent */);
-
-  _hrs.verify_optional();
-  verify_region_sets_optional();
-
-  print_heap_after_gc();
-  g1mm()->update_sizes();
   post_full_gc_dump();
 
   return true;
@@ -1782,7 +1814,7 @@
     ReservedSpace::page_align_size_down(shrink_bytes);
   aligned_shrink_bytes = align_size_down(aligned_shrink_bytes,
                                          HeapRegion::GrainBytes);
-  size_t num_regions_deleted = 0;
+  uint num_regions_deleted = 0;
   MemRegion mr = _hrs.shrink_by(aligned_shrink_bytes, &num_regions_deleted);
   HeapWord* old_end = (HeapWord*) _g1_storage.high();
   assert(mr.end() == old_end, "post-condition");
@@ -1871,9 +1903,12 @@
   _young_list(new YoungList(this)),
   _gc_time_stamp(0),
   _retained_old_gc_alloc_region(NULL),
+  _survivor_plab_stats(YoungPLABSize, PLABWeight),
+  _old_plab_stats(OldPLABSize, PLABWeight),
   _expand_heap_after_alloc_failure(true),
   _surviving_young_words(NULL),
-  _full_collections_completed(0),
+  _old_marking_cycles_started(0),
+  _old_marking_cycles_completed(0),
   _in_cset_fast_test(NULL),
   _in_cset_fast_test_base(NULL),
   _dirty_cards_region_list(NULL),
@@ -1893,14 +1928,14 @@
   assert(n_rem_sets > 0, "Invariant.");
 
   HeapRegionRemSetIterator** iter_arr =
-    NEW_C_HEAP_ARRAY(HeapRegionRemSetIterator*, n_queues);
+    NEW_C_HEAP_ARRAY(HeapRegionRemSetIterator*, n_queues, mtGC);
   for (int i = 0; i < n_queues; i++) {
     iter_arr[i] = new HeapRegionRemSetIterator();
   }
   _rem_set_iterator = iter_arr;
 
-  _worker_cset_start_region = NEW_C_HEAP_ARRAY(HeapRegion*, n_queues);
-  _worker_cset_start_region_time_stamp = NEW_C_HEAP_ARRAY(unsigned int, n_queues);
+  _worker_cset_start_region = NEW_C_HEAP_ARRAY(HeapRegion*, n_queues, mtGC);
+  _worker_cset_start_region_time_stamp = NEW_C_HEAP_ARRAY(unsigned int, n_queues, mtGC);
 
   for (int i = 0; i < n_queues; i++) {
     RefToScanQueue* q = new RefToScanQueue();
@@ -1910,6 +1945,9 @@
 
   clear_cset_start_regions();
 
+  // Initialize the G1EvacuationFailureALot counters and flags.
+  NOT_PRODUCT(reset_evacuation_should_fail();)
+
   guarantee(_task_queues != NULL, "task_queues allocation failure.");
 }
 
@@ -1917,6 +1955,8 @@
   CollectedHeap::pre_initialize();
   os::enable_vtime();
 
+  G1Log::init();
+
   // Necessary to satisfy locking discipline assertions.
 
   MutexLocker x(Heap_lock);
@@ -2003,7 +2043,7 @@
   _reserved.set_start((HeapWord*)heap_rs.base());
   _reserved.set_end((HeapWord*)(heap_rs.base() + heap_rs.size()));
 
-  _expansion_regions = max_byte_size/HeapRegion::GrainBytes;
+  _expansion_regions = (uint) (max_byte_size / HeapRegion::GrainBytes);
 
   // Create the gen rem set (and barrier set) for the entire reserved region.
   _rem_set = collector_policy()->create_rem_set(_reserved, 2);
@@ -2040,7 +2080,7 @@
 
   // 6843694 - ensure that the maximum region index can fit
   // in the remembered set structures.
-  const size_t max_region_idx = ((size_t)1 << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
+  const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1;
   guarantee((max_regions() - 1) <= max_region_idx, "too many regions");
 
   size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1;
@@ -2056,13 +2096,14 @@
   _g1h = this;
 
    _in_cset_fast_test_length = max_regions();
-   _in_cset_fast_test_base = NEW_C_HEAP_ARRAY(bool, _in_cset_fast_test_length);
+   _in_cset_fast_test_base =
+                   NEW_C_HEAP_ARRAY(bool, (size_t) _in_cset_fast_test_length, mtGC);
 
    // We're biasing _in_cset_fast_test to avoid subtracting the
    // beginning of the heap every time we want to index; basically
    // it's the same with what we do with the card table.
    _in_cset_fast_test = _in_cset_fast_test_base -
-                ((size_t) _g1_reserved.start() >> HeapRegion::LogOfHRGrainBytes);
+               ((uintx) _g1_reserved.start() >> HeapRegion::LogOfHRGrainBytes);
 
    // Clear the _cset_fast_test bitmap in anticipation of adding
    // regions to the incremental collection set for the first
@@ -2071,7 +2112,7 @@
 
   // Create the ConcurrentMark data structure and thread.
   // (Must do this late, so that "max_regions" is defined.)
-  _cm       = new ConcurrentMark(heap_rs, (int) max_regions());
+  _cm       = new ConcurrentMark(heap_rs, max_regions());
   _cmThread = _cm->cmThread();
 
   // Initialize the from_card cache structure of HeapRegionRemSet.
@@ -2236,6 +2277,51 @@
   return _g1_committed.byte_size();
 }
 
+void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
+  assert(!hr->continuesHumongous(), "pre-condition");
+  hr->reset_gc_time_stamp();
+  if (hr->startsHumongous()) {
+    uint first_index = hr->hrs_index() + 1;
+    uint last_index = hr->last_hc_index();
+    for (uint i = first_index; i < last_index; i += 1) {
+      HeapRegion* chr = region_at(i);
+      assert(chr->continuesHumongous(), "sanity");
+      chr->reset_gc_time_stamp();
+    }
+  }
+}
+
+#ifndef PRODUCT
+class CheckGCTimeStampsHRClosure : public HeapRegionClosure {
+private:
+  unsigned _gc_time_stamp;
+  bool _failures;
+
+public:
+  CheckGCTimeStampsHRClosure(unsigned gc_time_stamp) :
+    _gc_time_stamp(gc_time_stamp), _failures(false) { }
+
+  virtual bool doHeapRegion(HeapRegion* hr) {
+    unsigned region_gc_time_stamp = hr->get_gc_time_stamp();
+    if (_gc_time_stamp != region_gc_time_stamp) {
+      gclog_or_tty->print_cr("Region "HR_FORMAT" has GC time stamp = %d, "
+                             "expected %d", HR_FORMAT_PARAMS(hr),
+                             region_gc_time_stamp, _gc_time_stamp);
+      _failures = true;
+    }
+    return false;
+  }
+
+  bool failures() { return _failures; }
+};
+
+void G1CollectedHeap::check_gc_time_stamps() {
+  CheckGCTimeStampsHRClosure cl(_gc_time_stamp);
+  heap_region_iterate(&cl);
+  guarantee(!cl.failures(), "all GC time stamps should have been reset");
+}
+#endif // PRODUCT
+
 void G1CollectedHeap::iterate_dirty_card_closure(CardTableEntryClosure* cl,
                                                  DirtyCardQueue* into_cset_dcq,
                                                  bool concurrent,
@@ -2248,8 +2334,7 @@
   while (dcqs.apply_closure_to_completed_buffer(cl, worker_i, 0, true)) {
     n_completed_buffers++;
   }
-  g1_policy()->record_update_rs_processed_buffers(worker_i,
-                                                  (double) n_completed_buffers);
+  g1_policy()->phase_times()->record_update_rs_processed_buffers(worker_i, n_completed_buffers);
   dcqs.clear_n_completed_buffers();
   assert(!dcqs.completed_buffers_exist_dirty(), "Completed buffers exist!");
 }
@@ -2342,7 +2427,16 @@
 }
 #endif // !PRODUCT
 
-void G1CollectedHeap::increment_full_collections_completed(bool concurrent) {
+void G1CollectedHeap::increment_old_marking_cycles_started() {
+  assert(_old_marking_cycles_started == _old_marking_cycles_completed ||
+    _old_marking_cycles_started == _old_marking_cycles_completed + 1,
+    err_msg("Wrong marking cycle count (started: %d, completed: %d)",
+    _old_marking_cycles_started, _old_marking_cycles_completed));
+
+  _old_marking_cycles_started++;
+}
+
+void G1CollectedHeap::increment_old_marking_cycles_completed(bool concurrent) {
   MonitorLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
 
   // We assume that if concurrent == true, then the caller is a
@@ -2350,11 +2444,6 @@
   // Set. If there's ever a cheap way to check this, we should add an
   // assert here.
 
-  // We have already incremented _total_full_collections at the start
-  // of the GC, so total_full_collections() represents how many full
-  // collections have been started.
-  unsigned int full_collections_started = total_full_collections();
-
   // Given that this method is called at the end of a Full GC or of a
   // concurrent cycle, and those can be nested (i.e., a Full GC can
   // interrupt a concurrent cycle), the number of full collections
@@ -2364,21 +2453,21 @@
 
   // This is the case for the inner caller, i.e. a Full GC.
   assert(concurrent ||
-         (full_collections_started == _full_collections_completed + 1) ||
-         (full_collections_started == _full_collections_completed + 2),
-         err_msg("for inner caller (Full GC): full_collections_started = %u "
-                 "is inconsistent with _full_collections_completed = %u",
-                 full_collections_started, _full_collections_completed));
+         (_old_marking_cycles_started == _old_marking_cycles_completed + 1) ||
+         (_old_marking_cycles_started == _old_marking_cycles_completed + 2),
+         err_msg("for inner caller (Full GC): _old_marking_cycles_started = %u "
+                 "is inconsistent with _old_marking_cycles_completed = %u",
+                 _old_marking_cycles_started, _old_marking_cycles_completed));
 
   // This is the case for the outer caller, i.e. the concurrent cycle.
   assert(!concurrent ||
-         (full_collections_started == _full_collections_completed + 1),
+         (_old_marking_cycles_started == _old_marking_cycles_completed + 1),
          err_msg("for outer caller (concurrent cycle): "
-                 "full_collections_started = %u "
-                 "is inconsistent with _full_collections_completed = %u",
-                 full_collections_started, _full_collections_completed));
+                 "_old_marking_cycles_started = %u "
+                 "is inconsistent with _old_marking_cycles_completed = %u",
+                 _old_marking_cycles_started, _old_marking_cycles_completed));
 
-  _full_collections_completed += 1;
+  _old_marking_cycles_completed += 1;
 
   // We need to clear the "in_progress" flag in the CM thread before
   // we wake up any waiters (especially when ExplicitInvokesConcurrent
@@ -2414,7 +2503,7 @@
   assert_heap_not_locked();
 
   unsigned int gc_count_before;
-  unsigned int full_gc_count_before;
+  unsigned int old_marking_count_before;
   bool retry_gc;
 
   do {
@@ -2425,7 +2514,7 @@
 
       // Read the GC count while holding the Heap_lock
       gc_count_before = total_collections();
-      full_gc_count_before = total_full_collections();
+      old_marking_count_before = _old_marking_cycles_started;
     }
 
     if (should_do_concurrent_full_gc(cause)) {
@@ -2440,7 +2529,7 @@
 
       VMThread::execute(&op);
       if (!op.pause_succeeded()) {
-        if (full_gc_count_before == total_full_collections()) {
+        if (old_marking_count_before == _old_marking_cycles_started) {
           retry_gc = op.should_retry_gc();
         } else {
           // A Full GC happened while we were trying to schedule the
@@ -2468,7 +2557,7 @@
         VMThread::execute(&op);
       } else {
         // Schedule a Full GC.
-        VM_G1CollectFull op(gc_count_before, full_gc_count_before, cause);
+        VM_G1CollectFull op(gc_count_before, old_marking_count_before, cause);
         VMThread::execute(&op);
       }
     }
@@ -2499,7 +2588,7 @@
   IterateOopClosureRegionClosure(MemRegion mr, OopClosure* cl)
     : _mr(mr), _cl(cl) {}
   bool doHeapRegion(HeapRegion* r) {
-    if (! r->continuesHumongous()) {
+    if (!r->continuesHumongous()) {
       r->oop_iterate(_cl);
     }
     return false;
@@ -2570,17 +2659,12 @@
   _hrs.iterate(cl);
 }
 
-void G1CollectedHeap::heap_region_iterate_from(HeapRegion* r,
-                                               HeapRegionClosure* cl) const {
-  _hrs.iterate_from(r, cl);
-}
-
 void
 G1CollectedHeap::heap_region_par_iterate_chunked(HeapRegionClosure* cl,
-                                                 uint worker,
+                                                 uint worker_id,
                                                  uint no_of_par_workers,
                                                  jint claim_value) {
-  const size_t regions = n_regions();
+  const uint regions = n_regions();
   const uint max_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
                              no_of_par_workers :
                              1);
@@ -2588,11 +2672,13 @@
          no_of_par_workers == workers()->total_workers(),
          "Non dynamic should use fixed number of workers");
   // try to spread out the starting points of the workers
-  const size_t start_index = regions / max_workers * (size_t) worker;
+  const HeapRegion* start_hr =
+                        start_region_for_worker(worker_id, no_of_par_workers);
+  const uint start_index = start_hr->hrs_index();
 
   // each worker will actually look at all regions
-  for (size_t count = 0; count < regions; ++count) {
-    const size_t index = (start_index + count) % regions;
+  for (uint count = 0; count < regions; ++count) {
+    const uint index = (start_index + count) % regions;
     assert(0 <= index && index < regions, "sanity");
     HeapRegion* r = region_at(index);
     // we'll ignore "continues humongous" regions (we'll process them
@@ -2614,7 +2700,7 @@
         // result, we might end up processing them twice. So, we'll do
         // them first (notice: most closures will ignore them anyway) and
         // then we'll do the "starts humongous" region.
-        for (size_t ch_index = index + 1; ch_index < regions; ++ch_index) {
+        for (uint ch_index = index + 1; ch_index < regions; ++ch_index) {
           HeapRegion* chr = region_at(ch_index);
 
           // if the region has already been claimed or it's not
@@ -2682,8 +2768,9 @@
 class CheckClaimValuesClosure : public HeapRegionClosure {
 private:
   jint _claim_value;
-  size_t _failures;
+  uint _failures;
   HeapRegion* _sh_region;
+
 public:
   CheckClaimValuesClosure(jint claim_value) :
     _claim_value(claim_value), _failures(0), _sh_region(NULL) { }
@@ -2711,9 +2798,7 @@
     }
     return false;
   }
-  size_t failures() {
-    return _failures;
-  }
+  uint failures() { return _failures; }
 };
 
 bool G1CollectedHeap::check_heap_region_claim_values(jint claim_value) {
@@ -2723,17 +2808,15 @@
 }
 
 class CheckClaimValuesInCSetHRClosure: public HeapRegionClosure {
-  jint   _claim_value;
-  size_t _failures;
+private:
+  jint _claim_value;
+  uint _failures;
 
 public:
   CheckClaimValuesInCSetHRClosure(jint claim_value) :
-    _claim_value(claim_value),
-    _failures(0) { }
+    _claim_value(claim_value), _failures(0) { }
 
-  size_t failures() {
-    return _failures;
-  }
+  uint failures() { return _failures; }
 
   bool doHeapRegion(HeapRegion* hr) {
     assert(hr->in_collection_set(), "how?");
@@ -2800,14 +2883,14 @@
 
   result = g1_policy()->collection_set();
   if (G1CollectedHeap::use_parallel_gc_threads()) {
-    size_t cs_size = g1_policy()->cset_region_length();
+    uint cs_size = g1_policy()->cset_region_length();
     uint active_workers = workers()->active_workers();
     assert(UseDynamicNumberOfGCThreads ||
              active_workers == workers()->total_workers(),
              "Unless dynamic should use total workers");
 
-    size_t end_ind   = (cs_size * worker_i) / active_workers;
-    size_t start_ind = 0;
+    uint end_ind   = (cs_size * worker_i) / active_workers;
+    uint start_ind = 0;
 
     if (worker_i > 0 &&
         _worker_cset_start_region_time_stamp[worker_i - 1] == gc_time_stamp) {
@@ -2817,7 +2900,7 @@
       result = _worker_cset_start_region[worker_i - 1];
     }
 
-    for (size_t i = start_ind; i < end_ind; i++) {
+    for (uint i = start_ind; i < end_ind; i++) {
       result = result->next_in_collection_set();
     }
   }
@@ -2833,6 +2916,17 @@
   return result;
 }
 
+HeapRegion* G1CollectedHeap::start_region_for_worker(uint worker_i,
+                                                     uint no_of_par_workers) {
+  uint worker_num =
+           G1CollectedHeap::use_parallel_gc_threads() ? no_of_par_workers : 1U;
+  assert(UseDynamicNumberOfGCThreads ||
+         no_of_par_workers == workers()->total_workers(),
+         "Non dynamic should use fixed number of workers");
+  const uint start_index = n_regions() * worker_i / worker_num;
+  return region_at(start_index);
+}
+
 void G1CollectedHeap::collection_set_iterate(HeapRegionClosure* cl) {
   HeapRegion* r = g1_policy()->collection_set();
   while (r != NULL) {
@@ -2946,6 +3040,51 @@
   g1_rem_set()->prepare_for_verify();
 }
 
+bool G1CollectedHeap::allocated_since_marking(oop obj, HeapRegion* hr,
+                                              VerifyOption vo) {
+  switch (vo) {
+  case VerifyOption_G1UsePrevMarking:
+    return hr->obj_allocated_since_prev_marking(obj);
+  case VerifyOption_G1UseNextMarking:
+    return hr->obj_allocated_since_next_marking(obj);
+  case VerifyOption_G1UseMarkWord:
+    return false;
+  default:
+    ShouldNotReachHere();
+  }
+  return false; // keep some compilers happy
+}
+
+HeapWord* G1CollectedHeap::top_at_mark_start(HeapRegion* hr, VerifyOption vo) {
+  switch (vo) {
+  case VerifyOption_G1UsePrevMarking: return hr->prev_top_at_mark_start();
+  case VerifyOption_G1UseNextMarking: return hr->next_top_at_mark_start();
+  case VerifyOption_G1UseMarkWord:    return NULL;
+  default:                            ShouldNotReachHere();
+  }
+  return NULL; // keep some compilers happy
+}
+
+bool G1CollectedHeap::is_marked(oop obj, VerifyOption vo) {
+  switch (vo) {
+  case VerifyOption_G1UsePrevMarking: return isMarkedPrev(obj);
+  case VerifyOption_G1UseNextMarking: return isMarkedNext(obj);
+  case VerifyOption_G1UseMarkWord:    return obj->is_gc_marked();
+  default:                            ShouldNotReachHere();
+  }
+  return false; // keep some compilers happy
+}
+
+const char* G1CollectedHeap::top_at_mark_start_str(VerifyOption vo) {
+  switch (vo) {
+  case VerifyOption_G1UsePrevMarking: return "PTAMS";
+  case VerifyOption_G1UseNextMarking: return "NTAMS";
+  case VerifyOption_G1UseMarkWord:    return "NONE";
+  default:                            ShouldNotReachHere();
+  }
+  return NULL; // keep some compilers happy
+}
+
 class VerifyLivenessOopClosure: public OopClosure {
   G1CollectedHeap* _g1h;
   VerifyOption _vo;
@@ -3033,17 +3172,15 @@
 
 class VerifyRegionClosure: public HeapRegionClosure {
 private:
-  bool         _allow_dirty;
-  bool         _par;
-  VerifyOption _vo;
-  bool         _failures;
+  bool             _par;
+  VerifyOption     _vo;
+  bool             _failures;
 public:
   // _vo == UsePrevMarking -> use "prev" marking information,
   // _vo == UseNextMarking -> use "next" marking information,
   // _vo == UseMarkWord    -> use mark word from object header.
-  VerifyRegionClosure(bool allow_dirty, bool par, VerifyOption vo)
-    : _allow_dirty(allow_dirty),
-      _par(par),
+  VerifyRegionClosure(bool par, VerifyOption vo)
+    : _par(par),
       _vo(vo),
       _failures(false) {}
 
@@ -3052,11 +3189,9 @@
   }
 
   bool doHeapRegion(HeapRegion* r) {
-    guarantee(_par || r->claim_value() == HeapRegion::InitialClaimValue,
-              "Should be unclaimed at verify points.");
     if (!r->continuesHumongous()) {
       bool failures = false;
-      r->verify(_allow_dirty, _vo, &failures);
+      r->verify(_vo, &failures);
       if (failures) {
         _failures = true;
       } else {
@@ -3124,7 +3259,6 @@
 class G1ParVerifyTask: public AbstractGangTask {
 private:
   G1CollectedHeap* _g1h;
-  bool             _allow_dirty;
   VerifyOption     _vo;
   bool             _failures;
 
@@ -3132,10 +3266,9 @@
   // _vo == UsePrevMarking -> use "prev" marking information,
   // _vo == UseNextMarking -> use "next" marking information,
   // _vo == UseMarkWord    -> use mark word from object header.
-  G1ParVerifyTask(G1CollectedHeap* g1h, bool allow_dirty, VerifyOption vo) :
+  G1ParVerifyTask(G1CollectedHeap* g1h, VerifyOption vo) :
     AbstractGangTask("Parallel verify task"),
     _g1h(g1h),
-    _allow_dirty(allow_dirty),
     _vo(vo),
     _failures(false) { }
 
@@ -3145,7 +3278,7 @@
 
   void work(uint worker_id) {
     HandleMark hm;
-    VerifyRegionClosure blk(_allow_dirty, true, _vo);
+    VerifyRegionClosure blk(true, _vo);
     _g1h->heap_region_par_iterate_chunked(&blk, worker_id,
                                           _g1h->workers()->active_workers(),
                                           HeapRegion::ParVerifyClaimValue);
@@ -3155,12 +3288,11 @@
   }
 };
 
-void G1CollectedHeap::verify(bool allow_dirty, bool silent) {
-  verify(allow_dirty, silent, VerifyOption_G1UsePrevMarking);
+void G1CollectedHeap::verify(bool silent) {
+  verify(silent, VerifyOption_G1UsePrevMarking);
 }
 
-void G1CollectedHeap::verify(bool allow_dirty,
-                             bool silent,
+void G1CollectedHeap::verify(bool silent,
                              VerifyOption vo) {
   if (SafepointSynchronize::is_at_safepoint() || ! UseTLAB) {
     if (!silent) { gclog_or_tty->print("Roots (excluding permgen) "); }
@@ -3212,7 +3344,7 @@
       assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
              "sanity check");
 
-      G1ParVerifyTask task(this, allow_dirty, vo);
+      G1ParVerifyTask task(this, vo);
       assert(UseDynamicNumberOfGCThreads ||
         workers()->active_workers() == workers()->total_workers(),
         "If not dynamic should be using all the workers");
@@ -3234,7 +3366,7 @@
       assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
              "sanity check");
     } else {
-      VerifyRegionClosure blk(allow_dirty, false, vo);
+      VerifyRegionClosure blk(false, vo);
       heap_region_iterate(&blk);
       if (blk.failures()) {
         failures = true;
@@ -3284,12 +3416,12 @@
             _g1_storage.high_boundary());
   st->cr();
   st->print("  region size " SIZE_FORMAT "K, ", HeapRegion::GrainBytes / K);
-  size_t young_regions = _young_list->length();
-  st->print(SIZE_FORMAT " young (" SIZE_FORMAT "K), ",
-            young_regions, young_regions * HeapRegion::GrainBytes / K);
-  size_t survivor_regions = g1_policy()->recorded_survivor_regions();
-  st->print(SIZE_FORMAT " survivors (" SIZE_FORMAT "K)",
-            survivor_regions, survivor_regions * HeapRegion::GrainBytes / K);
+  uint young_regions = _young_list->length();
+  st->print("%u young (" SIZE_FORMAT "K), ", young_regions,
+            (size_t) young_regions * HeapRegion::GrainBytes / K);
+  uint survivor_regions = g1_policy()->recorded_survivor_regions();
+  st->print("%u survivors (" SIZE_FORMAT "K)", survivor_regions,
+            (size_t) survivor_regions * HeapRegion::GrainBytes / K);
   st->cr();
   perm()->as_gen()->print_on(st);
 }
@@ -3299,7 +3431,11 @@
 
   // Print the per-region information.
   st->cr();
-  st->print_cr("Heap Regions: (Y=young(eden), SU=young(survivor), HS=humongous(starts), HC=humongous(continues), CS=collection set, F=free, TS=gc time stamp, PTAMS=previous top-at-mark-start, NTAMS=next top-at-mark-start)");
+  st->print_cr("Heap Regions: (Y=young(eden), SU=young(survivor), "
+               "HS=humongous(starts), HC=humongous(continues), "
+               "CS=collection set, F=free, TS=gc time stamp, "
+               "PTAMS=previous top-at-mark-start, "
+               "NTAMS=next top-at-mark-start)");
   PrintRegionClosure blk(st);
   heap_region_iterate(&blk);
 }
@@ -3460,15 +3596,11 @@
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
   size_t buffer_size = dcqs.buffer_size();
   size_t buffer_num = dcqs.completed_buffers_num();
-  return buffer_size * buffer_num + extra_cards;
-}
 
-size_t G1CollectedHeap::max_pending_card_num() {
-  DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
-  size_t buffer_size = dcqs.buffer_size();
-  size_t buffer_num  = dcqs.completed_buffers_num();
-  int thread_num  = Threads::number_of_threads();
-  return (buffer_num + thread_num) * buffer_size;
+  // PtrQueueSet::buffer_size() and PtrQueue:size() return sizes
+  // in bytes - not the number of 'entries'. We need to convert
+  // into a number of cards.
+  return (buffer_size * buffer_num + extra_cards) / oopSize;
 }
 
 size_t G1CollectedHeap::cards_scanned() {
@@ -3477,16 +3609,16 @@
 
 void
 G1CollectedHeap::setup_surviving_young_words() {
-  guarantee( _surviving_young_words == NULL, "pre-condition" );
-  size_t array_length = g1_policy()->young_cset_region_length();
-  _surviving_young_words = NEW_C_HEAP_ARRAY(size_t, array_length);
+  assert(_surviving_young_words == NULL, "pre-condition");
+  uint array_length = g1_policy()->young_cset_region_length();
+  _surviving_young_words = NEW_C_HEAP_ARRAY(size_t, (size_t) array_length, mtGC);
   if (_surviving_young_words == NULL) {
     vm_exit_out_of_memory(sizeof(size_t) * array_length,
                           "Not enough space for young surv words summary.");
   }
-  memset(_surviving_young_words, 0, array_length * sizeof(size_t));
+  memset(_surviving_young_words, 0, (size_t) array_length * sizeof(size_t));
 #ifdef ASSERT
-  for (size_t i = 0;  i < array_length; ++i) {
+  for (uint i = 0;  i < array_length; ++i) {
     assert( _surviving_young_words[i] == 0, "memset above" );
   }
 #endif // !ASSERT
@@ -3495,15 +3627,16 @@
 void
 G1CollectedHeap::update_surviving_young_words(size_t* surv_young_words) {
   MutexLockerEx x(ParGCRareEvent_lock, Mutex::_no_safepoint_check_flag);
-  size_t array_length = g1_policy()->young_cset_region_length();
-  for (size_t i = 0; i < array_length; ++i)
+  uint array_length = g1_policy()->young_cset_region_length();
+  for (uint i = 0; i < array_length; ++i) {
     _surviving_young_words[i] += surv_young_words[i];
+  }
 }
 
 void
 G1CollectedHeap::cleanup_surviving_young_words() {
   guarantee( _surviving_young_words != NULL, "pre-condition" );
-  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words);
+  FREE_C_HEAP_ARRAY(size_t, _surviving_young_words, mtGC);
   _surviving_young_words = NULL;
 }
 
@@ -3558,6 +3691,44 @@
 }
 #endif // TASKQUEUE_STATS
 
+void G1CollectedHeap::log_gc_header() {
+  if (!G1Log::fine()) {
+    return;
+  }
+
+  gclog_or_tty->date_stamp(PrintGCDateStamps);
+  gclog_or_tty->stamp(PrintGCTimeStamps);
+
+  GCCauseString gc_cause_str = GCCauseString("GC pause", gc_cause())
+    .append(g1_policy()->gcs_are_young() ? " (young)" : " (mixed)")
+    .append(g1_policy()->during_initial_mark_pause() ? " (initial-mark)" : "");
+
+  gclog_or_tty->print("[%s", (const char*)gc_cause_str);
+}
+
+void G1CollectedHeap::log_gc_footer(double pause_time_sec) {
+  if (!G1Log::fine()) {
+    return;
+  }
+
+  if (G1Log::finer()) {
+    if (evacuation_failed()) {
+      gclog_or_tty->print(" (to-space exhausted)");
+    }
+    gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec);
+    g1_policy()->phase_times()->note_gc_end();
+    g1_policy()->phase_times()->print(pause_time_sec);
+    g1_policy()->print_detailed_heap_transition();
+  } else {
+    if (evacuation_failed()) {
+      gclog_or_tty->print("--");
+    }
+    g1_policy()->print_heap_transition();
+    gclog_or_tty->print_cr(", %3.7f secs]", pause_time_sec);
+  }
+  gclog_or_tty->flush();
+}
+
 bool
 G1CollectedHeap::do_collection_pause_at_safepoint(double target_pause_time_ms) {
   assert_at_safepoint(true /* should_be_vm_thread */);
@@ -3595,26 +3766,18 @@
 
   // Inner scope for scope based logging, timers, and stats collection
   {
-    char verbose_str[128];
-    sprintf(verbose_str, "GC pause ");
-    if (g1_policy()->gcs_are_young()) {
-      strcat(verbose_str, "(young)");
-    } else {
-      strcat(verbose_str, "(mixed)");
-    }
     if (g1_policy()->during_initial_mark_pause()) {
-      strcat(verbose_str, " (initial-mark)");
       // We are about to start a marking cycle, so we increment the
       // full collection counter.
-      increment_total_full_collections();
+      increment_old_marking_cycles_started();
     }
+    TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
 
-    // if PrintGCDetails is on, we'll print long statistics information
-    // in the collector policy code, so let's not print this as the output
-    // is messy if we do.
-    gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
-    TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t(verbose_str, PrintGC && !PrintGCDetails, true, gclog_or_tty);
+    int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
+                                workers()->active_workers() : 1);
+    double pause_start_sec = os::elapsedTime();
+    g1_policy()->phase_times()->note_gc_start(active_workers);
+    log_gc_header();
 
     TraceCollectorStats tcs(g1mm()->incremental_collection_counters());
     TraceMemoryManagerStats tms(false /* fullGC */, gc_cause());
@@ -3643,14 +3806,7 @@
       increment_total_collections(false /* full gc */);
       increment_gc_time_stamp();
 
-      if (VerifyBeforeGC && total_collections() >= VerifyGCStartAt) {
-        HandleMark hm;  // Discard invalid handles created during verification
-        gclog_or_tty->print(" VerifyBeforeGC:");
-        prepare_for_verify();
-        Universe::verify(/* allow dirty */ false,
-                         /* silent      */ false,
-                         /* option      */ VerifyOption_G1UsePrevMarking);
-      }
+      verify_before_gc();
 
       COMPILER2_PRESENT(DerivedPointerTable::clear());
 
@@ -3678,9 +3834,15 @@
         // before the start GC event.
         _hr_printer.start_gc(false /* full */, (size_t) total_collections());
 
+        // This timing is only used by the ergonomics to handle our pause target.
+        // It is unclear why this should not include the full pause. We will
+        // investigate this in CR 7178365.
+        //
+        // Preserving the old comment here if that helps the investigation:
+        //
         // The elapsed time induced by the start time below deliberately elides
         // the possible verification above.
-        double start_time_sec = os::elapsedTime();
+        double sample_start_time_sec = os::elapsedTime();
         size_t start_used_bytes = used();
 
 #if YOUNG_LIST_VERBOSE
@@ -3689,7 +3851,7 @@
         g1_policy()->print_collection_set(g1_policy()->inc_cset_head(), gclog_or_tty);
 #endif // YOUNG_LIST_VERBOSE
 
-        g1_policy()->record_collection_pause_start(start_time_sec,
+        g1_policy()->record_collection_pause_start(sample_start_time_sec,
                                                    start_used_bytes);
 
         double scan_wait_start = os::elapsedTime();
@@ -3698,11 +3860,12 @@
         // objects on them have been correctly scanned before we start
         // moving them during the GC.
         bool waited = _cm->root_regions()->wait_until_scan_finished();
+        double wait_time_ms = 0.0;
         if (waited) {
           double scan_wait_end = os::elapsedTime();
-          double wait_time_ms = (scan_wait_end - scan_wait_start) * 1000.0;
-          g1_policy()->record_root_region_scan_wait_time(wait_time_ms);
+          wait_time_ms = (scan_wait_end - scan_wait_start) * 1000.0;
         }
+        g1_policy()->phase_times()->record_root_region_scan_wait_time(wait_time_ms);
 
 #if YOUNG_LIST_VERBOSE
         gclog_or_tty->print_cr("\nAfter recording pause start.\nYoung_list:");
@@ -3856,12 +4019,12 @@
                                  true  /* verify_fingers */);
         _cm->note_end_of_gc();
 
-        double end_time_sec = os::elapsedTime();
-        double pause_time_ms = (end_time_sec - start_time_sec) * MILLIUNITS;
-        g1_policy()->record_pause_time_ms(pause_time_ms);
-        int active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
-                                workers()->active_workers() : 1);
-        g1_policy()->record_collection_pause_end(active_workers);
+        // This timing is only used by the ergonomics to handle our pause target.
+        // It is unclear why this should not include the full pause. We will
+        // investigate this in CR 7178365.
+        double sample_end_time_sec = os::elapsedTime();
+        double pause_time_ms = (sample_end_time_sec - sample_start_time_sec) * MILLIUNITS;
+        g1_policy()->record_collection_pause_end(pause_time_ms);
 
         MemoryService::track_memory_usage();
 
@@ -3888,14 +4051,7 @@
         // scanning cards (see CR 7039627).
         increment_gc_time_stamp();
 
-        if (VerifyAfterGC && total_collections() >= VerifyGCStartAt) {
-          HandleMark hm;  // Discard invalid handles created during verification
-          gclog_or_tty->print(" VerifyAfterGC:");
-          prepare_for_verify();
-          Universe::verify(/* allow dirty */ true,
-                           /* silent      */ false,
-                           /* option      */ VerifyOption_G1UsePrevMarking);
-        }
+        verify_after_gc();
 
         assert(!ref_processor_stw()->discovery_enabled(), "Postcondition");
         ref_processor_stw()->verify_no_references_recorded();
@@ -3909,9 +4065,6 @@
       // RETIRE events are generated before the end GC event.
       _hr_printer.end_gc(false /* full */, (size_t) total_collections());
 
-      // We have to do this after we decide whether to expand the heap or not.
-      g1_policy()->print_heap_transition();
-
       if (mark_in_progress()) {
         concurrent_mark()->update_g1_committed();
       }
@@ -3923,31 +4076,29 @@
       gc_epilogue(false);
     }
 
-    if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) {
-      gclog_or_tty->print_cr("Stopping after GC #%d", ExitAfterGCNum);
-      print_tracing_info();
-      vm_exit(-1);
-    }
+    // Print the remainder of the GC log output.
+    log_gc_footer(os::elapsedTime() - pause_start_sec);
+
+    // It is not yet to safe to tell the concurrent mark to
+    // start as we have some optional output below. We don't want the
+    // output from the concurrent mark thread interfering with this
+    // logging output either.
+
+    _hrs.verify_optional();
+    verify_region_sets_optional();
+
+    TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats());
+    TASKQUEUE_STATS_ONLY(reset_taskqueue_stats());
+
+    print_heap_after_gc();
+
+    // We must call G1MonitoringSupport::update_sizes() in the same scoping level
+    // as an active TraceMemoryManagerStats object (i.e. before the destructor for the
+    // TraceMemoryManagerStats is called) so that the G1 memory pools are updated
+    // before any GC notifications are raised.
+    g1mm()->update_sizes();
   }
 
-  // The closing of the inner scope, immediately above, will complete
-  // the PrintGC logging output. The record_collection_pause_end() call
-  // above will complete the logging output of PrintGCDetails.
-  //
-  // It is not yet to safe, however, to tell the concurrent mark to
-  // start as we have some optional output below. We don't want the
-  // output from the concurrent mark thread interfering with this
-  // logging output either.
-
-  _hrs.verify_optional();
-  verify_region_sets_optional();
-
-  TASKQUEUE_STATS_ONLY(if (ParallelGCVerbose) print_taskqueue_stats());
-  TASKQUEUE_STATS_ONLY(reset_taskqueue_stats());
-
-  print_heap_after_gc();
-  g1mm()->update_sizes();
-
   if (G1SummarizeRSetStats &&
       (G1SummarizeRSetStatsPeriod > 0) &&
       (total_collections() % G1SummarizeRSetStatsPeriod == 0)) {
@@ -3977,17 +4128,22 @@
   size_t gclab_word_size;
   switch (purpose) {
     case GCAllocForSurvived:
-      gclab_word_size = YoungPLABSize;
+      gclab_word_size = _survivor_plab_stats.desired_plab_sz();
       break;
     case GCAllocForTenured:
-      gclab_word_size = OldPLABSize;
+      gclab_word_size = _old_plab_stats.desired_plab_sz();
       break;
     default:
       assert(false, "unknown GCAllocPurpose");
-      gclab_word_size = OldPLABSize;
+      gclab_word_size = _old_plab_stats.desired_plab_sz();
       break;
   }
-  return gclab_word_size;
+
+  // Prevent humongous PLAB sizes for two reasons:
+  // * PLABs are allocated using a similar paths as oops, but should
+  //   never be in a humongous region
+  // * Allowing humongous PLABs needlessly churns the region free lists
+  return MIN2(_humongous_object_threshold_in_words, gclab_word_size);
 }
 
 void G1CollectedHeap::init_mutator_alloc_region() {
@@ -4035,7 +4191,7 @@
   }
 }
 
-void G1CollectedHeap::release_gc_alloc_regions() {
+void G1CollectedHeap::release_gc_alloc_regions(uint no_of_gc_workers) {
   _survivor_gc_alloc_region.release();
   // If we have an old GC alloc region to release, we'll save it in
   // _retained_old_gc_alloc_region. If we don't
@@ -4043,6 +4199,11 @@
   // want either way so no reason to check explicitly for either
   // condition.
   _retained_old_gc_alloc_region = _old_gc_alloc_region.release();
+
+  if (ResizePLAB) {
+    _survivor_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
+    _old_plab_stats.adjust_desired_plab_sz(no_of_gc_workers);
+  }
 }
 
 void G1CollectedHeap::abandon_gc_alloc_regions() {
@@ -4054,7 +4215,7 @@
 void G1CollectedHeap::init_for_evac_failure(OopsInHeapRegionClosure* cl) {
   _drain_in_progress = false;
   set_evac_failure_closure(cl);
-  _evac_failure_scan_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
+  _evac_failure_scan_stack = new (ResourceObj::C_HEAP, mtGC) GrowableArray<oop>(40, true);
 }
 
 void G1CollectedHeap::finalize_for_evac_failure() {
@@ -4068,7 +4229,6 @@
 
 void G1CollectedHeap::remove_self_forwarding_pointers() {
   assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
-  assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!");
 
   G1ParRemoveSelfForwardPtrsTask rsfp_task(this);
 
@@ -4086,7 +4246,6 @@
   reset_cset_heap_region_claim_values();
 
   assert(check_cset_heap_region_claim_values(HeapRegion::InitialClaimValue), "sanity");
-  assert(g1_policy()->assertMarkedBytesDataOK(), "Should be!");
 
   // Now restore saved marks, if any.
   if (_objs_with_preserved_marks != NULL) {
@@ -4190,9 +4349,9 @@
     if (_objs_with_preserved_marks == NULL) {
       assert(_preserved_marks_of_objs == NULL, "Both or none.");
       _objs_with_preserved_marks =
-        new (ResourceObj::C_HEAP) GrowableArray<oop>(40, true);
+        new (ResourceObj::C_HEAP, mtGC) GrowableArray<oop>(40, true);
       _preserved_marks_of_objs =
-        new (ResourceObj::C_HEAP) GrowableArray<markOop>(40, true);
+        new (ResourceObj::C_HEAP, mtGC) GrowableArray<markOop>(40, true);
     }
     _objs_with_preserved_marks->push(obj);
     _preserved_marks_of_objs->push(m);
@@ -4248,16 +4407,16 @@
   // non-young regions (where the age is -1)
   // We also add a few elements at the beginning and at the end in
   // an attempt to eliminate cache contention
-  size_t real_length = 1 + _g1h->g1_policy()->young_cset_region_length();
-  size_t array_length = PADDING_ELEM_NUM +
-                        real_length +
-                        PADDING_ELEM_NUM;
-  _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length);
+  uint real_length = 1 + _g1h->g1_policy()->young_cset_region_length();
+  uint array_length = PADDING_ELEM_NUM +
+                      real_length +
+                      PADDING_ELEM_NUM;
+  _surviving_young_words_base = NEW_C_HEAP_ARRAY(size_t, array_length, mtGC);
   if (_surviving_young_words_base == NULL)
     vm_exit_out_of_memory(array_length * sizeof(size_t),
                           "Not enough space for young surv histo.");
   _surviving_young_words = _surviving_young_words_base + PADDING_ELEM_NUM;
-  memset(_surviving_young_words, 0, real_length * sizeof(size_t));
+  memset(_surviving_young_words, 0, (size_t) real_length * sizeof(size_t));
 
   _alloc_buffers[GCAllocForSurvived] = &_surviving_alloc_buffer;
   _alloc_buffers[GCAllocForTenured]  = &_tenured_alloc_buffer;
@@ -4355,7 +4514,8 @@
   _during_initial_mark(_g1->g1_policy()->during_initial_mark_pause()),
   _mark_in_progress(_g1->mark_in_progress()) { }
 
-void G1ParCopyHelper::mark_object(oop obj) {
+template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
+void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object>::mark_object(oop obj) {
 #ifdef ASSERT
   HeapRegion* hr = _g1->heap_region_containing(obj);
   assert(hr != NULL, "sanity");
@@ -4366,7 +4526,9 @@
   _cm->grayRoot(obj, (size_t) obj->size(), _worker_id);
 }
 
-void G1ParCopyHelper::mark_forwarded_object(oop from_obj, oop to_obj) {
+template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
+void G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object>
+  ::mark_forwarded_object(oop from_obj, oop to_obj) {
 #ifdef ASSERT
   assert(from_obj->is_forwarded(), "from obj should be forwarded");
   assert(from_obj->forwardee() == to_obj, "to obj should be the forwardee");
@@ -4388,8 +4550,10 @@
   _cm->grayRoot(to_obj, (size_t) from_obj->size(), _worker_id);
 }
 
-oop G1ParCopyHelper::copy_to_survivor_space(oop old) {
-  size_t    word_sz = old->size();
+template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
+oop G1ParCopyClosure<do_gen_barrier, barrier, do_mark_object>
+  ::copy_to_survivor_space(oop old) {
+  size_t word_sz = old->size();
   HeapRegion* from_region = _g1->heap_region_containing_raw(old);
   // +1 to make the -1 indexes valid...
   int       young_index = from_region->young_index_in_cset()+1;
@@ -4402,7 +4566,15 @@
   GCAllocPurpose alloc_purpose = g1p->evacuation_destination(from_region, age,
                                                              word_sz);
   HeapWord* obj_ptr = _par_scan_state->allocate(alloc_purpose, word_sz);
-  oop       obj     = oop(obj_ptr);
+#ifndef PRODUCT
+  // Should this evacuation fail?
+  if (_g1->evacuation_should_fail()) {
+    if (obj_ptr != NULL) {
+      _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz);
+      obj_ptr = NULL;
+    }
+  }
+#endif // !PRODUCT
 
   if (obj_ptr == NULL) {
     // This will either forward-to-self, or detect that someone else has
@@ -4411,6 +4583,8 @@
     return _g1->handle_evacuation_failure_par(cl, old);
   }
 
+  oop obj = oop(obj_ptr);
+
   // We're going to allocate linearly, so might as well prefetch ahead.
   Prefetch::write(obj_ptr, PrefetchCopyIntervalInBytes);
 
@@ -4457,8 +4631,8 @@
     } else {
       // No point in using the slower heap_region_containing() method,
       // given that we know obj is in the heap.
-      _scanner->set_region(_g1->heap_region_containing_raw(obj));
-      obj->oop_iterate_backwards(_scanner);
+      _scanner.set_region(_g1->heap_region_containing_raw(obj));
+      obj->oop_iterate_backwards(&_scanner);
     }
   } else {
     _par_scan_state->undo_allocation(alloc_purpose, obj_ptr, word_sz);
@@ -4673,76 +4847,141 @@
     if (worker_id >= _n_workers) return;  // no work needed this round
 
     double start_time_ms = os::elapsedTime() * 1000.0;
-    _g1h->g1_policy()->record_gc_worker_start_time(worker_id, start_time_ms);
-
-    ResourceMark rm;
-    HandleMark   hm;
-
-    ReferenceProcessor*             rp = _g1h->ref_processor_stw();
-
-    G1ParScanThreadState            pss(_g1h, worker_id);
-    G1ParScanHeapEvacClosure        scan_evac_cl(_g1h, &pss, rp);
-    G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp);
-    G1ParScanPartialArrayClosure    partial_scan_cl(_g1h, &pss, rp);
-
-    pss.set_evac_closure(&scan_evac_cl);
-    pss.set_evac_failure_closure(&evac_failure_cl);
-    pss.set_partial_scan_closure(&partial_scan_cl);
-
-    G1ParScanExtRootClosure        only_scan_root_cl(_g1h, &pss, rp);
-    G1ParScanPermClosure           only_scan_perm_cl(_g1h, &pss, rp);
-
-    G1ParScanAndMarkExtRootClosure scan_mark_root_cl(_g1h, &pss, rp);
-    G1ParScanAndMarkPermClosure    scan_mark_perm_cl(_g1h, &pss, rp);
-
-    OopClosure*                    scan_root_cl = &only_scan_root_cl;
-    OopsInHeapRegionClosure*       scan_perm_cl = &only_scan_perm_cl;
-
-    if (_g1h->g1_policy()->during_initial_mark_pause()) {
-      // We also need to mark copied objects.
-      scan_root_cl = &scan_mark_root_cl;
-      scan_perm_cl = &scan_mark_perm_cl;
-    }
-
-    G1ParPushHeapRSClosure          push_heap_rs_cl(_g1h, &pss);
-
-    pss.start_strong_roots();
-    _g1h->g1_process_strong_roots(/* not collecting perm */ false,
-                                  SharedHeap::SO_AllClasses,
-                                  scan_root_cl,
-                                  &push_heap_rs_cl,
-                                  scan_perm_cl,
-                                  worker_id);
-    pss.end_strong_roots();
+    _g1h->g1_policy()->phase_times()->record_gc_worker_start_time(worker_id, start_time_ms);
 
     {
-      double start = os::elapsedTime();
-      G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
-      evac.do_void();
-      double elapsed_ms = (os::elapsedTime()-start)*1000.0;
-      double term_ms = pss.term_time()*1000.0;
-      _g1h->g1_policy()->record_obj_copy_time(worker_id, elapsed_ms-term_ms);
-      _g1h->g1_policy()->record_termination(worker_id, term_ms, pss.term_attempts());
-    }
-    _g1h->g1_policy()->record_thread_age_table(pss.age_table());
-    _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
+      ResourceMark rm;
+      HandleMark   hm;
 
-    // Clean up any par-expanded rem sets.
-    HeapRegionRemSet::par_cleanup();
+      ReferenceProcessor*             rp = _g1h->ref_processor_stw();
 
-    if (ParallelGCVerbose) {
-      MutexLocker x(stats_lock());
-      pss.print_termination_stats(worker_id);
+      G1ParScanThreadState            pss(_g1h, worker_id);
+      G1ParScanHeapEvacClosure        scan_evac_cl(_g1h, &pss, rp);
+      G1ParScanHeapEvacFailureClosure evac_failure_cl(_g1h, &pss, rp);
+      G1ParScanPartialArrayClosure    partial_scan_cl(_g1h, &pss, rp);
+
+      pss.set_evac_closure(&scan_evac_cl);
+      pss.set_evac_failure_closure(&evac_failure_cl);
+      pss.set_partial_scan_closure(&partial_scan_cl);
+
+      G1ParScanExtRootClosure        only_scan_root_cl(_g1h, &pss, rp);
+      G1ParScanPermClosure           only_scan_perm_cl(_g1h, &pss, rp);
+
+      G1ParScanAndMarkExtRootClosure scan_mark_root_cl(_g1h, &pss, rp);
+      G1ParScanAndMarkPermClosure    scan_mark_perm_cl(_g1h, &pss, rp);
+
+      OopClosure*                    scan_root_cl = &only_scan_root_cl;
+      OopsInHeapRegionClosure*       scan_perm_cl = &only_scan_perm_cl;
+
+      if (_g1h->g1_policy()->during_initial_mark_pause()) {
+        // We also need to mark copied objects.
+        scan_root_cl = &scan_mark_root_cl;
+        scan_perm_cl = &scan_mark_perm_cl;
+      }
+
+      G1ParPushHeapRSClosure          push_heap_rs_cl(_g1h, &pss);
+
+      pss.start_strong_roots();
+      _g1h->g1_process_strong_roots(/* not collecting perm */ false,
+                                    SharedHeap::SO_AllClasses,
+                                    scan_root_cl,
+                                    &push_heap_rs_cl,
+                                    scan_perm_cl,
+                                    worker_id);
+      pss.end_strong_roots();
+
+      {
+        double start = os::elapsedTime();
+        G1ParEvacuateFollowersClosure evac(_g1h, &pss, _queues, &_terminator);
+        evac.do_void();
+        double elapsed_ms = (os::elapsedTime()-start)*1000.0;
+        double term_ms = pss.term_time()*1000.0;
+        _g1h->g1_policy()->phase_times()->add_obj_copy_time(worker_id, elapsed_ms-term_ms);
+        _g1h->g1_policy()->phase_times()->record_termination(worker_id, term_ms, pss.term_attempts());
+      }
+      _g1h->g1_policy()->record_thread_age_table(pss.age_table());
+      _g1h->update_surviving_young_words(pss.surviving_young_words()+1);
+
+      if (ParallelGCVerbose) {
+        MutexLocker x(stats_lock());
+        pss.print_termination_stats(worker_id);
+      }
+
+      assert(pss.refs()->is_empty(), "should be empty");
+
+      // Close the inner scope so that the ResourceMark and HandleMark
+      // destructors are executed here and are included as part of the
+      // "GC Worker Time".
     }
 
-    assert(pss.refs()->is_empty(), "should be empty");
     double end_time_ms = os::elapsedTime() * 1000.0;
-    _g1h->g1_policy()->record_gc_worker_end_time(worker_id, end_time_ms);
+    _g1h->g1_policy()->phase_times()->record_gc_worker_end_time(worker_id, end_time_ms);
   }
 };
 
 // *** Common G1 Evacuation Stuff
 
+// Closures that support the filtering of CodeBlobs scanned during
+// external root scanning.
+
+// Closure applied to reference fields in code blobs (specifically nmethods)
+// to determine whether an nmethod contains references that point into
+// the collection set. Used as a predicate when walking code roots so
+// that only nmethods that point into the collection set are added to the
+// 'marked' list.
+
+class G1FilteredCodeBlobToOopClosure : public CodeBlobToOopClosure {
+
+  class G1PointsIntoCSOopClosure : public OopClosure {
+    G1CollectedHeap* _g1;
+    bool _points_into_cs;
+  public:
+    G1PointsIntoCSOopClosure(G1CollectedHeap* g1) :
+      _g1(g1), _points_into_cs(false) { }
+
+    bool points_into_cs() const { return _points_into_cs; }
+
+    template <class T>
+    void do_oop_nv(T* p) {
+      if (!_points_into_cs) {
+        T heap_oop = oopDesc::load_heap_oop(p);
+        if (!oopDesc::is_null(heap_oop) &&
+            _g1->in_cset_fast_test(oopDesc::decode_heap_oop_not_null(heap_oop))) {
+          _points_into_cs = true;
+        }
+      }
+    }
+
+    virtual void do_oop(oop* p)        { do_oop_nv(p); }
+    virtual void do_oop(narrowOop* p)  { do_oop_nv(p); }
+  };
+
+  G1CollectedHeap* _g1;
+
+public:
+  G1FilteredCodeBlobToOopClosure(G1CollectedHeap* g1, OopClosure* cl) :
+    CodeBlobToOopClosure(cl, true), _g1(g1) { }
+
+  virtual void do_code_blob(CodeBlob* cb) {
+    nmethod* nm = cb->as_nmethod_or_null();
+    if (nm != NULL && !(nm->test_oops_do_mark())) {
+      G1PointsIntoCSOopClosure predicate_cl(_g1);
+      nm->oops_do(&predicate_cl);
+
+      if (predicate_cl.points_into_cs()) {
+        // At least one of the reference fields or the oop relocations
+        // in the nmethod points into the collection set. We have to
+        // 'mark' this nmethod.
+        // Note: Revisit the following if CodeBlobToOopClosure::do_code_blob()
+        // or MarkingCodeBlobClosure::do_code_blob() change.
+        if (!nm->test_set_oops_do_mark()) {
+          do_newly_marked_nmethod(nm);
+        }
+      }
+    }
+  }
+};
+
 // This method is run in a GC worker.
 
 void
@@ -4764,7 +5003,7 @@
 
   // Walk the code cache w/o buffering, because StarTask cannot handle
   // unaligned oop locations.
-  CodeBlobToOopClosure eager_scan_code_roots(scan_non_heap_roots, /*do_marking=*/ true);
+  G1FilteredCodeBlobToOopClosure eager_scan_code_roots(this, scan_non_heap_roots);
 
   process_strong_roots(false, // no scoping; this is parallel code
                        collecting_perm_gen, so,
@@ -4785,28 +5024,29 @@
   buf_scan_non_heap_roots.done();
   buf_scan_perm.done();
 
-  double ext_roots_end = os::elapsedTime();
-
-  g1_policy()->reset_obj_copy_time(worker_i);
   double obj_copy_time_sec = buf_scan_perm.closure_app_seconds() +
                                 buf_scan_non_heap_roots.closure_app_seconds();
-  g1_policy()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
+  g1_policy()->phase_times()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
 
   double ext_root_time_ms =
-    ((ext_roots_end - ext_roots_start) - obj_copy_time_sec) * 1000.0;
+    ((os::elapsedTime() - ext_roots_start) - obj_copy_time_sec) * 1000.0;
 
-  g1_policy()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
+  g1_policy()->phase_times()->record_ext_root_scan_time(worker_i, ext_root_time_ms);
 
   // During conc marking we have to filter the per-thread SATB buffers
   // to make sure we remove any oops into the CSet (which will show up
   // as implicitly live).
+  double satb_filtering_ms = 0.0;
   if (!_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers)) {
     if (mark_in_progress()) {
+      double satb_filter_start = os::elapsedTime();
+
       JavaThread::satb_mark_queue_set().filter_thread_buffers();
+
+      satb_filtering_ms = (os::elapsedTime() - satb_filter_start) * 1000.0;
     }
   }
-  double satb_filtering_ms = (os::elapsedTime() - ext_roots_end) * 1000.0;
-  g1_policy()->record_satb_filtering_time(worker_i, satb_filtering_ms);
+  g1_policy()->phase_times()->record_satb_filtering_time(worker_i, satb_filtering_ms);
 
   // Now scan the complement of the collection set.
   if (scan_rs != NULL) {
@@ -5191,7 +5431,7 @@
 };
 
 // Weak Reference processing during an evacuation pause (part 1).
-void G1CollectedHeap::process_discovered_references() {
+void G1CollectedHeap::process_discovered_references(uint no_of_gc_workers) {
   double ref_proc_start = os::elapsedTime();
 
   ReferenceProcessor* rp = _ref_processor_stw;
@@ -5218,15 +5458,14 @@
   // referents points to another object which is also referenced by an
   // object discovered by the STW ref processor.
 
-  uint active_workers = (G1CollectedHeap::use_parallel_gc_threads() ?
-                        workers()->active_workers() : 1);
-
   assert(!G1CollectedHeap::use_parallel_gc_threads() ||
-           active_workers == workers()->active_workers(),
-           "Need to reset active_workers");
+           no_of_gc_workers == workers()->active_workers(),
+           "Need to reset active GC workers");
 
-  set_par_threads(active_workers);
-  G1ParPreserveCMReferentsTask keep_cm_referents(this, active_workers, _task_queues);
+  set_par_threads(no_of_gc_workers);
+  G1ParPreserveCMReferentsTask keep_cm_referents(this,
+                                                 no_of_gc_workers,
+                                                 _task_queues);
 
   if (G1CollectedHeap::use_parallel_gc_threads()) {
     workers()->run_task(&keep_cm_referents);
@@ -5292,10 +5531,10 @@
                                       NULL);
   } else {
     // Parallel reference processing
-    assert(rp->num_q() == active_workers, "sanity");
-    assert(active_workers <= rp->max_num_q(), "sanity");
+    assert(rp->num_q() == no_of_gc_workers, "sanity");
+    assert(no_of_gc_workers <= rp->max_num_q(), "sanity");
 
-    G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, active_workers);
+    G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers);
     rp->process_discovered_references(&is_alive, &keep_alive, &drain_queue, &par_task_executor);
   }
 
@@ -5306,11 +5545,11 @@
   assert(pss.refs()->is_empty(), "both queue and overflow should be empty");
 
   double ref_proc_time = os::elapsedTime() - ref_proc_start;
-  g1_policy()->record_ref_proc_time(ref_proc_time * 1000.0);
+  g1_policy()->phase_times()->record_ref_proc_time(ref_proc_time * 1000.0);
 }
 
 // Weak Reference processing during an evacuation pause (part 2).
-void G1CollectedHeap::enqueue_discovered_references() {
+void G1CollectedHeap::enqueue_discovered_references(uint no_of_gc_workers) {
   double ref_enq_start = os::elapsedTime();
 
   ReferenceProcessor* rp = _ref_processor_stw;
@@ -5324,13 +5563,12 @@
   } else {
     // Parallel reference enqueuing
 
-    uint active_workers = (ParallelGCThreads > 0 ? workers()->active_workers() : 1);
-    assert(active_workers == workers()->active_workers(),
-           "Need to reset active_workers");
-    assert(rp->num_q() == active_workers, "sanity");
-    assert(active_workers <= rp->max_num_q(), "sanity");
+    assert(no_of_gc_workers == workers()->active_workers(),
+           "Need to reset active workers");
+    assert(rp->num_q() == no_of_gc_workers, "sanity");
+    assert(no_of_gc_workers <= rp->max_num_q(), "sanity");
 
-    G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, active_workers);
+    G1STWRefProcTaskExecutor par_task_executor(this, workers(), _task_queues, no_of_gc_workers);
     rp->enqueue_discovered_references(&par_task_executor);
   }
 
@@ -5343,13 +5581,16 @@
   // and could signicantly increase the pause time.
 
   double ref_enq_time = os::elapsedTime() - ref_enq_start;
-  g1_policy()->record_ref_enq_time(ref_enq_time * 1000.0);
+  g1_policy()->phase_times()->record_ref_enq_time(ref_enq_time * 1000.0);
 }
 
 void G1CollectedHeap::evacuate_collection_set() {
   _expand_heap_after_alloc_failure = true;
   set_evacuation_failed(false);
 
+  // Should G1EvacuationFailureALot be in effect for this GC?
+  NOT_PRODUCT(set_evacuation_failure_alot_for_current_gc();)
+
   g1_rem_set()->prepare_for_oops_into_collection_set_do();
   concurrent_g1_refine()->set_use_cache(false);
   concurrent_g1_refine()->clear_hot_cache_claimed_index();
@@ -5378,25 +5619,39 @@
   rem_set()->prepare_for_younger_refs_iterate(true);
 
   assert(dirty_card_queue_set().completed_buffers_num() == 0, "Should be empty");
-  double start_par = os::elapsedTime();
+  double start_par_time_sec = os::elapsedTime();
+  double end_par_time_sec;
 
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    // The individual threads will set their evac-failure closures.
+  {
     StrongRootsScope srs(this);
-    if (ParallelGCVerbose) G1ParScanThreadState::print_termination_stats_hdr();
-    // These tasks use ShareHeap::_process_strong_tasks
-    assert(UseDynamicNumberOfGCThreads ||
-           workers()->active_workers() == workers()->total_workers(),
-           "If not dynamic should be using all the  workers");
-    workers()->run_task(&g1_par_task);
-  } else {
-    StrongRootsScope srs(this);
-    g1_par_task.set_for_termination(n_workers);
-    g1_par_task.work(0);
+
+    if (G1CollectedHeap::use_parallel_gc_threads()) {
+      // The individual threads will set their evac-failure closures.
+      if (ParallelGCVerbose) G1ParScanThreadState::print_termination_stats_hdr();
+      // These tasks use ShareHeap::_process_strong_tasks
+      assert(UseDynamicNumberOfGCThreads ||
+             workers()->active_workers() == workers()->total_workers(),
+             "If not dynamic should be using all the  workers");
+      workers()->run_task(&g1_par_task);
+    } else {
+      g1_par_task.set_for_termination(n_workers);
+      g1_par_task.work(0);
+    }
+    end_par_time_sec = os::elapsedTime();
+
+    // Closing the inner scope will execute the destructor
+    // for the StrongRootsScope object. We record the current
+    // elapsed time before closing the scope so that time
+    // taken for the SRS destructor is NOT included in the
+    // reported parallel time.
   }
 
-  double par_time = (os::elapsedTime() - start_par) * 1000.0;
-  g1_policy()->record_par_time(par_time);
+  double par_time_ms = (end_par_time_sec - start_par_time_sec) * 1000.0;
+  g1_policy()->phase_times()->record_par_time(par_time_ms);
+
+  double code_root_fixup_time_ms =
+        (os::elapsedTime() - end_par_time_sec) * 1000.0;
+  g1_policy()->phase_times()->record_code_root_fixup_time(code_root_fixup_time_ms);
 
   set_par_threads(0);
 
@@ -5405,7 +5660,7 @@
   // as we may have to copy some 'reachable' referent
   // objects (and their reachable sub-graphs) that were
   // not copied during the pause.
-  process_discovered_references();
+  process_discovered_references(n_workers);
 
   // Weak root processing.
   // Note: when JSR 292 is enabled and code blobs can contain
@@ -5417,7 +5672,7 @@
     JNIHandles::weak_oops_do(&is_alive, &keep_alive);
   }
 
-  release_gc_alloc_regions();
+  release_gc_alloc_regions(n_workers);
   g1_rem_set()->cleanup_after_oops_into_collection_set_do();
 
   concurrent_g1_refine()->clear_hot_cache();
@@ -5427,11 +5682,11 @@
 
   if (evacuation_failed()) {
     remove_self_forwarding_pointers();
-    if (PrintGCDetails) {
-      gclog_or_tty->print(" (to-space overflow)");
-    } else if (PrintGC) {
-      gclog_or_tty->print("--");
-    }
+
+    // Reset the G1EvacuationFailureALot counters and flags
+    // Note: the values are reset only when an actual
+    // evacuation failure occurs.
+    NOT_PRODUCT(reset_evacuation_should_fail();)
   }
 
   // Enqueue any remaining references remaining on the STW
@@ -5441,7 +5696,7 @@
   // will log these updates (and dirty their associated
   // cards). We need these updates logged to update any
   // RSets.
-  enqueue_discovered_references();
+  enqueue_discovered_references(n_workers);
 
   if (G1DeferredRSUpdate) {
     RedirtyLoggedCardTableEntryFastClosure redirty;
@@ -5501,19 +5756,18 @@
   size_t hr_capacity = hr->capacity();
   size_t hr_pre_used = 0;
   _humongous_set.remove_with_proxy(hr, humongous_proxy_set);
+  // We need to read this before we make the region non-humongous,
+  // otherwise the information will be gone.
+  uint last_index = hr->last_hc_index();
   hr->set_notHumongous();
   free_region(hr, &hr_pre_used, free_list, par);
 
-  size_t i = hr->hrs_index() + 1;
-  size_t num = 1;
-  while (i < n_regions()) {
+  uint i = hr->hrs_index() + 1;
+  while (i < last_index) {
     HeapRegion* curr_hr = region_at(i);
-    if (!curr_hr->continuesHumongous()) {
-      break;
-    }
+    assert(curr_hr->continuesHumongous(), "invariant");
     curr_hr->set_notHumongous();
     free_region(curr_hr, &hr_pre_used, free_list, par);
-    num += 1;
     i += 1;
   }
   assert(hr_pre_used == hr_used,
@@ -5621,7 +5875,6 @@
 
 void G1CollectedHeap::verify_dirty_young_regions() {
   verify_dirty_young_list(_young_list->first_region());
-  verify_dirty_young_list(_young_list->first_survivor_region());
 }
 #endif
 
@@ -5658,7 +5911,7 @@
   }
 
   double elapsed = os::elapsedTime() - start;
-  g1_policy()->record_clear_ct_time(elapsed * 1000.0);
+  g1_policy()->phase_times()->record_clear_ct_time(elapsed * 1000.0);
 }
 
 void G1CollectedHeap::free_collection_set(HeapRegion* cs_head) {
@@ -5714,7 +5967,7 @@
     if (cur->is_young()) {
       int index = cur->young_index_in_cset();
       assert(index != -1, "invariant");
-      assert((size_t) index < policy->young_cset_region_length(), "invariant");
+      assert((uint) index < policy->young_cset_region_length(), "invariant");
       size_t words_survived = _surviving_young_words[index];
       cur->record_surv_words_in_group(words_survived);
 
@@ -5767,8 +6020,8 @@
                                     NULL /* old_proxy_set */,
                                     NULL /* humongous_proxy_set */,
                                     false /* par */);
-  policy->record_young_free_cset_time_ms(young_time_ms);
-  policy->record_non_young_free_cset_time_ms(non_young_time_ms);
+  policy->phase_times()->record_young_free_cset_time_ms(young_time_ms);
+  policy->phase_times()->record_non_young_free_cset_time_ms(non_young_time_ms);
 }
 
 // This routine is similar to the above but does not record
@@ -6054,7 +6307,7 @@
 // Methods for the GC alloc regions
 
 HeapRegion* G1CollectedHeap::new_gc_alloc_region(size_t word_size,
-                                                 size_t count,
+                                                 uint count,
                                                  GCAllocPurpose ap) {
   assert(FreeList_lock->owned_by_self(), "pre-condition");
 
@@ -6126,7 +6379,7 @@
   FreeRegionList*     _free_list;
   OldRegionSet*       _old_set;
   HumongousRegionSet* _humongous_set;
-  size_t              _region_count;
+  uint                _region_count;
 
 public:
   VerifyRegionListsClosure(OldRegionSet* old_set,
@@ -6135,7 +6388,7 @@
     _old_set(old_set), _humongous_set(humongous_set),
     _free_list(free_list), _region_count(0) { }
 
-  size_t region_count()      { return _region_count;      }
+  uint region_count() { return _region_count; }
 
   bool doHeapRegion(HeapRegion* hr) {
     _region_count += 1;
@@ -6157,7 +6410,7 @@
   }
 };
 
-HeapRegion* G1CollectedHeap::new_heap_region(size_t hrs_index,
+HeapRegion* G1CollectedHeap::new_heap_region(uint hrs_index,
                                              HeapWord* bottom) {
   HeapWord* end = bottom + HeapRegion::GrainWords;
   MemRegion mr(bottom, end);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
index c1ccc4f..b8a2826 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp
@@ -33,7 +33,7 @@
 #include "gc_implementation/g1/heapRegionSeq.hpp"
 #include "gc_implementation/g1/heapRegionSets.hpp"
 #include "gc_implementation/shared/hSpaceCounters.hpp"
-#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "memory/barrierSet.hpp"
 #include "memory/memRegion.hpp"
 #include "memory/sharedHeap.hpp"
@@ -62,8 +62,8 @@
 class ConcurrentG1Refine;
 class GenerationCounters;
 
-typedef OverflowTaskQueue<StarTask>         RefToScanQueue;
-typedef GenericTaskQueueSet<RefToScanQueue> RefToScanQueueSet;
+typedef OverflowTaskQueue<StarTask, mtGC>         RefToScanQueue;
+typedef GenericTaskQueueSet<RefToScanQueue, mtGC> RefToScanQueueSet;
 
 typedef int RegionIdx_t;   // needs to hold [ 0..max_regions() )
 typedef int CardIdx_t;     // needs to hold [ 0..CardsPerRegion )
@@ -74,7 +74,7 @@
   GCAllocPurposeCount
 };
 
-class YoungList : public CHeapObj {
+class YoungList : public CHeapObj<mtGC> {
 private:
   G1CollectedHeap* _g1h;
 
@@ -85,8 +85,8 @@
 
   HeapRegion* _curr;
 
-  size_t      _length;
-  size_t      _survivor_length;
+  uint        _length;
+  uint        _survivor_length;
 
   size_t      _last_sampled_rs_lengths;
   size_t      _sampled_rs_lengths;
@@ -101,8 +101,8 @@
 
   void         empty_list();
   bool         is_empty() { return _length == 0; }
-  size_t       length() { return _length; }
-  size_t       survivor_length() { return _survivor_length; }
+  uint         length() { return _length; }
+  uint         survivor_length() { return _survivor_length; }
 
   // Currently we do not keep track of the used byte sum for the
   // young list and the survivors and it'd be quite a lot of work to
@@ -111,10 +111,10 @@
   // we'll report the more accurate information then.
   size_t       eden_used_bytes() {
     assert(length() >= survivor_length(), "invariant");
-    return (length() - survivor_length()) * HeapRegion::GrainBytes;
+    return (size_t) (length() - survivor_length()) * HeapRegion::GrainBytes;
   }
   size_t       survivor_used_bytes() {
-    return survivor_length() * HeapRegion::GrainBytes;
+    return (size_t) survivor_length() * HeapRegion::GrainBytes;
   }
 
   void rs_length_sampling_init();
@@ -199,7 +199,8 @@
   friend class OldGCAllocRegion;
 
   // Closures used in implementation.
-  friend class G1ParCopyHelper;
+  template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
+  friend class G1ParCopyClosure;
   friend class G1IsAliveClosure;
   friend class G1EvacuateFollowersClosure;
   friend class G1ParScanThreadState;
@@ -246,7 +247,7 @@
   MasterHumongousRegionSet  _humongous_set;
 
   // The number of regions we could create by expansion.
-  size_t _expansion_regions;
+  uint _expansion_regions;
 
   // The block offset table for the G1 heap.
   G1BlockOffsetSharedArray* _bot_shared;
@@ -277,10 +278,33 @@
   // survivor objects.
   SurvivorGCAllocRegion _survivor_gc_alloc_region;
 
+  // PLAB sizing policy for survivors.
+  PLABStats _survivor_plab_stats;
+
   // Alloc region used to satisfy allocation requests by the GC for
   // old objects.
   OldGCAllocRegion _old_gc_alloc_region;
 
+  // PLAB sizing policy for tenured objects.
+  PLABStats _old_plab_stats;
+
+  PLABStats* stats_for_purpose(GCAllocPurpose purpose) {
+    PLABStats* stats = NULL;
+
+    switch (purpose) {
+    case GCAllocForSurvived:
+      stats = &_survivor_plab_stats;
+      break;
+    case GCAllocForTenured:
+      stats = &_old_plab_stats;
+      break;
+    default:
+      assert(false, "unrecognized GCAllocPurpose");
+    }
+
+    return stats;
+  }
+
   // The last old region we allocated to during the last GC.
   // Typically, it is not full so we should re-use it during the next GC.
   HeapRegion* _retained_old_gc_alloc_region;
@@ -303,7 +327,7 @@
   void init_gc_alloc_regions();
 
   // It releases the GC alloc regions at the end of a GC.
-  void release_gc_alloc_regions();
+  void release_gc_alloc_regions(uint no_of_gc_workers);
 
   // It does any cleanup that needs to be done on the GC alloc regions
   // before a Full GC.
@@ -313,7 +337,7 @@
   G1MonitoringSupport* _g1mm;
 
   // Determines PLAB size for a particular allocation purpose.
-  static size_t desired_plab_sz(GCAllocPurpose purpose);
+  size_t desired_plab_sz(GCAllocPurpose purpose);
 
   // Outside of GC pauses, the number of bytes used in all regions other
   // than the current allocation region.
@@ -338,7 +362,7 @@
   bool* _in_cset_fast_test_base;
 
   // The length of the _in_cset_fast_test_base array.
-  size_t _in_cset_fast_test_length;
+  uint _in_cset_fast_test_length;
 
   volatile unsigned _gc_time_stamp;
 
@@ -358,10 +382,13 @@
   // (c) cause == _g1_humongous_allocation
   bool should_do_concurrent_full_gc(GCCause::Cause cause);
 
-  // Keeps track of how many "full collections" (i.e., Full GCs or
-  // concurrent cycles) we have completed. The number of them we have
-  // started is maintained in _total_full_collections in CollectedHeap.
-  volatile unsigned int _full_collections_completed;
+  // Keeps track of how many "old marking cycles" (i.e., Full GCs or
+  // concurrent cycles) we have started.
+  volatile unsigned int _old_marking_cycles_started;
+
+  // Keeps track of how many "old marking cycles" (i.e., Full GCs or
+  // concurrent cycles) we have completed.
+  volatile unsigned int _old_marking_cycles_completed;
 
   // This is a non-product method that is helpful for testing. It is
   // called at the end of a GC and artificially expands the heap by
@@ -371,6 +398,20 @@
   // this method will be found dead by the marking cycle).
   void allocate_dummy_regions() PRODUCT_RETURN;
 
+  // Clear RSets after a compaction. It also resets the GC time stamps.
+  void clear_rsets_post_compaction();
+
+  // If the HR printer is active, dump the state of the regions in the
+  // heap after a compaction.
+  void print_hrs_post_compaction();
+
+  double verify(bool guard, const char* msg);
+  void verify_before_gc();
+  void verify_after_gc();
+
+  void log_gc_header();
+  void log_gc_footer(double pause_time_sec);
+
   // These are macros so that, if the assert fires, we get the correct
   // line number, file, etc.
 
@@ -457,14 +498,14 @@
   // length and remove them from the master free list. Return the
   // index of the first region or G1_NULL_HRS_INDEX if the search
   // was unsuccessful.
-  size_t humongous_obj_allocate_find_first(size_t num_regions,
-                                           size_t word_size);
+  uint humongous_obj_allocate_find_first(uint num_regions,
+                                         size_t word_size);
 
   // Initialize a contiguous set of free regions of length num_regions
   // and starting at index first so that they appear as a single
   // humongous region.
-  HeapWord* humongous_obj_allocate_initialize_regions(size_t first,
-                                                      size_t num_regions,
+  HeapWord* humongous_obj_allocate_initialize_regions(uint first,
+                                                      uint num_regions,
                                                       size_t word_size);
 
   // Attempt to allocate a humongous object of the given size. Return
@@ -573,7 +614,7 @@
                                    size_t allocated_bytes);
 
   // For GC alloc regions.
-  HeapRegion* new_gc_alloc_region(size_t word_size, size_t count,
+  HeapRegion* new_gc_alloc_region(size_t word_size, uint count,
                                   GCAllocPurpose ap);
   void retire_gc_alloc_region(HeapRegion* alloc_region,
                               size_t allocated_bytes, GCAllocPurpose ap);
@@ -612,11 +653,11 @@
 
   // Process any reference objects discovered during
   // an incremental evacuation pause.
-  void process_discovered_references();
+  void process_discovered_references(uint no_of_gc_workers);
 
   // Enqueue any remaining discovered references
   // after processing.
-  void enqueue_discovered_references();
+  void enqueue_discovered_references(uint no_of_gc_workers);
 
 public:
 
@@ -640,7 +681,7 @@
   void register_region_with_in_cset_fast_test(HeapRegion* r) {
     assert(_in_cset_fast_test_base != NULL, "sanity");
     assert(r->in_collection_set(), "invariant");
-    size_t index = r->hrs_index();
+    uint index = r->hrs_index();
     assert(index < _in_cset_fast_test_length, "invariant");
     assert(!_in_cset_fast_test_base[index], "invariant");
     _in_cset_fast_test_base[index] = true;
@@ -654,7 +695,7 @@
     if (_g1_committed.contains((HeapWord*) obj)) {
       // no need to subtract the bottom of the heap from obj,
       // _in_cset_fast_test is biased
-      size_t index = ((size_t) obj) >> HeapRegion::LogOfHRGrainBytes;
+      uintx index = (uintx) obj >> HeapRegion::LogOfHRGrainBytes;
       bool ret = _in_cset_fast_test[index];
       // let's make sure the result is consistent with what the slower
       // test returns
@@ -669,11 +710,15 @@
   void clear_cset_fast_test() {
     assert(_in_cset_fast_test_base != NULL, "sanity");
     memset(_in_cset_fast_test_base, false,
-        _in_cset_fast_test_length * sizeof(bool));
+           (size_t) _in_cset_fast_test_length * sizeof(bool));
   }
 
+  // This is called at the start of either a concurrent cycle or a Full
+  // GC to update the number of old marking cycles started.
+  void increment_old_marking_cycles_started();
+
   // This is called at the end of either a concurrent cycle or a Full
-  // GC to update the number of full collections completed. Those two
+  // GC to update the number of old marking cycles completed. Those two
   // can happen in a nested fashion, i.e., we start a concurrent
   // cycle, a Full GC happens half-way through it which ends first,
   // and then the cycle notices that a Full GC happened and ends
@@ -682,14 +727,14 @@
   // false, the caller is the inner caller in the nesting (i.e., the
   // Full GC). If concurrent is true, the caller is the outer caller
   // in this nesting (i.e., the concurrent cycle). Further nesting is
-  // not currently supported. The end of the this call also notifies
+  // not currently supported. The end of this call also notifies
   // the FullGCCount_lock in case a Java thread is waiting for a full
   // GC to happen (e.g., it called System.gc() with
   // +ExplicitGCInvokesConcurrent).
-  void increment_full_collections_completed(bool concurrent);
+  void increment_old_marking_cycles_completed(bool concurrent);
 
-  unsigned int full_collections_completed() {
-    return _full_collections_completed;
+  unsigned int old_marking_cycles_completed() {
+    return _old_marking_cycles_completed;
   }
 
   G1HRPrinter* hr_printer() { return &_hr_printer; }
@@ -873,6 +918,39 @@
   oop handle_evacuation_failure_par(OopsInHeapRegionClosure* cl, oop obj);
   void handle_evacuation_failure_common(oop obj, markOop m);
 
+#ifndef PRODUCT
+  // Support for forcing evacuation failures. Analogous to
+  // PromotionFailureALot for the other collectors.
+
+  // Records whether G1EvacuationFailureALot should be in effect
+  // for the current GC
+  bool _evacuation_failure_alot_for_current_gc;
+
+  // Used to record the GC number for interval checking when
+  // determining whether G1EvaucationFailureALot is in effect
+  // for the current GC.
+  size_t _evacuation_failure_alot_gc_number;
+
+  // Count of the number of evacuations between failures.
+  volatile size_t _evacuation_failure_alot_count;
+
+  // Set whether G1EvacuationFailureALot should be in effect
+  // for the current GC (based upon the type of GC and which
+  // command line flags are set);
+  inline bool evacuation_failure_alot_for_gc_type(bool gcs_are_young,
+                                                  bool during_initial_mark,
+                                                  bool during_marking);
+
+  inline void set_evacuation_failure_alot_for_current_gc();
+
+  // Return true if it's time to cause an evacuation failure.
+  inline bool evacuation_should_fail();
+
+  // Reset the G1EvacuationFailureALot counters.  Should be called at
+  // the end of an evacuation pause in which an evacuation failure ocurred.
+  inline void reset_evacuation_should_fail();
+#endif // !PRODUCT
+
   // ("Weak") Reference processing support.
   //
   // G1 has 2 instances of the referece processor class. One
@@ -1053,11 +1131,18 @@
     clear_cset_start_regions();
   }
 
+  void check_gc_time_stamps() PRODUCT_RETURN;
+
   void increment_gc_time_stamp() {
     ++_gc_time_stamp;
     OrderAccess::fence();
   }
 
+  // Reset the given region's GC timestamp. If it's starts humongous,
+  // also reset the GC timestamp of its corresponding
+  // continues humongous regions too.
+  void reset_gc_time_stamps(HeapRegion* hr);
+
   void iterate_dirty_card_closure(CardTableEntryClosure* cl,
                                   DirtyCardQueue* into_cset_dcq,
                                   bool concurrent, int worker_i);
@@ -1100,23 +1185,23 @@
   }
 
   // The total number of regions in the heap.
-  size_t n_regions() { return _hrs.length(); }
+  uint n_regions() { return _hrs.length(); }
 
   // The max number of regions in the heap.
-  size_t max_regions() { return _hrs.max_length(); }
+  uint max_regions() { return _hrs.max_length(); }
 
   // The number of regions that are completely free.
-  size_t free_regions() { return _free_list.length(); }
+  uint free_regions() { return _free_list.length(); }
 
   // The number of regions that are not completely free.
-  size_t used_regions() { return n_regions() - free_regions(); }
+  uint used_regions() { return n_regions() - free_regions(); }
 
   // The number of regions available for "regular" expansion.
-  size_t expansion_regions() { return _expansion_regions; }
+  uint expansion_regions() { return _expansion_regions; }
 
   // Factory method for HeapRegion instances. It will return NULL if
   // the allocation fails.
-  HeapRegion* new_heap_region(size_t hrs_index, HeapWord* bottom);
+  HeapRegion* new_heap_region(uint hrs_index, HeapWord* bottom);
 
   void verify_not_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
   void verify_dirty_region(HeapRegion* hr) PRODUCT_RETURN;
@@ -1294,13 +1379,8 @@
   // iteration early if the "doHeapRegion" method returns "true".
   void heap_region_iterate(HeapRegionClosure* blk) const;
 
-  // Iterate over heap regions starting with r (or the first region if "r"
-  // is NULL), in address order, terminating early if the "doHeapRegion"
-  // method returns "true".
-  void heap_region_iterate_from(HeapRegion* r, HeapRegionClosure* blk) const;
-
   // Return the region with the given index. It assumes the index is valid.
-  HeapRegion* region_at(size_t index) const { return _hrs.at(index); }
+  HeapRegion* region_at(uint index) const { return _hrs.at(index); }
 
   // Divide the heap region sequence into "chunks" of some size (the number
   // of regions divided by the number of parallel threads times some
@@ -1343,6 +1423,11 @@
   // starting region for iterating over the current collection set.
   HeapRegion* start_cset_region_for_worker(int worker_i);
 
+  // This is a convenience method that is used by the
+  // HeapRegionIterator classes to calculate the starting region for
+  // each worker so that they do not all start from the same region.
+  HeapRegion* start_region_for_worker(uint worker_i, uint no_of_par_workers);
+
   // Iterate over the regions (if any) in the current collection set.
   void collection_set_iterate(HeapRegionClosure* blk);
 
@@ -1503,10 +1588,10 @@
   // Currently there is only one place where this is called with
   // vo == UseMarkWord, which is to verify the marking during a
   // full GC.
-  void verify(bool allow_dirty, bool silent, VerifyOption vo);
+  void verify(bool silent, VerifyOption vo);
 
   // Override; it uses the "prev" marking information
-  virtual void verify(bool allow_dirty, bool silent);
+  virtual void verify(bool silent);
   virtual void print_on(outputStream* st) const;
   virtual void print_extended_on(outputStream* st) const;
 
@@ -1550,24 +1635,6 @@
   bool isMarkedPrev(oop obj) const;
   bool isMarkedNext(oop obj) const;
 
-  // vo == UsePrevMarking -> use "prev" marking information,
-  // vo == UseNextMarking -> use "next" marking information,
-  // vo == UseMarkWord    -> use mark word from object header
-  bool is_obj_dead_cond(const oop obj,
-                        const HeapRegion* hr,
-                        const VerifyOption vo) const {
-
-    switch (vo) {
-      case VerifyOption_G1UsePrevMarking:
-        return is_obj_dead(obj, hr);
-      case VerifyOption_G1UseNextMarking:
-        return is_obj_ill(obj, hr);
-      default:
-        assert(vo == VerifyOption_G1UseMarkWord, "must be");
-        return !obj->is_gc_marked();
-    }
-  }
-
   // Determine if an object is dead, given the object and also
   // the region to which the object belongs. An object is dead
   // iff a) it was not allocated since the last mark and b) it
@@ -1579,15 +1646,6 @@
       !isMarkedPrev(obj);
   }
 
-  // This is used when copying an object to survivor space.
-  // If the object is marked live, then we mark the copy live.
-  // If the object is allocated since the start of this mark
-  // cycle, then we mark the copy live.
-  // If the object has been around since the previous mark
-  // phase, and hasn't been marked yet during this phase,
-  // then we don't mark it, we just wait for the
-  // current marking cycle to get to it.
-
   // This function returns true when an object has been
   // around since the previous marking and hasn't yet
   // been marked during this marking.
@@ -1605,23 +1663,6 @@
   // Added if it is in permanent gen it isn't dead.
   // Added if it is NULL it isn't dead.
 
-  // vo == UsePrevMarking -> use "prev" marking information,
-  // vo == UseNextMarking -> use "next" marking information,
-  // vo == UseMarkWord    -> use mark word from object header
-  bool is_obj_dead_cond(const oop obj,
-                        const VerifyOption vo) const {
-
-    switch (vo) {
-      case VerifyOption_G1UsePrevMarking:
-        return is_obj_dead(obj);
-      case VerifyOption_G1UseNextMarking:
-        return is_obj_ill(obj);
-      default:
-        assert(vo == VerifyOption_G1UseMarkWord, "must be");
-        return !obj->is_gc_marked();
-    }
-  }
-
   bool is_obj_dead(const oop obj) const {
     const HeapRegion* hr = heap_region_containing(obj);
     if (hr == NULL) {
@@ -1644,6 +1685,42 @@
     else return is_obj_ill(obj, hr);
   }
 
+  // The methods below are here for convenience and dispatch the
+  // appropriate method depending on value of the given VerifyOption
+  // parameter. The options for that parameter are:
+  //
+  // vo == UsePrevMarking -> use "prev" marking information,
+  // vo == UseNextMarking -> use "next" marking information,
+  // vo == UseMarkWord    -> use mark word from object header
+
+  bool is_obj_dead_cond(const oop obj,
+                        const HeapRegion* hr,
+                        const VerifyOption vo) const {
+    switch (vo) {
+    case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj, hr);
+    case VerifyOption_G1UseNextMarking: return is_obj_ill(obj, hr);
+    case VerifyOption_G1UseMarkWord:    return !obj->is_gc_marked();
+    default:                            ShouldNotReachHere();
+    }
+    return false; // keep some compilers happy
+  }
+
+  bool is_obj_dead_cond(const oop obj,
+                        const VerifyOption vo) const {
+    switch (vo) {
+    case VerifyOption_G1UsePrevMarking: return is_obj_dead(obj);
+    case VerifyOption_G1UseNextMarking: return is_obj_ill(obj);
+    case VerifyOption_G1UseMarkWord:    return !obj->is_gc_marked();
+    default:                            ShouldNotReachHere();
+    }
+    return false; // keep some compilers happy
+  }
+
+  bool allocated_since_marking(oop obj, HeapRegion* hr, VerifyOption vo);
+  HeapWord* top_at_mark_start(HeapRegion* hr, VerifyOption vo);
+  bool is_marked(oop obj, VerifyOption vo);
+  const char* top_at_mark_start_str(VerifyOption vo);
+
   // The following is just to alert the verification code
   // that a full collection has occurred and that the
   // remembered sets are no longer up to date.
@@ -1669,209 +1746,12 @@
   void stop_conc_gc_threads();
 
   size_t pending_card_num();
-  size_t max_pending_card_num();
   size_t cards_scanned();
 
 protected:
   size_t _max_heap_capacity;
 };
 
-#define use_local_bitmaps         1
-#define verify_local_bitmaps      0
-#define oop_buffer_length       256
-
-#ifndef PRODUCT
-class GCLabBitMap;
-class GCLabBitMapClosure: public BitMapClosure {
-private:
-  ConcurrentMark* _cm;
-  GCLabBitMap*    _bitmap;
-
-public:
-  GCLabBitMapClosure(ConcurrentMark* cm,
-                     GCLabBitMap* bitmap) {
-    _cm     = cm;
-    _bitmap = bitmap;
-  }
-
-  virtual bool do_bit(size_t offset);
-};
-#endif // !PRODUCT
-
-class GCLabBitMap: public BitMap {
-private:
-  ConcurrentMark* _cm;
-
-  int       _shifter;
-  size_t    _bitmap_word_covers_words;
-
-  // beginning of the heap
-  HeapWord* _heap_start;
-
-  // this is the actual start of the GCLab
-  HeapWord* _real_start_word;
-
-  // this is the actual end of the GCLab
-  HeapWord* _real_end_word;
-
-  // this is the first word, possibly located before the actual start
-  // of the GCLab, that corresponds to the first bit of the bitmap
-  HeapWord* _start_word;
-
-  // size of a GCLab in words
-  size_t _gclab_word_size;
-
-  static int shifter() {
-    return MinObjAlignment - 1;
-  }
-
-  // how many heap words does a single bitmap word corresponds to?
-  static size_t bitmap_word_covers_words() {
-    return BitsPerWord << shifter();
-  }
-
-  size_t gclab_word_size() const {
-    return _gclab_word_size;
-  }
-
-  // Calculates actual GCLab size in words
-  size_t gclab_real_word_size() const {
-    return bitmap_size_in_bits(pointer_delta(_real_end_word, _start_word))
-           / BitsPerWord;
-  }
-
-  static size_t bitmap_size_in_bits(size_t gclab_word_size) {
-    size_t bits_in_bitmap = gclab_word_size >> shifter();
-    // We are going to ensure that the beginning of a word in this
-    // bitmap also corresponds to the beginning of a word in the
-    // global marking bitmap. To handle the case where a GCLab
-    // starts from the middle of the bitmap, we need to add enough
-    // space (i.e. up to a bitmap word) to ensure that we have
-    // enough bits in the bitmap.
-    return bits_in_bitmap + BitsPerWord - 1;
-  }
-public:
-  GCLabBitMap(HeapWord* heap_start, size_t gclab_word_size)
-    : BitMap(bitmap_size_in_bits(gclab_word_size)),
-      _cm(G1CollectedHeap::heap()->concurrent_mark()),
-      _shifter(shifter()),
-      _bitmap_word_covers_words(bitmap_word_covers_words()),
-      _heap_start(heap_start),
-      _gclab_word_size(gclab_word_size),
-      _real_start_word(NULL),
-      _real_end_word(NULL),
-      _start_word(NULL) {
-    guarantee(false, "GCLabBitMap::GCLabBitmap(): don't call this any more");
-  }
-
-  inline unsigned heapWordToOffset(HeapWord* addr) {
-    unsigned offset = (unsigned) pointer_delta(addr, _start_word) >> _shifter;
-    assert(offset < size(), "offset should be within bounds");
-    return offset;
-  }
-
-  inline HeapWord* offsetToHeapWord(size_t offset) {
-    HeapWord* addr =  _start_word + (offset << _shifter);
-    assert(_real_start_word <= addr && addr < _real_end_word, "invariant");
-    return addr;
-  }
-
-  bool fields_well_formed() {
-    bool ret1 = (_real_start_word == NULL) &&
-                (_real_end_word == NULL) &&
-                (_start_word == NULL);
-    if (ret1)
-      return true;
-
-    bool ret2 = _real_start_word >= _start_word &&
-      _start_word < _real_end_word &&
-      (_real_start_word + _gclab_word_size) == _real_end_word &&
-      (_start_word + _gclab_word_size + _bitmap_word_covers_words)
-                                                              > _real_end_word;
-    return ret2;
-  }
-
-  inline bool mark(HeapWord* addr) {
-    guarantee(use_local_bitmaps, "invariant");
-    assert(fields_well_formed(), "invariant");
-
-    if (addr >= _real_start_word && addr < _real_end_word) {
-      assert(!isMarked(addr), "should not have already been marked");
-
-      // first mark it on the bitmap
-      at_put(heapWordToOffset(addr), true);
-
-      return true;
-    } else {
-      return false;
-    }
-  }
-
-  inline bool isMarked(HeapWord* addr) {
-    guarantee(use_local_bitmaps, "invariant");
-    assert(fields_well_formed(), "invariant");
-
-    return at(heapWordToOffset(addr));
-  }
-
-  void set_buffer(HeapWord* start) {
-    guarantee(false, "set_buffer(): don't call this any more");
-
-    guarantee(use_local_bitmaps, "invariant");
-    clear();
-
-    assert(start != NULL, "invariant");
-    _real_start_word = start;
-    _real_end_word   = start + _gclab_word_size;
-
-    size_t diff =
-      pointer_delta(start, _heap_start) % _bitmap_word_covers_words;
-    _start_word = start - diff;
-
-    assert(fields_well_formed(), "invariant");
-  }
-
-#ifndef PRODUCT
-  void verify() {
-    // verify that the marks have been propagated
-    GCLabBitMapClosure cl(_cm, this);
-    iterate(&cl);
-  }
-#endif // PRODUCT
-
-  void retire() {
-    guarantee(false, "retire(): don't call this any more");
-
-    guarantee(use_local_bitmaps, "invariant");
-    assert(fields_well_formed(), "invariant");
-
-    if (_start_word != NULL) {
-      CMBitMap*       mark_bitmap = _cm->nextMarkBitMap();
-
-      // this means that the bitmap was set up for the GCLab
-      assert(_real_start_word != NULL && _real_end_word != NULL, "invariant");
-
-      mark_bitmap->mostly_disjoint_range_union(this,
-                                0, // always start from the start of the bitmap
-                                _start_word,
-                                gclab_real_word_size());
-      _cm->grayRegionIfNecessary(MemRegion(_real_start_word, _real_end_word));
-
-#ifndef PRODUCT
-      if (use_local_bitmaps && verify_local_bitmaps)
-        verify();
-#endif // PRODUCT
-    } else {
-      assert(_real_start_word == NULL && _real_end_word == NULL, "invariant");
-    }
-  }
-
-  size_t bitmap_size_in_words() const {
-    return (bitmap_size_in_bits(gclab_word_size()) + BitsPerWord - 1) / BitsPerWord;
-  }
-
-};
-
 class G1ParGCAllocBuffer: public ParGCAllocBuffer {
 private:
   bool        _retired;
@@ -1960,7 +1840,7 @@
   G1ParScanThreadState(G1CollectedHeap* g1h, uint queue_num);
 
   ~G1ParScanThreadState() {
-    FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base);
+    FREE_C_HEAP_ARRAY(size_t, _surviving_young_words_base, mtGC);
   }
 
   RefToScanQueue*   refs()            { return _refs;             }
@@ -1993,19 +1873,17 @@
   }
 
   HeapWord* allocate_slow(GCAllocPurpose purpose, size_t word_sz) {
-
     HeapWord* obj = NULL;
     size_t gclab_word_size = _g1h->desired_plab_sz(purpose);
     if (word_sz * 100 < gclab_word_size * ParallelGCBufferWastePct) {
       G1ParGCAllocBuffer* alloc_buf = alloc_buffer(purpose);
-      assert(gclab_word_size == alloc_buf->word_sz(),
-             "dynamic resizing is not supported");
       add_to_alloc_buffer_waste(alloc_buf->words_remaining());
-      alloc_buf->retire(false, false);
+      alloc_buf->retire(false /* end_of_gc */, false /* retain */);
 
       HeapWord* buf = _g1h->par_allocate_during_gc(purpose, gclab_word_size);
       if (buf == NULL) return NULL; // Let caller handle allocation failure.
       // Otherwise.
+      alloc_buf->set_word_size(gclab_word_size);
       alloc_buf->set_buf(buf);
 
       obj = alloc_buf->allocate(word_sz);
@@ -2090,7 +1968,9 @@
     for (int ap = 0; ap < GCAllocPurposeCount; ++ap) {
       size_t waste = _alloc_buffers[ap]->words_remaining();
       add_to_alloc_buffer_waste(waste);
-      _alloc_buffers[ap]->retire(true, false);
+      _alloc_buffers[ap]->flush_stats_and_retire(_g1h->stats_for_purpose((GCAllocPurpose)ap),
+                                                 true /* end_of_gc */,
+                                                 false /* retain */);
     }
   }
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
index ee18c4d..4f9c772 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -138,7 +138,7 @@
   return _task_queues->queue(i);
 }
 
-inline  bool G1CollectedHeap::isMarkedPrev(oop obj) const {
+inline bool G1CollectedHeap::isMarkedPrev(oop obj) const {
   return _cm->prevMarkBitMap()->isMarked((HeapWord *)obj);
 }
 
@@ -146,4 +146,77 @@
   return _cm->nextMarkBitMap()->isMarked((HeapWord *)obj);
 }
 
+#ifndef PRODUCT
+// Support for G1EvacuationFailureALot
+
+inline bool
+G1CollectedHeap::evacuation_failure_alot_for_gc_type(bool gcs_are_young,
+                                                     bool during_initial_mark,
+                                                     bool during_marking) {
+  bool res = false;
+  if (during_marking) {
+    res |= G1EvacuationFailureALotDuringConcMark;
+  }
+  if (during_initial_mark) {
+    res |= G1EvacuationFailureALotDuringInitialMark;
+  }
+  if (gcs_are_young) {
+    res |= G1EvacuationFailureALotDuringYoungGC;
+  } else {
+    // GCs are mixed
+    res |= G1EvacuationFailureALotDuringMixedGC;
+  }
+  return res;
+}
+
+inline void
+G1CollectedHeap::set_evacuation_failure_alot_for_current_gc() {
+  if (G1EvacuationFailureALot) {
+    // Note we can't assert that _evacuation_failure_alot_for_current_gc
+    // is clear here. It may have been set during a previous GC but that GC
+    // did not copy enough objects (i.e. G1EvacuationFailureALotCount) to
+    // trigger an evacuation failure and clear the flags and and counts.
+
+    // Check if we have gone over the interval.
+    const size_t gc_num = total_collections();
+    const size_t elapsed_gcs = gc_num - _evacuation_failure_alot_gc_number;
+
+    _evacuation_failure_alot_for_current_gc = (elapsed_gcs >= G1EvacuationFailureALotInterval);
+
+    // Now check if G1EvacuationFailureALot is enabled for the current GC type.
+    const bool gcs_are_young = g1_policy()->gcs_are_young();
+    const bool during_im = g1_policy()->during_initial_mark_pause();
+    const bool during_marking = mark_in_progress();
+
+    _evacuation_failure_alot_for_current_gc &=
+      evacuation_failure_alot_for_gc_type(gcs_are_young,
+                                          during_im,
+                                          during_marking);
+  }
+}
+
+inline bool
+G1CollectedHeap::evacuation_should_fail() {
+  if (!G1EvacuationFailureALot || !_evacuation_failure_alot_for_current_gc) {
+    return false;
+  }
+  // G1EvacuationFailureALot is in effect for current GC
+  // Access to _evacuation_failure_alot_count is not atomic;
+  // the value does not have to be exact.
+  if (++_evacuation_failure_alot_count < G1EvacuationFailureALotCount) {
+    return false;
+  }
+  _evacuation_failure_alot_count = 0;
+  return true;
+}
+
+inline void G1CollectedHeap::reset_evacuation_should_fail() {
+  if (G1EvacuationFailureALot) {
+    _evacuation_failure_alot_gc_number = total_collections();
+    _evacuation_failure_alot_count = 0;
+    _evacuation_failure_alot_for_current_gc = false;
+  }
+}
+#endif  // #ifndef PRODUCT
+
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1COLLECTEDHEAP_INLINE_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
index f63d79c..6e9170a 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp
@@ -29,6 +29,8 @@
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
 #include "gc_implementation/g1/g1ErgoVerbose.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/heapRegionRemSet.hpp"
 #include "gc_implementation/shared/gcPolicyCounters.hpp"
 #include "runtime/arguments.hpp"
@@ -76,96 +78,18 @@
   1.0, 0.7, 0.7, 0.5, 0.5, 0.42, 0.42, 0.30
 };
 
-// Help class for avoiding interleaved logging
-class LineBuffer: public StackObj {
-
-private:
-  static const int BUFFER_LEN = 1024;
-  static const int INDENT_CHARS = 3;
-  char _buffer[BUFFER_LEN];
-  int _indent_level;
-  int _cur;
-
-  void vappend(const char* format, va_list ap) {
-    int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
-    if (res != -1) {
-      _cur += res;
-    } else {
-      DEBUG_ONLY(warning("buffer too small in LineBuffer");)
-      _buffer[BUFFER_LEN -1] = 0;
-      _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
-    }
-  }
-
-public:
-  explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
-    for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
-      _buffer[_cur] = ' ';
-    }
-  }
-
-#ifndef PRODUCT
-  ~LineBuffer() {
-    assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
-  }
-#endif
-
-  void append(const char* format, ...) {
-    va_list ap;
-    va_start(ap, format);
-    vappend(format, ap);
-    va_end(ap);
-  }
-
-  void append_and_print_cr(const char* format, ...) {
-    va_list ap;
-    va_start(ap, format);
-    vappend(format, ap);
-    va_end(ap);
-    gclog_or_tty->print_cr("%s", _buffer);
-    _cur = _indent_level * INDENT_CHARS;
-  }
-};
-
 G1CollectorPolicy::G1CollectorPolicy() :
   _parallel_gc_threads(G1CollectedHeap::use_parallel_gc_threads()
                         ? ParallelGCThreads : 1),
 
   _recent_gc_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
-  _all_pause_times_ms(new NumberSeq()),
   _stop_world_start(0.0),
-  _all_stop_world_times_ms(new NumberSeq()),
-  _all_yield_times_ms(new NumberSeq()),
-
-  _summary(new Summary()),
-
-  _cur_clear_ct_time_ms(0.0),
-  _mark_closure_time_ms(0.0),
-  _root_region_scan_wait_time_ms(0.0),
-
-  _cur_ref_proc_time_ms(0.0),
-  _cur_ref_enq_time_ms(0.0),
-
-#ifndef PRODUCT
-  _min_clear_cc_time_ms(-1.0),
-  _max_clear_cc_time_ms(-1.0),
-  _cur_clear_cc_time_ms(0.0),
-  _cum_clear_cc_time_ms(0.0),
-  _num_cc_clears(0L),
-#endif
-
-  _aux_num(10),
-  _all_aux_times_ms(new NumberSeq[_aux_num]),
-  _cur_aux_start_times_ms(new double[_aux_num]),
-  _cur_aux_times_ms(new double[_aux_num]),
-  _cur_aux_times_set(new bool[_aux_num]),
 
   _concurrent_mark_remark_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
   _concurrent_mark_cleanup_times_ms(new TruncatedSeq(NumPrevPausesForHeuristics)),
 
   _alloc_rate_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
   _prev_collection_pause_end_ms(0.0),
-  _pending_card_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
   _rs_length_diff_seq(new TruncatedSeq(TruncatedSeqLength)),
   _cost_per_card_ms_seq(new TruncatedSeq(TruncatedSeqLength)),
   _young_cards_per_entry_ratio_seq(new TruncatedSeq(TruncatedSeqLength)),
@@ -185,25 +109,16 @@
   _pause_time_target_ms((double) MaxGCPauseMillis),
 
   _gcs_are_young(true),
-  _young_pause_num(0),
-  _mixed_pause_num(0),
 
   _during_marking(false),
   _in_marking_window(false),
   _in_marking_window_im(false),
 
-  _known_garbage_ratio(0.0),
-  _known_garbage_bytes(0),
-
-  _young_gc_eff_seq(new TruncatedSeq(TruncatedSeqLength)),
-
   _recent_prev_end_times_for_all_gcs_sec(
                                 new TruncatedSeq(NumPrevPausesForHeuristics)),
 
   _recent_avg_pause_time_ratio(0.0),
 
-  _all_full_gc_times_ms(new NumberSeq()),
-
   _initiate_conc_mark_if_possible(false),
   _during_initial_mark_pause(false),
   _last_young_gc(false),
@@ -277,32 +192,10 @@
   _recent_prev_end_times_for_all_gcs_sec->add(os::elapsedTime());
   _prev_collection_pause_end_ms = os::elapsedTime() * 1000.0;
 
-  _par_last_gc_worker_start_times_ms = new double[_parallel_gc_threads];
-  _par_last_ext_root_scan_times_ms = new double[_parallel_gc_threads];
-  _par_last_satb_filtering_times_ms = new double[_parallel_gc_threads];
+  _phase_times = new G1GCPhaseTimes(_parallel_gc_threads);
 
-  _par_last_update_rs_times_ms = new double[_parallel_gc_threads];
-  _par_last_update_rs_processed_buffers = new double[_parallel_gc_threads];
+  int index = MIN2(_parallel_gc_threads - 1, 7);
 
-  _par_last_scan_rs_times_ms = new double[_parallel_gc_threads];
-
-  _par_last_obj_copy_times_ms = new double[_parallel_gc_threads];
-
-  _par_last_termination_times_ms = new double[_parallel_gc_threads];
-  _par_last_termination_attempts = new double[_parallel_gc_threads];
-  _par_last_gc_worker_end_times_ms = new double[_parallel_gc_threads];
-  _par_last_gc_worker_times_ms = new double[_parallel_gc_threads];
-  _par_last_gc_worker_other_times_ms = new double[_parallel_gc_threads];
-
-  int index;
-  if (ParallelGCThreads == 0)
-    index = 0;
-  else if (ParallelGCThreads > 8)
-    index = 7;
-  else
-    index = ParallelGCThreads - 1;
-
-  _pending_card_diff_seq->add(0.0);
   _rs_length_diff_seq->add(rs_length_diff_defaults[index]);
   _cost_per_card_ms_seq->add(cost_per_card_ms_defaults[index]);
   _young_cards_per_entry_ratio_seq->add(
@@ -431,31 +324,36 @@
   }
 
   if (FLAG_IS_CMDLINE(NewSize)) {
-     _min_desired_young_length = MAX2((size_t) 1, NewSize / HeapRegion::GrainBytes);
+    _min_desired_young_length = MAX2((uint) (NewSize / HeapRegion::GrainBytes),
+                                     1U);
     if (FLAG_IS_CMDLINE(MaxNewSize)) {
-      _max_desired_young_length = MAX2((size_t) 1, MaxNewSize / HeapRegion::GrainBytes);
+      _max_desired_young_length =
+                             MAX2((uint) (MaxNewSize / HeapRegion::GrainBytes),
+                                  1U);
       _sizer_kind = SizerMaxAndNewSize;
       _adaptive_size = _min_desired_young_length == _max_desired_young_length;
     } else {
       _sizer_kind = SizerNewSizeOnly;
     }
   } else if (FLAG_IS_CMDLINE(MaxNewSize)) {
-    _max_desired_young_length = MAX2((size_t) 1, MaxNewSize / HeapRegion::GrainBytes);
+    _max_desired_young_length =
+                             MAX2((uint) (MaxNewSize / HeapRegion::GrainBytes),
+                                  1U);
     _sizer_kind = SizerMaxNewSizeOnly;
   }
 }
 
-size_t G1YoungGenSizer::calculate_default_min_length(size_t new_number_of_heap_regions) {
-  size_t default_value = (new_number_of_heap_regions * G1DefaultMinNewGenPercent) / 100;
-  return MAX2((size_t)1, default_value);
+uint G1YoungGenSizer::calculate_default_min_length(uint new_number_of_heap_regions) {
+  uint default_value = (new_number_of_heap_regions * G1DefaultMinNewGenPercent) / 100;
+  return MAX2(1U, default_value);
 }
 
-size_t G1YoungGenSizer::calculate_default_max_length(size_t new_number_of_heap_regions) {
-  size_t default_value = (new_number_of_heap_regions * G1DefaultMaxNewGenPercent) / 100;
-  return MAX2((size_t)1, default_value);
+uint G1YoungGenSizer::calculate_default_max_length(uint new_number_of_heap_regions) {
+  uint default_value = (new_number_of_heap_regions * G1DefaultMaxNewGenPercent) / 100;
+  return MAX2(1U, default_value);
 }
 
-void G1YoungGenSizer::heap_size_changed(size_t new_number_of_heap_regions) {
+void G1YoungGenSizer::heap_size_changed(uint new_number_of_heap_regions) {
   assert(new_number_of_heap_regions > 0, "Heap must be initialized");
 
   switch (_sizer_kind) {
@@ -512,16 +410,16 @@
   _gc_policy_counters = new GCPolicyCounters("GarbageFirst", 1, 3);
 }
 
-bool G1CollectorPolicy::predict_will_fit(size_t young_length,
+bool G1CollectorPolicy::predict_will_fit(uint young_length,
                                          double base_time_ms,
-                                         size_t base_free_regions,
+                                         uint base_free_regions,
                                          double target_pause_time_ms) {
   if (young_length >= base_free_regions) {
     // end condition 1: not enough space for the young regions
     return false;
   }
 
-  double accum_surv_rate = accum_yg_surv_rate_pred((int)(young_length - 1));
+  double accum_surv_rate = accum_yg_surv_rate_pred((int) young_length - 1);
   size_t bytes_to_copy =
                (size_t) (accum_surv_rate * (double) HeapRegion::GrainBytes);
   double copy_time_ms = predict_object_copy_time_ms(bytes_to_copy);
@@ -533,7 +431,7 @@
   }
 
   size_t free_bytes =
-                  (base_free_regions - young_length) * HeapRegion::GrainBytes;
+                   (base_free_regions - young_length) * HeapRegion::GrainBytes;
   if ((2.0 * sigma()) * (double) bytes_to_copy > (double) free_bytes) {
     // end condition 3: out-of-space (conservatively!)
     return false;
@@ -543,25 +441,25 @@
   return true;
 }
 
-void G1CollectorPolicy::record_new_heap_size(size_t new_number_of_regions) {
+void G1CollectorPolicy::record_new_heap_size(uint new_number_of_regions) {
   // re-calculate the necessary reserve
   double reserve_regions_d = (double) new_number_of_regions * _reserve_factor;
   // We use ceiling so that if reserve_regions_d is > 0.0 (but
   // smaller than 1.0) we'll get 1.
-  _reserve_regions = (size_t) ceil(reserve_regions_d);
+  _reserve_regions = (uint) ceil(reserve_regions_d);
 
   _young_gen_sizer->heap_size_changed(new_number_of_regions);
 }
 
-size_t G1CollectorPolicy::calculate_young_list_desired_min_length(
-                                                     size_t base_min_length) {
-  size_t desired_min_length = 0;
+uint G1CollectorPolicy::calculate_young_list_desired_min_length(
+                                                       uint base_min_length) {
+  uint desired_min_length = 0;
   if (adaptive_young_list_length()) {
     if (_alloc_rate_ms_seq->num() > 3) {
       double now_sec = os::elapsedTime();
       double when_ms = _mmu_tracker->when_max_gc_sec(now_sec) * 1000.0;
       double alloc_rate_ms = predict_alloc_rate_ms();
-      desired_min_length = (size_t) ceil(alloc_rate_ms * when_ms);
+      desired_min_length = (uint) ceil(alloc_rate_ms * when_ms);
     } else {
       // otherwise we don't have enough info to make the prediction
     }
@@ -571,7 +469,7 @@
   return MAX2(_young_gen_sizer->min_desired_young_length(), desired_min_length);
 }
 
-size_t G1CollectorPolicy::calculate_young_list_desired_max_length() {
+uint G1CollectorPolicy::calculate_young_list_desired_max_length() {
   // Here, we might want to also take into account any additional
   // constraints (i.e., user-defined minimum bound). Currently, we
   // effectively don't set this bound.
@@ -588,11 +486,11 @@
   // Calculate the absolute and desired min bounds.
 
   // This is how many young regions we already have (currently: the survivors).
-  size_t base_min_length = recorded_survivor_regions();
+  uint base_min_length = recorded_survivor_regions();
   // This is the absolute minimum young length, which ensures that we
   // can allocate one eden region in the worst-case.
-  size_t absolute_min_length = base_min_length + 1;
-  size_t desired_min_length =
+  uint absolute_min_length = base_min_length + 1;
+  uint desired_min_length =
                      calculate_young_list_desired_min_length(base_min_length);
   if (desired_min_length < absolute_min_length) {
     desired_min_length = absolute_min_length;
@@ -601,16 +499,16 @@
   // Calculate the absolute and desired max bounds.
 
   // We will try our best not to "eat" into the reserve.
-  size_t absolute_max_length = 0;
+  uint absolute_max_length = 0;
   if (_free_regions_at_end_of_collection > _reserve_regions) {
     absolute_max_length = _free_regions_at_end_of_collection - _reserve_regions;
   }
-  size_t desired_max_length = calculate_young_list_desired_max_length();
+  uint desired_max_length = calculate_young_list_desired_max_length();
   if (desired_max_length > absolute_max_length) {
     desired_max_length = absolute_max_length;
   }
 
-  size_t young_list_target_length = 0;
+  uint young_list_target_length = 0;
   if (adaptive_young_list_length()) {
     if (gcs_are_young()) {
       young_list_target_length =
@@ -648,11 +546,11 @@
   update_max_gc_locker_expansion();
 }
 
-size_t
+uint
 G1CollectorPolicy::calculate_young_list_target_length(size_t rs_lengths,
-                                                   size_t base_min_length,
-                                                   size_t desired_min_length,
-                                                   size_t desired_max_length) {
+                                                     uint base_min_length,
+                                                     uint desired_min_length,
+                                                     uint desired_max_length) {
   assert(adaptive_young_list_length(), "pre-condition");
   assert(gcs_are_young(), "only call this for young GCs");
 
@@ -667,9 +565,9 @@
   // will be reflected in the predictions by the
   // survivor_regions_evac_time prediction.
   assert(desired_min_length > base_min_length, "invariant");
-  size_t min_young_length = desired_min_length - base_min_length;
+  uint min_young_length = desired_min_length - base_min_length;
   assert(desired_max_length > base_min_length, "invariant");
-  size_t max_young_length = desired_max_length - base_min_length;
+  uint max_young_length = desired_max_length - base_min_length;
 
   double target_pause_time_ms = _mmu_tracker->max_gc_time() * 1000.0;
   double survivor_regions_evac_time = predict_survivor_regions_evac_time();
@@ -679,8 +577,8 @@
   double base_time_ms =
     predict_base_elapsed_time_ms(pending_cards, scanned_cards) +
     survivor_regions_evac_time;
-  size_t available_free_regions = _free_regions_at_end_of_collection;
-  size_t base_free_regions = 0;
+  uint available_free_regions = _free_regions_at_end_of_collection;
+  uint base_free_regions = 0;
   if (available_free_regions > _reserve_regions) {
     base_free_regions = available_free_regions - _reserve_regions;
   }
@@ -717,9 +615,9 @@
       // the new max. This way we maintain the loop invariants.
 
       assert(min_young_length < max_young_length, "invariant");
-      size_t diff = (max_young_length - min_young_length) / 2;
+      uint diff = (max_young_length - min_young_length) / 2;
       while (diff > 0) {
-        size_t young_length = min_young_length + diff;
+        uint young_length = min_young_length + diff;
         if (predict_will_fit(young_length, base_time_ms,
                              base_free_regions, target_pause_time_ms)) {
           min_young_length = young_length;
@@ -757,7 +655,7 @@
   for (HeapRegion * r = _recorded_survivor_head;
        r != NULL && r != _recorded_survivor_tail->get_next_young_region();
        r = r->get_next_young_region()) {
-    survivor_regions_evac_time += predict_region_elapsed_time_ms(r, true);
+    survivor_regions_evac_time += predict_region_elapsed_time_ms(r, gcs_are_young());
   }
   return survivor_regions_evac_time;
 }
@@ -839,7 +737,7 @@
 #endif // PRODUCT
 
 void G1CollectorPolicy::record_full_collection_start() {
-  _cur_collection_start_sec = os::elapsedTime();
+  _full_collection_start_sec = os::elapsedTime();
   // Release the future to-space so that it is available for compaction into.
   _g1->set_full_collection();
 }
@@ -848,10 +746,10 @@
   // Consider this like a collection pause for the purposes of allocation
   // since last pause.
   double end_sec = os::elapsedTime();
-  double full_gc_time_sec = end_sec - _cur_collection_start_sec;
+  double full_gc_time_sec = end_sec - _full_collection_start_sec;
   double full_gc_time_ms = full_gc_time_sec * 1000.0;
 
-  _all_full_gc_times_ms->add(full_gc_time_ms);
+  _trace_gen1_time_data.record_full_collection(full_gc_time_ms);
 
   update_recent_gc_times(end_sec, full_gc_time_ms);
 
@@ -863,8 +761,6 @@
   _last_young_gc = false;
   clear_initiate_conc_mark_if_possible();
   clear_during_initial_mark_pause();
-  _known_garbage_bytes = 0;
-  _known_garbage_ratio = 0.0;
   _in_marking_window = false;
   _in_marking_window_im = false;
 
@@ -877,7 +773,7 @@
   // Reset survivors SurvRateGroup.
   _survivor_surv_rate_group->reset();
   update_young_list_target_length();
-  _collectionSetChooser->clearMarkedHeapRegions();
+  _collectionSetChooser->clear();
 }
 
 void G1CollectorPolicy::record_stop_world_start() {
@@ -886,12 +782,6 @@
 
 void G1CollectorPolicy::record_collection_pause_start(double start_time_sec,
                                                       size_t start_used) {
-  if (PrintGCDetails) {
-    gclog_or_tty->stamp(PrintGCTimeStamps);
-    gclog_or_tty->print("[GC pause");
-    gclog_or_tty->print(" (%s)", gcs_are_young() ? "young" : "mixed");
-  }
-
   // We only need to do this here as the policy will only be applied
   // to the GC we're about to start. so, no point is calculating this
   // every time we calculate / recalculate the target young length.
@@ -902,16 +792,15 @@
                  _g1->used(), _g1->recalculate_used()));
 
   double s_w_t_ms = (start_time_sec - _stop_world_start) * 1000.0;
-  _all_stop_world_times_ms->add(s_w_t_ms);
+  _trace_gen0_time_data.record_start_collection(s_w_t_ms);
   _stop_world_start = 0.0;
 
-  _cur_collection_start_sec = start_time_sec;
+  phase_times()->record_cur_collection_start_sec(start_time_sec);
   _cur_collection_pause_used_at_start_bytes = start_used;
   _cur_collection_pause_used_regions_at_start = _g1->used_regions();
   _pending_cards = _g1->pending_card_num();
-  _max_pending_cards = _g1->max_pending_card_num();
 
-  _bytes_in_collection_set_before_gc = 0;
+  _collection_set_bytes_used_before = 0;
   _bytes_copied_during_gc = 0;
 
   YoungList* young_list = _g1->young_list();
@@ -919,38 +808,6 @@
   _survivor_bytes_before_gc = young_list->survivor_used_bytes();
   _capacity_before_gc = _g1->capacity();
 
-#ifdef DEBUG
-  // initialise these to something well known so that we can spot
-  // if they are not set properly
-
-  for (int i = 0; i < _parallel_gc_threads; ++i) {
-    _par_last_gc_worker_start_times_ms[i] = -1234.0;
-    _par_last_ext_root_scan_times_ms[i] = -1234.0;
-    _par_last_satb_filtering_times_ms[i] = -1234.0;
-    _par_last_update_rs_times_ms[i] = -1234.0;
-    _par_last_update_rs_processed_buffers[i] = -1234.0;
-    _par_last_scan_rs_times_ms[i] = -1234.0;
-    _par_last_obj_copy_times_ms[i] = -1234.0;
-    _par_last_termination_times_ms[i] = -1234.0;
-    _par_last_termination_attempts[i] = -1234.0;
-    _par_last_gc_worker_end_times_ms[i] = -1234.0;
-    _par_last_gc_worker_times_ms[i] = -1234.0;
-    _par_last_gc_worker_other_times_ms[i] = -1234.0;
-  }
-#endif
-
-  for (int i = 0; i < _aux_num; ++i) {
-    _cur_aux_times_ms[i] = 0.0;
-    _cur_aux_times_set[i] = false;
-  }
-
-  // This is initialized to zero here and is set during
-  // the evacuation pause if marking is in progress.
-  _cur_satb_drain_time_ms = 0.0;
-  // This is initialized to zero here and is set during the evacuation
-  // pause if we actually waited for the root region scanning to finish.
-  _root_region_scan_wait_time_ms = 0.0;
-
   _last_gc_was_young = false;
 
   // do that for any other surv rate groups
@@ -995,131 +852,10 @@
 void G1CollectorPolicy::record_concurrent_pause() {
   if (_stop_world_start > 0.0) {
     double yield_ms = (os::elapsedTime() - _stop_world_start) * 1000.0;
-    _all_yield_times_ms->add(yield_ms);
+    _trace_gen0_time_data.record_yield_time(yield_ms);
   }
 }
 
-void G1CollectorPolicy::record_concurrent_pause_end() {
-}
-
-template<class T>
-T sum_of(T* sum_arr, int start, int n, int N) {
-  T sum = (T)0;
-  for (int i = 0; i < n; i++) {
-    int j = (start + i) % N;
-    sum += sum_arr[j];
-  }
-  return sum;
-}
-
-void G1CollectorPolicy::print_par_stats(int level,
-                                        const char* str,
-                                        double* data) {
-  double min = data[0], max = data[0];
-  double total = 0.0;
-  LineBuffer buf(level);
-  buf.append("[%s (ms):", str);
-  for (uint i = 0; i < no_of_gc_threads(); ++i) {
-    double val = data[i];
-    if (val < min)
-      min = val;
-    if (val > max)
-      max = val;
-    total += val;
-    buf.append("  %3.1lf", val);
-  }
-  buf.append_and_print_cr("");
-  double avg = total / (double) no_of_gc_threads();
-  buf.append_and_print_cr(" Avg: %5.1lf, Min: %5.1lf, Max: %5.1lf, Diff: %5.1lf]",
-    avg, min, max, max - min);
-}
-
-void G1CollectorPolicy::print_par_sizes(int level,
-                                        const char* str,
-                                        double* data) {
-  double min = data[0], max = data[0];
-  double total = 0.0;
-  LineBuffer buf(level);
-  buf.append("[%s :", str);
-  for (uint i = 0; i < no_of_gc_threads(); ++i) {
-    double val = data[i];
-    if (val < min)
-      min = val;
-    if (val > max)
-      max = val;
-    total += val;
-    buf.append(" %d", (int) val);
-  }
-  buf.append_and_print_cr("");
-  double avg = total / (double) no_of_gc_threads();
-  buf.append_and_print_cr(" Sum: %d, Avg: %d, Min: %d, Max: %d, Diff: %d]",
-    (int)total, (int)avg, (int)min, (int)max, (int)max - (int)min);
-}
-
-void G1CollectorPolicy::print_stats(int level,
-                                    const char* str,
-                                    double value) {
-  LineBuffer(level).append_and_print_cr("[%s: %5.1lf ms]", str, value);
-}
-
-void G1CollectorPolicy::print_stats(int level,
-                                    const char* str,
-                                    int value) {
-  LineBuffer(level).append_and_print_cr("[%s: %d]", str, value);
-}
-
-double G1CollectorPolicy::avg_value(double* data) {
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    double ret = 0.0;
-    for (uint i = 0; i < no_of_gc_threads(); ++i) {
-      ret += data[i];
-    }
-    return ret / (double) no_of_gc_threads();
-  } else {
-    return data[0];
-  }
-}
-
-double G1CollectorPolicy::max_value(double* data) {
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    double ret = data[0];
-    for (uint i = 1; i < no_of_gc_threads(); ++i) {
-      if (data[i] > ret) {
-        ret = data[i];
-      }
-    }
-    return ret;
-  } else {
-    return data[0];
-  }
-}
-
-double G1CollectorPolicy::sum_of_values(double* data) {
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    double sum = 0.0;
-    for (uint i = 0; i < no_of_gc_threads(); i++) {
-      sum += data[i];
-    }
-    return sum;
-  } else {
-    return data[0];
-  }
-}
-
-double G1CollectorPolicy::max_sum(double* data1, double* data2) {
-  double ret = data1[0] + data2[0];
-
-  if (G1CollectedHeap::use_parallel_gc_threads()) {
-    for (uint i = 1; i < no_of_gc_threads(); ++i) {
-      double data = data1[i] + data2[i];
-      if (data > ret) {
-        ret = data;
-      }
-    }
-  }
-  return ret;
-}
-
 bool G1CollectorPolicy::need_to_start_conc_mark(const char* source, size_t alloc_word_size) {
   if (_g1->concurrent_mark()->cmThread()->during_cycle()) {
     return false;
@@ -1167,10 +903,8 @@
 // Anything below that is considered to be zero
 #define MIN_TIMER_GRANULARITY 0.0000001
 
-void G1CollectorPolicy::record_collection_pause_end(int no_of_gc_threads) {
+void G1CollectorPolicy::record_collection_pause_end(double pause_time_ms) {
   double end_time_sec = os::elapsedTime();
-  double elapsed_ms = _last_pause_time_ms;
-  bool parallel = G1CollectedHeap::use_parallel_gc_threads();
   assert(_cur_collection_pause_used_regions_at_start >= cset_region_length(),
          "otherwise, the subtraction below does not make sense");
   size_t rs_size =
@@ -1179,7 +913,6 @@
   assert(cur_used_bytes == _g1->recalculate_used(), "It should!");
   bool last_pause_included_initial_mark = false;
   bool update_stats = !_g1->evacuation_failed();
-  set_no_of_gc_threads(no_of_gc_threads);
 
 #ifndef PRODUCT
   if (G1YoungSurvRateVerbose) {
@@ -1199,24 +932,9 @@
     set_initiate_conc_mark_if_possible();
   }
 
-  _mmu_tracker->add_pause(end_time_sec - elapsed_ms/1000.0,
+  _mmu_tracker->add_pause(end_time_sec - pause_time_ms/1000.0,
                           end_time_sec, false);
 
-  // This assert is exempted when we're doing parallel collection pauses,
-  // because the fragmentation caused by the parallel GC allocation buffers
-  // can lead to more memory being used during collection than was used
-  // before. Best leave this out until the fragmentation problem is fixed.
-  // Pauses in which evacuation failed can also lead to negative
-  // collections, since no space is reclaimed from a region containing an
-  // object whose evacuation failed.
-  // Further, we're now always doing parallel collection.  But I'm still
-  // leaving this here as a placeholder for a more precise assertion later.
-  // (DLD, 10/05.)
-  assert((true || parallel) // Always using GC LABs now.
-         || _g1->evacuation_failed()
-         || _cur_collection_pause_used_at_start_bytes >= cur_used_bytes,
-         "Negative collection");
-
   size_t freed_bytes =
     _cur_collection_pause_used_at_start_bytes - cur_used_bytes;
   size_t surviving_bytes = _collection_set_bytes_used_before - freed_bytes;
@@ -1225,103 +943,11 @@
     (double)surviving_bytes/
     (double)_collection_set_bytes_used_before;
 
-  // These values are used to update the summary information that is
-  // displayed when TraceGen0Time is enabled, and are output as part
-  // of the PrintGCDetails output, in the non-parallel case.
-
-  double ext_root_scan_time = avg_value(_par_last_ext_root_scan_times_ms);
-  double satb_filtering_time = avg_value(_par_last_satb_filtering_times_ms);
-  double update_rs_time = avg_value(_par_last_update_rs_times_ms);
-  double update_rs_processed_buffers =
-    sum_of_values(_par_last_update_rs_processed_buffers);
-  double scan_rs_time = avg_value(_par_last_scan_rs_times_ms);
-  double obj_copy_time = avg_value(_par_last_obj_copy_times_ms);
-  double termination_time = avg_value(_par_last_termination_times_ms);
-
-  double known_time = ext_root_scan_time +
-                      satb_filtering_time +
-                      update_rs_time +
-                      scan_rs_time +
-                      obj_copy_time;
-
-  double other_time_ms = elapsed_ms;
-
-  // Subtract the SATB drain time. It's initialized to zero at the
-  // start of the pause and is updated during the pause if marking
-  // is in progress.
-  other_time_ms -= _cur_satb_drain_time_ms;
-
-  // Subtract the root region scanning wait time. It's initialized to
-  // zero at the start of the pause.
-  other_time_ms -= _root_region_scan_wait_time_ms;
-
-  if (parallel) {
-    other_time_ms -= _cur_collection_par_time_ms;
-  } else {
-    other_time_ms -= known_time;
-  }
-
-  // Subtract the time taken to clean the card table from the
-  // current value of "other time"
-  other_time_ms -= _cur_clear_ct_time_ms;
-
-  // Subtract the time spent completing marking in the collection
-  // set. Note if marking is not in progress during the pause
-  // the value of _mark_closure_time_ms will be zero.
-  other_time_ms -= _mark_closure_time_ms;
-
-  // TraceGen0Time and TraceGen1Time summary info updating.
-  _all_pause_times_ms->add(elapsed_ms);
-
   if (update_stats) {
-    _summary->record_total_time_ms(elapsed_ms);
-    _summary->record_other_time_ms(other_time_ms);
-
-    MainBodySummary* body_summary = _summary->main_body_summary();
-    assert(body_summary != NULL, "should not be null!");
-
-    // This will be non-zero iff marking is currently in progress (i.e.
-    // _g1->mark_in_progress() == true) and the currrent pause was not
-    // an initial mark pause. Since the body_summary items are NumberSeqs,
-    // however, they have to be consistent and updated in lock-step with
-    // each other. Therefore we unconditionally record the SATB drain
-    // time - even if it's zero.
-    body_summary->record_satb_drain_time_ms(_cur_satb_drain_time_ms);
-    body_summary->record_root_region_scan_wait_time_ms(
-                                               _root_region_scan_wait_time_ms);
-
-    body_summary->record_ext_root_scan_time_ms(ext_root_scan_time);
-    body_summary->record_satb_filtering_time_ms(satb_filtering_time);
-    body_summary->record_update_rs_time_ms(update_rs_time);
-    body_summary->record_scan_rs_time_ms(scan_rs_time);
-    body_summary->record_obj_copy_time_ms(obj_copy_time);
-
-    if (parallel) {
-      body_summary->record_parallel_time_ms(_cur_collection_par_time_ms);
-      body_summary->record_termination_time_ms(termination_time);
-
-      double parallel_known_time = known_time + termination_time;
-      double parallel_other_time = _cur_collection_par_time_ms - parallel_known_time;
-      body_summary->record_parallel_other_time_ms(parallel_other_time);
-    }
-
-    body_summary->record_mark_closure_time_ms(_mark_closure_time_ms);
-    body_summary->record_clear_ct_time_ms(_cur_clear_ct_time_ms);
-
-    // We exempt parallel collection from this check because Alloc Buffer
-    // fragmentation can produce negative collections.  Same with evac
-    // failure.
-    // Further, we're now always doing parallel collection.  But I'm still
-    // leaving this here as a placeholder for a more precise assertion later.
-    // (DLD, 10/05.
-    assert((true || parallel)
-           || _g1->evacuation_failed()
-           || surviving_bytes <= _collection_set_bytes_used_before,
-           "Or else negative collection!");
-
+    _trace_gen0_time_data.record_end_collection(pause_time_ms, phase_times());
     // this is where we update the allocation rate of the application
     double app_time_ms =
-      (_cur_collection_start_sec * 1000.0 - _prev_collection_pause_end_ms);
+      (phase_times()->cur_collection_start_sec() * 1000.0 - _prev_collection_pause_end_ms);
     if (app_time_ms < MIN_TIMER_GRANULARITY) {
       // This usually happens due to the timer not having the required
       // granularity. Some Linuxes are the usual culprits.
@@ -1336,13 +962,13 @@
     // given that humongous object allocations do not really affect
     // either the pause's duration nor when the next pause will take
     // place we can safely ignore them here.
-    size_t regions_allocated = eden_cset_region_length();
+    uint regions_allocated = eden_cset_region_length();
     double alloc_rate_ms = (double) regions_allocated / app_time_ms;
     _alloc_rate_ms_seq->add(alloc_rate_ms);
 
     double interval_ms =
       (end_time_sec - _recent_prev_end_times_for_all_gcs_sec->oldest()) * 1000.0;
-    update_recent_gc_times(end_time_sec, elapsed_ms);
+    update_recent_gc_times(end_time_sec, pause_time_ms);
     _recent_avg_pause_time_ratio = _recent_gc_times_ms->sum()/interval_ms;
     if (recent_avg_pause_time_ratio() < 0.0 ||
         (recent_avg_pause_time_ratio() - 1.0 > 0.0)) {
@@ -1369,106 +995,6 @@
       }
     }
   }
-
-  for (int i = 0; i < _aux_num; ++i) {
-    if (_cur_aux_times_set[i]) {
-      _all_aux_times_ms[i].add(_cur_aux_times_ms[i]);
-    }
-  }
-
-  // PrintGCDetails output
-  if (PrintGCDetails) {
-    bool print_marking_info =
-      _g1->mark_in_progress() && !last_pause_included_initial_mark;
-
-    gclog_or_tty->print_cr("%s, %1.8lf secs]",
-                           (last_pause_included_initial_mark) ? " (initial-mark)" : "",
-                           elapsed_ms / 1000.0);
-
-    if (_root_region_scan_wait_time_ms > 0.0) {
-      print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
-    }
-    if (parallel) {
-      print_stats(1, "Parallel Time", _cur_collection_par_time_ms);
-      print_par_stats(2, "GC Worker Start", _par_last_gc_worker_start_times_ms);
-      print_par_stats(2, "Ext Root Scanning", _par_last_ext_root_scan_times_ms);
-      if (print_marking_info) {
-        print_par_stats(2, "SATB Filtering", _par_last_satb_filtering_times_ms);
-      }
-      print_par_stats(2, "Update RS", _par_last_update_rs_times_ms);
-      print_par_sizes(3, "Processed Buffers", _par_last_update_rs_processed_buffers);
-      print_par_stats(2, "Scan RS", _par_last_scan_rs_times_ms);
-      print_par_stats(2, "Object Copy", _par_last_obj_copy_times_ms);
-      print_par_stats(2, "Termination", _par_last_termination_times_ms);
-      print_par_sizes(3, "Termination Attempts", _par_last_termination_attempts);
-      print_par_stats(2, "GC Worker End", _par_last_gc_worker_end_times_ms);
-
-      for (int i = 0; i < _parallel_gc_threads; i++) {
-        _par_last_gc_worker_times_ms[i] = _par_last_gc_worker_end_times_ms[i] - _par_last_gc_worker_start_times_ms[i];
-
-        double worker_known_time = _par_last_ext_root_scan_times_ms[i] +
-                                   _par_last_satb_filtering_times_ms[i] +
-                                   _par_last_update_rs_times_ms[i] +
-                                   _par_last_scan_rs_times_ms[i] +
-                                   _par_last_obj_copy_times_ms[i] +
-                                   _par_last_termination_times_ms[i];
-
-        _par_last_gc_worker_other_times_ms[i] = _cur_collection_par_time_ms - worker_known_time;
-      }
-      print_par_stats(2, "GC Worker", _par_last_gc_worker_times_ms);
-      print_par_stats(2, "GC Worker Other", _par_last_gc_worker_other_times_ms);
-    } else {
-      print_stats(1, "Ext Root Scanning", ext_root_scan_time);
-      if (print_marking_info) {
-        print_stats(1, "SATB Filtering", satb_filtering_time);
-      }
-      print_stats(1, "Update RS", update_rs_time);
-      print_stats(2, "Processed Buffers", (int)update_rs_processed_buffers);
-      print_stats(1, "Scan RS", scan_rs_time);
-      print_stats(1, "Object Copying", obj_copy_time);
-    }
-    if (print_marking_info) {
-      print_stats(1, "Complete CSet Marking", _mark_closure_time_ms);
-    }
-    print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
-#ifndef PRODUCT
-    print_stats(1, "Cur Clear CC", _cur_clear_cc_time_ms);
-    print_stats(1, "Cum Clear CC", _cum_clear_cc_time_ms);
-    print_stats(1, "Min Clear CC", _min_clear_cc_time_ms);
-    print_stats(1, "Max Clear CC", _max_clear_cc_time_ms);
-    if (_num_cc_clears > 0) {
-      print_stats(1, "Avg Clear CC", _cum_clear_cc_time_ms / ((double)_num_cc_clears));
-    }
-#endif
-    print_stats(1, "Other", other_time_ms);
-    print_stats(2, "Choose CSet",
-                   (_recorded_young_cset_choice_time_ms +
-                    _recorded_non_young_cset_choice_time_ms));
-    print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
-    print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
-    print_stats(2, "Free CSet",
-                   (_recorded_young_free_cset_time_ms +
-                    _recorded_non_young_free_cset_time_ms));
-
-    for (int i = 0; i < _aux_num; ++i) {
-      if (_cur_aux_times_set[i]) {
-        char buffer[96];
-        sprintf(buffer, "Aux%d", i);
-        print_stats(1, buffer, _cur_aux_times_ms[i]);
-      }
-    }
-  }
-
-  // Update the efficiency-since-mark vars.
-  double proc_ms = elapsed_ms * (double) _parallel_gc_threads;
-  if (elapsed_ms < MIN_TIMER_GRANULARITY) {
-    // This usually happens due to the timer not having the required
-    // granularity. Some Linuxes are the usual culprits.
-    // We'll just set it to something (arbitrarily) small.
-    proc_ms = 1.0;
-  }
-  double cur_efficiency = (double) freed_bytes / proc_ms;
-
   bool new_in_marking_window = _in_marking_window;
   bool new_in_marking_window_im = false;
   if (during_initial_mark_pause()) {
@@ -1503,24 +1029,13 @@
     }
   }
 
-  if (_last_gc_was_young && !_during_marking) {
-    _young_gc_eff_seq->add(cur_efficiency);
-  }
-
   _short_lived_surv_rate_group->start_adding_regions();
   // do that for any other surv rate groupsx
 
   if (update_stats) {
-    double pause_time_ms = elapsed_ms;
-
-    size_t diff = 0;
-    if (_max_pending_cards >= _pending_cards)
-      diff = _max_pending_cards - _pending_cards;
-    _pending_card_diff_seq->add((double) diff);
-
     double cost_per_card_ms = 0.0;
     if (_pending_cards > 0) {
-      cost_per_card_ms = update_rs_time / (double) _pending_cards;
+      cost_per_card_ms = phase_times()->average_last_update_rs_time() / (double) _pending_cards;
       _cost_per_card_ms_seq->add(cost_per_card_ms);
     }
 
@@ -1528,7 +1043,7 @@
 
     double cost_per_entry_ms = 0.0;
     if (cards_scanned > 10) {
-      cost_per_entry_ms = scan_rs_time / (double) cards_scanned;
+      cost_per_entry_ms = phase_times()->average_last_scan_rs_time() / (double) cards_scanned;
       if (_last_gc_was_young) {
         _cost_per_entry_ms_seq->add(cost_per_entry_ms);
       } else {
@@ -1568,7 +1083,7 @@
     size_t copied_bytes = surviving_bytes;
     double cost_per_byte_ms = 0.0;
     if (copied_bytes > 0) {
-      cost_per_byte_ms = obj_copy_time / (double) copied_bytes;
+      cost_per_byte_ms = phase_times()->average_last_obj_copy_time() / (double) copied_bytes;
       if (_in_marking_window) {
         _cost_per_byte_ms_during_cm_seq->add(cost_per_byte_ms);
       } else {
@@ -1577,22 +1092,22 @@
     }
 
     double all_other_time_ms = pause_time_ms -
-      (update_rs_time + scan_rs_time + obj_copy_time +
-       _mark_closure_time_ms + termination_time);
+      (phase_times()->average_last_update_rs_time() + phase_times()->average_last_scan_rs_time()
+      + phase_times()->average_last_obj_copy_time() + phase_times()->average_last_termination_time());
 
     double young_other_time_ms = 0.0;
     if (young_cset_region_length() > 0) {
       young_other_time_ms =
-        _recorded_young_cset_choice_time_ms +
-        _recorded_young_free_cset_time_ms;
+        phase_times()->young_cset_choice_time_ms() +
+        phase_times()->young_free_cset_time_ms();
       _young_other_cost_per_region_ms_seq->add(young_other_time_ms /
                                           (double) young_cset_region_length());
     }
     double non_young_other_time_ms = 0.0;
     if (old_cset_region_length() > 0) {
       non_young_other_time_ms =
-        _recorded_non_young_cset_choice_time_ms +
-        _recorded_non_young_free_cset_time_ms;
+        phase_times()->non_young_cset_choice_time_ms() +
+        phase_times()->non_young_free_cset_time_ms();
 
       _non_young_other_cost_per_region_ms_seq->add(non_young_other_time_ms /
                                             (double) old_cset_region_length());
@@ -1603,9 +1118,9 @@
     _constant_other_time_ms_seq->add(constant_other_time_ms);
 
     double survival_ratio = 0.0;
-    if (_bytes_in_collection_set_before_gc > 0) {
+    if (_collection_set_bytes_used_before > 0) {
       survival_ratio = (double) _bytes_copied_during_gc /
-                                   (double) _bytes_in_collection_set_before_gc;
+                                   (double) _collection_set_bytes_used_before;
     }
 
     _pending_cards_seq->add((double) _pending_cards);
@@ -1619,18 +1134,23 @@
 
   // Note that _mmu_tracker->max_gc_time() returns the time in seconds.
   double update_rs_time_goal_ms = _mmu_tracker->max_gc_time() * MILLIUNITS * G1RSetUpdatingPauseTimePercent / 100.0;
-  adjust_concurrent_refinement(update_rs_time, update_rs_processed_buffers, update_rs_time_goal_ms);
+  adjust_concurrent_refinement(phase_times()->average_last_update_rs_time(),
+                               phase_times()->sum_last_update_rs_processed_buffers(), update_rs_time_goal_ms);
 
-  assert(assertMarkedBytesDataOK(), "Marked regions not OK at pause end.");
+  _collectionSetChooser->verify();
 }
 
-#define EXT_SIZE_FORMAT "%d%s"
+#define EXT_SIZE_FORMAT "%.1f%s"
 #define EXT_SIZE_PARAMS(bytes)                                  \
-  byte_size_in_proper_unit((bytes)),                            \
+  byte_size_in_proper_unit((double)(bytes)),                    \
   proper_unit_for_byte_size((bytes))
 
 void G1CollectorPolicy::print_heap_transition() {
-  if (PrintGCDetails) {
+  _g1->print_size_transition(gclog_or_tty,
+    _cur_collection_pause_used_at_start_bytes, _g1->used(), _g1->capacity());
+}
+
+void G1CollectorPolicy::print_detailed_heap_transition() {
     YoungList* young_list = _g1->young_list();
     size_t eden_bytes = young_list->eden_used_bytes();
     size_t survivor_bytes = young_list->survivor_used_bytes();
@@ -1657,11 +1177,6 @@
       EXT_SIZE_PARAMS(capacity));
 
     _prev_eden_capacity = eden_capacity;
-  } else if (PrintGC) {
-    _g1->print_size_transition(gclog_or_tty,
-                               _cur_collection_pause_used_at_start_bytes,
-                               _g1->used(), _g1->capacity());
-  }
 }
 
 void G1CollectorPolicy::adjust_concurrent_refinement(double update_rs_time,
@@ -1706,37 +1221,11 @@
 }
 
 double
-G1CollectorPolicy::
-predict_young_collection_elapsed_time_ms(size_t adjustment) {
-  guarantee( adjustment == 0 || adjustment == 1, "invariant" );
-
-  G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  size_t young_num = g1h->young_list()->length();
-  if (young_num == 0)
-    return 0.0;
-
-  young_num += adjustment;
-  size_t pending_cards = predict_pending_cards();
-  size_t rs_lengths = g1h->young_list()->sampled_rs_lengths() +
-                      predict_rs_length_diff();
-  size_t card_num;
-  if (gcs_are_young()) {
-    card_num = predict_young_card_num(rs_lengths);
-  } else {
-    card_num = predict_non_young_card_num(rs_lengths);
-  }
-  size_t young_byte_size = young_num * HeapRegion::GrainBytes;
-  double accum_yg_surv_rate =
-    _short_lived_surv_rate_group->accum_surv_rate(adjustment);
-
-  size_t bytes_to_copy =
-    (size_t) (accum_yg_surv_rate * (double) HeapRegion::GrainBytes);
-
+G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards,
+                                                size_t scanned_cards) {
   return
     predict_rs_update_time_ms(pending_cards) +
-    predict_rs_scan_time_ms(card_num) +
-    predict_object_copy_time_ms(bytes_to_copy) +
-    predict_young_other_time_ms(young_num) +
+    predict_rs_scan_time_ms(scanned_cards) +
     predict_constant_other_time_ms();
 }
 
@@ -1752,41 +1241,7 @@
   return predict_base_elapsed_time_ms(pending_cards, card_num);
 }
 
-double
-G1CollectorPolicy::predict_base_elapsed_time_ms(size_t pending_cards,
-                                                size_t scanned_cards) {
-  return
-    predict_rs_update_time_ms(pending_cards) +
-    predict_rs_scan_time_ms(scanned_cards) +
-    predict_constant_other_time_ms();
-}
-
-double
-G1CollectorPolicy::predict_region_elapsed_time_ms(HeapRegion* hr,
-                                                  bool young) {
-  size_t rs_length = hr->rem_set()->occupied();
-  size_t card_num;
-  if (gcs_are_young()) {
-    card_num = predict_young_card_num(rs_length);
-  } else {
-    card_num = predict_non_young_card_num(rs_length);
-  }
-  size_t bytes_to_copy = predict_bytes_to_copy(hr);
-
-  double region_elapsed_time_ms =
-    predict_rs_scan_time_ms(card_num) +
-    predict_object_copy_time_ms(bytes_to_copy);
-
-  if (young)
-    region_elapsed_time_ms += predict_young_other_time_ms(1);
-  else
-    region_elapsed_time_ms += predict_non_young_other_time_ms(1);
-
-  return region_elapsed_time_ms;
-}
-
-size_t
-G1CollectorPolicy::predict_bytes_to_copy(HeapRegion* hr) {
+size_t G1CollectorPolicy::predict_bytes_to_copy(HeapRegion* hr) {
   size_t bytes_to_copy;
   if (hr->is_marked())
     bytes_to_copy = hr->max_live_bytes();
@@ -1799,9 +1254,38 @@
   return bytes_to_copy;
 }
 
+double
+G1CollectorPolicy::predict_region_elapsed_time_ms(HeapRegion* hr,
+                                                  bool for_young_gc) {
+  size_t rs_length = hr->rem_set()->occupied();
+  size_t card_num;
+
+  // Predicting the number of cards is based on which type of GC
+  // we're predicting for.
+  if (for_young_gc) {
+    card_num = predict_young_card_num(rs_length);
+  } else {
+    card_num = predict_non_young_card_num(rs_length);
+  }
+  size_t bytes_to_copy = predict_bytes_to_copy(hr);
+
+  double region_elapsed_time_ms =
+    predict_rs_scan_time_ms(card_num) +
+    predict_object_copy_time_ms(bytes_to_copy);
+
+  // The prediction of the "other" time for this region is based
+  // upon the region type and NOT the GC type.
+  if (hr->is_young()) {
+    region_elapsed_time_ms += predict_young_other_time_ms(1);
+  } else {
+    region_elapsed_time_ms += predict_non_young_other_time_ms(1);
+  }
+  return region_elapsed_time_ms;
+}
+
 void
-G1CollectorPolicy::init_cset_region_lengths(size_t eden_cset_region_length,
-                                          size_t survivor_cset_region_length) {
+G1CollectorPolicy::init_cset_region_lengths(uint eden_cset_region_length,
+                                            uint survivor_cset_region_length) {
   _eden_cset_region_length     = eden_cset_region_length;
   _survivor_cset_region_length = survivor_cset_region_length;
   _old_cset_region_length      = 0;
@@ -1855,198 +1339,9 @@
   }
 }
 
-class CountCSClosure: public HeapRegionClosure {
-  G1CollectorPolicy* _g1_policy;
-public:
-  CountCSClosure(G1CollectorPolicy* g1_policy) :
-    _g1_policy(g1_policy) {}
-  bool doHeapRegion(HeapRegion* r) {
-    _g1_policy->_bytes_in_collection_set_before_gc += r->used();
-    return false;
-  }
-};
-
-void G1CollectorPolicy::count_CS_bytes_used() {
-  CountCSClosure cs_closure(this);
-  _g1->collection_set_iterate(&cs_closure);
-}
-
-void G1CollectorPolicy::print_summary(int level,
-                                      const char* str,
-                                      NumberSeq* seq) const {
-  double sum = seq->sum();
-  LineBuffer(level + 1).append_and_print_cr("%-24s = %8.2lf s (avg = %8.2lf ms)",
-                str, sum / 1000.0, seq->avg());
-}
-
-void G1CollectorPolicy::print_summary_sd(int level,
-                                         const char* str,
-                                         NumberSeq* seq) const {
-  print_summary(level, str, seq);
-  LineBuffer(level + 6).append_and_print_cr("(num = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
-                seq->num(), seq->sd(), seq->maximum());
-}
-
-void G1CollectorPolicy::check_other_times(int level,
-                                        NumberSeq* other_times_ms,
-                                        NumberSeq* calc_other_times_ms) const {
-  bool should_print = false;
-  LineBuffer buf(level + 2);
-
-  double max_sum = MAX2(fabs(other_times_ms->sum()),
-                        fabs(calc_other_times_ms->sum()));
-  double min_sum = MIN2(fabs(other_times_ms->sum()),
-                        fabs(calc_other_times_ms->sum()));
-  double sum_ratio = max_sum / min_sum;
-  if (sum_ratio > 1.1) {
-    should_print = true;
-    buf.append_and_print_cr("## CALCULATED OTHER SUM DOESN'T MATCH RECORDED ###");
-  }
-
-  double max_avg = MAX2(fabs(other_times_ms->avg()),
-                        fabs(calc_other_times_ms->avg()));
-  double min_avg = MIN2(fabs(other_times_ms->avg()),
-                        fabs(calc_other_times_ms->avg()));
-  double avg_ratio = max_avg / min_avg;
-  if (avg_ratio > 1.1) {
-    should_print = true;
-    buf.append_and_print_cr("## CALCULATED OTHER AVG DOESN'T MATCH RECORDED ###");
-  }
-
-  if (other_times_ms->sum() < -0.01) {
-    buf.append_and_print_cr("## RECORDED OTHER SUM IS NEGATIVE ###");
-  }
-
-  if (other_times_ms->avg() < -0.01) {
-    buf.append_and_print_cr("## RECORDED OTHER AVG IS NEGATIVE ###");
-  }
-
-  if (calc_other_times_ms->sum() < -0.01) {
-    should_print = true;
-    buf.append_and_print_cr("## CALCULATED OTHER SUM IS NEGATIVE ###");
-  }
-
-  if (calc_other_times_ms->avg() < -0.01) {
-    should_print = true;
-    buf.append_and_print_cr("## CALCULATED OTHER AVG IS NEGATIVE ###");
-  }
-
-  if (should_print)
-    print_summary(level, "Other(Calc)", calc_other_times_ms);
-}
-
-void G1CollectorPolicy::print_summary(PauseSummary* summary) const {
-  bool parallel = G1CollectedHeap::use_parallel_gc_threads();
-  MainBodySummary*    body_summary = summary->main_body_summary();
-  if (summary->get_total_seq()->num() > 0) {
-    print_summary_sd(0, "Evacuation Pauses", summary->get_total_seq());
-    if (body_summary != NULL) {
-      print_summary(1, "Root Region Scan Wait", body_summary->get_root_region_scan_wait_seq());
-      if (parallel) {
-        print_summary(1, "Parallel Time", body_summary->get_parallel_seq());
-        print_summary(2, "Ext Root Scanning", body_summary->get_ext_root_scan_seq());
-        print_summary(2, "SATB Filtering", body_summary->get_satb_filtering_seq());
-        print_summary(2, "Update RS", body_summary->get_update_rs_seq());
-        print_summary(2, "Scan RS", body_summary->get_scan_rs_seq());
-        print_summary(2, "Object Copy", body_summary->get_obj_copy_seq());
-        print_summary(2, "Termination", body_summary->get_termination_seq());
-        print_summary(2, "Parallel Other", body_summary->get_parallel_other_seq());
-        {
-          NumberSeq* other_parts[] = {
-            body_summary->get_ext_root_scan_seq(),
-            body_summary->get_satb_filtering_seq(),
-            body_summary->get_update_rs_seq(),
-            body_summary->get_scan_rs_seq(),
-            body_summary->get_obj_copy_seq(),
-            body_summary->get_termination_seq()
-          };
-          NumberSeq calc_other_times_ms(body_summary->get_parallel_seq(),
-                                        6, other_parts);
-          check_other_times(2, body_summary->get_parallel_other_seq(),
-                            &calc_other_times_ms);
-        }
-      } else {
-        print_summary(1, "Ext Root Scanning", body_summary->get_ext_root_scan_seq());
-        print_summary(1, "SATB Filtering", body_summary->get_satb_filtering_seq());
-        print_summary(1, "Update RS", body_summary->get_update_rs_seq());
-        print_summary(1, "Scan RS", body_summary->get_scan_rs_seq());
-        print_summary(1, "Object Copy", body_summary->get_obj_copy_seq());
-      }
-    }
-    print_summary(1, "Mark Closure", body_summary->get_mark_closure_seq());
-    print_summary(1, "Clear CT", body_summary->get_clear_ct_seq());
-    print_summary(1, "Other", summary->get_other_seq());
-    {
-      if (body_summary != NULL) {
-        NumberSeq calc_other_times_ms;
-        if (parallel) {
-          // parallel
-          NumberSeq* other_parts[] = {
-            body_summary->get_satb_drain_seq(),
-            body_summary->get_root_region_scan_wait_seq(),
-            body_summary->get_parallel_seq(),
-            body_summary->get_clear_ct_seq()
-          };
-          calc_other_times_ms = NumberSeq(summary->get_total_seq(),
-                                          4, other_parts);
-        } else {
-          // serial
-          NumberSeq* other_parts[] = {
-            body_summary->get_satb_drain_seq(),
-            body_summary->get_root_region_scan_wait_seq(),
-            body_summary->get_update_rs_seq(),
-            body_summary->get_ext_root_scan_seq(),
-            body_summary->get_satb_filtering_seq(),
-            body_summary->get_scan_rs_seq(),
-            body_summary->get_obj_copy_seq()
-          };
-          calc_other_times_ms = NumberSeq(summary->get_total_seq(),
-                                          7, other_parts);
-        }
-        check_other_times(1,  summary->get_other_seq(), &calc_other_times_ms);
-      }
-    }
-  } else {
-    LineBuffer(1).append_and_print_cr("none");
-  }
-  LineBuffer(0).append_and_print_cr("");
-}
-
 void G1CollectorPolicy::print_tracing_info() const {
-  if (TraceGen0Time) {
-    gclog_or_tty->print_cr("ALL PAUSES");
-    print_summary_sd(0, "Total", _all_pause_times_ms);
-    gclog_or_tty->print_cr("");
-    gclog_or_tty->print_cr("");
-    gclog_or_tty->print_cr("   Young GC Pauses: %8d", _young_pause_num);
-    gclog_or_tty->print_cr("   Mixed GC Pauses: %8d", _mixed_pause_num);
-    gclog_or_tty->print_cr("");
-
-    gclog_or_tty->print_cr("EVACUATION PAUSES");
-    print_summary(_summary);
-
-    gclog_or_tty->print_cr("MISC");
-    print_summary_sd(0, "Stop World", _all_stop_world_times_ms);
-    print_summary_sd(0, "Yields", _all_yield_times_ms);
-    for (int i = 0; i < _aux_num; ++i) {
-      if (_all_aux_times_ms[i].num() > 0) {
-        char buffer[96];
-        sprintf(buffer, "Aux%d", i);
-        print_summary_sd(0, buffer, &_all_aux_times_ms[i]);
-      }
-    }
-  }
-  if (TraceGen1Time) {
-    if (_all_full_gc_times_ms->num() > 0) {
-      gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s",
-                 _all_full_gc_times_ms->num(),
-                 _all_full_gc_times_ms->sum() / 1000.0);
-      gclog_or_tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times_ms->avg());
-      gclog_or_tty->print_cr("                     [std. dev = %8.2f ms, max = %8.2f ms]",
-                    _all_full_gc_times_ms->sd(),
-                    _all_full_gc_times_ms->maximum());
-    }
-  }
+  _trace_gen0_time_data.print();
+  _trace_gen1_time_data.print();
 }
 
 void G1CollectorPolicy::print_yg_surv_rate_info() const {
@@ -2068,7 +1363,7 @@
 }
 #endif // PRODUCT
 
-size_t G1CollectorPolicy::max_regions(int purpose) {
+uint G1CollectorPolicy::max_regions(int purpose) {
   switch (purpose) {
     case GCAllocForSurvived:
       return _max_survivor_regions;
@@ -2081,13 +1376,13 @@
 }
 
 void G1CollectorPolicy::update_max_gc_locker_expansion() {
-  size_t expansion_region_num = 0;
+  uint expansion_region_num = 0;
   if (GCLockerEdenExpansionPercent > 0) {
     double perc = (double) GCLockerEdenExpansionPercent / 100.0;
     double expansion_region_num_d = perc * (double) _young_list_target_length;
     // We use ceiling so that if expansion_region_num_d is > 0.0 (but
     // less than 1.0) we'll get 1.
-    expansion_region_num = (size_t) ceil(expansion_region_num_d);
+    expansion_region_num = (uint) ceil(expansion_region_num_d);
   } else {
     assert(expansion_region_num == 0, "sanity");
   }
@@ -2101,34 +1396,12 @@
                  (double) _young_list_target_length / (double) SurvivorRatio;
   // We use ceiling so that if max_survivor_regions_d is > 0.0 (but
   // smaller than 1.0) we'll get 1.
-  _max_survivor_regions = (size_t) ceil(max_survivor_regions_d);
+  _max_survivor_regions = (uint) ceil(max_survivor_regions_d);
 
   _tenuring_threshold = _survivors_age_table.compute_tenuring_threshold(
         HeapRegion::GrainWords * _max_survivor_regions);
 }
 
-#ifndef PRODUCT
-class HRSortIndexIsOKClosure: public HeapRegionClosure {
-  CollectionSetChooser* _chooser;
-public:
-  HRSortIndexIsOKClosure(CollectionSetChooser* chooser) :
-    _chooser(chooser) {}
-
-  bool doHeapRegion(HeapRegion* r) {
-    if (!r->continuesHumongous()) {
-      assert(_chooser->regionProperlyOrdered(r), "Ought to be.");
-    }
-    return false;
-  }
-};
-
-bool G1CollectorPolicy::assertMarkedBytesDataOK() {
-  HRSortIndexIsOKClosure cl(_collectionSetChooser);
-  _g1->heap_region_iterate(&cl);
-  return true;
-}
-#endif
-
 bool G1CollectorPolicy::force_initial_mark_if_outside_cycle(
                                                      GCCause::Cause gc_cause) {
   bool during_cycle = _g1->concurrent_mark()->cmThread()->during_cycle();
@@ -2226,8 +1499,8 @@
       // We will skip any region that's currently used as an old GC
       // alloc region (we should not consider those for collection
       // before we fill them up).
-      if (_hrSorted->shouldAdd(r) && !_g1h->is_old_gc_alloc_region(r)) {
-        _hrSorted->addMarkedHeapRegion(r);
+      if (_hrSorted->should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
+        _hrSorted->add_region(r);
       }
     }
     return false;
@@ -2236,130 +1509,75 @@
 
 class ParKnownGarbageHRClosure: public HeapRegionClosure {
   G1CollectedHeap* _g1h;
-  CollectionSetChooser* _hrSorted;
-  jint _marked_regions_added;
-  size_t _reclaimable_bytes_added;
-  jint _chunk_size;
-  jint _cur_chunk_idx;
-  jint _cur_chunk_end; // Cur chunk [_cur_chunk_idx, _cur_chunk_end)
-  int _worker;
-  int _invokes;
-
-  void get_new_chunk() {
-    _cur_chunk_idx = _hrSorted->getParMarkedHeapRegionChunk(_chunk_size);
-    _cur_chunk_end = _cur_chunk_idx + _chunk_size;
-  }
-  void add_region(HeapRegion* r) {
-    if (_cur_chunk_idx == _cur_chunk_end) {
-      get_new_chunk();
-    }
-    assert(_cur_chunk_idx < _cur_chunk_end, "postcondition");
-    _hrSorted->setMarkedHeapRegion(_cur_chunk_idx, r);
-    _marked_regions_added++;
-    _reclaimable_bytes_added += r->reclaimable_bytes();
-    _cur_chunk_idx++;
-  }
+  CSetChooserParUpdater _cset_updater;
 
 public:
   ParKnownGarbageHRClosure(CollectionSetChooser* hrSorted,
-                           jint chunk_size,
-                           int worker) :
-      _g1h(G1CollectedHeap::heap()),
-      _hrSorted(hrSorted), _chunk_size(chunk_size), _worker(worker),
-      _marked_regions_added(0), _reclaimable_bytes_added(0),
-      _cur_chunk_idx(0), _cur_chunk_end(0), _invokes(0) { }
+                           uint chunk_size) :
+    _g1h(G1CollectedHeap::heap()),
+    _cset_updater(hrSorted, true /* parallel */, chunk_size) { }
 
   bool doHeapRegion(HeapRegion* r) {
-    // We only include humongous regions in collection
-    // sets when concurrent mark shows that their contained object is
-    // unreachable.
-    _invokes++;
-
     // Do we have any marking information for this region?
     if (r->is_marked()) {
       // We will skip any region that's currently used as an old GC
       // alloc region (we should not consider those for collection
       // before we fill them up).
-      if (_hrSorted->shouldAdd(r) && !_g1h->is_old_gc_alloc_region(r)) {
-        add_region(r);
+      if (_cset_updater.should_add(r) && !_g1h->is_old_gc_alloc_region(r)) {
+        _cset_updater.add_region(r);
       }
     }
     return false;
   }
-  jint marked_regions_added() { return _marked_regions_added; }
-  size_t reclaimable_bytes_added() { return _reclaimable_bytes_added; }
-  int invokes() { return _invokes; }
 };
 
 class ParKnownGarbageTask: public AbstractGangTask {
   CollectionSetChooser* _hrSorted;
-  jint _chunk_size;
+  uint _chunk_size;
   G1CollectedHeap* _g1;
 public:
-  ParKnownGarbageTask(CollectionSetChooser* hrSorted, jint chunk_size) :
+  ParKnownGarbageTask(CollectionSetChooser* hrSorted, uint chunk_size) :
     AbstractGangTask("ParKnownGarbageTask"),
     _hrSorted(hrSorted), _chunk_size(chunk_size),
     _g1(G1CollectedHeap::heap()) { }
 
   void work(uint worker_id) {
-    ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted,
-                                               _chunk_size,
-                                               worker_id);
+    ParKnownGarbageHRClosure parKnownGarbageCl(_hrSorted, _chunk_size);
+
     // Back to zero for the claim value.
     _g1->heap_region_par_iterate_chunked(&parKnownGarbageCl, worker_id,
                                          _g1->workers()->active_workers(),
                                          HeapRegion::InitialClaimValue);
-    jint regions_added = parKnownGarbageCl.marked_regions_added();
-    size_t reclaimable_bytes_added =
-                                   parKnownGarbageCl.reclaimable_bytes_added();
-    _hrSorted->updateTotals(regions_added, reclaimable_bytes_added);
-    if (G1PrintParCleanupStats) {
-      gclog_or_tty->print_cr("     Thread %d called %d times, added %d regions to list.",
-                 worker_id, parKnownGarbageCl.invokes(), regions_added);
-    }
   }
 };
 
 void
 G1CollectorPolicy::record_concurrent_mark_cleanup_end(int no_of_gc_threads) {
-  double start_sec;
-  if (G1PrintParCleanupStats) {
-    start_sec = os::elapsedTime();
-  }
+  _collectionSetChooser->clear();
 
-  _collectionSetChooser->clearMarkedHeapRegions();
-  double clear_marked_end_sec;
-  if (G1PrintParCleanupStats) {
-    clear_marked_end_sec = os::elapsedTime();
-    gclog_or_tty->print_cr("  clear marked regions: %8.3f ms.",
-                           (clear_marked_end_sec - start_sec) * 1000.0);
-  }
-
+  uint region_num = _g1->n_regions();
   if (G1CollectedHeap::use_parallel_gc_threads()) {
-    const size_t OverpartitionFactor = 4;
-    size_t WorkUnit;
+    const uint OverpartitionFactor = 4;
+    uint WorkUnit;
     // The use of MinChunkSize = 8 in the original code
     // causes some assertion failures when the total number of
     // region is less than 8.  The code here tries to fix that.
     // Should the original code also be fixed?
     if (no_of_gc_threads > 0) {
-      const size_t MinWorkUnit =
-        MAX2(_g1->n_regions() / no_of_gc_threads, (size_t) 1U);
-      WorkUnit =
-        MAX2(_g1->n_regions() / (no_of_gc_threads * OverpartitionFactor),
-             MinWorkUnit);
+      const uint MinWorkUnit = MAX2(region_num / no_of_gc_threads, 1U);
+      WorkUnit = MAX2(region_num / (no_of_gc_threads * OverpartitionFactor),
+                      MinWorkUnit);
     } else {
       assert(no_of_gc_threads > 0,
         "The active gc workers should be greater than 0");
       // In a product build do something reasonable to avoid a crash.
-      const size_t MinWorkUnit =
-        MAX2(_g1->n_regions() / ParallelGCThreads, (size_t) 1U);
+      const uint MinWorkUnit = MAX2(region_num / (uint) ParallelGCThreads, 1U);
       WorkUnit =
-        MAX2(_g1->n_regions() / (ParallelGCThreads * OverpartitionFactor),
+        MAX2(region_num / (uint) (ParallelGCThreads * OverpartitionFactor),
              MinWorkUnit);
     }
-    _collectionSetChooser->prepareForAddMarkedHeapRegionsPar(_g1->n_regions(),
-                                                             WorkUnit);
+    _collectionSetChooser->prepare_for_par_region_addition(_g1->n_regions(),
+                                                           WorkUnit);
     ParKnownGarbageTask parKnownGarbageTask(_collectionSetChooser,
                                             (int) WorkUnit);
     _g1->workers()->run_task(&parKnownGarbageTask);
@@ -2370,20 +1588,10 @@
     KnownGarbageClosure knownGarbagecl(_collectionSetChooser);
     _g1->heap_region_iterate(&knownGarbagecl);
   }
-  double known_garbage_end_sec;
-  if (G1PrintParCleanupStats) {
-    known_garbage_end_sec = os::elapsedTime();
-    gclog_or_tty->print_cr("  compute known garbage: %8.3f ms.",
-                      (known_garbage_end_sec - clear_marked_end_sec) * 1000.0);
-  }
 
-  _collectionSetChooser->sortMarkedHeapRegions();
+  _collectionSetChooser->sort_regions();
+
   double end_sec = os::elapsedTime();
-  if (G1PrintParCleanupStats) {
-    gclog_or_tty->print_cr("  sorting: %8.3f ms.",
-                           (end_sec - known_garbage_end_sec) * 1000.0);
-  }
-
   double elapsed_time_ms = (end_sec - _mark_cleanup_start_sec) * 1000.0;
   _concurrent_mark_cleanup_times_ms->add(elapsed_time_ms);
   _cur_mark_stop_world_time_ms += elapsed_time_ms;
@@ -2469,7 +1677,7 @@
   // retiring the current allocation region) or a concurrent
   // refine thread (RSet sampling).
 
-  double region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, true);
+  double region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
   size_t used_bytes = hr->used();
   _inc_cset_recorded_rs_lengths += rs_length;
   _inc_cset_predicted_elapsed_time_ms += region_elapsed_time_ms;
@@ -2504,7 +1712,7 @@
   _inc_cset_recorded_rs_lengths_diffs += rs_lengths_diff;
 
   double old_elapsed_time_ms = hr->predicted_elapsed_time_ms();
-  double new_region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, true);
+  double new_region_elapsed_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
   double elapsed_ms_diff = new_region_elapsed_time_ms - old_elapsed_time_ms;
   _inc_cset_predicted_elapsed_time_ms_diffs += elapsed_ms_diff;
 
@@ -2581,16 +1789,10 @@
   while (csr != NULL) {
     HeapRegion* next = csr->next_in_collection_set();
     assert(csr->in_collection_set(), "bad CS");
-    st->print_cr("  [%08x-%08x], t: %08x, P: %08x, N: %08x, C: %08x, "
-                 "age: %4d, y: %d, surv: %d",
-                        csr->bottom(), csr->end(),
-                        csr->top(),
-                        csr->prev_top_at_mark_start(),
-                        csr->next_top_at_mark_start(),
-                        csr->top_at_conc_mark_count(),
-                        csr->age_in_surv_rate_group_cond(),
-                        csr->is_young(),
-                        csr->is_survivor());
+    st->print_cr("  "HR_FORMAT", P: "PTR_FORMAT "N: "PTR_FORMAT", age: %4d",
+                 HR_FORMAT_PARAMS(csr),
+                 csr->prev_top_at_mark_start(), csr->next_top_at_mark_start(),
+                 csr->age_in_surv_rate_group_cond());
     csr = next;
   }
 }
@@ -2599,16 +1801,16 @@
 bool G1CollectorPolicy::next_gc_should_be_mixed(const char* true_action_str,
                                                 const char* false_action_str) {
   CollectionSetChooser* cset_chooser = _collectionSetChooser;
-  if (cset_chooser->isEmpty()) {
+  if (cset_chooser->is_empty()) {
     ergo_verbose0(ErgoMixedGCs,
                   false_action_str,
                   ergo_format_reason("candidate old regions not available"));
     return false;
   }
-  size_t reclaimable_bytes = cset_chooser->remainingReclaimableBytes();
+  size_t reclaimable_bytes = cset_chooser->remaining_reclaimable_bytes();
   size_t capacity_bytes = _g1->capacity();
   double perc = (double) reclaimable_bytes * 100.0 / (double) capacity_bytes;
-  double threshold = (double) G1OldReclaimableThresholdPercent;
+  double threshold = (double) G1HeapWastePercent;
   if (perc < threshold) {
     ergo_verbose4(ErgoMixedGCs,
               false_action_str,
@@ -2616,7 +1818,7 @@
               ergo_format_region("candidate old regions")
               ergo_format_byte_perc("reclaimable")
               ergo_format_perc("threshold"),
-              cset_chooser->remainingRegions(),
+              cset_chooser->remaining_regions(),
               reclaimable_bytes, perc, threshold);
     return false;
   }
@@ -2627,14 +1829,13 @@
                 ergo_format_region("candidate old regions")
                 ergo_format_byte_perc("reclaimable")
                 ergo_format_perc("threshold"),
-                cset_chooser->remainingRegions(),
+                cset_chooser->remaining_regions(),
                 reclaimable_bytes, perc, threshold);
   return true;
 }
 
 void G1CollectorPolicy::finalize_cset(double target_pause_time_ms) {
-  // Set this here - in case we're not doing young collections.
-  double non_young_start_time_sec = os::elapsedTime();
+  double young_start_time_sec = os::elapsedTime();
 
   YoungList* young_list = _g1->young_list();
   finalize_incremental_cset_building();
@@ -2648,33 +1849,31 @@
   double predicted_pause_time_ms = base_time_ms;
   double time_remaining_ms = target_pause_time_ms - base_time_ms;
 
-  ergo_verbose3(ErgoCSetConstruction | ErgoHigh,
+  ergo_verbose4(ErgoCSetConstruction | ErgoHigh,
                 "start choosing CSet",
+                ergo_format_size("_pending_cards")
                 ergo_format_ms("predicted base time")
                 ergo_format_ms("remaining time")
                 ergo_format_ms("target pause time"),
-                base_time_ms, time_remaining_ms, target_pause_time_ms);
+                _pending_cards, base_time_ms, time_remaining_ms, target_pause_time_ms);
 
-  HeapRegion* hr;
-  double young_start_time_sec = os::elapsedTime();
-
-  _collection_set_bytes_used_before = 0;
   _last_gc_was_young = gcs_are_young() ? true : false;
 
   if (_last_gc_was_young) {
-    ++_young_pause_num;
+    _trace_gen0_time_data.increment_young_collection_count();
   } else {
-    ++_mixed_pause_num;
+    _trace_gen0_time_data.increment_mixed_collection_count();
   }
 
   // The young list is laid with the survivor regions from the previous
   // pause are appended to the RHS of the young list, i.e.
   //   [Newly Young Regions ++ Survivors from last pause].
 
-  size_t survivor_region_length = young_list->survivor_length();
-  size_t eden_region_length = young_list->length() - survivor_region_length;
+  uint survivor_region_length = young_list->survivor_length();
+  uint eden_region_length = young_list->length() - survivor_region_length;
   init_cset_region_lengths(eden_region_length, survivor_region_length);
-  hr = young_list->first_survivor_region();
+
+  HeapRegion* hr = young_list->first_survivor_region();
   while (hr != NULL) {
     assert(hr->is_survivor(), "badly formed young list");
     hr->set_young();
@@ -2702,20 +1901,20 @@
   set_recorded_rs_lengths(_inc_cset_recorded_rs_lengths);
 
   double young_end_time_sec = os::elapsedTime();
-  _recorded_young_cset_choice_time_ms =
-    (young_end_time_sec - young_start_time_sec) * 1000.0;
+  phase_times()->record_young_cset_choice_time_ms((young_end_time_sec - young_start_time_sec) * 1000.0);
 
-  // We are doing young collections so reset this.
-  non_young_start_time_sec = young_end_time_sec;
+  // Set the start of the non-young choice time.
+  double non_young_start_time_sec = young_end_time_sec;
 
   if (!gcs_are_young()) {
     CollectionSetChooser* cset_chooser = _collectionSetChooser;
-    assert(cset_chooser->verify(), "CSet Chooser verification - pre");
-    const size_t min_old_cset_length = cset_chooser->calcMinOldCSetLength();
-    const size_t max_old_cset_length = cset_chooser->calcMaxOldCSetLength();
+    cset_chooser->verify();
+    const uint min_old_cset_length = cset_chooser->calc_min_old_cset_length();
+    const uint max_old_cset_length = cset_chooser->calc_max_old_cset_length();
 
-    size_t expensive_region_num = 0;
+    uint expensive_region_num = 0;
     bool check_time_remaining = adaptive_young_list_length();
+
     HeapRegion* hr = cset_chooser->peek();
     while (hr != NULL) {
       if (old_cset_region_length() >= max_old_cset_length) {
@@ -2729,7 +1928,7 @@
         break;
       }
 
-      double predicted_time_ms = predict_region_elapsed_time_ms(hr, false);
+      double predicted_time_ms = predict_region_elapsed_time_ms(hr, gcs_are_young());
       if (check_time_remaining) {
         if (predicted_time_ms > time_remaining_ms) {
           // Too expensive for the current CSet.
@@ -2799,13 +1998,11 @@
                     time_remaining_ms);
     }
 
-    assert(cset_chooser->verify(), "CSet Chooser verification - post");
+    cset_chooser->verify();
   }
 
   stop_incremental_cset_building();
 
-  count_CS_bytes_used();
-
   ergo_verbose5(ErgoCSetConstruction,
                 "finish choosing CSet",
                 ergo_format_region("eden")
@@ -2818,6 +2015,129 @@
                 predicted_pause_time_ms, target_pause_time_ms);
 
   double non_young_end_time_sec = os::elapsedTime();
-  _recorded_non_young_cset_choice_time_ms =
-    (non_young_end_time_sec - non_young_start_time_sec) * 1000.0;
+  phase_times()->record_non_young_cset_choice_time_ms((non_young_end_time_sec - non_young_start_time_sec) * 1000.0);
+}
+
+void TraceGen0TimeData::record_start_collection(double time_to_stop_the_world_ms) {
+  if(TraceGen0Time) {
+    _all_stop_world_times_ms.add(time_to_stop_the_world_ms);
+  }
+}
+
+void TraceGen0TimeData::record_yield_time(double yield_time_ms) {
+  if(TraceGen0Time) {
+    _all_yield_times_ms.add(yield_time_ms);
+  }
+}
+
+void TraceGen0TimeData::record_end_collection(double pause_time_ms, G1GCPhaseTimes* phase_times) {
+  if(TraceGen0Time) {
+    _total.add(pause_time_ms);
+    _other.add(pause_time_ms - phase_times->accounted_time_ms());
+    _root_region_scan_wait.add(phase_times->root_region_scan_wait_time_ms());
+    _parallel.add(phase_times->cur_collection_par_time_ms());
+    _ext_root_scan.add(phase_times->average_last_ext_root_scan_time());
+    _satb_filtering.add(phase_times->average_last_satb_filtering_times_ms());
+    _update_rs.add(phase_times->average_last_update_rs_time());
+    _scan_rs.add(phase_times->average_last_scan_rs_time());
+    _obj_copy.add(phase_times->average_last_obj_copy_time());
+    _termination.add(phase_times->average_last_termination_time());
+
+    double parallel_known_time = phase_times->average_last_ext_root_scan_time() +
+      phase_times->average_last_satb_filtering_times_ms() +
+      phase_times->average_last_update_rs_time() +
+      phase_times->average_last_scan_rs_time() +
+      phase_times->average_last_obj_copy_time() +
+      + phase_times->average_last_termination_time();
+
+    double parallel_other_time = phase_times->cur_collection_par_time_ms() - parallel_known_time;
+    _parallel_other.add(parallel_other_time);
+    _clear_ct.add(phase_times->cur_clear_ct_time_ms());
+  }
+}
+
+void TraceGen0TimeData::increment_young_collection_count() {
+  if(TraceGen0Time) {
+    ++_young_pause_num;
+  }
+}
+
+void TraceGen0TimeData::increment_mixed_collection_count() {
+  if(TraceGen0Time) {
+    ++_mixed_pause_num;
+  }
+}
+
+void TraceGen0TimeData::print_summary(const char* str,
+                                      const NumberSeq* seq) const {
+  double sum = seq->sum();
+  gclog_or_tty->print_cr("%-27s = %8.2lf s (avg = %8.2lf ms)",
+                str, sum / 1000.0, seq->avg());
+}
+
+void TraceGen0TimeData::print_summary_sd(const char* str,
+                                         const NumberSeq* seq) const {
+  print_summary(str, seq);
+  gclog_or_tty->print_cr("%+45s = %5d, std dev = %8.2lf ms, max = %8.2lf ms)",
+                "(num", seq->num(), seq->sd(), seq->maximum());
+}
+
+void TraceGen0TimeData::print() const {
+  if (!TraceGen0Time) {
+    return;
+  }
+
+  gclog_or_tty->print_cr("ALL PAUSES");
+  print_summary_sd("   Total", &_total);
+  gclog_or_tty->print_cr("");
+  gclog_or_tty->print_cr("");
+  gclog_or_tty->print_cr("   Young GC Pauses: %8d", _young_pause_num);
+  gclog_or_tty->print_cr("   Mixed GC Pauses: %8d", _mixed_pause_num);
+  gclog_or_tty->print_cr("");
+
+  gclog_or_tty->print_cr("EVACUATION PAUSES");
+
+  if (_young_pause_num == 0 && _mixed_pause_num == 0) {
+    gclog_or_tty->print_cr("none");
+  } else {
+    print_summary_sd("   Evacuation Pauses", &_total);
+    print_summary("      Root Region Scan Wait", &_root_region_scan_wait);
+    print_summary("      Parallel Time", &_parallel);
+    print_summary("         Ext Root Scanning", &_ext_root_scan);
+    print_summary("         SATB Filtering", &_satb_filtering);
+    print_summary("         Update RS", &_update_rs);
+    print_summary("         Scan RS", &_scan_rs);
+    print_summary("         Object Copy", &_obj_copy);
+    print_summary("         Termination", &_termination);
+    print_summary("         Parallel Other", &_parallel_other);
+    print_summary("      Clear CT", &_clear_ct);
+    print_summary("      Other", &_other);
+  }
+  gclog_or_tty->print_cr("");
+
+  gclog_or_tty->print_cr("MISC");
+  print_summary_sd("   Stop World", &_all_stop_world_times_ms);
+  print_summary_sd("   Yields", &_all_yield_times_ms);
+}
+
+void TraceGen1TimeData::record_full_collection(double full_gc_time_ms) {
+  if (TraceGen1Time) {
+    _all_full_gc_times.add(full_gc_time_ms);
+  }
+}
+
+void TraceGen1TimeData::print() const {
+  if (!TraceGen1Time) {
+    return;
+  }
+
+  if (_all_full_gc_times.num() > 0) {
+    gclog_or_tty->print("\n%4d full_gcs: total time = %8.2f s",
+      _all_full_gc_times.num(),
+      _all_full_gc_times.sum() / 1000.0);
+    gclog_or_tty->print_cr(" (avg = %8.2fms).", _all_full_gc_times.avg());
+    gclog_or_tty->print_cr("                     [std. dev = %8.2f ms, max = %8.2f ms]",
+      _all_full_gc_times.sd(),
+      _all_full_gc_times.maximum());
+  }
 }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
index 213e0aa..fdeaf8e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp
@@ -36,52 +36,52 @@
 
 class HeapRegion;
 class CollectionSetChooser;
+class G1GCPhaseTimes;
 
-// Yes, this is a bit unpleasant... but it saves replicating the same thing
-// over and over again and introducing subtle problems through small typos and
-// cutting and pasting mistakes. The macros below introduces a number
-// sequnce into the following two classes and the methods that access it.
+// TraceGen0Time collects data on _both_ young and mixed evacuation pauses
+// (the latter may contain non-young regions - i.e. regions that are
+// technically in Gen1) while TraceGen1Time collects data about full GCs.
+class TraceGen0TimeData : public CHeapObj<mtGC> {
+ private:
+  unsigned  _young_pause_num;
+  unsigned  _mixed_pause_num;
 
-#define define_num_seq(name)                                                  \
-private:                                                                      \
-  NumberSeq _all_##name##_times_ms;                                           \
-public:                                                                       \
-  void record_##name##_time_ms(double ms) {                                   \
-    _all_##name##_times_ms.add(ms);                                           \
-  }                                                                           \
-  NumberSeq* get_##name##_seq() {                                             \
-    return &_all_##name##_times_ms;                                           \
-  }
+  NumberSeq _all_stop_world_times_ms;
+  NumberSeq _all_yield_times_ms;
 
-class MainBodySummary;
+  NumberSeq _total;
+  NumberSeq _other;
+  NumberSeq _root_region_scan_wait;
+  NumberSeq _parallel;
+  NumberSeq _ext_root_scan;
+  NumberSeq _satb_filtering;
+  NumberSeq _update_rs;
+  NumberSeq _scan_rs;
+  NumberSeq _obj_copy;
+  NumberSeq _termination;
+  NumberSeq _parallel_other;
+  NumberSeq _clear_ct;
 
-class PauseSummary: public CHeapObj {
-  define_num_seq(total)
-    define_num_seq(other)
+  void print_summary(const char* str, const NumberSeq* seq) const;
+  void print_summary_sd(const char* str, const NumberSeq* seq) const;
 
 public:
-  virtual MainBodySummary*    main_body_summary()    { return NULL; }
+   TraceGen0TimeData() : _young_pause_num(0), _mixed_pause_num(0) {};
+  void record_start_collection(double time_to_stop_the_world_ms);
+  void record_yield_time(double yield_time_ms);
+  void record_end_collection(double pause_time_ms, G1GCPhaseTimes* phase_times);
+  void increment_young_collection_count();
+  void increment_mixed_collection_count();
+  void print() const;
 };
 
-class MainBodySummary: public CHeapObj {
-  define_num_seq(satb_drain) // optional
-  define_num_seq(root_region_scan_wait)
-  define_num_seq(parallel) // parallel only
-    define_num_seq(ext_root_scan)
-    define_num_seq(satb_filtering)
-    define_num_seq(update_rs)
-    define_num_seq(scan_rs)
-    define_num_seq(obj_copy)
-    define_num_seq(termination) // parallel only
-    define_num_seq(parallel_other) // parallel only
-  define_num_seq(mark_closure)
-  define_num_seq(clear_ct)
-};
+class TraceGen1TimeData : public CHeapObj<mtGC> {
+ private:
+  NumberSeq _all_full_gc_times;
 
-class Summary: public PauseSummary,
-               public MainBodySummary {
-public:
-  virtual MainBodySummary*    main_body_summary()    { return this; }
+ public:
+  void record_full_collection(double full_gc_time_ms);
+  void print() const;
 };
 
 // There are three command line options related to the young gen size:
@@ -120,7 +120,7 @@
 //
 // NewSize and MaxNewSize override NewRatio. So, NewRatio is ignored if it is
 // combined with either NewSize or MaxNewSize. (A warning message is printed.)
-class G1YoungGenSizer : public CHeapObj {
+class G1YoungGenSizer : public CHeapObj<mtGC> {
 private:
   enum SizerKind {
     SizerDefaults,
@@ -130,19 +130,19 @@
     SizerNewRatio
   };
   SizerKind _sizer_kind;
-  size_t _min_desired_young_length;
-  size_t _max_desired_young_length;
+  uint _min_desired_young_length;
+  uint _max_desired_young_length;
   bool _adaptive_size;
-  size_t calculate_default_min_length(size_t new_number_of_heap_regions);
-  size_t calculate_default_max_length(size_t new_number_of_heap_regions);
+  uint calculate_default_min_length(uint new_number_of_heap_regions);
+  uint calculate_default_max_length(uint new_number_of_heap_regions);
 
 public:
   G1YoungGenSizer();
-  void heap_size_changed(size_t new_number_of_heap_regions);
-  size_t min_desired_young_length() {
+  void heap_size_changed(uint new_number_of_heap_regions);
+  uint min_desired_young_length() {
     return _min_desired_young_length;
   }
-  size_t max_desired_young_length() {
+  uint max_desired_young_length() {
     return _max_desired_young_length;
   }
   bool adaptive_young_list_length() {
@@ -175,23 +175,9 @@
 
   CollectionSetChooser* _collectionSetChooser;
 
-  double _cur_collection_start_sec;
+  double _full_collection_start_sec;
   size_t _cur_collection_pause_used_at_start_bytes;
-  size_t _cur_collection_pause_used_regions_at_start;
-  double _cur_collection_par_time_ms;
-  double _cur_satb_drain_time_ms;
-  double _cur_clear_ct_time_ms;
-  double _cur_ref_proc_time_ms;
-  double _cur_ref_enq_time_ms;
-
-#ifndef PRODUCT
-  // Card Table Count Cache stats
-  double _min_clear_cc_time_ms;         // min
-  double _max_clear_cc_time_ms;         // max
-  double _cur_clear_cc_time_ms;         // clearing time during current pause
-  double _cum_clear_cc_time_ms;         // cummulative clearing time
-  jlong  _num_cc_clears;                // number of times the card count cache has been cleared
-#endif
+  uint   _cur_collection_pause_used_regions_at_start;
 
   // These exclude marking times.
   TruncatedSeq* _recent_gc_times_ms;
@@ -199,53 +185,24 @@
   TruncatedSeq* _concurrent_mark_remark_times_ms;
   TruncatedSeq* _concurrent_mark_cleanup_times_ms;
 
-  Summary*           _summary;
+  TraceGen0TimeData _trace_gen0_time_data;
+  TraceGen1TimeData _trace_gen1_time_data;
 
-  NumberSeq* _all_pause_times_ms;
-  NumberSeq* _all_full_gc_times_ms;
   double _stop_world_start;
-  NumberSeq* _all_stop_world_times_ms;
-  NumberSeq* _all_yield_times_ms;
-
-  int        _aux_num;
-  NumberSeq* _all_aux_times_ms;
-  double*    _cur_aux_start_times_ms;
-  double*    _cur_aux_times_ms;
-  bool*      _cur_aux_times_set;
-
-  double* _par_last_gc_worker_start_times_ms;
-  double* _par_last_ext_root_scan_times_ms;
-  double* _par_last_satb_filtering_times_ms;
-  double* _par_last_update_rs_times_ms;
-  double* _par_last_update_rs_processed_buffers;
-  double* _par_last_scan_rs_times_ms;
-  double* _par_last_obj_copy_times_ms;
-  double* _par_last_termination_times_ms;
-  double* _par_last_termination_attempts;
-  double* _par_last_gc_worker_end_times_ms;
-  double* _par_last_gc_worker_times_ms;
-
-  // Each workers 'other' time i.e. the elapsed time of the parallel
-  // phase of the pause minus the sum of the individual sub-phase
-  // times for a given worker thread.
-  double* _par_last_gc_worker_other_times_ms;
 
   // indicates whether we are in young or mixed GC mode
   bool _gcs_are_young;
 
-  size_t _young_list_target_length;
-  size_t _young_list_fixed_length;
+  uint _young_list_target_length;
+  uint _young_list_fixed_length;
   size_t _prev_eden_capacity; // used for logging
 
   // The max number of regions we can extend the eden by while the GC
   // locker is active. This should be >= _young_list_target_length;
-  size_t _young_list_max_length;
+  uint _young_list_max_length;
 
   bool                  _last_gc_was_young;
 
-  unsigned              _young_pause_num;
-  unsigned              _mixed_pause_num;
-
   bool                  _during_marking;
   bool                  _in_marking_window;
   bool                  _in_marking_window_im;
@@ -257,7 +214,7 @@
   double                _gc_overhead_perc;
 
   double _reserve_factor;
-  size_t _reserve_regions;
+  uint _reserve_regions;
 
   bool during_marking() {
     return _during_marking;
@@ -271,7 +228,6 @@
   TruncatedSeq* _alloc_rate_ms_seq;
   double        _prev_collection_pause_end_ms;
 
-  TruncatedSeq* _pending_card_diff_seq;
   TruncatedSeq* _rs_length_diff_seq;
   TruncatedSeq* _cost_per_card_ms_seq;
   TruncatedSeq* _young_cards_per_entry_ratio_seq;
@@ -288,36 +244,27 @@
 
   TruncatedSeq* _cost_per_byte_ms_during_cm_seq;
 
-  TruncatedSeq* _young_gc_eff_seq;
-
   G1YoungGenSizer* _young_gen_sizer;
 
-  size_t _eden_cset_region_length;
-  size_t _survivor_cset_region_length;
-  size_t _old_cset_region_length;
+  uint _eden_cset_region_length;
+  uint _survivor_cset_region_length;
+  uint _old_cset_region_length;
 
-  void init_cset_region_lengths(size_t eden_cset_region_length,
-                                size_t survivor_cset_region_length);
+  void init_cset_region_lengths(uint eden_cset_region_length,
+                                uint survivor_cset_region_length);
 
-  size_t eden_cset_region_length()     { return _eden_cset_region_length;     }
-  size_t survivor_cset_region_length() { return _survivor_cset_region_length; }
-  size_t old_cset_region_length()      { return _old_cset_region_length;      }
+  uint eden_cset_region_length()     { return _eden_cset_region_length;     }
+  uint survivor_cset_region_length() { return _survivor_cset_region_length; }
+  uint old_cset_region_length()      { return _old_cset_region_length;      }
 
-  size_t _free_regions_at_end_of_collection;
+  uint _free_regions_at_end_of_collection;
 
   size_t _recorded_rs_lengths;
   size_t _max_rs_lengths;
-
-  double _recorded_young_free_cset_time_ms;
-  double _recorded_non_young_free_cset_time_ms;
-
   double _sigma;
 
   size_t _rs_lengths_prediction;
 
-  size_t _known_garbage_bytes;
-  double _known_garbage_ratio;
-
   double sigma() { return _sigma; }
 
   // A function that prevents us putting too much stock in small sample
@@ -345,10 +292,8 @@
   void set_no_of_gc_threads(uintx v) { _no_of_gc_threads = v; }
 
   double _pause_time_target_ms;
-  double _recorded_young_cset_choice_time_ms;
-  double _recorded_non_young_cset_choice_time_ms;
+
   size_t _pending_cards;
-  size_t _max_pending_cards;
 
 public:
   // Accessors
@@ -378,28 +323,6 @@
     _max_rs_lengths = rs_lengths;
   }
 
-  size_t predict_pending_card_diff() {
-    double prediction = get_new_neg_prediction(_pending_card_diff_seq);
-    if (prediction < 0.00001) {
-      return 0;
-    } else {
-      return (size_t) prediction;
-    }
-  }
-
-  size_t predict_pending_cards() {
-    size_t max_pending_card_num = _g1->max_pending_card_num();
-    size_t diff = predict_pending_card_diff();
-    size_t prediction;
-    if (diff > max_pending_card_num) {
-      prediction = max_pending_card_num;
-    } else {
-      prediction = max_pending_card_num - diff;
-    }
-
-    return prediction;
-  }
-
   size_t predict_rs_length_diff() {
     return (size_t) get_new_prediction(_rs_length_diff_seq);
   }
@@ -488,31 +411,18 @@
            get_new_prediction(_non_young_other_cost_per_region_ms_seq);
   }
 
-  double predict_young_collection_elapsed_time_ms(size_t adjustment);
   double predict_base_elapsed_time_ms(size_t pending_cards);
   double predict_base_elapsed_time_ms(size_t pending_cards,
                                       size_t scanned_cards);
   size_t predict_bytes_to_copy(HeapRegion* hr);
-  double predict_region_elapsed_time_ms(HeapRegion* hr, bool young);
+  double predict_region_elapsed_time_ms(HeapRegion* hr, bool for_young_gc);
 
   void set_recorded_rs_lengths(size_t rs_lengths);
 
-  size_t cset_region_length()       { return young_cset_region_length() +
-                                             old_cset_region_length(); }
-  size_t young_cset_region_length() { return eden_cset_region_length() +
-                                             survivor_cset_region_length(); }
-
-  void record_young_free_cset_time_ms(double time_ms) {
-    _recorded_young_free_cset_time_ms = time_ms;
-  }
-
-  void record_non_young_free_cset_time_ms(double time_ms) {
-    _recorded_non_young_free_cset_time_ms = time_ms;
-  }
-
-  double predict_young_gc_eff() {
-    return get_new_neg_prediction(_young_gc_eff_seq);
-  }
+  uint cset_region_length()       { return young_cset_region_length() +
+                                           old_cset_region_length(); }
+  uint young_cset_region_length() { return eden_cset_region_length() +
+                                           survivor_cset_region_length(); }
 
   double predict_survivor_regions_evac_time();
 
@@ -523,20 +433,6 @@
     // also call it on any more surv rate groups
   }
 
-  void set_known_garbage_bytes(size_t known_garbage_bytes) {
-    _known_garbage_bytes = known_garbage_bytes;
-    size_t heap_bytes = _g1->capacity();
-    _known_garbage_ratio = (double) _known_garbage_bytes / (double) heap_bytes;
-  }
-
-  void decrease_known_garbage_bytes(size_t known_garbage_bytes) {
-    guarantee( _known_garbage_bytes >= known_garbage_bytes, "invariant" );
-
-    _known_garbage_bytes -= known_garbage_bytes;
-    size_t heap_bytes = _g1->capacity();
-    _known_garbage_ratio = (double) _known_garbage_bytes / (double) heap_bytes;
-  }
-
   G1MMUTracker* mmu_tracker() {
     return _mmu_tracker;
   }
@@ -575,34 +471,6 @@
   }
 
 private:
-  void print_stats(int level, const char* str, double value);
-  void print_stats(int level, const char* str, int value);
-
-  void print_par_stats(int level, const char* str, double* data);
-  void print_par_sizes(int level, const char* str, double* data);
-
-  void check_other_times(int level,
-                         NumberSeq* other_times_ms,
-                         NumberSeq* calc_other_times_ms) const;
-
-  void print_summary (PauseSummary* stats) const;
-
-  void print_summary (int level, const char* str, NumberSeq* seq) const;
-  void print_summary_sd (int level, const char* str, NumberSeq* seq) const;
-
-  double avg_value (double* data);
-  double max_value (double* data);
-  double sum_of_values (double* data);
-  double max_sum (double* data1, double* data2);
-
-  double _last_pause_time_ms;
-
-  size_t _bytes_in_collection_set_before_gc;
-  size_t _bytes_copied_during_gc;
-
-  // Used to count used bytes in CS.
-  friend class CountCSClosure;
-
   // Statistics kept per GC stoppage, pause or full.
   TruncatedSeq* _recent_prev_end_times_for_all_gcs_sec;
 
@@ -616,9 +484,13 @@
 
   // The number of bytes in the collection set before the pause. Set from
   // the incrementally built collection set at the start of an evacuation
-  // pause.
+  // pause, and incremented in finalize_cset() when adding old regions
+  // (if any) to the collection set.
   size_t _collection_set_bytes_used_before;
 
+  // The number of bytes copied during the GC.
+  size_t _bytes_copied_during_gc;
+
   // The associated information that is maintained while the incremental
   // collection set is being built with young regions. Used to populate
   // the recorded info for the evacuation pause.
@@ -670,6 +542,8 @@
   // Stash a pointer to the g1 heap.
   G1CollectedHeap* _g1;
 
+  G1GCPhaseTimes* _phase_times;
+
   // The ratio of gc time to elapsed time, computed over recent pauses.
   double _recent_avg_pause_time_ratio;
 
@@ -709,8 +583,6 @@
   double _cur_mark_stop_world_time_ms;
   double _mark_remark_start_sec;
   double _mark_cleanup_start_sec;
-  double _mark_closure_time_ms;
-  double _root_region_scan_wait_time_ms;
 
   // Update the young list target length either by setting it to the
   // desired fixed value or by calculating it using G1's pause
@@ -722,12 +594,12 @@
   // Calculate and return the minimum desired young list target
   // length. This is the minimum desired young list length according
   // to the user's inputs.
-  size_t calculate_young_list_desired_min_length(size_t base_min_length);
+  uint calculate_young_list_desired_min_length(uint base_min_length);
 
   // Calculate and return the maximum desired young list target
   // length. This is the maximum desired young list length according
   // to the user's inputs.
-  size_t calculate_young_list_desired_max_length();
+  uint calculate_young_list_desired_max_length();
 
   // Calculate and return the maximum young list target length that
   // can fit into the pause time goal. The parameters are: rs_lengths
@@ -735,21 +607,18 @@
   // be, base_min_length is the alreay existing number of regions in
   // the young list, min_length and max_length are the desired min and
   // max young list length according to the user's inputs.
-  size_t calculate_young_list_target_length(size_t rs_lengths,
-                                            size_t base_min_length,
-                                            size_t desired_min_length,
-                                            size_t desired_max_length);
+  uint calculate_young_list_target_length(size_t rs_lengths,
+                                          uint base_min_length,
+                                          uint desired_min_length,
+                                          uint desired_max_length);
 
   // Check whether a given young length (young_length) fits into the
   // given target pause time and whether the prediction for the amount
   // of objects to be copied for the given length will fit into the
   // given free space (expressed by base_free_regions).  It is used by
   // calculate_young_list_target_length().
-  bool predict_will_fit(size_t young_length, double base_time_ms,
-                        size_t base_free_regions, double target_pause_time_ms);
-
-  // Count the number of bytes used in the CS.
-  void count_CS_bytes_used();
+  bool predict_will_fit(uint young_length, double base_time_ms,
+                        uint base_free_regions, double target_pause_time_ms);
 
 public:
 
@@ -761,21 +630,15 @@
     return CollectorPolicy::G1CollectorPolicyKind;
   }
 
+  G1GCPhaseTimes* phase_times() const { return _phase_times; }
+
   // Check the current value of the young list RSet lengths and
   // compare it against the last prediction. If the current value is
   // higher, recalculate the young list target length prediction.
   void revise_young_list_target_length_if_necessary();
 
-  size_t bytes_in_collection_set() {
-    return _bytes_in_collection_set_before_gc;
-  }
-
-  unsigned calc_gc_alloc_time_stamp() {
-    return _all_pause_times_ms->num() + 1;
-  }
-
   // This should be called after the heap is resized.
-  void record_new_heap_size(size_t new_number_of_regions);
+  void record_new_heap_size(uint new_number_of_regions);
 
   void init();
 
@@ -809,14 +672,6 @@
   void record_concurrent_mark_init_end(double
                                            mark_init_elapsed_time_ms);
 
-  void record_mark_closure_time(double mark_closure_time_ms) {
-    _mark_closure_time_ms = mark_closure_time_ms;
-  }
-
-  void record_root_region_scan_wait_time(double time_ms) {
-    _root_region_scan_wait_time_ms = time_ms;
-  }
-
   void record_concurrent_mark_remark_start();
   void record_concurrent_mark_remark_end();
 
@@ -825,110 +680,15 @@
   void record_concurrent_mark_cleanup_completed();
 
   void record_concurrent_pause();
-  void record_concurrent_pause_end();
 
-  void record_collection_pause_end(int no_of_gc_threads);
+  void record_collection_pause_end(double pause_time);
   void print_heap_transition();
+  void print_detailed_heap_transition();
 
   // Record the fact that a full collection occurred.
   void record_full_collection_start();
   void record_full_collection_end();
 
-  void record_gc_worker_start_time(int worker_i, double ms) {
-    _par_last_gc_worker_start_times_ms[worker_i] = ms;
-  }
-
-  void record_ext_root_scan_time(int worker_i, double ms) {
-    _par_last_ext_root_scan_times_ms[worker_i] = ms;
-  }
-
-  void record_satb_filtering_time(int worker_i, double ms) {
-    _par_last_satb_filtering_times_ms[worker_i] = ms;
-  }
-
-  void record_satb_drain_time(double ms) {
-    assert(_g1->mark_in_progress(), "shouldn't be here otherwise");
-    _cur_satb_drain_time_ms = ms;
-  }
-
-  void record_update_rs_time(int thread, double ms) {
-    _par_last_update_rs_times_ms[thread] = ms;
-  }
-
-  void record_update_rs_processed_buffers (int thread,
-                                           double processed_buffers) {
-    _par_last_update_rs_processed_buffers[thread] = processed_buffers;
-  }
-
-  void record_scan_rs_time(int thread, double ms) {
-    _par_last_scan_rs_times_ms[thread] = ms;
-  }
-
-  void reset_obj_copy_time(int thread) {
-    _par_last_obj_copy_times_ms[thread] = 0.0;
-  }
-
-  void reset_obj_copy_time() {
-    reset_obj_copy_time(0);
-  }
-
-  void record_obj_copy_time(int thread, double ms) {
-    _par_last_obj_copy_times_ms[thread] += ms;
-  }
-
-  void record_termination(int thread, double ms, size_t attempts) {
-    _par_last_termination_times_ms[thread] = ms;
-    _par_last_termination_attempts[thread] = (double) attempts;
-  }
-
-  void record_gc_worker_end_time(int worker_i, double ms) {
-    _par_last_gc_worker_end_times_ms[worker_i] = ms;
-  }
-
-  void record_pause_time_ms(double ms) {
-    _last_pause_time_ms = ms;
-  }
-
-  void record_clear_ct_time(double ms) {
-    _cur_clear_ct_time_ms = ms;
-  }
-
-  void record_par_time(double ms) {
-    _cur_collection_par_time_ms = ms;
-  }
-
-  void record_aux_start_time(int i) {
-    guarantee(i < _aux_num, "should be within range");
-    _cur_aux_start_times_ms[i] = os::elapsedTime() * 1000.0;
-  }
-
-  void record_aux_end_time(int i) {
-    guarantee(i < _aux_num, "should be within range");
-    double ms = os::elapsedTime() * 1000.0 - _cur_aux_start_times_ms[i];
-    _cur_aux_times_set[i] = true;
-    _cur_aux_times_ms[i] += ms;
-  }
-
-  void record_ref_proc_time(double ms) {
-    _cur_ref_proc_time_ms = ms;
-  }
-
-  void record_ref_enq_time(double ms) {
-    _cur_ref_enq_time_ms = ms;
-  }
-
-#ifndef PRODUCT
-  void record_cc_clear_time(double ms) {
-    if (_min_clear_cc_time_ms < 0.0 || ms <= _min_clear_cc_time_ms)
-      _min_clear_cc_time_ms = ms;
-    if (_max_clear_cc_time_ms < 0.0 || ms >= _max_clear_cc_time_ms)
-      _max_clear_cc_time_ms = ms;
-    _cur_clear_cc_time_ms = ms;
-    _cum_clear_cc_time_ms += ms;
-    _num_cc_clears++;
-  }
-#endif
-
   // Record how much space we copied during a GC. This is typically
   // called when a GC alloc region is being retired.
   void record_bytes_copied_during_gc(size_t bytes) {
@@ -940,10 +700,9 @@
     return _bytes_copied_during_gc;
   }
 
-  // Determine whether the next GC should be mixed. Called to determine
-  // whether to start mixed GCs or whether to carry on doing mixed
-  // GCs. The two action strings are used in the ergo output when the
-  // method returns true or false.
+  // Determine whether there are candidate regions so that the
+  // next GC should be mixed. The two action strings are used
+  // in the ergo output when the method returns true or false.
   bool next_gc_should_be_mixed(const char* true_action_str,
                                const char* false_action_str);
 
@@ -1034,12 +793,6 @@
   // exceeded the desired limit, return an amount to expand by.
   size_t expansion_amount();
 
-#ifndef PRODUCT
-  // Check any appropriate marked bytes info, asserting false if
-  // something's wrong, else returning "true".
-  bool assertMarkedBytesDataOK();
-#endif
-
   // Print tracing information.
   void print_tracing_info() const;
 
@@ -1056,18 +809,18 @@
   }
 
   bool is_young_list_full() {
-    size_t young_list_length = _g1->young_list()->length();
-    size_t young_list_target_length = _young_list_target_length;
+    uint young_list_length = _g1->young_list()->length();
+    uint young_list_target_length = _young_list_target_length;
     return young_list_length >= young_list_target_length;
   }
 
   bool can_expand_young_list() {
-    size_t young_list_length = _g1->young_list()->length();
-    size_t young_list_max_length = _young_list_max_length;
+    uint young_list_length = _g1->young_list()->length();
+    uint young_list_max_length = _young_list_max_length;
     return young_list_length < young_list_max_length;
   }
 
-  size_t young_list_max_length() {
+  uint young_list_max_length() {
     return _young_list_max_length;
   }
 
@@ -1082,19 +835,6 @@
     return _young_gen_sizer->adaptive_young_list_length();
   }
 
-  inline double get_gc_eff_factor() {
-    double ratio = _known_garbage_ratio;
-
-    double square = ratio * ratio;
-    // square = square * square;
-    double ret = square * 9.0 + 1.0;
-#if 0
-    gclog_or_tty->print_cr("ratio = %1.2lf, ret = %1.2lf", ratio, ret);
-#endif // 0
-    guarantee(0.0 <= ret && ret < 10.0, "invariant!");
-    return ret;
-  }
-
 private:
   //
   // Survivor regions policy.
@@ -1105,7 +845,7 @@
   int _tenuring_threshold;
 
   // The limit on the number of regions allocated for survivors.
-  size_t _max_survivor_regions;
+  uint _max_survivor_regions;
 
   // For reporting purposes.
   size_t _eden_bytes_before_gc;
@@ -1113,7 +853,7 @@
   size_t _capacity_before_gc;
 
   // The amount of survor regions after a collection.
-  size_t _recorded_survivor_regions;
+  uint _recorded_survivor_regions;
   // List of survivor regions.
   HeapRegion* _recorded_survivor_head;
   HeapRegion* _recorded_survivor_tail;
@@ -1135,9 +875,9 @@
     return purpose == GCAllocForSurvived;
   }
 
-  static const size_t REGIONS_UNLIMITED = ~(size_t)0;
+  static const uint REGIONS_UNLIMITED = (uint) -1;
 
-  size_t max_regions(int purpose);
+  uint max_regions(int purpose);
 
   // The limit on regions for a particular purpose is reached.
   void note_alloc_region_limit_reached(int purpose) {
@@ -1154,7 +894,7 @@
     _survivor_surv_rate_group->stop_adding_regions();
   }
 
-  void record_survivor_regions(size_t      regions,
+  void record_survivor_regions(uint regions,
                                HeapRegion* head,
                                HeapRegion* tail) {
     _recorded_survivor_regions = regions;
@@ -1162,12 +902,11 @@
     _recorded_survivor_tail    = tail;
   }
 
-  size_t recorded_survivor_regions() {
+  uint recorded_survivor_regions() {
     return _recorded_survivor_regions;
   }
 
-  void record_thread_age_table(ageTable* age_table)
-  {
+  void record_thread_age_table(ageTable* age_table) {
     _survivors_age_table.merge_par(age_table);
   }
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp
index 1e738fd..eff1196 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1ErgoVerbose.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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
@@ -120,11 +120,12 @@
 
 // Single parameter format strings
 #define ergo_format_str(_name_)      ", " _name_ ": %s"
-#define ergo_format_region(_name_)   ", " _name_ ": "SIZE_FORMAT" regions"
+#define ergo_format_region(_name_)   ", " _name_ ": %u regions"
 #define ergo_format_byte(_name_)     ", " _name_ ": "SIZE_FORMAT" bytes"
 #define ergo_format_double(_name_)   ", " _name_ ": %1.2f"
 #define ergo_format_perc(_name_)     ", " _name_ ": %1.2f %%"
 #define ergo_format_ms(_name_)       ", " _name_ ": %1.2f ms"
+#define ergo_format_size(_name_)     ", " _name_ ": "SIZE_FORMAT
 
 // Double parameter format strings
 #define ergo_format_byte_perc(_name_)                                   \
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp
new file mode 100644
index 0000000..ae8439a
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.cpp
@@ -0,0 +1,323 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+
+#include "precompiled.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
+
+// Helper class for avoiding interleaved logging
+class LineBuffer: public StackObj {
+
+private:
+  static const int BUFFER_LEN = 1024;
+  static const int INDENT_CHARS = 3;
+  char _buffer[BUFFER_LEN];
+  int _indent_level;
+  int _cur;
+
+  void vappend(const char* format, va_list ap) {
+    int res = vsnprintf(&_buffer[_cur], BUFFER_LEN - _cur, format, ap);
+    if (res != -1) {
+      _cur += res;
+    } else {
+      DEBUG_ONLY(warning("buffer too small in LineBuffer");)
+      _buffer[BUFFER_LEN -1] = 0;
+      _cur = BUFFER_LEN; // vsnprintf above should not add to _buffer if we are called again
+    }
+  }
+
+public:
+  explicit LineBuffer(int indent_level): _indent_level(indent_level), _cur(0) {
+    for (; (_cur < BUFFER_LEN && _cur < (_indent_level * INDENT_CHARS)); _cur++) {
+      _buffer[_cur] = ' ';
+    }
+  }
+
+#ifndef PRODUCT
+  ~LineBuffer() {
+    assert(_cur == _indent_level * INDENT_CHARS, "pending data in buffer - append_and_print_cr() not called?");
+  }
+#endif
+
+  void append(const char* format, ...) {
+    va_list ap;
+    va_start(ap, format);
+    vappend(format, ap);
+    va_end(ap);
+  }
+
+  void append_and_print_cr(const char* format, ...) {
+    va_list ap;
+    va_start(ap, format);
+    vappend(format, ap);
+    va_end(ap);
+    gclog_or_tty->print_cr("%s", _buffer);
+    _cur = _indent_level * INDENT_CHARS;
+  }
+};
+
+template <class T>
+void WorkerDataArray<T>::print(int level, const char* title) {
+  if (_length == 1) {
+    // No need for min, max, average and sum for only one worker
+    LineBuffer buf(level);
+    buf.append("[%s:  ", title);
+    buf.append(_print_format, _data[0]);
+    buf.append_and_print_cr("]");
+    return;
+  }
+
+  T min = _data[0];
+  T max = _data[0];
+  T sum = 0;
+
+  LineBuffer buf(level);
+  buf.append("[%s:", title);
+  for (uint i = 0; i < _length; ++i) {
+    T val = _data[i];
+    min = MIN2(val, min);
+    max = MAX2(val, max);
+    sum += val;
+    if (G1Log::finest()) {
+      buf.append("  ");
+      buf.append(_print_format, val);
+    }
+  }
+
+  if (G1Log::finest()) {
+    buf.append_and_print_cr("");
+  }
+
+  double avg = (double)sum / (double)_length;
+  buf.append(" Min: ");
+  buf.append(_print_format, min);
+  buf.append(", Avg: ");
+  buf.append("%.1lf", avg); // Always print average as a double
+  buf.append(", Max: ");
+  buf.append(_print_format, max);
+  buf.append(", Diff: ");
+  buf.append(_print_format, max - min);
+  if (_print_sum) {
+    // for things like the start and end times the sum is not
+    // that relevant
+    buf.append(", Sum: ");
+    buf.append(_print_format, sum);
+  }
+  buf.append_and_print_cr("]");
+}
+
+#ifdef ASSERT
+
+template <class T>
+void WorkerDataArray<T>::reset() {
+  for (uint i = 0; i < _length; i++) {
+    _data[i] = (T)-1;
+  }
+}
+
+template <class T>
+void WorkerDataArray<T>::verify() {
+  for (uint i = 0; i < _length; i++) {
+    assert(_data[i] >= (T)0, err_msg("Invalid data for worker %d", i));
+  }
+}
+
+#endif
+
+G1GCPhaseTimes::G1GCPhaseTimes(uint max_gc_threads) :
+  _max_gc_threads(max_gc_threads),
+  _min_clear_cc_time_ms(-1.0),
+  _max_clear_cc_time_ms(-1.0),
+  _cur_clear_cc_time_ms(0.0),
+  _cum_clear_cc_time_ms(0.0),
+  _num_cc_clears(0L),
+  _last_gc_worker_start_times_ms(_max_gc_threads, "%.1lf", false),
+  _last_ext_root_scan_times_ms(_max_gc_threads, "%.1lf"),
+  _last_satb_filtering_times_ms(_max_gc_threads, "%.1lf"),
+  _last_update_rs_times_ms(_max_gc_threads, "%.1lf"),
+  _last_update_rs_processed_buffers(_max_gc_threads, "%d"),
+  _last_scan_rs_times_ms(_max_gc_threads, "%.1lf"),
+  _last_obj_copy_times_ms(_max_gc_threads, "%.1lf"),
+  _last_termination_times_ms(_max_gc_threads, "%.1lf"),
+  _last_termination_attempts(_max_gc_threads, SIZE_FORMAT),
+  _last_gc_worker_end_times_ms(_max_gc_threads, "%.1lf", false),
+  _last_gc_worker_times_ms(_max_gc_threads, "%.1lf"),
+  _last_gc_worker_other_times_ms(_max_gc_threads, "%.1lf")
+{
+  assert(max_gc_threads > 0, "Must have some GC threads");
+}
+
+void G1GCPhaseTimes::note_gc_start(uint active_gc_threads) {
+  assert(active_gc_threads > 0, "The number of threads must be > 0");
+  assert(active_gc_threads <= _max_gc_threads, "The number of active threads must be <= the max nubmer of threads");
+  _active_gc_threads = active_gc_threads;
+
+  _last_gc_worker_start_times_ms.reset();
+  _last_ext_root_scan_times_ms.reset();
+  _last_satb_filtering_times_ms.reset();
+  _last_update_rs_times_ms.reset();
+  _last_update_rs_processed_buffers.reset();
+  _last_scan_rs_times_ms.reset();
+  _last_obj_copy_times_ms.reset();
+  _last_termination_times_ms.reset();
+  _last_termination_attempts.reset();
+  _last_gc_worker_end_times_ms.reset();
+  _last_gc_worker_times_ms.reset();
+  _last_gc_worker_other_times_ms.reset();
+}
+
+void G1GCPhaseTimes::note_gc_end() {
+  _last_gc_worker_start_times_ms.verify();
+  _last_ext_root_scan_times_ms.verify();
+  _last_satb_filtering_times_ms.verify();
+  _last_update_rs_times_ms.verify();
+  _last_update_rs_processed_buffers.verify();
+  _last_scan_rs_times_ms.verify();
+  _last_obj_copy_times_ms.verify();
+  _last_termination_times_ms.verify();
+  _last_termination_attempts.verify();
+  _last_gc_worker_end_times_ms.verify();
+
+    for (uint i = 0; i < _active_gc_threads; i++) {
+      double worker_time = _last_gc_worker_end_times_ms.get(i) - _last_gc_worker_start_times_ms.get(i);
+      _last_gc_worker_times_ms.set(i, worker_time);
+
+      double worker_known_time = _last_ext_root_scan_times_ms.get(i) +
+        _last_satb_filtering_times_ms.get(i) +
+        _last_update_rs_times_ms.get(i) +
+        _last_scan_rs_times_ms.get(i) +
+        _last_obj_copy_times_ms.get(i) +
+        _last_termination_times_ms.get(i);
+
+      double worker_other_time = worker_time - worker_known_time;
+      _last_gc_worker_other_times_ms.set(i, worker_other_time);
+    }
+
+  _last_gc_worker_times_ms.verify();
+  _last_gc_worker_other_times_ms.verify();
+}
+
+void G1GCPhaseTimes::print_stats(int level, const char* str, double value) {
+  LineBuffer(level).append_and_print_cr("[%s: %.1lf ms]", str, value);
+}
+
+void G1GCPhaseTimes::print_stats(int level, const char* str, double value, int workers) {
+  LineBuffer(level).append_and_print_cr("[%s: %.1lf ms, GC Workers: %d]", str, value, workers);
+}
+
+double G1GCPhaseTimes::accounted_time_ms() {
+    // Subtract the root region scanning wait time. It's initialized to
+    // zero at the start of the pause.
+    double misc_time_ms = _root_region_scan_wait_time_ms;
+
+    misc_time_ms += _cur_collection_par_time_ms;
+
+    // Now subtract the time taken to fix up roots in generated code
+    misc_time_ms += _cur_collection_code_root_fixup_time_ms;
+
+    // Subtract the time taken to clean the card table from the
+    // current value of "other time"
+    misc_time_ms += _cur_clear_ct_time_ms;
+
+    return misc_time_ms;
+}
+
+void G1GCPhaseTimes::print(double pause_time_sec) {
+  if (_root_region_scan_wait_time_ms > 0.0) {
+    print_stats(1, "Root Region Scan Waiting", _root_region_scan_wait_time_ms);
+  }
+  if (G1CollectedHeap::use_parallel_gc_threads()) {
+    print_stats(1, "Parallel Time", _cur_collection_par_time_ms, _active_gc_threads);
+    _last_gc_worker_start_times_ms.print(2, "GC Worker Start (ms)");
+    _last_ext_root_scan_times_ms.print(2, "Ext Root Scanning (ms)");
+    if (_last_satb_filtering_times_ms.sum() > 0.0) {
+      _last_satb_filtering_times_ms.print(2, "SATB Filtering (ms)");
+    }
+    _last_update_rs_times_ms.print(2, "Update RS (ms)");
+      _last_update_rs_processed_buffers.print(3, "Processed Buffers");
+    _last_scan_rs_times_ms.print(2, "Scan RS (ms)");
+    _last_obj_copy_times_ms.print(2, "Object Copy (ms)");
+    _last_termination_times_ms.print(2, "Termination (ms)");
+    if (G1Log::finest()) {
+      _last_termination_attempts.print(3, "Termination Attempts");
+    }
+    _last_gc_worker_other_times_ms.print(2, "GC Worker Other (ms)");
+    _last_gc_worker_times_ms.print(2, "GC Worker Total (ms)");
+    _last_gc_worker_end_times_ms.print(2, "GC Worker End (ms)");
+  } else {
+    _last_ext_root_scan_times_ms.print(1, "Ext Root Scanning (ms)");
+    if (_last_satb_filtering_times_ms.sum() > 0.0) {
+      _last_satb_filtering_times_ms.print(1, "SATB Filtering (ms)");
+    }
+    _last_update_rs_times_ms.print(1, "Update RS (ms)");
+      _last_update_rs_processed_buffers.print(2, "Processed Buffers");
+    _last_scan_rs_times_ms.print(1, "Scan RS (ms)");
+    _last_obj_copy_times_ms.print(1, "Object Copy (ms)");
+  }
+  print_stats(1, "Code Root Fixup", _cur_collection_code_root_fixup_time_ms);
+  print_stats(1, "Clear CT", _cur_clear_ct_time_ms);
+  if (Verbose && G1Log::finest()) {
+    print_stats(1, "Cur Clear CC", _cur_clear_cc_time_ms);
+    print_stats(1, "Cum Clear CC", _cum_clear_cc_time_ms);
+    print_stats(1, "Min Clear CC", _min_clear_cc_time_ms);
+    print_stats(1, "Max Clear CC", _max_clear_cc_time_ms);
+    if (_num_cc_clears > 0) {
+      print_stats(1, "Avg Clear CC", _cum_clear_cc_time_ms / ((double)_num_cc_clears));
+    }
+  }
+  double misc_time_ms = pause_time_sec * MILLIUNITS - accounted_time_ms();
+  print_stats(1, "Other", misc_time_ms);
+  if (_cur_verify_before_time_ms > 0.0) {
+    print_stats(2, "Verify Before", _cur_verify_before_time_ms);
+  }
+  print_stats(2, "Choose CSet",
+    (_recorded_young_cset_choice_time_ms +
+    _recorded_non_young_cset_choice_time_ms));
+  print_stats(2, "Ref Proc", _cur_ref_proc_time_ms);
+  print_stats(2, "Ref Enq", _cur_ref_enq_time_ms);
+  print_stats(2, "Free CSet",
+    (_recorded_young_free_cset_time_ms +
+    _recorded_non_young_free_cset_time_ms));
+  if (_cur_verify_after_time_ms > 0.0) {
+    print_stats(2, "Verify After", _cur_verify_after_time_ms);
+  }
+}
+
+void G1GCPhaseTimes::record_cc_clear_time_ms(double ms) {
+  if (!(Verbose && G1Log::finest())) {
+    return;
+  }
+
+  if (_min_clear_cc_time_ms < 0.0 || ms <= _min_clear_cc_time_ms) {
+    _min_clear_cc_time_ms = ms;
+  }
+  if (_max_clear_cc_time_ms < 0.0 || ms >= _max_clear_cc_time_ms) {
+    _max_clear_cc_time_ms = ms;
+  }
+  _cur_clear_cc_time_ms = ms;
+  _cum_clear_cc_time_ms += ms;
+  _num_cc_clears++;
+}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp
new file mode 100644
index 0000000..99e35c6
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1GCPhaseTimes.hpp
@@ -0,0 +1,321 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
+
+#include "memory/allocation.hpp"
+#include "gc_interface/gcCause.hpp"
+
+template <class T>
+class WorkerDataArray  : public CHeapObj<mtGC> {
+  T*          _data;
+  uint        _length;
+  const char* _print_format;
+  bool        _print_sum;
+
+  // We are caching the sum and average to only have to calculate them once.
+  // This is not done in an MT-safe way. It is intetened to allow single
+  // threaded code to call sum() and average() multiple times in any order
+  // without having to worry about the cost.
+  bool   _has_new_data;
+  T      _sum;
+  double _average;
+
+ public:
+  WorkerDataArray(uint length, const char* print_format, bool print_sum = true) :
+  _length(length), _print_format(print_format), _print_sum(print_sum), _has_new_data(true) {
+    assert(length > 0, "Must have some workers to store data for");
+    _data = NEW_C_HEAP_ARRAY(T, _length, mtGC);
+  }
+
+  ~WorkerDataArray() {
+    FREE_C_HEAP_ARRAY(T, _data, mtGC);
+  }
+
+  void set(uint worker_i, T value) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] == (T)-1, err_msg("Overwriting data for worker %d", worker_i));
+    _data[worker_i] = value;
+    _has_new_data = true;
+  }
+
+  T get(uint worker_i) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
+    return _data[worker_i];
+  }
+
+  void add(uint worker_i, T value) {
+    assert(worker_i < _length, err_msg("Worker %d is greater than max: %d", worker_i, _length));
+    assert(_data[worker_i] != (T)-1, err_msg("No data to add to for worker %d", worker_i));
+    _data[worker_i] += value;
+    _has_new_data = true;
+  }
+
+  double average(){
+    if (_has_new_data) {
+      calculate_totals();
+    }
+    return _average;
+  }
+
+  T sum() {
+    if (_has_new_data) {
+      calculate_totals();
+    }
+    return _sum;
+  }
+
+  void print(int level, const char* title);
+
+  void reset() PRODUCT_RETURN;
+  void verify() PRODUCT_RETURN;
+
+ private:
+
+  void calculate_totals(){
+    _sum = (T)0;
+    for (uint i = 0; i < _length; ++i) {
+      _sum += _data[i];
+    }
+    _average = (double)_sum / (double)_length;
+    _has_new_data = false;
+  }
+};
+
+class G1GCPhaseTimes : public CHeapObj<mtGC> {
+
+ private:
+  uint _active_gc_threads;
+  uint _max_gc_threads;
+
+  WorkerDataArray<double> _last_gc_worker_start_times_ms;
+  WorkerDataArray<double> _last_ext_root_scan_times_ms;
+  WorkerDataArray<double> _last_satb_filtering_times_ms;
+  WorkerDataArray<double> _last_update_rs_times_ms;
+  WorkerDataArray<int>    _last_update_rs_processed_buffers;
+  WorkerDataArray<double> _last_scan_rs_times_ms;
+  WorkerDataArray<double> _last_obj_copy_times_ms;
+  WorkerDataArray<double> _last_termination_times_ms;
+  WorkerDataArray<size_t> _last_termination_attempts;
+  WorkerDataArray<double> _last_gc_worker_end_times_ms;
+  WorkerDataArray<double> _last_gc_worker_times_ms;
+  WorkerDataArray<double> _last_gc_worker_other_times_ms;
+
+  double _cur_collection_par_time_ms;
+  double _cur_collection_code_root_fixup_time_ms;
+
+  double _cur_clear_ct_time_ms;
+  double _cur_ref_proc_time_ms;
+  double _cur_ref_enq_time_ms;
+
+  // Card Table Count Cache stats
+  double _min_clear_cc_time_ms;         // min
+  double _max_clear_cc_time_ms;         // max
+  double _cur_clear_cc_time_ms;         // clearing time during current pause
+  double _cum_clear_cc_time_ms;         // cummulative clearing time
+  jlong  _num_cc_clears;                // number of times the card count cache has been cleared
+
+  double _cur_collection_start_sec;
+  double _root_region_scan_wait_time_ms;
+
+  double _recorded_young_cset_choice_time_ms;
+  double _recorded_non_young_cset_choice_time_ms;
+
+  double _recorded_young_free_cset_time_ms;
+  double _recorded_non_young_free_cset_time_ms;
+
+  double _cur_verify_before_time_ms;
+  double _cur_verify_after_time_ms;
+
+  // Helper methods for detailed logging
+  void print_stats(int level, const char* str, double value);
+  void print_stats(int level, const char* str, double value, int workers);
+
+ public:
+  G1GCPhaseTimes(uint max_gc_threads);
+  void note_gc_start(uint active_gc_threads);
+  void note_gc_end();
+  void print(double pause_time_sec);
+
+  void record_gc_worker_start_time(uint worker_i, double ms) {
+    _last_gc_worker_start_times_ms.set(worker_i, ms);
+  }
+
+  void record_ext_root_scan_time(uint worker_i, double ms) {
+    _last_ext_root_scan_times_ms.set(worker_i, ms);
+  }
+
+  void record_satb_filtering_time(uint worker_i, double ms) {
+    _last_satb_filtering_times_ms.set(worker_i, ms);
+  }
+
+  void record_update_rs_time(uint worker_i, double ms) {
+    _last_update_rs_times_ms.set(worker_i, ms);
+  }
+
+  void record_update_rs_processed_buffers(uint worker_i, int processed_buffers) {
+    _last_update_rs_processed_buffers.set(worker_i, processed_buffers);
+  }
+
+  void record_scan_rs_time(uint worker_i, double ms) {
+    _last_scan_rs_times_ms.set(worker_i, ms);
+  }
+
+  void record_obj_copy_time(uint worker_i, double ms) {
+    _last_obj_copy_times_ms.set(worker_i, ms);
+  }
+
+  void add_obj_copy_time(uint worker_i, double ms) {
+    _last_obj_copy_times_ms.add(worker_i, ms);
+  }
+
+  void record_termination(uint worker_i, double ms, size_t attempts) {
+    _last_termination_times_ms.set(worker_i, ms);
+    _last_termination_attempts.set(worker_i, attempts);
+  }
+
+  void record_gc_worker_end_time(uint worker_i, double ms) {
+    _last_gc_worker_end_times_ms.set(worker_i, ms);
+  }
+
+  void record_clear_ct_time(double ms) {
+    _cur_clear_ct_time_ms = ms;
+  }
+
+  void record_par_time(double ms) {
+    _cur_collection_par_time_ms = ms;
+  }
+
+  void record_code_root_fixup_time(double ms) {
+    _cur_collection_code_root_fixup_time_ms = ms;
+  }
+
+  void record_ref_proc_time(double ms) {
+    _cur_ref_proc_time_ms = ms;
+  }
+
+  void record_ref_enq_time(double ms) {
+    _cur_ref_enq_time_ms = ms;
+  }
+
+  void record_root_region_scan_wait_time(double time_ms) {
+    _root_region_scan_wait_time_ms = time_ms;
+  }
+
+  void record_cc_clear_time_ms(double ms);
+
+  void record_young_free_cset_time_ms(double time_ms) {
+    _recorded_young_free_cset_time_ms = time_ms;
+  }
+
+  void record_non_young_free_cset_time_ms(double time_ms) {
+    _recorded_non_young_free_cset_time_ms = time_ms;
+  }
+
+  void record_young_cset_choice_time_ms(double time_ms) {
+    _recorded_young_cset_choice_time_ms = time_ms;
+  }
+
+  void record_non_young_cset_choice_time_ms(double time_ms) {
+    _recorded_non_young_cset_choice_time_ms = time_ms;
+  }
+
+  void record_cur_collection_start_sec(double time_ms) {
+    _cur_collection_start_sec = time_ms;
+  }
+
+  void record_verify_before_time_ms(double time_ms) {
+    _cur_verify_before_time_ms = time_ms;
+  }
+
+  void record_verify_after_time_ms(double time_ms) {
+    _cur_verify_after_time_ms = time_ms;
+  }
+
+  double accounted_time_ms();
+
+  double cur_collection_start_sec() {
+    return _cur_collection_start_sec;
+  }
+
+  double cur_collection_par_time_ms() {
+    return _cur_collection_par_time_ms;
+  }
+
+  double cur_clear_ct_time_ms() {
+    return _cur_clear_ct_time_ms;
+  }
+
+  double root_region_scan_wait_time_ms() {
+    return _root_region_scan_wait_time_ms;
+  }
+
+  double young_cset_choice_time_ms() {
+    return _recorded_young_cset_choice_time_ms;
+  }
+
+  double young_free_cset_time_ms() {
+    return _recorded_young_free_cset_time_ms;
+  }
+
+  double non_young_cset_choice_time_ms() {
+    return _recorded_non_young_cset_choice_time_ms;
+  }
+
+  double non_young_free_cset_time_ms() {
+    return _recorded_non_young_free_cset_time_ms;
+  }
+
+  double average_last_update_rs_time() {
+    return _last_update_rs_times_ms.average();
+  }
+
+  int sum_last_update_rs_processed_buffers() {
+    return _last_update_rs_processed_buffers.sum();
+  }
+
+  double average_last_scan_rs_time(){
+    return _last_scan_rs_times_ms.average();
+  }
+
+  double average_last_obj_copy_time() {
+    return _last_obj_copy_times_ms.average();
+  }
+
+  double average_last_termination_time() {
+    return _last_termination_times_ms.average();
+  }
+
+  double average_last_ext_root_scan_time() {
+    return _last_ext_root_scan_times_ms.average();
+  }
+
+  double average_last_satb_filtering_times_ms() {
+    return _last_satb_filtering_times_ms.average();
+  }
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1GCPHASETIMESLOG_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1Log.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1Log.cpp
new file mode 100644
index 0000000..56d957f
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Log.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/g1/g1_globals.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
+#include "runtime/globals.hpp"
+
+G1Log::LogLevel G1Log::_level = G1Log::LevelNone;
+
+// If G1LogLevel has not been set up we will use the values of PrintGC
+// and PrintGCDetails for the logging level.
+// - PrintGC maps to "fine".
+// - PrintGCDetails maps to "finer".
+void G1Log::init() {
+  if (G1LogLevel != NULL && G1LogLevel[0] != '\0') {
+    if (strncmp("none", G1LogLevel, 4) == 0 && G1LogLevel[4] == '\0') {
+      _level = LevelNone;
+    } else if (strncmp("fine", G1LogLevel, 4) == 0 && G1LogLevel[4] == '\0') {
+      _level = LevelFine;
+    } else if (strncmp("finer", G1LogLevel, 5) == 0 && G1LogLevel[5] == '\0') {
+      _level = LevelFiner;
+    } else if (strncmp("finest", G1LogLevel, 6) == 0 && G1LogLevel[6] == '\0') {
+      _level = LevelFinest;
+    } else {
+      warning("Unknown logging level '%s', should be one of 'fine', 'finer' or 'finest'.", G1LogLevel);
+    }
+  } else {
+    if (PrintGCDetails) {
+      _level = LevelFiner;
+    } else if (PrintGC) {
+      _level = LevelFine;
+    }
+  }
+}
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1Log.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1Log.hpp
new file mode 100644
index 0000000..b8da001
--- /dev/null
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1Log.hpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_G1LOG_HPP
+#define SHARE_VM_GC_IMPLEMENTATION_G1_G1LOG_HPP
+
+#include "memory/allocation.hpp"
+
+class G1Log : public AllStatic {
+  typedef enum {
+    LevelNone,
+    LevelFine,
+    LevelFiner,
+    LevelFinest
+  } LogLevel;
+
+  static LogLevel _level;
+
+ public:
+  inline static bool fine() {
+    return _level >= LevelFine;
+  }
+
+  inline static bool finer() {
+    return _level >= LevelFiner;
+  }
+
+  inline static bool finest() {
+    return _level == LevelFinest;
+  }
+
+  static void init();
+};
+
+#endif // SHARE_VM_GC_IMPLEMENTATION_G1_G1LOG_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp
index a13c62e..a8146c9 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MMUTracker.hpp
@@ -34,7 +34,7 @@
 /***** ALL TIMES ARE IN SECS!!!!!!! *****/
 
 // this is the "interface"
-class G1MMUTracker: public CHeapObj {
+class G1MMUTracker: public CHeapObj<mtGC> {
 protected:
   double          _time_slice;
   double          _max_gc_time; // this is per time slice
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
index f32030b..9301754 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp
@@ -29,6 +29,7 @@
 #include "classfile/vmSymbols.hpp"
 #include "code/codeCache.hpp"
 #include "code/icBuffer.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/g1MarkSweep.hpp"
 #include "memory/gcLocker.hpp"
 #include "memory/genCollectedHeap.hpp"
@@ -126,7 +127,7 @@
 void G1MarkSweep::mark_sweep_phase1(bool& marked_for_unloading,
                                     bool clear_all_softrefs) {
   // Recursively traverse all live objects and mark them
-  TraceTime tm("phase 1", PrintGC && Verbose, true, gclog_or_tty);
+  TraceTime tm("phase 1", G1Log::fine() && Verbose, true, gclog_or_tty);
   GenMarkSweep::trace(" 1");
 
   SharedHeap* sh = SharedHeap::heap();
@@ -192,8 +193,7 @@
     // fail. At the end of the GC, the orginal mark word values
     // (including hash values) are restored to the appropriate
     // objects.
-    Universe::heap()->verify(/* allow dirty */ true,
-                             /* silent      */ false,
+    Universe::heap()->verify(/* silent      */ false,
                              /* option      */ VerifyOption_G1UseMarkWord);
 
     G1CollectedHeap* g1h = G1CollectedHeap::heap();
@@ -262,18 +262,6 @@
   }
 };
 
-// Finds the first HeapRegion.
-class FindFirstRegionClosure: public HeapRegionClosure {
-  HeapRegion* _a_region;
-public:
-  FindFirstRegionClosure() : _a_region(NULL) {}
-  bool doHeapRegion(HeapRegion* r) {
-    _a_region = r;
-    return true;
-  }
-  HeapRegion* result() { return _a_region; }
-};
-
 void G1MarkSweep::mark_sweep_phase2() {
   // Now all live objects are marked, compute the new object addresses.
 
@@ -291,12 +279,11 @@
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   Generation* pg = g1h->perm_gen();
 
-  TraceTime tm("phase 2", PrintGC && Verbose, true, gclog_or_tty);
+  TraceTime tm("phase 2", G1Log::fine() && Verbose, true, gclog_or_tty);
   GenMarkSweep::trace("2");
 
-  FindFirstRegionClosure cl;
-  g1h->heap_region_iterate(&cl);
-  HeapRegion *r = cl.result();
+  // find the first region
+  HeapRegion* r = g1h->region_at(0);
   CompactibleSpace* sp = r;
   if (r->isHumongous() && oop(r->bottom())->is_gc_marked()) {
     sp = r->next_compaction_space();
@@ -335,7 +322,7 @@
   Generation* pg = g1h->perm_gen();
 
   // Adjust the pointers to reflect the new locations
-  TraceTime tm("phase 3", PrintGC && Verbose, true, gclog_or_tty);
+  TraceTime tm("phase 3", G1Log::fine() && Verbose, true, gclog_or_tty);
   GenMarkSweep::trace("3");
 
   SharedHeap* sh = SharedHeap::heap();
@@ -399,7 +386,7 @@
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   Generation* pg = g1h->perm_gen();
 
-  TraceTime tm("phase 4", PrintGC && Verbose, true, gclog_or_tty);
+  TraceTime tm("phase 4", G1Log::fine() && Verbose, true, gclog_or_tty);
   GenMarkSweep::trace("4");
 
   pg->compact();
@@ -408,7 +395,3 @@
   g1h->heap_region_iterate(&blk);
 
 }
-
-// Local Variables: ***
-// c-indentation-style: gnu ***
-// End: ***
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp
index d22dc7a..55627cb 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,9 @@
                G1MonitoringSupport::pad_capacity(0, 3) /* min_capacity */,
                G1MonitoringSupport::pad_capacity(g1mm->young_gen_max(), 3),
                G1MonitoringSupport::pad_capacity(0, 3) /* curr_capacity */) {
-  update_all();
+  if (UsePerfData) {
+    update_all();
+  }
 }
 
 G1OldGenerationCounters::G1OldGenerationCounters(G1MonitoringSupport* g1mm,
@@ -53,7 +55,9 @@
                G1MonitoringSupport::pad_capacity(0) /* min_capacity */,
                G1MonitoringSupport::pad_capacity(g1mm->old_gen_max()),
                G1MonitoringSupport::pad_capacity(0) /* curr_capacity */) {
-  update_all();
+  if (UsePerfData) {
+    update_all();
+  }
 }
 
 void G1YoungGenerationCounters::update_all() {
@@ -149,10 +153,6 @@
     pad_capacity(0) /* max_capacity */,
     pad_capacity(0) /* init_capacity */,
     _young_collection_counters);
-  // Given that this survivor space is not used, we update it here
-  // once to reflect that its used space is 0 so that we don't have to
-  // worry about updating it again later.
-  _from_counters->update_used(0);
 
   //  name "generation.0.space.2"
   // See _old_space_counters for additional counters
@@ -160,6 +160,13 @@
     pad_capacity(overall_reserved()) /* max_capacity */,
     pad_capacity(survivor_space_committed()) /* init_capacity */,
     _young_collection_counters);
+
+  if (UsePerfData) {
+    // Given that this survivor space is not used, we update it here
+    // once to reflect that its used space is 0 so that we don't have to
+    // worry about updating it again later.
+    _from_counters->update_used(0);
+  }
 }
 
 void G1MonitoringSupport::recalculate_sizes() {
@@ -170,19 +177,19 @@
   // values we read here are possible (i.e., at a STW phase at the end
   // of a GC).
 
-  size_t young_list_length = g1->young_list()->length();
-  size_t survivor_list_length = g1->g1_policy()->recorded_survivor_regions();
+  uint young_list_length = g1->young_list()->length();
+  uint survivor_list_length = g1->g1_policy()->recorded_survivor_regions();
   assert(young_list_length >= survivor_list_length, "invariant");
-  size_t eden_list_length = young_list_length - survivor_list_length;
+  uint eden_list_length = young_list_length - survivor_list_length;
   // Max length includes any potential extensions to the young gen
   // we'll do when the GC locker is active.
-  size_t young_list_max_length = g1->g1_policy()->young_list_max_length();
+  uint young_list_max_length = g1->g1_policy()->young_list_max_length();
   assert(young_list_max_length >= survivor_list_length, "invariant");
-  size_t eden_list_max_length = young_list_max_length - survivor_list_length;
+  uint eden_list_max_length = young_list_max_length - survivor_list_length;
 
   _overall_used = g1->used_unlocked();
-  _eden_used = eden_list_length * HeapRegion::GrainBytes;
-  _survivor_used = survivor_list_length * HeapRegion::GrainBytes;
+  _eden_used = (size_t) eden_list_length * HeapRegion::GrainBytes;
+  _survivor_used = (size_t) survivor_list_length * HeapRegion::GrainBytes;
   _young_region_num = young_list_length;
   _old_used = subtract_up_to_zero(_overall_used, _eden_used + _survivor_used);
 
@@ -200,7 +207,7 @@
   committed -= _survivor_committed + _old_committed;
 
   // Next, calculate and remove the committed size for the eden.
-  _eden_committed = eden_list_max_length * HeapRegion::GrainBytes;
+  _eden_committed = (size_t) eden_list_max_length * HeapRegion::GrainBytes;
   // Somewhat defensive: be robust in case there are inaccuracies in
   // the calculations
   _eden_committed = MIN2(_eden_committed, committed);
@@ -230,10 +237,10 @@
   // When a new eden region is allocated, only the eden_used size is
   // affected (since we have recalculated everything else at the last GC).
 
-  size_t young_region_num = g1h()->young_list()->length();
+  uint young_region_num = g1h()->young_list()->length();
   if (young_region_num > _young_region_num) {
-    size_t diff = young_region_num - _young_region_num;
-    _eden_used += diff * HeapRegion::GrainBytes;
+    uint diff = young_region_num - _young_region_num;
+    _eden_used += (size_t) diff * HeapRegion::GrainBytes;
     // Somewhat defensive: cap the eden used size to make sure it
     // never exceeds the committed size.
     _eden_used = MIN2(_eden_used, _eden_committed);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp
index a428b10..4e1761e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1MonitoringSupport.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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,7 +112,7 @@
 // do which is important as we want to keep the eden region allocation
 // path as low-overhead as possible.
 
-class G1MonitoringSupport : public CHeapObj {
+class G1MonitoringSupport : public CHeapObj<mtGC> {
   friend class VMStructs;
 
   G1CollectedHeap* _g1h;
@@ -147,7 +147,7 @@
   size_t _overall_committed;
   size_t _overall_used;
 
-  size_t _young_region_num;
+  uint   _young_region_num;
   size_t _young_gen_committed;
   size_t _eden_committed;
   size_t _eden_used;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp
index 52a6c50..cc5b986 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.hpp
@@ -118,9 +118,11 @@
   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
 };
 
+template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
+class G1ParCopyClosure : public G1ParClosureSuper {
+  G1ParScanClosure _scanner;
+  template <class T> void do_oop_work(T* p);
 
-class G1ParCopyHelper : public G1ParClosureSuper {
-  G1ParScanClosure *_scanner;
 protected:
   // Mark the object if it's not already marked. This is used to mark
   // objects pointed to by roots that are guaranteed not to move
@@ -135,22 +137,10 @@
   oop copy_to_survivor_space(oop obj);
 
 public:
-  G1ParCopyHelper(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state,
-                  G1ParScanClosure *scanner) :
-    G1ParClosureSuper(g1, par_scan_state), _scanner(scanner) { }
-};
-
-template <bool do_gen_barrier, G1Barrier barrier, bool do_mark_object>
-class G1ParCopyClosure : public G1ParCopyHelper {
-  G1ParScanClosure _scanner;
-
-  template <class T> void do_oop_work(T* p);
-
-public:
   G1ParCopyClosure(G1CollectedHeap* g1, G1ParScanThreadState* par_scan_state,
                    ReferenceProcessor* rp) :
       _scanner(g1, par_scan_state, rp),
-      G1ParCopyHelper(g1, par_scan_state, &_scanner) {
+      G1ParClosureSuper(g1, par_scan_state) {
     assert(_ref_processor == NULL, "sanity");
   }
 
@@ -207,7 +197,6 @@
   HeapWord* _r_bottom;
   HeapWord* _r_end;
   OopClosure* _oc;
-  int _out_of_region;
 public:
   FilterOutOfRegionClosure(HeapRegion* r, OopClosure* oc);
   template <class T> void do_oop_nv(T* p);
@@ -215,7 +204,6 @@
   virtual void do_oop(narrowOop* p) { do_oop_nv(p); }
   bool apply_to_weak_ref_discovered_field() { return true; }
   bool do_header() { return false; }
-  int out_of_region() { return _out_of_region; }
 };
 
 // Closure for iterating over object fields during concurrent marking
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp
index 18a9c02..c84de6e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1OopClosures.inline.hpp
@@ -29,31 +29,22 @@
 #include "gc_implementation/g1/g1CollectedHeap.hpp"
 #include "gc_implementation/g1/g1OopClosures.hpp"
 #include "gc_implementation/g1/g1RemSet.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
 
 /*
  * This really ought to be an inline function, but apparently the C++
  * compiler sometimes sees fit to ignore inline declarations.  Sigh.
  */
 
-// This must a ifdef'ed because the counting it controls is in a
-// perf-critical inner loop.
-#define FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT 0
-
 template <class T>
 inline void FilterIntoCSClosure::do_oop_nv(T* p) {
   T heap_oop = oopDesc::load_heap_oop(p);
   if (!oopDesc::is_null(heap_oop) &&
       _g1->obj_in_cs(oopDesc::decode_heap_oop_not_null(heap_oop))) {
     _oc->do_oop(p);
-#if FILTERINTOCSCLOSURE_DOHISTOGRAMCOUNT
-    if (_dcto_cl != NULL)
-      _dcto_cl->incr_count();
-#endif
   }
 }
 
-#define FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT 0
-
 template <class T>
 inline void FilterOutOfRegionClosure::do_oop_nv(T* p) {
   T heap_oop = oopDesc::load_heap_oop(p);
@@ -61,9 +52,6 @@
     HeapWord* obj_hw = (HeapWord*)oopDesc::decode_heap_oop_not_null(heap_oop);
     if (obj_hw < _r_bottom || obj_hw >= _r_end) {
       _oc->do_oop(p);
-#if FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT
-      _out_of_region++;
-#endif
     }
   }
 }
@@ -182,6 +170,7 @@
 #endif // ASSERT
 
   assert(_from != NULL, "from region must be non-NULL");
+  assert(_from->is_in_reserved(p), "p is not in from");
 
   HeapRegion* to = _g1->heap_region_containing(obj);
   if (to != NULL && _from != to) {
@@ -212,14 +201,16 @@
       // or processed (if an evacuation failure occurs) at the end
       // of the collection.
       // See G1RemSet::cleanup_after_oops_into_collection_set_do().
-    } else {
-      // We either don't care about pushing references that point into the
-      // collection set (i.e. we're not during an evacuation pause) _or_
-      // the reference doesn't point into the collection set. Either way
-      // we add the reference directly to the RSet of the region containing
-      // the referenced object.
-      _g1_rem_set->par_write_ref(_from, p, _worker_i);
+      return;
     }
+
+    // We either don't care about pushing references that point into the
+    // collection set (i.e. we're not during an evacuation pause) _or_
+    // the reference doesn't point into the collection set. Either way
+    // we add the reference directly to the RSet of the region containing
+    // the referenced object.
+    assert(to->rem_set() != NULL, "Need per-region 'into' remsets.");
+    to->rem_set()->add_reference(p, _worker_i);
   }
 }
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
index 1f366c8..b6d8219 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.cpp
@@ -29,6 +29,7 @@
 #include "gc_implementation/g1/g1BlockOffsetTable.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1GCPhaseTimes.hpp"
 #include "gc_implementation/g1/g1OopClosures.inline.hpp"
 #include "gc_implementation/g1/g1RemSet.inline.hpp"
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
@@ -75,7 +76,7 @@
 {
   _seq_task = new SubTasksDone(NumSeqTasks);
   guarantee(n_workers() > 0, "There should be some workers");
-  _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers());
+  _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC);
   for (uint i = 0; i < n_workers(); i++) {
     _cset_rs_update_cl[i] = NULL;
   }
@@ -86,7 +87,7 @@
   for (uint i = 0; i < n_workers(); i++) {
     assert(_cset_rs_update_cl[i] == NULL, "it should be");
   }
-  FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl);
+  FREE_C_HEAP_ARRAY(OopsInHeapRegionClosure*, _cset_rs_update_cl, mtGC);
 }
 
 void CountNonCleanMemRegionClosure::do_MemRegion(MemRegion mr) {
@@ -224,7 +225,7 @@
   assert( _cards_scanned != NULL, "invariant" );
   _cards_scanned[worker_i] = scanRScl.cards_done();
 
-  _g1p->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
+  _g1p->phase_times()->record_scan_rs_time(worker_i, scan_rs_time_sec * 1000.0);
 }
 
 // Closure used for updating RSets and recording references that
@@ -276,65 +277,9 @@
     guarantee(cl.n() == 0, "Card table should be clean.");
   }
 
-  _g1p->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
+  _g1p->phase_times()->record_update_rs_time(worker_i, (os::elapsedTime() - start) * 1000.0);
 }
 
-class CountRSSizeClosure: public HeapRegionClosure {
-  size_t _n;
-  size_t _tot;
-  size_t _max;
-  HeapRegion* _max_r;
-  enum {
-    N = 20,
-    MIN = 6
-  };
-  int _histo[N];
-public:
-  CountRSSizeClosure() : _n(0), _tot(0), _max(0), _max_r(NULL) {
-    for (int i = 0; i < N; i++) _histo[i] = 0;
-  }
-  bool doHeapRegion(HeapRegion* r) {
-    if (!r->continuesHumongous()) {
-      size_t occ = r->rem_set()->occupied();
-      _n++;
-      _tot += occ;
-      if (occ > _max) {
-        _max = occ;
-        _max_r = r;
-      }
-      // Fit it into a histo bin.
-      int s = 1 << MIN;
-      int i = 0;
-      while (occ > (size_t) s && i < (N-1)) {
-        s = s << 1;
-        i++;
-      }
-      _histo[i]++;
-    }
-    return false;
-  }
-  size_t n() { return _n; }
-  size_t tot() { return _tot; }
-  size_t mx() { return _max; }
-  HeapRegion* mxr() { return _max_r; }
-  void print_histo() {
-    int mx = N;
-    while (mx >= 0) {
-      if (_histo[mx-1] > 0) break;
-      mx--;
-    }
-    gclog_or_tty->print_cr("Number of regions with given RS sizes:");
-    gclog_or_tty->print_cr("           <= %8d   %8d", 1 << MIN, _histo[0]);
-    for (int i = 1; i < mx-1; i++) {
-      gclog_or_tty->print_cr("  %8d  - %8d   %8d",
-                    (1 << (MIN + i - 1)) + 1,
-                    1 << (MIN + i),
-                    _histo[i]);
-    }
-    gclog_or_tty->print_cr("            > %8d   %8d", (1 << (MIN+mx-2))+1, _histo[mx-1]);
-  }
-};
-
 void G1RemSet::cleanupHRRS() {
   HeapRegionRemSet::cleanup();
 }
@@ -348,17 +293,6 @@
     _cg1r->clear_and_record_card_counts();
   }
 
-  // Make this into a command-line flag...
-  if (G1RSCountHisto && (ParallelGCThreads == 0 || worker_i == 0)) {
-    CountRSSizeClosure count_cl;
-    _g1->heap_region_iterate(&count_cl);
-    gclog_or_tty->print_cr("Avg of %d RS counts is %f, max is %d, "
-                  "max region is " PTR_FORMAT,
-                  count_cl.n(), (float)count_cl.tot()/(float)count_cl.n(),
-                  count_cl.mx(), count_cl.mxr());
-    count_cl.print_histo();
-  }
-
   // We cache the value of 'oc' closure into the appropriate slot in the
   // _cset_rs_update_cl for this worker
   assert(worker_i < (int)n_workers(), "sanity");
@@ -390,13 +324,13 @@
   if (G1UseParallelRSetUpdating || (worker_i == 0)) {
     updateRS(&into_cset_dcq, worker_i);
   } else {
-    _g1p->record_update_rs_processed_buffers(worker_i, 0.0);
-    _g1p->record_update_rs_time(worker_i, 0.0);
+    _g1p->phase_times()->record_update_rs_processed_buffers(worker_i, 0);
+    _g1p->phase_times()->record_update_rs_time(worker_i, 0.0);
   }
   if (G1UseParallelRSetScanning || (worker_i == 0)) {
     scanRS(oc, worker_i);
   } else {
-    _g1p->record_scan_rs_time(worker_i, 0.0);
+    _g1p->phase_times()->record_scan_rs_time(worker_i, 0.0);
   }
 
   // We now clear the cached values of _cset_rs_update_cl for this worker
@@ -416,7 +350,7 @@
     // _seq_task->set_n_termination((int)n_workers());
   }
   guarantee( _cards_scanned == NULL, "invariant" );
-  _cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers());
+  _cards_scanned = NEW_C_HEAP_ARRAY(size_t, n_workers(), mtGC);
   for (uint i = 0; i < n_workers(); ++i) {
     _cards_scanned[i] = 0;
   }
@@ -487,7 +421,7 @@
   for (uint i = 0; i < n_workers(); ++i) {
     _total_cards_scanned += _cards_scanned[i];
   }
-  FREE_C_HEAP_ARRAY(size_t, _cards_scanned);
+  FREE_C_HEAP_ARRAY(size_t, _cards_scanned, mtGC);
   _cards_scanned = NULL;
   // Cleanup after copy
   _g1->set_refine_cte_cl_concurrency(true);
@@ -567,8 +501,6 @@
 }
 
 
-static IntHistogram out_of_histo(50, 50);
-
 
 G1TriggerClosure::G1TriggerClosure() :
   _triggered(false) { }
@@ -670,7 +602,6 @@
       sdcq->enqueue(card_ptr);
     }
   } else {
-    out_of_histo.add_entry(filter_then_update_rs_oop_cl.out_of_region());
     _conc_refine_cards++;
   }
 
@@ -861,11 +792,6 @@
   card_repeat_count.print_on(gclog_or_tty);
 #endif
 
-  if (FILTEROUTOFREGIONCLOSURE_DOHISTOGRAMCOUNT) {
-    gclog_or_tty->print_cr("\nG1 rem-set out-of-region histogram: ");
-    gclog_or_tty->print_cr("  # of CS ptrs --> # of cards with that number.");
-    out_of_histo.print_on(gclog_or_tty);
-  }
   gclog_or_tty->print_cr("\n Concurrent RS processed %d cards",
                          _conc_refine_cards);
   DirtyCardQueueSet& dcqs = JavaThread::dirty_card_queue_set();
@@ -888,21 +814,24 @@
 
   HRRSStatsIter blk;
   g1->heap_region_iterate(&blk);
-  gclog_or_tty->print_cr("  Total heap region rem set sizes = " SIZE_FORMAT "K."
-                         "  Max = " SIZE_FORMAT "K.",
+  gclog_or_tty->print_cr("  Total heap region rem set sizes = "SIZE_FORMAT"K."
+                         "  Max = "SIZE_FORMAT"K.",
                          blk.total_mem_sz()/K, blk.max_mem_sz()/K);
-  gclog_or_tty->print_cr("  Static structures = " SIZE_FORMAT "K,"
-                         " free_lists = " SIZE_FORMAT "K.",
-                         HeapRegionRemSet::static_mem_size()/K,
-                         HeapRegionRemSet::fl_mem_size()/K);
-  gclog_or_tty->print_cr("    %d occupied cards represented.",
+  gclog_or_tty->print_cr("  Static structures = "SIZE_FORMAT"K,"
+                         " free_lists = "SIZE_FORMAT"K.",
+                         HeapRegionRemSet::static_mem_size() / K,
+                         HeapRegionRemSet::fl_mem_size() / K);
+  gclog_or_tty->print_cr("    "SIZE_FORMAT" occupied cards represented.",
                          blk.occupied());
-  gclog_or_tty->print_cr("    Max sz region = [" PTR_FORMAT ", " PTR_FORMAT " )"
-                         ", cap = " SIZE_FORMAT "K, occ = " SIZE_FORMAT "K.",
-                         blk.max_mem_sz_region()->bottom(), blk.max_mem_sz_region()->end(),
-                         (blk.max_mem_sz_region()->rem_set()->mem_size() + K - 1)/K,
-                         (blk.max_mem_sz_region()->rem_set()->occupied() + K - 1)/K);
-  gclog_or_tty->print_cr("    Did %d coarsenings.", HeapRegionRemSet::n_coarsenings());
+  HeapRegion* max_mem_sz_region = blk.max_mem_sz_region();
+  HeapRegionRemSet* rem_set = max_mem_sz_region->rem_set();
+  gclog_or_tty->print_cr("    Max size region = "HR_FORMAT", "
+                         "size = "SIZE_FORMAT "K, occupied = "SIZE_FORMAT"K.",
+                         HR_FORMAT_PARAMS(max_mem_sz_region),
+                         (rem_set->mem_size() + K - 1)/K,
+                         (rem_set->occupied() + K - 1)/K);
+  gclog_or_tty->print_cr("    Did %d coarsenings.",
+                         HeapRegionRemSet::n_coarsenings());
 }
 
 void G1RemSet::prepare_for_verify() {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
index 9c86905..edf28a0 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1RemSet.hpp
@@ -36,7 +36,7 @@
 // external heap references into it.  Uses a mod ref bs to track updates,
 // so that they can be used to update the individual region remsets.
 
-class G1RemSet: public CHeapObj {
+class G1RemSet: public CHeapObj<mtGC> {
 protected:
   G1CollectedHeap* _g1;
   unsigned _conc_refine_cards;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
index 137e8df..a8405e0 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1_globals.hpp
@@ -26,7 +26,6 @@
 #define SHARE_VM_GC_IMPLEMENTATION_G1_G1_GLOBALS_HPP
 
 #include "runtime/globals.hpp"
-
 //
 // Defines all globals flags used by the garbage-first compiler.
 //
@@ -54,6 +53,9 @@
   develop(bool, G1TraceMarkStackOverflow, false,                            \
           "If true, extra debugging code for CM restart for ovflw.")        \
                                                                             \
+  develop(bool, G1TraceHeapRegionRememberedSet, false,                      \
+          "Enables heap region remembered set debug logs")                  \
+                                                                            \
   diagnostic(bool, G1SummarizeConcMark, false,                              \
           "Summarize concurrent mark info")                                 \
                                                                             \
@@ -69,9 +71,6 @@
   diagnostic(bool, G1TraceConcRefinement, false,                            \
           "Trace G1 concurrent refinement")                                 \
                                                                             \
-  product(intx, G1MarkRegionStackSize, 1024 * 1024,                         \
-          "Size of the region stack for concurrent marking.")               \
-                                                                            \
   product(double, G1ConcMarkStepDurationMillis, 10.0,                       \
           "Target duration of individual concurrent marking steps "         \
           "in milliseconds.")                                               \
@@ -131,9 +130,6 @@
             "Prints the liveness information for all regions in the heap "  \
             "at the end of a marking cycle.")                               \
                                                                             \
-  develop(bool, G1PrintParCleanupStats, false,                              \
-          "When true, print extra stats about parallel cleanup.")           \
-                                                                            \
   product(intx, G1UpdateBufferSize, 256,                                    \
           "Size of an update buffer")                                       \
                                                                             \
@@ -291,29 +287,59 @@
           "The number of times we'll force an overflow during "             \
           "concurrent marking")                                             \
                                                                             \
-  develop(uintx, G1DefaultMinNewGenPercent, 20,                             \
+  experimental(uintx, G1DefaultMinNewGenPercent, 20,                        \
           "Percentage (0-100) of the heap size to use as minimum "          \
           "young gen size.")                                                \
                                                                             \
-  develop(uintx, G1DefaultMaxNewGenPercent, 80,                             \
+  experimental(uintx, G1DefaultMaxNewGenPercent, 80,                        \
           "Percentage (0-100) of the heap size to use as maximum "          \
           "young gen size.")                                                \
                                                                             \
-  develop(uintx, G1OldCSetRegionLiveThresholdPercent, 95,                   \
+  experimental(uintx, G1OldCSetRegionLiveThresholdPercent, 90,              \
           "Threshold for regions to be added to the collection set. "       \
-          "Regions with more live bytes that this will not be collected.")  \
+          "Regions with more live bytes than this will not be collected.")  \
                                                                             \
-  develop(uintx, G1OldReclaimableThresholdPercent, 1,                       \
-          "Threshold for the remaining old reclaimable bytes, expressed "   \
-          "as a percentage of the heap size. If the old reclaimable bytes " \
-          "are under this we will not collect them with more mixed GCs.")   \
+  product(uintx, G1HeapWastePercent, 5,                                     \
+          "Amount of space, expressed as a percentage of the heap size, "   \
+          "that G1 is willing not to collect to avoid expensive GCs.")      \
                                                                             \
-  develop(uintx, G1MaxMixedGCNum, 4,                                        \
-          "The maximum desired number of mixed GCs after a marking cycle.") \
+  product(uintx, G1MixedGCCountTarget, 4,                                   \
+          "The target number of mixed GCs after a marking cycle.")          \
                                                                             \
-  develop(uintx, G1OldCSetRegionThresholdPercent, 10,                       \
+  experimental(uintx, G1OldCSetRegionThresholdPercent, 10,                  \
           "An upper bound for the number of old CSet regions expressed "    \
-          "as a percentage of the heap size.")
+          "as a percentage of the heap size.")                              \
+                                                                            \
+  experimental(ccstr, G1LogLevel, NULL,                                     \
+          "Log level for G1 logging: fine, finer, finest")                  \
+                                                                            \
+  notproduct(bool, G1EvacuationFailureALot, false,                          \
+          "Force use of evacuation failure handling during certain "        \
+          "evacuation pauses")                                              \
+                                                                            \
+  develop(uintx, G1EvacuationFailureALotCount, 1000,                        \
+          "Number of successful evacuations between evacuation failures "   \
+          "occurring at object copying")                                    \
+                                                                            \
+  develop(uintx, G1EvacuationFailureALotInterval, 5,                        \
+          "Total collections between forced triggering of evacuation "      \
+          "failures")                                                       \
+                                                                            \
+  develop(bool, G1EvacuationFailureALotDuringConcMark, true,                \
+          "Force use of evacuation failure handling during evacuation "     \
+          "pauses when marking is in progress")                             \
+                                                                            \
+  develop(bool, G1EvacuationFailureALotDuringInitialMark, true,             \
+          "Force use of evacuation failure handling during initial mark "   \
+          "evacuation pauses")                                              \
+                                                                            \
+  develop(bool, G1EvacuationFailureALotDuringYoungGC, true,                 \
+          "Force use of evacuation failure handling during young "          \
+          "evacuation pauses")                                              \
+                                                                            \
+  develop(bool, G1EvacuationFailureALotDuringMixedGC, true,                 \
+          "Force use of evacuation failure handling during mixed "          \
+          "evacuation pauses")
 
 G1_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG, DECLARE_MANAGEABLE_FLAG, DECLARE_PRODUCT_RW_FLAG)
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
index 0fc499e..a6046f1 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.cpp
@@ -44,14 +44,11 @@
                                  CardTableModRefBS::PrecisionStyle precision,
                                  FilterKind fk) :
   ContiguousSpaceDCTOC(hr, cl, precision, NULL),
-  _hr(hr), _fk(fk), _g1(g1)
-{ }
+  _hr(hr), _fk(fk), _g1(g1) { }
 
 FilterOutOfRegionClosure::FilterOutOfRegionClosure(HeapRegion* r,
                                                    OopClosure* oc) :
-  _r_bottom(r->bottom()), _r_end(r->end()),
-  _oc(oc), _out_of_region(0)
-{}
+  _r_bottom(r->bottom()), _r_end(r->end()), _oc(oc) { }
 
 class VerifyLiveClosure: public OopClosure {
 private:
@@ -334,7 +331,7 @@
 
   guarantee(GrainWords == 0, "we should only set it once");
   GrainWords = GrainBytes >> LogHeapWordSize;
-  guarantee((size_t)(1 << LogOfHRGrainWords) == GrainWords, "sanity");
+  guarantee((size_t) 1 << LogOfHRGrainWords == GrainWords, "sanity");
 
   guarantee(CardsPerRegion == 0, "we should only set it once");
   CardsPerRegion = GrainBytes >> CardTableModRefBS::card_shift;
@@ -370,7 +367,6 @@
     _claimed = InitialClaimValue;
   }
   zero_marked_bytes();
-  set_sort_index(-1);
 
   _offsets.resize(HeapRegion::GrainWords);
   init_top_at_mark_start();
@@ -388,10 +384,17 @@
 }
 
 void HeapRegion::calc_gc_efficiency() {
+  // GC efficiency is the ratio of how much space would be
+  // reclaimed over how long we predict it would take to reclaim it.
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
   G1CollectorPolicy* g1p = g1h->g1_policy();
-  _gc_efficiency = (double) reclaimable_bytes() /
-                            g1p->predict_region_elapsed_time_ms(this, false);
+
+  // Retrieve a prediction of the elapsed time for this region for
+  // a mixed gc because the region will only be evacuated during a
+  // mixed gc.
+  double region_elapsed_time_ms =
+    g1p->predict_region_elapsed_time_ms(this, false /* for_young_gc */);
+  _gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms;
 }
 
 void HeapRegion::set_startsHumongous(HeapWord* new_top, HeapWord* new_end) {
@@ -482,17 +485,16 @@
 #endif // _MSC_VER
 
 
-HeapRegion::
-HeapRegion(size_t hrs_index, G1BlockOffsetSharedArray* sharedOffsetArray,
-           MemRegion mr, bool is_zeroed)
-  : G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed),
+HeapRegion::HeapRegion(uint hrs_index,
+                       G1BlockOffsetSharedArray* sharedOffsetArray,
+                       MemRegion mr, bool is_zeroed) :
+    G1OffsetTableContigSpace(sharedOffsetArray, mr, is_zeroed),
     _hrs_index(hrs_index),
     _humongous_type(NotHumongous), _humongous_start_region(NULL),
     _in_collection_set(false),
     _next_in_special_set(NULL), _orig_end(NULL),
     _claimed(InitialClaimValue), _evacuation_failed(false),
-    _prev_marked_bytes(0), _next_marked_bytes(0), _sort_index(-1),
-    _gc_efficiency(0.0),
+    _prev_marked_bytes(0), _next_marked_bytes(0), _gc_efficiency(0.0),
     _young_type(NotYoung), _next_young_region(NULL),
     _next_dirty_cards_region(NULL), _next(NULL), _pending_removal(false),
 #ifdef ASSERT
@@ -512,40 +514,21 @@
   _rem_set =  new HeapRegionRemSet(sharedOffsetArray, this);
 
   assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant.");
-  // In case the region is allocated during a pause, note the top.
-  // We haven't done any counting on a brand new region.
-  _top_at_conc_mark_count = bottom();
 }
 
-class NextCompactionHeapRegionClosure: public HeapRegionClosure {
-  const HeapRegion* _target;
-  bool _target_seen;
-  HeapRegion* _last;
-  CompactibleSpace* _res;
-public:
-  NextCompactionHeapRegionClosure(const HeapRegion* target) :
-    _target(target), _target_seen(false), _res(NULL) {}
-  bool doHeapRegion(HeapRegion* cur) {
-    if (_target_seen) {
-      if (!cur->isHumongous()) {
-        _res = cur;
-        return true;
-      }
-    } else if (cur == _target) {
-      _target_seen = true;
-    }
-    return false;
-  }
-  CompactibleSpace* result() { return _res; }
-};
-
 CompactibleSpace* HeapRegion::next_compaction_space() const {
+  // We're not using an iterator given that it will wrap around when
+  // it reaches the last region and this is not what we want here.
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
-  // cast away const-ness
-  HeapRegion* r = (HeapRegion*) this;
-  NextCompactionHeapRegionClosure blk(r);
-  g1h->heap_region_iterate_from(r, &blk);
-  return blk.result();
+  uint index = hrs_index() + 1;
+  while (index < g1h->n_regions()) {
+    HeapRegion* hr = g1h->region_at(index);
+    if (!hr->isHumongous()) {
+      return hr;
+    }
+    index += 1;
+  }
+  return NULL;
 }
 
 void HeapRegion::save_marks() {
@@ -587,14 +570,12 @@
     // we find to be self-forwarded on the next bitmap. So all
     // objects need to be below NTAMS.
     _next_top_at_mark_start = top();
-    set_top_at_conc_mark_count(bottom());
     _next_marked_bytes = 0;
   } else if (during_conc_mark) {
     // During concurrent mark, all objects in the CSet (including
     // the ones we find to be self-forwarded) are implicitly live.
     // So all objects need to be above NTAMS.
     _next_top_at_mark_start = bottom();
-    set_top_at_conc_mark_count(bottom());
     _next_marked_bytes = 0;
   }
 }
@@ -779,16 +760,15 @@
   G1OffsetTableContigSpace::print_on(st);
 }
 
-void HeapRegion::verify(bool allow_dirty) const {
+void HeapRegion::verify() const {
   bool dummy = false;
-  verify(allow_dirty, VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
+  verify(VerifyOption_G1UsePrevMarking, /* failures */ &dummy);
 }
 
 // This really ought to be commoned up into OffsetTableContigSpace somehow.
 // We would need a mechanism to make that code skip dead objects.
 
-void HeapRegion::verify(bool allow_dirty,
-                        VerifyOption vo,
+void HeapRegion::verify(VerifyOption vo,
                         bool* failures) const {
   G1CollectedHeap* g1 = G1CollectedHeap::heap();
   *failures = false;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
index 76843a0..8ab893f 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.hpp
@@ -52,12 +52,18 @@
 class HeapRegion;
 class HeapRegionSetBase;
 
-#define HR_FORMAT SIZE_FORMAT":(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
+#define HR_FORMAT "%u:(%s)["PTR_FORMAT","PTR_FORMAT","PTR_FORMAT"]"
 #define HR_FORMAT_PARAMS(_hr_) \
                 (_hr_)->hrs_index(), \
-                (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : "-", \
+                (_hr_)->is_survivor() ? "S" : (_hr_)->is_young() ? "E" : \
+                (_hr_)->startsHumongous() ? "HS" : \
+                (_hr_)->continuesHumongous() ? "HC" : \
+                !(_hr_)->is_empty() ? "O" : "F", \
                 (_hr_)->bottom(), (_hr_)->top(), (_hr_)->end()
 
+// sentinel value for hrs_index
+#define G1_NULL_HRS_INDEX ((uint) -1)
+
 // A dirty card to oop closure for heap regions. It
 // knows how to get the G1 heap and how to use the bitmap
 // in the concurrent marker used by G1 to filter remembered
@@ -170,6 +176,7 @@
   virtual HeapWord* saved_mark_word() const;
   virtual void set_saved_mark();
   void reset_gc_time_stamp() { _gc_time_stamp = 0; }
+  unsigned get_gc_time_stamp() { return _gc_time_stamp; }
 
   // See the comment above in the declaration of _pre_dummy_top for an
   // explanation of what it is.
@@ -235,7 +242,7 @@
 
  protected:
   // The index of this region in the heap region sequence.
-  size_t  _hrs_index;
+  uint  _hrs_index;
 
   HumongousType _humongous_type;
   // For a humongous region, region in which it starts.
@@ -278,12 +285,8 @@
   size_t _prev_marked_bytes;    // Bytes known to be live via last completed marking.
   size_t _next_marked_bytes;    // Bytes known to be live via in-progress marking.
 
-  // See "sort_index" method.  -1 means is not in the array.
-  int _sort_index;
-
-  // <PREDICTION>
+  // The calculated GC efficiency of the region.
   double _gc_efficiency;
-  // </PREDICTION>
 
   enum YoungType {
     NotYoung,                   // a region is not young
@@ -307,9 +310,6 @@
   // If a collection pause is in progress, this is the top at the start
   // of that pause.
 
-  // We've counted the marked bytes of objects below here.
-  HeapWord* _top_at_conc_mark_count;
-
   void init_top_at_mark_start() {
     assert(_prev_marked_bytes == 0 &&
            _next_marked_bytes == 0,
@@ -317,7 +317,6 @@
     HeapWord* bot = bottom();
     _prev_top_at_mark_start = bot;
     _next_top_at_mark_start = bot;
-    _top_at_conc_mark_count = bot;
   }
 
   void set_young_type(YoungType new_type) {
@@ -342,7 +341,7 @@
 
  public:
   // If "is_zeroed" is "true", the region "mr" can be assumed to contain zeros.
-  HeapRegion(size_t hrs_index,
+  HeapRegion(uint hrs_index,
              G1BlockOffsetSharedArray* sharedOffsetArray,
              MemRegion mr, bool is_zeroed);
 
@@ -373,10 +372,9 @@
     ScrubRemSetClaimValue      = 3,
     ParVerifyClaimValue        = 4,
     RebuildRSClaimValue        = 5,
-    CompleteMarkCSetClaimValue = 6,
-    ParEvacFailureClaimValue   = 7,
-    AggregateCountClaimValue   = 8,
-    VerifyCountClaimValue      = 9
+    ParEvacFailureClaimValue   = 6,
+    AggregateCountClaimValue   = 7,
+    VerifyCountClaimValue      = 8
   };
 
   inline HeapWord* par_allocate_no_bot_updates(size_t word_size) {
@@ -390,7 +388,7 @@
 
   // If this region is a member of a HeapRegionSeq, the index in that
   // sequence, otherwise -1.
-  size_t hrs_index() const { return _hrs_index; }
+  uint hrs_index() const { return _hrs_index; }
 
   // The number of bytes marked live in the region in the last marking phase.
   size_t marked_bytes()    { return _prev_marked_bytes; }
@@ -445,6 +443,25 @@
     return _humongous_start_region;
   }
 
+  // Return the number of distinct regions that are covered by this region:
+  // 1 if the region is not humongous, >= 1 if the region is humongous.
+  uint region_num() const {
+    if (!isHumongous()) {
+      return 1U;
+    } else {
+      assert(startsHumongous(), "doesn't make sense on HC regions");
+      assert(capacity() % HeapRegion::GrainBytes == 0, "sanity");
+      return (uint) (capacity() >> HeapRegion::LogOfHRGrainBytes);
+    }
+  }
+
+  // Return the index + 1 of the last HC regions that's associated
+  // with this HS region.
+  uint last_hc_index() const {
+    assert(startsHumongous(), "don't call this otherwise");
+    return hrs_index() + region_num();
+  }
+
   // Same as Space::is_in_reserved, but will use the original size of the region.
   // The original size is different only for start humongous regions. They get
   // their _end set up to be the end of the last continues region of the
@@ -627,32 +644,9 @@
   // last mark phase ended.
   bool is_marked() { return _prev_top_at_mark_start != bottom(); }
 
-  // If "is_marked()" is true, then this is the index of the region in
-  // an array constructed at the end of marking of the regions in a
-  // "desirability" order.
-  int sort_index() {
-    return _sort_index;
-  }
-  void set_sort_index(int i) {
-    _sort_index = i;
-  }
-
-  void init_top_at_conc_mark_count() {
-    _top_at_conc_mark_count = bottom();
-  }
-
-  void set_top_at_conc_mark_count(HeapWord *cur) {
-    assert(bottom() <= cur && cur <= end(), "Sanity.");
-    _top_at_conc_mark_count = cur;
-  }
-
-  HeapWord* top_at_conc_mark_count() {
-    return _top_at_conc_mark_count;
-  }
-
   void reset_during_compaction() {
-    guarantee( isHumongous() && startsHumongous(),
-               "should only be called for humongous regions");
+    assert(isHumongous() && startsHumongous(),
+           "should only be called for starts humongous regions");
 
     zero_marked_bytes();
     init_top_at_mark_start();
@@ -745,7 +739,6 @@
     _evacuation_failed = b;
 
     if (b) {
-      init_top_at_conc_mark_count();
       _next_marked_bytes = 0;
     }
   }
@@ -804,7 +797,7 @@
   virtual void oop_since_save_marks_iterate##nv_suffix(OopClosureType* cl);
   SPECIALIZED_SINCE_SAVE_MARKS_CLOSURES(HeapRegion_OOP_SINCE_SAVE_MARKS_DECL)
 
-  CompactibleSpace* next_compaction_space() const;
+  virtual CompactibleSpace* next_compaction_space() const;
 
   virtual void reset_after_compaction();
 
@@ -824,10 +817,10 @@
   // Currently there is only one place where this is called with
   // vo == UseMarkWord, which is to verify the marking during a
   // full GC.
-  void verify(bool allow_dirty, VerifyOption vo, bool *failures) const;
+  void verify(VerifyOption vo, bool *failures) const;
 
   // Override; it uses the "prev" marking information
-  virtual void verify(bool allow_dirty) const;
+  virtual void verify() const;
 };
 
 // HeapRegionClosure is used for iterating over regions.
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp
index 1498b94..d88bc07 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegion.inline.hpp
@@ -56,7 +56,6 @@
 }
 
 inline void HeapRegion::note_start_of_marking() {
-  init_top_at_conc_mark_count();
   _next_marked_bytes = 0;
   _next_top_at_mark_start = top();
 }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
index 47c4155..56e9405 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,102 +30,54 @@
 #include "gc_implementation/g1/heapRegionSeq.inline.hpp"
 #include "memory/allocation.hpp"
 #include "memory/space.inline.hpp"
+#include "oops/oop.inline.hpp"
 #include "utilities/bitMap.inline.hpp"
 #include "utilities/globalDefinitions.hpp"
 
-#define HRRS_VERBOSE 0
-
-#define PRT_COUNT_OCCUPIED 1
-
-// OtherRegionsTable
-
-class PerRegionTable: public CHeapObj {
+class PerRegionTable: public CHeapObj<mtGC> {
   friend class OtherRegionsTable;
   friend class HeapRegionRemSetIterator;
 
   HeapRegion*     _hr;
   BitMap          _bm;
-#if PRT_COUNT_OCCUPIED
   jint            _occupied;
-#endif
-  PerRegionTable* _next_free;
 
-  PerRegionTable* next_free() { return _next_free; }
-  void set_next_free(PerRegionTable* prt) { _next_free = prt; }
+  // next pointer for free/allocated 'all' list
+  PerRegionTable* _next;
 
+  // prev pointer for the allocated 'all' list
+  PerRegionTable* _prev;
 
+  // next pointer in collision list
+  PerRegionTable * _collision_list_next;
+
+  // Global free list of PRTs
   static PerRegionTable* _free_list;
 
-#ifdef _MSC_VER
-  // For some reason even though the classes are marked as friend they are unable
-  // to access CardsPerRegion when private/protected. Only the windows c++ compiler
-  // says this Sun CC and linux gcc don't have a problem with access when private
-
-  public:
-
-#endif // _MSC_VER
-
 protected:
   // We need access in order to union things into the base table.
   BitMap* bm() { return &_bm; }
 
-#if PRT_COUNT_OCCUPIED
   void recount_occupied() {
     _occupied = (jint) bm()->count_one_bits();
   }
-#endif
 
   PerRegionTable(HeapRegion* hr) :
     _hr(hr),
-#if PRT_COUNT_OCCUPIED
     _occupied(0),
-#endif
-    _bm(HeapRegion::CardsPerRegion, false /* in-resource-area */)
+    _bm(HeapRegion::CardsPerRegion, false /* in-resource-area */),
+    _collision_list_next(NULL), _next(NULL), _prev(NULL)
   {}
 
-  static void free(PerRegionTable* prt) {
-    while (true) {
-      PerRegionTable* fl = _free_list;
-      prt->set_next_free(fl);
-      PerRegionTable* res =
-        (PerRegionTable*)
-        Atomic::cmpxchg_ptr(prt, &_free_list, fl);
-      if (res == fl) return;
-    }
-    ShouldNotReachHere();
-  }
-
-  static PerRegionTable* alloc(HeapRegion* hr) {
-    PerRegionTable* fl = _free_list;
-    while (fl != NULL) {
-      PerRegionTable* nxt = fl->next_free();
-      PerRegionTable* res =
-        (PerRegionTable*)
-        Atomic::cmpxchg_ptr(nxt, &_free_list, fl);
-      if (res == fl) {
-        fl->init(hr);
-        return fl;
-      } else {
-        fl = _free_list;
-      }
-    }
-    assert(fl == NULL, "Loop condition.");
-    return new PerRegionTable(hr);
-  }
-
   void add_card_work(CardIdx_t from_card, bool par) {
     if (!_bm.at(from_card)) {
       if (par) {
         if (_bm.par_at_put(from_card, 1)) {
-#if PRT_COUNT_OCCUPIED
           Atomic::inc(&_occupied);
-#endif
         }
       } else {
         _bm.at_put(from_card, 1);
-#if PRT_COUNT_OCCUPIED
         _occupied++;
-#endif
       }
     }
   }
@@ -134,10 +86,13 @@
     // Must make this robust in case "from" is not in "_hr", because of
     // concurrency.
 
-#if HRRS_VERBOSE
-    gclog_or_tty->print_cr("    PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT").",
-                           from, *from);
-#endif
+    if (G1TraceHeapRegionRememberedSet) {
+      gclog_or_tty->print_cr("    PRT::Add_reference_work(" PTR_FORMAT "->" PTR_FORMAT").",
+                             from,
+                             UseCompressedOops
+                             ? oopDesc::load_decode_heap_oop((narrowOop*)from)
+                             : oopDesc::load_decode_heap_oop((oop*)from));
+    }
 
     HeapRegion* loc_hr = hr();
     // If the test below fails, then this table was reused concurrently
@@ -162,23 +117,20 @@
 
   HeapRegion* hr() const { return _hr; }
 
-#if PRT_COUNT_OCCUPIED
   jint occupied() const {
     // Overkill, but if we ever need it...
     // guarantee(_occupied == _bm.count_one_bits(), "Check");
     return _occupied;
   }
-#else
-  jint occupied() const {
-    return _bm.count_one_bits();
-  }
-#endif
 
-  void init(HeapRegion* hr) {
+  void init(HeapRegion* hr, bool clear_links_to_all_list) {
+    if (clear_links_to_all_list) {
+      set_next(NULL);
+      set_prev(NULL);
+    }
     _hr = hr;
-#if PRT_COUNT_OCCUPIED
+    _collision_list_next = NULL;
     _occupied = 0;
-#endif
     _bm.clear();
   }
 
@@ -194,9 +146,7 @@
     HeapWord* hr_bot = hr()->bottom();
     size_t hr_first_card_index = ctbs->index_for(hr_bot);
     bm()->set_intersection_at_offset(*card_bm, hr_first_card_index);
-#if PRT_COUNT_OCCUPIED
     recount_occupied();
-#endif
   }
 
   void add_card(CardIdx_t from_card_index) {
@@ -218,16 +168,6 @@
     return sizeof(this) + _bm.size_in_words() * HeapWordSize;
   }
 
-  static size_t fl_mem_size() {
-    PerRegionTable* cur = _free_list;
-    size_t res = 0;
-    while (cur != NULL) {
-      res += sizeof(PerRegionTable);
-      cur = cur->next_free();
-    }
-    return res;
-  }
-
   // Requires "from" to be in "hr()".
   bool contains_reference(OopOrNarrowOopStar from) const {
     assert(hr()->is_in_reserved(from), "Precondition.");
@@ -235,273 +175,86 @@
                                     CardTableModRefBS::card_size);
     return _bm.at(card_ind);
   }
-};
 
-PerRegionTable* PerRegionTable::_free_list = NULL;
-
-
-#define COUNT_PAR_EXPANDS 0
-
-#if COUNT_PAR_EXPANDS
-static jint n_par_expands = 0;
-static jint n_par_contracts = 0;
-static jint par_expand_list_len = 0;
-static jint max_par_expand_list_len = 0;
-
-static void print_par_expand() {
-  Atomic::inc(&n_par_expands);
-  Atomic::inc(&par_expand_list_len);
-  if (par_expand_list_len > max_par_expand_list_len) {
-    max_par_expand_list_len = par_expand_list_len;
-  }
-  if ((n_par_expands % 10) == 0) {
-    gclog_or_tty->print_cr("\n\n%d par expands: %d contracts, "
-                  "len = %d, max_len = %d\n.",
-                  n_par_expands, n_par_contracts, par_expand_list_len,
-                  max_par_expand_list_len);
-  }
-}
-#endif
-
-class PosParPRT: public PerRegionTable {
-  PerRegionTable** _par_tables;
-
-  enum SomePrivateConstants {
-    ReserveParTableExpansion = 1
-  };
-
-  void par_contract() {
-    assert(_par_tables != NULL, "Precondition.");
-    int n = HeapRegionRemSet::num_par_rem_sets()-1;
-    for (int i = 0; i < n; i++) {
-      _par_tables[i]->union_bitmap_into(bm());
-      PerRegionTable::free(_par_tables[i]);
-      _par_tables[i] = NULL;
-    }
-#if PRT_COUNT_OCCUPIED
-    // We must recount the "occupied."
-    recount_occupied();
-#endif
-    FREE_C_HEAP_ARRAY(PerRegionTable*, _par_tables);
-    _par_tables = NULL;
-#if COUNT_PAR_EXPANDS
-    Atomic::inc(&n_par_contracts);
-    Atomic::dec(&par_expand_list_len);
-#endif
-  }
-
-  static PerRegionTable** _par_table_fl;
-
-  PosParPRT* _next;
-
-  static PosParPRT* _free_list;
-
-  PerRegionTable** par_tables() const {
-    assert(uintptr_t(NULL) == 0, "Assumption.");
-    if (uintptr_t(_par_tables) <= ReserveParTableExpansion)
-      return NULL;
-    else
-      return _par_tables;
-  }
-
-  PosParPRT* _next_par_expanded;
-  PosParPRT* next_par_expanded() { return _next_par_expanded; }
-  void set_next_par_expanded(PosParPRT* ppprt) { _next_par_expanded = ppprt; }
-  static PosParPRT* _par_expanded_list;
-
-public:
-
-  PosParPRT(HeapRegion* hr) : PerRegionTable(hr), _par_tables(NULL) {}
-
-  jint occupied() const {
-    jint res = PerRegionTable::occupied();
-    if (par_tables() != NULL) {
-      for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets()-1; i++) {
-        res += par_tables()[i]->occupied();
-      }
-    }
-    return res;
-  }
-
-  void init(HeapRegion* hr) {
-    PerRegionTable::init(hr);
-    _next = NULL;
-    if (par_tables() != NULL) {
-      for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets()-1; i++) {
-        par_tables()[i]->init(hr);
-      }
-    }
-  }
-
-  static void free(PosParPRT* prt) {
+  // Bulk-free the PRTs from prt to last, assumes that they are
+  // linked together using their _next field.
+  static void bulk_free(PerRegionTable* prt, PerRegionTable* last) {
     while (true) {
-      PosParPRT* fl = _free_list;
-      prt->set_next(fl);
-      PosParPRT* res =
-        (PosParPRT*)
-        Atomic::cmpxchg_ptr(prt, &_free_list, fl);
-      if (res == fl) return;
+      PerRegionTable* fl = _free_list;
+      last->set_next(fl);
+      PerRegionTable* res = (PerRegionTable*) Atomic::cmpxchg_ptr(prt, &_free_list, fl);
+      if (res == fl) {
+        return;
+      }
     }
     ShouldNotReachHere();
   }
 
-  static PosParPRT* alloc(HeapRegion* hr) {
-    PosParPRT* fl = _free_list;
+  static void free(PerRegionTable* prt) {
+    bulk_free(prt, prt);
+  }
+
+  // Returns an initialized PerRegionTable instance.
+  static PerRegionTable* alloc(HeapRegion* hr) {
+    PerRegionTable* fl = _free_list;
     while (fl != NULL) {
-      PosParPRT* nxt = fl->next();
-      PosParPRT* res =
-        (PosParPRT*)
+      PerRegionTable* nxt = fl->next();
+      PerRegionTable* res =
+        (PerRegionTable*)
         Atomic::cmpxchg_ptr(nxt, &_free_list, fl);
       if (res == fl) {
-        fl->init(hr);
+        fl->init(hr, true);
         return fl;
       } else {
         fl = _free_list;
       }
     }
     assert(fl == NULL, "Loop condition.");
-    return new PosParPRT(hr);
+    return new PerRegionTable(hr);
   }
 
-  PosParPRT* next() const { return _next; }
-  void set_next(PosParPRT* nxt) { _next = nxt; }
-  PosParPRT** next_addr() { return &_next; }
+  PerRegionTable* next() const { return _next; }
+  void set_next(PerRegionTable* next) { _next = next; }
+  PerRegionTable* prev() const { return _prev; }
+  void set_prev(PerRegionTable* prev) { _prev = prev; }
 
-  bool should_expand(int tid) {
-    // Given that we now defer RSet updates for after a GC we don't
-    // really need to expand the tables any more. This code should be
-    // cleaned up in the future (see CR 6921087).
-    return false;
+  // Accessor and Modification routines for the pointer for the
+  // singly linked collision list that links the PRTs within the
+  // OtherRegionsTable::_fine_grain_regions hash table.
+  //
+  // It might be useful to also make the collision list doubly linked
+  // to avoid iteration over the collisions list during scrubbing/deletion.
+  // OTOH there might not be many collisions.
+
+  PerRegionTable* collision_list_next() const {
+    return _collision_list_next;
   }
 
-  void par_expand() {
-    int n = HeapRegionRemSet::num_par_rem_sets()-1;
-    if (n <= 0) return;
-    if (_par_tables == NULL) {
-      PerRegionTable* res =
-        (PerRegionTable*)
-        Atomic::cmpxchg_ptr((PerRegionTable*)ReserveParTableExpansion,
-                            &_par_tables, NULL);
-      if (res != NULL) return;
-      // Otherwise, we reserved the right to do the expansion.
-
-      PerRegionTable** ptables = NEW_C_HEAP_ARRAY(PerRegionTable*, n);
-      for (int i = 0; i < n; i++) {
-        PerRegionTable* ptable = PerRegionTable::alloc(hr());
-        ptables[i] = ptable;
-      }
-      // Here we do not need an atomic.
-      _par_tables = ptables;
-#if COUNT_PAR_EXPANDS
-      print_par_expand();
-#endif
-      // We must put this table on the expanded list.
-      PosParPRT* exp_head = _par_expanded_list;
-      while (true) {
-        set_next_par_expanded(exp_head);
-        PosParPRT* res =
-          (PosParPRT*)
-          Atomic::cmpxchg_ptr(this, &_par_expanded_list, exp_head);
-        if (res == exp_head) return;
-        // Otherwise.
-        exp_head = res;
-      }
-      ShouldNotReachHere();
-    }
+  void set_collision_list_next(PerRegionTable* next) {
+    _collision_list_next = next;
   }
 
-  void add_reference(OopOrNarrowOopStar from, int tid) {
-    // Expand if necessary.
-    PerRegionTable** pt = par_tables();
-    if (pt != NULL) {
-      // We always have to assume that mods to table 0 are in parallel,
-      // because of the claiming scheme in parallel expansion.  A thread
-      // with tid != 0 that finds the table to be NULL, but doesn't succeed
-      // in claiming the right of expanding it, will end up in the else
-      // clause of the above if test.  That thread could be delayed, and a
-      // thread 0 add reference could see the table expanded, and come
-      // here.  Both threads would be adding in parallel.  But we get to
-      // not use atomics for tids > 0.
-      if (tid == 0) {
-        PerRegionTable::add_reference(from);
-      } else {
-        pt[tid-1]->seq_add_reference(from);
-      }
-    } else {
-      // Not expanded -- add to the base table.
-      PerRegionTable::add_reference(from);
-    }
-  }
-
-  void scrub(CardTableModRefBS* ctbs, BitMap* card_bm) {
-    assert(_par_tables == NULL, "Precondition");
-    PerRegionTable::scrub(ctbs, card_bm);
-  }
-
-  size_t mem_size() const {
-    size_t res =
-      PerRegionTable::mem_size() + sizeof(this) - sizeof(PerRegionTable);
-    if (_par_tables != NULL) {
-      for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets()-1; i++) {
-        res += _par_tables[i]->mem_size();
-      }
-    }
-    return res;
+  PerRegionTable** collision_list_next_addr() {
+    return &_collision_list_next;
   }
 
   static size_t fl_mem_size() {
-    PosParPRT* cur = _free_list;
+    PerRegionTable* cur = _free_list;
     size_t res = 0;
     while (cur != NULL) {
-      res += sizeof(PosParPRT);
+      res += sizeof(PerRegionTable);
       cur = cur->next();
     }
     return res;
   }
-
-  bool contains_reference(OopOrNarrowOopStar from) const {
-    if (PerRegionTable::contains_reference(from)) return true;
-    if (_par_tables != NULL) {
-      for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets()-1; i++) {
-        if (_par_tables[i]->contains_reference(from)) return true;
-      }
-    }
-    return false;
-  }
-
-  static void par_contract_all();
 };
 
-void PosParPRT::par_contract_all() {
-  PosParPRT* hd = _par_expanded_list;
-  while (hd != NULL) {
-    PosParPRT* nxt = hd->next_par_expanded();
-    PosParPRT* res =
-      (PosParPRT*)
-      Atomic::cmpxchg_ptr(nxt, &_par_expanded_list, hd);
-    if (res == hd) {
-      // We claimed the right to contract this table.
-      hd->set_next_par_expanded(NULL);
-      hd->par_contract();
-      hd = _par_expanded_list;
-    } else {
-      hd = res;
-    }
-  }
-}
-
-PosParPRT* PosParPRT::_free_list = NULL;
-PosParPRT* PosParPRT::_par_expanded_list = NULL;
-
-jint OtherRegionsTable::_cache_probes = 0;
-jint OtherRegionsTable::_cache_hits = 0;
+PerRegionTable* PerRegionTable::_free_list = NULL;
 
 size_t OtherRegionsTable::_max_fine_entries = 0;
 size_t OtherRegionsTable::_mod_max_fine_entries_mask = 0;
-#if SAMPLE_FOR_EVICTION
 size_t OtherRegionsTable::_fine_eviction_stride = 0;
 size_t OtherRegionsTable::_fine_eviction_sample_size = 0;
-#endif
 
 OtherRegionsTable::OtherRegionsTable(HeapRegion* hr) :
   _g1h(G1CollectedHeap::heap()),
@@ -510,35 +263,98 @@
   _coarse_map(G1CollectedHeap::heap()->max_regions(),
               false /* in-resource-area */),
   _fine_grain_regions(NULL),
+  _first_all_fine_prts(NULL), _last_all_fine_prts(NULL),
   _n_fine_entries(0), _n_coarse_entries(0),
-#if SAMPLE_FOR_EVICTION
   _fine_eviction_start(0),
-#endif
   _sparse_table(hr)
 {
-  typedef PosParPRT* PosParPRTPtr;
+  typedef PerRegionTable* PerRegionTablePtr;
+
   if (_max_fine_entries == 0) {
     assert(_mod_max_fine_entries_mask == 0, "Both or none.");
     size_t max_entries_log = (size_t)log2_long((jlong)G1RSetRegionEntries);
-    _max_fine_entries = (size_t)(1 << max_entries_log);
+    _max_fine_entries = (size_t)1 << max_entries_log;
     _mod_max_fine_entries_mask = _max_fine_entries - 1;
-#if SAMPLE_FOR_EVICTION
+
     assert(_fine_eviction_sample_size == 0
            && _fine_eviction_stride == 0, "All init at same time.");
     _fine_eviction_sample_size = MAX2((size_t)4, max_entries_log);
     _fine_eviction_stride = _max_fine_entries / _fine_eviction_sample_size;
-#endif
   }
-  _fine_grain_regions = new PosParPRTPtr[_max_fine_entries];
-  if (_fine_grain_regions == NULL)
+
+  _fine_grain_regions = new PerRegionTablePtr[_max_fine_entries];
+
+  if (_fine_grain_regions == NULL) {
     vm_exit_out_of_memory(sizeof(void*)*_max_fine_entries,
                           "Failed to allocate _fine_grain_entries.");
+  }
+
   for (size_t i = 0; i < _max_fine_entries; i++) {
     _fine_grain_regions[i] = NULL;
   }
 }
 
-int** OtherRegionsTable::_from_card_cache = NULL;
+void OtherRegionsTable::link_to_all(PerRegionTable* prt) {
+  // We always append to the beginning of the list for convenience;
+  // the order of entries in this list does not matter.
+  if (_first_all_fine_prts != NULL) {
+    assert(_first_all_fine_prts->prev() == NULL, "invariant");
+    _first_all_fine_prts->set_prev(prt);
+    prt->set_next(_first_all_fine_prts);
+  } else {
+    // this is the first element we insert. Adjust the "last" pointer
+    _last_all_fine_prts = prt;
+    assert(prt->next() == NULL, "just checking");
+  }
+  // the new element is always the first element without a predecessor
+  prt->set_prev(NULL);
+  _first_all_fine_prts = prt;
+
+  assert(prt->prev() == NULL, "just checking");
+  assert(_first_all_fine_prts == prt, "just checking");
+  assert((_first_all_fine_prts == NULL && _last_all_fine_prts == NULL) ||
+         (_first_all_fine_prts != NULL && _last_all_fine_prts != NULL),
+         "just checking");
+  assert(_last_all_fine_prts == NULL || _last_all_fine_prts->next() == NULL,
+         "just checking");
+  assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
+         "just checking");
+}
+
+void OtherRegionsTable::unlink_from_all(PerRegionTable* prt) {
+  if (prt->prev() != NULL) {
+    assert(_first_all_fine_prts != prt, "just checking");
+    prt->prev()->set_next(prt->next());
+    // removing the last element in the list?
+    if (_last_all_fine_prts == prt) {
+      _last_all_fine_prts = prt->prev();
+    }
+  } else {
+    assert(_first_all_fine_prts == prt, "just checking");
+    _first_all_fine_prts = prt->next();
+    // list is empty now?
+    if (_first_all_fine_prts == NULL) {
+      _last_all_fine_prts = NULL;
+    }
+  }
+
+  if (prt->next() != NULL) {
+    prt->next()->set_prev(prt->prev());
+  }
+
+  prt->set_next(NULL);
+  prt->set_prev(NULL);
+
+  assert((_first_all_fine_prts == NULL && _last_all_fine_prts == NULL) ||
+         (_first_all_fine_prts != NULL && _last_all_fine_prts != NULL),
+         "just checking");
+  assert(_last_all_fine_prts == NULL || _last_all_fine_prts->next() == NULL,
+         "just checking");
+  assert(_first_all_fine_prts == NULL || _first_all_fine_prts->prev() == NULL,
+         "just checking");
+}
+
+int**  OtherRegionsTable::_from_card_cache = NULL;
 size_t OtherRegionsTable::_from_card_cache_max_regions = 0;
 size_t OtherRegionsTable::_from_card_cache_mem_size = 0;
 
@@ -546,9 +362,9 @@
   _from_card_cache_max_regions = max_regions;
 
   int n_par_rs = HeapRegionRemSet::num_par_rem_sets();
-  _from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs);
+  _from_card_cache = NEW_C_HEAP_ARRAY(int*, n_par_rs, mtGC);
   for (int i = 0; i < n_par_rs; i++) {
-    _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, max_regions);
+    _from_card_cache[i] = NEW_C_HEAP_ARRAY(int, max_regions, mtGC);
     for (size_t j = 0; j < max_regions; j++) {
       _from_card_cache[i][j] = -1;  // An invalid value.
     }
@@ -577,40 +393,28 @@
 #endif
 
 void OtherRegionsTable::add_reference(OopOrNarrowOopStar from, int tid) {
-  size_t cur_hrs_ind = hr()->hrs_index();
+  size_t cur_hrs_ind = (size_t) hr()->hrs_index();
 
-#if HRRS_VERBOSE
-  gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
-                                                  from,
-                                                  UseCompressedOops
-                                                  ? oopDesc::load_decode_heap_oop((narrowOop*)from)
-                                                  : oopDesc::load_decode_heap_oop((oop*)from));
-#endif
+  if (G1TraceHeapRegionRememberedSet) {
+    gclog_or_tty->print_cr("ORT::add_reference_work(" PTR_FORMAT "->" PTR_FORMAT ").",
+                                                    from,
+                                                    UseCompressedOops
+                                                    ? oopDesc::load_decode_heap_oop((narrowOop*)from)
+                                                    : oopDesc::load_decode_heap_oop((oop*)from));
+  }
 
   int from_card = (int)(uintptr_t(from) >> CardTableModRefBS::card_shift);
 
-#if HRRS_VERBOSE
-  gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)",
-                hr()->bottom(), from_card,
-                _from_card_cache[tid][cur_hrs_ind]);
-#endif
-
-#define COUNT_CACHE 0
-#if COUNT_CACHE
-  jint p = Atomic::add(1, &_cache_probes);
-  if ((p % 10000) == 0) {
-    jint hits = _cache_hits;
-    gclog_or_tty->print_cr("%d/%d = %5.2f%% RS cache hits.",
-                  _cache_hits, p, 100.0* (float)hits/(float)p);
+  if (G1TraceHeapRegionRememberedSet) {
+    gclog_or_tty->print_cr("Table for [" PTR_FORMAT "...): card %d (cache = %d)",
+                  hr()->bottom(), from_card,
+                  _from_card_cache[tid][cur_hrs_ind]);
   }
-#endif
+
   if (from_card == _from_card_cache[tid][cur_hrs_ind]) {
-#if HRRS_VERBOSE
-    gclog_or_tty->print_cr("  from-card cache hit.");
-#endif
-#if COUNT_CACHE
-    Atomic::inc(&_cache_hits);
-#endif
+    if (G1TraceHeapRegionRememberedSet) {
+      gclog_or_tty->print_cr("  from-card cache hit.");
+    }
     assert(contains_reference(from), "We just added it!");
     return;
   } else {
@@ -623,16 +427,16 @@
 
   // If the region is already coarsened, return.
   if (_coarse_map.at(from_hrs_ind)) {
-#if HRRS_VERBOSE
-    gclog_or_tty->print_cr("  coarse map hit.");
-#endif
+    if (G1TraceHeapRegionRememberedSet) {
+      gclog_or_tty->print_cr("  coarse map hit.");
+    }
     assert(contains_reference(from), "We just added it!");
     return;
   }
 
   // Otherwise find a per-region table to add it to.
   size_t ind = from_hrs_ind & _mod_max_fine_entries_mask;
-  PosParPRT* prt = find_region_table(ind, from_hr);
+  PerRegionTable* prt = find_region_table(ind, from_hr);
   if (prt == NULL) {
     MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
     // Confirm that it's really not there...
@@ -649,36 +453,39 @@
           _sparse_table.add_card(from_hrs_ind, card_index)) {
         if (G1RecordHRRSOops) {
           HeapRegionRemSet::record(hr(), from);
-#if HRRS_VERBOSE
-          gclog_or_tty->print("   Added card " PTR_FORMAT " to region "
-                              "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
-                              align_size_down(uintptr_t(from),
-                                              CardTableModRefBS::card_size),
-                              hr()->bottom(), from);
-#endif
+          if (G1TraceHeapRegionRememberedSet) {
+            gclog_or_tty->print("   Added card " PTR_FORMAT " to region "
+                                "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
+                                align_size_down(uintptr_t(from),
+                                                CardTableModRefBS::card_size),
+                                hr()->bottom(), from);
+          }
         }
-#if HRRS_VERBOSE
-        gclog_or_tty->print_cr("   added card to sparse table.");
-#endif
+        if (G1TraceHeapRegionRememberedSet) {
+          gclog_or_tty->print_cr("   added card to sparse table.");
+        }
         assert(contains_reference_locked(from), "We just added it!");
         return;
       } else {
-#if HRRS_VERBOSE
-        gclog_or_tty->print_cr("   [tid %d] sparse table entry "
-                      "overflow(f: %d, t: %d)",
-                      tid, from_hrs_ind, cur_hrs_ind);
-#endif
+        if (G1TraceHeapRegionRememberedSet) {
+          gclog_or_tty->print_cr("   [tid %d] sparse table entry "
+                        "overflow(f: %d, t: %d)",
+                        tid, from_hrs_ind, cur_hrs_ind);
+        }
       }
 
       if (_n_fine_entries == _max_fine_entries) {
         prt = delete_region_table();
+        // There is no need to clear the links to the 'all' list here:
+        // prt will be reused immediately, i.e. remain in the 'all' list.
+        prt->init(from_hr, false /* clear_links_to_all_list */);
       } else {
-        prt = PosParPRT::alloc(from_hr);
+        prt = PerRegionTable::alloc(from_hr);
+        link_to_all(prt);
       }
-      prt->init(from_hr);
 
-      PosParPRT* first_prt = _fine_grain_regions[ind];
-      prt->set_next(first_prt);  // XXX Maybe move to init?
+      PerRegionTable* first_prt = _fine_grain_regions[ind];
+      prt->set_collision_list_next(first_prt);
       _fine_grain_regions[ind] = prt;
       _n_fine_entries++;
 
@@ -704,71 +511,42 @@
   // OtherRegionsTable for why this is OK.
   assert(prt != NULL, "Inv");
 
-  if (prt->should_expand(tid)) {
-    MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
-    HeapRegion* prt_hr = prt->hr();
-    if (prt_hr == from_hr) {
-      // Make sure the table still corresponds to the same region
-      prt->par_expand();
-      prt->add_reference(from, tid);
-    }
-    // else: The table has been concurrently coarsened, evicted, and
-    // the table data structure re-used for another table. So, we
-    // don't need to add the reference any more given that the table
-    // has been coarsened and the whole region will be scanned anyway.
-  } else {
-    prt->add_reference(from, tid);
-  }
+  prt->add_reference(from);
+
   if (G1RecordHRRSOops) {
     HeapRegionRemSet::record(hr(), from);
-#if HRRS_VERBOSE
-    gclog_or_tty->print("Added card " PTR_FORMAT " to region "
-                        "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
-                        align_size_down(uintptr_t(from),
-                                        CardTableModRefBS::card_size),
-                        hr()->bottom(), from);
-#endif
+    if (G1TraceHeapRegionRememberedSet) {
+      gclog_or_tty->print("Added card " PTR_FORMAT " to region "
+                          "[" PTR_FORMAT "...) for ref " PTR_FORMAT ".\n",
+                          align_size_down(uintptr_t(from),
+                                          CardTableModRefBS::card_size),
+                          hr()->bottom(), from);
+    }
   }
   assert(contains_reference(from), "We just added it!");
 }
 
-PosParPRT*
+PerRegionTable*
 OtherRegionsTable::find_region_table(size_t ind, HeapRegion* hr) const {
   assert(0 <= ind && ind < _max_fine_entries, "Preconditions.");
-  PosParPRT* prt = _fine_grain_regions[ind];
+  PerRegionTable* prt = _fine_grain_regions[ind];
   while (prt != NULL && prt->hr() != hr) {
-    prt = prt->next();
+    prt = prt->collision_list_next();
   }
   // Loop postcondition is the method postcondition.
   return prt;
 }
 
-
-#define DRT_CENSUS 0
-
-#if DRT_CENSUS
-static const int HistoSize = 6;
-static int global_histo[HistoSize] = { 0, 0, 0, 0, 0, 0 };
-static int coarsenings = 0;
-static int occ_sum = 0;
-#endif
-
 jint OtherRegionsTable::_n_coarsenings = 0;
 
-PosParPRT* OtherRegionsTable::delete_region_table() {
-#if DRT_CENSUS
-  int histo[HistoSize] = { 0, 0, 0, 0, 0, 0 };
-  const int histo_limits[] = { 1, 4, 16, 64, 256, 2048 };
-#endif
-
+PerRegionTable* OtherRegionsTable::delete_region_table() {
   assert(_m.owned_by_self(), "Precondition");
   assert(_n_fine_entries == _max_fine_entries, "Precondition");
-  PosParPRT* max = NULL;
+  PerRegionTable* max = NULL;
   jint max_occ = 0;
-  PosParPRT** max_prev;
+  PerRegionTable** max_prev;
   size_t max_ind;
 
-#if SAMPLE_FOR_EVICTION
   size_t i = _fine_eviction_start;
   for (size_t k = 0; k < _fine_eviction_sample_size; k++) {
     size_t ii = i;
@@ -778,8 +556,8 @@
       if (ii == _max_fine_entries) ii = 0;
       guarantee(ii != i, "We must find one.");
     }
-    PosParPRT** prev = &_fine_grain_regions[ii];
-    PosParPRT* cur = *prev;
+    PerRegionTable** prev = &_fine_grain_regions[ii];
+    PerRegionTable* cur = *prev;
     while (cur != NULL) {
       jint cur_occ = cur->occupied();
       if (max == NULL || cur_occ > max_occ) {
@@ -788,74 +566,37 @@
         max_ind = i;
         max_occ = cur_occ;
       }
-      prev = cur->next_addr();
-      cur = cur->next();
+      prev = cur->collision_list_next_addr();
+      cur = cur->collision_list_next();
     }
     i = i + _fine_eviction_stride;
     if (i >= _n_fine_entries) i = i - _n_fine_entries;
   }
+
   _fine_eviction_start++;
-  if (_fine_eviction_start >= _n_fine_entries)
+
+  if (_fine_eviction_start >= _n_fine_entries) {
     _fine_eviction_start -= _n_fine_entries;
-#else
-  for (int i = 0; i < _max_fine_entries; i++) {
-    PosParPRT** prev = &_fine_grain_regions[i];
-    PosParPRT* cur = *prev;
-    while (cur != NULL) {
-      jint cur_occ = cur->occupied();
-#if DRT_CENSUS
-      for (int k = 0; k < HistoSize; k++) {
-        if (cur_occ <= histo_limits[k]) {
-          histo[k]++; global_histo[k]++; break;
-        }
-      }
-#endif
-      if (max == NULL || cur_occ > max_occ) {
-        max = cur;
-        max_prev = prev;
-        max_ind = i;
-        max_occ = cur_occ;
-      }
-      prev = cur->next_addr();
-      cur = cur->next();
-    }
   }
-#endif
-  // XXX
+
   guarantee(max != NULL, "Since _n_fine_entries > 0");
-#if DRT_CENSUS
-  gclog_or_tty->print_cr("In a coarsening: histo of occs:");
-  for (int k = 0; k < HistoSize; k++) {
-    gclog_or_tty->print_cr("  <= %4d: %5d.", histo_limits[k], histo[k]);
-  }
-  coarsenings++;
-  occ_sum += max_occ;
-  if ((coarsenings % 100) == 0) {
-    gclog_or_tty->print_cr("\ncoarsenings = %d; global summary:", coarsenings);
-    for (int k = 0; k < HistoSize; k++) {
-      gclog_or_tty->print_cr("  <= %4d: %5d.", histo_limits[k], global_histo[k]);
-    }
-    gclog_or_tty->print_cr("Avg occ of deleted region = %6.2f.",
-                  (float)occ_sum/(float)coarsenings);
-  }
-#endif
 
   // Set the corresponding coarse bit.
-  size_t max_hrs_index = max->hr()->hrs_index();
+  size_t max_hrs_index = (size_t) max->hr()->hrs_index();
   if (!_coarse_map.at(max_hrs_index)) {
     _coarse_map.at_put(max_hrs_index, true);
     _n_coarse_entries++;
-#if 0
-    gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
-               "for region [" PTR_FORMAT "...] (%d coarse entries).\n",
-               hr()->bottom(),
-               max->hr()->bottom(),
-               _n_coarse_entries);
-#endif
+    if (G1TraceHeapRegionRememberedSet) {
+      gclog_or_tty->print("Coarsened entry in region [" PTR_FORMAT "...] "
+                 "for region [" PTR_FORMAT "...] (%d coarse entries).\n",
+                 hr()->bottom(),
+                 max->hr()->bottom(),
+                 _n_coarse_entries);
+    }
   }
 
   // Unsplice.
-  *max_prev = max->next();
+  *max_prev = max->collision_list_next();
   Atomic::inc(&_n_coarsenings);
   _n_fine_entries--;
   return max;
@@ -866,50 +607,59 @@
 void OtherRegionsTable::scrub(CardTableModRefBS* ctbs,
                               BitMap* region_bm, BitMap* card_bm) {
   // First eliminated garbage regions from the coarse map.
-  if (G1RSScrubVerbose)
-    gclog_or_tty->print_cr("Scrubbing region "SIZE_FORMAT":",
-                           hr()->hrs_index());
+  if (G1RSScrubVerbose) {
+    gclog_or_tty->print_cr("Scrubbing region %u:", hr()->hrs_index());
+  }
 
   assert(_coarse_map.size() == region_bm->size(), "Precondition");
-  if (G1RSScrubVerbose)
-    gclog_or_tty->print("   Coarse map: before = %d...", _n_coarse_entries);
+  if (G1RSScrubVerbose) {
+    gclog_or_tty->print("   Coarse map: before = "SIZE_FORMAT"...",
+                        _n_coarse_entries);
+  }
   _coarse_map.set_intersection(*region_bm);
   _n_coarse_entries = _coarse_map.count_one_bits();
-  if (G1RSScrubVerbose)
-    gclog_or_tty->print_cr("   after = %d.", _n_coarse_entries);
+  if (G1RSScrubVerbose) {
+    gclog_or_tty->print_cr("   after = "SIZE_FORMAT".", _n_coarse_entries);
+  }
 
   // Now do the fine-grained maps.
   for (size_t i = 0; i < _max_fine_entries; i++) {
-    PosParPRT* cur = _fine_grain_regions[i];
-    PosParPRT** prev = &_fine_grain_regions[i];
+    PerRegionTable* cur = _fine_grain_regions[i];
+    PerRegionTable** prev = &_fine_grain_regions[i];
     while (cur != NULL) {
-      PosParPRT* nxt = cur->next();
+      PerRegionTable* nxt = cur->collision_list_next();
       // If the entire region is dead, eliminate.
-      if (G1RSScrubVerbose)
-        gclog_or_tty->print_cr("     For other region "SIZE_FORMAT":",
+      if (G1RSScrubVerbose) {
+        gclog_or_tty->print_cr("     For other region %u:",
                                cur->hr()->hrs_index());
-      if (!region_bm->at(cur->hr()->hrs_index())) {
+      }
+      if (!region_bm->at((size_t) cur->hr()->hrs_index())) {
         *prev = nxt;
-        cur->set_next(NULL);
+        cur->set_collision_list_next(NULL);
         _n_fine_entries--;
-        if (G1RSScrubVerbose)
+        if (G1RSScrubVerbose) {
           gclog_or_tty->print_cr("          deleted via region map.");
-        PosParPRT::free(cur);
+        }
+        unlink_from_all(cur);
+        PerRegionTable::free(cur);
       } else {
         // Do fine-grain elimination.
-        if (G1RSScrubVerbose)
+        if (G1RSScrubVerbose) {
           gclog_or_tty->print("          occ: before = %4d.", cur->occupied());
+        }
         cur->scrub(ctbs, card_bm);
-        if (G1RSScrubVerbose)
+        if (G1RSScrubVerbose) {
           gclog_or_tty->print_cr("          after = %4d.", cur->occupied());
+        }
         // Did that empty the table completely?
         if (cur->occupied() == 0) {
           *prev = nxt;
-          cur->set_next(NULL);
+          cur->set_collision_list_next(NULL);
           _n_fine_entries--;
-          PosParPRT::free(cur);
+          unlink_from_all(cur);
+          PerRegionTable::free(cur);
         } else {
-          prev = cur->next_addr();
+          prev = cur->collision_list_next_addr();
         }
       }
       cur = nxt;
@@ -932,13 +682,15 @@
 
 size_t OtherRegionsTable::occ_fine() const {
   size_t sum = 0;
-  for (size_t i = 0; i < _max_fine_entries; i++) {
-    PosParPRT* cur = _fine_grain_regions[i];
-    while (cur != NULL) {
-      sum += cur->occupied();
-      cur = cur->next();
-    }
+
+  size_t num = 0;
+  PerRegionTable * cur = _first_all_fine_prts;
+  while (cur != NULL) {
+    sum += cur->occupied();
+    cur = cur->next();
+    num++;
   }
+  guarantee(num == _n_fine_entries, "just checking");
   return sum;
 }
 
@@ -954,14 +706,12 @@
   // Cast away const in this case.
   MutexLockerEx x((Mutex*)&_m, Mutex::_no_safepoint_check_flag);
   size_t sum = 0;
-  for (size_t i = 0; i < _max_fine_entries; i++) {
-    PosParPRT* cur = _fine_grain_regions[i];
-    while (cur != NULL) {
-      sum += cur->mem_size();
-      cur = cur->next();
-    }
+  PerRegionTable * cur = _first_all_fine_prts;
+  while (cur != NULL) {
+    sum += cur->mem_size();
+    cur = cur->next();
   }
-  sum += (sizeof(PosParPRT*) * _max_fine_entries);
+  sum += (sizeof(PerRegionTable*) * _max_fine_entries);
   sum += (_coarse_map.size_in_words() * HeapWordSize);
   sum += (_sparse_table.mem_size());
   sum += sizeof(*this) - sizeof(_sparse_table); // Avoid double counting above.
@@ -973,26 +723,28 @@
 }
 
 size_t OtherRegionsTable::fl_mem_size() {
-  return PerRegionTable::fl_mem_size() + PosParPRT::fl_mem_size();
+  return PerRegionTable::fl_mem_size();
 }
 
 void OtherRegionsTable::clear_fcc() {
+  size_t hrs_idx = hr()->hrs_index();
   for (int i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) {
-    _from_card_cache[i][hr()->hrs_index()] = -1;
+    _from_card_cache[i][hrs_idx] = -1;
   }
 }
 
 void OtherRegionsTable::clear() {
   MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
-  for (size_t i = 0; i < _max_fine_entries; i++) {
-    PosParPRT* cur = _fine_grain_regions[i];
-    while (cur != NULL) {
-      PosParPRT* nxt = cur->next();
-      PosParPRT::free(cur);
-      cur = nxt;
-    }
-    _fine_grain_regions[i] = NULL;
+  // if there are no entries, skip this step
+  if (_first_all_fine_prts != NULL) {
+    guarantee(_first_all_fine_prts != NULL && _last_all_fine_prts != NULL, "just checking");
+    PerRegionTable::bulk_free(_first_all_fine_prts, _last_all_fine_prts);
+    memset(_fine_grain_regions, 0, _max_fine_entries * sizeof(_fine_grain_regions[0]));
+  } else {
+    guarantee(_first_all_fine_prts == NULL && _last_all_fine_prts == NULL, "just checking");
   }
+
+  _first_all_fine_prts = _last_all_fine_prts = NULL;
   _sparse_table.clear();
   _coarse_map.clear();
   _n_fine_entries = 0;
@@ -1003,7 +755,7 @@
 
 void OtherRegionsTable::clear_incoming_entry(HeapRegion* from_hr) {
   MutexLockerEx x(&_m, Mutex::_no_safepoint_check_flag);
-  size_t hrs_ind = from_hr->hrs_index();
+  size_t hrs_ind = (size_t) from_hr->hrs_index();
   size_t ind = hrs_ind & _mod_max_fine_entries_mask;
   if (del_single_region_table(ind, from_hr)) {
     assert(!_coarse_map.at(hrs_ind), "Inv");
@@ -1011,7 +763,7 @@
     _coarse_map.par_at_put(hrs_ind, 0);
   }
   // Check to see if any of the fcc entries come from here.
-  size_t hr_ind = hr()->hrs_index();
+  size_t hr_ind = (size_t) hr()->hrs_index();
   for (int tid = 0; tid < HeapRegionRemSet::num_par_rem_sets(); tid++) {
     int fcc_ent = _from_card_cache[tid][hr_ind];
     if (fcc_ent != -1) {
@@ -1028,16 +780,17 @@
 bool OtherRegionsTable::del_single_region_table(size_t ind,
                                                 HeapRegion* hr) {
   assert(0 <= ind && ind < _max_fine_entries, "Preconditions.");
-  PosParPRT** prev_addr = &_fine_grain_regions[ind];
-  PosParPRT* prt = *prev_addr;
+  PerRegionTable** prev_addr = &_fine_grain_regions[ind];
+  PerRegionTable* prt = *prev_addr;
   while (prt != NULL && prt->hr() != hr) {
-    prev_addr = prt->next_addr();
-    prt = prt->next();
+    prev_addr = prt->collision_list_next_addr();
+    prt = prt->collision_list_next();
   }
   if (prt != NULL) {
     assert(prt->hr() == hr, "Loop postcondition.");
-    *prev_addr = prt->next();
-    PosParPRT::free(prt);
+    *prev_addr = prt->collision_list_next();
+    unlink_from_all(prt);
+    PerRegionTable::free(prt);
     _n_fine_entries--;
     return true;
   } else {
@@ -1058,7 +811,7 @@
   // Is this region in the coarse map?
   if (_coarse_map.at(hr_ind)) return true;
 
-  PosParPRT* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask,
+  PerRegionTable* prt = find_region_table(hr_ind & _mod_max_fine_entries_mask,
                                      hr);
   if (prt != NULL) {
     return prt->contains_reference(from);
@@ -1099,7 +852,8 @@
 void HeapRegionRemSet::setup_remset_size() {
   // Setup sparse and fine-grain tables sizes.
   // table_size = base * (log(region_size / 1M) + 1)
-  int region_size_log_mb = MAX2((int)HeapRegion::LogOfHRGrainBytes - (int)LOG_M, 0);
+  const int LOG_M = 20;
+  int region_size_log_mb = MAX2(HeapRegion::LogOfHRGrainBytes - LOG_M, 0);
   if (FLAG_IS_DEFAULT(G1RSetSparseRegionEntries)) {
     G1RSetSparseRegionEntries = G1RSetSparseRegionEntriesBase * (region_size_log_mb + 1);
   }
@@ -1137,7 +891,6 @@
       G1CollectedHeap::heap()->bot_shared()->address_for_index(card_index);
     gclog_or_tty->print_cr("  Card " PTR_FORMAT, card_start);
   }
-  // XXX
   if (iter.n_yielded() != occupied()) {
     gclog_or_tty->print_cr("Yielded disagrees with occupied:");
     gclog_or_tty->print_cr("  %6d yielded (%6d coarse, %6d fine).",
@@ -1155,10 +908,6 @@
   SparsePRT::cleanup_all();
 }
 
-void HeapRegionRemSet::par_cleanup() {
-  PosParPRT::par_contract_all();
-}
-
 void HeapRegionRemSet::clear() {
   _other_regions.clear();
   assert(occupied() == 0, "Should be clear.");
@@ -1223,7 +972,7 @@
     if ((size_t)_coarse_cur_region_index < _coarse_map->size()) {
       _coarse_cur_region_cur_card = 0;
       HeapWord* r_bot =
-        _g1h->region_at(_coarse_cur_region_index)->bottom();
+        _g1h->region_at((uint) _coarse_cur_region_index)->bottom();
       _cur_region_card_offset = _bosa->index_for(r_bot);
     } else {
       return false;
@@ -1253,7 +1002,7 @@
   while (!fine_has_next()) {
     if (_cur_region_cur_card == (size_t) HeapRegion::CardsPerRegion) {
       _cur_region_cur_card = 0;
-      _fine_cur_prt = _fine_cur_prt->next();
+      _fine_cur_prt = _fine_cur_prt->collision_list_next();
     }
     if (_fine_cur_prt == NULL) {
       fine_find_next_non_null_prt();
@@ -1325,9 +1074,9 @@
            && _recorded_cards == NULL
            && _recorded_regions == NULL,
            "Inv");
-    _recorded_oops    = NEW_C_HEAP_ARRAY(OopOrNarrowOopStar, MaxRecorded);
-    _recorded_cards   = NEW_C_HEAP_ARRAY(HeapWord*,          MaxRecorded);
-    _recorded_regions = NEW_C_HEAP_ARRAY(HeapRegion*,        MaxRecorded);
+    _recorded_oops    = NEW_C_HEAP_ARRAY(OopOrNarrowOopStar, MaxRecorded, mtGC);
+    _recorded_cards   = NEW_C_HEAP_ARRAY(HeapWord*,          MaxRecorded, mtGC);
+    _recorded_regions = NEW_C_HEAP_ARRAY(HeapRegion*,        MaxRecorded, mtGC);
   }
   if (_n_recorded == MaxRecorded) {
     gclog_or_tty->print_cr("Filled up 'recorded' (%d).", MaxRecorded);
@@ -1348,8 +1097,8 @@
     assert(_n_recorded_events == 0
            && _recorded_event_index == NULL,
            "Inv");
-    _recorded_events = NEW_C_HEAP_ARRAY(Event, MaxRecordedEvents);
-    _recorded_event_index = NEW_C_HEAP_ARRAY(int, MaxRecordedEvents);
+    _recorded_events = NEW_C_HEAP_ARRAY(Event, MaxRecordedEvents, mtGC);
+    _recorded_event_index = NEW_C_HEAP_ARRAY(int, MaxRecordedEvents, mtGC);
   }
   if (_n_recorded_events == MaxRecordedEvents) {
     gclog_or_tty->print_cr("Filled up 'recorded_events' (%d).", MaxRecordedEvents);
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
index 4534350..1b1d42d 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionRemSet.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -35,7 +35,7 @@
 class G1BlockOffsetSharedArray;
 class HeapRegion;
 class HeapRegionRemSetIterator;
-class PosParPRT;
+class PerRegionTable;
 class SparsePRT;
 
 // Essentially a wrapper around SparsePRTCleanupTask. See
@@ -79,15 +79,22 @@
   size_t      _n_coarse_entries;
   static jint _n_coarsenings;
 
-  PosParPRT** _fine_grain_regions;
-  size_t      _n_fine_entries;
+  PerRegionTable** _fine_grain_regions;
+  size_t           _n_fine_entries;
 
-#define SAMPLE_FOR_EVICTION 1
-#if SAMPLE_FOR_EVICTION
+  // The fine grain remembered sets are doubly linked together using
+  // their 'next' and 'prev' fields.
+  // This allows fast bulk freeing of all the fine grain remembered
+  // set entries, and fast finding of all of them without iterating
+  // over the _fine_grain_regions table.
+  PerRegionTable * _first_all_fine_prts;
+  PerRegionTable * _last_all_fine_prts;
+
+  // Used to sample a subset of the fine grain PRTs to determine which
+  // PRT to evict and coarsen.
   size_t        _fine_eviction_start;
   static size_t _fine_eviction_stride;
   static size_t _fine_eviction_sample_size;
-#endif
 
   SparsePRT   _sparse_table;
 
@@ -98,26 +105,28 @@
   // Requires "prt" to be the first element of the bucket list appropriate
   // for "hr".  If this list contains an entry for "hr", return it,
   // otherwise return "NULL".
-  PosParPRT* find_region_table(size_t ind, HeapRegion* hr) const;
+  PerRegionTable* find_region_table(size_t ind, HeapRegion* hr) const;
 
-  // Find, delete, and return a candidate PosParPRT, if any exists,
+  // Find, delete, and return a candidate PerRegionTable, if any exists,
   // adding the deleted region to the coarse bitmap.  Requires the caller
   // to hold _m, and the fine-grain table to be full.
-  PosParPRT* delete_region_table();
+  PerRegionTable* delete_region_table();
 
   // If a PRT for "hr" is in the bucket list indicated by "ind" (which must
   // be the correct index for "hr"), delete it and return true; else return
   // false.
   bool del_single_region_table(size_t ind, HeapRegion* hr);
 
-  static jint _cache_probes;
-  static jint _cache_hits;
-
   // Indexed by thread X heap region, to minimize thread contention.
   static int** _from_card_cache;
   static size_t _from_card_cache_max_regions;
   static size_t _from_card_cache_mem_size;
 
+  // link/add the given fine grain remembered set into the "all" list
+  void link_to_all(PerRegionTable * prt);
+  // unlink/remove the given fine grain remembered set into the "all" list
+  void unlink_from_all(PerRegionTable * prt);
+
 public:
   OtherRegionsTable(HeapRegion* hr);
 
@@ -127,10 +136,6 @@
   // sense.
   void add_reference(OopOrNarrowOopStar from, int tid);
 
-  void add_reference(OopOrNarrowOopStar from) {
-    return add_reference(from, 0);
-  }
-
   // Removes any entries shown by the given bitmaps to contain only dead
   // objects.
   void scrub(CardTableModRefBS* ctbs, BitMap* region_bm, BitMap* card_bm);
@@ -173,7 +178,7 @@
   static void print_from_card_cache();
 };
 
-class HeapRegionRemSet : public CHeapObj {
+class HeapRegionRemSet : public CHeapObj<mtGC> {
   friend class VMStructs;
   friend class HeapRegionRemSetIterator;
 
@@ -233,14 +238,12 @@
 
   static jint n_coarsenings() { return OtherRegionsTable::n_coarsenings(); }
 
-  /* Used in the sequential case.  Returns "true" iff this addition causes
-     the size limit to be reached. */
+  // Used in the sequential case.
   void add_reference(OopOrNarrowOopStar from) {
-    _other_regions.add_reference(from);
+    _other_regions.add_reference(from, 0);
   }
 
-  /* Used in the parallel case.  Returns "true" iff this addition causes
-     the size limit to be reached. */
+  // Used in the parallel case.
   void add_reference(OopOrNarrowOopStar from, int tid) {
     _other_regions.add_reference(from, tid);
   }
@@ -253,15 +256,6 @@
   // entries for this region in other remsets.
   void clear();
 
-  // Forget any entries due to pointers from "from_hr".
-  void clear_incoming_entry(HeapRegion* from_hr) {
-    _other_regions.clear_incoming_entry(from_hr);
-  }
-
-#if 0
-  virtual void cleanup() = 0;
-#endif
-
   // Attempt to claim the region.  Returns true iff this call caused an
   // atomic transition from Unclaimed to Claimed.
   bool claim_iter();
@@ -290,12 +284,6 @@
   // Initialize the given iterator to iterate over this rem set.
   void init_iterator(HeapRegionRemSetIterator* iter) const;
 
-#if 0
-  // Apply the "do_card" method to the start address of every card in the
-  // rem set.  Returns false if some application of the closure aborted.
-  virtual bool card_iterate(CardClosure* iter) = 0;
-#endif
-
   // The actual # of bytes this hr_remset takes up.
   size_t mem_size() {
     return _other_regions.mem_size()
@@ -322,20 +310,17 @@
   void print() const;
 
   // Called during a stop-world phase to perform any deferred cleanups.
-  // The second version may be called by parallel threads after then finish
-  // collection work.
   static void cleanup();
-  static void par_cleanup();
 
   // Declare the heap size (in # of regions) to the HeapRegionRemSet(s).
   // (Uses it to initialize from_card_cache).
-  static void init_heap(size_t max_regions) {
-    OtherRegionsTable::init_from_card_cache(max_regions);
+  static void init_heap(uint max_regions) {
+    OtherRegionsTable::init_from_card_cache((size_t) max_regions);
   }
 
   // Declares that only regions i s.t. 0 <= i < new_n_regs are in use.
-  static void shrink_heap(size_t new_n_regs) {
-    OtherRegionsTable::shrink_from_card_cache(new_n_regs);
+  static void shrink_heap(uint new_n_regs) {
+    OtherRegionsTable::shrink_from_card_cache((size_t) new_n_regs);
   }
 
 #ifndef PRODUCT
@@ -360,14 +345,14 @@
 #endif
 };
 
-class HeapRegionRemSetIterator : public CHeapObj {
+class HeapRegionRemSetIterator : public CHeapObj<mtGC> {
 
   // The region over which we're iterating.
   const HeapRegionRemSet* _hrrs;
 
   // Local caching of HRRS fields.
   const BitMap*             _coarse_map;
-  PosParPRT**               _fine_grain_regions;
+  PerRegionTable**          _fine_grain_regions;
 
   G1BlockOffsetSharedArray* _bosa;
   G1CollectedHeap*          _g1h;
@@ -404,8 +389,9 @@
 
   // Index of bucket-list we're working on.
   int _fine_array_index;
+
   // Per Region Table we're doing within current bucket list.
-  PosParPRT* _fine_cur_prt;
+  PerRegionTable* _fine_cur_prt;
 
   /* SparsePRT::*/ SparsePRTIter _sparse_iter;
 
@@ -435,12 +421,4 @@
   }
 };
 
-#if 0
-class CardClosure: public Closure {
-public:
-  virtual void do_card(HeapWord* card_start) = 0;
-};
-
-#endif
-
 #endif // SHARE_VM_GC_IMPLEMENTATION_G1_HEAPREGIONREMSET_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp
index fecdca1..fcee7cb 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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,16 +31,15 @@
 
 // Private
 
-size_t HeapRegionSeq::find_contiguous_from(size_t from, size_t num) {
-  size_t len = length();
+uint HeapRegionSeq::find_contiguous_from(uint from, uint num) {
+  uint len = length();
   assert(num > 1, "use this only for sequences of length 2 or greater");
   assert(from <= len,
-         err_msg("from: "SIZE_FORMAT" should be valid and <= than "SIZE_FORMAT,
-                 from, len));
+         err_msg("from: %u should be valid and <= than %u", from, len));
 
-  size_t curr = from;
-  size_t first = G1_NULL_HRS_INDEX;
-  size_t num_so_far = 0;
+  uint curr = from;
+  uint first = G1_NULL_HRS_INDEX;
+  uint num_so_far = 0;
   while (curr < len && num_so_far < num) {
     if (at(curr)->is_empty()) {
       if (first == G1_NULL_HRS_INDEX) {
@@ -60,7 +59,7 @@
     // we found enough space for the humongous object
     assert(from <= first && first < len, "post-condition");
     assert(first < curr && (curr - first) == num, "post-condition");
-    for (size_t i = first; i < first + num; ++i) {
+    for (uint i = first; i < first + num; ++i) {
       assert(at(i)->is_empty(), "post-condition");
     }
     return first;
@@ -73,10 +72,10 @@
 // Public
 
 void HeapRegionSeq::initialize(HeapWord* bottom, HeapWord* end,
-                               size_t max_length) {
-  assert((size_t) bottom % HeapRegion::GrainBytes == 0,
+                               uint max_length) {
+  assert((uintptr_t) bottom % HeapRegion::GrainBytes == 0,
          "bottom should be heap region aligned");
-  assert((size_t) end % HeapRegion::GrainBytes == 0,
+  assert((uintptr_t) end % HeapRegion::GrainBytes == 0,
          "end should be heap region aligned");
 
   _length = 0;
@@ -87,9 +86,9 @@
   _allocated_length = 0;
   _max_length = max_length;
 
-  _regions = NEW_C_HEAP_ARRAY(HeapRegion*, max_length);
-  memset(_regions, 0, max_length * sizeof(HeapRegion*));
-  _regions_biased = _regions - ((size_t) bottom >> _region_shift);
+  _regions = NEW_C_HEAP_ARRAY(HeapRegion*, max_length, mtGC);
+  memset(_regions, 0, (size_t) max_length * sizeof(HeapRegion*));
+  _regions_biased = _regions - ((uintx) bottom >> _region_shift);
 
   assert(&_regions[0] == &_regions_biased[addr_to_index_biased(bottom)],
          "bottom should be included in the region with index 0");
@@ -105,7 +104,7 @@
   assert(_heap_bottom <= next_bottom, "invariant");
   while (next_bottom < new_end) {
     assert(next_bottom < _heap_end, "invariant");
-    size_t index = length();
+    uint index = length();
 
     assert(index < _max_length, "otherwise we cannot expand further");
     if (index == 0) {
@@ -139,9 +138,9 @@
   return MemRegion(old_end, next_bottom);
 }
 
-size_t HeapRegionSeq::free_suffix() {
-  size_t res = 0;
-  size_t index = length();
+uint HeapRegionSeq::free_suffix() {
+  uint res = 0;
+  uint index = length();
   while (index > 0) {
     index -= 1;
     if (!at(index)->is_empty()) {
@@ -152,27 +151,24 @@
   return res;
 }
 
-size_t HeapRegionSeq::find_contiguous(size_t num) {
+uint HeapRegionSeq::find_contiguous(uint num) {
   assert(num > 1, "use this only for sequences of length 2 or greater");
   assert(_next_search_index <= length(),
-         err_msg("_next_search_indeex: "SIZE_FORMAT" "
-                 "should be valid and <= than "SIZE_FORMAT,
+         err_msg("_next_search_index: %u should be valid and <= than %u",
                  _next_search_index, length()));
 
-  size_t start = _next_search_index;
-  size_t res = find_contiguous_from(start, num);
+  uint start = _next_search_index;
+  uint res = find_contiguous_from(start, num);
   if (res == G1_NULL_HRS_INDEX && start > 0) {
     // Try starting from the beginning. If _next_search_index was 0,
     // no point in doing this again.
     res = find_contiguous_from(0, num);
   }
   if (res != G1_NULL_HRS_INDEX) {
-    assert(res < length(),
-           err_msg("res: "SIZE_FORMAT" should be valid", res));
+    assert(res < length(), err_msg("res: %u should be valid", res));
     _next_search_index = res + num;
     assert(_next_search_index <= length(),
-           err_msg("_next_search_indeex: "SIZE_FORMAT" "
-                   "should be valid and <= than "SIZE_FORMAT,
+           err_msg("_next_search_index: %u should be valid and <= than %u",
                    _next_search_index, length()));
   }
   return res;
@@ -183,20 +179,20 @@
 }
 
 void HeapRegionSeq::iterate_from(HeapRegion* hr, HeapRegionClosure* blk) const {
-  size_t hr_index = 0;
+  uint hr_index = 0;
   if (hr != NULL) {
-    hr_index = (size_t) hr->hrs_index();
+    hr_index = hr->hrs_index();
   }
 
-  size_t len = length();
-  for (size_t i = hr_index; i < len; i += 1) {
+  uint len = length();
+  for (uint i = hr_index; i < len; i += 1) {
     bool res = blk->doHeapRegion(at(i));
     if (res) {
       blk->incomplete();
       return;
     }
   }
-  for (size_t i = 0; i < hr_index; i += 1) {
+  for (uint i = 0; i < hr_index; i += 1) {
     bool res = blk->doHeapRegion(at(i));
     if (res) {
       blk->incomplete();
@@ -206,7 +202,7 @@
 }
 
 MemRegion HeapRegionSeq::shrink_by(size_t shrink_bytes,
-                                   size_t* num_regions_deleted) {
+                                   uint* num_regions_deleted) {
   // Reset this in case it's currently pointing into the regions that
   // we just removed.
   _next_search_index = 0;
@@ -218,7 +214,7 @@
   assert(_allocated_length > 0, "we should have at least one region committed");
 
   // around the loop, i will be the next region to be removed
-  size_t i = length() - 1;
+  uint i = length() - 1;
   assert(i > 0, "we should never remove all regions");
   // [last_start, end) is the MemRegion that covers the regions we will remove.
   HeapWord* end = at(i)->end();
@@ -249,29 +245,24 @@
 #ifndef PRODUCT
 void HeapRegionSeq::verify_optional() {
   guarantee(_length <= _allocated_length,
-            err_msg("invariant: _length: "SIZE_FORMAT" "
-                    "_allocated_length: "SIZE_FORMAT,
+            err_msg("invariant: _length: %u _allocated_length: %u",
                     _length, _allocated_length));
   guarantee(_allocated_length <= _max_length,
-            err_msg("invariant: _allocated_length: "SIZE_FORMAT" "
-                    "_max_length: "SIZE_FORMAT,
+            err_msg("invariant: _allocated_length: %u _max_length: %u",
                     _allocated_length, _max_length));
   guarantee(_next_search_index <= _length,
-            err_msg("invariant: _next_search_index: "SIZE_FORMAT" "
-                    "_length: "SIZE_FORMAT,
+            err_msg("invariant: _next_search_index: %u _length: %u",
                     _next_search_index, _length));
 
   HeapWord* prev_end = _heap_bottom;
-  for (size_t i = 0; i < _allocated_length; i += 1) {
+  for (uint i = 0; i < _allocated_length; i += 1) {
     HeapRegion* hr = _regions[i];
-    guarantee(hr != NULL, err_msg("invariant: i: "SIZE_FORMAT, i));
+    guarantee(hr != NULL, err_msg("invariant: i: %u", i));
     guarantee(hr->bottom() == prev_end,
-              err_msg("invariant i: "SIZE_FORMAT" "HR_FORMAT" "
-                      "prev_end: "PTR_FORMAT,
+              err_msg("invariant i: %u "HR_FORMAT" prev_end: "PTR_FORMAT,
                       i, HR_FORMAT_PARAMS(hr), prev_end));
     guarantee(hr->hrs_index() == i,
-              err_msg("invariant: i: "SIZE_FORMAT" hrs_index(): "SIZE_FORMAT,
-                      i, hr->hrs_index()));
+              err_msg("invariant: i: %u hrs_index(): %u", i, hr->hrs_index()));
     if (i < _length) {
       // Asserts will fire if i is >= _length
       HeapWord* addr = hr->bottom();
@@ -290,8 +281,8 @@
       prev_end = hr->end();
     }
   }
-  for (size_t i = _allocated_length; i < _max_length; i += 1) {
-    guarantee(_regions[i] == NULL, err_msg("invariant i: "SIZE_FORMAT, i));
+  for (uint i = _allocated_length; i < _max_length; i += 1) {
+    guarantee(_regions[i] == NULL, err_msg("invariant i: %u", i));
   }
 }
 #endif // PRODUCT
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp
index 3df8d73..b1da14f 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -29,8 +29,6 @@
 class HeapRegionClosure;
 class FreeRegionList;
 
-#define G1_NULL_HRS_INDEX ((size_t) -1)
-
 // This class keeps track of the region metadata (i.e., HeapRegion
 // instances). They are kept in the _regions array in address
 // order. A region's index in the array corresponds to its index in
@@ -55,7 +53,7 @@
 //
 // and maintain that: _length <= _allocated_length <= _max_length
 
-class HeapRegionSeq: public CHeapObj {
+class HeapRegionSeq: public CHeapObj<mtGC> {
   friend class VMStructs;
 
   // The array that holds the HeapRegions.
@@ -65,7 +63,7 @@
   HeapRegion** _regions_biased;
 
   // The number of regions committed in the heap.
-  size_t _length;
+  uint _length;
 
   // The address of the first reserved word in the heap.
   HeapWord* _heap_bottom;
@@ -74,32 +72,32 @@
   HeapWord* _heap_end;
 
   // The log of the region byte size.
-  size_t _region_shift;
+  uint _region_shift;
 
   // A hint for which index to start searching from for humongous
   // allocations.
-  size_t _next_search_index;
+  uint _next_search_index;
 
   // The number of regions for which we have allocated HeapRegions for.
-  size_t _allocated_length;
+  uint _allocated_length;
 
   // The maximum number of regions in the heap.
-  size_t _max_length;
+  uint _max_length;
 
   // Find a contiguous set of empty regions of length num, starting
   // from the given index.
-  size_t find_contiguous_from(size_t from, size_t num);
+  uint find_contiguous_from(uint from, uint num);
 
   // Map a heap address to a biased region index. Assume that the
   // address is valid.
-  inline size_t addr_to_index_biased(HeapWord* addr) const;
+  inline uintx addr_to_index_biased(HeapWord* addr) const;
 
-  void increment_length(size_t* length) {
+  void increment_length(uint* length) {
     assert(*length < _max_length, "pre-condition");
     *length += 1;
   }
 
-  void decrement_length(size_t* length) {
+  void decrement_length(uint* length) {
     assert(*length > 0, "pre-condition");
     *length -= 1;
   }
@@ -108,11 +106,11 @@
   // Empty contructor, we'll initialize it with the initialize() method.
   HeapRegionSeq() { }
 
-  void initialize(HeapWord* bottom, HeapWord* end, size_t max_length);
+  void initialize(HeapWord* bottom, HeapWord* end, uint max_length);
 
   // Return the HeapRegion at the given index. Assume that the index
   // is valid.
-  inline HeapRegion* at(size_t index) const;
+  inline HeapRegion* at(uint index) const;
 
   // If addr is within the committed space return its corresponding
   // HeapRegion, otherwise return NULL.
@@ -123,10 +121,10 @@
   inline HeapRegion* addr_to_region_unsafe(HeapWord* addr) const;
 
   // Return the number of regions that have been committed in the heap.
-  size_t length() const { return _length; }
+  uint length() const { return _length; }
 
   // Return the maximum number of regions in the heap.
-  size_t max_length() const { return _max_length; }
+  uint max_length() const { return _max_length; }
 
   // Expand the sequence to reflect that the heap has grown from
   // old_end to new_end. Either create new HeapRegions, or re-use
@@ -139,12 +137,12 @@
 
   // Return the number of contiguous regions at the end of the sequence
   // that are available for allocation.
-  size_t free_suffix();
+  uint free_suffix();
 
   // Find a contiguous set of empty regions of length num and return
   // the index of the first region or G1_NULL_HRS_INDEX if the
   // search was unsuccessful.
-  size_t find_contiguous(size_t num);
+  uint find_contiguous(uint num);
 
   // Apply blk->doHeapRegion() on all committed regions in address order,
   // terminating the iteration early if doHeapRegion() returns true.
@@ -159,7 +157,7 @@
   // sequence. Return a MemRegion that corresponds to the address
   // range of the uncommitted regions. Assume shrink_bytes is page and
   // heap region aligned.
-  MemRegion shrink_by(size_t shrink_bytes, size_t* num_regions_deleted);
+  MemRegion shrink_by(size_t shrink_bytes, uint* num_regions_deleted);
 
   // Do some sanity checking.
   void verify_optional() PRODUCT_RETURN;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp
index 3cc5aa8..e840287 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSeq.inline.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,11 +28,11 @@
 #include "gc_implementation/g1/heapRegion.hpp"
 #include "gc_implementation/g1/heapRegionSeq.hpp"
 
-inline size_t HeapRegionSeq::addr_to_index_biased(HeapWord* addr) const {
+inline uintx HeapRegionSeq::addr_to_index_biased(HeapWord* addr) const {
   assert(_heap_bottom <= addr && addr < _heap_end,
          err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT" end: "PTR_FORMAT,
                  addr, _heap_bottom, _heap_end));
-  size_t index = (size_t) addr >> _region_shift;
+  uintx index = (uintx) addr >> _region_shift;
   return index;
 }
 
@@ -40,7 +40,7 @@
   assert(_heap_bottom <= addr && addr < _heap_end,
          err_msg("addr: "PTR_FORMAT" bottom: "PTR_FORMAT" end: "PTR_FORMAT,
                  addr, _heap_bottom, _heap_end));
-  size_t index_biased = addr_to_index_biased(addr);
+  uintx index_biased = addr_to_index_biased(addr);
   HeapRegion* hr = _regions_biased[index_biased];
   assert(hr != NULL, "invariant");
   return hr;
@@ -55,7 +55,7 @@
   return NULL;
 }
 
-inline HeapRegion* HeapRegionSeq::at(size_t index) const {
+inline HeapRegion* HeapRegionSeq::at(uint index) const {
   assert(index < length(), "pre-condition");
   HeapRegion* hr = _regions[index];
   assert(hr != NULL, "sanity");
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp
index e21cdd74..c0533c6 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,28 +25,18 @@
 #include "precompiled.hpp"
 #include "gc_implementation/g1/heapRegionSet.inline.hpp"
 
-size_t HeapRegionSetBase::_unrealistically_long_length = 0;
+uint HeapRegionSetBase::_unrealistically_long_length = 0;
 HRSPhase HeapRegionSetBase::_phase = HRSPhaseNone;
 
 //////////////////// HeapRegionSetBase ////////////////////
 
-void HeapRegionSetBase::set_unrealistically_long_length(size_t len) {
+void HeapRegionSetBase::set_unrealistically_long_length(uint len) {
   guarantee(_unrealistically_long_length == 0, "should only be set once");
   _unrealistically_long_length = len;
 }
 
-size_t HeapRegionSetBase::calculate_region_num(HeapRegion* hr) {
-  assert(hr->startsHumongous(), "pre-condition");
-  assert(hr->capacity() % HeapRegion::GrainBytes == 0, "invariant");
-  size_t region_num = hr->capacity() >> HeapRegion::LogOfHRGrainBytes;
-  assert(region_num > 0, "sanity");
-  return region_num;
-}
-
 void HeapRegionSetBase::fill_in_ext_msg(hrs_ext_msg* msg, const char* message) {
-  msg->append("[%s] %s "
-              "ln: "SIZE_FORMAT" rn: "SIZE_FORMAT" "
-              "cy: "SIZE_FORMAT" ud: "SIZE_FORMAT,
+  msg->append("[%s] %s ln: %u rn: %u cy: "SIZE_FORMAT" ud: "SIZE_FORMAT,
               name(), message, length(), region_num(),
               total_capacity_bytes(), total_used_bytes());
   fill_in_ext_msg_extra(msg);
@@ -154,11 +144,7 @@
   guarantee(verify_region(hr, this), hrs_ext_msg(this, "region verification"));
 
   _calc_length               += 1;
-  if (!hr->isHumongous()) {
-    _calc_region_num         += 1;
-  } else {
-    _calc_region_num         += calculate_region_num(hr);
-  }
+  _calc_region_num           += hr->region_num();
   _calc_total_capacity_bytes += hr->capacity();
   _calc_total_used_bytes     += hr->used();
 }
@@ -170,13 +156,11 @@
          hrs_ext_msg(this, "verification should be in progress"));
 
   guarantee(length() == _calc_length,
-            hrs_err_msg("[%s] length: "SIZE_FORMAT" should be == "
-                        "calc length: "SIZE_FORMAT,
+            hrs_err_msg("[%s] length: %u should be == calc length: %u",
                         name(), length(), _calc_length));
 
   guarantee(region_num() == _calc_region_num,
-            hrs_err_msg("[%s] region num: "SIZE_FORMAT" should be == "
-                        "calc region num: "SIZE_FORMAT,
+            hrs_err_msg("[%s] region num: %u should be == calc region num: %u",
                         name(), region_num(), _calc_region_num));
 
   guarantee(total_capacity_bytes() == _calc_total_capacity_bytes,
@@ -211,8 +195,8 @@
   out->print_cr("    humongous         : %s", BOOL_TO_STR(regions_humongous()));
   out->print_cr("    empty             : %s", BOOL_TO_STR(regions_empty()));
   out->print_cr("  Attributes");
-  out->print_cr("    length            : "SIZE_FORMAT_W(14), length());
-  out->print_cr("    region num        : "SIZE_FORMAT_W(14), region_num());
+  out->print_cr("    length            : %14u", length());
+  out->print_cr("    region num        : %14u", region_num());
   out->print_cr("    total capacity    : "SIZE_FORMAT_W(14)" bytes",
                 total_capacity_bytes());
   out->print_cr("    total used        : "SIZE_FORMAT_W(14)" bytes",
@@ -243,14 +227,12 @@
   if (proxy_set->is_empty()) return;
 
   assert(proxy_set->length() <= _length,
-         hrs_err_msg("[%s] proxy set length: "SIZE_FORMAT" "
-                     "should be <= length: "SIZE_FORMAT,
+         hrs_err_msg("[%s] proxy set length: %u should be <= length: %u",
                      name(), proxy_set->length(), _length));
   _length -= proxy_set->length();
 
   assert(proxy_set->region_num() <= _region_num,
-         hrs_err_msg("[%s] proxy set region num: "SIZE_FORMAT" "
-                     "should be <= region num: "SIZE_FORMAT,
+         hrs_err_msg("[%s] proxy set region num: %u should be <= region num: %u",
                      name(), proxy_set->region_num(), _region_num));
   _region_num -= proxy_set->region_num();
 
@@ -298,7 +280,7 @@
     assert(length() >  0 && _tail != NULL, hrs_ext_msg(this, "invariant"));
     from_list->_tail->set_next(_head);
   } else {
-    assert(length() == 0 && _head == NULL, hrs_ext_msg(this, "invariant"));
+    assert(length() == 0 && _tail == NULL, hrs_ext_msg(this, "invariant"));
     _tail = from_list->_tail;
   }
   _head = from_list->_head;
@@ -369,17 +351,17 @@
   verify_optional();
 }
 
-void HeapRegionLinkedList::remove_all_pending(size_t target_count) {
+void HeapRegionLinkedList::remove_all_pending(uint target_count) {
   hrs_assert_mt_safety_ok(this);
   assert(target_count > 1, hrs_ext_msg(this, "pre-condition"));
   assert(!is_empty(), hrs_ext_msg(this, "pre-condition"));
 
   verify_optional();
-  DEBUG_ONLY(size_t old_length = length();)
+  DEBUG_ONLY(uint old_length = length();)
 
   HeapRegion* curr = _head;
   HeapRegion* prev = NULL;
-  size_t count = 0;
+  uint count = 0;
   while (curr != NULL) {
     hrs_assert_region_ok(this, curr, this);
     HeapRegion* next = curr->next();
@@ -387,7 +369,7 @@
     if (curr->pending_removal()) {
       assert(count < target_count,
              hrs_err_msg("[%s] should not come across more regions "
-                         "pending for removal than target_count: "SIZE_FORMAT,
+                         "pending for removal than target_count: %u",
                          name(), target_count));
 
       if (prev == NULL) {
@@ -422,12 +404,11 @@
   }
 
   assert(count == target_count,
-         hrs_err_msg("[%s] count: "SIZE_FORMAT" should be == "
-                     "target_count: "SIZE_FORMAT, name(), count, target_count));
+         hrs_err_msg("[%s] count: %u should be == target_count: %u",
+                     name(), count, target_count));
   assert(length() + target_count == old_length,
          hrs_err_msg("[%s] new length should be consistent "
-                     "new length: "SIZE_FORMAT" old length: "SIZE_FORMAT" "
-                     "target_count: "SIZE_FORMAT,
+                     "new length: %u old length: %u target_count: %u",
                      name(), length(), old_length, target_count));
 
   verify_optional();
@@ -444,16 +425,16 @@
   HeapRegion* curr  = _head;
   HeapRegion* prev1 = NULL;
   HeapRegion* prev0 = NULL;
-  size_t      count = 0;
+  uint        count = 0;
   while (curr != NULL) {
     verify_next_region(curr);
 
     count += 1;
     guarantee(count < _unrealistically_long_length,
-              hrs_err_msg("[%s] the calculated length: "SIZE_FORMAT" "
+              hrs_err_msg("[%s] the calculated length: %u "
                           "seems very long, is there maybe a cycle? "
                           "curr: "PTR_FORMAT" prev0: "PTR_FORMAT" "
-                          "prev1: "PTR_FORMAT" length: "SIZE_FORMAT,
+                          "prev1: "PTR_FORMAT" length: %u",
                           name(), count, curr, prev0, prev1, length()));
 
     prev1 = prev0;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp
index 8231c77..f2f10d8 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.hpp
@@ -62,20 +62,18 @@
   friend class VMStructs;
 
 protected:
-  static size_t calculate_region_num(HeapRegion* hr);
-
-  static size_t _unrealistically_long_length;
+  static uint _unrealistically_long_length;
 
   // The number of regions added to the set. If the set contains
   // only humongous regions, this reflects only 'starts humongous'
   // regions and does not include 'continues humongous' ones.
-  size_t _length;
+  uint _length;
 
   // The total number of regions represented by the set. If the set
   // does not contain humongous regions, this should be the same as
   // _length. If the set contains only humongous regions, this will
   // include the 'continues humongous' regions.
-  size_t _region_num;
+  uint _region_num;
 
   // We don't keep track of the total capacity explicitly, we instead
   // recalculate it based on _region_num and the heap region size.
@@ -86,8 +84,8 @@
   const char* _name;
 
   bool        _verify_in_progress;
-  size_t      _calc_length;
-  size_t      _calc_region_num;
+  uint        _calc_length;
+  uint        _calc_region_num;
   size_t      _calc_total_capacity_bytes;
   size_t      _calc_total_used_bytes;
 
@@ -153,18 +151,18 @@
   HeapRegionSetBase(const char* name);
 
 public:
-  static void set_unrealistically_long_length(size_t len);
+  static void set_unrealistically_long_length(uint len);
 
   const char* name() { return _name; }
 
-  size_t length() { return _length; }
+  uint length() { return _length; }
 
   bool is_empty() { return _length == 0; }
 
-  size_t region_num() { return _region_num; }
+  uint region_num() { return _region_num; }
 
   size_t total_capacity_bytes() {
-    return region_num() << HeapRegion::LogOfHRGrainBytes;
+    return (size_t) region_num() << HeapRegion::LogOfHRGrainBytes;
   }
 
   size_t total_used_bytes() { return _total_used_bytes; }
@@ -341,7 +339,7 @@
   // of regions that are pending for removal in the list, and
   // target_count should be > 1 (currently, we never need to remove a
   // single region using this).
-  void remove_all_pending(size_t target_count);
+  void remove_all_pending(uint target_count);
 
   virtual void verify();
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp
index 9cb40b5..18c754b 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/heapRegionSet.inline.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,11 +33,7 @@
   // Assumes the caller has already verified the region.
 
   _length           += 1;
-  if (!hr->isHumongous()) {
-    _region_num     += 1;
-  } else {
-    _region_num     += calculate_region_num(hr);
-  }
+  _region_num       += hr->region_num();
   _total_used_bytes += hr->used();
 }
 
@@ -54,15 +50,10 @@
   assert(_length > 0, hrs_ext_msg(this, "pre-condition"));
   _length -= 1;
 
-  size_t region_num_diff;
-  if (!hr->isHumongous()) {
-    region_num_diff = 1;
-  } else {
-    region_num_diff = calculate_region_num(hr);
-  }
+  uint region_num_diff = hr->region_num();
   assert(region_num_diff <= _region_num,
-         hrs_err_msg("[%s] region's region num: "SIZE_FORMAT" "
-                     "should be <= region num: "SIZE_FORMAT,
+         hrs_err_msg("[%s] region's region num: %u "
+                     "should be <= region num: %u",
                      name(), region_num_diff, _region_num));
   _region_num -= region_num_diff;
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp
index 7bf8fec..1a756aa 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/ptrQueue.cpp
@@ -126,7 +126,7 @@
     return res;
   } else {
     // Allocate space for the BufferNode in front of the buffer.
-    char *b =  NEW_C_HEAP_ARRAY(char, _sz + BufferNode::aligned_size());
+    char *b =  NEW_C_HEAP_ARRAY(char, _sz + BufferNode::aligned_size(), mtGC);
     return BufferNode::make_buffer_from_block(b);
   }
 }
@@ -149,7 +149,7 @@
     assert(_buf_free_list != NULL, "_buf_free_list_sz must be wrong.");
     void* b = BufferNode::make_block_from_node(_buf_free_list);
     _buf_free_list = _buf_free_list->next();
-    FREE_C_HEAP_ARRAY(char, b);
+    FREE_C_HEAP_ARRAY(char, b, mtGC);
     _buf_free_list_sz --;
     n--;
   }
diff --git a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp
index 69b01bc..c87f12d 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/satbQueue.cpp
@@ -208,7 +208,7 @@
   PtrQueueSet::initialize(cbl_mon, fl_lock, process_completed_threshold, -1);
   _shared_satb_queue.set_lock(lock);
   if (ParallelGCThreads > 0) {
-    _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads);
+    _par_closures = NEW_C_HEAP_ARRAY(ObjectClosure*, ParallelGCThreads, mtGC);
   }
 }
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp
index 5cdd101..0daa635 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -148,8 +148,8 @@
 RSHashTable::RSHashTable(size_t capacity) :
   _capacity(capacity), _capacity_mask(capacity-1),
   _occupied_entries(0), _occupied_cards(0),
-  _entries((SparsePRTEntry*)NEW_C_HEAP_ARRAY(char, SparsePRTEntry::size() * capacity)),
-  _buckets(NEW_C_HEAP_ARRAY(int, capacity)),
+  _entries((SparsePRTEntry*)NEW_C_HEAP_ARRAY(char, SparsePRTEntry::size() * capacity, mtGC)),
+  _buckets(NEW_C_HEAP_ARRAY(int, capacity, mtGC)),
   _free_list(NullEntry), _free_region(0)
 {
   clear();
@@ -157,11 +157,11 @@
 
 RSHashTable::~RSHashTable() {
   if (_entries != NULL) {
-    FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries);
+    FREE_C_HEAP_ARRAY(SparsePRTEntry, _entries, mtGC);
     _entries = NULL;
   }
   if (_buckets != NULL) {
-    FREE_C_HEAP_ARRAY(int, _buckets);
+    FREE_C_HEAP_ARRAY(int, _buckets, mtGC);
     _buckets = NULL;
   }
 }
@@ -481,8 +481,7 @@
 
 bool SparsePRT::add_card(RegionIdx_t region_id, CardIdx_t card_index) {
 #if SPARSE_PRT_VERBOSE
-  gclog_or_tty->print_cr("  Adding card %d from region %d to region "
-                         SIZE_FORMAT" sparse.",
+  gclog_or_tty->print_cr("  Adding card %d from region %d to region %u sparse.",
                          card_index, region_id, _hr->hrs_index());
 #endif
   if (_next->occupied_entries() * 2 > _next->capacity()) {
@@ -534,7 +533,7 @@
   _next = new RSHashTable(last->capacity() * 2);
 
 #if SPARSE_PRT_VERBOSE
-  gclog_or_tty->print_cr("  Expanded sparse table for "SIZE_FORMAT" to %d.",
+  gclog_or_tty->print_cr("  Expanded sparse table for %u to %d.",
                          _hr->hrs_index(), _next->capacity());
 #endif
   for (size_t i = 0; i < last->capacity(); i++) {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp
index 6780086..6a86029 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/sparsePRT.hpp
@@ -42,7 +42,7 @@
 // insertions only enqueue old versions for deletions, but do not delete
 // old versions synchronously.
 
-class SparsePRTEntry: public CHeapObj {
+class SparsePRTEntry: public CHeapObj<mtGC> {
 public:
   enum SomePublicConstants {
     NullEntry     = -1,
@@ -101,7 +101,7 @@
 };
 
 
-class RSHashTable : public CHeapObj {
+class RSHashTable : public CHeapObj<mtGC> {
 
   friend class RSHashTableIter;
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp
index ec44c8e..1232cf3 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.cpp
@@ -43,7 +43,7 @@
   reset();
   if (summary_surv_rates_len > 0) {
     size_t length = summary_surv_rates_len;
-    _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length);
+      _summary_surv_rates = NEW_C_HEAP_ARRAY(NumberSeq*, length, mtGC);
     for (size_t i = 0; i < length; ++i) {
       _summary_surv_rates[i] = new NumberSeq();
     }
@@ -90,9 +90,9 @@
     double* old_accum_surv_rate_pred = _accum_surv_rate_pred;
     TruncatedSeq** old_surv_rate_pred = _surv_rate_pred;
 
-    _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num);
-    _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num);
-    _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num);
+    _surv_rate = NEW_C_HEAP_ARRAY(double, _region_num, mtGC);
+    _accum_surv_rate_pred = NEW_C_HEAP_ARRAY(double, _region_num, mtGC);
+    _surv_rate_pred = NEW_C_HEAP_ARRAY(TruncatedSeq*, _region_num, mtGC);
 
     for (size_t i = 0; i < _stats_arrays_length; ++i) {
       _surv_rate_pred[i] = old_surv_rate_pred[i];
@@ -104,13 +104,13 @@
     _stats_arrays_length = _region_num;
 
     if (old_surv_rate != NULL) {
-      FREE_C_HEAP_ARRAY(double, old_surv_rate);
+      FREE_C_HEAP_ARRAY(double, old_surv_rate, mtGC);
     }
     if (old_accum_surv_rate_pred != NULL) {
-      FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred);
+      FREE_C_HEAP_ARRAY(double, old_accum_surv_rate_pred, mtGC);
     }
     if (old_surv_rate_pred != NULL) {
-      FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred);
+      FREE_C_HEAP_ARRAY(TruncatedSeq*, old_surv_rate_pred, mtGC);
     }
   }
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.hpp b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.hpp
index c9617f2..abac3e0 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/survRateGroup.hpp
@@ -29,7 +29,7 @@
 
 class G1CollectorPolicy;
 
-class SurvRateGroup : public CHeapObj {
+class SurvRateGroup : public CHeapObj<mtGC> {
 private:
   G1CollectorPolicy* _g1p;
   const char* _name;
diff --git a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
index a646b48..5507dee 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/vmStructs_g1.hpp
@@ -34,7 +34,7 @@
   static_field(HeapRegion, GrainBytes, size_t)                                \
                                                                               \
   nonstatic_field(HeapRegionSeq,   _regions, HeapRegion**)                    \
-  nonstatic_field(HeapRegionSeq,   _length,  size_t)                          \
+  nonstatic_field(HeapRegionSeq,   _length,  uint)                            \
                                                                               \
   nonstatic_field(G1CollectedHeap, _hrs,                HeapRegionSeq)        \
   nonstatic_field(G1CollectedHeap, _g1_committed,       MemRegion)            \
@@ -50,8 +50,8 @@
   nonstatic_field(G1MonitoringSupport, _old_committed,      size_t)           \
   nonstatic_field(G1MonitoringSupport, _old_used,           size_t)           \
                                                                               \
-  nonstatic_field(HeapRegionSetBase,   _length,             size_t)           \
-  nonstatic_field(HeapRegionSetBase,   _region_num,         size_t)           \
+  nonstatic_field(HeapRegionSetBase,   _length,             uint)             \
+  nonstatic_field(HeapRegionSetBase,   _region_num,         uint)             \
   nonstatic_field(HeapRegionSetBase,   _total_used_bytes,   size_t)           \
 
 
diff --git a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
index 05e7f35..cf7488f 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.cpp
@@ -26,6 +26,7 @@
 #include "gc_implementation/g1/concurrentMarkThread.inline.hpp"
 #include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
 #include "gc_implementation/g1/g1CollectorPolicy.hpp"
+#include "gc_implementation/g1/g1Log.hpp"
 #include "gc_implementation/g1/vm_operations_g1.hpp"
 #include "gc_implementation/shared/isGCActiveMark.hpp"
 #include "gc_implementation/g1/vm_operations_g1.hpp"
@@ -41,6 +42,7 @@
 
 void VM_G1CollectForAllocation::doit() {
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
+  GCCauseSetter x(g1h, _gc_cause);
   _result = g1h->satisfy_failed_allocation(_word_size, &_pause_succeeded);
   assert(_result == NULL || _pause_succeeded,
          "if we get back a result, the pause should have succeeded");
@@ -62,7 +64,7 @@
     _should_initiate_conc_mark(should_initiate_conc_mark),
     _target_pause_time_ms(target_pause_time_ms),
     _should_retry_gc(false),
-    _full_collections_completed_before(0) {
+    _old_marking_cycles_completed_before(0) {
   guarantee(target_pause_time_ms > 0.0,
             err_msg("target_pause_time_ms = %1.6lf should be positive",
                     target_pause_time_ms));
@@ -110,11 +112,11 @@
 
   GCCauseSetter x(g1h, _gc_cause);
   if (_should_initiate_conc_mark) {
-    // It's safer to read full_collections_completed() here, given
+    // It's safer to read old_marking_cycles_completed() here, given
     // that noone else will be updating it concurrently. Since we'll
     // only need it if we're initiating a marking cycle, no point in
     // setting it earlier.
-    _full_collections_completed_before = g1h->full_collections_completed();
+    _old_marking_cycles_completed_before = g1h->old_marking_cycles_completed();
 
     // At this point we are supposed to start a concurrent cycle. We
     // will do so if one is not already in progress.
@@ -179,17 +181,17 @@
 
     G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
-    // In the doit() method we saved g1h->full_collections_completed()
-    // in the _full_collections_completed_before field. We have to
-    // wait until we observe that g1h->full_collections_completed()
+    // In the doit() method we saved g1h->old_marking_cycles_completed()
+    // in the _old_marking_cycles_completed_before field. We have to
+    // wait until we observe that g1h->old_marking_cycles_completed()
     // has increased by at least one. This can happen if a) we started
     // a cycle and it completes, b) a cycle already in progress
     // completes, or c) a Full GC happens.
 
     // If the condition has already been reached, there's no point in
     // actually taking the lock and doing the wait.
-    if (g1h->full_collections_completed() <=
-                                          _full_collections_completed_before) {
+    if (g1h->old_marking_cycles_completed() <=
+                                          _old_marking_cycles_completed_before) {
       // The following is largely copied from CMS
 
       Thread* thr = Thread::current();
@@ -198,8 +200,8 @@
       ThreadToNativeFromVM native(jt);
 
       MutexLockerEx x(FullGCCount_lock, Mutex::_no_safepoint_check_flag);
-      while (g1h->full_collections_completed() <=
-                                          _full_collections_completed_before) {
+      while (g1h->old_marking_cycles_completed() <=
+                                          _old_marking_cycles_completed_before) {
         FullGCCount_lock->wait(Mutex::_no_safepoint_check_flag);
       }
     }
@@ -223,9 +225,9 @@
 }
 
 void VM_CGC_Operation::doit() {
-  gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
-  TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-  TraceTime t(_printGCMessage, PrintGC, true, gclog_or_tty);
+  gclog_or_tty->date_stamp(G1Log::fine() && PrintGCDateStamps);
+  TraceCPUTime tcpu(G1Log::finer(), true, gclog_or_tty);
+  TraceTime t(_printGCMessage, G1Log::fine(), true, gclog_or_tty);
   SharedHeap* sh = SharedHeap::heap();
   // This could go away if CollectedHeap gave access to _gc_is_active...
   if (sh != NULL) {
diff --git a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp
index ea2aeae..691812e 100644
--- a/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp
+++ b/hotspot/src/share/vm/gc_implementation/g1/vm_operations_g1.hpp
@@ -80,7 +80,7 @@
   bool         _should_initiate_conc_mark;
   bool         _should_retry_gc;
   double       _target_pause_time_ms;
-  unsigned int _full_collections_completed_before;
+  unsigned int _old_marking_cycles_completed_before;
 public:
   VM_G1IncCollectionPause(unsigned int   gc_count_before,
                           size_t         word_size,
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp
index 25be723..b4b62fc 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parCardTableModRefBS.cpp
@@ -457,12 +457,12 @@
         if (_lowest_non_clean[i] != NULL) {
           assert(n_chunks != _lowest_non_clean_chunk_size[i],
                  "logical consequence");
-          FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i]);
+          FREE_C_HEAP_ARRAY(CardPtr, _lowest_non_clean[i], mtGC);
           _lowest_non_clean[i] = NULL;
         }
         // Now allocate a new one if necessary.
         if (_lowest_non_clean[i] == NULL) {
-          _lowest_non_clean[i]                  = NEW_C_HEAP_ARRAY(CardPtr, n_chunks);
+          _lowest_non_clean[i]                  = NEW_C_HEAP_ARRAY(CardPtr, n_chunks, mtGC);
           _lowest_non_clean_chunk_size[i]       = n_chunks;
           _lowest_non_clean_base_chunk_index[i] = addr_to_chunk_index(covered.start());
           for (int j = 0; j < (int)n_chunks; j++)
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
index 4f64dff..dd3ead5 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp
@@ -24,11 +24,11 @@
 
 #include "precompiled.hpp"
 #include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
-#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
 #include "gc_implementation/parNew/parNewGeneration.hpp"
 #include "gc_implementation/parNew/parOopClosures.inline.hpp"
 #include "gc_implementation/shared/adaptiveSizePolicy.hpp"
 #include "gc_implementation/shared/ageTable.hpp"
+#include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "gc_implementation/shared/spaceDecorator.hpp"
 #include "memory/defNewGeneration.inline.hpp"
 #include "memory/genCollectedHeap.hpp"
@@ -59,7 +59,7 @@
                                        Generation* old_gen_,
                                        int thread_num_,
                                        ObjToScanQueueSet* work_queue_set_,
-                                       Stack<oop>* overflow_stacks_,
+                                       Stack<oop, mtGC>* overflow_stacks_,
                                        size_t desired_plab_sz_,
                                        ParallelTaskTerminator& term_) :
   _to_space(to_space_), _old_gen(old_gen_), _young_gen(gen_), _thread_num(thread_num_),
@@ -184,7 +184,7 @@
   assert(ParGCUseLocalOverflow, "Else should not call");
   assert(young_gen()->overflow_list() == NULL, "Error");
   ObjToScanQueue* queue = work_queue();
-  Stack<oop>* const of_stack = overflow_stack();
+  Stack<oop, mtGC>* const of_stack = overflow_stack();
   const size_t num_overflow_elems = of_stack->size();
   const size_t space_available = queue->max_elems() - queue->size();
   const size_t num_take_elems = MIN3(space_available / 4,
@@ -297,7 +297,7 @@
                         ParNewGeneration&       gen,
                         Generation&             old_gen,
                         ObjToScanQueueSet&      queue_set,
-                        Stack<oop>*             overflow_stacks_,
+                        Stack<oop, mtGC>*       overflow_stacks_,
                         size_t                  desired_plab_sz,
                         ParallelTaskTerminator& term);
 
@@ -331,7 +331,7 @@
 ParScanThreadStateSet::ParScanThreadStateSet(
   int num_threads, Space& to_space, ParNewGeneration& gen,
   Generation& old_gen, ObjToScanQueueSet& queue_set,
-  Stack<oop>* overflow_stacks,
+  Stack<oop, mtGC>* overflow_stacks,
   size_t desired_plab_sz, ParallelTaskTerminator& term)
   : ResourceArray(sizeof(ParScanThreadState), num_threads),
     _gen(gen), _next_gen(old_gen), _term(term)
@@ -453,7 +453,8 @@
     // retire the last buffer.
     par_scan_state.to_space_alloc_buffer()->
       flush_stats_and_retire(_gen.plab_stats(),
-                             false /* !retain */);
+                             true /* end_of_gc */,
+                             false /* retain */);
 
     // Every thread has its own age table.  We need to merge
     // them all into one.
@@ -649,9 +650,14 @@
 
   _overflow_stacks = NULL;
   if (ParGCUseLocalOverflow) {
-    _overflow_stacks = NEW_C_HEAP_ARRAY(Stack<oop>, ParallelGCThreads);
+
+    // typedef to workaround NEW_C_HEAP_ARRAY macro, which can not deal
+    // with ','
+    typedef Stack<oop, mtGC> GCOopStack;
+
+    _overflow_stacks = NEW_C_HEAP_ARRAY(GCOopStack, ParallelGCThreads, mtGC);
     for (size_t i = 0; i < ParallelGCThreads; ++i) {
-      new (_overflow_stacks + i) Stack<oop>();
+      new (_overflow_stacks + i) Stack<oop, mtGC>();
     }
   }
 
@@ -916,7 +922,7 @@
     size_policy->minor_collection_begin();
   }
 
-  TraceTime t1("GC", PrintGC && !PrintGCDetails, true, gclog_or_tty);
+  TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
   // Capture heap used before collection (for printing).
   size_t gch_prev_used = gch->used();
 
@@ -1025,7 +1031,7 @@
 
   adjust_desired_tenuring_threshold();
   if (ResizePLAB) {
-    plab_stats()->adjust_desired_plab_sz();
+    plab_stats()->adjust_desired_plab_sz(n_workers);
   }
 
   if (PrintGC && !PrintGCDetails) {
@@ -1401,7 +1407,7 @@
     assert(_num_par_pushes > 0, "Tautology");
 #endif
     if (from_space_obj->forwardee() == from_space_obj) {
-      oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1);
+      oopDesc* listhead = NEW_C_HEAP_ARRAY(oopDesc, 1, mtGC);
       listhead->forward_to(from_space_obj);
       from_space_obj = listhead;
     }
@@ -1553,7 +1559,7 @@
       // This can become a scaling bottleneck when there is work queue overflow coincident
       // with promotion failure.
       oopDesc* f = cur;
-      FREE_C_HEAP_ARRAY(oopDesc, f);
+      FREE_C_HEAP_ARRAY(oopDesc, f, mtGC);
     } else if (par_scan_state->should_be_partially_scanned(obj_to_push, cur)) {
       assert(arrayOop(cur)->length() == 0, "entire array remaining to be scanned");
       obj_to_push = cur;
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
index 75eac03..b8a2d1e 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parNewGeneration.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_PARNEW_PARNEWGENERATION_HPP
 
-#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "memory/defNewGeneration.hpp"
 #include "utilities/taskqueue.hpp"
 
@@ -41,7 +41,7 @@
 // in genOopClosures.inline.hpp.
 
 typedef Padded<OopTaskQueue> ObjToScanQueue;
-typedef GenericTaskQueueSet<ObjToScanQueue> ObjToScanQueueSet;
+typedef GenericTaskQueueSet<ObjToScanQueue, mtGC> ObjToScanQueueSet;
 
 class ParKeepAliveClosure: public DefNewGeneration::KeepAliveClosure {
  private:
@@ -59,7 +59,7 @@
   friend class ParScanThreadStateSet;
  private:
   ObjToScanQueue *_work_queue;
-  Stack<oop>* const _overflow_stack;
+  Stack<oop, mtGC>* const _overflow_stack;
 
   ParGCAllocBuffer _to_space_alloc_buffer;
 
@@ -127,7 +127,7 @@
   ParScanThreadState(Space* to_space_, ParNewGeneration* gen_,
                      Generation* old_gen_, int thread_num_,
                      ObjToScanQueueSet* work_queue_set_,
-                     Stack<oop>* overflow_stacks_,
+                     Stack<oop, mtGC>* overflow_stacks_,
                      size_t desired_plab_sz_,
                      ParallelTaskTerminator& term_);
 
@@ -151,7 +151,7 @@
   void trim_queues(int max_size);
 
   // Private overflow stack usage
-  Stack<oop>* overflow_stack() { return _overflow_stack; }
+  Stack<oop, mtGC>* overflow_stack() { return _overflow_stack; }
   bool take_from_overflow_stack();
   void push_on_overflow_stack(oop p);
 
@@ -312,7 +312,7 @@
   ObjToScanQueueSet* _task_queues;
 
   // Per-worker-thread local overflow stacks
-  Stack<oop>* _overflow_stacks;
+  Stack<oop, mtGC>* _overflow_stacks;
 
   // Desired size of survivor space plab's
   PLABStats _plab_stats;
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp
index 747868f..4a727e9 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parNew/parOopClosures.hpp
@@ -32,7 +32,7 @@
 class ParScanThreadState;
 class ParNewGeneration;
 typedef Padded<OopTaskQueue> ObjToScanQueue;
-typedef GenericTaskQueueSet<ObjToScanQueue> ObjToScanQueueSet;
+typedef GenericTaskQueueSet<ObjToScanQueue, mtGC> ObjToScanQueueSet;
 class ParallelTaskTerminator;
 
 class ParScanClosure: public OopsInGenClosure {
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp
index 77fe9e0..3018805 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/adjoiningGenerations.hpp
@@ -40,7 +40,7 @@
 // must be shrunk.  Adjusting the boundary between the generations
 // is called for in this class.
 
-class AdjoiningGenerations : public CHeapObj {
+class AdjoiningGenerations : public CHeapObj<mtGC> {
   friend class VMStructs;
  private:
   // The young generation and old generation, respectively
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
index 6e42fac..b5ee675 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/cardTableExtension.cpp
@@ -42,7 +42,7 @@
 
  protected:
   template <class T> void do_oop_work(T* p) {
-    oop obj = oopDesc::load_decode_heap_oop_not_null(p);
+    oop obj = oopDesc::load_decode_heap_oop(p);
     if (_young_gen->is_in_reserved(obj) &&
         !_card_table->addr_is_marked_imprecise(p)) {
       // Don't overwrite the first missing card mark
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp
index 04424aa..b32007e 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.cpp
@@ -116,7 +116,7 @@
 }
 
 GCTaskQueue* GCTaskQueue::create_on_c_heap() {
-  GCTaskQueue* result = new(ResourceObj::C_HEAP) GCTaskQueue(true);
+  GCTaskQueue* result = new(ResourceObj::C_HEAP, mtGC) GCTaskQueue(true);
   if (TraceGCTaskQueue) {
     tty->print_cr("GCTaskQueue::create_on_c_heap()"
                   " returns " INTPTR_FORMAT,
@@ -403,19 +403,19 @@
   _queue = SynchronizedGCTaskQueue::create(unsynchronized_queue, lock());
   _noop_task = NoopGCTask::create_on_c_heap();
   _idle_inactive_task = WaitForBarrierGCTask::create_on_c_heap();
-  _resource_flag = NEW_C_HEAP_ARRAY(bool, workers());
+  _resource_flag = NEW_C_HEAP_ARRAY(bool, workers(), mtGC);
   {
     // Set up worker threads.
     //     Distribute the workers among the available processors,
     //     unless we were told not to, or if the os doesn't want to.
-    uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers());
+    uint* processor_assignment = NEW_C_HEAP_ARRAY(uint, workers(), mtGC);
     if (!BindGCTaskThreadsToCPUs ||
         !os::distribute_processes(workers(), processor_assignment)) {
       for (uint a = 0; a < workers(); a += 1) {
         processor_assignment[a] = sentinel_worker();
       }
     }
-    _thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers());
+    _thread = NEW_C_HEAP_ARRAY(GCTaskThread*, workers(), mtGC);
     for (uint t = 0; t < workers(); t += 1) {
       set_thread(t, GCTaskThread::create(this, t, processor_assignment[t]));
     }
@@ -426,7 +426,7 @@
       }
       tty->cr();
     }
-    FREE_C_HEAP_ARRAY(uint, processor_assignment);
+    FREE_C_HEAP_ARRAY(uint, processor_assignment, mtGC);
   }
   reset_busy_workers();
   set_unblocked();
@@ -455,11 +455,11 @@
       GCTaskThread::destroy(thread(i));
       set_thread(i, NULL);
     }
-    FREE_C_HEAP_ARRAY(GCTaskThread*, _thread);
+    FREE_C_HEAP_ARRAY(GCTaskThread*, _thread, mtGC);
     _thread = NULL;
   }
   if (_resource_flag != NULL) {
-    FREE_C_HEAP_ARRAY(bool, _resource_flag);
+    FREE_C_HEAP_ARRAY(bool, _resource_flag, mtGC);
     _resource_flag = NULL;
   }
   if (queue() != NULL) {
@@ -817,7 +817,7 @@
 }
 
 NoopGCTask* NoopGCTask::create_on_c_heap() {
-  NoopGCTask* result = new(ResourceObj::C_HEAP) NoopGCTask(true);
+  NoopGCTask* result = new(ResourceObj::C_HEAP, mtGC) NoopGCTask(true);
   return result;
 }
 
@@ -848,7 +848,7 @@
 }
 
 IdleGCTask* IdleGCTask::create_on_c_heap() {
-  IdleGCTask* result = new(ResourceObj::C_HEAP) IdleGCTask(true);
+  IdleGCTask* result = new(ResourceObj::C_HEAP, mtGC) IdleGCTask(true);
   assert(UseDynamicNumberOfGCThreads,
     "Should only be used with dynamic GC thread");
   return result;
@@ -984,7 +984,7 @@
 
 WaitForBarrierGCTask* WaitForBarrierGCTask::create_on_c_heap() {
   WaitForBarrierGCTask* result =
-    new (ResourceObj::C_HEAP) WaitForBarrierGCTask(true);
+    new (ResourceObj::C_HEAP, mtGC) WaitForBarrierGCTask(true);
   return result;
 }
 
@@ -1114,7 +1114,7 @@
     // Lazy initialization.
     if (freelist() == NULL) {
       _freelist =
-        new(ResourceObj::C_HEAP) GrowableArray<Monitor*>(ParallelGCThreads,
+        new(ResourceObj::C_HEAP, mtGC) GrowableArray<Monitor*>(ParallelGCThreads,
                                                          true);
     }
     if (! freelist()->is_empty()) {
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp
index 65a8458..b64f7d9 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskManager.hpp
@@ -216,7 +216,7 @@
 
 // A GCTaskQueue that can be synchronized.
 // This "has-a" GCTaskQueue and a mutex to do the exclusion.
-class SynchronizedGCTaskQueue : public CHeapObj {
+class SynchronizedGCTaskQueue : public CHeapObj<mtGC> {
 private:
   // Instance state.
   GCTaskQueue* _unsynchronized_queue;   // Has-a unsynchronized queue.
@@ -278,7 +278,7 @@
 
 // This is an abstract base class for getting notifications
 // when a GCTaskManager is done.
-class NotifyDoneClosure : public CHeapObj {
+class NotifyDoneClosure : public CHeapObj<mtGC> {
 public:
   // The notification callback method.
   virtual void notify(GCTaskManager* manager) = 0;
@@ -355,7 +355,7 @@
 // held in the GCTaskThread** _thread array in GCTaskManager.
 
 
-class GCTaskManager : public CHeapObj {
+class GCTaskManager : public CHeapObj<mtGC> {
  friend class ParCompactionManager;
  friend class PSParallelCompact;
  friend class PSScavenge;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp
index 976d879..9bbdf49 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.cpp
@@ -46,7 +46,7 @@
     vm_exit_out_of_memory(0, "Cannot create GC thread. Out of system resources.");
 
   if (PrintGCTaskTimeStamps) {
-    _time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries );
+    _time_stamps = NEW_C_HEAP_ARRAY(GCTaskTimeStamp, GCTaskTimeStampEntries, mtGC);
 
     guarantee(_time_stamps != NULL, "Sanity");
   }
@@ -56,7 +56,7 @@
 
 GCTaskThread::~GCTaskThread() {
   if (_time_stamps != NULL) {
-    FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps);
+    FREE_C_HEAP_ARRAY(GCTaskTimeStamp, _time_stamps, mtGC);
   }
 }
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp
index c840654..1a77fe0 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/gcTaskThread.hpp
@@ -90,7 +90,7 @@
   void set_is_working(bool v) { _is_working = v; }
 };
 
-class GCTaskTimeStamp : public CHeapObj
+class GCTaskTimeStamp : public CHeapObj<mtGC>
 {
  private:
   jlong  _entry_time;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp
index 1b80839..8a852cc 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.cpp
@@ -28,6 +28,7 @@
 #include "memory/cardTableModRefBS.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
+#include "services/memTracker.hpp"
 
 void ObjectStartArray::initialize(MemRegion reserved_region) {
   // We're based on the assumption that we use the same
@@ -50,6 +51,7 @@
   if (!backing_store.is_reserved()) {
     vm_exit_during_initialization("Could not reserve space for ObjectStartArray");
   }
+  MemTracker::record_virtual_memory_type((address)backing_store.base(), mtGC);
 
   // We do not commit any memory initially
   if (!_virtual_space.initialize(backing_store, 0)) {
@@ -57,10 +59,14 @@
   }
 
   _raw_base = (jbyte*)_virtual_space.low_boundary();
+
   if (_raw_base == NULL) {
     vm_exit_during_initialization("Could not get raw_base address");
   }
 
+  MemTracker::record_virtual_memory_type((address)_raw_base, mtGC);
+
+
   _offset_base = _raw_base - (size_t(reserved_region.start()) >> block_shift);
 
   _covered_region.set_start(reserved_region.start());
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp
index cea680b..cbd671a 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/objectStartArray.hpp
@@ -35,7 +35,7 @@
 // covered region.
 //
 
-class ObjectStartArray : public CHeapObj {
+class ObjectStartArray : public CHeapObj<mtGC> {
  friend class VerifyObjectStartArrayClosure;
 
  private:
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
index 4496a69..44ddcba 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.cpp
@@ -29,6 +29,7 @@
 #include "oops/oop.inline.hpp"
 #include "runtime/os.hpp"
 #include "utilities/bitMap.inline.hpp"
+#include "services/memTracker.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
 #endif
@@ -61,6 +62,9 @@
   ReservedSpace rs(bytes, rs_align, rs_align > 0);
   os::trace_page_sizes("par bitmap", raw_bytes, raw_bytes, page_sz,
                        rs.base(), rs.size());
+
+  MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
+
   _virtual_space = new PSVirtualSpace(rs, page_sz);
   if (_virtual_space != NULL && _virtual_space->expand_by(bytes)) {
     _region_start = covered_region.start();
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
index e6a0731..9523b79 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parMarkBitMap.hpp
@@ -32,7 +32,7 @@
 class oopDesc;
 class ParMarkBitMapClosure;
 
-class ParMarkBitMap: public CHeapObj
+class ParMarkBitMap: public CHeapObj<mtGC>
 {
 public:
   typedef BitMap::idx_t idx_t;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
index 8fef37e..a1031a7 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.cpp
@@ -40,6 +40,7 @@
 #include "runtime/handles.inline.hpp"
 #include "runtime/java.hpp"
 #include "runtime/vmThread.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/vmError.hpp"
 
 PSYoungGen*  ParallelScavengeHeap::_young_gen = NULL;
@@ -161,6 +162,8 @@
     }
   }
 
+  MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtJavaHeap);
+
   os::trace_page_sizes("ps perm", pg_min_size, pg_max_size, pg_page_sz,
                        heap_rs.base(), pg_max_size);
   os::trace_page_sizes("ps main", og_min_size + yg_min_size,
@@ -911,23 +914,23 @@
 }
 
 
-void ParallelScavengeHeap::verify(bool allow_dirty, bool silent, VerifyOption option /* ignored */) {
+void ParallelScavengeHeap::verify(bool silent, VerifyOption option /* ignored */) {
   // Why do we need the total_collections()-filter below?
   if (total_collections() > 0) {
     if (!silent) {
       gclog_or_tty->print("permanent ");
     }
-    perm_gen()->verify(allow_dirty);
+    perm_gen()->verify();
 
     if (!silent) {
       gclog_or_tty->print("tenured ");
     }
-    old_gen()->verify(allow_dirty);
+    old_gen()->verify();
 
     if (!silent) {
       gclog_or_tty->print("eden ");
     }
-    young_gen()->verify(allow_dirty);
+    young_gen()->verify();
   }
 }
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
index 5934cdf..e118997 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/parallelScavengeHeap.hpp
@@ -257,7 +257,7 @@
   virtual void gc_threads_do(ThreadClosure* tc) const;
   virtual void print_tracing_info() const;
 
-  void verify(bool allow_dirty, bool silent, VerifyOption option /* ignored */);
+  void verify(bool silent, VerifyOption option /* ignored */);
 
   void print_heap_change(size_t prev_used);
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
index ab4ad84..fc66dcf 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.cpp
@@ -81,14 +81,14 @@
   uint parallel_gc_threads = PSParallelCompact::gc_task_manager()->workers();
 
   assert(_manager_array == NULL, "Attempt to initialize twice");
-  _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1 );
+  _manager_array = NEW_C_HEAP_ARRAY(ParCompactionManager*, parallel_gc_threads+1, mtGC);
   guarantee(_manager_array != NULL, "Could not allocate manager_array");
 
   _region_list = NEW_C_HEAP_ARRAY(RegionTaskQueue*,
-                                         parallel_gc_threads+1);
+                         parallel_gc_threads+1, mtGC);
   guarantee(_region_list != NULL, "Could not initialize promotion manager");
 
-  _recycled_stack_index = NEW_C_HEAP_ARRAY(uint, parallel_gc_threads);
+  _recycled_stack_index = NEW_C_HEAP_ARRAY(uint, parallel_gc_threads, mtGC);
 
   // parallel_gc-threads + 1 to be consistent with the number of
   // compaction managers.
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
index a864ac8..73849be 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psCompactionManager.hpp
@@ -41,7 +41,7 @@
 class ParallelCompactData;
 class ParMarkBitMap;
 
-class ParCompactionManager : public CHeapObj {
+class ParCompactionManager : public CHeapObj<mtGC> {
   friend class ParallelTaskTerminator;
   friend class ParMarkBitMap;
   friend class PSParallelCompact;
@@ -66,8 +66,8 @@
  private:
   // 32-bit:  4K * 8 = 32KiB; 64-bit:  8K * 16 = 128KiB
   #define QUEUE_SIZE (1 << NOT_LP64(12) LP64_ONLY(13))
-  typedef OverflowTaskQueue<ObjArrayTask, QUEUE_SIZE> ObjArrayTaskQueue;
-  typedef GenericTaskQueueSet<ObjArrayTaskQueue>      ObjArrayTaskQueueSet;
+  typedef OverflowTaskQueue<ObjArrayTask, mtGC, QUEUE_SIZE> ObjArrayTaskQueue;
+  typedef GenericTaskQueueSet<ObjArrayTaskQueue, mtGC>      ObjArrayTaskQueueSet;
   #undef QUEUE_SIZE
 
   static ParCompactionManager** _manager_array;
@@ -78,7 +78,7 @@
   static PSOldGen*              _old_gen;
 
 private:
-  OverflowTaskQueue<oop>        _marking_stack;
+  OverflowTaskQueue<oop, mtGC>        _marking_stack;
   ObjArrayTaskQueue             _objarray_stack;
 
   // Is there a way to reuse the _marking_stack for the
@@ -110,8 +110,8 @@
   // popped.  If -1, there has not been any entry popped.
   static int                      _recycled_bottom;
 
-  Stack<Klass*>                 _revisit_klass_stack;
-  Stack<DataLayout*>            _revisit_mdo_stack;
+  Stack<Klass*, mtGC>                 _revisit_klass_stack;
+  Stack<DataLayout*, mtGC>            _revisit_mdo_stack;
 
   static ParMarkBitMap* _mark_bitmap;
 
@@ -126,7 +126,7 @@
  protected:
   // Array of tasks.  Needed by the ParallelTaskTerminator.
   static RegionTaskQueueSet* region_array()      { return _region_array; }
-  OverflowTaskQueue<oop>*  marking_stack()       { return &_marking_stack; }
+  OverflowTaskQueue<oop, mtGC>*  marking_stack()       { return &_marking_stack; }
 
   // Pushes onto the marking stack.  If the marking stack is full,
   // pushes onto the overflow stack.
@@ -175,8 +175,8 @@
   bool should_update();
   bool should_copy();
 
-  Stack<Klass*>* revisit_klass_stack() { return &_revisit_klass_stack; }
-  Stack<DataLayout*>* revisit_mdo_stack() { return &_revisit_mdo_stack; }
+  Stack<Klass*, mtGC>* revisit_klass_stack() { return &_revisit_klass_stack; }
+  Stack<DataLayout*, mtGC>* revisit_mdo_stack() { return &_revisit_mdo_stack; }
 
   // Save for later processing.  Must not fail.
   inline void push(oop obj) { _marking_stack.push(obj); }
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp
index 67378de..ccb4298 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psGenerationCounters.cpp
@@ -40,7 +40,7 @@
 
     const char* cns = PerfDataManager::name_space("generation", ordinal);
 
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1);
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
     strcpy(_name_space, cns);
 
     const char* cname = PerfDataManager::counter_name(_name_space, "name");
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
index ad599ae..660babf 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweep.cpp
@@ -141,7 +141,7 @@
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
     gclog_or_tty->print(" VerifyBeforeGC:");
-    Universe::verify(true);
+    Universe::verify();
   }
 
   // Verify object start arrays
@@ -160,16 +160,10 @@
 
   {
     HandleMark hm;
-    const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc;
-    // This is useful for debugging but don't change the output the
-    // the customer sees.
-    const char* gc_cause_str = "Full GC";
-    if (is_system_gc && PrintGCDetails) {
-      gc_cause_str = "Full GC (System)";
-    }
+
     gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty);
+    TraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
 
@@ -358,7 +352,7 @@
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
     gclog_or_tty->print(" VerifyAfterGC:");
-    Universe::verify(false);
+    Universe::verify();
   }
 
   // Re-verify object start arrays
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp
index 9d721d6..ae92f36 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psMarkSweepDecorator.hpp
@@ -34,7 +34,7 @@
 
 class ObjectStartArray;
 
-class PSMarkSweepDecorator: public CHeapObj {
+class PSMarkSweepDecorator: public CHeapObj<mtGC> {
  private:
   static PSMarkSweepDecorator* _destination_decorator;
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp
index a46ac63..63df001 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -477,8 +477,8 @@
 }
 #endif
 
-void PSOldGen::verify(bool allow_dirty) {
-  object_space()->verify(allow_dirty);
+void PSOldGen::verify() {
+  object_space()->verify();
 }
 class VerifyObjectStartArrayClosure : public ObjectClosure {
   PSOldGen* _gen;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp
index 174db29..c07b381 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psOldGen.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -34,7 +34,7 @@
 
 class PSMarkSweepDecorator;
 
-class PSOldGen : public CHeapObj {
+class PSOldGen : public CHeapObj<mtGC> {
   friend class VMStructs;
   friend class PSPromotionManager; // Uses the cas_allocate methods
   friend class ParallelScavengeHeap;
@@ -174,7 +174,7 @@
   virtual void print_on(outputStream* st) const;
   void print_used_change(size_t prev_used) const;
 
-  void verify(bool allow_dirty);
+  void verify();
   void verify_object_start_array();
 
   // These should not used
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
index 354b3d0..195511d 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psParallelCompact.cpp
@@ -53,6 +53,7 @@
 #include "runtime/vmThread.hpp"
 #include "services/management.hpp"
 #include "services/memoryService.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/events.hpp"
 #include "utilities/stack.inline.hpp"
 
@@ -405,6 +406,9 @@
   ReservedSpace rs(bytes, rs_align, rs_align > 0);
   os::trace_page_sizes("par compact", raw_bytes, raw_bytes, page_sz, rs.base(),
                        rs.size());
+
+  MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
+
   PSVirtualSpace* vspace = new PSVirtualSpace(rs, page_sz);
   if (vspace != 0) {
     if (vspace->expand_by(bytes)) {
@@ -992,7 +996,7 @@
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
     gclog_or_tty->print(" VerifyBeforeGC:");
-    Universe::verify(true);
+    Universe::verify();
   }
 
   // Verify object start arrays
@@ -2047,17 +2051,9 @@
     gc_task_manager()->task_idle_workers();
     heap->set_par_threads(gc_task_manager()->active_workers());
 
-    const bool is_system_gc = gc_cause == GCCause::_java_lang_system_gc;
-
-    // This is useful for debugging but don't change the output the
-    // the customer sees.
-    const char* gc_cause_str = "Full GC";
-    if (is_system_gc && PrintGCDetails) {
-      gc_cause_str = "Full GC (System)";
-    }
     gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t1(gc_cause_str, PrintGC, !PrintGCDetails, gclog_or_tty);
+    TraceTime t1(GCCauseString("Full GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(true /* Full GC */,gc_cause);
 
@@ -2090,7 +2086,8 @@
     }
 #endif  // #ifndef PRODUCT
 
-    bool max_on_system_gc = UseMaximumCompactionOnSystemGC && is_system_gc;
+    bool max_on_system_gc = UseMaximumCompactionOnSystemGC
+      && gc_cause == GCCause::_java_lang_system_gc;
     summary_phase(vmthread_cm, maximum_heap_compaction || max_on_system_gc);
 
     COMPILER2_PRESENT(assert(DerivedPointerTable::is_active(), "Sanity"));
@@ -2215,7 +2212,7 @@
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
     gclog_or_tty->print(" VerifyAfterGC:");
-    Universe::verify(false);
+    Universe::verify();
   }
 
   // Re-verify object start arrays
@@ -2739,7 +2736,7 @@
   for (uint i = 0; i < ParallelGCThreads + 1; i++) {
     ParCompactionManager* cm = ParCompactionManager::manager_array(i);
     KeepAliveClosure keep_alive_closure(cm);
-    Stack<Klass*>* const rks = cm->revisit_klass_stack();
+    Stack<Klass*, mtGC>* const rks = cm->revisit_klass_stack();
     if (PrintRevisitStats) {
       gclog_or_tty->print_cr("Revisit klass stack[%u] length = " SIZE_FORMAT,
                              i, rks->size());
@@ -2772,7 +2769,7 @@
   }
   for (uint i = 0; i < ParallelGCThreads + 1; i++) {
     ParCompactionManager* cm = ParCompactionManager::manager_array(i);
-    Stack<DataLayout*>* rms = cm->revisit_mdo_stack();
+    Stack<DataLayout*, mtGC>* rms = cm->revisit_mdo_stack();
     if (PrintRevisitStats) {
       gclog_or_tty->print_cr("Revisit MDO stack[%u] size = " SIZE_FORMAT,
                              i, rms->size());
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp
index fd6a7bf..e11ce40 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionLAB.hpp
@@ -36,7 +36,7 @@
 
 class ObjectStartArray;
 
-class PSPromotionLAB : public CHeapObj {
+class PSPromotionLAB : public CHeapObj<mtGC> {
  protected:
   static size_t filler_header_size;
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
index f724969..b3f91d5 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.cpp
@@ -45,7 +45,7 @@
   _young_space = heap->young_gen()->to_space();
 
   assert(_manager_array == NULL, "Attempt to initialize twice");
-  _manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1 );
+  _manager_array = NEW_C_HEAP_ARRAY(PSPromotionManager*, ParallelGCThreads+1, mtGC);
   guarantee(_manager_array != NULL, "Could not initialize promotion manager");
 
   _stack_array_depth = new OopStarTaskQueueSet(ParallelGCThreads);
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
index 360640e..0e429ed 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.hpp
@@ -49,7 +49,7 @@
 class PSOldGen;
 class ParCompactionManager;
 
-class PSPromotionManager : public CHeapObj {
+class PSPromotionManager : public CHeapObj<mtGC> {
   friend class PSScavenge;
   friend class PSRefProcTaskExecutor;
  private:
@@ -77,7 +77,7 @@
   bool                                _old_gen_is_full;
 
   OopStarTaskQueue                    _claimed_stack_depth;
-  OverflowTaskQueue<oop>              _claimed_stack_breadth;
+  OverflowTaskQueue<oop, mtGC>        _claimed_stack_breadth;
 
   bool                                _totally_drain;
   uint                                _target_stack_size;
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
index 6c5da30..62216c2 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psPromotionManager.inline.hpp
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
 #define SHARE_VM_GC_IMPLEMENTATION_PARALLELSCAVENGE_PSPROMOTIONMANAGER_INLINE_HPP
 
+#include "gc_implementation/parallelScavenge/psOldGen.hpp"
 #include "gc_implementation/parallelScavenge/psPromotionManager.hpp"
 #include "gc_implementation/parallelScavenge/psScavenge.hpp"
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
index 984b1a4..fe674f8 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.cpp
@@ -62,8 +62,8 @@
 int                        PSScavenge::_tenuring_threshold = 0;
 HeapWord*                  PSScavenge::_young_generation_boundary = NULL;
 elapsedTimer               PSScavenge::_accumulated_time;
-Stack<markOop>             PSScavenge::_preserved_mark_stack;
-Stack<oop>                 PSScavenge::_preserved_oop_stack;
+Stack<markOop, mtGC>       PSScavenge::_preserved_mark_stack;
+Stack<oop, mtGC>           PSScavenge::_preserved_oop_stack;
 CollectorCounters*         PSScavenge::_counters = NULL;
 bool                       PSScavenge::_promotion_failed = false;
 
@@ -316,7 +316,7 @@
   if (VerifyBeforeGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
     gclog_or_tty->print(" VerifyBeforeGC:");
-    Universe::verify(true);
+    Universe::verify();
   }
 
   {
@@ -325,7 +325,7 @@
 
     gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t1("GC", PrintGC, !PrintGCDetails, gclog_or_tty);
+    TraceTime t1(GCCauseString("GC", gc_cause), PrintGC, !PrintGCDetails, gclog_or_tty);
     TraceCollectorStats tcs(counters());
     TraceMemoryManagerStats tms(false /* not full GC */,gc_cause);
 
@@ -646,7 +646,7 @@
   if (VerifyAfterGC && heap->total_collections() >= VerifyGCStartAt) {
     HandleMark hm;  // Discard invalid handles created during verification
     gclog_or_tty->print(" VerifyAfterGC:");
-    Universe::verify(false);
+    Universe::verify();
   }
 
   heap->print_heap_after_gc();
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
index 2ff201e..25416d0 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psScavenge.hpp
@@ -71,8 +71,8 @@
   static HeapWord*           _young_generation_boundary; // The lowest address possible for the young_gen.
                                                          // This is used to decide if an oop should be scavenged,
                                                          // cards should be marked, etc.
-  static Stack<markOop>          _preserved_mark_stack; // List of marks to be restored after failed promotion
-  static Stack<oop>              _preserved_oop_stack;  // List of oops that need their mark restored.
+  static Stack<markOop, mtGC> _preserved_mark_stack; // List of marks to be restored after failed promotion
+  static Stack<oop, mtGC>     _preserved_oop_stack;  // List of oops that need their mark restored.
   static CollectorCounters*      _counters;         // collector performance counters
   static bool                    _promotion_failed;
 
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp
index da452ca..b90ed97 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psVirtualspace.hpp
@@ -32,7 +32,7 @@
 // VirtualSpace is data structure for committing a previously reserved address
 // range in smaller chunks.
 
-class PSVirtualSpace : public CHeapObj {
+class PSVirtualSpace : public CHeapObj<mtGC> {
   friend class VMStructs;
  protected:
   // The space is committed/uncommited in chunks of size _alignment.  The
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp
index 5355abe..70c071d 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -937,10 +937,10 @@
   }
 }
 
-void PSYoungGen::verify(bool allow_dirty) {
-  eden_space()->verify(allow_dirty);
-  from_space()->verify(allow_dirty);
-  to_space()->verify(allow_dirty);
+void PSYoungGen::verify() {
+  eden_space()->verify();
+  from_space()->verify();
+  to_space()->verify();
 }
 
 #ifndef PRODUCT
diff --git a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp
index 640c761..7f1c297 100644
--- a/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp
+++ b/hotspot/src/share/vm/gc_implementation/parallelScavenge/psYoungGen.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 
 class PSMarkSweepDecorator;
 
-class PSYoungGen : public CHeapObj {
+class PSYoungGen : public CHeapObj<mtGC> {
   friend class VMStructs;
   friend class ParallelScavengeHeap;
   friend class AdjoiningGenerations;
@@ -181,7 +181,7 @@
   void print_used_change(size_t prev_used) const;
   virtual const char* name() const { return "PSYoungGen"; }
 
-  void verify(bool allow_dirty);
+  void verify();
 
   // Space boundary invariant checker
   void space_invariants() PRODUCT_RETURN;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp b/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp
index dd1895e..4becadc 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/adaptiveSizePolicy.hpp
@@ -38,7 +38,7 @@
 class elapsedTimer;
 class CollectorPolicy;
 
-class AdaptiveSizePolicy : public CHeapObj {
+class AdaptiveSizePolicy : public CHeapObj<mtGC> {
  friend class GCAdaptivePolicyCounters;
  friend class PSGCAdaptivePolicyCounters;
  friend class CMSGCAdaptivePolicyCounters;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp
index 1c94538..46f2537 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/allocationStats.hpp
@@ -39,7 +39,7 @@
   // We measure the demand between the end of the previous sweep and
   // beginning of this sweep:
   //   Count(end_last_sweep) - Count(start_this_sweep)
-  //     + splitBirths(between) - splitDeaths(between)
+  //     + split_births(between) - split_deaths(between)
   // The above number divided by the time since the end of the
   // previous sweep gives us a time rate of demand for blocks
   // of this size. We compute a padded average of this rate as
@@ -51,34 +51,34 @@
   AdaptivePaddedAverage _demand_rate_estimate;
 
   ssize_t     _desired;         // Demand stimate computed as described above
-  ssize_t     _coalDesired;     // desired +/- small-percent for tuning coalescing
+  ssize_t     _coal_desired;     // desired +/- small-percent for tuning coalescing
 
   ssize_t     _surplus;         // count - (desired +/- small-percent),
                                 // used to tune splitting in best fit
-  ssize_t     _bfrSurp;         // surplus at start of current sweep
-  ssize_t     _prevSweep;       // count from end of previous sweep
-  ssize_t     _beforeSweep;     // count from before current sweep
-  ssize_t     _coalBirths;      // additional chunks from coalescing
-  ssize_t     _coalDeaths;      // loss from coalescing
-  ssize_t     _splitBirths;     // additional chunks from splitting
-  ssize_t     _splitDeaths;     // loss from splitting
-  size_t      _returnedBytes;   // number of bytes returned to list.
+  ssize_t     _bfr_surp;         // surplus at start of current sweep
+  ssize_t     _prev_sweep;       // count from end of previous sweep
+  ssize_t     _before_sweep;     // count from before current sweep
+  ssize_t     _coal_births;      // additional chunks from coalescing
+  ssize_t     _coal_deaths;      // loss from coalescing
+  ssize_t     _split_births;     // additional chunks from splitting
+  ssize_t     _split_deaths;     // loss from splitting
+  size_t      _returned_bytes;   // number of bytes returned to list.
  public:
   void initialize(bool split_birth = false) {
     AdaptivePaddedAverage* dummy =
       new (&_demand_rate_estimate) AdaptivePaddedAverage(CMS_FLSWeight,
                                                          CMS_FLSPadding);
     _desired = 0;
-    _coalDesired = 0;
+    _coal_desired = 0;
     _surplus = 0;
-    _bfrSurp = 0;
-    _prevSweep = 0;
-    _beforeSweep = 0;
-    _coalBirths = 0;
-    _coalDeaths = 0;
-    _splitBirths = (split_birth ? 1 : 0);
-    _splitDeaths = 0;
-    _returnedBytes = 0;
+    _bfr_surp = 0;
+    _prev_sweep = 0;
+    _before_sweep = 0;
+    _coal_births = 0;
+    _coal_deaths = 0;
+    _split_births = (split_birth ? 1 : 0);
+    _split_deaths = 0;
+    _returned_bytes = 0;
   }
 
   AllocationStats() {
@@ -99,12 +99,12 @@
     // vulnerable to noisy glitches. In such cases, we
     // ignore the current sample and use currently available
     // historical estimates.
-    assert(prevSweep() + splitBirths() + coalBirths()        // "Total Production Stock"
-           >= splitDeaths() + coalDeaths() + (ssize_t)count, // "Current stock + depletion"
+    assert(prev_sweep() + split_births() + coal_births()        // "Total Production Stock"
+           >= split_deaths() + coal_deaths() + (ssize_t)count, // "Current stock + depletion"
            "Conservation Principle");
     if (inter_sweep_current > _threshold) {
-      ssize_t demand = prevSweep() - (ssize_t)count + splitBirths() + coalBirths()
-                       - splitDeaths() - coalDeaths();
+      ssize_t demand = prev_sweep() - (ssize_t)count + split_births() + coal_births()
+                       - split_deaths() - coal_deaths();
       assert(demand >= 0,
              err_msg("Demand (" SSIZE_FORMAT ") should be non-negative for "
                      PTR_FORMAT " (size=" SIZE_FORMAT ")",
@@ -130,40 +130,40 @@
   ssize_t desired() const { return _desired; }
   void set_desired(ssize_t v) { _desired = v; }
 
-  ssize_t coalDesired() const { return _coalDesired; }
-  void set_coalDesired(ssize_t v) { _coalDesired = v; }
+  ssize_t coal_desired() const { return _coal_desired; }
+  void set_coal_desired(ssize_t v) { _coal_desired = v; }
 
   ssize_t surplus() const { return _surplus; }
   void set_surplus(ssize_t v) { _surplus = v; }
   void increment_surplus() { _surplus++; }
   void decrement_surplus() { _surplus--; }
 
-  ssize_t bfrSurp() const { return _bfrSurp; }
-  void set_bfrSurp(ssize_t v) { _bfrSurp = v; }
-  ssize_t prevSweep() const { return _prevSweep; }
-  void set_prevSweep(ssize_t v) { _prevSweep = v; }
-  ssize_t beforeSweep() const { return _beforeSweep; }
-  void set_beforeSweep(ssize_t v) { _beforeSweep = v; }
+  ssize_t bfr_surp() const { return _bfr_surp; }
+  void set_bfr_surp(ssize_t v) { _bfr_surp = v; }
+  ssize_t prev_sweep() const { return _prev_sweep; }
+  void set_prev_sweep(ssize_t v) { _prev_sweep = v; }
+  ssize_t before_sweep() const { return _before_sweep; }
+  void set_before_sweep(ssize_t v) { _before_sweep = v; }
 
-  ssize_t coalBirths() const { return _coalBirths; }
-  void set_coalBirths(ssize_t v) { _coalBirths = v; }
-  void increment_coalBirths() { _coalBirths++; }
+  ssize_t coal_births() const { return _coal_births; }
+  void set_coal_births(ssize_t v) { _coal_births = v; }
+  void increment_coal_births() { _coal_births++; }
 
-  ssize_t coalDeaths() const { return _coalDeaths; }
-  void set_coalDeaths(ssize_t v) { _coalDeaths = v; }
-  void increment_coalDeaths() { _coalDeaths++; }
+  ssize_t coal_deaths() const { return _coal_deaths; }
+  void set_coal_deaths(ssize_t v) { _coal_deaths = v; }
+  void increment_coal_deaths() { _coal_deaths++; }
 
-  ssize_t splitBirths() const { return _splitBirths; }
-  void set_splitBirths(ssize_t v) { _splitBirths = v; }
-  void increment_splitBirths() { _splitBirths++; }
+  ssize_t split_births() const { return _split_births; }
+  void set_split_births(ssize_t v) { _split_births = v; }
+  void increment_split_births() { _split_births++; }
 
-  ssize_t splitDeaths() const { return _splitDeaths; }
-  void set_splitDeaths(ssize_t v) { _splitDeaths = v; }
-  void increment_splitDeaths() { _splitDeaths++; }
+  ssize_t split_deaths() const { return _split_deaths; }
+  void set_split_deaths(ssize_t v) { _split_deaths = v; }
+  void increment_split_deaths() { _split_deaths++; }
 
   NOT_PRODUCT(
-    size_t returnedBytes() const { return _returnedBytes; }
-    void set_returnedBytes(size_t v) { _returnedBytes = v; }
+    size_t returned_bytes() const { return _returned_bytes; }
+    void set_returned_bytes(size_t v) { _returned_bytes = v; }
   )
 };
 
diff --git a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp
index e682072..2319ca1 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.cpp
@@ -37,7 +37,7 @@
     const char* cns = PerfDataManager::name_space(gc->name_space(), "space",
                                                   ordinal);
 
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1);
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
     strcpy(_name_space, cns);
 
     const char* cname = PerfDataManager::counter_name(_name_space, "name");
diff --git a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp
index d4a860e..c113a33 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/cSpaceCounters.hpp
@@ -32,7 +32,7 @@
 // A CSpaceCounters is a holder class for performance counters
 // that track a space;
 
-class CSpaceCounters: public CHeapObj {
+class CSpaceCounters: public CHeapObj<mtGC> {
   friend class VMStructs;
 
  private:
@@ -52,7 +52,7 @@
                  ContiguousSpace* s, GenerationCounters* gc);
 
   ~CSpaceCounters() {
-      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtInternal);
   }
 
   inline void update_capacity() {
diff --git a/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp b/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp
index 91dad5e..d5aff5c 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.cpp
@@ -34,7 +34,7 @@
 
     const char* cns = PerfDataManager::name_space("collector", ordinal);
 
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1);
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
     strcpy(_name_space, cns);
 
     char* cname = PerfDataManager::counter_name(_name_space, "name");
diff --git a/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp
index b793f7b..52eb443 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/collectorCounters.hpp
@@ -30,7 +30,7 @@
 // CollectorCounters is a holder class for performance counters
 // that track a collector
 
-class CollectorCounters: public CHeapObj {
+class CollectorCounters: public CHeapObj<mtGC> {
   friend class VMStructs;
 
   private:
@@ -50,7 +50,7 @@
     CollectorCounters(const char* name, int ordinal);
 
     ~CollectorCounters() {
-      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+      if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
     }
 
     inline PerfCounter* invocation_counter() const  { return _invocations; }
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp b/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp
index 3d95950..00a9670 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.cpp
@@ -41,7 +41,7 @@
     const char* cns = PerfDataManager::name_space(gc->name_space(), "space",
                                                   ordinal);
 
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1);
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
     strcpy(_name_space, cns);
 
     const char* cname = PerfDataManager::counter_name(_name_space, "name");
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
index 85764c4..8b901e2 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/gSpaceCounters.hpp
@@ -34,7 +34,7 @@
 // A GSpaceCounter is a holder class for performance counters
 // that track a space;
 
-class GSpaceCounters: public CHeapObj {
+class GSpaceCounters: public CHeapObj<mtGC> {
   friend class VMStructs;
 
  private:
@@ -54,7 +54,7 @@
                  GenerationCounters* gc, bool sampled=true);
 
   ~GSpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
   }
 
   inline void update_capacity() {
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp
index 6d4494c..10a7bac 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcPolicyCounters.hpp
@@ -30,7 +30,7 @@
 // GCPolicyCounters is a holder class for performance counters
 // that track a generation
 
-class GCPolicyCounters: public CHeapObj {
+class GCPolicyCounters: public CHeapObj<mtGC> {
   friend class VMStructs;
 
   private:
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp
index 070300e..af16ca6 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcStats.hpp
@@ -27,7 +27,7 @@
 
 #include "gc_implementation/shared/gcUtil.hpp"
 
-class GCStats : public CHeapObj {
+class GCStats : public CHeapObj<mtGC> {
  protected:
   // Avg amount promoted; used for avoiding promotion undo
   // This class does not update deviations if the sample is zero.
diff --git a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp
index 86daba6..ba97f7c 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/gcUtil.hpp
@@ -43,7 +43,7 @@
 //
 // This serves as our best estimate of a future unknown.
 //
-class AdaptiveWeightedAverage : public CHeapObj {
+class AdaptiveWeightedAverage : public CHeapObj<mtGC> {
  private:
   float            _average;        // The last computed average
   unsigned         _sample_count;   // How often we've sampled this average
@@ -146,7 +146,7 @@
   // Placement support
   void* operator new(size_t ignored, void* p) { return p; }
   // Allocator
-  void* operator new(size_t size) { return CHeapObj::operator new(size); }
+  void* operator new(size_t size) { return CHeapObj<mtGC>::operator new(size); }
 
   // Accessor
   float padded_average() const         { return _padded_avg; }
@@ -192,7 +192,7 @@
 // equation.
 //              y = intercept + slope * x
 
-class LinearLeastSquareFit : public CHeapObj {
+class LinearLeastSquareFit : public CHeapObj<mtGC> {
   double _sum_x;        // sum of all independent data points x
   double _sum_x_squared; // sum of all independent data points x**2
   double _sum_y;        // sum of all dependent data points y
diff --git a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp
index 68ab6ff..8cbfac1 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.cpp
@@ -35,7 +35,7 @@
 
     const char* cns = PerfDataManager::name_space("generation", ordinal);
 
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1);
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
     strcpy(_name_space, cns);
 
     const char* cname = PerfDataManager::counter_name(_name_space, "name");
diff --git a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp
index f399b95..78c0076 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/generationCounters.hpp
@@ -31,7 +31,7 @@
 // A GenerationCounter is a holder class for performance counters
 // that track a generation
 
-class GenerationCounters: public CHeapObj {
+class GenerationCounters: public CHeapObj<mtGC> {
   friend class VMStructs;
 
 private:
@@ -69,7 +69,7 @@
                      VirtualSpace* v);
 
   ~GenerationCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
   }
 
   virtual void update_all();
diff --git a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.cpp b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.cpp
index 17a69fa..cc4cccb 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.cpp
@@ -40,7 +40,7 @@
     const char* cns =
       PerfDataManager::name_space(gc->name_space(), "space", ordinal);
 
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1);
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
     strcpy(_name_space, cns);
 
     const char* cname = PerfDataManager::counter_name(_name_space, "name");
diff --git a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
index a55d443..d33a103 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/hSpaceCounters.hpp
@@ -37,7 +37,7 @@
 class HeapSpaceUsedHelper;
 class G1SpaceMonitoringSupport;
 
-class HSpaceCounters: public CHeapObj {
+class HSpaceCounters: public CHeapObj<mtGC> {
   friend class VMStructs;
 
  private:
@@ -55,7 +55,7 @@
                  size_t initial_capacity, GenerationCounters* gc);
 
   ~HSpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
   }
 
   inline void update_capacity(size_t v) {
diff --git a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp
index de08165..68af9eb 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -70,7 +70,7 @@
 
 #endif
 
-void ImmutableSpace::verify(bool allow_dirty) {
+void ImmutableSpace::verify() {
   HeapWord* p = bottom();
   HeapWord* t = end();
   HeapWord* prev_p = NULL;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp
index bc5c1bd..6152e64 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/immutableSpace.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
 // Invariant: bottom() and end() are on page_size boundaries and
 // bottom() <= end()
 
-class ImmutableSpace: public CHeapObj {
+class ImmutableSpace: public CHeapObj<mtGC> {
   friend class VMStructs;
  protected:
   HeapWord* _bottom;
@@ -65,7 +65,7 @@
   // Debugging
   virtual void print() const            PRODUCT_RETURN;
   virtual void print_short() const      PRODUCT_RETURN;
-  virtual void verify(bool allow_dirty);
+  virtual void verify();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_IMMUTABLESPACE_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
index 584c24c..7767829 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.cpp
@@ -30,13 +30,13 @@
 #include "oops/objArrayKlass.inline.hpp"
 #include "oops/oop.inline.hpp"
 
-Stack<oop>              MarkSweep::_marking_stack;
-Stack<DataLayout*>      MarkSweep::_revisit_mdo_stack;
-Stack<Klass*>           MarkSweep::_revisit_klass_stack;
-Stack<ObjArrayTask>     MarkSweep::_objarray_stack;
+Stack<oop, mtGC>              MarkSweep::_marking_stack;
+Stack<DataLayout*, mtGC>      MarkSweep::_revisit_mdo_stack;
+Stack<Klass*, mtGC>           MarkSweep::_revisit_klass_stack;
+Stack<ObjArrayTask, mtGC>     MarkSweep::_objarray_stack;
 
-Stack<oop>              MarkSweep::_preserved_oop_stack;
-Stack<markOop>          MarkSweep::_preserved_mark_stack;
+Stack<oop, mtGC>              MarkSweep::_preserved_oop_stack;
+Stack<markOop, mtGC>          MarkSweep::_preserved_mark_stack;
 size_t                  MarkSweep::_preserved_count = 0;
 size_t                  MarkSweep::_preserved_count_max = 0;
 PreservedMark*          MarkSweep::_preserved_marks = NULL;
@@ -166,7 +166,7 @@
   }
 
   // deal with the overflow stack
-  StackIterator<oop> iter(_preserved_oop_stack);
+  StackIterator<oop, mtGC> iter(_preserved_oop_stack);
   while (!iter.is_empty()) {
     oop* p = iter.next_addr();
     adjust_pointer(p);
diff --git a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
index 19bee0e..4decbdd 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/markSweep.hpp
@@ -122,16 +122,16 @@
   //
  protected:
   // Traversal stacks used during phase1
-  static Stack<oop>                      _marking_stack;
-  static Stack<ObjArrayTask>             _objarray_stack;
+  static Stack<oop, mtGC>                      _marking_stack;
+  static Stack<ObjArrayTask, mtGC>             _objarray_stack;
   // Stack for live klasses to revisit at end of marking phase
-  static Stack<Klass*>                   _revisit_klass_stack;
+  static Stack<Klass*, mtGC>                   _revisit_klass_stack;
   // Set (stack) of MDO's to revisit at end of marking phase
-  static Stack<DataLayout*>              _revisit_mdo_stack;
+  static Stack<DataLayout*, mtGC>              _revisit_mdo_stack;
 
   // Space for storing/restoring mark word
-  static Stack<markOop>                  _preserved_mark_stack;
-  static Stack<oop>                      _preserved_oop_stack;
+  static Stack<markOop, mtGC>                  _preserved_mark_stack;
+  static Stack<oop, mtGC>                      _preserved_oop_stack;
   static size_t                          _preserved_count;
   static size_t                          _preserved_count_max;
   static PreservedMark*                  _preserved_marks;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
index 706fd37..d930b00 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.cpp
@@ -43,7 +43,7 @@
 
 
 MutableNUMASpace::MutableNUMASpace(size_t alignment) : MutableSpace(alignment) {
-  _lgrp_spaces = new (ResourceObj::C_HEAP) GrowableArray<LGRPSpace*>(0, true);
+  _lgrp_spaces = new (ResourceObj::C_HEAP, mtGC) GrowableArray<LGRPSpace*>(0, true);
   _page_size = os::vm_page_size();
   _adaptation_cycles = 0;
   _samples_count = 0;
@@ -231,7 +231,7 @@
   if (force || changed) {
     // Compute lgrp intersection. Add/remove spaces.
     int lgrp_limit = (int)os::numa_get_groups_num();
-    int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit);
+    int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtGC);
     int lgrp_num = (int)os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
     assert(lgrp_num > 0, "There should be at least one locality group");
     // Add new spaces for the new nodes
@@ -265,7 +265,7 @@
       }
     }
 
-    FREE_C_HEAP_ARRAY(int, lgrp_ids);
+    FREE_C_HEAP_ARRAY(int, lgrp_ids, mtGC);
 
     if (changed) {
       for (JavaThread *thread = Threads::first(); thread; thread = thread->next()) {
@@ -891,12 +891,12 @@
   }
 }
 
-void MutableNUMASpace::verify(bool allow_dirty) {
+void MutableNUMASpace::verify() {
   // This can be called after setting an arbitary value to the space's top,
   // so an object can cross the chunk boundary. We ensure the parsablity
   // of the space and just walk the objects in linear fashion.
   ensure_parsability();
-  MutableSpace::verify(allow_dirty);
+  MutableSpace::verify();
 }
 
 // Scan pages and gather stats about page placement and size.
diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
index 7b70e6e..8b8f8d6 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableNUMASpace.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -63,7 +63,7 @@
 class MutableNUMASpace : public MutableSpace {
   friend class VMStructs;
 
-  class LGRPSpace : public CHeapObj {
+  class LGRPSpace : public CHeapObj<mtGC> {
     int _lgrp_id;
     MutableSpace* _space;
     MemRegion _invalid_region;
@@ -225,7 +225,7 @@
   // Debugging
   virtual void print_on(outputStream* st) const;
   virtual void print_short_on(outputStream* st) const;
-  virtual void verify(bool allow_dirty);
+  virtual void verify();
 
   virtual void set_top(HeapWord* value);
 };
diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp
index 9725c4a..c47fbec 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -246,7 +246,7 @@
                  bottom(), top(), end());
 }
 
-void MutableSpace::verify(bool allow_dirty) {
+void MutableSpace::verify() {
   HeapWord* p = bottom();
   HeapWord* t = top();
   HeapWord* prev_p = NULL;
diff --git a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp
index 01fb23f..9ef8922 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/mutableSpace.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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,7 +141,7 @@
   virtual void print_on(outputStream* st) const;
   virtual void print_short() const;
   virtual void print_short_on(outputStream* st) const;
-  virtual void verify(bool allow_dirty);
+  virtual void verify();
 };
 
 #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_MUTABLESPACE_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
similarity index 95%
rename from hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp
rename to hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
index 466d2f6..87f7448 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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,7 +23,7 @@
  */
 
 #include "precompiled.hpp"
-#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
+#include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "memory/sharedHeap.hpp"
 #include "oops/arrayOop.hpp"
 #include "oops/oop.inline.hpp"
@@ -87,10 +87,17 @@
 // Compute desired plab size and latch result for later
 // use. This should be called once at the end of parallel
 // scavenge; it clears the sensor accumulators.
-void PLABStats::adjust_desired_plab_sz() {
+void PLABStats::adjust_desired_plab_sz(uint no_of_gc_workers) {
   assert(ResizePLAB, "Not set");
   if (_allocated == 0) {
-    assert(_unused == 0, "Inconsistency in PLAB stats");
+    assert(_unused == 0,
+           err_msg("Inconsistency in PLAB stats: "
+                   "_allocated: "SIZE_FORMAT", "
+                   "_wasted: "SIZE_FORMAT", "
+                   "_unused: "SIZE_FORMAT", "
+                   "_used  : "SIZE_FORMAT,
+                   _allocated, _wasted, _unused, _used));
+
     _allocated = 1;
   }
   double wasted_frac    = (double)_unused/(double)_allocated;
@@ -100,7 +107,7 @@
     target_refills = 1;
   }
   _used = _allocated - _wasted - _unused;
-  size_t plab_sz = _used/(target_refills*ParallelGCThreads);
+  size_t plab_sz = _used/(target_refills*no_of_gc_workers);
   if (PrintPLAB) gclog_or_tty->print(" (plab_sz = %d ", plab_sz);
   // Take historical weighted average
   _filter.sample(plab_sz);
@@ -110,9 +117,7 @@
   plab_sz = align_object_size(plab_sz);
   // Latch the result
   if (PrintPLAB) gclog_or_tty->print(" desired_plab_sz = %d) ", plab_sz);
-  if (ResizePLAB) {
-    _desired_plab_sz = plab_sz;
-  }
+  _desired_plab_sz = plab_sz;
   // Now clear the accumulators for next round:
   // note this needs to be fixed in the case where we
   // are retaining across scavenges. FIX ME !!! XXX
diff --git a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
similarity index 89%
rename from hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp
rename to hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
index 6d1504a..0666353 100644
--- a/hotspot/src/share/vm/gc_implementation/parNew/parGCAllocBuffer.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/parGCAllocBuffer.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -35,7 +35,7 @@
 class PLABStats;
 
 // A per-thread allocation buffer used during GC.
-class ParGCAllocBuffer: public CHeapObj {
+class ParGCAllocBuffer: public CHeapObj<mtGC> {
 protected:
   char head[32];
   size_t _word_sz;          // in HeapWord units
@@ -52,6 +52,10 @@
   static size_t FillerHeaderSize;
   static size_t AlignmentReserve;
 
+  // Flush the stats supporting ergonomic sizing of PLAB's
+  // Should not be called directly
+  void flush_stats(PLABStats* stats);
+
 public:
   // Initializes the buffer to be empty, but with the given "word_sz".
   // Must get initialized with "set_buf" for an allocation to succeed.
@@ -120,15 +124,25 @@
   }
 
   // Flush the stats supporting ergonomic sizing of PLAB's
-  void flush_stats(PLABStats* stats);
-  void flush_stats_and_retire(PLABStats* stats, bool retain) {
+  // and retire the current buffer.
+  void flush_stats_and_retire(PLABStats* stats, bool end_of_gc, bool retain) {
     // We flush the stats first in order to get a reading of
     // unused space in the last buffer.
     if (ResizePLAB) {
       flush_stats(stats);
+
+      // Since we have flushed the stats we need to clear
+      // the _allocated and _wasted fields. Not doing so
+      // will artifically inflate the values in the stats
+      // to which we add them.
+      // The next time we flush these values, we will add
+      // what we have just flushed in addition to the size
+      // of the buffers allocated between now and then.
+      _allocated = 0;
+      _wasted = 0;
     }
     // Retire the last allocation buffer.
-    retire(true, retain);
+    retire(end_of_gc, retain);
   }
 
   // Force future allocations to fail and queries for contains()
@@ -190,7 +204,8 @@
     return _desired_plab_sz;
   }
 
-  void adjust_desired_plab_sz(); // filter computation, latches output to
+  void adjust_desired_plab_sz(uint no_of_gc_workers);
+                                 // filter computation, latches output to
                                  // _desired_plab_sz, clears sensor accumulators
 
   void add_allocated(size_t v) {
diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp b/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp
index a5815c9..44fc6e1 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.cpp
@@ -39,7 +39,7 @@
     const char* cns = PerfDataManager::name_space(gc->name_space(), "space",
                                                   ordinal);
 
-    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1);
+    _name_space = NEW_C_HEAP_ARRAY(char, strlen(cns)+1, mtGC);
     strcpy(_name_space, cns);
 
     const char* cname = PerfDataManager::counter_name(_name_space, "name");
diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp b/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp
index f75a9f2..1369ee0 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/spaceCounters.hpp
@@ -35,7 +35,7 @@
 // A SpaceCounter is a holder class for performance counters
 // that track a space;
 
-class SpaceCounters: public CHeapObj {
+class SpaceCounters: public CHeapObj<mtGC> {
   friend class VMStructs;
 
  private:
@@ -55,7 +55,7 @@
                 MutableSpace* m, GenerationCounters* gc);
 
   ~SpaceCounters() {
-    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space);
+    if (_name_space != NULL) FREE_C_HEAP_ARRAY(char, _name_space, mtGC);
   }
 
   inline void update_capacity() {
diff --git a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp
index c41a5eb..513735d 100644
--- a/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp
+++ b/hotspot/src/share/vm/gc_implementation/shared/spaceDecorator.hpp
@@ -70,7 +70,7 @@
 // These subclasses abstract the differences in the types of spaces used
 // by each heap.
 
-class SpaceMangler: public CHeapObj {
+class SpaceMangler: public CHeapObj<mtGC> {
   friend class VMStructs;
 
   // High water mark for allocations.  Typically, the space above
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
index 21dd6c5..d986d76 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.cpp
@@ -333,7 +333,7 @@
 
   // Set the length first for concurrent GC.
   ((arrayOop)start)->set_length((int)len);
-  post_allocation_setup_common(Universe::intArrayKlassObj(), start, words);
+  post_allocation_setup_common(Universe::intArrayKlassObj(), start);
   DEBUG_ONLY(zap_filler_array(start, words, zap);)
 }
 
@@ -346,8 +346,7 @@
     fill_with_array(start, words, zap);
   } else if (words > 0) {
     assert(words == min_fill_size(), "unaligned size");
-    post_allocation_setup_common(SystemDictionary::Object_klass(), start,
-                                 words);
+    post_allocation_setup_common(SystemDictionary::Object_klass(), start);
   }
 }
 
@@ -477,7 +476,7 @@
     assert(ScavengeRootsInCode > 0, "must be");
     obj = common_mem_allocate_init(size, CHECK_NULL);
   }
-  post_allocation_setup_common(klass, obj, size);
+  post_allocation_setup_common(klass, obj);
   assert(Universe::is_bootstrapping() ||
          !((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
index 8fe7014..be42500 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.hpp
@@ -74,7 +74,7 @@
 //     G1CollectedHeap
 //   ParallelScavengeHeap
 //
-class CollectedHeap : public CHeapObj {
+class CollectedHeap : public CHeapObj<mtInternal> {
   friend class VMStructs;
   friend class IsGCActiveMark; // Block structured external access to _is_gc_active
   friend class constantPoolCacheKlass; // allocate() method inserts is_conc_safe
@@ -149,18 +149,14 @@
   inline static HeapWord* common_permanent_mem_allocate_init(size_t size, TRAPS);
 
   // Helper functions for (VM) allocation.
-  inline static void post_allocation_setup_common(KlassHandle klass,
-                                                  HeapWord* obj, size_t size);
+  inline static void post_allocation_setup_common(KlassHandle klass, HeapWord* obj);
   inline static void post_allocation_setup_no_klass_install(KlassHandle klass,
-                                                            HeapWord* objPtr,
-                                                            size_t size);
+                                                            HeapWord* objPtr);
 
-  inline static void post_allocation_setup_obj(KlassHandle klass,
-                                               HeapWord* obj, size_t size);
+  inline static void post_allocation_setup_obj(KlassHandle klass, HeapWord* obj);
 
   inline static void post_allocation_setup_array(KlassHandle klass,
-                                                 HeapWord* obj, size_t size,
-                                                 int length);
+                                                 HeapWord* obj, int length);
 
   // Clears an allocated object.
   inline static void init_obj(HeapWord* obj, size_t size);
@@ -368,9 +364,7 @@
   inline static oop permanent_obj_allocate_no_klass_install(KlassHandle klass,
                                                             int size,
                                                             TRAPS);
-  inline static void post_allocation_install_obj_klass(KlassHandle klass,
-                                                       oop obj,
-                                                       int size);
+  inline static void post_allocation_install_obj_klass(KlassHandle klass, oop obj);
   inline static oop permanent_array_allocate(KlassHandle klass, int size, int length, TRAPS);
 
   // Raw memory allocation facilities
@@ -664,11 +658,8 @@
     }
   }
 
-  // Allocate GCHeapLog during VM startup
-  static void initialize_heap_log();
-
   // Heap verification
-  virtual void verify(bool allow_dirty, bool silent, VerifyOption option) = 0;
+  virtual void verify(bool silent, VerifyOption option) = 0;
 
   // Non product verification and debugging.
 #ifndef PRODUCT
diff --git a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
index adced06..4ac7185 100644
--- a/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
+++ b/hotspot/src/share/vm/gc_interface/collectedHeap.inline.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -50,15 +50,13 @@
 // Inline allocation implementations.
 
 void CollectedHeap::post_allocation_setup_common(KlassHandle klass,
-                                                 HeapWord* obj,
-                                                 size_t size) {
-  post_allocation_setup_no_klass_install(klass, obj, size);
-  post_allocation_install_obj_klass(klass, oop(obj), (int) size);
+                                                 HeapWord* obj) {
+  post_allocation_setup_no_klass_install(klass, obj);
+  post_allocation_install_obj_klass(klass, oop(obj));
 }
 
 void CollectedHeap::post_allocation_setup_no_klass_install(KlassHandle klass,
-                                                           HeapWord* objPtr,
-                                                           size_t size) {
+                                                           HeapWord* objPtr) {
   oop obj = (oop)objPtr;
 
   assert(obj != NULL, "NULL object pointer");
@@ -71,8 +69,7 @@
 }
 
 void CollectedHeap::post_allocation_install_obj_klass(KlassHandle klass,
-                                                   oop obj,
-                                                   int size) {
+                                                   oop obj) {
   // These asserts are kind of complicated because of klassKlass
   // and the beginning of the world.
   assert(klass() != NULL || !Universe::is_fully_initialized(), "NULL klass");
@@ -101,9 +98,8 @@
 }
 
 void CollectedHeap::post_allocation_setup_obj(KlassHandle klass,
-                                              HeapWord* obj,
-                                              size_t size) {
-  post_allocation_setup_common(klass, obj, size);
+                                              HeapWord* obj) {
+  post_allocation_setup_common(klass, obj);
   assert(Universe::is_bootstrapping() ||
          !((oop)obj)->blueprint()->oop_is_array(), "must not be an array");
   // notify jvmti and dtrace
@@ -112,14 +108,13 @@
 
 void CollectedHeap::post_allocation_setup_array(KlassHandle klass,
                                                 HeapWord* obj,
-                                                size_t size,
                                                 int length) {
   // Set array length before setting the _klass field
   // in post_allocation_setup_common() because the klass field
   // indicates that the object is parsable by concurrent GC.
   assert(length >= 0, "length should be non-negative");
   ((arrayOop)obj)->set_length(length);
-  post_allocation_setup_common(klass, obj, size);
+  post_allocation_setup_common(klass, obj);
   assert(((oop)obj)->blueprint()->oop_is_array(), "must be an array");
   // notify jvmti and dtrace (must be after length is set for dtrace)
   post_allocation_notify(klass, (oop)obj);
@@ -256,7 +251,7 @@
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
-  post_allocation_setup_obj(klass, obj, size);
+  post_allocation_setup_obj(klass, obj);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
 }
@@ -269,7 +264,7 @@
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_mem_allocate_init(size, CHECK_NULL);
-  post_allocation_setup_array(klass, obj, size, length);
+  post_allocation_setup_array(klass, obj, length);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
 }
@@ -283,7 +278,7 @@
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_mem_allocate_noinit(size, CHECK_NULL);
   ((oop)obj)->set_klass_gap(0);
-  post_allocation_setup_array(klass, obj, size, length);
+  post_allocation_setup_array(klass, obj, length);
 #ifndef PRODUCT
   const size_t hs = oopDesc::header_size()+1;
   Universe::heap()->check_for_non_bad_heap_word_value(obj+hs, size-hs);
@@ -293,7 +288,7 @@
 
 oop CollectedHeap::permanent_obj_allocate(KlassHandle klass, int size, TRAPS) {
   oop obj = permanent_obj_allocate_no_klass_install(klass, size, CHECK_NULL);
-  post_allocation_install_obj_klass(klass, obj, size);
+  post_allocation_install_obj_klass(klass, obj);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value((HeapWord*) obj,
                                                               size));
   return obj;
@@ -306,7 +301,7 @@
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
-  post_allocation_setup_no_klass_install(klass, obj, size);
+  post_allocation_setup_no_klass_install(klass, obj);
 #ifndef PRODUCT
   const size_t hs = oopDesc::header_size();
   Universe::heap()->check_for_bad_heap_word_value(obj+hs, size-hs);
@@ -322,7 +317,7 @@
   assert(!Universe::heap()->is_gc_active(), "Allocation during gc not allowed");
   assert(size >= 0, "int won't convert to size_t");
   HeapWord* obj = common_permanent_mem_allocate_init(size, CHECK_NULL);
-  post_allocation_setup_array(klass, obj, size, length);
+  post_allocation_setup_array(klass, obj, length);
   NOT_PRODUCT(Universe::heap()->check_for_bad_heap_word_value(obj, size));
   return (oop)obj;
 }
diff --git a/hotspot/src/share/vm/gc_interface/gcCause.hpp b/hotspot/src/share/vm/gc_interface/gcCause.hpp
index ae14115..8866d76 100644
--- a/hotspot/src/share/vm/gc_interface/gcCause.hpp
+++ b/hotspot/src/share/vm/gc_interface/gcCause.hpp
@@ -88,4 +88,36 @@
   static const char* to_string(GCCause::Cause cause);
 };
 
+// Helper class for doing logging that includes the GC Cause
+// as a string.
+class GCCauseString : StackObj {
+ private:
+   static const int _length = 128;
+   char _buffer[_length];
+   int _position;
+
+ public:
+   GCCauseString(const char* prefix, GCCause::Cause cause) {
+     if (PrintGCCause) {
+      _position = jio_snprintf(_buffer, _length, "%s (%s)", prefix, GCCause::to_string(cause));
+     } else {
+      _position = jio_snprintf(_buffer, _length, "%s", prefix);
+     }
+     assert(_position >= 0 && _position <= _length,
+       err_msg("Need to increase the buffer size in GCCauseString? %d", _position));
+   }
+
+   GCCauseString& append(const char* str) {
+     int res = jio_snprintf(_buffer + _position, _length - _position, "%s", str);
+     _position += res;
+     assert(res >= 0 && _position <= _length,
+       err_msg("Need to increase the buffer size in GCCauseString? %d", res));
+     return *this;
+   }
+
+   operator const char*() {
+     return _buffer;
+   }
+};
+
 #endif // SHARE_VM_GC_INTERFACE_GCCAUSE_HPP
diff --git a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp
index a68fac1..b941e6f 100644
--- a/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp
+++ b/hotspot/src/share/vm/interpreter/abstractInterpreter.hpp
@@ -99,7 +99,10 @@
     empty,                                                      // empty method (code: _return)
     accessor,                                                   // accessor method (code: _aload_0, _getfield, _(a|i)return)
     abstract,                                                   // abstract method (throws an AbstractMethodException)
-    method_handle,                                              // java.lang.invoke.MethodHandles::invoke
+    method_handle_invoke_FIRST,                                 // java.lang.invoke.MethodHandles::invokeExact, etc.
+    method_handle_invoke_LAST                                   = (method_handle_invoke_FIRST
+                                                                   + (vmIntrinsics::LAST_MH_SIG_POLY
+                                                                      - vmIntrinsics::FIRST_MH_SIG_POLY)),
     java_lang_math_sin,                                         // implementation of java.lang.Math.sin   (x)
     java_lang_math_cos,                                         // implementation of java.lang.Math.cos   (x)
     java_lang_math_tan,                                         // implementation of java.lang.Math.tan   (x)
@@ -107,11 +110,21 @@
     java_lang_math_sqrt,                                        // implementation of java.lang.Math.sqrt  (x)
     java_lang_math_log,                                         // implementation of java.lang.Math.log   (x)
     java_lang_math_log10,                                       // implementation of java.lang.Math.log10 (x)
+    java_lang_math_pow,                                         // implementation of java.lang.Math.pow   (x,y)
+    java_lang_math_exp,                                         // implementation of java.lang.Math.exp   (x)
     java_lang_ref_reference_get,                                // implementation of java.lang.ref.Reference.get()
     number_of_method_entries,
     invalid = -1
   };
 
+  // Conversion from the part of the above enum to vmIntrinsics::_invokeExact, etc.
+  static vmIntrinsics::ID method_handle_intrinsic(MethodKind kind) {
+    if (kind >= method_handle_invoke_FIRST && kind <= method_handle_invoke_LAST)
+      return (vmIntrinsics::ID)( vmIntrinsics::FIRST_MH_SIG_POLY + (kind - method_handle_invoke_FIRST) );
+    else
+      return vmIntrinsics::_none;
+  }
+
   enum SomeConstants {
     number_of_result_handlers = 10                              // number of result handlers for native calls
   };
@@ -146,6 +159,9 @@
   static address    entry_for_kind(MethodKind k)                { assert(0 <= k && k < number_of_method_entries, "illegal kind"); return _entry_table[k]; }
   static address    entry_for_method(methodHandle m)            { return entry_for_kind(method_kind(m)); }
 
+  // used for bootstrapping method handles:
+  static void       set_entry_for_kind(MethodKind k, address e);
+
   static void       print_method_kind(MethodKind kind)          PRODUCT_RETURN;
 
   static bool       can_be_compiled(methodHandle m);
diff --git a/hotspot/src/share/vm/interpreter/bytecode.cpp b/hotspot/src/share/vm/interpreter/bytecode.cpp
index eefc72e..49d6331 100644
--- a/hotspot/src/share/vm/interpreter/bytecode.cpp
+++ b/hotspot/src/share/vm/interpreter/bytecode.cpp
@@ -120,19 +120,22 @@
 
 void Bytecode_invoke::verify() const {
   assert(is_valid(), "check invoke");
-  assert(method()->constants()->cache() != NULL, "do not call this from verifier or rewriter");
+  assert(cpcache() != NULL, "do not call this from verifier or rewriter");
 }
 
 
-Symbol* Bytecode_member_ref::signature() const {
-  constantPoolOop constants = method()->constants();
-  return constants->signature_ref_at(index());
+Symbol* Bytecode_member_ref::klass() const {
+  return constants()->klass_ref_at_noresolve(index());
 }
 
 
 Symbol* Bytecode_member_ref::name() const {
-  constantPoolOop constants = method()->constants();
-  return constants->name_ref_at(index());
+  return constants()->name_ref_at(index());
+}
+
+
+Symbol* Bytecode_member_ref::signature() const {
+  return constants()->signature_ref_at(index());
 }
 
 
@@ -146,18 +149,19 @@
 methodHandle Bytecode_invoke::static_target(TRAPS) {
   methodHandle m;
   KlassHandle resolved_klass;
-  constantPoolHandle constants(THREAD, _method->constants());
+  constantPoolHandle constants(THREAD, this->constants());
 
-  if (java_code() == Bytecodes::_invokedynamic) {
-    LinkResolver::resolve_dynamic_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
-  } else if (java_code() != Bytecodes::_invokeinterface) {
-    LinkResolver::resolve_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
-  } else {
-    LinkResolver::resolve_interface_method(m, resolved_klass, constants, index(), CHECK_(methodHandle()));
-  }
+  Bytecodes::Code bc = invoke_code();
+  LinkResolver::resolve_method_statically(m, resolved_klass, bc, constants, index(), CHECK_(methodHandle()));
   return m;
 }
 
+Handle Bytecode_invoke::appendix(TRAPS) {
+  ConstantPoolCacheEntry* cpce = cpcache_entry();
+  if (cpce->has_appendix())
+    return Handle(THREAD, cpce->f1_appendix());
+  return Handle();  // usual case
+}
 
 int Bytecode_member_ref::index() const {
   // Note:  Rewriter::rewrite changes the Java_u2 of an invokedynamic to a native_u4,
@@ -170,12 +174,16 @@
 }
 
 int Bytecode_member_ref::pool_index() const {
+  return cpcache_entry()->constant_pool_index();
+}
+
+ConstantPoolCacheEntry* Bytecode_member_ref::cpcache_entry() const {
   int index = this->index();
   DEBUG_ONLY({
       if (!has_index_u4(code()))
-        index -= constantPoolOopDesc::CPCACHE_INDEX_TAG;
+        index = constantPoolOopDesc::get_cpcache_index(index);
     });
-  return _method->constants()->cache()->entry_at(index)->constant_pool_index();
+  return cpcache()->entry_at(index);
 }
 
 // Implementation of Bytecode_field
diff --git a/hotspot/src/share/vm/interpreter/bytecode.hpp b/hotspot/src/share/vm/interpreter/bytecode.hpp
index 107161a..fa202bd 100644
--- a/hotspot/src/share/vm/interpreter/bytecode.hpp
+++ b/hotspot/src/share/vm/interpreter/bytecode.hpp
@@ -80,6 +80,7 @@
 
   Bytecodes::Code code() const                   { return _code; }
   Bytecodes::Code java_code() const              { return Bytecodes::java_code(code()); }
+  Bytecodes::Code invoke_code() const            { return (code() == Bytecodes::_invokehandle) ? code() : java_code(); }
 
   // Static functions for parsing bytecodes in place.
   int get_index_u1(Bytecodes::Code bc) const {
@@ -195,10 +196,14 @@
   Bytecode_member_ref(methodHandle method, int bci)  : Bytecode(method(), method()->bcp_from(bci)), _method(method) {}
 
   methodHandle method() const                    { return _method; }
+  constantPoolOop constants() const              { return _method->constants(); }
+  constantPoolCacheOop cpcache() const           { return _method->constants()->cache(); }
+  ConstantPoolCacheEntry* cpcache_entry() const;
 
  public:
   int          index() const;                    // cache index (loaded from instruction)
   int          pool_index() const;               // constant pool index
+  Symbol*      klass() const;                    // returns the klass of the method or field
   Symbol*      name() const;                     // returns the name of the method or field
   Symbol*      signature() const;                // returns the signature of the method or field
 
@@ -218,13 +223,15 @@
 
   // Attributes
   methodHandle static_target(TRAPS);             // "specified" method   (from constant pool)
+  Handle       appendix(TRAPS);                  // if CPCE::has_appendix (from constant pool)
 
   // Testers
-  bool is_invokeinterface() const                { return java_code() == Bytecodes::_invokeinterface; }
-  bool is_invokevirtual() const                  { return java_code() == Bytecodes::_invokevirtual; }
-  bool is_invokestatic() const                   { return java_code() == Bytecodes::_invokestatic; }
-  bool is_invokespecial() const                  { return java_code() == Bytecodes::_invokespecial; }
-  bool is_invokedynamic() const                  { return java_code() == Bytecodes::_invokedynamic; }
+  bool is_invokeinterface() const                { return invoke_code() == Bytecodes::_invokeinterface; }
+  bool is_invokevirtual() const                  { return invoke_code() == Bytecodes::_invokevirtual; }
+  bool is_invokestatic() const                   { return invoke_code() == Bytecodes::_invokestatic; }
+  bool is_invokespecial() const                  { return invoke_code() == Bytecodes::_invokespecial; }
+  bool is_invokedynamic() const                  { return invoke_code() == Bytecodes::_invokedynamic; }
+  bool is_invokehandle() const                   { return invoke_code() == Bytecodes::_invokehandle; }
 
   bool has_receiver() const                      { return !is_invokestatic() && !is_invokedynamic(); }
 
@@ -232,15 +239,12 @@
                                                           is_invokevirtual()   ||
                                                           is_invokestatic()    ||
                                                           is_invokespecial()   ||
-                                                          is_invokedynamic(); }
+                                                          is_invokedynamic()   ||
+                                                          is_invokehandle(); }
 
-  bool is_method_handle_invoke() const {
-    return (is_invokedynamic() ||
-            (is_invokevirtual() &&
-             method()->constants()->klass_ref_at_noresolve(index()) == vmSymbols::java_lang_invoke_MethodHandle() &&
-             methodOopDesc::is_method_handle_invoke_name(name())));
-  }
+  bool has_appendix()                            { return cpcache_entry()->has_appendix(); }
 
+ private:
   // Helper to skip verification.   Used is_valid() to check if the result is really an invoke
   inline friend Bytecode_invoke Bytecode_invoke_check(methodHandle method, int bci);
 };
diff --git a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
index 68bd1c7..eaa41762 100644
--- a/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
+++ b/hotspot/src/share/vm/interpreter/bytecodeInterpreter.cpp
@@ -1774,7 +1774,7 @@
 
           oop obj;
           if ((Bytecodes::Code)opcode == Bytecodes::_getstatic) {
-            obj = (oop) cache->f1();
+            obj = (oop) cache->f1_as_instance();
             MORE_STACK(1);  // Assume single slot push
           } else {
             obj = (oop) STACK_OBJECT(-1);
@@ -1785,7 +1785,7 @@
           // Now store the result on the stack
           //
           TosState tos_type = cache->flag_state();
-          int field_offset = cache->f2();
+          int field_offset = cache->f2_as_index();
           if (cache->is_volatile()) {
             if (tos_type == atos) {
               VERIFY_OOP(obj->obj_field_acquire(field_offset));
@@ -1885,7 +1885,7 @@
             --count;
           }
           if ((Bytecodes::Code)opcode == Bytecodes::_putstatic) {
-            obj = (oop) cache->f1();
+            obj = (oop) cache->f1_as_instance();
           } else {
             --count;
             obj = (oop) STACK_OBJECT(count);
@@ -1895,7 +1895,7 @@
           //
           // Now store the result
           //
-          int field_offset = cache->f2();
+          int field_offset = cache->f2_as_index();
           if (cache->is_volatile()) {
             if (tos_type == itos) {
               obj->release_int_field_put(field_offset, STACK_INT(-1));
@@ -2177,13 +2177,15 @@
         // This kind of CP cache entry does not need to match the flags byte, because
         // there is a 1-1 relation between bytecode type and CP entry type.
         ConstantPoolCacheEntry* cache = cp->entry_at(index);
-        if (cache->is_f1_null()) {
+        oop result = cache->f1_as_instance();
+        if (result == NULL) {
           CALL_VM(InterpreterRuntime::resolve_ldc(THREAD, (Bytecodes::Code) opcode),
                   handle_exception);
+          result = cache->f1_as_instance();
         }
 
-        VERIFY_OOP(cache->f1());
-        SET_STACK_OBJECT(cache->f1(), 0);
+        VERIFY_OOP(result);
+        SET_STACK_OBJECT(result, 0);
         UPDATE_PC_AND_TOS_AND_CONTINUE(incr, 1);
       }
 
@@ -2204,13 +2206,15 @@
         // there is a 1-1 relation between bytecode type and CP entry type.
         assert(constantPoolCacheOopDesc::is_secondary_index(index), "incorrect format");
         ConstantPoolCacheEntry* cache = cp->secondary_entry_at(index);
-        if (cache->is_f1_null()) {
+        oop result = cache->f1_as_instance();
+        if (result == NULL) {
           CALL_VM(InterpreterRuntime::resolve_invokedynamic(THREAD),
                   handle_exception);
+          result = cache->f1_as_instance();
         }
 
-        VERIFY_OOP(cache->f1());
-        oop method_handle = java_lang_invoke_CallSite::target(cache->f1());
+        VERIFY_OOP(result);
+        oop method_handle = java_lang_invoke_CallSite::target(result);
         CHECK_NULL(method_handle);
 
         istate->set_msg(call_method_handle);
@@ -2239,11 +2243,11 @@
         // java.lang.Object.  See cpCacheOop.cpp for details.
         // This code isn't produced by javac, but could be produced by
         // another compliant java compiler.
-        if (cache->is_methodInterface()) {
+        if (cache->is_forced_virtual()) {
           methodOop callee;
           CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
           if (cache->is_vfinal()) {
-            callee = (methodOop) cache->f2();
+            callee = cache->f2_as_vfinal_method();
           } else {
             // get receiver
             int parms = cache->parameter_size();
@@ -2251,7 +2255,7 @@
             VERIFY_OOP(STACK_OBJECT(-parms));
             instanceKlass* rcvrKlass = (instanceKlass*)
                                  STACK_OBJECT(-parms)->klass()->klass_part();
-            callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()];
+            callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2_as_index()];
           }
           istate->set_callee(callee);
           istate->set_callee_entry_point(callee->from_interpreted_entry());
@@ -2266,7 +2270,7 @@
 
         // this could definitely be cleaned up QQQ
         methodOop callee;
-        klassOop iclass = (klassOop)cache->f1();
+        klassOop iclass = cache->f1_as_klass();
         // instanceKlass* interface = (instanceKlass*) iclass->klass_part();
         // get receiver
         int parms = cache->parameter_size();
@@ -2284,7 +2288,7 @@
         if (i == int2->itable_length()) {
           VM_JAVA_ERROR(vmSymbols::java_lang_IncompatibleClassChangeError(), "");
         }
-        int mindex = cache->f2();
+        int mindex = cache->f2_as_index();
         itableMethodEntry* im = ki->first_method_entry(rcvr->klass());
         callee = im[mindex].method();
         if (callee == NULL) {
@@ -2322,12 +2326,12 @@
           methodOop callee;
           if ((Bytecodes::Code)opcode == Bytecodes::_invokevirtual) {
             CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
-            if (cache->is_vfinal()) callee = (methodOop) cache->f2();
+            if (cache->is_vfinal()) callee = cache->f2_as_vfinal_method();
             else {
               // get receiver
               int parms = cache->parameter_size();
               // this works but needs a resourcemark and seems to create a vtable on every call:
-              // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2());
+              // methodOop callee = rcvr->klass()->klass_part()->vtable()->method_at(cache->f2_as_index());
               //
               // this fails with an assert
               // instanceKlass* rcvrKlass = instanceKlass::cast(STACK_OBJECT(-parms)->klass());
@@ -2350,13 +2354,13 @@
                   However it seems to have a vtable in the right location. Huh?
 
               */
-              callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2()];
+              callee = (methodOop) rcvrKlass->start_of_vtable()[ cache->f2_as_index()];
             }
           } else {
             if ((Bytecodes::Code)opcode == Bytecodes::_invokespecial) {
               CHECK_NULL(STACK_OBJECT(-(cache->parameter_size())));
             }
-            callee = (methodOop) cache->f1();
+            callee = cache->f1_as_method();
           }
 
           istate->set_callee(callee);
diff --git a/hotspot/src/share/vm/interpreter/bytecodes.cpp b/hotspot/src/share/vm/interpreter/bytecodes.cpp
index 5e4b9dc..ee842f4 100644
--- a/hotspot/src/share/vm/interpreter/bytecodes.cpp
+++ b/hotspot/src/share/vm/interpreter/bytecodes.cpp
@@ -534,6 +534,8 @@
 
   def(_return_register_finalizer , "return_register_finalizer" , "b"    , NULL    , T_VOID   ,  0, true, _return);
 
+  def(_invokehandle        , "invokehandle"        , "bJJ"  , NULL    , T_ILLEGAL, -1, true, _invokevirtual   );
+
   def(_fast_aldc           , "fast_aldc"           , "bj"   , NULL    , T_OBJECT,   1, true,  _ldc   );
   def(_fast_aldc_w         , "fast_aldc_w"         , "bJJ"  , NULL    , T_OBJECT,   1, true,  _ldc_w );
 
diff --git a/hotspot/src/share/vm/interpreter/bytecodes.hpp b/hotspot/src/share/vm/interpreter/bytecodes.hpp
index 2ea7336..4cd078a 100644
--- a/hotspot/src/share/vm/interpreter/bytecodes.hpp
+++ b/hotspot/src/share/vm/interpreter/bytecodes.hpp
@@ -282,6 +282,9 @@
 
     _return_register_finalizer    ,
 
+    // special handling of signature-polymorphic methods:
+    _invokehandle         ,
+
     _shouldnotreachhere,      // For debugging
 
     // Platform specific JVM bytecodes
@@ -356,8 +359,8 @@
 
  public:
   // Conversion
-  static void        check          (Code code)    { assert(is_defined(code), "illegal code"); }
-  static void        wide_check     (Code code)    { assert(wide_is_defined(code), "illegal code"); }
+  static void        check          (Code code)    { assert(is_defined(code),      err_msg("illegal code: %d", (int)code)); }
+  static void        wide_check     (Code code)    { assert(wide_is_defined(code), err_msg("illegal code: %d", (int)code)); }
   static Code        cast           (int  code)    { return (Code)code; }
 
 
@@ -421,6 +424,8 @@
                                                            || code == _fconst_0 || code == _dconst_0); }
   static bool        is_invoke      (Code code)    { return (_invokevirtual <= code && code <= _invokedynamic); }
 
+  static bool        has_optional_appendix(Code code) { return code == _invokedynamic || code == _invokehandle; }
+
   static int         compute_flags  (const char* format, int more_flags = 0);  // compute the flags
   static int         flags          (int code, bool is_wide) {
     assert(code == (u_char)code, "must be a byte");
diff --git a/hotspot/src/share/vm/interpreter/interpreter.cpp b/hotspot/src/share/vm/interpreter/interpreter.cpp
index 137f50e..1645a33 100644
--- a/hotspot/src/share/vm/interpreter/interpreter.cpp
+++ b/hotspot/src/share/vm/interpreter/interpreter.cpp
@@ -37,6 +37,7 @@
 #include "oops/oop.inline.hpp"
 #include "prims/forte.hpp"
 #include "prims/jvmtiExport.hpp"
+#include "prims/methodHandles.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/sharedRuntime.hpp"
 #include "runtime/stubRoutines.hpp"
@@ -59,6 +60,8 @@
 
 
 void InterpreterCodelet::print_on(outputStream* st) const {
+  ttyLocker ttyl;
+
   if (PrintInterpreter) {
     st->cr();
     st->print_cr("----------------------------------------------------------------------");
@@ -71,7 +74,7 @@
 
   if (PrintInterpreter) {
     st->cr();
-    Disassembler::decode(code_begin(), code_end(), st);
+    Disassembler::decode(code_begin(), code_end(), st, DEBUG_ONLY(_comments) NOT_DEBUG(CodeComments()));
   }
 }
 
@@ -180,14 +183,21 @@
   // Abstract method?
   if (m->is_abstract()) return abstract;
 
-  // Invoker for method handles?
-  if (m->is_method_handle_invoke())  return method_handle;
+  // Method handle primitive?
+  if (m->is_method_handle_intrinsic()) {
+    vmIntrinsics::ID id = m->intrinsic_id();
+    assert(MethodHandles::is_signature_polymorphic(id), "must match an intrinsic");
+    MethodKind kind = (MethodKind)( method_handle_invoke_FIRST +
+                                    ((int)id - vmIntrinsics::FIRST_MH_SIG_POLY) );
+    assert(kind <= method_handle_invoke_LAST, "parallel enum ranges");
+    return kind;
+  }
 
   // Native method?
   // Note: This test must come _before_ the test for intrinsic
   //       methods. See also comments below.
   if (m->is_native()) {
-    assert(!m->is_method_handle_invoke(), "overlapping bits here, watch out");
+    assert(!m->is_method_handle_intrinsic(), "overlapping bits here, watch out");
     return m->is_synchronized() ? native_synchronized : native;
   }
 
@@ -221,6 +231,8 @@
     case vmIntrinsics::_dsqrt : return java_lang_math_sqrt ;
     case vmIntrinsics::_dlog  : return java_lang_math_log  ;
     case vmIntrinsics::_dlog10: return java_lang_math_log10;
+    case vmIntrinsics::_dpow  : return java_lang_math_pow  ;
+    case vmIntrinsics::_dexp  : return java_lang_math_exp  ;
 
     case vmIntrinsics::_Reference_get:
                                 return java_lang_ref_reference_get;
@@ -237,6 +249,14 @@
 }
 
 
+void AbstractInterpreter::set_entry_for_kind(AbstractInterpreter::MethodKind kind, address entry) {
+  assert(kind >= method_handle_invoke_FIRST &&
+         kind <= method_handle_invoke_LAST, "late initialization only for MH entry points");
+  assert(_entry_table[kind] == _entry_table[abstract], "previous value must be AME entry");
+  _entry_table[kind] = entry;
+}
+
+
 // Return true if the interpreter can prove that the given bytecode has
 // not yet been executed (in Java semantics, not in actual operation).
 bool AbstractInterpreter::is_not_reached(methodHandle method, int bci) {
@@ -268,7 +288,6 @@
     case empty                  : tty->print("empty"                  ); break;
     case accessor               : tty->print("accessor"               ); break;
     case abstract               : tty->print("abstract"               ); break;
-    case method_handle          : tty->print("method_handle"          ); break;
     case java_lang_math_sin     : tty->print("java_lang_math_sin"     ); break;
     case java_lang_math_cos     : tty->print("java_lang_math_cos"     ); break;
     case java_lang_math_tan     : tty->print("java_lang_math_tan"     ); break;
@@ -276,7 +295,16 @@
     case java_lang_math_sqrt    : tty->print("java_lang_math_sqrt"    ); break;
     case java_lang_math_log     : tty->print("java_lang_math_log"     ); break;
     case java_lang_math_log10   : tty->print("java_lang_math_log10"   ); break;
-    default                     : ShouldNotReachHere();
+    default:
+      if (kind >= method_handle_invoke_FIRST &&
+          kind <= method_handle_invoke_LAST) {
+        const char* kind_name = vmIntrinsics::name_at(method_handle_intrinsic(kind));
+        if (kind_name[0] == '_')  kind_name = &kind_name[1];  // '_invokeExact' => 'invokeExact'
+        tty->print("method_handle_%s", kind_name);
+        break;
+      }
+      ShouldNotReachHere();
+      break;
   }
 }
 #endif // PRODUCT
diff --git a/hotspot/src/share/vm/interpreter/interpreter.hpp b/hotspot/src/share/vm/interpreter/interpreter.hpp
index 0ab0be7..478edb1 100644
--- a/hotspot/src/share/vm/interpreter/interpreter.hpp
+++ b/hotspot/src/share/vm/interpreter/interpreter.hpp
@@ -48,10 +48,12 @@
   int         _size;                             // the size in bytes
   const char* _description;                      // a description of the codelet, for debugging & printing
   Bytecodes::Code _bytecode;                     // associated bytecode if any
+  DEBUG_ONLY(CodeComments _comments;)            // Comments for annotating assembler output.
 
  public:
   // Initialization/finalization
-  void    initialize(int size)                   { _size = size; }
+  void    initialize(int size,
+                     CodeComments& comments)     { _size = size; DEBUG_ONLY(_comments.assign(comments);) }
   void    finalize()                             { ShouldNotCallThis(); }
 
   // General info/converters
@@ -129,7 +131,7 @@
 
 
     // commit Codelet
-    AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size());
+    AbstractInterpreter::code()->commit((*_masm)->code()->pure_insts_size(), (*_masm)->code()->comments());
     // make sure nobody can use _masm outside a CodeletMark lifespan
     *_masm = NULL;
   }
diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
index 6f5511f..52b718a 100644
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -145,7 +145,7 @@
     // The bytecode wrappers aren't GC-safe so construct a new one
     Bytecode_loadconstant ldc2(m, bci(thread));
     ConstantPoolCacheEntry* cpce = m->constants()->cache()->entry_at(ldc2.cache_index());
-    assert(result == cpce->f1(), "expected result for assembly code");
+    assert(result == cpce->f1_as_instance(), "expected result for assembly code");
   }
 #endif
 }
@@ -375,7 +375,6 @@
   Handle             h_exception(thread, exception);
   methodHandle       h_method   (thread, method(thread));
   constantPoolHandle h_constants(thread, h_method->constants());
-  typeArrayHandle    h_extable  (thread, h_method->exception_table());
   bool               should_repeat;
   int                handler_bci;
   int                current_bci = bci(thread);
@@ -547,23 +546,6 @@
     }
   }
 
-  if (is_put && !is_static && klass->is_subclass_of(SystemDictionary::CallSite_klass()) && (info.name() == vmSymbols::target_name())) {
-    const jint direction = frame::interpreter_frame_expression_stack_direction();
-    Handle call_site    (THREAD, *((oop*) thread->last_frame().interpreter_frame_tos_at(-1 * direction)));
-    Handle method_handle(THREAD, *((oop*) thread->last_frame().interpreter_frame_tos_at( 0 * direction)));
-    assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "must be");
-    assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
-
-    {
-      // Walk all nmethods depending on this call site.
-      MutexLocker mu(Compile_lock, thread);
-      Universe::flush_dependents_on(call_site, method_handle);
-    }
-
-    // Don't allow fast path for setting CallSite.target and sub-classes.
-    put_code = (Bytecodes::Code) 0;
-  }
-
   cache_entry(thread)->set_field(
     get_code,
     put_code,
@@ -674,7 +656,7 @@
   JvmtiExport::post_raw_breakpoint(thread, method, bcp);
 IRT_END
 
-IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode))
+IRT_ENTRY(void, InterpreterRuntime::resolve_invoke(JavaThread* thread, Bytecodes::Code bytecode)) {
   // extract receiver from the outgoing argument list if necessary
   Handle receiver(thread, NULL);
   if (bytecode == Bytecodes::_invokevirtual || bytecode == Bytecodes::_invokeinterface) {
@@ -742,86 +724,58 @@
       info.resolved_method(),
       info.vtable_index());
   }
+}
+IRT_END
+
+
+// First time execution:  Resolve symbols, create a permanent MethodType object.
+IRT_ENTRY(void, InterpreterRuntime::resolve_invokehandle(JavaThread* thread)) {
+  assert(EnableInvokeDynamic, "");
+  const Bytecodes::Code bytecode = Bytecodes::_invokehandle;
+
+  // resolve method
+  CallInfo info;
+  constantPoolHandle pool(thread, method(thread)->constants());
+
+  {
+    JvmtiHideSingleStepping jhss(thread);
+    LinkResolver::resolve_invoke(info, Handle(), pool,
+                                 get_index_u2_cpcache(thread, bytecode), bytecode, CHECK);
+  } // end JvmtiHideSingleStepping
+
+  cache_entry(thread)->set_method_handle(
+      pool,
+      info.resolved_method(),
+      info.resolved_appendix(),
+      info.resolved_method_type());
+}
 IRT_END
 
 
 // First time execution:  Resolve symbols, create a permanent CallSite object.
 IRT_ENTRY(void, InterpreterRuntime::resolve_invokedynamic(JavaThread* thread)) {
-  ResourceMark rm(thread);
-
   assert(EnableInvokeDynamic, "");
-
   const Bytecodes::Code bytecode = Bytecodes::_invokedynamic;
 
-  methodHandle caller_method(thread, method(thread));
+  //TO DO: consider passing BCI to Java.
+  //  int caller_bci = method(thread)->bci_from(bcp(thread));
 
-  constantPoolHandle pool(thread, caller_method->constants());
-  pool->set_invokedynamic();    // mark header to flag active call sites
+  // resolve method
+  CallInfo info;
+  constantPoolHandle pool(thread, method(thread)->constants());
+  int index = get_index_u4(thread, bytecode);
 
-  int caller_bci = 0;
-  int site_index = 0;
-  { address caller_bcp = bcp(thread);
-    caller_bci = caller_method->bci_from(caller_bcp);
-    site_index = Bytes::get_native_u4(caller_bcp+1);
-  }
-  assert(site_index == InterpreterRuntime::bytecode(thread).get_index_u4(bytecode), "");
-  assert(constantPoolCacheOopDesc::is_secondary_index(site_index), "proper format");
-  // there is a second CPC entries that is of interest; it caches signature info:
-  int main_index = pool->cache()->secondary_entry_at(site_index)->main_entry_index();
-  int pool_index = pool->cache()->entry_at(main_index)->constant_pool_index();
-
-  // first resolve the signature to a MH.invoke methodOop
-  if (!pool->cache()->entry_at(main_index)->is_resolved(bytecode)) {
+  {
     JvmtiHideSingleStepping jhss(thread);
-    CallInfo callinfo;
-    LinkResolver::resolve_invoke(callinfo, Handle(), pool,
-                                 site_index, bytecode, CHECK);
-    // The main entry corresponds to a JVM_CONSTANT_InvokeDynamic, and serves
-    // as a common reference point for all invokedynamic call sites with
-    // that exact call descriptor.  We will link it in the CP cache exactly
-    // as if it were an invokevirtual of MethodHandle.invoke.
-    pool->cache()->entry_at(main_index)->set_method(
-      bytecode,
-      callinfo.resolved_method(),
-      callinfo.vtable_index());
-  }
+    LinkResolver::resolve_invoke(info, Handle(), pool,
+                                 index, bytecode, CHECK);
+  } // end JvmtiHideSingleStepping
 
-  // The method (f2 entry) of the main entry is the MH.invoke for the
-  // invokedynamic target call signature.
-  oop f1_value = pool->cache()->entry_at(main_index)->f1();
-  methodHandle signature_invoker(THREAD, (methodOop) f1_value);
-  assert(signature_invoker.not_null() && signature_invoker->is_method() && signature_invoker->is_method_handle_invoke(),
-         "correct result from LinkResolver::resolve_invokedynamic");
-
-  Handle info;  // optional argument(s) in JVM_CONSTANT_InvokeDynamic
-  Handle bootm = SystemDictionary::find_bootstrap_method(caller_method, caller_bci,
-                                                         main_index, info, CHECK);
-  if (!java_lang_invoke_MethodHandle::is_instance(bootm())) {
-    THROW_MSG(vmSymbols::java_lang_IllegalStateException(),
-              "no bootstrap method found for invokedynamic");
-  }
-
-  // Short circuit if CallSite has been bound already:
-  if (!pool->cache()->secondary_entry_at(site_index)->is_f1_null())
-    return;
-
-  Symbol*  call_site_name = pool->name_ref_at(site_index);
-
-  Handle call_site
-    = SystemDictionary::make_dynamic_call_site(bootm,
-                                               // Callee information:
-                                               call_site_name,
-                                               signature_invoker,
-                                               info,
-                                               // Caller information:
-                                               caller_method,
-                                               caller_bci,
-                                               CHECK);
-
-  // In the secondary entry, the f1 field is the call site, and the f2 (index)
-  // field is some data about the invoke site.  Currently, it is just the BCI.
-  // Later, it might be changed to help manage inlining dependencies.
-  pool->cache()->secondary_entry_at(site_index)->set_dynamic_call(call_site, signature_invoker);
+  pool->cache()->secondary_entry_at(index)->set_dynamic_call(
+      pool,
+      info.resolved_method(),
+      info.resolved_appendix(),
+      info.resolved_method_type());
 }
 IRT_END
 
@@ -993,7 +947,7 @@
 
   // check the access_flags for the field in the klass
 
-  instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1()));
+  instanceKlass* ik = instanceKlass::cast(java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror()));
   int index = cp_entry->field_index();
   if ((ik->field_access_flags(index) & JVM_ACC_FIELD_ACCESS_WATCHED) == 0) return;
 
@@ -1016,15 +970,15 @@
     // non-static field accessors have an object, but we need a handle
     h_obj = Handle(thread, obj);
   }
-  instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1()));
-  jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2(), is_static);
+  instanceKlassHandle h_cp_entry_f1(thread, java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror()));
+  jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_cp_entry_f1, cp_entry->f2_as_index(), is_static);
   JvmtiExport::post_field_access(thread, method(thread), bcp(thread), h_cp_entry_f1, h_obj, fid);
 IRT_END
 
 IRT_ENTRY(void, InterpreterRuntime::post_field_modification(JavaThread *thread,
   oopDesc* obj, ConstantPoolCacheEntry *cp_entry, jvalue *value))
 
-  klassOop k = java_lang_Class::as_klassOop(cp_entry->f1());
+  klassOop k = java_lang_Class::as_klassOop(cp_entry->f1_as_klass_mirror());
 
   // check the access_flags for the field in the klass
   instanceKlass* ik = instanceKlass::cast(k);
@@ -1049,7 +1003,7 @@
 
   HandleMark hm(thread);
   instanceKlassHandle h_klass(thread, k);
-  jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2(), is_static);
+  jfieldID fid = jfieldIDWorkaround::to_jfieldID(h_klass, cp_entry->f2_as_index(), is_static);
   jvalue fvalue;
 #ifdef _LP64
   fvalue = *value;
@@ -1118,8 +1072,8 @@
                                       SignatureHandlerLibrary::buffer_size);
   _buffer = bb->code_begin();
 
-  _fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true);
-  _handlers     = new(ResourceObj::C_HEAP)GrowableArray<address>(32, true);
+  _fingerprints = new(ResourceObj::C_HEAP, mtCode)GrowableArray<uint64_t>(32, true);
+  _handlers     = new(ResourceObj::C_HEAP, mtCode)GrowableArray<address>(32, true);
 }
 
 address SignatureHandlerLibrary::set_handler(CodeBuffer* buffer) {
diff --git a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp
index 93c1a9e..7ec8e49 100644
--- a/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp
+++ b/hotspot/src/share/vm/interpreter/interpreterRuntime.hpp
@@ -71,6 +71,8 @@
                                                         { return bytecode(thread).get_index_u2(bc); }
   static int       get_index_u2_cpcache(JavaThread *thread, Bytecodes::Code bc)
                                                         { return bytecode(thread).get_index_u2_cpcache(bc); }
+  static int       get_index_u4(JavaThread *thread, Bytecodes::Code bc)
+                                                        { return bytecode(thread).get_index_u4(bc); }
   static int       number_of_dimensions(JavaThread *thread)  { return bcp(thread)[3]; }
 
   static ConstantPoolCacheEntry* cache_entry_at(JavaThread *thread, int i)  { return method(thread)->constants()->cache()->entry_at(i); }
@@ -118,6 +120,7 @@
 
   // Calls
   static void    resolve_invoke       (JavaThread* thread, Bytecodes::Code bytecode);
+  static void    resolve_invokehandle (JavaThread* thread);
   static void    resolve_invokedynamic(JavaThread* thread);
 
   // Breakpoints
diff --git a/hotspot/src/share/vm/interpreter/linkResolver.cpp b/hotspot/src/share/vm/interpreter/linkResolver.cpp
index b7defd7..2472067 100644
--- a/hotspot/src/share/vm/interpreter/linkResolver.cpp
+++ b/hotspot/src/share/vm/interpreter/linkResolver.cpp
@@ -96,15 +96,22 @@
 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
   assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index");
   set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
+  assert(!resolved_method->is_compiled_lambda_form(), "these must be handled via an invokehandle call");
 }
 
-void CallInfo::set_dynamic(methodHandle resolved_method, TRAPS) {
-  assert(resolved_method->is_method_handle_invoke(), "");
+void CallInfo::set_handle(methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS) {
+  if (resolved_method.is_null()) {
+    THROW_MSG(vmSymbols::java_lang_InternalError(), "resolved method is null");
+  }
   KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
-  assert(resolved_klass == resolved_method->method_holder(), "");
+  assert(resolved_method->intrinsic_id() == vmIntrinsics::_invokeBasic ||
+         resolved_method->is_compiled_lambda_form(),
+         "linkMethod must return one of these");
   int vtable_index = methodOopDesc::nonvirtual_vtable_index;
   assert(resolved_method->vtable_index() == vtable_index, "");
-  set_common(resolved_klass, KlassHandle(), resolved_method, resolved_method, vtable_index, CHECK);
+  set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
+  _resolved_appendix    = resolved_appendix;
+  _resolved_method_type = resolved_method_type;
 }
 
 void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
@@ -114,6 +121,7 @@
   _resolved_method = resolved_method;
   _selected_method = selected_method;
   _vtable_index    = vtable_index;
+  _resolved_appendix = Handle();
   if (CompilationPolicy::must_be_compiled(selected_method)) {
     // This path is unusual, mostly used by the '-Xcomp' stress test mode.
 
@@ -180,11 +188,9 @@
 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) {
   methodOop result_oop = klass->uncached_lookup_method(name, signature);
   if (EnableInvokeDynamic && result_oop != NULL) {
-    switch (result_oop->intrinsic_id()) {
-    case vmIntrinsics::_invokeExact:
-    case vmIntrinsics::_invokeGeneric:
-    case vmIntrinsics::_invokeDynamic:
-      // Do not link directly to these.  The VM must produce a synthetic one using lookup_implicit_method.
+    vmIntrinsics::ID iid = result_oop->intrinsic_id();
+    if (MethodHandles::is_signature_polymorphic(iid)) {
+      // Do not link directly to these.  The VM must produce a synthetic one using lookup_polymorphic_method.
       return;
     }
   }
@@ -213,31 +219,101 @@
   result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature));
 }
 
-void LinkResolver::lookup_implicit_method(methodHandle& result,
-                                          KlassHandle klass, Symbol* name, Symbol* signature,
-                                          KlassHandle current_klass,
-                                          TRAPS) {
+void LinkResolver::lookup_polymorphic_method(methodHandle& result,
+                                             KlassHandle klass, Symbol* name, Symbol* full_signature,
+                                             KlassHandle current_klass,
+                                             Handle *appendix_result_or_null,
+                                             Handle *method_type_result,
+                                             TRAPS) {
+  vmIntrinsics::ID iid = MethodHandles::signature_polymorphic_name_id(name);
+  if (TraceMethodHandles) {
+    tty->print_cr("lookup_polymorphic_method iid=%s %s.%s%s",
+                  vmIntrinsics::name_at(iid), klass->external_name(),
+                  name->as_C_string(), full_signature->as_C_string());
+  }
   if (EnableInvokeDynamic &&
       klass() == SystemDictionary::MethodHandle_klass() &&
-      methodOopDesc::is_method_handle_invoke_name(name)) {
-    if (!THREAD->is_Compiler_thread() && !MethodHandles::enabled()) {
-      // Make sure the Java part of the runtime has been booted up.
-      klassOop natives = SystemDictionary::MethodHandleNatives_klass();
-      if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
-        SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(),
-                                          Handle(),
-                                          Handle(),
-                                          true,
-                                          CHECK);
+      iid != vmIntrinsics::_none) {
+    if (MethodHandles::is_signature_polymorphic_intrinsic(iid)) {
+      // Most of these do not need an up-call to Java to resolve, so can be done anywhere.
+      // Do not erase last argument type (MemberName) if it is a static linkTo method.
+      bool keep_last_arg = MethodHandles::is_signature_polymorphic_static(iid);
+      TempNewSymbol basic_signature =
+        MethodHandles::lookup_basic_type_signature(full_signature, keep_last_arg, CHECK);
+      if (TraceMethodHandles) {
+        tty->print_cr("lookup_polymorphic_method %s %s => basic %s",
+                      name->as_C_string(),
+                      full_signature->as_C_string(),
+                      basic_signature->as_C_string());
       }
-    }
-    methodOop result_oop = SystemDictionary::find_method_handle_invoke(name,
-                                                                       signature,
-                                                                       current_klass,
-                                                                       CHECK);
-    if (result_oop != NULL) {
-      assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature, "consistent");
-      result = methodHandle(THREAD, result_oop);
+      result = SystemDictionary::find_method_handle_intrinsic(iid,
+                                                              basic_signature,
+                                                              CHECK);
+      if (result.not_null()) {
+        assert(result->is_method_handle_intrinsic(), "MH.invokeBasic or MH.linkTo* intrinsic");
+        assert(result->intrinsic_id() != vmIntrinsics::_invokeGeneric, "wrong place to find this");
+        assert(basic_signature == result->signature(), "predict the result signature");
+        if (TraceMethodHandles) {
+          tty->print("lookup_polymorphic_method => intrinsic ");
+          result->print_on(tty);
+        }
+        return;
+      }
+    } else if (iid == vmIntrinsics::_invokeGeneric
+               && !THREAD->is_Compiler_thread()
+               && appendix_result_or_null != NULL) {
+      // This is a method with type-checking semantics.
+      // We will ask Java code to spin an adapter method for it.
+      if (!MethodHandles::enabled()) {
+        // Make sure the Java part of the runtime has been booted up.
+        klassOop natives = SystemDictionary::MethodHandleNatives_klass();
+        if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) {
+          SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(),
+                                            Handle(),
+                                            Handle(),
+                                            true,
+                                            CHECK);
+        }
+      }
+
+      Handle appendix;
+      Handle method_type;
+      result = SystemDictionary::find_method_handle_invoker(name,
+                                                            full_signature,
+                                                            current_klass,
+                                                            &appendix,
+                                                            &method_type,
+                                                            CHECK);
+      if (TraceMethodHandles) {
+        tty->print("lookup_polymorphic_method => (via Java) ");
+        result->print_on(tty);
+        tty->print("  lookup_polymorphic_method => appendix = ");
+        if (appendix.is_null())  tty->print_cr("(none)");
+        else                     appendix->print_on(tty);
+      }
+      if (result.not_null()) {
+#ifdef ASSERT
+        TempNewSymbol basic_signature =
+          MethodHandles::lookup_basic_type_signature(full_signature, CHECK);
+        int actual_size_of_params = result->size_of_parameters();
+        int expected_size_of_params = ArgumentSizeComputer(basic_signature).size();
+        // +1 for MethodHandle.this, +1 for trailing MethodType
+        if (!MethodHandles::is_signature_polymorphic_static(iid))  expected_size_of_params += 1;
+        if (appendix.not_null())                                   expected_size_of_params += 1;
+        if (actual_size_of_params != expected_size_of_params) {
+          tty->print_cr("*** basic_signature=%s", basic_signature->as_C_string());
+          tty->print_cr("*** result for %s: ", vmIntrinsics::name_at(iid));
+          result->print();
+        }
+        assert(actual_size_of_params == expected_size_of_params,
+               err_msg("%d != %d", actual_size_of_params, expected_size_of_params));
+#endif //ASSERT
+
+        assert(appendix_result_or_null != NULL, "");
+        (*appendix_result_or_null) = appendix;
+        (*method_type_result)      = method_type;
+        return;
+      }
     }
   }
 }
@@ -267,6 +343,7 @@
     new_flags = new_flags | JVM_ACC_PUBLIC;
     flags.set_flags(new_flags);
   }
+//  assert(extra_arg_result_or_null != NULL, "must be able to return extra argument");
 
   if (!Reflection::verify_field_access(ref_klass->as_klassOop(),
                                        resolved_klass->as_klassOop(),
@@ -287,10 +364,19 @@
   }
 }
 
-void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle& resolved_klass,
-                                  constantPoolHandle pool, int index, TRAPS) {
+void LinkResolver::resolve_method_statically(methodHandle& resolved_method, KlassHandle& resolved_klass,
+                                             Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS) {
 
   // resolve klass
+  if (code == Bytecodes::_invokedynamic) {
+    resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
+    Symbol* method_name = vmSymbols::invoke_name();
+    Symbol* method_signature = pool->signature_ref_at(index);
+    KlassHandle  current_klass(THREAD, pool->pool_holder());
+    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
+    return;
+  }
+
   resolve_klass(resolved_klass, pool, index, CHECK);
 
   Symbol*  method_name       = pool->name_ref_at(index);
@@ -299,7 +385,7 @@
 
   if (pool->has_preresolution()
       || (resolved_klass() == SystemDictionary::MethodHandle_klass() &&
-          methodOopDesc::is_method_handle_invoke_name(method_name))) {
+          MethodHandles::is_signature_polymorphic_name(resolved_klass(), method_name))) {
     methodOop result_oop = constantPoolOopDesc::method_at_if_loaded(pool, index);
     if (result_oop != NULL) {
       resolved_method = methodHandle(THREAD, result_oop);
@@ -307,33 +393,13 @@
     }
   }
 
-  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
+  if (code == Bytecodes::_invokeinterface) {
+    resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
+  } else {
+    resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
+  }
 }
 
-void LinkResolver::resolve_dynamic_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) {
-  // The class is java.lang.invoke.MethodHandle
-  resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
-
-  Symbol* method_name = vmSymbols::invokeExact_name();
-
-  Symbol*  method_signature = pool->signature_ref_at(index);
-  KlassHandle  current_klass   (THREAD, pool->pool_holder());
-
-  resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
-}
-
-void LinkResolver::resolve_interface_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) {
-
-  // resolve klass
-  resolve_klass(resolved_klass, pool, index, CHECK);
-  Symbol*  method_name       = pool->name_ref_at(index);
-  Symbol*  method_signature  = pool->signature_ref_at(index);
-  KlassHandle  current_klass(THREAD, pool->pool_holder());
-
-  resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
-}
-
-
 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass,
                                   Symbol* method_name, Symbol* method_signature,
                                   KlassHandle current_klass, bool check_access, TRAPS) {
@@ -346,6 +412,8 @@
     THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
   }
 
+  Handle nested_exception;
+
   // 2. lookup method in resolved klass and its super klasses
   lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
 
@@ -354,17 +422,23 @@
     lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
 
     if (resolved_method.is_null()) {
-      // JSR 292:  see if this is an implicitly generated method MethodHandle.invoke(*...)
-      lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, CHECK);
+      // JSR 292:  see if this is an implicitly generated method MethodHandle.linkToVirtual(*...), etc
+      lookup_polymorphic_method(resolved_method, resolved_klass, method_name, method_signature,
+                                current_klass, (Handle*)NULL, (Handle*)NULL, THREAD);
+      if (HAS_PENDING_EXCEPTION) {
+        nested_exception = Handle(THREAD, PENDING_EXCEPTION);
+        CLEAR_PENDING_EXCEPTION;
+      }
     }
 
     if (resolved_method.is_null()) {
       // 4. method lookup failed
       ResourceMark rm(THREAD);
-      THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
-                methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
-                                                        method_name,
-                                                        method_signature));
+      THROW_MSG_CAUSE(vmSymbols::java_lang_NoSuchMethodError(),
+                      methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
+                                                              method_name,
+                                                              method_signature),
+                      nested_exception);
     }
   }
 
@@ -1053,6 +1127,7 @@
     case Bytecodes::_invokestatic   : resolve_invokestatic   (result,       pool, index, CHECK); break;
     case Bytecodes::_invokespecial  : resolve_invokespecial  (result,       pool, index, CHECK); break;
     case Bytecodes::_invokevirtual  : resolve_invokevirtual  (result, recv, pool, index, CHECK); break;
+    case Bytecodes::_invokehandle   : resolve_invokehandle   (result,       pool, index, CHECK); break;
     case Bytecodes::_invokedynamic  : resolve_invokedynamic  (result,       pool, index, CHECK); break;
     case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
   }
@@ -1116,22 +1191,95 @@
 }
 
 
-void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int raw_index, TRAPS) {
+void LinkResolver::resolve_invokehandle(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
   assert(EnableInvokeDynamic, "");
+  // This guy is reached from InterpreterRuntime::resolve_invokehandle.
+  KlassHandle  resolved_klass;
+  Symbol* method_name = NULL;
+  Symbol* method_signature = NULL;
+  KlassHandle  current_klass;
+  resolve_pool(resolved_klass, method_name,  method_signature, current_klass, pool, index, CHECK);
+  if (TraceMethodHandles)
+    tty->print_cr("resolve_invokehandle %s %s", method_name->as_C_string(), method_signature->as_C_string());
+  resolve_handle_call(result, resolved_klass, method_name, method_signature, current_klass, CHECK);
+}
 
-  // This guy is reached from InterpreterRuntime::resolve_invokedynamic.
-
-  // At this point, we only need the signature, and can ignore the name.
-  Symbol*  method_signature = pool->signature_ref_at(raw_index);  // raw_index works directly
-  Symbol* method_name = vmSymbols::invokeExact_name();
-  KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass();
-
-  // JSR 292:  this must be an implicitly generated method MethodHandle.invokeExact(*...)
-  // The extra MH receiver will be inserted into the stack on every call.
+void LinkResolver::resolve_handle_call(CallInfo& result, KlassHandle resolved_klass,
+                                       Symbol* method_name, Symbol* method_signature,
+                                       KlassHandle current_klass,
+                                       TRAPS) {
+  // JSR 292:  this must be an implicitly generated method MethodHandle.invokeExact(*...) or similar
+  assert(resolved_klass() == SystemDictionary::MethodHandle_klass(), "");
+  assert(MethodHandles::is_signature_polymorphic_name(method_name), "");
   methodHandle resolved_method;
-  KlassHandle current_klass(THREAD, pool->pool_holder());
-  lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, THREAD);
+  Handle       resolved_appendix;
+  Handle       resolved_method_type;
+  lookup_polymorphic_method(resolved_method, resolved_klass,
+                            method_name, method_signature,
+                            current_klass, &resolved_appendix, &resolved_method_type, CHECK);
+  result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
+}
+
+
+void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
+  assert(EnableInvokeDynamic, "");
+  pool->set_invokedynamic();    // mark header to flag active call sites
+
+  //resolve_pool(<resolved_klass>, method_name, method_signature, current_klass, pool, index, CHECK);
+  Symbol* method_name       = pool->name_ref_at(index);
+  Symbol* method_signature  = pool->signature_ref_at(index);
+  KlassHandle current_klass = KlassHandle(THREAD, pool->pool_holder());
+
+  // Resolve the bootstrap specifier (BSM + optional arguments).
+  Handle bootstrap_specifier;
+  // Check if CallSite has been bound already:
+  ConstantPoolCacheEntry* cpce = pool->cache()->secondary_entry_at(index);
+  if (cpce->is_f1_null()) {
+    int pool_index = pool->cache()->main_entry_at(index)->constant_pool_index();
+    oop bsm_info = pool->resolve_bootstrap_specifier_at(pool_index, CHECK);
+    assert(bsm_info != NULL, "");
+    // FIXME: Cache this once per BootstrapMethods entry, not once per CONSTANT_InvokeDynamic.
+    bootstrap_specifier = Handle(THREAD, bsm_info);
+  }
+  if (!cpce->is_f1_null()) {
+    methodHandle method(     THREAD, cpce->f2_as_vfinal_method());
+    Handle       appendix(   THREAD, cpce->appendix_if_resolved(pool));
+    Handle       method_type(THREAD, cpce->method_type_if_resolved(pool));
+    result.set_handle(method, appendix, method_type, CHECK);
+    return;
+  }
+
+  if (TraceMethodHandles) {
+    tty->print_cr("resolve_invokedynamic #%d %s %s",
+                  constantPoolCacheOopDesc::decode_secondary_index(index),
+                  method_name->as_C_string(), method_signature->as_C_string());
+    tty->print("  BSM info: "); bootstrap_specifier->print();
+  }
+
+  resolve_dynamic_call(result, bootstrap_specifier, method_name, method_signature, current_klass, CHECK);
+}
+
+void LinkResolver::resolve_dynamic_call(CallInfo& result,
+                                        Handle bootstrap_specifier,
+                                        Symbol* method_name, Symbol* method_signature,
+                                        KlassHandle current_klass,
+                                        TRAPS) {
+  // JSR 292:  this must resolve to an implicitly generated method MH.linkToCallSite(*...)
+  // The appendix argument is likely to be a freshly-created CallSite.
+  Handle       resolved_appendix;
+  Handle       resolved_method_type;
+  methodHandle resolved_method =
+    SystemDictionary::find_dynamic_call_site_invoker(current_klass,
+                                                     bootstrap_specifier,
+                                                     method_name, method_signature,
+                                                     &resolved_appendix,
+                                                     &resolved_method_type,
+                                                     THREAD);
   if (HAS_PENDING_EXCEPTION) {
+    if (TraceMethodHandles) {
+      tty->print_cr("invokedynamic throws BSME for "INTPTR_FORMAT, PENDING_EXCEPTION);
+      PENDING_EXCEPTION->print();
+    }
     if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) {
       // throw these guys, since they are already wrapped
       return;
@@ -1141,17 +1289,11 @@
       return;
     }
     // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS.
-    Handle ex(THREAD, PENDING_EXCEPTION);
+    Handle nested_exception(THREAD, PENDING_EXCEPTION);
     CLEAR_PENDING_EXCEPTION;
-    oop bsme = Klass::cast(SystemDictionary::BootstrapMethodError_klass())->java_mirror();
-    MethodHandles::raise_exception(Bytecodes::_athrow, ex(), bsme, CHECK);
-    // java code should not return, but if it does throw out anyway
-    THROW(vmSymbols::java_lang_InternalError());
+    THROW_CAUSE(vmSymbols::java_lang_BootstrapMethodError(), nested_exception)
   }
-  if (resolved_method.is_null()) {
-    THROW(vmSymbols::java_lang_InternalError());
-  }
-  result.set_dynamic(resolved_method, CHECK);
+  result.set_handle(resolved_method, resolved_appendix, resolved_method_type, CHECK);
 }
 
 //------------------------------------------------------------------------------------------------------------------------
diff --git a/hotspot/src/share/vm/interpreter/linkResolver.hpp b/hotspot/src/share/vm/interpreter/linkResolver.hpp
index 3d4c6f4..dfd74f9 100644
--- a/hotspot/src/share/vm/interpreter/linkResolver.hpp
+++ b/hotspot/src/share/vm/interpreter/linkResolver.hpp
@@ -75,12 +75,14 @@
   methodHandle _resolved_method;        // static target method
   methodHandle _selected_method;        // dynamic (actual) target method
   int          _vtable_index;           // vtable index of selected method
+  Handle       _resolved_appendix;      // extra argument in constant pool (if CPCE::has_appendix)
+  Handle       _resolved_method_type;   // MethodType (for invokedynamic and invokehandle call sites)
 
-  void         set_static(   KlassHandle resolved_klass,                             methodHandle resolved_method                                                , TRAPS);
-  void         set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method                  , TRAPS);
-  void         set_virtual(  KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS);
-  void         set_dynamic(                                                          methodHandle resolved_method,                                                 TRAPS);
-  void         set_common(   KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS);
+  void         set_static(   KlassHandle resolved_klass,                             methodHandle resolved_method                                                       , TRAPS);
+  void         set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method                         , TRAPS);
+  void         set_virtual(  KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index       , TRAPS);
+  void         set_handle(                                                           methodHandle resolved_method, Handle resolved_appendix, Handle resolved_method_type, TRAPS);
+  void         set_common(   KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index       , TRAPS);
 
   friend class LinkResolver;
 
@@ -89,6 +91,8 @@
   KlassHandle  selected_klass() const            { return _selected_klass; }
   methodHandle resolved_method() const           { return _resolved_method; }
   methodHandle selected_method() const           { return _selected_method; }
+  Handle       resolved_appendix() const         { return _resolved_appendix; }
+  Handle       resolved_method_type() const      { return _resolved_method_type; }
 
   BasicType    result_type() const               { return selected_method()->result_type(); }
   bool         has_vtable_index() const          { return _vtable_index >= 0; }
@@ -110,8 +114,8 @@
   static void lookup_method_in_klasses          (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
   static void lookup_instance_method_in_klasses (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
   static void lookup_method_in_interfaces       (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
-  static void lookup_implicit_method            (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
-                                                 KlassHandle current_klass, TRAPS);
+  static void lookup_polymorphic_method         (methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature,
+                                                 KlassHandle current_klass, Handle *appendix_result_or_null, Handle *method_type_result, TRAPS);
 
   static int vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS);
 
@@ -139,10 +143,9 @@
   // constant pool resolving
   static void check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS);
 
-  // static resolving for all calls except interface calls
-  static void resolve_method          (methodHandle& method_result, KlassHandle& klass_result, constantPoolHandle pool, int index, TRAPS);
-  static void resolve_dynamic_method  (methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS);
-  static void resolve_interface_method(methodHandle& method_result, KlassHandle& klass_result, constantPoolHandle pool, int index, TRAPS);
+  // static resolving calls (will not run any Java code); used only from Bytecode_invoke::static_target
+  static void resolve_method_statically(methodHandle& method_result, KlassHandle& klass_result,
+                                        Bytecodes::Code code, constantPoolHandle pool, int index, TRAPS);
 
   // runtime/static resolving for fields
   static void resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS);
@@ -156,6 +159,8 @@
   static void resolve_special_call  (CallInfo& result,              KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS);
   static void resolve_virtual_call  (CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
   static void resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, bool check_access, bool check_null_and_abstract, TRAPS);
+  static void resolve_handle_call   (CallInfo& result,                                      KlassHandle resolved_klass, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS);
+  static void resolve_dynamic_call  (CallInfo& result,                                      Handle bootstrap_specifier, Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, TRAPS);
 
   // same as above for compile-time resolution; but returns null handle instead of throwing an exception on error
   // also, does not initialize klass (i.e., no side effects)
@@ -177,6 +182,7 @@
   static void resolve_invokevirtual  (CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS);
   static void resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS);
   static void resolve_invokedynamic  (CallInfo& result,              constantPoolHandle pool, int index, TRAPS);
+  static void resolve_invokehandle   (CallInfo& result,              constantPoolHandle pool, int index, TRAPS);
 
   static void resolve_invoke         (CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS);
 };
diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.cpp b/hotspot/src/share/vm/interpreter/oopMapCache.cpp
index f5ff6f6..01d5753 100644
--- a/hotspot/src/share/vm/interpreter/oopMapCache.cpp
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.cpp
@@ -348,7 +348,7 @@
   if (mask_size() > small_mask_limit) {
     assert(_bit_mask[0] == 0, "bit mask should be new or just flushed");
     _bit_mask[0] = (intptr_t)
-      NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size());
+      NEW_C_HEAP_ARRAY(uintptr_t, mask_word_size(), mtClass);
   }
 }
 
@@ -356,7 +356,7 @@
   if (mask_size() > small_mask_limit && _bit_mask[0] != 0) {
     assert(!Thread::current()->resource_area()->contains((void*)_bit_mask[0]),
       "This bit mask should not be in the resource area");
-    FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0]);
+    FREE_C_HEAP_ARRAY(uintptr_t, _bit_mask[0], mtClass);
     debug_only(_bit_mask[0] = 0;)
   }
 }
@@ -506,7 +506,7 @@
 OopMapCache::OopMapCache() :
   _mut(Mutex::leaf, "An OopMapCache lock", true)
 {
-  _array  = NEW_C_HEAP_ARRAY(OopMapCacheEntry, _size);
+  _array  = NEW_C_HEAP_ARRAY(OopMapCacheEntry, _size, mtClass);
   // Cannot call flush for initialization, since flush
   // will check if memory should be deallocated
   for(int i = 0; i < _size; i++) _array[i].initialize();
@@ -520,7 +520,7 @@
   flush();
   // Deallocate array
   NOT_PRODUCT(_total_memory_usage -= sizeof(OopMapCache) + (sizeof(OopMapCacheEntry) * _size);)
-  FREE_C_HEAP_ARRAY(OopMapCacheEntry, _array);
+  FREE_C_HEAP_ARRAY(OopMapCacheEntry, _array, mtClass);
 }
 
 OopMapCacheEntry* OopMapCache::entry_at(int i) const {
@@ -639,9 +639,9 @@
 
 void OopMapCache::compute_one_oop_map(methodHandle method, int bci, InterpreterOopMap* entry) {
   // Due to the invariants above it's tricky to allocate a temporary OopMapCacheEntry on the stack
-  OopMapCacheEntry* tmp = NEW_C_HEAP_ARRAY(OopMapCacheEntry, 1);
+  OopMapCacheEntry* tmp = NEW_C_HEAP_ARRAY(OopMapCacheEntry, 1, mtClass);
   tmp->initialize();
   tmp->fill(method, bci);
   entry->resource_copy(tmp);
-  FREE_C_HEAP_ARRAY(OopMapCacheEntry, tmp);
+  FREE_C_HEAP_ARRAY(OopMapCacheEntry, tmp, mtInternal);
 }
diff --git a/hotspot/src/share/vm/interpreter/oopMapCache.hpp b/hotspot/src/share/vm/interpreter/oopMapCache.hpp
index 068e4d3..fea9ec0 100644
--- a/hotspot/src/share/vm/interpreter/oopMapCache.hpp
+++ b/hotspot/src/share/vm/interpreter/oopMapCache.hpp
@@ -156,7 +156,7 @@
 #endif
 };
 
-class OopMapCache : public CHeapObj {
+class OopMapCache : public CHeapObj<mtClass> {
  private:
   enum { _size        = 32,     // Use fixed size for now
          _probe_depth = 3       // probe depth in case of collisions
diff --git a/hotspot/src/share/vm/interpreter/rewriter.cpp b/hotspot/src/share/vm/interpreter/rewriter.cpp
index faffae8..8fca376 100644
--- a/hotspot/src/share/vm/interpreter/rewriter.cpp
+++ b/hotspot/src/share/vm/interpreter/rewriter.cpp
@@ -33,6 +33,7 @@
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/methodComparator.hpp"
+#include "prims/methodHandles.hpp"
 
 // Computes a CPC map (new_index -> original_index) for constant pool entries
 // that are referred to by the interpreter at runtime via the constant pool cache.
@@ -41,10 +42,9 @@
 void Rewriter::compute_index_maps() {
   const int length  = _pool->length();
   init_cp_map(length);
-  jint tag_mask = 0;
+  bool saw_mh_symbol = false;
   for (int i = 0; i < length; i++) {
     int tag = _pool->tag_at(i).value();
-    tag_mask |= (1 << tag);
     switch (tag) {
       case JVM_CONSTANT_InterfaceMethodref:
       case JVM_CONSTANT_Fieldref          : // fall through
@@ -54,13 +54,18 @@
       case JVM_CONSTANT_InvokeDynamic     : // fall through
         add_cp_cache_entry(i);
         break;
+      case JVM_CONSTANT_Utf8:
+        if (_pool->symbol_at(i) == vmSymbols::java_lang_invoke_MethodHandle())
+          saw_mh_symbol = true;
+        break;
     }
   }
 
   guarantee((int)_cp_cache_map.length()-1 <= (int)((u2)-1),
             "all cp cache indexes fit in a u2");
 
-  _have_invoke_dynamic = ((tag_mask & (1 << JVM_CONSTANT_InvokeDynamic)) != 0);
+  if (saw_mh_symbol)
+    _method_handle_invokers.initialize(length, (int)0);
 }
 
 // Unrewrite the bytecodes if an error occurs.
@@ -80,22 +85,6 @@
       oopFactory::new_constantPoolCache(length, CHECK);
   No_Safepoint_Verifier nsv;
   cache->initialize(_cp_cache_map);
-
-  // Don't bother with the next pass if there is no JVM_CONSTANT_InvokeDynamic.
-  if (_have_invoke_dynamic) {
-    for (int i = 0; i < length; i++) {
-      int pool_index = cp_cache_entry_pool_index(i);
-      if (pool_index >= 0 &&
-          _pool->tag_at(pool_index).is_invoke_dynamic()) {
-        int bsm_index = _pool->invoke_dynamic_bootstrap_method_ref_index_at(pool_index);
-        assert(_pool->tag_at(bsm_index).is_method_handle(), "must be a MH constant");
-        // There is a CP cache entry holding the BSM for these calls.
-        int bsm_cache_index = cp_entry_to_cp_cache(bsm_index);
-        cache->entry_at(i)->initialize_bootstrap_method_index_in_cache(bsm_cache_index);
-      }
-    }
-  }
-
   _pool->set_cache(cache);
   cache->set_constant_pool(_pool());
 }
@@ -148,10 +137,57 @@
     int  cp_index    = Bytes::get_Java_u2(p);
     int  cache_index = cp_entry_to_cp_cache(cp_index);
     Bytes::put_native_u2(p, cache_index);
+    if (!_method_handle_invokers.is_empty())
+      maybe_rewrite_invokehandle(p - 1, cp_index, reverse);
   } else {
     int cache_index = Bytes::get_native_u2(p);
     int pool_index = cp_cache_entry_pool_index(cache_index);
     Bytes::put_Java_u2(p, pool_index);
+    if (!_method_handle_invokers.is_empty())
+      maybe_rewrite_invokehandle(p - 1, pool_index, reverse);
+  }
+}
+
+
+// Adjust the invocation bytecode for a signature-polymorphic method (MethodHandle.invoke, etc.)
+void Rewriter::maybe_rewrite_invokehandle(address opc, int cp_index, bool reverse) {
+  if (!reverse) {
+    if ((*opc) == (u1)Bytecodes::_invokevirtual ||
+        // allow invokespecial as an alias, although it would be very odd:
+        (*opc) == (u1)Bytecodes::_invokespecial) {
+      assert(_pool->tag_at(cp_index).is_method(), "wrong index");
+      // Determine whether this is a signature-polymorphic method.
+      if (cp_index >= _method_handle_invokers.length())  return;
+      int status = _method_handle_invokers[cp_index];
+      assert(status >= -1 && status <= 1, "oob tri-state");
+      if (status == 0) {
+        if (_pool->klass_ref_at_noresolve(cp_index) == vmSymbols::java_lang_invoke_MethodHandle() &&
+            MethodHandles::is_signature_polymorphic_name(SystemDictionary::MethodHandle_klass(),
+                                                         _pool->name_ref_at(cp_index))) {
+          assert(has_cp_cache(cp_index), "should already have an entry");
+          int cpc  = maybe_add_cp_cache_entry(cp_index);  // should already have an entry
+          int cpc2 = add_secondary_cp_cache_entry(cpc);
+          status = +1;
+        } else {
+          status = -1;
+        }
+        _method_handle_invokers[cp_index] = status;
+      }
+      // We use a special internal bytecode for such methods (if non-static).
+      // The basic reason for this is that such methods need an extra "appendix" argument
+      // to transmit the call site's intended call type.
+      if (status > 0) {
+        (*opc) = (u1)Bytecodes::_invokehandle;
+      }
+    }
+  } else {
+    // Do not need to look at cp_index.
+    if ((*opc) == (u1)Bytecodes::_invokehandle) {
+      (*opc) = (u1)Bytecodes::_invokevirtual;
+      // Ignore corner case of original _invokespecial instruction.
+      // This is safe because (a) the signature polymorphic method was final, and
+      // (b) the implementation of MethodHandle will not call invokespecial on it.
+    }
   }
 }
 
@@ -163,6 +199,10 @@
     int cp_index = Bytes::get_Java_u2(p);
     int cpc  = maybe_add_cp_cache_entry(cp_index);  // add lazily
     int cpc2 = add_secondary_cp_cache_entry(cpc);
+    // The second secondary entry is required to store the MethodType and
+    // must be the next entry.
+    int cpc3 = add_secondary_cp_cache_entry(cpc);
+    assert(cpc2 + 1 == cpc3, err_msg_res("must be consecutive: %d + 1 == %d", cpc2, cpc3));
 
     // Replace the trailing four bytes with a CPC index for the dynamic
     // call site.  Unlike other CPC entries, there is one per bytecode,
@@ -297,17 +337,18 @@
         case Bytecodes::_invokespecial  : // fall through
         case Bytecodes::_invokestatic   :
         case Bytecodes::_invokeinterface:
+        case Bytecodes::_invokehandle   : // if reverse=true
           rewrite_member_reference(bcp, prefix_length+1, reverse);
           break;
         case Bytecodes::_invokedynamic:
           rewrite_invokedynamic(bcp, prefix_length+1, reverse);
           break;
         case Bytecodes::_ldc:
-        case Bytecodes::_fast_aldc:
+        case Bytecodes::_fast_aldc:  // if reverse=true
           maybe_rewrite_ldc(bcp, prefix_length+1, false, reverse);
           break;
         case Bytecodes::_ldc_w:
-        case Bytecodes::_fast_aldc_w:
+        case Bytecodes::_fast_aldc_w:  // if reverse=true
           maybe_rewrite_ldc(bcp, prefix_length+1, true, reverse);
           break;
         case Bytecodes::_jsr            : // fall through
diff --git a/hotspot/src/share/vm/interpreter/rewriter.hpp b/hotspot/src/share/vm/interpreter/rewriter.hpp
index 27e0d56..8d47754 100644
--- a/hotspot/src/share/vm/interpreter/rewriter.hpp
+++ b/hotspot/src/share/vm/interpreter/rewriter.hpp
@@ -39,7 +39,7 @@
   objArrayHandle      _methods;
   intArray            _cp_map;
   intStack            _cp_cache_map;
-  bool                _have_invoke_dynamic;
+  intArray            _method_handle_invokers;
 
   void init_cp_map(int length) {
     _cp_map.initialize(length, -1);
@@ -88,6 +88,7 @@
   void scan_method(methodOop m, bool reverse = false);
   void rewrite_Object_init(methodHandle m, TRAPS);
   void rewrite_member_reference(address bcp, int offset, bool reverse = false);
+  void maybe_rewrite_invokehandle(address opc, int cp_index, bool reverse = false);
   void rewrite_invokedynamic(address bcp, int offset, bool reverse = false);
   void maybe_rewrite_ldc(address bcp, int offset, bool is_wide, bool reverse = false);
   // Revert bytecodes in case of an exception.
diff --git a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp
index 231c46f..246b5b5 100644
--- a/hotspot/src/share/vm/interpreter/templateInterpreter.cpp
+++ b/hotspot/src/share/vm/interpreter/templateInterpreter.cpp
@@ -362,7 +362,6 @@
   method_entry(empty)
   method_entry(accessor)
   method_entry(abstract)
-  method_entry(method_handle)
   method_entry(java_lang_math_sin  )
   method_entry(java_lang_math_cos  )
   method_entry(java_lang_math_tan  )
@@ -370,8 +369,16 @@
   method_entry(java_lang_math_sqrt )
   method_entry(java_lang_math_log  )
   method_entry(java_lang_math_log10)
+  method_entry(java_lang_math_exp  )
+  method_entry(java_lang_math_pow  )
   method_entry(java_lang_ref_reference_get)
 
+  // method handle entry kinds are generated later in MethodHandlesAdapterGenerator::generate:
+  for (int i = Interpreter::method_handle_invoke_FIRST; i <= Interpreter::method_handle_invoke_LAST; i++) {
+    Interpreter::MethodKind kind = (Interpreter::MethodKind) i;
+    Interpreter::_entry_table[kind] = Interpreter::_entry_table[Interpreter::abstract];
+  }
+
   // all native method kinds (must be one contiguous block)
   Interpreter::_native_entry_begin = Interpreter::code()->code_end();
   method_entry(native)
diff --git a/hotspot/src/share/vm/interpreter/templateTable.cpp b/hotspot/src/share/vm/interpreter/templateTable.cpp
index 30c6348..45bb6d5 100644
--- a/hotspot/src/share/vm/interpreter/templateTable.cpp
+++ b/hotspot/src/share/vm/interpreter/templateTable.cpp
@@ -444,7 +444,7 @@
   def(Bytecodes::_invokespecial       , ubcp|disp|clvm|____, vtos, vtos, invokespecial       , f1_byte      );
   def(Bytecodes::_invokestatic        , ubcp|disp|clvm|____, vtos, vtos, invokestatic        , f1_byte      );
   def(Bytecodes::_invokeinterface     , ubcp|disp|clvm|____, vtos, vtos, invokeinterface     , f1_byte      );
-  def(Bytecodes::_invokedynamic       , ubcp|disp|clvm|____, vtos, vtos, invokedynamic       , f1_oop       );
+  def(Bytecodes::_invokedynamic       , ubcp|disp|clvm|____, vtos, vtos, invokedynamic       , f12_oop      );
   def(Bytecodes::_new                 , ubcp|____|clvm|____, vtos, atos, _new                ,  _           );
   def(Bytecodes::_newarray            , ubcp|____|clvm|____, itos, atos, newarray            ,  _           );
   def(Bytecodes::_anewarray           , ubcp|____|clvm|____, itos, atos, anewarray           ,  _           );
@@ -514,6 +514,8 @@
 
   def(Bytecodes::_return_register_finalizer , ____|disp|clvm|____, vtos, vtos, _return       ,  vtos        );
 
+  def(Bytecodes::_invokehandle        , ubcp|disp|clvm|____, vtos, vtos, invokehandle        , f12_oop      );
+
   def(Bytecodes::_shouldnotreachhere   , ____|____|____|____, vtos, vtos, shouldnotreachhere ,  _           );
   // platform specific bytecodes
   pd_initialize();
diff --git a/hotspot/src/share/vm/interpreter/templateTable.hpp b/hotspot/src/share/vm/interpreter/templateTable.hpp
index 3b006ad..17e9f26 100644
--- a/hotspot/src/share/vm/interpreter/templateTable.hpp
+++ b/hotspot/src/share/vm/interpreter/templateTable.hpp
@@ -98,7 +98,7 @@
  public:
   enum Operation { add, sub, mul, div, rem, _and, _or, _xor, shl, shr, ushr };
   enum Condition { equal, not_equal, less, less_equal, greater, greater_equal };
-  enum CacheByte { f1_byte = 1, f2_byte = 2, f1_oop = 0x11 };  // byte_no codes
+  enum CacheByte { f1_byte = 1, f2_byte = 2, f12_oop = 0x12 };  // byte_no codes
 
  private:
   static bool            _is_initialized;        // true if TemplateTable has been initialized
@@ -294,6 +294,7 @@
   static void invokestatic(int byte_no);
   static void invokeinterface(int byte_no);
   static void invokedynamic(int byte_no);
+  static void invokehandle(int byte_no);
   static void fast_invokevfinal(int byte_no);
 
   static void getfield_or_static(int byte_no, bool is_static);
diff --git a/hotspot/src/share/vm/libadt/set.cpp b/hotspot/src/share/vm/libadt/set.cpp
index 1849b13..c475a21 100644
--- a/hotspot/src/share/vm/libadt/set.cpp
+++ b/hotspot/src/share/vm/libadt/set.cpp
@@ -71,7 +71,7 @@
   set.Sort();                   // Sort elements for in-order retrieval
 
   uint len = 128;               // Total string space
-  char *buf = NEW_C_HEAP_ARRAY(char,len);// Some initial string space
+  char *buf = NEW_C_HEAP_ARRAY(char,len, mtCompiler);// Some initial string space
 
   register char *s = buf;       // Current working string pointer
   *s++ = '{';
@@ -86,7 +86,7 @@
       if( buf+len-s < 25 ) {      // Generous trailing space for upcoming numbers
         int offset = (int)(s-buf);// Not enuf space; compute offset into buffer
         len <<= 1;                // Double string size
-        buf = REALLOC_C_HEAP_ARRAY(char,buf,len); // Reallocate doubled size
+        buf = REALLOC_C_HEAP_ARRAY(char,buf,len, mtCompiler); // Reallocate doubled size
         s = buf+offset;         // Get working pointer into new bigger buffer
       }
       if( lo != (uint)-2 ) {    // Startup?  No!  Then print previous range.
@@ -101,7 +101,7 @@
     if( buf+len-s < 25 ) {      // Generous trailing space for upcoming numbers
       int offset = (int)(s-buf);// Not enuf space; compute offset into buffer
       len <<= 1;                // Double string size
-      buf = (char*)ReallocateHeap(buf,len); // Reallocate doubled size
+      buf = (char*)ReallocateHeap(buf,len, mtCompiler); // Reallocate doubled size
       s = buf+offset;           // Get working pointer into new bigger buffer
     }
     if( lo != hi ) sprintf(s,"%d-%d}",lo,hi);
diff --git a/hotspot/src/share/vm/libadt/vectset.cpp b/hotspot/src/share/vm/libadt/vectset.cpp
index 0042ca7..de7bcd8 100644
--- a/hotspot/src/share/vm/libadt/vectset.cpp
+++ b/hotspot/src/share/vm/libadt/vectset.cpp
@@ -362,7 +362,7 @@
 };
 
 SetI_ *VectorSet::iterate(uint &elem) const {
-  return new(ResourceObj::C_HEAP) VSetI_(this, elem);
+  return new(ResourceObj::C_HEAP, mtInternal) VSetI_(this, elem);
 }
 
 //=============================================================================
diff --git a/hotspot/src/share/vm/memory/allocation.cpp b/hotspot/src/share/vm/memory/allocation.cpp
index 0479e73..032d335 100644
--- a/hotspot/src/share/vm/memory/allocation.cpp
+++ b/hotspot/src/share/vm/memory/allocation.cpp
@@ -26,10 +26,13 @@
 #include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
+#include "runtime/atomic.hpp"
 #include "runtime/os.hpp"
 #include "runtime/task.hpp"
 #include "runtime/threadCritical.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/ostream.hpp"
+
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
 #endif
@@ -43,32 +46,16 @@
 # include "os_bsd.inline.hpp"
 #endif
 
-void* CHeapObj::operator new(size_t size){
-  return (void *) AllocateHeap(size, "CHeapObj-new");
-}
-
-void* CHeapObj::operator new (size_t size, const std::nothrow_t&  nothrow_constant) {
-  char* p = (char*) os::malloc(size);
-#ifdef ASSERT
-  if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
-#endif
-  return p;
-}
-
-void CHeapObj::operator delete(void* p){
- FreeHeap(p);
-}
-
 void* StackObj::operator new(size_t size)  { ShouldNotCallThis(); return 0; };
 void  StackObj::operator delete(void* p)   { ShouldNotCallThis(); };
 void* _ValueObj::operator new(size_t size)  { ShouldNotCallThis(); return 0; };
 void  _ValueObj::operator delete(void* p)   { ShouldNotCallThis(); };
 
-void* ResourceObj::operator new(size_t size, allocation_type type) {
+void* ResourceObj::operator new(size_t size, allocation_type type, MEMFLAGS flags) {
   address res;
   switch (type) {
    case C_HEAP:
-    res = (address)AllocateHeap(size, "C_Heap: ResourceOBJ");
+    res = (address)AllocateHeap(size, flags, CALLER_PC);
     DEBUG_ONLY(set_allocation_type(res, C_HEAP);)
     break;
    case RESOURCE_AREA:
@@ -184,7 +171,7 @@
 
 // MT-safe pool of chunks to reduce malloc/free thrashing
 // NB: not using Mutex because pools are used before Threads are initialized
-class ChunkPool {
+class ChunkPool: public CHeapObj<mtInternal> {
   Chunk*       _first;        // first cached Chunk; its first word points to next chunk
   size_t       _num_chunks;   // number of unused chunks in pool
   size_t       _num_used;     // number of chunks currently checked out
@@ -210,14 +197,16 @@
    ChunkPool(size_t size) : _size(size) { _first = NULL; _num_chunks = _num_used = 0; }
 
   // Allocate a new chunk from the pool (might expand the pool)
-  void* allocate(size_t bytes) {
+  _NOINLINE_ void* allocate(size_t bytes) {
     assert(bytes == _size, "bad size");
     void* p = NULL;
+    // No VM lock can be taken inside ThreadCritical lock, so os::malloc
+    // should be done outside ThreadCritical lock due to NMT
     { ThreadCritical tc;
       _num_used++;
       p = get_first();
-      if (p == NULL) p = os::malloc(bytes);
     }
+    if (p == NULL) p = os::malloc(bytes, mtChunk, CURRENT_PC);
     if (p == NULL)
       vm_exit_out_of_memory(bytes, "ChunkPool::allocate");
 
@@ -238,28 +227,34 @@
 
   // Prune the pool
   void free_all_but(size_t n) {
+    Chunk* cur = NULL;
+    Chunk* next;
+    {
     // if we have more than n chunks, free all of them
     ThreadCritical tc;
     if (_num_chunks > n) {
       // free chunks at end of queue, for better locality
-      Chunk* cur = _first;
+        cur = _first;
       for (size_t i = 0; i < (n - 1) && cur != NULL; i++) cur = cur->next();
 
       if (cur != NULL) {
-        Chunk* next = cur->next();
+          next = cur->next();
         cur->set_next(NULL);
         cur = next;
 
-        // Free all remaining chunks
-        while(cur != NULL) {
-          next = cur->next();
-          os::free(cur);
-          _num_chunks--;
-          cur = next;
+          _num_chunks = n;
         }
       }
     }
-  }
+
+    // Free all remaining chunks, outside of ThreadCritical
+    // to avoid deadlock with NMT
+        while(cur != NULL) {
+          next = cur->next();
+      os::free(cur, mtChunk);
+          cur = next;
+        }
+      }
 
   // Accessors to preallocated pool's
   static ChunkPool* large_pool()  { assert(_large_pool  != NULL, "must be initialized"); return _large_pool;  }
@@ -323,7 +318,7 @@
    case Chunk::medium_size: return ChunkPool::medium_pool()->allocate(bytes);
    case Chunk::init_size:   return ChunkPool::small_pool()->allocate(bytes);
    default: {
-     void *p =  os::malloc(bytes);
+     void *p =  os::malloc(bytes, mtChunk, CALLER_PC);
      if (p == NULL)
        vm_exit_out_of_memory(bytes, "Chunk::new");
      return p;
@@ -337,7 +332,7 @@
    case Chunk::size:        ChunkPool::large_pool()->free(c); break;
    case Chunk::medium_size: ChunkPool::medium_pool()->free(c); break;
    case Chunk::init_size:   ChunkPool::small_pool()->free(c); break;
-   default:                 os::free(c);
+   default:                 os::free(c, mtChunk);
   }
 }
 
@@ -374,6 +369,7 @@
 }
 
 //------------------------------Arena------------------------------------------
+NOT_PRODUCT(volatile jint Arena::_instance_count = 0;)
 
 Arena::Arena(size_t init_size) {
   size_t round_size = (sizeof (char *)) - 1;
@@ -382,6 +378,7 @@
   _hwm = _chunk->bottom();      // Save the cached hwm, max
   _max = _chunk->top();
   set_size_in_bytes(init_size);
+  NOT_PRODUCT(Atomic::inc(&_instance_count);)
 }
 
 Arena::Arena() {
@@ -389,10 +386,7 @@
   _hwm = _chunk->bottom();      // Save the cached hwm, max
   _max = _chunk->top();
   set_size_in_bytes(Chunk::init_size);
-}
-
-Arena::Arena(Arena *a) : _chunk(a->_chunk), _hwm(a->_hwm), _max(a->_max), _first(a->_first) {
-  set_size_in_bytes(a->size_in_bytes());
+  NOT_PRODUCT(Atomic::inc(&_instance_count);)
 }
 
 Arena *Arena::move_contents(Arena *copy) {
@@ -401,7 +395,12 @@
   copy->_hwm   = _hwm;
   copy->_max   = _max;
   copy->_first = _first;
-  copy->set_size_in_bytes(size_in_bytes());
+
+  // workaround rare racing condition, which could double count
+  // the arena size by native memory tracking
+  size_t size = size_in_bytes();
+  set_size_in_bytes(0);
+  copy->set_size_in_bytes(size);
   // Destroy original arena
   reset();
   return copy;            // Return Arena with contents
@@ -409,6 +408,42 @@
 
 Arena::~Arena() {
   destruct_contents();
+  NOT_PRODUCT(Atomic::dec(&_instance_count);)
+}
+
+void* Arena::operator new(size_t size) {
+  assert(false, "Use dynamic memory type binding");
+  return NULL;
+}
+
+void* Arena::operator new (size_t size, const std::nothrow_t&  nothrow_constant) {
+  assert(false, "Use dynamic memory type binding");
+  return NULL;
+}
+
+  // dynamic memory type binding
+void* Arena::operator new(size_t size, MEMFLAGS flags) {
+#ifdef ASSERT
+  void* p = (void*)AllocateHeap(size, flags|otArena, CALLER_PC);
+  if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p);
+  return p;
+#else
+  return (void *) AllocateHeap(size, flags|otArena, CALLER_PC);
+#endif
+}
+
+void* Arena::operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags) {
+#ifdef ASSERT
+  void* p = os::malloc(size, flags|otArena, CALLER_PC);
+  if (PrintMallocFree) trace_heap_malloc(size, "Arena-new", p);
+  return p;
+#else
+  return os::malloc(size, flags|otArena, CALLER_PC);
+#endif
+}
+
+void Arena::operator delete(void* p) {
+  FreeHeap(p);
 }
 
 // Destroy this arenas contents and reset to empty
@@ -417,10 +452,21 @@
     char* end = _first->next() ? _first->top() : _hwm;
     free_malloced_objects(_first, _first->bottom(), end, _hwm);
   }
+  // reset size before chop to avoid a rare racing condition
+  // that can have total arena memory exceed total chunk memory
+  set_size_in_bytes(0);
   _first->chop();
   reset();
 }
 
+// This is high traffic method, but many calls actually don't
+// change the size
+void Arena::set_size_in_bytes(size_t size) {
+  if (_size_in_bytes != size) {
+    _size_in_bytes = size;
+    MemTracker::record_arena_size((address)this, size);
+  }
+}
 
 // Total of all Chunks in arena
 size_t Arena::used() const {
@@ -448,7 +494,6 @@
   if (_chunk == NULL) {
     signal_out_of_memory(len * Chunk::aligned_overhead_size(), "Arena::grow");
   }
-
   if (k) k->set_next(_chunk);   // Append new chunk to end of linked list
   else _first = _chunk;
   _hwm  = _chunk->bottom();     // Save the cached hwm, max
@@ -538,7 +583,7 @@
   assert(UseMallocOnly, "shouldn't call");
   // use malloc, but save pointer in res. area for later freeing
   char** save = (char**)internal_malloc_4(sizeof(char*));
-  return (*save = (char*)os::malloc(size));
+  return (*save = (char*)os::malloc(size, mtChunk));
 }
 
 // for debugging with UseMallocOnly
diff --git a/hotspot/src/share/vm/memory/allocation.hpp b/hotspot/src/share/vm/memory/allocation.hpp
index 4c2f1e8..9cd677f 100644
--- a/hotspot/src/share/vm/memory/allocation.hpp
+++ b/hotspot/src/share/vm/memory/allocation.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -40,6 +40,18 @@
 #define ARENA_ALIGN_MASK (~((size_t)ARENA_ALIGN_M1))
 #define ARENA_ALIGN(x) ((((size_t)(x)) + ARENA_ALIGN_M1) & ARENA_ALIGN_MASK)
 
+
+// noinline attribute
+#ifdef _WINDOWS
+  #define _NOINLINE_  __declspec(noinline)
+#else
+  #if __GNUC__ < 3    // gcc 2.x does not support noinline attribute
+    #define _NOINLINE_
+  #else
+    #define _NOINLINE_ __attribute__ ((noinline))
+  #endif
+#endif
+
 // All classes in the virtual machine must be subclassed
 // by one of the following allocation classes:
 //
@@ -98,12 +110,74 @@
 };
 #endif
 
-class CHeapObj ALLOCATION_SUPER_CLASS_SPEC {
+
+/*
+ * MemoryType bitmap layout:
+ * | 16 15 14 13 12 11 10 09 | 08 07 06 05 | 04 03 02 01 |
+ * |      memory type        |   object    | reserved    |
+ * |                         |     type    |             |
+ */
+enum MemoryType {
+  // Memory type by sub systems. It occupies lower byte.
+  mtNone              = 0x0000,  // undefined
+  mtClass             = 0x0100,  // memory class for Java classes
+  mtThread            = 0x0200,  // memory for thread objects
+  mtThreadStack       = 0x0300,
+  mtCode              = 0x0400,  // memory for generated code
+  mtGC                = 0x0500,  // memory for GC
+  mtCompiler          = 0x0600,  // memory for compiler
+  mtInternal          = 0x0700,  // memory used by VM, but does not belong to
+                                 // any of above categories, and not used for
+                                 // native memory tracking
+  mtOther             = 0x0800,  // memory not used by VM
+  mtSymbol            = 0x0900,  // symbol
+  mtNMT               = 0x0A00,  // memory used by native memory tracking
+  mtChunk             = 0x0B00,  // chunk that holds content of arenas
+  mtJavaHeap          = 0x0C00,  // Java heap
+  mtClassShared       = 0x0D00,  // class data sharing
+  mt_number_of_types  = 0x000D,  // number of memory types (mtDontTrack
+                                 // is not included as validate type)
+  mtDontTrack         = 0x0E00,  // memory we do not or cannot track
+  mt_masks            = 0x7F00,
+
+  // object type mask
+  otArena             = 0x0010, // an arena object
+  otNMTRecorder       = 0x0020, // memory recorder object
+  ot_masks            = 0x00F0
+};
+
+#define IS_MEMORY_TYPE(flags, type) ((flags & mt_masks) == type)
+#define HAS_VALID_MEMORY_TYPE(flags)((flags & mt_masks) != mtNone)
+#define FLAGS_TO_MEMORY_TYPE(flags) (flags & mt_masks)
+
+#define IS_ARENA_OBJ(flags)         ((flags & ot_masks) == otArena)
+#define IS_NMT_RECORDER(flags)      ((flags & ot_masks) == otNMTRecorder)
+#define NMT_CAN_TRACK(flags)        (!IS_NMT_RECORDER(flags) && !(IS_MEMORY_TYPE(flags, mtDontTrack)))
+
+typedef unsigned short MEMFLAGS;
+
+extern bool NMT_track_callsite;
+
+// debug build does not inline
+#if defined(_DEBUG_)
+  #define CURRENT_PC       (NMT_track_callsite ? os::get_caller_pc(1) : 0)
+  #define CALLER_PC        (NMT_track_callsite ? os::get_caller_pc(2) : 0)
+  #define CALLER_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(3) : 0)
+#else
+  #define CURRENT_PC      (NMT_track_callsite? os::get_caller_pc(0) : 0)
+  #define CALLER_PC       (NMT_track_callsite ? os::get_caller_pc(1) : 0)
+  #define CALLER_CALLER_PC (NMT_track_callsite ? os::get_caller_pc(2) : 0)
+#endif
+
+
+
+template <MEMFLAGS F> class CHeapObj ALLOCATION_SUPER_CLASS_SPEC {
  public:
-  void* operator new(size_t size);
-  void* operator new (size_t size, const std::nothrow_t&  nothrow_constant);
+  _NOINLINE_ void* operator new(size_t size, address caller_pc = 0);
+  _NOINLINE_ void* operator new (size_t size, const std::nothrow_t&  nothrow_constant,
+                               address caller_pc = 0);
+
   void  operator delete(void* p);
-  void* new_array(size_t size);
 };
 
 // Base class for objects allocated on the stack only.
@@ -150,7 +224,7 @@
 
 //------------------------------Chunk------------------------------------------
 // Linked list of raw memory chunks
-class Chunk: public CHeapObj {
+class Chunk: CHeapObj<mtChunk> {
   friend class VMStructs;
 
  protected:
@@ -197,7 +271,7 @@
 
 //------------------------------Arena------------------------------------------
 // Fast allocation of memory
-class Arena: public CHeapObj {
+class Arena : public CHeapObj<mtNone|otArena> {
 protected:
   friend class ResourceMark;
   friend class HandleMark;
@@ -208,7 +282,8 @@
   Chunk *_chunk;                // current chunk
   char *_hwm, *_max;            // High water mark and max in current chunk
   void* grow(size_t x);         // Get a new Chunk of at least size x
-  NOT_PRODUCT(size_t _size_in_bytes;) // Size of arena (used for memory usage tracing)
+  size_t _size_in_bytes;        // Size of arena (used for native memory tracking)
+
   NOT_PRODUCT(static julong _bytes_allocated;) // total #bytes allocated since start
   friend class AllocStats;
   debug_only(void* malloc(size_t size);)
@@ -226,11 +301,19 @@
  public:
   Arena();
   Arena(size_t init_size);
-  Arena(Arena *old);
   ~Arena();
   void  destruct_contents();
   char* hwm() const             { return _hwm; }
 
+  // new operators
+  void* operator new (size_t size);
+  void* operator new (size_t size, const std::nothrow_t& nothrow_constant);
+
+  // dynamic memory type tagging
+  void* operator new(size_t size, MEMFLAGS flags);
+  void* operator new(size_t size, const std::nothrow_t& nothrow_constant, MEMFLAGS flags);
+  void  operator delete(void* p);
+
   // Fast allocate in the arena.  Common case is: pointer test + increment.
   void* Amalloc(size_t x) {
     assert(is_power_of_2(ARENA_AMALLOC_ALIGNMENT) , "should be a power of 2");
@@ -306,16 +389,20 @@
   size_t used() const;
 
   // Total # of bytes used
-  size_t size_in_bytes() const         NOT_PRODUCT({  return _size_in_bytes; }) PRODUCT_RETURN0;
-  void set_size_in_bytes(size_t size)  NOT_PRODUCT({ _size_in_bytes = size;  }) PRODUCT_RETURN;
+  size_t size_in_bytes() const         {  return _size_in_bytes; };
+  void set_size_in_bytes(size_t size);
+
   static void free_malloced_objects(Chunk* chunk, char* hwm, char* max, char* hwm2)  PRODUCT_RETURN;
   static void free_all(char** start, char** end)                                     PRODUCT_RETURN;
 
+  // how many arena instances
+  NOT_PRODUCT(static volatile jint _instance_count;)
 private:
   // Reset this Arena to empty, access will trigger grow if necessary
   void   reset(void) {
     _first = _chunk = NULL;
     _hwm = _max = NULL;
+    set_size_in_bytes(0);
   }
 };
 
@@ -373,7 +460,7 @@
 #endif // ASSERT
 
  public:
-  void* operator new(size_t size, allocation_type type);
+  void* operator new(size_t size, allocation_type type, MEMFLAGS flags);
   void* operator new(size_t size, Arena *arena) {
       address res = (address)arena->Amalloc(size);
       DEBUG_ONLY(set_allocation_type(res, ARENA);)
@@ -409,17 +496,28 @@
 #define NEW_RESOURCE_OBJ(type)\
   NEW_RESOURCE_ARRAY(type, 1)
 
-#define NEW_C_HEAP_ARRAY(type, size)\
-  (type*) (AllocateHeap((size) * sizeof(type), XSTR(type) " in " __FILE__))
+#define NEW_C_HEAP_ARRAY(type, size, memflags)\
+  (type*) (AllocateHeap((size) * sizeof(type), memflags))
 
-#define REALLOC_C_HEAP_ARRAY(type, old, size)\
-  (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), XSTR(type) " in " __FILE__))
+#define REALLOC_C_HEAP_ARRAY(type, old, size, memflags)\
+  (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags))
 
-#define FREE_C_HEAP_ARRAY(type,old) \
-  FreeHeap((char*)(old))
+#define FREE_C_HEAP_ARRAY(type,old,memflags) \
+  FreeHeap((char*)(old), memflags)
 
-#define NEW_C_HEAP_OBJ(type)\
-  NEW_C_HEAP_ARRAY(type, 1)
+#define NEW_C_HEAP_OBJ(type, memflags)\
+  NEW_C_HEAP_ARRAY(type, 1, memflags)
+
+
+#define NEW_C_HEAP_ARRAY2(type, size, memflags, pc)\
+  (type*) (AllocateHeap((size) * sizeof(type), memflags, pc))
+
+#define REALLOC_C_HEAP_ARRAY2(type, old, size, memflags, pc)\
+  (type*) (ReallocateHeap((char*)old, (size) * sizeof(type), memflags, pc))
+
+#define NEW_C_HEAP_OBJ2(type, memflags, pc)\
+  NEW_C_HEAP_ARRAY2(type, 1, memflags, pc)
+
 
 extern bool warn_new_operator;
 
diff --git a/hotspot/src/share/vm/memory/allocation.inline.hpp b/hotspot/src/share/vm/memory/allocation.inline.hpp
index 795016d..21e8a3b 100644
--- a/hotspot/src/share/vm/memory/allocation.inline.hpp
+++ b/hotspot/src/share/vm/memory/allocation.inline.hpp
@@ -48,33 +48,60 @@
 #endif
 
 // allocate using malloc; will fail if no memory available
-inline char* AllocateHeap(size_t size, const char* name = NULL) {
-  char* p = (char*) os::malloc(size);
+inline char* AllocateHeap(size_t size, MEMFLAGS flags, address pc = 0) {
+  if (pc == 0) {
+    pc = CURRENT_PC;
+  }
+  char* p = (char*) os::malloc(size, flags, pc);
   #ifdef ASSERT
-  if (PrintMallocFree) trace_heap_malloc(size, name, p);
-  #else
-  Unused_Variable(name);
+  if (PrintMallocFree) trace_heap_malloc(size, "AllocateHeap", p);
   #endif
-  if (p == NULL) vm_exit_out_of_memory(size, name);
+  if (p == NULL) vm_exit_out_of_memory(size, "AllocateHeap");
   return p;
 }
 
-inline char* ReallocateHeap(char *old, size_t size, const char* name = NULL) {
-  char* p = (char*) os::realloc(old,size);
+inline char* ReallocateHeap(char *old, size_t size, MEMFLAGS flags) {
+  char* p = (char*) os::realloc(old, size, flags, CURRENT_PC);
   #ifdef ASSERT
-  if (PrintMallocFree) trace_heap_malloc(size, name, p);
-  #else
-  Unused_Variable(name);
+  if (PrintMallocFree) trace_heap_malloc(size, "ReallocateHeap", p);
   #endif
-  if (p == NULL) vm_exit_out_of_memory(size, name);
+  if (p == NULL) vm_exit_out_of_memory(size, "ReallocateHeap");
   return p;
 }
 
-inline void FreeHeap(void* p) {
+inline void FreeHeap(void* p, MEMFLAGS memflags = mtInternal) {
   #ifdef ASSERT
   if (PrintMallocFree) trace_heap_free(p);
   #endif
-  os::free(p);
+  os::free(p, memflags);
 }
 
+
+template <MEMFLAGS F> void* CHeapObj<F>::operator new(size_t size,
+      address caller_pc){
+#ifdef ASSERT
+    void* p = (void*)AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
+    if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
+    return p;
+#else
+    return (void *) AllocateHeap(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
+#endif
+  }
+
+template <MEMFLAGS F> void* CHeapObj<F>::operator new (size_t size,
+  const std::nothrow_t&  nothrow_constant, address caller_pc) {
+#ifdef ASSERT
+    void* p = os::malloc(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
+    if (PrintMallocFree) trace_heap_malloc(size, "CHeapObj-new", p);
+    return p;
+#else
+    return os::malloc(size, F, (caller_pc != 0 ? caller_pc : CALLER_PC));
+#endif
+}
+
+template <MEMFLAGS F> void CHeapObj<F>::operator delete(void* p){
+   FreeHeap(p, F);
+}
+
+
 #endif // SHARE_VM_MEMORY_ALLOCATION_INLINE_HPP
diff --git a/hotspot/src/share/vm/memory/barrierSet.hpp b/hotspot/src/share/vm/memory/barrierSet.hpp
index d9cf3c2..bd92616 100644
--- a/hotspot/src/share/vm/memory/barrierSet.hpp
+++ b/hotspot/src/share/vm/memory/barrierSet.hpp
@@ -31,7 +31,7 @@
 // This class provides the interface between a barrier implementation and
 // the rest of the system.
 
-class BarrierSet: public CHeapObj {
+class BarrierSet: public CHeapObj<mtGC> {
   friend class VMStructs;
 public:
   enum Name {
diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp
new file mode 100644
index 0000000..08a9b03
--- /dev/null
+++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.cpp
@@ -0,0 +1,1346 @@
+/*
+ * Copyright (c) 2001, 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "gc_implementation/shared/allocationStats.hpp"
+#include "memory/binaryTreeDictionary.hpp"
+#include "runtime/globals.hpp"
+#include "utilities/ostream.hpp"
+#ifndef SERIALGC
+#include "gc_implementation/shared/spaceDecorator.hpp"
+#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
+#endif // SERIALGC
+
+////////////////////////////////////////////////////////////////////////////////
+// A binary tree based search structure for free blocks.
+// This is currently used in the Concurrent Mark&Sweep implementation.
+////////////////////////////////////////////////////////////////////////////////
+
+template <class Chunk>
+TreeChunk<Chunk>* TreeChunk<Chunk>::as_TreeChunk(Chunk* fc) {
+  // Do some assertion checking here.
+  return (TreeChunk<Chunk>*) fc;
+}
+
+template <class Chunk>
+void TreeChunk<Chunk>::verify_tree_chunk_list() const {
+  TreeChunk<Chunk>* nextTC = (TreeChunk<Chunk>*)next();
+  if (prev() != NULL) { // interior list node shouldn'r have tree fields
+    guarantee(embedded_list()->parent() == NULL && embedded_list()->left() == NULL &&
+              embedded_list()->right()  == NULL, "should be clear");
+  }
+  if (nextTC != NULL) {
+    guarantee(as_TreeChunk(nextTC->prev()) == this, "broken chain");
+    guarantee(nextTC->size() == size(), "wrong size");
+    nextTC->verify_tree_chunk_list();
+  }
+}
+
+
+template <class Chunk>
+TreeList<Chunk>* TreeList<Chunk>::as_TreeList(TreeChunk<Chunk>* tc) {
+  // This first free chunk in the list will be the tree list.
+  assert(tc->size() >= BinaryTreeDictionary<Chunk>::min_tree_chunk_size, "Chunk is too small for a TreeChunk");
+  TreeList<Chunk>* tl = tc->embedded_list();
+  tc->set_list(tl);
+#ifdef ASSERT
+  tl->set_protecting_lock(NULL);
+#endif
+  tl->set_hint(0);
+  tl->set_size(tc->size());
+  tl->link_head(tc);
+  tl->link_tail(tc);
+  tl->set_count(1);
+  tl->init_statistics(true /* split_birth */);
+  tl->set_parent(NULL);
+  tl->set_left(NULL);
+  tl->set_right(NULL);
+  return tl;
+}
+
+template <class Chunk>
+TreeList<Chunk>* TreeList<Chunk>::as_TreeList(HeapWord* addr, size_t size) {
+  TreeChunk<Chunk>* tc = (TreeChunk<Chunk>*) addr;
+  assert(size >= BinaryTreeDictionary<Chunk>::min_tree_chunk_size, "Chunk is too small for a TreeChunk");
+  // The space in the heap will have been mangled initially but
+  // is not remangled when a free chunk is returned to the free list
+  // (since it is used to maintain the chunk on the free list).
+  assert((ZapUnusedHeapArea &&
+          SpaceMangler::is_mangled((HeapWord*) tc->size_addr()) &&
+          SpaceMangler::is_mangled((HeapWord*) tc->prev_addr()) &&
+          SpaceMangler::is_mangled((HeapWord*) tc->next_addr())) ||
+          (tc->size() == 0 && tc->prev() == NULL && tc->next() == NULL),
+    "Space should be clear or mangled");
+  tc->set_size(size);
+  tc->link_prev(NULL);
+  tc->link_next(NULL);
+  TreeList<Chunk>* tl = TreeList<Chunk>::as_TreeList(tc);
+  return tl;
+}
+
+template <class Chunk>
+TreeList<Chunk>* TreeList<Chunk>::remove_chunk_replace_if_needed(TreeChunk<Chunk>* tc) {
+
+  TreeList<Chunk>* retTL = this;
+  Chunk* list = head();
+  assert(!list || list != list->next(), "Chunk on list twice");
+  assert(tc != NULL, "Chunk being removed is NULL");
+  assert(parent() == NULL || this == parent()->left() ||
+    this == parent()->right(), "list is inconsistent");
+  assert(tc->is_free(), "Header is not marked correctly");
+  assert(head() == NULL || head()->prev() == NULL, "list invariant");
+  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
+
+  Chunk* prevFC = tc->prev();
+  TreeChunk<Chunk>* nextTC = TreeChunk<Chunk>::as_TreeChunk(tc->next());
+  assert(list != NULL, "should have at least the target chunk");
+
+  // Is this the first item on the list?
+  if (tc == list) {
+    // The "getChunk..." functions for a TreeList<Chunk> will not return the
+    // first chunk in the list unless it is the last chunk in the list
+    // because the first chunk is also acting as the tree node.
+    // When coalescing happens, however, the first chunk in the a tree
+    // list can be the start of a free range.  Free ranges are removed
+    // from the free lists so that they are not available to be
+    // allocated when the sweeper yields (giving up the free list lock)
+    // to allow mutator activity.  If this chunk is the first in the
+    // list and is not the last in the list, do the work to copy the
+    // TreeList<Chunk> from the first chunk to the next chunk and update all
+    // the TreeList<Chunk> pointers in the chunks in the list.
+    if (nextTC == NULL) {
+      assert(prevFC == NULL, "Not last chunk in the list");
+      set_tail(NULL);
+      set_head(NULL);
+    } else {
+      // copy embedded list.
+      nextTC->set_embedded_list(tc->embedded_list());
+      retTL = nextTC->embedded_list();
+      // Fix the pointer to the list in each chunk in the list.
+      // This can be slow for a long list.  Consider having
+      // an option that does not allow the first chunk on the
+      // list to be coalesced.
+      for (TreeChunk<Chunk>* curTC = nextTC; curTC != NULL;
+          curTC = TreeChunk<Chunk>::as_TreeChunk(curTC->next())) {
+        curTC->set_list(retTL);
+      }
+      // Fix the parent to point to the new TreeList<Chunk>.
+      if (retTL->parent() != NULL) {
+        if (this == retTL->parent()->left()) {
+          retTL->parent()->set_left(retTL);
+        } else {
+          assert(this == retTL->parent()->right(), "Parent is incorrect");
+          retTL->parent()->set_right(retTL);
+        }
+      }
+      // Fix the children's parent pointers to point to the
+      // new list.
+      assert(right() == retTL->right(), "Should have been copied");
+      if (retTL->right() != NULL) {
+        retTL->right()->set_parent(retTL);
+      }
+      assert(left() == retTL->left(), "Should have been copied");
+      if (retTL->left() != NULL) {
+        retTL->left()->set_parent(retTL);
+      }
+      retTL->link_head(nextTC);
+      assert(nextTC->is_free(), "Should be a free chunk");
+    }
+  } else {
+    if (nextTC == NULL) {
+      // Removing chunk at tail of list
+      link_tail(prevFC);
+    }
+    // Chunk is interior to the list
+    prevFC->link_after(nextTC);
+  }
+
+  // Below this point the embeded TreeList<Chunk> being used for the
+  // tree node may have changed. Don't use "this"
+  // TreeList<Chunk>*.
+  // chunk should still be a free chunk (bit set in _prev)
+  assert(!retTL->head() || retTL->size() == retTL->head()->size(),
+    "Wrong sized chunk in list");
+  debug_only(
+    tc->link_prev(NULL);
+    tc->link_next(NULL);
+    tc->set_list(NULL);
+    bool prev_found = false;
+    bool next_found = false;
+    for (Chunk* curFC = retTL->head();
+         curFC != NULL; curFC = curFC->next()) {
+      assert(curFC != tc, "Chunk is still in list");
+      if (curFC == prevFC) {
+        prev_found = true;
+      }
+      if (curFC == nextTC) {
+        next_found = true;
+      }
+    }
+    assert(prevFC == NULL || prev_found, "Chunk was lost from list");
+    assert(nextTC == NULL || next_found, "Chunk was lost from list");
+    assert(retTL->parent() == NULL ||
+           retTL == retTL->parent()->left() ||
+           retTL == retTL->parent()->right(),
+           "list is inconsistent");
+  )
+  retTL->decrement_count();
+
+  assert(tc->is_free(), "Should still be a free chunk");
+  assert(retTL->head() == NULL || retTL->head()->prev() == NULL,
+    "list invariant");
+  assert(retTL->tail() == NULL || retTL->tail()->next() == NULL,
+    "list invariant");
+  return retTL;
+}
+
+template <class Chunk>
+void TreeList<Chunk>::return_chunk_at_tail(TreeChunk<Chunk>* chunk) {
+  assert(chunk != NULL, "returning NULL chunk");
+  assert(chunk->list() == this, "list should be set for chunk");
+  assert(tail() != NULL, "The tree list is embedded in the first chunk");
+  // which means that the list can never be empty.
+  assert(!verify_chunk_in_free_list(chunk), "Double entry");
+  assert(head() == NULL || head()->prev() == NULL, "list invariant");
+  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
+
+  Chunk* fc = tail();
+  fc->link_after(chunk);
+  link_tail(chunk);
+
+  assert(!tail() || size() == tail()->size(), "Wrong sized chunk in list");
+  increment_count();
+  debug_only(increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
+  assert(head() == NULL || head()->prev() == NULL, "list invariant");
+  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
+}
+
+// Add this chunk at the head of the list.  "At the head of the list"
+// is defined to be after the chunk pointer to by head().  This is
+// because the TreeList<Chunk> is embedded in the first TreeChunk<Chunk> in the
+// list.  See the definition of TreeChunk<Chunk>.
+template <class Chunk>
+void TreeList<Chunk>::return_chunk_at_head(TreeChunk<Chunk>* chunk) {
+  assert(chunk->list() == this, "list should be set for chunk");
+  assert(head() != NULL, "The tree list is embedded in the first chunk");
+  assert(chunk != NULL, "returning NULL chunk");
+  assert(!verify_chunk_in_free_list(chunk), "Double entry");
+  assert(head() == NULL || head()->prev() == NULL, "list invariant");
+  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
+
+  Chunk* fc = head()->next();
+  if (fc != NULL) {
+    chunk->link_after(fc);
+  } else {
+    assert(tail() == NULL, "List is inconsistent");
+    link_tail(chunk);
+  }
+  head()->link_after(chunk);
+  assert(!head() || size() == head()->size(), "Wrong sized chunk in list");
+  increment_count();
+  debug_only(increment_returned_bytes_by(chunk->size()*sizeof(HeapWord));)
+  assert(head() == NULL || head()->prev() == NULL, "list invariant");
+  assert(tail() == NULL || tail()->next() == NULL, "list invariant");
+}
+
+template <class Chunk>
+TreeChunk<Chunk>* TreeList<Chunk>::head_as_TreeChunk() {
+  assert(head() == NULL || TreeChunk<Chunk>::as_TreeChunk(head())->list() == this,
+    "Wrong type of chunk?");
+  return TreeChunk<Chunk>::as_TreeChunk(head());
+}
+
+template <class Chunk>
+TreeChunk<Chunk>* TreeList<Chunk>::first_available() {
+  assert(head() != NULL, "The head of the list cannot be NULL");
+  Chunk* fc = head()->next();
+  TreeChunk<Chunk>* retTC;
+  if (fc == NULL) {
+    retTC = head_as_TreeChunk();
+  } else {
+    retTC = TreeChunk<Chunk>::as_TreeChunk(fc);
+  }
+  assert(retTC->list() == this, "Wrong type of chunk.");
+  return retTC;
+}
+
+// Returns the block with the largest heap address amongst
+// those in the list for this size; potentially slow and expensive,
+// use with caution!
+template <class Chunk>
+TreeChunk<Chunk>* TreeList<Chunk>::largest_address() {
+  assert(head() != NULL, "The head of the list cannot be NULL");
+  Chunk* fc = head()->next();
+  TreeChunk<Chunk>* retTC;
+  if (fc == NULL) {
+    retTC = head_as_TreeChunk();
+  } else {
+    // walk down the list and return the one with the highest
+    // heap address among chunks of this size.
+    Chunk* last = fc;
+    while (fc->next() != NULL) {
+      if ((HeapWord*)last < (HeapWord*)fc) {
+        last = fc;
+      }
+      fc = fc->next();
+    }
+    retTC = TreeChunk<Chunk>::as_TreeChunk(last);
+  }
+  assert(retTC->list() == this, "Wrong type of chunk.");
+  return retTC;
+}
+
+template <class Chunk>
+BinaryTreeDictionary<Chunk>::BinaryTreeDictionary(bool adaptive_freelists, bool splay) :
+  _splay(splay), _adaptive_freelists(adaptive_freelists),
+  _total_size(0), _total_free_blocks(0), _root(0) {}
+
+template <class Chunk>
+BinaryTreeDictionary<Chunk>::BinaryTreeDictionary(MemRegion mr,
+                                           bool adaptive_freelists,
+                                           bool splay):
+  _adaptive_freelists(adaptive_freelists), _splay(splay)
+{
+  assert(mr.word_size() >= BinaryTreeDictionary<Chunk>::min_tree_chunk_size, "minimum chunk size");
+
+  reset(mr);
+  assert(root()->left() == NULL, "reset check failed");
+  assert(root()->right() == NULL, "reset check failed");
+  assert(root()->head()->next() == NULL, "reset check failed");
+  assert(root()->head()->prev() == NULL, "reset check failed");
+  assert(total_size() == root()->size(), "reset check failed");
+  assert(total_free_blocks() == 1, "reset check failed");
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::inc_total_size(size_t inc) {
+  _total_size = _total_size + inc;
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::dec_total_size(size_t dec) {
+  _total_size = _total_size - dec;
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::reset(MemRegion mr) {
+  assert(mr.word_size() >= BinaryTreeDictionary<Chunk>::min_tree_chunk_size, "minimum chunk size");
+  set_root(TreeList<Chunk>::as_TreeList(mr.start(), mr.word_size()));
+  set_total_size(mr.word_size());
+  set_total_free_blocks(1);
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::reset(HeapWord* addr, size_t byte_size) {
+  MemRegion mr(addr, heap_word_size(byte_size));
+  reset(mr);
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::reset() {
+  set_root(NULL);
+  set_total_size(0);
+  set_total_free_blocks(0);
+}
+
+// Get a free block of size at least size from tree, or NULL.
+// If a splay step is requested, the removal algorithm (only) incorporates
+// a splay step as follows:
+// . the search proceeds down the tree looking for a possible
+//   match. At the (closest) matching location, an appropriate splay step is applied
+//   (zig, zig-zig or zig-zag). A chunk of the appropriate size is then returned
+//   if available, and if it's the last chunk, the node is deleted. A deteleted
+//   node is replaced in place by its tree successor.
+template <class Chunk>
+TreeChunk<Chunk>*
+BinaryTreeDictionary<Chunk>::get_chunk_from_tree(size_t size, enum FreeBlockDictionary<Chunk>::Dither dither, bool splay)
+{
+  TreeList<Chunk> *curTL, *prevTL;
+  TreeChunk<Chunk>* retTC = NULL;
+  assert(size >= BinaryTreeDictionary<Chunk>::min_tree_chunk_size, "minimum chunk size");
+  if (FLSVerifyDictionary) {
+    verify_tree();
+  }
+  // starting at the root, work downwards trying to find match.
+  // Remember the last node of size too great or too small.
+  for (prevTL = curTL = root(); curTL != NULL;) {
+    if (curTL->size() == size) {        // exact match
+      break;
+    }
+    prevTL = curTL;
+    if (curTL->size() < size) {        // proceed to right sub-tree
+      curTL = curTL->right();
+    } else {                           // proceed to left sub-tree
+      assert(curTL->size() > size, "size inconsistency");
+      curTL = curTL->left();
+    }
+  }
+  if (curTL == NULL) { // couldn't find exact match
+
+    if (dither == FreeBlockDictionary<Chunk>::exactly) return NULL;
+
+    // try and find the next larger size by walking back up the search path
+    for (curTL = prevTL; curTL != NULL;) {
+      if (curTL->size() >= size) break;
+      else curTL = curTL->parent();
+    }
+    assert(curTL == NULL || curTL->count() > 0,
+      "An empty list should not be in the tree");
+  }
+  if (curTL != NULL) {
+    assert(curTL->size() >= size, "size inconsistency");
+    if (adaptive_freelists()) {
+
+      // A candidate chunk has been found.  If it is already under
+      // populated, get a chunk associated with the hint for this
+      // chunk.
+      if (curTL->surplus() <= 0) {
+        /* Use the hint to find a size with a surplus, and reset the hint. */
+        TreeList<Chunk>* hintTL = curTL;
+        while (hintTL->hint() != 0) {
+          assert(hintTL->hint() == 0 || hintTL->hint() > hintTL->size(),
+            "hint points in the wrong direction");
+          hintTL = find_list(hintTL->hint());
+          assert(curTL != hintTL, "Infinite loop");
+          if (hintTL == NULL ||
+              hintTL == curTL /* Should not happen but protect against it */ ) {
+            // No useful hint.  Set the hint to NULL and go on.
+            curTL->set_hint(0);
+            break;
+          }
+          assert(hintTL->size() > size, "hint is inconsistent");
+          if (hintTL->surplus() > 0) {
+            // The hint led to a list that has a surplus.  Use it.
+            // Set the hint for the candidate to an overpopulated
+            // size.
+            curTL->set_hint(hintTL->size());
+            // Change the candidate.
+            curTL = hintTL;
+            break;
+          }
+          // The evm code reset the hint of the candidate as
+          // at an interim point.  Why?  Seems like this leaves
+          // the hint pointing to a list that didn't work.
+          // curTL->set_hint(hintTL->size());
+        }
+      }
+    }
+    // don't waste time splaying if chunk's singleton
+    if (splay && curTL->head()->next() != NULL) {
+      semi_splay_step(curTL);
+    }
+    retTC = curTL->first_available();
+    assert((retTC != NULL) && (curTL->count() > 0),
+      "A list in the binary tree should not be NULL");
+    assert(retTC->size() >= size,
+      "A chunk of the wrong size was found");
+    remove_chunk_from_tree(retTC);
+    assert(retTC->is_free(), "Header is not marked correctly");
+  }
+
+  if (FLSVerifyDictionary) {
+    verify();
+  }
+  return retTC;
+}
+
+template <class Chunk>
+TreeList<Chunk>* BinaryTreeDictionary<Chunk>::find_list(size_t size) const {
+  TreeList<Chunk>* curTL;
+  for (curTL = root(); curTL != NULL;) {
+    if (curTL->size() == size) {        // exact match
+      break;
+    }
+
+    if (curTL->size() < size) {        // proceed to right sub-tree
+      curTL = curTL->right();
+    } else {                           // proceed to left sub-tree
+      assert(curTL->size() > size, "size inconsistency");
+      curTL = curTL->left();
+    }
+  }
+  return curTL;
+}
+
+
+template <class Chunk>
+bool BinaryTreeDictionary<Chunk>::verify_chunk_in_free_list(Chunk* tc) const {
+  size_t size = tc->size();
+  TreeList<Chunk>* tl = find_list(size);
+  if (tl == NULL) {
+    return false;
+  } else {
+    return tl->verify_chunk_in_free_list(tc);
+  }
+}
+
+template <class Chunk>
+Chunk* BinaryTreeDictionary<Chunk>::find_largest_dict() const {
+  TreeList<Chunk> *curTL = root();
+  if (curTL != NULL) {
+    while(curTL->right() != NULL) curTL = curTL->right();
+    return curTL->largest_address();
+  } else {
+    return NULL;
+  }
+}
+
+// Remove the current chunk from the tree.  If it is not the last
+// chunk in a list on a tree node, just unlink it.
+// If it is the last chunk in the list (the next link is NULL),
+// remove the node and repair the tree.
+template <class Chunk>
+TreeChunk<Chunk>*
+BinaryTreeDictionary<Chunk>::remove_chunk_from_tree(TreeChunk<Chunk>* tc) {
+  assert(tc != NULL, "Should not call with a NULL chunk");
+  assert(tc->is_free(), "Header is not marked correctly");
+
+  TreeList<Chunk> *newTL, *parentTL;
+  TreeChunk<Chunk>* retTC;
+  TreeList<Chunk>* tl = tc->list();
+  debug_only(
+    bool removing_only_chunk = false;
+    if (tl == _root) {
+      if ((_root->left() == NULL) && (_root->right() == NULL)) {
+        if (_root->count() == 1) {
+          assert(_root->head() == tc, "Should only be this one chunk");
+          removing_only_chunk = true;
+        }
+      }
+    }
+  )
+  assert(tl != NULL, "List should be set");
+  assert(tl->parent() == NULL || tl == tl->parent()->left() ||
+         tl == tl->parent()->right(), "list is inconsistent");
+
+  bool complicated_splice = false;
+
+  retTC = tc;
+  // Removing this chunk can have the side effect of changing the node
+  // (TreeList<Chunk>*) in the tree.  If the node is the root, update it.
+  TreeList<Chunk>* replacementTL = tl->remove_chunk_replace_if_needed(tc);
+  assert(tc->is_free(), "Chunk should still be free");
+  assert(replacementTL->parent() == NULL ||
+         replacementTL == replacementTL->parent()->left() ||
+         replacementTL == replacementTL->parent()->right(),
+         "list is inconsistent");
+  if (tl == root()) {
+    assert(replacementTL->parent() == NULL, "Incorrectly replacing root");
+    set_root(replacementTL);
+  }
+  debug_only(
+    if (tl != replacementTL) {
+      assert(replacementTL->head() != NULL,
+        "If the tree list was replaced, it should not be a NULL list");
+      TreeList<Chunk>* rhl = replacementTL->head_as_TreeChunk()->list();
+      TreeList<Chunk>* rtl = TreeChunk<Chunk>::as_TreeChunk(replacementTL->tail())->list();
+      assert(rhl == replacementTL, "Broken head");
+      assert(rtl == replacementTL, "Broken tail");
+      assert(replacementTL->size() == tc->size(),  "Broken size");
+    }
+  )
+
+  // Does the tree need to be repaired?
+  if (replacementTL->count() == 0) {
+    assert(replacementTL->head() == NULL &&
+           replacementTL->tail() == NULL, "list count is incorrect");
+    // Find the replacement node for the (soon to be empty) node being removed.
+    // if we have a single (or no) child, splice child in our stead
+    if (replacementTL->left() == NULL) {
+      // left is NULL so pick right.  right may also be NULL.
+      newTL = replacementTL->right();
+      debug_only(replacementTL->clear_right();)
+    } else if (replacementTL->right() == NULL) {
+      // right is NULL
+      newTL = replacementTL->left();
+      debug_only(replacementTL->clearLeft();)
+    } else {  // we have both children, so, by patriarchal convention,
+              // my replacement is least node in right sub-tree
+      complicated_splice = true;
+      newTL = remove_tree_minimum(replacementTL->right());
+      assert(newTL != NULL && newTL->left() == NULL &&
+             newTL->right() == NULL, "sub-tree minimum exists");
+    }
+    // newTL is the replacement for the (soon to be empty) node.
+    // newTL may be NULL.
+    // should verify; we just cleanly excised our replacement
+    if (FLSVerifyDictionary) {
+      verify_tree();
+    }
+    // first make newTL my parent's child
+    if ((parentTL = replacementTL->parent()) == NULL) {
+      // newTL should be root
+      assert(tl == root(), "Incorrectly replacing root");
+      set_root(newTL);
+      if (newTL != NULL) {
+        newTL->clear_parent();
+      }
+    } else if (parentTL->right() == replacementTL) {
+      // replacementTL is a right child
+      parentTL->set_right(newTL);
+    } else {                                // replacementTL is a left child
+      assert(parentTL->left() == replacementTL, "should be left child");
+      parentTL->set_left(newTL);
+    }
+    debug_only(replacementTL->clear_parent();)
+    if (complicated_splice) {  // we need newTL to get replacementTL's
+                              // two children
+      assert(newTL != NULL &&
+             newTL->left() == NULL && newTL->right() == NULL,
+            "newTL should not have encumbrances from the past");
+      // we'd like to assert as below:
+      // assert(replacementTL->left() != NULL && replacementTL->right() != NULL,
+      //       "else !complicated_splice");
+      // ... however, the above assertion is too strong because we aren't
+      // guaranteed that replacementTL->right() is still NULL.
+      // Recall that we removed
+      // the right sub-tree minimum from replacementTL.
+      // That may well have been its right
+      // child! So we'll just assert half of the above:
+      assert(replacementTL->left() != NULL, "else !complicated_splice");
+      newTL->set_left(replacementTL->left());
+      newTL->set_right(replacementTL->right());
+      debug_only(
+        replacementTL->clear_right();
+        replacementTL->clearLeft();
+      )
+    }
+    assert(replacementTL->right() == NULL &&
+           replacementTL->left() == NULL &&
+           replacementTL->parent() == NULL,
+        "delete without encumbrances");
+  }
+
+  assert(total_size() >= retTC->size(), "Incorrect total size");
+  dec_total_size(retTC->size());     // size book-keeping
+  assert(total_free_blocks() > 0, "Incorrect total count");
+  set_total_free_blocks(total_free_blocks() - 1);
+
+  assert(retTC != NULL, "null chunk?");
+  assert(retTC->prev() == NULL && retTC->next() == NULL,
+         "should return without encumbrances");
+  if (FLSVerifyDictionary) {
+    verify_tree();
+  }
+  assert(!removing_only_chunk || _root == NULL, "root should be NULL");
+  return TreeChunk<Chunk>::as_TreeChunk(retTC);
+}
+
+// Remove the leftmost node (lm) in the tree and return it.
+// If lm has a right child, link it to the left node of
+// the parent of lm.
+template <class Chunk>
+TreeList<Chunk>* BinaryTreeDictionary<Chunk>::remove_tree_minimum(TreeList<Chunk>* tl) {
+  assert(tl != NULL && tl->parent() != NULL, "really need a proper sub-tree");
+  // locate the subtree minimum by walking down left branches
+  TreeList<Chunk>* curTL = tl;
+  for (; curTL->left() != NULL; curTL = curTL->left());
+  // obviously curTL now has at most one child, a right child
+  if (curTL != root()) {  // Should this test just be removed?
+    TreeList<Chunk>* parentTL = curTL->parent();
+    if (parentTL->left() == curTL) { // curTL is a left child
+      parentTL->set_left(curTL->right());
+    } else {
+      // If the list tl has no left child, then curTL may be
+      // the right child of parentTL.
+      assert(parentTL->right() == curTL, "should be a right child");
+      parentTL->set_right(curTL->right());
+    }
+  } else {
+    // The only use of this method would not pass the root of the
+    // tree (as indicated by the assertion above that the tree list
+    // has a parent) but the specification does not explicitly exclude the
+    // passing of the root so accomodate it.
+    set_root(NULL);
+  }
+  debug_only(
+    curTL->clear_parent();  // Test if this needs to be cleared
+    curTL->clear_right();    // recall, above, left child is already null
+  )
+  // we just excised a (non-root) node, we should still verify all tree invariants
+  if (FLSVerifyDictionary) {
+    verify_tree();
+  }
+  return curTL;
+}
+
+// Based on a simplification of the algorithm by Sleator and Tarjan (JACM 1985).
+// The simplifications are the following:
+// . we splay only when we delete (not when we insert)
+// . we apply a single spay step per deletion/access
+// By doing such partial splaying, we reduce the amount of restructuring,
+// while getting a reasonably efficient search tree (we think).
+// [Measurements will be needed to (in)validate this expectation.]
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::semi_splay_step(TreeList<Chunk>* tc) {
+  // apply a semi-splay step at the given node:
+  // . if root, norting needs to be done
+  // . if child of root, splay once
+  // . else zig-zig or sig-zag depending on path from grandparent
+  if (root() == tc) return;
+  warning("*** Splaying not yet implemented; "
+          "tree operations may be inefficient ***");
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::insert_chunk_in_tree(Chunk* fc) {
+  TreeList<Chunk> *curTL, *prevTL;
+  size_t size = fc->size();
+
+  assert(size >= BinaryTreeDictionary<Chunk>::min_tree_chunk_size, "too small to be a TreeList<Chunk>");
+  if (FLSVerifyDictionary) {
+    verify_tree();
+  }
+
+  fc->clear_next();
+  fc->link_prev(NULL);
+
+  // work down from the _root, looking for insertion point
+  for (prevTL = curTL = root(); curTL != NULL;) {
+    if (curTL->size() == size)  // exact match
+      break;
+    prevTL = curTL;
+    if (curTL->size() > size) { // follow left branch
+      curTL = curTL->left();
+    } else {                    // follow right branch
+      assert(curTL->size() < size, "size inconsistency");
+      curTL = curTL->right();
+    }
+  }
+  TreeChunk<Chunk>* tc = TreeChunk<Chunk>::as_TreeChunk(fc);
+  // This chunk is being returned to the binary tree.  Its embedded
+  // TreeList<Chunk> should be unused at this point.
+  tc->initialize();
+  if (curTL != NULL) {          // exact match
+    tc->set_list(curTL);
+    curTL->return_chunk_at_tail(tc);
+  } else {                     // need a new node in tree
+    tc->clear_next();
+    tc->link_prev(NULL);
+    TreeList<Chunk>* newTL = TreeList<Chunk>::as_TreeList(tc);
+    assert(((TreeChunk<Chunk>*)tc)->list() == newTL,
+      "List was not initialized correctly");
+    if (prevTL == NULL) {      // we are the only tree node
+      assert(root() == NULL, "control point invariant");
+      set_root(newTL);
+    } else {                   // insert under prevTL ...
+      if (prevTL->size() < size) {   // am right child
+        assert(prevTL->right() == NULL, "control point invariant");
+        prevTL->set_right(newTL);
+      } else {                       // am left child
+        assert(prevTL->size() > size && prevTL->left() == NULL, "cpt pt inv");
+        prevTL->set_left(newTL);
+      }
+    }
+  }
+  assert(tc->list() != NULL, "Tree list should be set");
+
+  inc_total_size(size);
+  // Method 'total_size_in_tree' walks through the every block in the
+  // tree, so it can cause significant performance loss if there are
+  // many blocks in the tree
+  assert(!FLSVerifyDictionary || total_size_in_tree(root()) == total_size(), "_total_size inconsistency");
+  set_total_free_blocks(total_free_blocks() + 1);
+  if (FLSVerifyDictionary) {
+    verify_tree();
+  }
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::max_chunk_size() const {
+  FreeBlockDictionary<Chunk>::verify_par_locked();
+  TreeList<Chunk>* tc = root();
+  if (tc == NULL) return 0;
+  for (; tc->right() != NULL; tc = tc->right());
+  return tc->size();
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::total_list_length(TreeList<Chunk>* tl) const {
+  size_t res;
+  res = tl->count();
+#ifdef ASSERT
+  size_t cnt;
+  Chunk* tc = tl->head();
+  for (cnt = 0; tc != NULL; tc = tc->next(), cnt++);
+  assert(res == cnt, "The count is not being maintained correctly");
+#endif
+  return res;
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::total_size_in_tree(TreeList<Chunk>* tl) const {
+  if (tl == NULL)
+    return 0;
+  return (tl->size() * total_list_length(tl)) +
+         total_size_in_tree(tl->left())    +
+         total_size_in_tree(tl->right());
+}
+
+template <class Chunk>
+double BinaryTreeDictionary<Chunk>::sum_of_squared_block_sizes(TreeList<Chunk>* const tl) const {
+  if (tl == NULL) {
+    return 0.0;
+  }
+  double size = (double)(tl->size());
+  double curr = size * size * total_list_length(tl);
+  curr += sum_of_squared_block_sizes(tl->left());
+  curr += sum_of_squared_block_sizes(tl->right());
+  return curr;
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::total_free_blocks_in_tree(TreeList<Chunk>* tl) const {
+  if (tl == NULL)
+    return 0;
+  return total_list_length(tl) +
+         total_free_blocks_in_tree(tl->left()) +
+         total_free_blocks_in_tree(tl->right());
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::num_free_blocks() const {
+  assert(total_free_blocks_in_tree(root()) == total_free_blocks(),
+         "_total_free_blocks inconsistency");
+  return total_free_blocks();
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::tree_height_helper(TreeList<Chunk>* tl) const {
+  if (tl == NULL)
+    return 0;
+  return 1 + MAX2(tree_height_helper(tl->left()),
+                  tree_height_helper(tl->right()));
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::treeHeight() const {
+  return tree_height_helper(root());
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::total_nodes_helper(TreeList<Chunk>* tl) const {
+  if (tl == NULL) {
+    return 0;
+  }
+  return 1 + total_nodes_helper(tl->left()) +
+    total_nodes_helper(tl->right());
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::total_nodes_in_tree(TreeList<Chunk>* tl) const {
+  return total_nodes_helper(root());
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::dict_census_udpate(size_t size, bool split, bool birth){
+  TreeList<Chunk>* nd = find_list(size);
+  if (nd) {
+    if (split) {
+      if (birth) {
+        nd->increment_split_births();
+        nd->increment_surplus();
+      }  else {
+        nd->increment_split_deaths();
+        nd->decrement_surplus();
+      }
+    } else {
+      if (birth) {
+        nd->increment_coal_births();
+        nd->increment_surplus();
+      } else {
+        nd->increment_coal_deaths();
+        nd->decrement_surplus();
+      }
+    }
+  }
+  // A list for this size may not be found (nd == 0) if
+  //   This is a death where the appropriate list is now
+  //     empty and has been removed from the list.
+  //   This is a birth associated with a LinAB.  The chunk
+  //     for the LinAB is not in the dictionary.
+}
+
+template <class Chunk>
+bool BinaryTreeDictionary<Chunk>::coal_dict_over_populated(size_t size) {
+  if (FLSAlwaysCoalesceLarge) return true;
+
+  TreeList<Chunk>* list_of_size = find_list(size);
+  // None of requested size implies overpopulated.
+  return list_of_size == NULL || list_of_size->coal_desired() <= 0 ||
+         list_of_size->count() > list_of_size->coal_desired();
+}
+
+// Closures for walking the binary tree.
+//   do_list() walks the free list in a node applying the closure
+//     to each free chunk in the list
+//   do_tree() walks the nodes in the binary tree applying do_list()
+//     to each list at each node.
+
+template <class Chunk>
+class TreeCensusClosure : public StackObj {
+ protected:
+  virtual void do_list(FreeList<Chunk>* fl) = 0;
+ public:
+  virtual void do_tree(TreeList<Chunk>* tl) = 0;
+};
+
+template <class Chunk>
+class AscendTreeCensusClosure : public TreeCensusClosure<Chunk> {
+  using TreeCensusClosure<Chunk>::do_list;
+ public:
+  void do_tree(TreeList<Chunk>* tl) {
+    if (tl != NULL) {
+      do_tree(tl->left());
+      do_list(tl);
+      do_tree(tl->right());
+    }
+  }
+};
+
+template <class Chunk>
+class DescendTreeCensusClosure : public TreeCensusClosure<Chunk> {
+  using TreeCensusClosure<Chunk>::do_list;
+ public:
+  void do_tree(TreeList<Chunk>* tl) {
+    if (tl != NULL) {
+      do_tree(tl->right());
+      do_list(tl);
+      do_tree(tl->left());
+    }
+  }
+};
+
+// For each list in the tree, calculate the desired, desired
+// coalesce, count before sweep, and surplus before sweep.
+template <class Chunk>
+class BeginSweepClosure : public AscendTreeCensusClosure<Chunk> {
+  double _percentage;
+  float _inter_sweep_current;
+  float _inter_sweep_estimate;
+  float _intra_sweep_estimate;
+
+ public:
+  BeginSweepClosure(double p, float inter_sweep_current,
+                              float inter_sweep_estimate,
+                              float intra_sweep_estimate) :
+   _percentage(p),
+   _inter_sweep_current(inter_sweep_current),
+   _inter_sweep_estimate(inter_sweep_estimate),
+   _intra_sweep_estimate(intra_sweep_estimate) { }
+
+  void do_list(FreeList<Chunk>* fl) {
+    double coalSurplusPercent = _percentage;
+    fl->compute_desired(_inter_sweep_current, _inter_sweep_estimate, _intra_sweep_estimate);
+    fl->set_coal_desired((ssize_t)((double)fl->desired() * coalSurplusPercent));
+    fl->set_before_sweep(fl->count());
+    fl->set_bfr_surp(fl->surplus());
+  }
+};
+
+// Used to search the tree until a condition is met.
+// Similar to TreeCensusClosure but searches the
+// tree and returns promptly when found.
+
+template <class Chunk>
+class TreeSearchClosure : public StackObj {
+ protected:
+  virtual bool do_list(FreeList<Chunk>* fl) = 0;
+ public:
+  virtual bool do_tree(TreeList<Chunk>* tl) = 0;
+};
+
+#if 0 //  Don't need this yet but here for symmetry.
+template <class Chunk>
+class AscendTreeSearchClosure : public TreeSearchClosure {
+ public:
+  bool do_tree(TreeList<Chunk>* tl) {
+    if (tl != NULL) {
+      if (do_tree(tl->left())) return true;
+      if (do_list(tl)) return true;
+      if (do_tree(tl->right())) return true;
+    }
+    return false;
+  }
+};
+#endif
+
+template <class Chunk>
+class DescendTreeSearchClosure : public TreeSearchClosure<Chunk> {
+  using TreeSearchClosure<Chunk>::do_list;
+ public:
+  bool do_tree(TreeList<Chunk>* tl) {
+    if (tl != NULL) {
+      if (do_tree(tl->right())) return true;
+      if (do_list(tl)) return true;
+      if (do_tree(tl->left())) return true;
+    }
+    return false;
+  }
+};
+
+// Searches the tree for a chunk that ends at the
+// specified address.
+template <class Chunk>
+class EndTreeSearchClosure : public DescendTreeSearchClosure<Chunk> {
+  HeapWord* _target;
+  Chunk* _found;
+
+ public:
+  EndTreeSearchClosure(HeapWord* target) : _target(target), _found(NULL) {}
+  bool do_list(FreeList<Chunk>* fl) {
+    Chunk* item = fl->head();
+    while (item != NULL) {
+      if (item->end() == _target) {
+        _found = item;
+        return true;
+      }
+      item = item->next();
+    }
+    return false;
+  }
+  Chunk* found() { return _found; }
+};
+
+template <class Chunk>
+Chunk* BinaryTreeDictionary<Chunk>::find_chunk_ends_at(HeapWord* target) const {
+  EndTreeSearchClosure<Chunk> etsc(target);
+  bool found_target = etsc.do_tree(root());
+  assert(found_target || etsc.found() == NULL, "Consistency check");
+  assert(!found_target || etsc.found() != NULL, "Consistency check");
+  return etsc.found();
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::begin_sweep_dict_census(double coalSurplusPercent,
+  float inter_sweep_current, float inter_sweep_estimate, float intra_sweep_estimate) {
+  BeginSweepClosure<Chunk> bsc(coalSurplusPercent, inter_sweep_current,
+                                            inter_sweep_estimate,
+                                            intra_sweep_estimate);
+  bsc.do_tree(root());
+}
+
+// Closures and methods for calculating total bytes returned to the
+// free lists in the tree.
+#ifndef PRODUCT
+template <class Chunk>
+class InitializeDictReturnedBytesClosure : public AscendTreeCensusClosure<Chunk> {
+   public:
+  void do_list(FreeList<Chunk>* fl) {
+    fl->set_returned_bytes(0);
+  }
+};
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::initialize_dict_returned_bytes() {
+  InitializeDictReturnedBytesClosure<Chunk> idrb;
+  idrb.do_tree(root());
+}
+
+template <class Chunk>
+class ReturnedBytesClosure : public AscendTreeCensusClosure<Chunk> {
+  size_t _dict_returned_bytes;
+ public:
+  ReturnedBytesClosure() { _dict_returned_bytes = 0; }
+  void do_list(FreeList<Chunk>* fl) {
+    _dict_returned_bytes += fl->returned_bytes();
+  }
+  size_t dict_returned_bytes() { return _dict_returned_bytes; }
+};
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::sum_dict_returned_bytes() {
+  ReturnedBytesClosure<Chunk> rbc;
+  rbc.do_tree(root());
+
+  return rbc.dict_returned_bytes();
+}
+
+// Count the number of entries in the tree.
+template <class Chunk>
+class treeCountClosure : public DescendTreeCensusClosure<Chunk> {
+ public:
+  uint count;
+  treeCountClosure(uint c) { count = c; }
+  void do_list(FreeList<Chunk>* fl) {
+    count++;
+  }
+};
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::total_count() {
+  treeCountClosure<Chunk> ctc(0);
+  ctc.do_tree(root());
+  return ctc.count;
+}
+#endif // PRODUCT
+
+// Calculate surpluses for the lists in the tree.
+template <class Chunk>
+class setTreeSurplusClosure : public AscendTreeCensusClosure<Chunk> {
+  double percentage;
+ public:
+  setTreeSurplusClosure(double v) { percentage = v; }
+  void do_list(FreeList<Chunk>* fl) {
+    double splitSurplusPercent = percentage;
+    fl->set_surplus(fl->count() -
+                   (ssize_t)((double)fl->desired() * splitSurplusPercent));
+  }
+};
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::set_tree_surplus(double splitSurplusPercent) {
+  setTreeSurplusClosure<Chunk> sts(splitSurplusPercent);
+  sts.do_tree(root());
+}
+
+// Set hints for the lists in the tree.
+template <class Chunk>
+class setTreeHintsClosure : public DescendTreeCensusClosure<Chunk> {
+  size_t hint;
+ public:
+  setTreeHintsClosure(size_t v) { hint = v; }
+  void do_list(FreeList<Chunk>* fl) {
+    fl->set_hint(hint);
+    assert(fl->hint() == 0 || fl->hint() > fl->size(),
+      "Current hint is inconsistent");
+    if (fl->surplus() > 0) {
+      hint = fl->size();
+    }
+  }
+};
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::set_tree_hints(void) {
+  setTreeHintsClosure<Chunk> sth(0);
+  sth.do_tree(root());
+}
+
+// Save count before previous sweep and splits and coalesces.
+template <class Chunk>
+class clearTreeCensusClosure : public AscendTreeCensusClosure<Chunk> {
+  void do_list(FreeList<Chunk>* fl) {
+    fl->set_prev_sweep(fl->count());
+    fl->set_coal_births(0);
+    fl->set_coal_deaths(0);
+    fl->set_split_births(0);
+    fl->set_split_deaths(0);
+  }
+};
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::clear_tree_census(void) {
+  clearTreeCensusClosure<Chunk> ctc;
+  ctc.do_tree(root());
+}
+
+// Do reporting and post sweep clean up.
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::end_sweep_dict_census(double splitSurplusPercent) {
+  // Does walking the tree 3 times hurt?
+  set_tree_surplus(splitSurplusPercent);
+  set_tree_hints();
+  if (PrintGC && Verbose) {
+    report_statistics();
+  }
+  clear_tree_census();
+}
+
+// Print summary statistics
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::report_statistics() const {
+  FreeBlockDictionary<Chunk>::verify_par_locked();
+  gclog_or_tty->print("Statistics for BinaryTreeDictionary:\n"
+         "------------------------------------\n");
+  size_t total_size = total_chunk_size(debug_only(NULL));
+  size_t    free_blocks = num_free_blocks();
+  gclog_or_tty->print("Total Free Space: %d\n", total_size);
+  gclog_or_tty->print("Max   Chunk Size: %d\n", max_chunk_size());
+  gclog_or_tty->print("Number of Blocks: %d\n", free_blocks);
+  if (free_blocks > 0) {
+    gclog_or_tty->print("Av.  Block  Size: %d\n", total_size/free_blocks);
+  }
+  gclog_or_tty->print("Tree      Height: %d\n", treeHeight());
+}
+
+// Print census information - counts, births, deaths, etc.
+// for each list in the tree.  Also print some summary
+// information.
+template <class Chunk>
+class PrintTreeCensusClosure : public AscendTreeCensusClosure<Chunk> {
+  int _print_line;
+  size_t _total_free;
+  FreeList<Chunk> _total;
+
+ public:
+  PrintTreeCensusClosure() {
+    _print_line = 0;
+    _total_free = 0;
+  }
+  FreeList<Chunk>* total() { return &_total; }
+  size_t total_free() { return _total_free; }
+  void do_list(FreeList<Chunk>* fl) {
+    if (++_print_line >= 40) {
+      FreeList<Chunk>::print_labels_on(gclog_or_tty, "size");
+      _print_line = 0;
+    }
+    fl->print_on(gclog_or_tty);
+    _total_free +=            fl->count()            * fl->size()        ;
+    total()->set_count(      total()->count()       + fl->count()      );
+    total()->set_bfr_surp(    total()->bfr_surp()     + fl->bfr_surp()    );
+    total()->set_surplus(    total()->split_deaths() + fl->surplus()    );
+    total()->set_desired(    total()->desired()     + fl->desired()    );
+    total()->set_prev_sweep(  total()->prev_sweep()   + fl->prev_sweep()  );
+    total()->set_before_sweep(total()->before_sweep() + fl->before_sweep());
+    total()->set_coal_births( total()->coal_births()  + fl->coal_births() );
+    total()->set_coal_deaths( total()->coal_deaths()  + fl->coal_deaths() );
+    total()->set_split_births(total()->split_births() + fl->split_births());
+    total()->set_split_deaths(total()->split_deaths() + fl->split_deaths());
+  }
+};
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::print_dict_census(void) const {
+
+  gclog_or_tty->print("\nBinaryTree\n");
+  FreeList<Chunk>::print_labels_on(gclog_or_tty, "size");
+  PrintTreeCensusClosure<Chunk> ptc;
+  ptc.do_tree(root());
+
+  FreeList<Chunk>* total = ptc.total();
+  FreeList<Chunk>::print_labels_on(gclog_or_tty, " ");
+  total->print_on(gclog_or_tty, "TOTAL\t");
+  gclog_or_tty->print(
+              "total_free(words): " SIZE_FORMAT_W(16)
+              " growth: %8.5f  deficit: %8.5f\n",
+              ptc.total_free(),
+              (double)(total->split_births() + total->coal_births()
+                     - total->split_deaths() - total->coal_deaths())
+              /(total->prev_sweep() != 0 ? (double)total->prev_sweep() : 1.0),
+             (double)(total->desired() - total->count())
+             /(total->desired() != 0 ? (double)total->desired() : 1.0));
+}
+
+template <class Chunk>
+class PrintFreeListsClosure : public AscendTreeCensusClosure<Chunk> {
+  outputStream* _st;
+  int _print_line;
+
+ public:
+  PrintFreeListsClosure(outputStream* st) {
+    _st = st;
+    _print_line = 0;
+  }
+  void do_list(FreeList<Chunk>* fl) {
+    if (++_print_line >= 40) {
+      FreeList<Chunk>::print_labels_on(_st, "size");
+      _print_line = 0;
+    }
+    fl->print_on(gclog_or_tty);
+    size_t sz = fl->size();
+    for (Chunk* fc = fl->head(); fc != NULL;
+         fc = fc->next()) {
+      _st->print_cr("\t[" PTR_FORMAT "," PTR_FORMAT ")  %s",
+                    fc, (HeapWord*)fc + sz,
+                    fc->cantCoalesce() ? "\t CC" : "");
+    }
+  }
+};
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::print_free_lists(outputStream* st) const {
+
+  FreeList<Chunk>::print_labels_on(st, "size");
+  PrintFreeListsClosure<Chunk> pflc(st);
+  pflc.do_tree(root());
+}
+
+// Verify the following tree invariants:
+// . _root has no parent
+// . parent and child point to each other
+// . each node's key correctly related to that of its child(ren)
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::verify_tree() const {
+  guarantee(root() == NULL || total_free_blocks() == 0 ||
+    total_size() != 0, "_total_size should't be 0?");
+  guarantee(root() == NULL || root()->parent() == NULL, "_root shouldn't have parent");
+  verify_tree_helper(root());
+}
+
+template <class Chunk>
+size_t BinaryTreeDictionary<Chunk>::verify_prev_free_ptrs(TreeList<Chunk>* tl) {
+  size_t ct = 0;
+  for (Chunk* curFC = tl->head(); curFC != NULL; curFC = curFC->next()) {
+    ct++;
+    assert(curFC->prev() == NULL || curFC->prev()->is_free(),
+      "Chunk should be free");
+  }
+  return ct;
+}
+
+// Note: this helper is recursive rather than iterative, so use with
+// caution on very deep trees; and watch out for stack overflow errors;
+// In general, to be used only for debugging.
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::verify_tree_helper(TreeList<Chunk>* tl) const {
+  if (tl == NULL)
+    return;
+  guarantee(tl->size() != 0, "A list must has a size");
+  guarantee(tl->left()  == NULL || tl->left()->parent()  == tl,
+         "parent<-/->left");
+  guarantee(tl->right() == NULL || tl->right()->parent() == tl,
+         "parent<-/->right");;
+  guarantee(tl->left() == NULL  || tl->left()->size()    <  tl->size(),
+         "parent !> left");
+  guarantee(tl->right() == NULL || tl->right()->size()   >  tl->size(),
+         "parent !< left");
+  guarantee(tl->head() == NULL || tl->head()->is_free(), "!Free");
+  guarantee(tl->head() == NULL || tl->head_as_TreeChunk()->list() == tl,
+    "list inconsistency");
+  guarantee(tl->count() > 0 || (tl->head() == NULL && tl->tail() == NULL),
+    "list count is inconsistent");
+  guarantee(tl->count() > 1 || tl->head() == tl->tail(),
+    "list is incorrectly constructed");
+  size_t count = verify_prev_free_ptrs(tl);
+  guarantee(count == (size_t)tl->count(), "Node count is incorrect");
+  if (tl->head() != NULL) {
+    tl->head_as_TreeChunk()->verify_tree_chunk_list();
+  }
+  verify_tree_helper(tl->left());
+  verify_tree_helper(tl->right());
+}
+
+template <class Chunk>
+void BinaryTreeDictionary<Chunk>::verify() const {
+  verify_tree();
+  guarantee(total_size() == total_size_in_tree(root()), "Total Size inconsistency");
+}
+
+#ifndef SERIALGC
+// Explicitly instantiate these types for FreeChunk.
+template class BinaryTreeDictionary<FreeChunk>;
+template class TreeChunk<FreeChunk>;
+template class TreeList<FreeChunk>;
+#endif // SERIALGC
diff --git a/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp b/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp
new file mode 100644
index 0000000..4b8c0d8
--- /dev/null
+++ b/hotspot/src/share/vm/memory/binaryTreeDictionary.hpp
@@ -0,0 +1,334 @@
+/*
+ * Copyright (c) 2001, 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP
+#define SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP
+
+#include "memory/freeBlockDictionary.hpp"
+#include "memory/freeList.hpp"
+
+/*
+ * A binary tree based search structure for free blocks.
+ * This is currently used in the Concurrent Mark&Sweep implementation, but
+ * will be used for free block management for metadata.
+ */
+
+// A TreeList is a FreeList which can be used to maintain a
+// binary tree of free lists.
+
+template <class Chunk> class TreeChunk;
+template <class Chunk> class BinaryTreeDictionary;
+template <class Chunk> class AscendTreeCensusClosure;
+template <class Chunk> class DescendTreeCensusClosure;
+template <class Chunk> class DescendTreeSearchClosure;
+
+template <class Chunk>
+class TreeList: public FreeList<Chunk> {
+  friend class TreeChunk<Chunk>;
+  friend class BinaryTreeDictionary<Chunk>;
+  friend class AscendTreeCensusClosure<Chunk>;
+  friend class DescendTreeCensusClosure<Chunk>;
+  friend class DescendTreeSearchClosure<Chunk>;
+
+  TreeList<Chunk>* _parent;
+  TreeList<Chunk>* _left;
+  TreeList<Chunk>* _right;
+
+ protected:
+  TreeList<Chunk>* parent() const { return _parent; }
+  TreeList<Chunk>* left()   const { return _left;   }
+  TreeList<Chunk>* right()  const { return _right;  }
+
+  // Explicitly import these names into our namespace to fix name lookup with templates
+  using FreeList<Chunk>::head;
+  using FreeList<Chunk>::set_head;
+
+  using FreeList<Chunk>::tail;
+  using FreeList<Chunk>::set_tail;
+  using FreeList<Chunk>::link_tail;
+
+  using FreeList<Chunk>::increment_count;
+  NOT_PRODUCT(using FreeList<Chunk>::increment_returned_bytes_by;)
+  using FreeList<Chunk>::verify_chunk_in_free_list;
+  using FreeList<Chunk>::size;
+
+  // Accessors for links in tree.
+
+  void set_left(TreeList<Chunk>* tl) {
+    _left   = tl;
+    if (tl != NULL)
+      tl->set_parent(this);
+  }
+  void set_right(TreeList<Chunk>* tl) {
+    _right  = tl;
+    if (tl != NULL)
+      tl->set_parent(this);
+  }
+  void set_parent(TreeList<Chunk>* tl)  { _parent = tl;   }
+
+  void clearLeft()               { _left = NULL;   }
+  void clear_right()              { _right = NULL;  }
+  void clear_parent()             { _parent = NULL; }
+  void initialize()              { clearLeft(); clear_right(), clear_parent(); }
+
+  // For constructing a TreeList from a Tree chunk or
+  // address and size.
+  static TreeList<Chunk>* as_TreeList(TreeChunk<Chunk>* tc);
+  static TreeList<Chunk>* as_TreeList(HeapWord* addr, size_t size);
+
+  // Returns the head of the free list as a pointer to a TreeChunk.
+  TreeChunk<Chunk>* head_as_TreeChunk();
+
+  // Returns the first available chunk in the free list as a pointer
+  // to a TreeChunk.
+  TreeChunk<Chunk>* first_available();
+
+  // Returns the block with the largest heap address amongst
+  // those in the list for this size; potentially slow and expensive,
+  // use with caution!
+  TreeChunk<Chunk>* largest_address();
+
+  // remove_chunk_replace_if_needed() removes the given "tc" from the TreeList.
+  // If "tc" is the first chunk in the list, it is also the
+  // TreeList that is the node in the tree.  remove_chunk_replace_if_needed()
+  // returns the possibly replaced TreeList* for the node in
+  // the tree.  It also updates the parent of the original
+  // node to point to the new node.
+  TreeList<Chunk>* remove_chunk_replace_if_needed(TreeChunk<Chunk>* tc);
+  // See FreeList.
+  void return_chunk_at_head(TreeChunk<Chunk>* tc);
+  void return_chunk_at_tail(TreeChunk<Chunk>* tc);
+};
+
+// A TreeChunk is a subclass of a Chunk that additionally
+// maintains a pointer to the free list on which it is currently
+// linked.
+// A TreeChunk is also used as a node in the binary tree.  This
+// allows the binary tree to be maintained without any additional
+// storage (the free chunks are used).  In a binary tree the first
+// chunk in the free list is also the tree node.  Note that the
+// TreeChunk has an embedded TreeList for this purpose.  Because
+// the first chunk in the list is distinguished in this fashion
+// (also is the node in the tree), it is the last chunk to be found
+// on the free list for a node in the tree and is only removed if
+// it is the last chunk on the free list.
+
+template <class Chunk>
+class TreeChunk : public Chunk {
+  friend class TreeList<Chunk>;
+  TreeList<Chunk>* _list;
+  TreeList<Chunk> _embedded_list;  // if non-null, this chunk is on _list
+ protected:
+  TreeList<Chunk>* embedded_list() const { return (TreeList<Chunk>*) &_embedded_list; }
+  void set_embedded_list(TreeList<Chunk>* v) { _embedded_list = *v; }
+ public:
+  TreeList<Chunk>* list() { return _list; }
+  void set_list(TreeList<Chunk>* v) { _list = v; }
+  static TreeChunk<Chunk>* as_TreeChunk(Chunk* fc);
+  // Initialize fields in a TreeChunk that should be
+  // initialized when the TreeChunk is being added to
+  // a free list in the tree.
+  void initialize() { embedded_list()->initialize(); }
+
+  Chunk* next() const { return Chunk::next(); }
+  Chunk* prev() const { return Chunk::prev(); }
+  size_t size() const volatile { return Chunk::size(); }
+
+  // debugging
+  void verify_tree_chunk_list() const;
+};
+
+
+template <class Chunk>
+class BinaryTreeDictionary: public FreeBlockDictionary<Chunk> {
+  friend class VMStructs;
+  bool       _splay;
+  size_t     _total_size;
+  size_t     _total_free_blocks;
+  TreeList<Chunk>* _root;
+  bool       _adaptive_freelists;
+
+  // private accessors
+  bool splay() const { return _splay; }
+  void set_splay(bool v) { _splay = v; }
+  void set_total_size(size_t v) { _total_size = v; }
+  virtual void inc_total_size(size_t v);
+  virtual void dec_total_size(size_t v);
+  size_t total_free_blocks() const { return _total_free_blocks; }
+  void set_total_free_blocks(size_t v) { _total_free_blocks = v; }
+  TreeList<Chunk>* root() const { return _root; }
+  void set_root(TreeList<Chunk>* v) { _root = v; }
+  bool adaptive_freelists() { return _adaptive_freelists; }
+
+  // This field is added and can be set to point to the
+  // the Mutex used to synchronize access to the
+  // dictionary so that assertion checking can be done.
+  // For example it is set to point to _parDictionaryAllocLock.
+  NOT_PRODUCT(Mutex* _lock;)
+
+  // Remove a chunk of size "size" or larger from the tree and
+  // return it.  If the chunk
+  // is the last chunk of that size, remove the node for that size
+  // from the tree.
+  TreeChunk<Chunk>* get_chunk_from_tree(size_t size, enum FreeBlockDictionary<Chunk>::Dither dither, bool splay);
+  // Return a list of the specified size or NULL from the tree.
+  // The list is not removed from the tree.
+  TreeList<Chunk>* find_list (size_t size) const;
+  // Remove this chunk from the tree.  If the removal results
+  // in an empty list in the tree, remove the empty list.
+  TreeChunk<Chunk>* remove_chunk_from_tree(TreeChunk<Chunk>* tc);
+  // Remove the node in the trees starting at tl that has the
+  // minimum value and return it.  Repair the tree as needed.
+  TreeList<Chunk>* remove_tree_minimum(TreeList<Chunk>* tl);
+  void       semi_splay_step(TreeList<Chunk>* tl);
+  // Add this free chunk to the tree.
+  void       insert_chunk_in_tree(Chunk* freeChunk);
+ public:
+
+  static const size_t min_tree_chunk_size  = sizeof(TreeChunk<Chunk>)/HeapWordSize;
+
+  void       verify_tree() const;
+  // verify that the given chunk is in the tree.
+  bool       verify_chunk_in_free_list(Chunk* tc) const;
+ private:
+  void          verify_tree_helper(TreeList<Chunk>* tl) const;
+  static size_t verify_prev_free_ptrs(TreeList<Chunk>* tl);
+
+  // Returns the total number of chunks in the list.
+  size_t     total_list_length(TreeList<Chunk>* tl) const;
+  // Returns the total number of words in the chunks in the tree
+  // starting at "tl".
+  size_t     total_size_in_tree(TreeList<Chunk>* tl) const;
+  // Returns the sum of the square of the size of each block
+  // in the tree starting at "tl".
+  double     sum_of_squared_block_sizes(TreeList<Chunk>* const tl) const;
+  // Returns the total number of free blocks in the tree starting
+  // at "tl".
+  size_t     total_free_blocks_in_tree(TreeList<Chunk>* tl) const;
+  size_t     num_free_blocks() const;
+  size_t     treeHeight() const;
+  size_t     tree_height_helper(TreeList<Chunk>* tl) const;
+  size_t     total_nodes_in_tree(TreeList<Chunk>* tl) const;
+  size_t     total_nodes_helper(TreeList<Chunk>* tl) const;
+
+ public:
+  // Constructor
+  BinaryTreeDictionary(bool adaptive_freelists, bool splay = false);
+  BinaryTreeDictionary(MemRegion mr, bool adaptive_freelists, bool splay = false);
+
+  // Public accessors
+  size_t total_size() const { return _total_size; }
+
+  // Reset the dictionary to the initial conditions with
+  // a single free chunk.
+  void       reset(MemRegion mr);
+  void       reset(HeapWord* addr, size_t size);
+  // Reset the dictionary to be empty.
+  void       reset();
+
+  // Return a chunk of size "size" or greater from
+  // the tree.
+  // want a better dynamic splay strategy for the future.
+  Chunk* get_chunk(size_t size, enum FreeBlockDictionary<Chunk>::Dither dither) {
+    FreeBlockDictionary<Chunk>::verify_par_locked();
+    Chunk* res = get_chunk_from_tree(size, dither, splay());
+    assert(res == NULL || res->is_free(),
+           "Should be returning a free chunk");
+    return res;
+  }
+
+  void return_chunk(Chunk* chunk) {
+    FreeBlockDictionary<Chunk>::verify_par_locked();
+    insert_chunk_in_tree(chunk);
+  }
+
+  void remove_chunk(Chunk* chunk) {
+    FreeBlockDictionary<Chunk>::verify_par_locked();
+    remove_chunk_from_tree((TreeChunk<Chunk>*)chunk);
+    assert(chunk->is_free(), "Should still be a free chunk");
+  }
+
+  size_t     max_chunk_size() const;
+  size_t     total_chunk_size(debug_only(const Mutex* lock)) const {
+    debug_only(
+      if (lock != NULL && lock->owned_by_self()) {
+        assert(total_size_in_tree(root()) == total_size(),
+               "_total_size inconsistency");
+      }
+    )
+    return total_size();
+  }
+
+  size_t     min_size() const {
+    return min_tree_chunk_size;
+  }
+
+  double     sum_of_squared_block_sizes() const {
+    return sum_of_squared_block_sizes(root());
+  }
+
+  Chunk* find_chunk_ends_at(HeapWord* target) const;
+
+  // Find the list with size "size" in the binary tree and update
+  // the statistics in the list according to "split" (chunk was
+  // split or coalesce) and "birth" (chunk was added or removed).
+  void       dict_census_udpate(size_t size, bool split, bool birth);
+  // Return true if the dictionary is overpopulated (more chunks of
+  // this size than desired) for size "size".
+  bool       coal_dict_over_populated(size_t size);
+  // Methods called at the beginning of a sweep to prepare the
+  // statistics for the sweep.
+  void       begin_sweep_dict_census(double coalSurplusPercent,
+                                  float inter_sweep_current,
+                                  float inter_sweep_estimate,
+                                  float intra_sweep_estimate);
+  // Methods called after the end of a sweep to modify the
+  // statistics for the sweep.
+  void       end_sweep_dict_census(double splitSurplusPercent);
+  // Return the largest free chunk in the tree.
+  Chunk* find_largest_dict() const;
+  // Accessors for statistics
+  void       set_tree_surplus(double splitSurplusPercent);
+  void       set_tree_hints(void);
+  // Reset statistics for all the lists in the tree.
+  void       clear_tree_census(void);
+  // Print the statistcis for all the lists in the tree.  Also may
+  // print out summaries.
+  void       print_dict_census(void) const;
+  void       print_free_lists(outputStream* st) const;
+
+  // For debugging.  Returns the sum of the _returned_bytes for
+  // all lists in the tree.
+  size_t     sum_dict_returned_bytes()     PRODUCT_RETURN0;
+  // Sets the _returned_bytes for all the lists in the tree to zero.
+  void       initialize_dict_returned_bytes()      PRODUCT_RETURN;
+  // For debugging.  Return the total number of chunks in the dictionary.
+  size_t     total_count()       PRODUCT_RETURN0;
+
+  void       report_statistics() const;
+
+  void       verify() const;
+};
+
+#endif // SHARE_VM_MEMORY_BINARYTREEDICTIONARY_HPP
diff --git a/hotspot/src/share/vm/memory/blockOffsetTable.cpp b/hotspot/src/share/vm/memory/blockOffsetTable.cpp
index d40965e..0d607db 100644
--- a/hotspot/src/share/vm/memory/blockOffsetTable.cpp
+++ b/hotspot/src/share/vm/memory/blockOffsetTable.cpp
@@ -30,6 +30,7 @@
 #include "memory/universe.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/java.hpp"
+#include "services/memTracker.hpp"
 
 //////////////////////////////////////////////////////////////////////
 // BlockOffsetSharedArray
@@ -44,6 +45,9 @@
   if (!rs.is_reserved()) {
     vm_exit_during_initialization("Could not reserve enough space for heap offset array");
   }
+
+  MemTracker::record_virtual_memory_type((address)rs.base(), mtGC);
+
   if (!_vs.initialize(rs, 0)) {
     vm_exit_during_initialization("Could not reserve enough space for heap offset array");
   }
diff --git a/hotspot/src/share/vm/memory/blockOffsetTable.hpp b/hotspot/src/share/vm/memory/blockOffsetTable.hpp
index 16f329b..6be35be 100644
--- a/hotspot/src/share/vm/memory/blockOffsetTable.hpp
+++ b/hotspot/src/share/vm/memory/blockOffsetTable.hpp
@@ -100,7 +100,7 @@
 //////////////////////////////////////////////////////////////////////////
 // BlockOffsetSharedArray
 //////////////////////////////////////////////////////////////////////////
-class BlockOffsetSharedArray: public CHeapObj {
+class BlockOffsetSharedArray: public CHeapObj<mtGC> {
   friend class BlockOffsetArray;
   friend class BlockOffsetArrayNonContigSpace;
   friend class BlockOffsetArrayContigSpace;
@@ -289,7 +289,7 @@
   };
 
   static size_t power_to_cards_back(uint i) {
-    return (size_t)(1 << (LogBase * i));
+    return (size_t)1 << (LogBase * i);
   }
   static size_t power_to_words_back(uint i) {
     return power_to_cards_back(i) * N_words;
diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
index acf6413..496b2cb 100644
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.cpp
@@ -33,6 +33,7 @@
 #include "runtime/java.hpp"
 #include "runtime/mutexLocker.hpp"
 #include "runtime/virtualspace.hpp"
+#include "services/memTracker.hpp"
 #ifdef COMPILER1
 #include "c1/c1_LIR.hpp"
 #include "c1/c1_LIRGenerator.hpp"
@@ -90,6 +91,9 @@
   const size_t rs_align = _page_size == (size_t) os::vm_page_size() ? 0 :
     MAX2(_page_size, (size_t) os::vm_allocation_granularity());
   ReservedSpace heap_rs(_byte_map_size, rs_align, false);
+
+  MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtGC);
+
   os::trace_page_sizes("card table", _guard_index + 1, _guard_index + 1,
                        _page_size, heap_rs.base(), heap_rs.size());
   if (!heap_rs.is_reserved()) {
@@ -113,16 +117,17 @@
     // Do better than this for Merlin
     vm_exit_out_of_memory(_page_size, "card table last card");
   }
+
   *guard_card = last_card;
 
    _lowest_non_clean =
-    NEW_C_HEAP_ARRAY(CardArr, max_covered_regions);
+    NEW_C_HEAP_ARRAY(CardArr, max_covered_regions, mtGC);
   _lowest_non_clean_chunk_size =
-    NEW_C_HEAP_ARRAY(size_t, max_covered_regions);
+    NEW_C_HEAP_ARRAY(size_t, max_covered_regions, mtGC);
   _lowest_non_clean_base_chunk_index =
-    NEW_C_HEAP_ARRAY(uintptr_t, max_covered_regions);
+    NEW_C_HEAP_ARRAY(uintptr_t, max_covered_regions, mtGC);
   _last_LNC_resizing_collection =
-    NEW_C_HEAP_ARRAY(int, max_covered_regions);
+    NEW_C_HEAP_ARRAY(int, max_covered_regions, mtGC);
   if (_lowest_non_clean == NULL
       || _lowest_non_clean_chunk_size == NULL
       || _lowest_non_clean_base_chunk_index == NULL
diff --git a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
index 670070dc..ada9542 100644
--- a/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
+++ b/hotspot/src/share/vm/memory/cardTableModRefBS.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -72,6 +72,9 @@
     CT_MR_BS_last_reserved      = 16
   };
 
+  // a word's worth (row) of clean card values
+  static const intptr_t clean_card_row = (intptr_t)(-1);
+
   // dirty and precleaned are equivalent wrt younger_refs_iter.
   static bool card_is_dirty_wrt_gen_iter(jbyte cv) {
     return cv == dirty_card || cv == precleaned_card;
diff --git a/hotspot/src/share/vm/memory/cardTableRS.cpp b/hotspot/src/share/vm/memory/cardTableRS.cpp
index c152d6c..539f706 100644
--- a/hotspot/src/share/vm/memory/cardTableRS.cpp
+++ b/hotspot/src/share/vm/memory/cardTableRS.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -173,6 +173,10 @@
             SharedHeap::heap()->workers()->active_workers()), "Mismatch");
 }
 
+bool ClearNoncleanCardWrapper::is_word_aligned(jbyte* entry) {
+  return (((intptr_t)entry) & (BytesPerWord-1)) == 0;
+}
+
 void ClearNoncleanCardWrapper::do_MemRegion(MemRegion mr) {
   assert(mr.word_size() > 0, "Error");
   assert(_ct->is_aligned(mr.start()), "mr.start() should be card aligned");
@@ -194,6 +198,17 @@
         const MemRegion mrd(start_of_non_clean, end_of_non_clean);
         _dirty_card_closure->do_MemRegion(mrd);
       }
+
+      // fast forward through potential continuous whole-word range of clean cards beginning at a word-boundary
+      if (is_word_aligned(cur_entry)) {
+        jbyte* cur_row = cur_entry - BytesPerWord;
+        while (cur_row >= limit && *((intptr_t*)cur_row) ==  CardTableRS::clean_card_row()) {
+          cur_row -= BytesPerWord;
+        }
+        cur_entry = cur_row + BytesPerWord;
+        cur_hw = _ct->addr_for(cur_entry);
+      }
+
       // Reset the dirty window, while continuing to look
       // for the next dirty card that will start a
       // new dirty window.
diff --git a/hotspot/src/share/vm/memory/cardTableRS.hpp b/hotspot/src/share/vm/memory/cardTableRS.hpp
index a15b85f..1b155a3 100644
--- a/hotspot/src/share/vm/memory/cardTableRS.hpp
+++ b/hotspot/src/share/vm/memory/cardTableRS.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,10 @@
     return CardTableModRefBS::clean_card;
   }
 
+  static intptr_t clean_card_row() {
+    return CardTableModRefBS::clean_card_row;
+  }
+
   static bool
   card_is_dirty_wrt_gen_iter(jbyte cv) {
     return CardTableModRefBS::card_is_dirty_wrt_gen_iter(cv);
@@ -176,6 +180,8 @@
   // Work methods called by the clear_card()
   inline bool clear_card_serial(jbyte* entry);
   inline bool clear_card_parallel(jbyte* entry);
+  // check alignment of pointer
+  bool is_word_aligned(jbyte* entry);
 
 public:
   ClearNoncleanCardWrapper(DirtyCardToOopClosure* dirty_card_closure, CardTableRS* ct);
diff --git a/hotspot/src/share/vm/memory/collectorPolicy.hpp b/hotspot/src/share/vm/memory/collectorPolicy.hpp
index 7030eb7..9b6b2d4 100644
--- a/hotspot/src/share/vm/memory/collectorPolicy.hpp
+++ b/hotspot/src/share/vm/memory/collectorPolicy.hpp
@@ -56,7 +56,7 @@
 class PermanentGenerationSpec;
 class MarkSweepPolicy;
 
-class CollectorPolicy : public CHeapObj {
+class CollectorPolicy : public CHeapObj<mtGC> {
  protected:
   PermanentGenerationSpec *_permanent_generation;
   GCPolicyCounters* _gc_policy_counters;
diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp
index c903bf4..7d1515b 100644
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.cpp
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.cpp
@@ -444,11 +444,11 @@
 }
 
 
-void CompactingPermGenGen::verify(bool allow_dirty) {
-  the_space()->verify(allow_dirty);
+void CompactingPermGenGen::verify() {
+  the_space()->verify();
   if (!SharedSkipVerify && spec()->enable_shared_spaces()) {
-    ro_space()->verify(allow_dirty);
-    rw_space()->verify(allow_dirty);
+    ro_space()->verify();
+    rw_space()->verify();
   }
 }
 
diff --git a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp
index e3428d7..3cab19c 100644
--- a/hotspot/src/share/vm/memory/compactingPermGenGen.hpp
+++ b/hotspot/src/share/vm/memory/compactingPermGenGen.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -230,7 +230,7 @@
                                       void* new_vtable_start,
                                       void* obj);
 
-  void verify(bool allow_dirty);
+  void verify();
 
   // Serialization
   static void initialize_oops() KERNEL_RETURN;
diff --git a/hotspot/src/share/vm/memory/defNewGeneration.cpp b/hotspot/src/share/vm/memory/defNewGeneration.cpp
index 69ae362..452f630 100644
--- a/hotspot/src/share/vm/memory/defNewGeneration.cpp
+++ b/hotspot/src/share/vm/memory/defNewGeneration.cpp
@@ -548,7 +548,7 @@
 
   init_assuming_no_promotion_failure();
 
-  TraceTime t1("GC", PrintGC && !PrintGCDetails, true, gclog_or_tty);
+  TraceTime t1(GCCauseString("GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
   // Capture heap used before collection (for printing).
   size_t gch_prev_used = gch->used();
 
@@ -939,10 +939,10 @@
   }
 }
 
-void DefNewGeneration::verify(bool allow_dirty) {
-  eden()->verify(allow_dirty);
-  from()->verify(allow_dirty);
-    to()->verify(allow_dirty);
+void DefNewGeneration::verify() {
+  eden()->verify();
+  from()->verify();
+    to()->verify();
 }
 
 void DefNewGeneration::print_on(outputStream* st) const {
diff --git a/hotspot/src/share/vm/memory/defNewGeneration.hpp b/hotspot/src/share/vm/memory/defNewGeneration.hpp
index e7b8528..4f959d6 100644
--- a/hotspot/src/share/vm/memory/defNewGeneration.hpp
+++ b/hotspot/src/share/vm/memory/defNewGeneration.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -89,8 +89,8 @@
 
   // Together, these keep <object with a preserved mark, mark value> pairs.
   // They should always contain the same number of elements.
-  Stack<oop>     _objs_with_preserved_marks;
-  Stack<markOop> _preserved_marks_of_objs;
+  Stack<oop, mtGC>     _objs_with_preserved_marks;
+  Stack<markOop, mtGC> _preserved_marks_of_objs;
 
   // Promotion failure handling
   OopClosure *_promo_failure_scan_stack_closure;
@@ -98,7 +98,7 @@
     _promo_failure_scan_stack_closure = scan_stack_closure;
   }
 
-  Stack<oop> _promo_failure_scan_stack;
+  Stack<oop, mtGC> _promo_failure_scan_stack;
   void drain_promo_failure_scan_stack(void);
   bool _promo_failure_drain_in_progress;
 
@@ -340,7 +340,7 @@
   // PrintHeapAtGC support.
   void print_on(outputStream* st) const;
 
-  void verify(bool allow_dirty);
+  void verify();
 
   bool promo_failure_scan_is_complete() const {
     return _promo_failure_scan_stack.is_empty();
diff --git a/hotspot/src/share/vm/memory/dump.cpp b/hotspot/src/share/vm/memory/dump.cpp
index 28a12af..f9dc8b8 100644
--- a/hotspot/src/share/vm/memory/dump.cpp
+++ b/hotspot/src/share/vm/memory/dump.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -231,8 +231,6 @@
     if (obj->is_constMethod()) {
       mark_object(obj);
       mark_object(constMethodOop(obj)->stackmap_data());
-      // Exception tables are needed by ci code during compilation.
-      mark_object(constMethodOop(obj)->exception_table());
     }
 
     // Mark objects referenced by klass objects which are read-only.
@@ -297,16 +295,14 @@
 
       if (obj->blueprint()->oop_is_instanceKlass()) {
         instanceKlass* ik = instanceKlass::cast((klassOop)obj);
-        typeArrayOop inner_classes = ik->inner_classes();
-        if (inner_classes != NULL) {
-          constantPoolOop constants = ik->constants();
-          int n = inner_classes->length();
-          for (int i = 0; i < n; i += instanceKlass::inner_class_next_offset) {
-            int ioff = i + instanceKlass::inner_class_inner_name_offset;
-            int index = inner_classes->ushort_at(ioff);
-            if (index != 0) {
-              _closure->do_symbol(constants->symbol_at_addr(index));
-            }
+        instanceKlassHandle ik_h((klassOop)obj);
+        InnerClassesIterator iter(ik_h);
+        constantPoolOop constants = ik->constants();
+        for (; !iter.done(); iter.next()) {
+          int index = iter.inner_name_index();
+
+          if (index != 0) {
+            _closure->do_symbol(constants->symbol_at_addr(index));
           }
         }
       }
@@ -515,7 +511,6 @@
       for(i = 0; i < methods->length(); i++) {
         methodOop m = methodOop(methods->obj_at(i));
         mark_and_move_for_policy(OP_favor_startup, m->constMethod(), _move_ro);
-        mark_and_move_for_policy(OP_favor_runtime, m->constMethod()->exception_table(), _move_ro);
         mark_and_move_for_policy(OP_favor_runtime, m->constMethod()->stackmap_data(), _move_ro);
       }
 
@@ -1490,12 +1485,11 @@
 
     // sun.io.Converters
     static const char obj_array_sig[] = "[[Ljava/lang/Object;";
-    SymbolTable::lookup(obj_array_sig, (int)strlen(obj_array_sig), THREAD);
+    (void)SymbolTable::new_permanent_symbol(obj_array_sig, THREAD);
 
     // java.util.HashMap
     static const char map_entry_array_sig[] = "[Ljava/util/Map$Entry;";
-    SymbolTable::lookup(map_entry_array_sig, (int)strlen(map_entry_array_sig),
-                        THREAD);
+    (void)SymbolTable::new_permanent_symbol(map_entry_array_sig, THREAD);
 
     tty->print("Loading classes to share ... ");
     while ((fgets(class_name, sizeof class_name, file)) != NULL) {
@@ -1514,7 +1508,7 @@
       computed_jsum = jsum(computed_jsum, class_name, (const int)name_len - 1);
 
       // Got a class name - load it.
-      TempNewSymbol class_name_symbol = SymbolTable::new_symbol(class_name, THREAD);
+      Symbol* class_name_symbol = SymbolTable::new_permanent_symbol(class_name, THREAD);
       guarantee(!HAS_PENDING_EXCEPTION, "Exception creating a symbol.");
       klassOop klass = SystemDictionary::resolve_or_null(class_name_symbol,
                                                          THREAD);
diff --git a/hotspot/src/share/vm/memory/filemap.cpp b/hotspot/src/share/vm/memory/filemap.cpp
index aa9fadc..81b54f8 100644
--- a/hotspot/src/share/vm/memory/filemap.cpp
+++ b/hotspot/src/share/vm/memory/filemap.cpp
@@ -29,6 +29,7 @@
 #include "runtime/arguments.hpp"
 #include "runtime/java.hpp"
 #include "runtime/os.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/defaultStream.hpp"
 
 # include <sys/stat.h>
@@ -358,7 +359,13 @@
   ReservedSpace unmapped_rs = rs.last_part(size);
   mapped_rs.release();
 
-  return map_region(i, true);
+  // This memory still belongs to JavaHeap
+  MemTracker::record_virtual_memory_type((address)unmapped_rs.base(), mtJavaHeap);
+  char* mapped_addr = map_region(i, true);
+  if (mapped_addr != NULL) {
+    MemTracker::record_virtual_memory_type((address)mapped_addr, mtJavaHeap);
+  }
+  return mapped_addr;
 }
 
 
diff --git a/hotspot/src/share/vm/memory/filemap.hpp b/hotspot/src/share/vm/memory/filemap.hpp
index 8d239b8..5c03ae3 100644
--- a/hotspot/src/share/vm/memory/filemap.hpp
+++ b/hotspot/src/share/vm/memory/filemap.hpp
@@ -44,7 +44,7 @@
 
 
 
-class FileMapInfo : public CHeapObj {
+class FileMapInfo : public CHeapObj<mtInternal> {
 private:
   enum {
     _invalid_version = -1,
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp
similarity index 72%
rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp
rename to hotspot/src/share/vm/memory/freeBlockDictionary.cpp
index 1870c1f..3c6c811 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeBlockDictionary.cpp
+++ b/hotspot/src/share/vm/memory/freeBlockDictionary.cpp
@@ -23,7 +23,10 @@
  */
 
 #include "precompiled.hpp"
-#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp"
+#ifndef SERIALGC
+#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
+#endif // SERIALGC
+#include "memory/freeBlockDictionary.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "thread_linux.inline.hpp"
 #endif
@@ -38,19 +41,19 @@
 #endif
 
 #ifndef PRODUCT
-Mutex* FreeBlockDictionary::par_lock() const {
+template <class Chunk> Mutex* FreeBlockDictionary<Chunk>::par_lock() const {
   return _lock;
 }
 
-void FreeBlockDictionary::set_par_lock(Mutex* lock) {
+template <class Chunk> void FreeBlockDictionary<Chunk>::set_par_lock(Mutex* lock) {
   _lock = lock;
 }
 
-void FreeBlockDictionary::verify_par_locked() const {
+template <class Chunk> void FreeBlockDictionary<Chunk>::verify_par_locked() const {
 #ifdef ASSERT
   if (ParallelGCThreads > 0) {
-    Thread* myThread = Thread::current();
-    if (myThread->is_GC_task_thread()) {
+    Thread* my_thread = Thread::current();
+    if (my_thread->is_GC_task_thread()) {
       assert(par_lock() != NULL, "Should be using locking?");
       assert_lock_strong(par_lock());
     }
@@ -58,3 +61,8 @@
 #endif // ASSERT
 }
 #endif
+
+#ifndef SERIALGC
+// Explicitly instantiate for FreeChunk
+template class FreeBlockDictionary<FreeChunk>;
+#endif // SERIALGC
diff --git a/hotspot/src/share/vm/memory/freeBlockDictionary.hpp b/hotspot/src/share/vm/memory/freeBlockDictionary.hpp
new file mode 100644
index 0000000..66ce2be
--- /dev/null
+++ b/hotspot/src/share/vm/memory/freeBlockDictionary.hpp
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2001, 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_MEMORY_FREEBLOCKDICTIONARY_HPP
+#define SHARE_VM_MEMORY_FREEBLOCKDICTIONARY_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/mutex.hpp"
+#include "utilities/debug.hpp"
+#include "utilities/globalDefinitions.hpp"
+#include "utilities/ostream.hpp"
+
+// A FreeBlockDictionary is an abstract superclass that will allow
+// a number of alternative implementations in the future.
+template <class Chunk>
+class FreeBlockDictionary: public CHeapObj<mtGC> {
+ public:
+  enum Dither {
+    atLeast,
+    exactly,
+    roughly
+  };
+  enum DictionaryChoice {
+    dictionaryBinaryTree = 0,
+    dictionarySplayTree  = 1,
+    dictionarySkipList   = 2
+  };
+
+ private:
+  NOT_PRODUCT(Mutex* _lock;)
+
+ public:
+  virtual void       remove_chunk(Chunk* fc) = 0;
+  virtual Chunk*     get_chunk(size_t size, Dither dither = atLeast) = 0;
+  virtual void       return_chunk(Chunk* chunk) = 0;
+  virtual size_t     total_chunk_size(debug_only(const Mutex* lock)) const = 0;
+  virtual size_t     max_chunk_size()   const = 0;
+  virtual size_t     min_size()        const = 0;
+  // Reset the dictionary to the initial conditions for a single
+  // block.
+  virtual void       reset(HeapWord* addr, size_t size) = 0;
+  virtual void       reset() = 0;
+
+  virtual void       dict_census_udpate(size_t size, bool split, bool birth) = 0;
+  virtual bool       coal_dict_over_populated(size_t size) = 0;
+  virtual void       begin_sweep_dict_census(double coalSurplusPercent,
+                       float inter_sweep_current, float inter_sweep_estimate,
+                       float intra__sweep_current) = 0;
+  virtual void       end_sweep_dict_census(double splitSurplusPercent) = 0;
+  virtual Chunk*     find_largest_dict() const = 0;
+  // verify that the given chunk is in the dictionary.
+  virtual bool verify_chunk_in_free_list(Chunk* tc) const = 0;
+
+  // Sigma_{all_free_blocks} (block_size^2)
+  virtual double sum_of_squared_block_sizes() const = 0;
+
+  virtual Chunk* find_chunk_ends_at(HeapWord* target) const = 0;
+  virtual void inc_total_size(size_t v) = 0;
+  virtual void dec_total_size(size_t v) = 0;
+
+  NOT_PRODUCT (
+    virtual size_t   sum_dict_returned_bytes() = 0;
+    virtual void     initialize_dict_returned_bytes() = 0;
+    virtual size_t   total_count() = 0;
+  )
+
+  virtual void       report_statistics() const {
+    gclog_or_tty->print("No statistics available");
+  }
+
+  virtual void       print_dict_census() const = 0;
+  virtual void       print_free_lists(outputStream* st) const = 0;
+
+  virtual void       verify()         const = 0;
+
+  Mutex* par_lock()                const PRODUCT_RETURN0;
+  void   set_par_lock(Mutex* lock)       PRODUCT_RETURN;
+  void   verify_par_locked()       const PRODUCT_RETURN;
+};
+
+#endif // SHARE_VM_MEMORY_FREEBLOCKDICTIONARY_HPP
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp b/hotspot/src/share/vm/memory/freeList.cpp
similarity index 71%
rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp
rename to hotspot/src/share/vm/memory/freeList.cpp
index 192b055..1c60180 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.cpp
+++ b/hotspot/src/share/vm/memory/freeList.cpp
@@ -23,20 +23,25 @@
  */
 
 #include "precompiled.hpp"
-#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp"
-#include "gc_implementation/concurrentMarkSweep/freeList.hpp"
+#include "memory/freeBlockDictionary.hpp"
+#include "memory/freeList.hpp"
 #include "memory/sharedHeap.hpp"
 #include "runtime/globals.hpp"
 #include "runtime/mutex.hpp"
 #include "runtime/vmThread.hpp"
 
+#ifndef SERIALGC
+#include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
+#endif // SERIALGC
+
 // Free list.  A FreeList is used to access a linked list of chunks
 // of space in the heap.  The head and tail are maintained so that
 // items can be (as in the current implementation) added at the
 // at the tail of the list and removed from the head of the list to
 // maintain a FIFO queue.
 
-FreeList::FreeList() :
+template <class Chunk>
+FreeList<Chunk>::FreeList() :
   _head(NULL), _tail(NULL)
 #ifdef ASSERT
   , _protecting_lock(NULL)
@@ -48,7 +53,8 @@
   init_statistics();
 }
 
-FreeList::FreeList(FreeChunk* fc) :
+template <class Chunk>
+FreeList<Chunk>::FreeList(Chunk* fc) :
   _head(fc), _tail(fc)
 #ifdef ASSERT
   , _protecting_lock(NULL)
@@ -59,48 +65,35 @@
   _hint         = 0;
   init_statistics();
 #ifndef PRODUCT
-  _allocation_stats.set_returnedBytes(size() * HeapWordSize);
+  _allocation_stats.set_returned_bytes(size() * HeapWordSize);
 #endif
 }
 
-FreeList::FreeList(HeapWord* addr, size_t size) :
-  _head((FreeChunk*) addr), _tail((FreeChunk*) addr)
-#ifdef ASSERT
-  , _protecting_lock(NULL)
-#endif
-{
-  assert(size > sizeof(FreeChunk), "size is too small");
-  head()->setSize(size);
-  _size         = size;
-  _count        = 1;
-  init_statistics();
-#ifndef PRODUCT
-  _allocation_stats.set_returnedBytes(_size * HeapWordSize);
-#endif
-}
-
-void FreeList::reset(size_t hint) {
+template <class Chunk>
+void FreeList<Chunk>::reset(size_t hint) {
   set_count(0);
   set_head(NULL);
   set_tail(NULL);
   set_hint(hint);
 }
 
-void FreeList::init_statistics(bool split_birth) {
+template <class Chunk>
+void FreeList<Chunk>::init_statistics(bool split_birth) {
   _allocation_stats.initialize(split_birth);
 }
 
-FreeChunk* FreeList::getChunkAtHead() {
+template <class Chunk>
+Chunk* FreeList<Chunk>::get_chunk_at_head() {
   assert_proper_lock_protection();
   assert(head() == NULL || head()->prev() == NULL, "list invariant");
   assert(tail() == NULL || tail()->next() == NULL, "list invariant");
-  FreeChunk* fc = head();
+  Chunk* fc = head();
   if (fc != NULL) {
-    FreeChunk* nextFC = fc->next();
+    Chunk* nextFC = fc->next();
     if (nextFC != NULL) {
       // The chunk fc being removed has a "next".  Set the "next" to the
       // "prev" of fc.
-      nextFC->linkPrev(NULL);
+      nextFC->link_prev(NULL);
     } else { // removed tail of list
       link_tail(NULL);
     }
@@ -113,29 +106,30 @@
 }
 
 
-void FreeList::getFirstNChunksFromList(size_t n, FreeList* fl) {
+template <class Chunk>
+void FreeList<Chunk>::getFirstNChunksFromList(size_t n, FreeList<Chunk>* fl) {
   assert_proper_lock_protection();
   assert(fl->count() == 0, "Precondition");
   if (count() > 0) {
     int k = 1;
     fl->set_head(head()); n--;
-    FreeChunk* tl = head();
+    Chunk* tl = head();
     while (tl->next() != NULL && n > 0) {
       tl = tl->next(); n--; k++;
     }
     assert(tl != NULL, "Loop Inv.");
 
     // First, fix up the list we took from.
-    FreeChunk* new_head = tl->next();
+    Chunk* new_head = tl->next();
     set_head(new_head);
     set_count(count() - k);
     if (new_head == NULL) {
       set_tail(NULL);
     } else {
-      new_head->linkPrev(NULL);
+      new_head->link_prev(NULL);
     }
     // Now we can fix up the tail.
-    tl->linkNext(NULL);
+    tl->link_next(NULL);
     // And return the result.
     fl->set_tail(tl);
     fl->set_count(k);
@@ -143,7 +137,8 @@
 }
 
 // Remove this chunk from the list
-void FreeList::removeChunk(FreeChunk*fc) {
+template <class Chunk>
+void FreeList<Chunk>::remove_chunk(Chunk*fc) {
    assert_proper_lock_protection();
    assert(head() != NULL, "Remove from empty list");
    assert(fc != NULL, "Remove a NULL chunk");
@@ -151,12 +146,12 @@
    assert(head() == NULL || head()->prev() == NULL, "list invariant");
    assert(tail() == NULL || tail()->next() == NULL, "list invariant");
 
-   FreeChunk* prevFC = fc->prev();
-   FreeChunk* nextFC = fc->next();
+   Chunk* prevFC = fc->prev();
+   Chunk* nextFC = fc->next();
    if (nextFC != NULL) {
      // The chunk fc being removed has a "next".  Set the "next" to the
      // "prev" of fc.
-     nextFC->linkPrev(prevFC);
+     nextFC->link_prev(prevFC);
    } else { // removed tail of list
      link_tail(prevFC);
    }
@@ -165,7 +160,7 @@
      assert(nextFC == NULL || nextFC->prev() == NULL,
        "Prev of head should be NULL");
    } else {
-     prevFC->linkNext(nextFC);
+     prevFC->link_next(nextFC);
      assert(tail() != prevFC || prevFC->next() == NULL,
        "Next of tail should be NULL");
    }
@@ -174,10 +169,10 @@
           "H/T/C Inconsistency");
    // clear next and prev fields of fc, debug only
    NOT_PRODUCT(
-     fc->linkPrev(NULL);
-     fc->linkNext(NULL);
+     fc->link_prev(NULL);
+     fc->link_next(NULL);
    )
-   assert(fc->isFree(), "Should still be a free chunk");
+   assert(fc->is_free(), "Should still be a free chunk");
    assert(head() == NULL || head()->prev() == NULL, "list invariant");
    assert(tail() == NULL || tail()->next() == NULL, "list invariant");
    assert(head() == NULL || head()->size() == size(), "wrong item on list");
@@ -185,16 +180,17 @@
 }
 
 // Add this chunk at the head of the list.
-void FreeList::returnChunkAtHead(FreeChunk* chunk, bool record_return) {
+template <class Chunk>
+void FreeList<Chunk>::return_chunk_at_head(Chunk* chunk, bool record_return) {
   assert_proper_lock_protection();
   assert(chunk != NULL, "insert a NULL chunk");
   assert(size() == chunk->size(), "Wrong size");
   assert(head() == NULL || head()->prev() == NULL, "list invariant");
   assert(tail() == NULL || tail()->next() == NULL, "list invariant");
 
-  FreeChunk* oldHead = head();
+  Chunk* oldHead = head();
   assert(chunk != oldHead, "double insertion");
-  chunk->linkAfter(oldHead);
+  chunk->link_after(oldHead);
   link_head(chunk);
   if (oldHead == NULL) { // only chunk in list
     assert(tail() == NULL, "inconsistent FreeList");
@@ -203,7 +199,7 @@
   increment_count(); // of # of chunks in list
   DEBUG_ONLY(
     if (record_return) {
-      increment_returnedBytes_by(size()*HeapWordSize);
+      increment_returned_bytes_by(size()*HeapWordSize);
     }
   )
   assert(head() == NULL || head()->prev() == NULL, "list invariant");
@@ -212,23 +208,25 @@
   assert(tail() == NULL || tail()->size() == size(), "wrong item on list");
 }
 
-void FreeList::returnChunkAtHead(FreeChunk* chunk) {
+template <class Chunk>
+void FreeList<Chunk>::return_chunk_at_head(Chunk* chunk) {
   assert_proper_lock_protection();
-  returnChunkAtHead(chunk, true);
+  return_chunk_at_head(chunk, true);
 }
 
 // Add this chunk at the tail of the list.
-void FreeList::returnChunkAtTail(FreeChunk* chunk, bool record_return) {
+template <class Chunk>
+void FreeList<Chunk>::return_chunk_at_tail(Chunk* chunk, bool record_return) {
   assert_proper_lock_protection();
   assert(head() == NULL || head()->prev() == NULL, "list invariant");
   assert(tail() == NULL || tail()->next() == NULL, "list invariant");
   assert(chunk != NULL, "insert a NULL chunk");
   assert(size() == chunk->size(), "wrong size");
 
-  FreeChunk* oldTail = tail();
+  Chunk* oldTail = tail();
   assert(chunk != oldTail, "double insertion");
   if (oldTail != NULL) {
-    oldTail->linkAfter(chunk);
+    oldTail->link_after(chunk);
   } else { // only chunk in list
     assert(head() == NULL, "inconsistent FreeList");
     link_head(chunk);
@@ -237,7 +235,7 @@
   increment_count();  // of # of chunks in list
   DEBUG_ONLY(
     if (record_return) {
-      increment_returnedBytes_by(size()*HeapWordSize);
+      increment_returned_bytes_by(size()*HeapWordSize);
     }
   )
   assert(head() == NULL || head()->prev() == NULL, "list invariant");
@@ -246,11 +244,13 @@
   assert(tail() == NULL || tail()->size() == size(), "wrong item on list");
 }
 
-void FreeList::returnChunkAtTail(FreeChunk* chunk) {
-  returnChunkAtTail(chunk, true);
+template <class Chunk>
+void FreeList<Chunk>::return_chunk_at_tail(Chunk* chunk) {
+  return_chunk_at_tail(chunk, true);
 }
 
-void FreeList::prepend(FreeList* fl) {
+template <class Chunk>
+void FreeList<Chunk>::prepend(FreeList<Chunk>* fl) {
   assert_proper_lock_protection();
   if (fl->count() > 0) {
     if (count() == 0) {
@@ -259,11 +259,11 @@
       set_count(fl->count());
     } else {
       // Both are non-empty.
-      FreeChunk* fl_tail = fl->tail();
-      FreeChunk* this_head = head();
+      Chunk* fl_tail = fl->tail();
+      Chunk* this_head = head();
       assert(fl_tail->next() == NULL, "Well-formedness of fl");
-      fl_tail->linkNext(this_head);
-      this_head->linkPrev(fl_tail);
+      fl_tail->link_next(this_head);
+      this_head->link_prev(fl_tail);
       set_head(fl->head());
       set_count(count() + fl->count());
     }
@@ -273,13 +273,14 @@
   }
 }
 
-// verifyChunkInFreeLists() is used to verify that an item is in this free list.
+// verify_chunk_in_free_list() is used to verify that an item is in this free list.
 // It is used as a debugging aid.
-bool FreeList::verifyChunkInFreeLists(FreeChunk* fc) const {
+template <class Chunk>
+bool FreeList<Chunk>::verify_chunk_in_free_list(Chunk* fc) const {
   // This is an internal consistency check, not part of the check that the
   // chunk is in the free lists.
   guarantee(fc->size() == size(), "Wrong list is being searched");
-  FreeChunk* curFC = head();
+  Chunk* curFC = head();
   while (curFC) {
     // This is an internal consistency check.
     guarantee(size() == curFC->size(), "Chunk is in wrong list.");
@@ -292,7 +293,8 @@
 }
 
 #ifndef PRODUCT
-void FreeList::verify_stats() const {
+template <class Chunk>
+void FreeList<Chunk>::verify_stats() const {
   // The +1 of the LH comparand is to allow some "looseness" in
   // checking: we usually call this interface when adding a block
   // and we'll subsequently update the stats; we cannot update the
@@ -300,24 +302,25 @@
   // dictionary for example, this might be the first block and
   // in that case there would be no place that we could record
   // the stats (which are kept in the block itself).
-  assert((_allocation_stats.prevSweep() + _allocation_stats.splitBirths()
-          + _allocation_stats.coalBirths() + 1)   // Total Production Stock + 1
-         >= (_allocation_stats.splitDeaths() + _allocation_stats.coalDeaths()
+  assert((_allocation_stats.prev_sweep() + _allocation_stats.split_births()
+          + _allocation_stats.coal_births() + 1)   // Total Production Stock + 1
+         >= (_allocation_stats.split_deaths() + _allocation_stats.coal_deaths()
              + (ssize_t)count()),                // Total Current Stock + depletion
          err_msg("FreeList " PTR_FORMAT " of size " SIZE_FORMAT
                  " violates Conservation Principle: "
-                 "prevSweep(" SIZE_FORMAT ")"
-                 " + splitBirths(" SIZE_FORMAT ")"
-                 " + coalBirths(" SIZE_FORMAT ") + 1 >= "
-                 " splitDeaths(" SIZE_FORMAT ")"
-                 " coalDeaths(" SIZE_FORMAT ")"
+                 "prev_sweep(" SIZE_FORMAT ")"
+                 " + split_births(" SIZE_FORMAT ")"
+                 " + coal_births(" SIZE_FORMAT ") + 1 >= "
+                 " split_deaths(" SIZE_FORMAT ")"
+                 " coal_deaths(" SIZE_FORMAT ")"
                  " + count(" SSIZE_FORMAT ")",
-                 this, _size, _allocation_stats.prevSweep(), _allocation_stats.splitBirths(),
-                 _allocation_stats.splitBirths(), _allocation_stats.splitDeaths(),
-                 _allocation_stats.coalDeaths(), count()));
+                 this, _size, _allocation_stats.prev_sweep(), _allocation_stats.split_births(),
+                 _allocation_stats.split_births(), _allocation_stats.split_deaths(),
+                 _allocation_stats.coal_deaths(), count()));
 }
 
-void FreeList::assert_proper_lock_protection_work() const {
+template <class Chunk>
+void FreeList<Chunk>::assert_proper_lock_protection_work() const {
   assert(_protecting_lock != NULL, "Don't call this directly");
   assert(ParallelGCThreads > 0, "Don't call this directly");
   Thread* thr = Thread::current();
@@ -334,7 +337,8 @@
 #endif
 
 // Print the "label line" for free list stats.
-void FreeList::print_labels_on(outputStream* st, const char* c) {
+template <class Chunk>
+void FreeList<Chunk>::print_labels_on(outputStream* st, const char* c) {
   st->print("%16s\t", c);
   st->print("%14s\t"    "%14s\t"    "%14s\t"    "%14s\t"    "%14s\t"
             "%14s\t"    "%14s\t"    "%14s\t"    "%14s\t"    "%14s\t"    "\n",
@@ -346,7 +350,8 @@
 // to the call is a non-null string, it is printed in the first column;
 // otherwise, if the argument is null (the default), then the size of the
 // (free list) block is printed in the first column.
-void FreeList::print_on(outputStream* st, const char* c) const {
+template <class Chunk>
+void FreeList<Chunk>::print_on(outputStream* st, const char* c) const {
   if (c != NULL) {
     st->print("%16s", c);
   } else {
@@ -355,6 +360,11 @@
   st->print("\t"
            SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t"
            SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\t" SSIZE_FORMAT_W(14) "\n",
-           bfrSurp(),             surplus(),             desired(),             prevSweep(),           beforeSweep(),
-           count(),               coalBirths(),          coalDeaths(),          splitBirths(),         splitDeaths());
+           bfr_surp(),             surplus(),             desired(),             prev_sweep(),           before_sweep(),
+           count(),               coal_births(),          coal_deaths(),          split_births(),         split_deaths());
 }
+
+#ifndef SERIALGC
+// Needs to be after the definitions have been seen.
+template class FreeList<FreeChunk>;
+#endif // SERIALGC
diff --git a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp b/hotspot/src/share/vm/memory/freeList.hpp
similarity index 67%
rename from hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp
rename to hotspot/src/share/vm/memory/freeList.hpp
index 44afe8e..d306578 100644
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/freeList.hpp
+++ b/hotspot/src/share/vm/memory/freeList.hpp
@@ -22,39 +22,36 @@
  *
  */
 
-#ifndef SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREELIST_HPP
-#define SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREELIST_HPP
+#ifndef SHARE_VM_MEMORY_FREELIST_HPP
+#define SHARE_VM_MEMORY_FREELIST_HPP
 
 #include "gc_implementation/shared/allocationStats.hpp"
 
 class CompactibleFreeListSpace;
 
-// A class for maintaining a free list of FreeChunk's.  The FreeList
+// A class for maintaining a free list of Chunk's.  The FreeList
 // maintains a the structure of the list (head, tail, etc.) plus
 // statistics for allocations from the list.  The links between items
 // are not part of FreeList.  The statistics are
-// used to make decisions about coalescing FreeChunk's when they
+// used to make decisions about coalescing Chunk's when they
 // are swept during collection.
 //
 // See the corresponding .cpp file for a description of the specifics
 // for that implementation.
 
 class Mutex;
-class TreeList;
+template <class Chunk> class TreeList;
+template <class Chunk> class PrintTreeCensusClosure;
 
+template <class Chunk>
 class FreeList VALUE_OBJ_CLASS_SPEC {
   friend class CompactibleFreeListSpace;
   friend class VMStructs;
-  friend class PrintTreeCensusClosure;
-
- protected:
-  TreeList* _parent;
-  TreeList* _left;
-  TreeList* _right;
+  friend class PrintTreeCensusClosure<Chunk>;
 
  private:
-  FreeChunk*    _head;          // Head of list of free chunks
-  FreeChunk*    _tail;          // Tail of list of free chunks
+  Chunk*        _head;          // Head of list of free chunks
+  Chunk*        _tail;          // Tail of list of free chunks
   size_t        _size;          // Size in Heap words of each chunk
   ssize_t       _count;         // Number of entries in list
   size_t        _hint;          // next larger size list with a positive surplus
@@ -92,10 +89,7 @@
   // Construct a list without any entries.
   FreeList();
   // Construct a list with "fc" as the first (and lone) entry in the list.
-  FreeList(FreeChunk* fc);
-  // Construct a list which will have a FreeChunk at address "addr" and
-  // of size "size" as the first (and lone) entry in the list.
-  FreeList(HeapWord* addr, size_t size);
+  FreeList(Chunk* fc);
 
   // Reset the head, tail, hint, and count of a free list.
   void reset(size_t hint);
@@ -108,43 +102,43 @@
 #endif
 
   // Accessors.
-  FreeChunk* head() const {
+  Chunk* head() const {
     assert_proper_lock_protection();
     return _head;
   }
-  void set_head(FreeChunk* v) {
+  void set_head(Chunk* v) {
     assert_proper_lock_protection();
     _head = v;
     assert(!_head || _head->size() == _size, "bad chunk size");
   }
   // Set the head of the list and set the prev field of non-null
   // values to NULL.
-  void link_head(FreeChunk* v) {
+  void link_head(Chunk* v) {
     assert_proper_lock_protection();
     set_head(v);
     // If this method is not used (just set the head instead),
     // this check can be avoided.
     if (v != NULL) {
-      v->linkPrev(NULL);
+      v->link_prev(NULL);
     }
   }
 
-  FreeChunk* tail() const {
+  Chunk* tail() const {
     assert_proper_lock_protection();
     return _tail;
   }
-  void set_tail(FreeChunk* v) {
+  void set_tail(Chunk* v) {
     assert_proper_lock_protection();
     _tail = v;
     assert(!_tail || _tail->size() == _size, "bad chunk size");
   }
   // Set the tail of the list and set the next field of non-null
   // values to NULL.
-  void link_tail(FreeChunk* v) {
+  void link_tail(Chunk* v) {
     assert_proper_lock_protection();
     set_tail(v);
     if (v != NULL) {
-      v->clearNext();
+      v->clear_next();
     }
   }
 
@@ -191,12 +185,12 @@
                                       inter_sweep_estimate,
                                       intra_sweep_estimate);
   }
-  ssize_t coalDesired() const {
-    return _allocation_stats.coalDesired();
+  ssize_t coal_desired() const {
+    return _allocation_stats.coal_desired();
   }
-  void set_coalDesired(ssize_t v) {
+  void set_coal_desired(ssize_t v) {
     assert_proper_lock_protection();
-    _allocation_stats.set_coalDesired(v);
+    _allocation_stats.set_coal_desired(v);
   }
 
   ssize_t surplus() const {
@@ -215,114 +209,114 @@
     _allocation_stats.decrement_surplus();
   }
 
-  ssize_t bfrSurp() const {
-    return _allocation_stats.bfrSurp();
+  ssize_t bfr_surp() const {
+    return _allocation_stats.bfr_surp();
   }
-  void set_bfrSurp(ssize_t v) {
+  void set_bfr_surp(ssize_t v) {
     assert_proper_lock_protection();
-    _allocation_stats.set_bfrSurp(v);
+    _allocation_stats.set_bfr_surp(v);
   }
-  ssize_t prevSweep() const {
-    return _allocation_stats.prevSweep();
+  ssize_t prev_sweep() const {
+    return _allocation_stats.prev_sweep();
   }
-  void set_prevSweep(ssize_t v) {
+  void set_prev_sweep(ssize_t v) {
     assert_proper_lock_protection();
-    _allocation_stats.set_prevSweep(v);
+    _allocation_stats.set_prev_sweep(v);
   }
-  ssize_t beforeSweep() const {
-    return _allocation_stats.beforeSweep();
+  ssize_t before_sweep() const {
+    return _allocation_stats.before_sweep();
   }
-  void set_beforeSweep(ssize_t v) {
+  void set_before_sweep(ssize_t v) {
     assert_proper_lock_protection();
-    _allocation_stats.set_beforeSweep(v);
+    _allocation_stats.set_before_sweep(v);
   }
 
-  ssize_t coalBirths() const {
-    return _allocation_stats.coalBirths();
+  ssize_t coal_births() const {
+    return _allocation_stats.coal_births();
   }
-  void set_coalBirths(ssize_t v) {
+  void set_coal_births(ssize_t v) {
     assert_proper_lock_protection();
-    _allocation_stats.set_coalBirths(v);
+    _allocation_stats.set_coal_births(v);
   }
-  void increment_coalBirths() {
+  void increment_coal_births() {
     assert_proper_lock_protection();
-    _allocation_stats.increment_coalBirths();
+    _allocation_stats.increment_coal_births();
   }
 
-  ssize_t coalDeaths() const {
-    return _allocation_stats.coalDeaths();
+  ssize_t coal_deaths() const {
+    return _allocation_stats.coal_deaths();
   }
-  void set_coalDeaths(ssize_t v) {
+  void set_coal_deaths(ssize_t v) {
     assert_proper_lock_protection();
-    _allocation_stats.set_coalDeaths(v);
+    _allocation_stats.set_coal_deaths(v);
   }
-  void increment_coalDeaths() {
+  void increment_coal_deaths() {
     assert_proper_lock_protection();
-    _allocation_stats.increment_coalDeaths();
+    _allocation_stats.increment_coal_deaths();
   }
 
-  ssize_t splitBirths() const {
-    return _allocation_stats.splitBirths();
+  ssize_t split_births() const {
+    return _allocation_stats.split_births();
   }
-  void set_splitBirths(ssize_t v) {
+  void set_split_births(ssize_t v) {
     assert_proper_lock_protection();
-    _allocation_stats.set_splitBirths(v);
+    _allocation_stats.set_split_births(v);
   }
-  void increment_splitBirths() {
+  void increment_split_births() {
     assert_proper_lock_protection();
-    _allocation_stats.increment_splitBirths();
+    _allocation_stats.increment_split_births();
   }
 
-  ssize_t splitDeaths() const {
-    return _allocation_stats.splitDeaths();
+  ssize_t split_deaths() const {
+    return _allocation_stats.split_deaths();
   }
-  void set_splitDeaths(ssize_t v) {
+  void set_split_deaths(ssize_t v) {
     assert_proper_lock_protection();
-    _allocation_stats.set_splitDeaths(v);
+    _allocation_stats.set_split_deaths(v);
   }
-  void increment_splitDeaths() {
+  void increment_split_deaths() {
     assert_proper_lock_protection();
-    _allocation_stats.increment_splitDeaths();
+    _allocation_stats.increment_split_deaths();
   }
 
   NOT_PRODUCT(
-    // For debugging.  The "_returnedBytes" in all the lists are summed
+    // For debugging.  The "_returned_bytes" in all the lists are summed
     // and compared with the total number of bytes swept during a
     // collection.
-    size_t returnedBytes() const { return _allocation_stats.returnedBytes(); }
-    void set_returnedBytes(size_t v) { _allocation_stats.set_returnedBytes(v); }
-    void increment_returnedBytes_by(size_t v) {
-      _allocation_stats.set_returnedBytes(_allocation_stats.returnedBytes() + v);
+    size_t returned_bytes() const { return _allocation_stats.returned_bytes(); }
+    void set_returned_bytes(size_t v) { _allocation_stats.set_returned_bytes(v); }
+    void increment_returned_bytes_by(size_t v) {
+      _allocation_stats.set_returned_bytes(_allocation_stats.returned_bytes() + v);
     }
   )
 
   // Unlink head of list and return it.  Returns NULL if
   // the list is empty.
-  FreeChunk* getChunkAtHead();
+  Chunk* get_chunk_at_head();
 
   // Remove the first "n" or "count", whichever is smaller, chunks from the
   // list, setting "fl", which is required to be empty, to point to them.
-  void getFirstNChunksFromList(size_t n, FreeList* fl);
+  void getFirstNChunksFromList(size_t n, FreeList<Chunk>* fl);
 
   // Unlink this chunk from it's free list
-  void removeChunk(FreeChunk* fc);
+  void remove_chunk(Chunk* fc);
 
   // Add this chunk to this free list.
-  void returnChunkAtHead(FreeChunk* fc);
-  void returnChunkAtTail(FreeChunk* fc);
+  void return_chunk_at_head(Chunk* fc);
+  void return_chunk_at_tail(Chunk* fc);
 
   // Similar to returnChunk* but also records some diagnostic
   // information.
-  void returnChunkAtHead(FreeChunk* fc, bool record_return);
-  void returnChunkAtTail(FreeChunk* fc, bool record_return);
+  void return_chunk_at_head(Chunk* fc, bool record_return);
+  void return_chunk_at_tail(Chunk* fc, bool record_return);
 
   // Prepend "fl" (whose size is required to be the same as that of "this")
   // to the front of "this" list.
-  void prepend(FreeList* fl);
+  void prepend(FreeList<Chunk>* fl);
 
   // Verify that the chunk is in the list.
   // found.  Return NULL if "fc" is not found.
-  bool verifyChunkInFreeLists(FreeChunk* fc) const;
+  bool verify_chunk_in_free_list(Chunk* fc) const;
 
   // Stats verification
   void verify_stats() const PRODUCT_RETURN;
@@ -332,4 +326,4 @@
   void print_on(outputStream* st, const char* c = NULL) const;
 };
 
-#endif // SHARE_VM_GC_IMPLEMENTATION_CONCURRENTMARKSWEEP_FREELIST_HPP
+#endif // SHARE_VM_MEMORY_FREELIST_HPP
diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.cpp b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
index 3cd791d..1953480 100644
--- a/hotspot/src/share/vm/memory/genCollectedHeap.cpp
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.cpp
@@ -51,6 +51,7 @@
 #include "runtime/java.hpp"
 #include "runtime/vmThread.hpp"
 #include "services/memoryService.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/vmError.hpp"
 #include "utilities/workgroup.hpp"
 #ifndef SERIALGC
@@ -171,9 +172,13 @@
     ReservedSpace this_rs = heap_rs.first_part(_gen_specs[i]->max_size(),
                                               UseSharedSpaces, UseSharedSpaces);
     _gens[i] = _gen_specs[i]->init(this_rs, i, rem_set());
+    // tag generations in JavaHeap
+    MemTracker::record_virtual_memory_type((address)this_rs.base(), mtJavaHeap);
     heap_rs = heap_rs.last_part(_gen_specs[i]->max_size());
   }
   _perm_gen = perm_gen_spec->init(heap_rs, PermSize, rem_set());
+  // tag PermGen
+  MemTracker::record_virtual_memory_type((address)heap_rs.base(), mtJavaHeap);
 
   clear_incremental_collection_failed();
 
@@ -480,26 +485,15 @@
   const size_t perm_prev_used = perm_gen()->used();
 
   print_heap_before_gc();
-  if (Verbose) {
-    gclog_or_tty->print_cr("GC Cause: %s", GCCause::to_string(gc_cause()));
-  }
 
   {
     FlagSetting fl(_is_gc_active, true);
 
     bool complete = full && (max_level == (n_gens()-1));
-    const char* gc_cause_str = "GC ";
-    if (complete) {
-      GCCause::Cause cause = gc_cause();
-      if (cause == GCCause::_java_lang_system_gc) {
-        gc_cause_str = "Full GC (System) ";
-      } else {
-        gc_cause_str = "Full GC ";
-      }
-    }
+    const char* gc_cause_prefix = complete ? "Full GC" : "GC";
     gclog_or_tty->date_stamp(PrintGC && PrintGCDateStamps);
     TraceCPUTime tcpu(PrintGCDetails, true, gclog_or_tty);
-    TraceTime t(gc_cause_str, PrintGCDetails, false, gclog_or_tty);
+    TraceTime t(GCCauseString(gc_cause_prefix, gc_cause()), PrintGCDetails, false, gclog_or_tty);
 
     gc_prologue(complete);
     increment_total_collections(complete);
@@ -559,7 +553,7 @@
             prepared_for_verification = true;
           }
           gclog_or_tty->print(" VerifyBeforeGC:");
-          Universe::verify(true);
+          Universe::verify();
         }
         COMPILER2_PRESENT(DerivedPointerTable::clear());
 
@@ -631,7 +625,7 @@
             total_collections() >= VerifyGCStartAt) {
           HandleMark hm;  // Discard invalid handles created during verification
           gclog_or_tty->print(" VerifyAfterGC:");
-          Universe::verify(false);
+          Universe::verify();
         }
 
         if (PrintGCDetails) {
@@ -688,11 +682,6 @@
 #ifdef TRACESPINNING
   ParallelTaskTerminator::print_termination_counts();
 #endif
-
-  if (ExitAfterGCNum > 0 && total_collections() == ExitAfterGCNum) {
-    tty->print_cr("Stopping after GC #%d", ExitAfterGCNum);
-    vm_exit(-1);
-  }
 }
 
 HeapWord* GenCollectedHeap::satisfy_failed_allocation(size_t size, bool is_tlab) {
@@ -1247,18 +1236,18 @@
   return _gens[level]->gc_stats();
 }
 
-void GenCollectedHeap::verify(bool allow_dirty, bool silent, VerifyOption option /* ignored */) {
+void GenCollectedHeap::verify(bool silent, VerifyOption option /* ignored */) {
   if (!silent) {
     gclog_or_tty->print("permgen ");
   }
-  perm_gen()->verify(allow_dirty);
+  perm_gen()->verify();
   for (int i = _n_gens-1; i >= 0; i--) {
     Generation* g = _gens[i];
     if (!silent) {
       gclog_or_tty->print(g->name());
       gclog_or_tty->print(" ");
     }
-    g->verify(allow_dirty);
+    g->verify();
   }
   if (!silent) {
     gclog_or_tty->print("remset ");
diff --git a/hotspot/src/share/vm/memory/genCollectedHeap.hpp b/hotspot/src/share/vm/memory/genCollectedHeap.hpp
index 5f35dec..557d0a9 100644
--- a/hotspot/src/share/vm/memory/genCollectedHeap.hpp
+++ b/hotspot/src/share/vm/memory/genCollectedHeap.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -357,7 +357,7 @@
   void prepare_for_verify();
 
   // Override.
-  void verify(bool allow_dirty, bool silent, VerifyOption option);
+  void verify(bool silent, VerifyOption option);
 
   // Override.
   virtual void print_on(outputStream* st) const;
diff --git a/hotspot/src/share/vm/memory/genMarkSweep.cpp b/hotspot/src/share/vm/memory/genMarkSweep.cpp
index d5cf4dc..e7097db 100644
--- a/hotspot/src/share/vm/memory/genMarkSweep.cpp
+++ b/hotspot/src/share/vm/memory/genMarkSweep.cpp
@@ -76,7 +76,7 @@
   _ref_processor = rp;
   rp->setup_policy(clear_all_softrefs);
 
-  TraceTime t1("Full GC", PrintGC && !PrintGCDetails, true, gclog_or_tty);
+  TraceTime t1(GCCauseString("Full GC", gch->gc_cause()), PrintGC && !PrintGCDetails, true, gclog_or_tty);
 
   // When collecting the permanent generation methodOops may be moving,
   // so we either have to flush all bcp data or convert it into bci.
@@ -203,21 +203,21 @@
 
 #ifdef VALIDATE_MARK_SWEEP
   if (ValidateMarkSweep) {
-    _root_refs_stack    = new (ResourceObj::C_HEAP) GrowableArray<void*>(100, true);
-    _other_refs_stack   = new (ResourceObj::C_HEAP) GrowableArray<void*>(100, true);
-    _adjusted_pointers  = new (ResourceObj::C_HEAP) GrowableArray<void*>(100, true);
-    _live_oops          = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true);
-    _live_oops_moved_to = new (ResourceObj::C_HEAP) GrowableArray<oop>(100, true);
-    _live_oops_size     = new (ResourceObj::C_HEAP) GrowableArray<size_t>(100, true);
+    _root_refs_stack    = new (ResourceObj::C_HEAP, mtGC) GrowableArray<void*>(100, true);
+    _other_refs_stack   = new (ResourceObj::C_HEAP, mtGC) GrowableArray<void*>(100, true);
+    _adjusted_pointers  = new (ResourceObj::C_HEAP, mtGC) GrowableArray<void*>(100, true);
+    _live_oops          = new (ResourceObj::C_HEAP, mtGC) GrowableArray<oop>(100, true);
+    _live_oops_moved_to = new (ResourceObj::C_HEAP, mtGC) GrowableArray<oop>(100, true);
+    _live_oops_size     = new (ResourceObj::C_HEAP, mtGC) GrowableArray<size_t>(100, true);
   }
   if (RecordMarkSweepCompaction) {
     if (_cur_gc_live_oops == NULL) {
-      _cur_gc_live_oops           = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true);
-      _cur_gc_live_oops_moved_to  = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true);
-      _cur_gc_live_oops_size      = new(ResourceObj::C_HEAP) GrowableArray<size_t>(100, true);
-      _last_gc_live_oops          = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true);
-      _last_gc_live_oops_moved_to = new(ResourceObj::C_HEAP) GrowableArray<HeapWord*>(100, true);
-      _last_gc_live_oops_size     = new(ResourceObj::C_HEAP) GrowableArray<size_t>(100, true);
+      _cur_gc_live_oops           = new(ResourceObj::C_HEAP, mtGC) GrowableArray<HeapWord*>(100, true);
+      _cur_gc_live_oops_moved_to  = new(ResourceObj::C_HEAP, mtGC) GrowableArray<HeapWord*>(100, true);
+      _cur_gc_live_oops_size      = new(ResourceObj::C_HEAP, mtGC) GrowableArray<size_t>(100, true);
+      _last_gc_live_oops          = new(ResourceObj::C_HEAP, mtGC) GrowableArray<HeapWord*>(100, true);
+      _last_gc_live_oops_moved_to = new(ResourceObj::C_HEAP, mtGC) GrowableArray<HeapWord*>(100, true);
+      _last_gc_live_oops_size     = new(ResourceObj::C_HEAP, mtGC) GrowableArray<size_t>(100, true);
     } else {
       _cur_gc_live_oops->clear();
       _cur_gc_live_oops_moved_to->clear();
diff --git a/hotspot/src/share/vm/memory/genOopClosures.hpp b/hotspot/src/share/vm/memory/genOopClosures.hpp
index 2c9b5ad..ded9c62 100644
--- a/hotspot/src/share/vm/memory/genOopClosures.hpp
+++ b/hotspot/src/share/vm/memory/genOopClosures.hpp
@@ -34,10 +34,10 @@
 class CardTableModRefBS;
 class DefNewGeneration;
 
-template<class E, unsigned int N> class GenericTaskQueue;
-typedef GenericTaskQueue<oop, TASKQUEUE_SIZE> OopTaskQueue;
-template<class T> class GenericTaskQueueSet;
-typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet;
+template<class E, MEMFLAGS F, unsigned int N> class GenericTaskQueue;
+typedef GenericTaskQueue<oop, mtGC, TASKQUEUE_SIZE> OopTaskQueue;
+template<class T, MEMFLAGS F> class GenericTaskQueueSet;
+typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet;
 
 // Closure for iterating roots from a particular generation
 // Note: all classes deriving from this MUST call this do_barrier
diff --git a/hotspot/src/share/vm/memory/genRemSet.hpp b/hotspot/src/share/vm/memory/genRemSet.hpp
index bf0535f..9306d45 100644
--- a/hotspot/src/share/vm/memory/genRemSet.hpp
+++ b/hotspot/src/share/vm/memory/genRemSet.hpp
@@ -35,7 +35,7 @@
 class OopsInGenClosure;
 class CardTableRS;
 
-class GenRemSet: public CHeapObj {
+class GenRemSet: public CHeapObj<mtGC> {
   friend class Generation;
 
   BarrierSet* _bs;
diff --git a/hotspot/src/share/vm/memory/generation.cpp b/hotspot/src/share/vm/memory/generation.cpp
index 75a3732..13e0858 100644
--- a/hotspot/src/share/vm/memory/generation.cpp
+++ b/hotspot/src/share/vm/memory/generation.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -696,8 +696,8 @@
   the_space()->set_top_for_allocations();
 }
 
-void OneContigSpaceCardGeneration::verify(bool allow_dirty) {
-  the_space()->verify(allow_dirty);
+void OneContigSpaceCardGeneration::verify() {
+  the_space()->verify();
 }
 
 void OneContigSpaceCardGeneration::print_on(outputStream* st)  const {
diff --git a/hotspot/src/share/vm/memory/generation.hpp b/hotspot/src/share/vm/memory/generation.hpp
index 61fcf18..96becb6 100644
--- a/hotspot/src/share/vm/memory/generation.hpp
+++ b/hotspot/src/share/vm/memory/generation.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -86,7 +86,7 @@
 };
 
 
-class Generation: public CHeapObj {
+class Generation: public CHeapObj<mtGC> {
   friend class VMStructs;
  private:
   jlong _time_of_last_gc; // time when last gc on this generation happened (ms)
@@ -599,7 +599,7 @@
   virtual void print() const;
   virtual void print_on(outputStream* st) const;
 
-  virtual void verify(bool allow_dirty) = 0;
+  virtual void verify() = 0;
 
   struct StatRecord {
     int invocations;
@@ -753,7 +753,7 @@
 
   virtual void record_spaces_top();
 
-  virtual void verify(bool allow_dirty);
+  virtual void verify();
   virtual void print_on(outputStream* st) const;
 };
 
diff --git a/hotspot/src/share/vm/memory/generationSpec.cpp b/hotspot/src/share/vm/memory/generationSpec.cpp
index bbe63ce..4b2c3fc 100644
--- a/hotspot/src/share/vm/memory/generationSpec.cpp
+++ b/hotspot/src/share/vm/memory/generationSpec.cpp
@@ -68,7 +68,7 @@
       ConcurrentMarkSweepGeneration* g = NULL;
       g = new ConcurrentMarkSweepGeneration(rs,
                  init_size(), level, ctrs, UseCMSAdaptiveFreeLists,
-                 (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice);
+                 (FreeBlockDictionary<FreeChunk>::DictionaryChoice)CMSDictionaryChoice);
 
       g->initialize_performance_counters();
 
@@ -88,7 +88,7 @@
       ASConcurrentMarkSweepGeneration* g = NULL;
       g = new ASConcurrentMarkSweepGeneration(rs,
                  init_size(), level, ctrs, UseCMSAdaptiveFreeLists,
-                 (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice);
+                 (FreeBlockDictionary<FreeChunk>::DictionaryChoice)CMSDictionaryChoice);
 
       g->initialize_performance_counters();
 
@@ -175,7 +175,7 @@
       }
       // XXXPERM
       return new CMSPermGen(perm_rs, init_size, ctrs,
-                   (FreeBlockDictionary::DictionaryChoice)CMSDictionaryChoice);
+                   (FreeBlockDictionary<FreeChunk>::DictionaryChoice)CMSDictionaryChoice);
     }
 #endif // SERIALGC
     default:
diff --git a/hotspot/src/share/vm/memory/generationSpec.hpp b/hotspot/src/share/vm/memory/generationSpec.hpp
index 5aff302..e602ef7 100644
--- a/hotspot/src/share/vm/memory/generationSpec.hpp
+++ b/hotspot/src/share/vm/memory/generationSpec.hpp
@@ -32,7 +32,7 @@
 // some generation-specific behavior.  This is done here rather than as a
 // virtual function of Generation because these methods are needed in
 // initialization of the Generations.
-class GenerationSpec : public CHeapObj {
+class GenerationSpec : public CHeapObj<mtGC> {
   friend class VMStructs;
 private:
   Generation::Name _name;
@@ -71,7 +71,7 @@
 // The specification of a permanent generation. This class is very
 // similar to GenerationSpec in use. Due to PermGen's not being a
 // true Generation, we cannot combine the spec classes either.
-class PermanentGenerationSpec : public CHeapObj {
+class PermanentGenerationSpec : public CHeapObj<mtGC> {
   friend class VMStructs;
 private:
   PermGen::Name    _name;
diff --git a/hotspot/src/share/vm/memory/heap.cpp b/hotspot/src/share/vm/memory/heap.cpp
index dcf1e41..95c9908 100644
--- a/hotspot/src/share/vm/memory/heap.cpp
+++ b/hotspot/src/share/vm/memory/heap.cpp
@@ -26,7 +26,7 @@
 #include "memory/heap.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/os.hpp"
-
+#include "services/memTracker.hpp"
 
 size_t CodeHeap::header_size() {
   return sizeof(HeapBlock);
@@ -130,6 +130,9 @@
   if (!_segmap.initialize(align_to_page_size(_number_of_reserved_segments), align_to_page_size(_number_of_committed_segments))) {
     return false;
   }
+
+  MemTracker::record_virtual_memory_type((address)_segmap.low_boundary(), mtCode);
+
   assert(_segmap.committed_size() >= (size_t) _number_of_committed_segments, "could not commit  enough space for segment map");
   assert(_segmap.reserved_size()  >= (size_t) _number_of_reserved_segments , "could not reserve enough space for segment map");
   assert(_segmap.reserved_size()  >= _segmap.committed_size()     , "just checking");
diff --git a/hotspot/src/share/vm/memory/heap.hpp b/hotspot/src/share/vm/memory/heap.hpp
index 4f592a2..74f68ae 100644
--- a/hotspot/src/share/vm/memory/heap.hpp
+++ b/hotspot/src/share/vm/memory/heap.hpp
@@ -77,7 +77,7 @@
   void set_link(FreeBlock* link)             { _link = link; }
 };
 
-class CodeHeap : public CHeapObj {
+class CodeHeap : public CHeapObj<mtCode> {
   friend class VMStructs;
  private:
   VirtualSpace _memory;                          // the memory holding the blocks
diff --git a/hotspot/src/share/vm/memory/heapInspection.cpp b/hotspot/src/share/vm/memory/heapInspection.cpp
index 1042ff4..998a1ec 100644
--- a/hotspot/src/share/vm/memory/heapInspection.cpp
+++ b/hotspot/src/share/vm/memory/heapInspection.cpp
@@ -116,7 +116,7 @@
 KlassInfoTable::KlassInfoTable(int size, HeapWord* ref) {
   _size = 0;
   _ref = ref;
-  _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size);
+  _buckets = NEW_C_HEAP_ARRAY(KlassInfoBucket, size, mtInternal);
   if (_buckets != NULL) {
     _size = size;
     for (int index = 0; index < _size; index++) {
@@ -130,7 +130,7 @@
     for (int index = 0; index < _size; index++) {
       _buckets[index].empty();
     }
-    FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets);
+    FREE_C_HEAP_ARRAY(KlassInfoBucket, _buckets, mtInternal);
     _size = 0;
   }
 }
@@ -179,7 +179,7 @@
 
 KlassInfoHisto::KlassInfoHisto(const char* title, int estimatedCount) :
   _title(title) {
-  _elements = new (ResourceObj::C_HEAP) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
+  _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<KlassInfoEntry*>(estimatedCount,true);
 }
 
 KlassInfoHisto::~KlassInfoHisto() {
diff --git a/hotspot/src/share/vm/memory/heapInspection.hpp b/hotspot/src/share/vm/memory/heapInspection.hpp
index 6d2f544..779ff07 100644
--- a/hotspot/src/share/vm/memory/heapInspection.hpp
+++ b/hotspot/src/share/vm/memory/heapInspection.hpp
@@ -44,7 +44,7 @@
 // to KlassInfoEntry's and is used to sort
 // the entries.
 
-class KlassInfoEntry: public CHeapObj {
+class KlassInfoEntry: public CHeapObj<mtInternal> {
  private:
   KlassInfoEntry* _next;
   klassOop        _klass;
@@ -72,7 +72,7 @@
   virtual void do_cinfo(KlassInfoEntry* cie) = 0;
 };
 
-class KlassInfoBucket: public CHeapObj {
+class KlassInfoBucket: public CHeapObj<mtInternal> {
  private:
   KlassInfoEntry* _list;
   KlassInfoEntry* list()           { return _list; }
diff --git a/hotspot/src/share/vm/memory/memRegion.hpp b/hotspot/src/share/vm/memory/memRegion.hpp
index 4ed33d7..e8de140 100644
--- a/hotspot/src/share/vm/memory/memRegion.hpp
+++ b/hotspot/src/share/vm/memory/memRegion.hpp
@@ -99,8 +99,8 @@
 
 class MemRegionClosureRO: public MemRegionClosure {
 public:
-  void* operator new(size_t size, ResourceObj::allocation_type type) {
-        return ResourceObj::operator new(size, type);
+  void* operator new(size_t size, ResourceObj::allocation_type type, MEMFLAGS flags) {
+        return ResourceObj::operator new(size, type, flags);
   }
   void* operator new(size_t size, Arena *arena) {
         return ResourceObj::operator new(size, arena);
diff --git a/hotspot/src/share/vm/memory/oopFactory.cpp b/hotspot/src/share/vm/memory/oopFactory.cpp
index c6e644c..def88cc 100644
--- a/hotspot/src/share/vm/memory/oopFactory.cpp
+++ b/hotspot/src/share/vm/memory/oopFactory.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,23 +127,28 @@
 klassOop oopFactory::new_instanceKlass(Symbol* name, int vtable_len, int itable_len,
                                        int static_field_size,
                                        unsigned int nonstatic_oop_map_count,
-                                       ReferenceType rt, TRAPS) {
+                                       AccessFlags access_flags,
+                                       ReferenceType rt,
+                                       KlassHandle host_klass, TRAPS) {
   instanceKlassKlass* ikk = instanceKlassKlass::cast(Universe::instanceKlassKlassObj());
-  return ikk->allocate_instance_klass(name, vtable_len, itable_len, static_field_size, nonstatic_oop_map_count, rt, CHECK_NULL);
+  return ikk->allocate_instance_klass(name, vtable_len, itable_len,
+                                      static_field_size, nonstatic_oop_map_count,
+                                      access_flags, rt, host_klass, CHECK_NULL);
 }
 
 
 constMethodOop oopFactory::new_constMethod(int byte_code_size,
                                            int compressed_line_number_size,
                                            int localvariable_table_length,
+                                           int exception_table_length,
                                            int checked_exceptions_length,
                                            bool is_conc_safe,
                                            TRAPS) {
   klassOop cmkObj = Universe::constMethodKlassObj();
   constMethodKlass* cmk = constMethodKlass::cast(cmkObj);
   return cmk->allocate(byte_code_size, compressed_line_number_size,
-                       localvariable_table_length, checked_exceptions_length,
-                       is_conc_safe,
+                       localvariable_table_length, exception_table_length,
+                       checked_exceptions_length, is_conc_safe,
                        CHECK_NULL);
 }
 
@@ -151,6 +156,7 @@
 methodOop oopFactory::new_method(int byte_code_size, AccessFlags access_flags,
                                  int compressed_line_number_size,
                                  int localvariable_table_length,
+                                 int exception_table_length,
                                  int checked_exceptions_length,
                                  bool is_conc_safe,
                                  TRAPS) {
@@ -160,6 +166,7 @@
   constMethodOop cm = new_constMethod(byte_code_size,
                                       compressed_line_number_size,
                                       localvariable_table_length,
+                                      exception_table_length,
                                       checked_exceptions_length,
                                       is_conc_safe, CHECK_NULL);
   constMethodHandle rw(THREAD, cm);
diff --git a/hotspot/src/share/vm/memory/oopFactory.hpp b/hotspot/src/share/vm/memory/oopFactory.hpp
index dbb42f0..5fd843e 100644
--- a/hotspot/src/share/vm/memory/oopFactory.hpp
+++ b/hotspot/src/share/vm/memory/oopFactory.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -77,13 +77,16 @@
                                            int vtable_len, int itable_len,
                                            int static_field_size,
                                            unsigned int nonstatic_oop_map_count,
-                                           ReferenceType rt, TRAPS);
+                                           AccessFlags access_flags,
+                                           ReferenceType rt,
+                                           KlassHandle host_klass, TRAPS);
 
   // Methods
 private:
   static constMethodOop  new_constMethod(int byte_code_size,
                                          int compressed_line_number_size,
                                          int localvariable_table_length,
+                                         int exception_table_length,
                                          int checked_exceptions_length,
                                          bool is_conc_safe,
                                          TRAPS);
@@ -95,6 +98,7 @@
                                     AccessFlags access_flags,
                                     int compressed_line_number_size,
                                     int localvariable_table_length,
+                                    int exception_table_length,
                                     int checked_exceptions_length,
                                     bool is_conc_safe,
                                     TRAPS);
diff --git a/hotspot/src/share/vm/memory/permGen.hpp b/hotspot/src/share/vm/memory/permGen.hpp
index 7400ed6..a6e2c8a 100644
--- a/hotspot/src/share/vm/memory/permGen.hpp
+++ b/hotspot/src/share/vm/memory/permGen.hpp
@@ -42,7 +42,7 @@
 
 // PermGen models the part of the heap used to allocate class meta-data.
 
-class PermGen : public CHeapObj {
+class PermGen : public CHeapObj<mtGC> {
   friend class VMStructs;
  protected:
   size_t _capacity_expansion_limit;  // maximum expansion allowed without a
diff --git a/hotspot/src/share/vm/memory/referencePolicy.hpp b/hotspot/src/share/vm/memory/referencePolicy.hpp
index 6616f25..99015d0 100644
--- a/hotspot/src/share/vm/memory/referencePolicy.hpp
+++ b/hotspot/src/share/vm/memory/referencePolicy.hpp
@@ -29,7 +29,7 @@
 // should be cleared.
 
 
-class ReferencePolicy : public CHeapObj {
+class ReferencePolicy : public CHeapObj<mtGC> {
  public:
   virtual bool should_clear_reference(oop p, jlong timestamp_clock) {
     ShouldNotReachHere();
diff --git a/hotspot/src/share/vm/memory/referenceProcessor.cpp b/hotspot/src/share/vm/memory/referenceProcessor.cpp
index 2699ecd..f103dc9 100644
--- a/hotspot/src/share/vm/memory/referenceProcessor.cpp
+++ b/hotspot/src/share/vm/memory/referenceProcessor.cpp
@@ -108,7 +108,8 @@
   _num_q               = MAX2(1U, mt_processing_degree);
   _max_num_q           = MAX2(_num_q, mt_discovery_degree);
   _discovered_refs     = NEW_C_HEAP_ARRAY(DiscoveredList,
-                                          _max_num_q * number_of_subclasses_of_ref());
+            _max_num_q * number_of_subclasses_of_ref(), mtGC);
+
   if (_discovered_refs == NULL) {
     vm_exit_during_initialization("Could not allocated RefProc Array");
   }
diff --git a/hotspot/src/share/vm/memory/referenceProcessor.hpp b/hotspot/src/share/vm/memory/referenceProcessor.hpp
index bfa3bdf..9df15bd 100644
--- a/hotspot/src/share/vm/memory/referenceProcessor.hpp
+++ b/hotspot/src/share/vm/memory/referenceProcessor.hpp
@@ -203,7 +203,7 @@
   }
 };
 
-class ReferenceProcessor : public CHeapObj {
+class ReferenceProcessor : public CHeapObj<mtGC> {
  protected:
   // Compatibility with pre-4965777 JDK's
   static bool _pending_list_uses_discovered_field;
diff --git a/hotspot/src/share/vm/memory/resourceArea.hpp b/hotspot/src/share/vm/memory/resourceArea.hpp
index 3d31248..4bb10f2 100644
--- a/hotspot/src/share/vm/memory/resourceArea.hpp
+++ b/hotspot/src/share/vm/memory/resourceArea.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -75,7 +75,7 @@
     if (UseMallocOnly) {
       // use malloc, but save pointer in res. area for later freeing
       char** save = (char**)internal_malloc_4(sizeof(char*));
-      return (*save = (char*)os::malloc(size));
+      return (*save = (char*)os::malloc(size, mtThread));
     }
 #endif
     return (char*)Amalloc(size);
@@ -93,18 +93,17 @@
   ResourceArea *_area;          // Resource area to stack allocate
   Chunk *_chunk;                // saved arena chunk
   char *_hwm, *_max;
-  NOT_PRODUCT(size_t _size_in_bytes;)
+  size_t _size_in_bytes;
 
   void initialize(Thread *thread) {
     _area = thread->resource_area();
     _chunk = _area->_chunk;
     _hwm = _area->_hwm;
     _max= _area->_max;
-    NOT_PRODUCT(_size_in_bytes = _area->size_in_bytes();)
+    _size_in_bytes = _area->size_in_bytes();
     debug_only(_area->_nesting++;)
     assert( _area->_nesting > 0, "must stack allocate RMs" );
   }
-
  public:
 
 #ifndef ASSERT
@@ -120,7 +119,7 @@
 
   ResourceMark( ResourceArea *r ) :
     _area(r), _chunk(r->_chunk), _hwm(r->_hwm), _max(r->_max) {
-    NOT_PRODUCT(_size_in_bytes = _area->size_in_bytes();)
+    _size_in_bytes = r->_size_in_bytes;
     debug_only(_area->_nesting++;)
     assert( _area->_nesting > 0, "must stack allocate RMs" );
   }
@@ -128,15 +127,21 @@
   void reset_to_mark() {
     if (UseMallocOnly) free_malloced_objects();
 
-    if( _chunk->next() )        // Delete later chunks
+    if( _chunk->next() ) {       // Delete later chunks
+      // reset arena size before delete chunks. Otherwise, the total
+      // arena size could exceed total chunk size
+      assert(_area->size_in_bytes() > size_in_bytes(), "Sanity check");
+      _area->set_size_in_bytes(size_in_bytes());
       _chunk->next_chop();
+    } else {
+      assert(_area->size_in_bytes() == size_in_bytes(), "Sanity check");
+    }
     _area->_chunk = _chunk;     // Roll back arena to saved chunk
     _area->_hwm = _hwm;
     _area->_max = _max;
 
     // clear out this chunk (to detect allocation bugs)
     if (ZapResourceArea) memset(_hwm, badResourceValue, _max - _hwm);
-    _area->set_size_in_bytes(size_in_bytes());
   }
 
   ~ResourceMark() {
@@ -148,7 +153,7 @@
 
  private:
   void free_malloced_objects()                                         PRODUCT_RETURN;
-  size_t size_in_bytes()       NOT_PRODUCT({ return _size_in_bytes; }) PRODUCT_RETURN0;
+  size_t size_in_bytes() { return _size_in_bytes; }
 };
 
 //------------------------------DeoptResourceMark-----------------------------------
@@ -180,19 +185,19 @@
 // and they would be stack allocated. This leaves open the possibilty of accidental
 // misuse so we simple duplicate the ResourceMark functionality here.
 
-class DeoptResourceMark: public CHeapObj {
+class DeoptResourceMark: public CHeapObj<mtInternal> {
 protected:
   ResourceArea *_area;          // Resource area to stack allocate
   Chunk *_chunk;                // saved arena chunk
   char *_hwm, *_max;
-  NOT_PRODUCT(size_t _size_in_bytes;)
+  size_t _size_in_bytes;
 
   void initialize(Thread *thread) {
     _area = thread->resource_area();
     _chunk = _area->_chunk;
     _hwm = _area->_hwm;
     _max= _area->_max;
-    NOT_PRODUCT(_size_in_bytes = _area->size_in_bytes();)
+    _size_in_bytes = _area->size_in_bytes();
     debug_only(_area->_nesting++;)
     assert( _area->_nesting > 0, "must stack allocate RMs" );
   }
@@ -212,7 +217,7 @@
 
   DeoptResourceMark( ResourceArea *r ) :
     _area(r), _chunk(r->_chunk), _hwm(r->_hwm), _max(r->_max) {
-    NOT_PRODUCT(_size_in_bytes = _area->size_in_bytes();)
+    _size_in_bytes = _area->size_in_bytes();
     debug_only(_area->_nesting++;)
     assert( _area->_nesting > 0, "must stack allocate RMs" );
   }
@@ -220,15 +225,21 @@
   void reset_to_mark() {
     if (UseMallocOnly) free_malloced_objects();
 
-    if( _chunk->next() )        // Delete later chunks
+    if( _chunk->next() ) {        // Delete later chunks
+      // reset arena size before delete chunks. Otherwise, the total
+      // arena size could exceed total chunk size
+      assert(_area->size_in_bytes() > size_in_bytes(), "Sanity check");
+      _area->set_size_in_bytes(size_in_bytes());
       _chunk->next_chop();
+    } else {
+      assert(_area->size_in_bytes() == size_in_bytes(), "Sanity check");
+    }
     _area->_chunk = _chunk;     // Roll back arena to saved chunk
     _area->_hwm = _hwm;
     _area->_max = _max;
 
     // clear out this chunk (to detect allocation bugs)
     if (ZapResourceArea) memset(_hwm, badResourceValue, _max - _hwm);
-    _area->set_size_in_bytes(size_in_bytes());
   }
 
   ~DeoptResourceMark() {
@@ -240,7 +251,7 @@
 
  private:
   void free_malloced_objects()                                         PRODUCT_RETURN;
-  size_t size_in_bytes()       NOT_PRODUCT({ return _size_in_bytes; }) PRODUCT_RETURN0;
+  size_t size_in_bytes() { return _size_in_bytes; };
 };
 
 #endif // SHARE_VM_MEMORY_RESOURCEAREA_HPP
diff --git a/hotspot/src/share/vm/memory/restore.cpp b/hotspot/src/share/vm/memory/restore.cpp
index 263867e..e2f8b6a 100644
--- a/hotspot/src/share/vm/memory/restore.cpp
+++ b/hotspot/src/share/vm/memory/restore.cpp
@@ -132,7 +132,7 @@
   buffer += sizeof(intptr_t);
   int number_of_entries = *(intptr_t*)buffer;
   buffer += sizeof(intptr_t);
-  SymbolTable::create_table((HashtableBucket*)buffer, symbolTableLen,
+  SymbolTable::create_table((HashtableBucket<mtSymbol>*)buffer, symbolTableLen,
                             number_of_entries);
   buffer += symbolTableLen;
 
@@ -144,7 +144,7 @@
   buffer += sizeof(intptr_t);
   number_of_entries = *(intptr_t*)buffer;
   buffer += sizeof(intptr_t);
-  StringTable::create_table((HashtableBucket*)buffer, stringTableLen,
+  StringTable::create_table((HashtableBucket<mtSymbol>*)buffer, stringTableLen,
                             number_of_entries);
   buffer += stringTableLen;
 
@@ -157,7 +157,7 @@
   buffer += sizeof(intptr_t);
   number_of_entries = *(intptr_t*)buffer;
   buffer += sizeof(intptr_t);
-  SystemDictionary::set_shared_dictionary((HashtableBucket*)buffer,
+  SystemDictionary::set_shared_dictionary((HashtableBucket<mtClass>*)buffer,
                                           sharedDictionaryLen,
                                           number_of_entries);
   buffer += sharedDictionaryLen;
@@ -171,7 +171,7 @@
   buffer += sizeof(intptr_t);
   number_of_entries = *(intptr_t*)buffer;
   buffer += sizeof(intptr_t);
-  ClassLoader::create_package_info_table((HashtableBucket*)buffer, pkgInfoLen,
+  ClassLoader::create_package_info_table((HashtableBucket<mtClass>*)buffer, pkgInfoLen,
                                          number_of_entries);
   buffer += pkgInfoLen;
   ClassLoader::verify();
diff --git a/hotspot/src/share/vm/memory/space.cpp b/hotspot/src/share/vm/memory/space.cpp
index 7f3aceb..f97bc34 100644
--- a/hotspot/src/share/vm/memory/space.cpp
+++ b/hotspot/src/share/vm/memory/space.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -531,7 +531,7 @@
               bottom(), top(), _offsets.threshold(), end());
 }
 
-void ContiguousSpace::verify(bool allow_dirty) const {
+void ContiguousSpace::verify() const {
   HeapWord* p = bottom();
   HeapWord* t = top();
   HeapWord* prev_p = NULL;
@@ -790,7 +790,9 @@
 
 // Very general, slow implementation.
 HeapWord* ContiguousSpace::block_start_const(const void* p) const {
-  assert(MemRegion(bottom(), end()).contains(p), "p not in space");
+  assert(MemRegion(bottom(), end()).contains(p),
+         err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
+                  p, bottom(), end()));
   if (p >= top()) {
     return top();
   } else {
@@ -800,19 +802,27 @@
       last = cur;
       cur += oop(cur)->size();
     }
-    assert(oop(last)->is_oop(), "Should be an object start");
+    assert(oop(last)->is_oop(),
+           err_msg(PTR_FORMAT " should be an object start", last));
     return last;
   }
 }
 
 size_t ContiguousSpace::block_size(const HeapWord* p) const {
-  assert(MemRegion(bottom(), end()).contains(p), "p not in space");
+  assert(MemRegion(bottom(), end()).contains(p),
+         err_msg("p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")",
+                  p, bottom(), end()));
   HeapWord* current_top = top();
-  assert(p <= current_top, "p is not a block start");
-  assert(p == current_top || oop(p)->is_oop(), "p is not a block start");
-  if (p < current_top)
+  assert(p <= current_top,
+         err_msg("p > current top - p: " PTR_FORMAT ", current top: " PTR_FORMAT,
+                  p, current_top));
+  assert(p == current_top || oop(p)->is_oop(),
+         err_msg("p (" PTR_FORMAT ") is not a block start - "
+                 "current_top: " PTR_FORMAT ", is_oop: %s",
+                 p, current_top, BOOL_TO_STR(oop(p)->is_oop())));
+  if (p < current_top) {
     return oop(p)->size();
-  else {
+  } else {
     assert(p == current_top, "just checking");
     return pointer_delta(end(), (HeapWord*) p);
   }
@@ -965,27 +975,12 @@
   initialize(mr, SpaceDecorator::Clear, SpaceDecorator::Mangle);
 }
 
-
-class VerifyOldOopClosure : public OopClosure {
- public:
-  oop  _the_obj;
-  bool _allow_dirty;
-  void do_oop(oop* p) {
-    _the_obj->verify_old_oop(p, _allow_dirty);
-  }
-  void do_oop(narrowOop* p) {
-    _the_obj->verify_old_oop(p, _allow_dirty);
-  }
-};
-
 #define OBJ_SAMPLE_INTERVAL 0
 #define BLOCK_SAMPLE_INTERVAL 100
 
-void OffsetTableContigSpace::verify(bool allow_dirty) const {
+void OffsetTableContigSpace::verify() const {
   HeapWord* p = bottom();
   HeapWord* prev_p = NULL;
-  VerifyOldOopClosure blk;      // Does this do anything?
-  blk._allow_dirty = allow_dirty;
   int objs = 0;
   int blocks = 0;
 
@@ -1007,8 +1002,6 @@
 
     if (objs == OBJ_SAMPLE_INTERVAL) {
       oop(p)->verify();
-      blk._the_obj = oop(p);
-      oop(p)->oop_iterate(&blk);
       objs = 0;
     } else {
       objs++;
diff --git a/hotspot/src/share/vm/memory/space.hpp b/hotspot/src/share/vm/memory/space.hpp
index 2d718c2..ef2f2c6 100644
--- a/hotspot/src/share/vm/memory/space.hpp
+++ b/hotspot/src/share/vm/memory/space.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -105,7 +105,7 @@
 // bottom() <= top() <= end()
 // top() is inclusive and end() is exclusive.
 
-class Space: public CHeapObj {
+class Space: public CHeapObj<mtGC> {
   friend class VMStructs;
  protected:
   HeapWord* _bottom;
@@ -306,7 +306,7 @@
   }
 
   // Debugging
-  virtual void verify(bool allow_dirty) const = 0;
+  virtual void verify() const = 0;
 };
 
 // A MemRegionClosure (ResourceObj) whose "do_MemRegion" function applies an
@@ -880,10 +880,17 @@
   void object_iterate_mem(MemRegion mr, UpwardsObjectClosure* cl);
   // iterates on objects up to the safe limit
   HeapWord* object_iterate_careful(ObjectClosureCareful* cl);
-  inline HeapWord* concurrent_iteration_safe_limit();
+  HeapWord* concurrent_iteration_safe_limit() {
+    assert(_concurrent_iteration_safe_limit <= top(),
+           "_concurrent_iteration_safe_limit update missed");
+    return _concurrent_iteration_safe_limit;
+  }
   // changes the safe limit, all objects from bottom() to the new
   // limit should be properly initialized
-  inline void set_concurrent_iteration_safe_limit(HeapWord* new_limit);
+  void set_concurrent_iteration_safe_limit(HeapWord* new_limit) {
+    assert(new_limit <= top(), "uninitialized objects in the safe range");
+    _concurrent_iteration_safe_limit = new_limit;
+  }
 
 #ifndef SERIALGC
   // In support of parallel oop_iterate.
@@ -948,7 +955,7 @@
   }
 
   // Debugging
-  virtual void verify(bool allow_dirty) const;
+  virtual void verify() const;
 
   // Used to increase collection frequency.  "factor" of 0 means entire
   // space.
@@ -1100,7 +1107,7 @@
   virtual void print_on(outputStream* st) const;
 
   // Debugging
-  void verify(bool allow_dirty) const;
+  void verify() const;
 
   // Shared space support
   void serialize_block_offset_array_offsets(SerializeOopClosure* soc);
diff --git a/hotspot/src/share/vm/memory/space.inline.hpp b/hotspot/src/share/vm/memory/space.inline.hpp
index 7d62476..07e6127 100644
--- a/hotspot/src/share/vm/memory/space.inline.hpp
+++ b/hotspot/src/share/vm/memory/space.inline.hpp
@@ -67,17 +67,4 @@
   return _offsets.block_start(p);
 }
 
-inline HeapWord* ContiguousSpace::concurrent_iteration_safe_limit()
-{
-  assert(_concurrent_iteration_safe_limit <= top(),
-         "_concurrent_iteration_safe_limit update missed");
-  return _concurrent_iteration_safe_limit;
-}
-
-inline void ContiguousSpace::set_concurrent_iteration_safe_limit(HeapWord* new_limit)
-{
-  assert(new_limit <= top(), "uninitialized objects in the safe range");
-  _concurrent_iteration_safe_limit = new_limit;
-}
-
 #endif // SHARE_VM_MEMORY_SPACE_INLINE_HPP
diff --git a/hotspot/src/share/vm/memory/tenuredGeneration.cpp b/hotspot/src/share/vm/memory/tenuredGeneration.cpp
index b88f315..1d38095 100644
--- a/hotspot/src/share/vm/memory/tenuredGeneration.cpp
+++ b/hotspot/src/share/vm/memory/tenuredGeneration.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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,8 +23,8 @@
  */
 
 #include "precompiled.hpp"
-#include "gc_implementation/parNew/parGCAllocBuffer.hpp"
 #include "gc_implementation/shared/collectorCounters.hpp"
+#include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/blockOffsetTable.inline.hpp"
 #include "memory/generation.inline.hpp"
@@ -65,7 +65,7 @@
   if (UseParNewGC && ParallelGCThreads > 0) {
     typedef ParGCAllocBufferWithBOT* ParGCAllocBufferWithBOTPtr;
     _alloc_buffers = NEW_C_HEAP_ARRAY(ParGCAllocBufferWithBOTPtr,
-                                      ParallelGCThreads);
+                                      ParallelGCThreads, mtGC);
     if (_alloc_buffers == NULL)
       vm_exit_during_initialization("Could not allocate alloc_buffers");
     for (uint i = 0; i < ParallelGCThreads; i++) {
diff --git a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp
index 1b8bb0a..c85a59d 100644
--- a/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp
+++ b/hotspot/src/share/vm/memory/threadLocalAllocBuffer.hpp
@@ -36,7 +36,7 @@
 //            It is thread-private at any time, but maybe multiplexed over
 //            time across multiple threads. The park()/unpark() pair is
 //            used to make it avaiable for such multiplexing.
-class ThreadLocalAllocBuffer: public CHeapObj {
+class ThreadLocalAllocBuffer: public CHeapObj<mtThread> {
   friend class VMStructs;
 private:
   HeapWord* _start;                              // address of TLAB
@@ -172,7 +172,7 @@
   void verify();
 };
 
-class GlobalTLABStats: public CHeapObj {
+class GlobalTLABStats: public CHeapObj<mtThread> {
 private:
 
   // Accumulate perfdata in private variables because
diff --git a/hotspot/src/share/vm/memory/universe.cpp b/hotspot/src/share/vm/memory/universe.cpp
index 2651f4d..4ed723a 100644
--- a/hotspot/src/share/vm/memory/universe.cpp
+++ b/hotspot/src/share/vm/memory/universe.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -764,7 +764,7 @@
 
   FileMapInfo* mapinfo = NULL;
   if (UseSharedSpaces) {
-    mapinfo = NEW_C_HEAP_OBJ(FileMapInfo);
+    mapinfo = NEW_C_HEAP_OBJ(FileMapInfo, mtInternal);
     memset(mapinfo, 0, sizeof(FileMapInfo));
 
     // Open the shared archive file, read and validate the header. If
@@ -1326,7 +1326,7 @@
   st->print_cr("}");
 }
 
-void Universe::verify(bool allow_dirty, bool silent, VerifyOption option) {
+void Universe::verify(bool silent, VerifyOption option) {
   if (SharedSkipVerify) {
     return;
   }
@@ -1350,7 +1350,7 @@
   if (!silent) gclog_or_tty->print("[Verifying ");
   if (!silent) gclog_or_tty->print("threads ");
   Threads::verify();
-  heap()->verify(allow_dirty, silent, option);
+  heap()->verify(silent, option);
 
   if (!silent) gclog_or_tty->print("syms ");
   SymbolTable::verify();
@@ -1546,7 +1546,7 @@
     // This is the first previous version so make some space.
     // Start with 2 elements under the assumption that the class
     // won't be redefined much.
-    _prev_methods = new (ResourceObj::C_HEAP) GrowableArray<jweak>(2, true);
+    _prev_methods = new (ResourceObj::C_HEAP, mtClass) GrowableArray<jweak>(2, true);
   }
 
   // RC_TRACE macro has an embedded ResourceMark
diff --git a/hotspot/src/share/vm/memory/universe.hpp b/hotspot/src/share/vm/memory/universe.hpp
index e8ebf8f..6013438 100644
--- a/hotspot/src/share/vm/memory/universe.hpp
+++ b/hotspot/src/share/vm/memory/universe.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -43,7 +43,7 @@
 // Common parts of a methodOop cache. This cache safely interacts with
 // the RedefineClasses API.
 //
-class CommonMethodOopCache : public CHeapObj {
+class CommonMethodOopCache : public CHeapObj<mtClass> {
   // We save the klassOop and the idnum of methodOop in order to get
   // the current cached methodOop.
  private:
@@ -412,8 +412,14 @@
 
   // Debugging
   static bool verify_in_progress() { return _verify_in_progress; }
-  static void verify(bool allow_dirty = true, bool silent = false,
-                     VerifyOption option = VerifyOption_Default );
+  static void verify(bool silent, VerifyOption option);
+  static void verify(bool silent) {
+    verify(silent, VerifyOption_Default /* option */);
+  }
+  static void verify() {
+    verify(false /* silent */);
+  }
+
   static int  verify_count()       { return _verify_count; }
   // The default behavior is to call print_on() on gclog_or_tty.
   static void print();
@@ -455,7 +461,7 @@
   static int base_vtable_size()               { return _base_vtable_size; }
 };
 
-class DeferredObjAllocEvent : public CHeapObj {
+class DeferredObjAllocEvent : public CHeapObj<mtInternal> {
   private:
     oop    _oop;
     size_t _bytesize;
diff --git a/hotspot/src/share/vm/oops/constMethodKlass.cpp b/hotspot/src/share/vm/oops/constMethodKlass.cpp
index 509b411..e74811f 100644
--- a/hotspot/src/share/vm/oops/constMethodKlass.cpp
+++ b/hotspot/src/share/vm/oops/constMethodKlass.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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 @@
 constMethodOop constMethodKlass::allocate(int byte_code_size,
                                           int compressed_line_number_size,
                                           int localvariable_table_length,
+                                          int exception_table_length,
                                           int checked_exceptions_length,
                                           bool is_conc_safe,
                                           TRAPS) {
@@ -72,6 +73,7 @@
   int size = constMethodOopDesc::object_size(byte_code_size,
                                              compressed_line_number_size,
                                              localvariable_table_length,
+                                             exception_table_length,
                                              checked_exceptions_length);
   KlassHandle h_k(THREAD, as_klassOop());
   constMethodOop cm = (constMethodOop)
@@ -80,14 +82,14 @@
   No_Safepoint_Verifier no_safepoint;
   cm->set_interpreter_kind(Interpreter::invalid);
   cm->init_fingerprint();
-  cm->set_method(NULL);
+  cm->set_constants(NULL);
   cm->set_stackmap_data(NULL);
-  cm->set_exception_table(NULL);
   cm->set_code_size(byte_code_size);
   cm->set_constMethod_size(size);
   cm->set_inlined_tables_length(checked_exceptions_length,
                                 compressed_line_number_size,
-                                localvariable_table_length);
+                                localvariable_table_length,
+                                exception_table_length);
   assert(cm->size() == size, "wrong size for object");
   cm->set_is_conc_safe(is_conc_safe);
   cm->set_partially_loaded();
@@ -98,9 +100,8 @@
 void constMethodKlass::oop_follow_contents(oop obj) {
   assert (obj->is_constMethod(), "object must be constMethod");
   constMethodOop cm = constMethodOop(obj);
-  MarkSweep::mark_and_push(cm->adr_method());
+  MarkSweep::mark_and_push(cm->adr_constants());
   MarkSweep::mark_and_push(cm->adr_stackmap_data());
-  MarkSweep::mark_and_push(cm->adr_exception_table());
   // Performance tweak: We skip iterating over the klass pointer since we
   // know that Universe::constMethodKlassObj never moves.
 }
@@ -110,9 +111,8 @@
                                            oop obj) {
   assert (obj->is_constMethod(), "object must be constMethod");
   constMethodOop cm_oop = constMethodOop(obj);
-  PSParallelCompact::mark_and_push(cm, cm_oop->adr_method());
+  PSParallelCompact::mark_and_push(cm, cm_oop->adr_constants());
   PSParallelCompact::mark_and_push(cm, cm_oop->adr_stackmap_data());
-  PSParallelCompact::mark_and_push(cm, cm_oop->adr_exception_table());
   // Performance tweak: We skip iterating over the klass pointer since we
   // know that Universe::constMethodKlassObj never moves.
 }
@@ -121,9 +121,8 @@
 int constMethodKlass::oop_oop_iterate(oop obj, OopClosure* blk) {
   assert (obj->is_constMethod(), "object must be constMethod");
   constMethodOop cm = constMethodOop(obj);
-  blk->do_oop(cm->adr_method());
+  blk->do_oop(cm->adr_constants());
   blk->do_oop(cm->adr_stackmap_data());
-  blk->do_oop(cm->adr_exception_table());
   // Get size before changing pointers.
   // Don't call size() or oop_size() since that is a virtual call.
   int size = cm->object_size();
@@ -135,12 +134,10 @@
   assert (obj->is_constMethod(), "object must be constMethod");
   constMethodOop cm = constMethodOop(obj);
   oop* adr;
-  adr = cm->adr_method();
+  adr = cm->adr_constants();
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = cm->adr_stackmap_data();
   if (mr.contains(adr)) blk->do_oop(adr);
-  adr = cm->adr_exception_table();
-  if (mr.contains(adr)) blk->do_oop(adr);
   // Get size before changing pointers.
   // Don't call size() or oop_size() since that is a virtual call.
   int size = cm->object_size();
@@ -153,9 +150,8 @@
 int constMethodKlass::oop_adjust_pointers(oop obj) {
   assert(obj->is_constMethod(), "should be constMethod");
   constMethodOop cm = constMethodOop(obj);
-  MarkSweep::adjust_pointer(cm->adr_method());
+  MarkSweep::adjust_pointer(cm->adr_constants());
   MarkSweep::adjust_pointer(cm->adr_stackmap_data());
-  MarkSweep::adjust_pointer(cm->adr_exception_table());
   // Get size before changing pointers.
   // Don't call size() or oop_size() since that is a virtual call.
   int size = cm->object_size();
@@ -188,9 +184,8 @@
   assert(obj->is_constMethod(), "must be constMethod");
   Klass::oop_print_on(obj, st);
   constMethodOop m = constMethodOop(obj);
-  st->print(" - method:       " INTPTR_FORMAT " ", (address)m->method());
-  m->method()->print_value_on(st); st->cr();
-  st->print(" - exceptions:   " INTPTR_FORMAT "\n", (address)m->exception_table());
+  st->print(" - constants:       " INTPTR_FORMAT " ", (address)m->constants());
+  m->constants()->print_value_on(st); st->cr();
   if (m->has_stackmap_table()) {
     st->print(" - stackmap data:       ");
     m->stackmap_data()->print_value_on(st);
@@ -223,13 +218,11 @@
   // Verification can occur during oop construction before the method or
   // other fields have been initialized.
   if (!obj->partially_loaded()) {
-    guarantee(m->method()->is_perm(), "should be in permspace");
-    guarantee(m->method()->is_method(), "should be method");
+    guarantee(m->constants()->is_perm(), "should be in permspace");
+    guarantee(m->constants()->is_constantPool(), "should be constant pool");
     typeArrayOop stackmap_data = m->stackmap_data();
     guarantee(stackmap_data == NULL ||
               stackmap_data->is_perm(),  "should be in permspace");
-    guarantee(m->exception_table()->is_perm(), "should be in permspace");
-    guarantee(m->exception_table()->is_typeArray(), "should be type array");
 
     address m_end = (address)((oop*) m + m->size());
     address compressed_table_start = m->code_end();
@@ -244,11 +237,15 @@
       compressed_table_end += stream.position();
     }
     guarantee(compressed_table_end <= m_end, "invalid method layout");
-    // Verify checked exceptions and local variable tables
+    // Verify checked exceptions, exception table and local variable tables
     if (m->has_checked_exceptions()) {
       u2* addr = m->checked_exceptions_length_addr();
       guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
     }
+    if (m->has_exception_handler()) {
+      u2* addr = m->exception_table_length_addr();
+      guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
+    }
     if (m->has_localvariable_table()) {
       u2* addr = m->localvariable_table_length_addr();
       guarantee(*addr > 0 && (address) addr >= compressed_table_end && (address) addr < m_end, "invalid method layout");
@@ -257,12 +254,12 @@
     u2* uncompressed_table_start;
     if (m->has_localvariable_table()) {
       uncompressed_table_start = (u2*) m->localvariable_table_start();
-    } else {
-      if (m->has_checked_exceptions()) {
+    } else if (m->has_exception_handler()) {
+      uncompressed_table_start = (u2*) m->exception_table_start();
+    } else if (m->has_checked_exceptions()) {
         uncompressed_table_start = (u2*) m->checked_exceptions_start();
-      } else {
+    } else {
         uncompressed_table_start = (u2*) m_end;
-      }
     }
     int gap = (intptr_t) uncompressed_table_start - (intptr_t) compressed_table_end;
     int max_gap = align_object_size(1)*BytesPerWord;
@@ -273,8 +270,8 @@
 bool constMethodKlass::oop_partially_loaded(oop obj) const {
   assert(obj->is_constMethod(), "object must be klass");
   constMethodOop m = constMethodOop(obj);
-  // check whether exception_table points to self (flag for partially loaded)
-  return m->exception_table() == (typeArrayOop)obj;
+  // check whether stackmap_data points to self (flag for partially loaded)
+  return m->stackmap_data() == (typeArrayOop)obj;
 }
 
 
@@ -282,6 +279,6 @@
 void constMethodKlass::oop_set_partially_loaded(oop obj) {
   assert(obj->is_constMethod(), "object must be klass");
   constMethodOop m = constMethodOop(obj);
-  // Temporarily set exception_table to point to self
-  m->set_exception_table((typeArrayOop)obj);
+  // Temporarily set stackmap_data to point to self
+  m->set_stackmap_data((typeArrayOop)obj);
 }
diff --git a/hotspot/src/share/vm/oops/constMethodKlass.hpp b/hotspot/src/share/vm/oops/constMethodKlass.hpp
index 1c3e3c8..23ba112 100644
--- a/hotspot/src/share/vm/oops/constMethodKlass.hpp
+++ b/hotspot/src/share/vm/oops/constMethodKlass.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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 @@
   DEFINE_ALLOCATE_PERMANENT(constMethodKlass);
   constMethodOop allocate(int byte_code_size, int compressed_line_number_size,
                           int localvariable_table_length,
+                          int exception_table_length,
                           int checked_exceptions_length,
                           bool is_conc_safe,
                           TRAPS);
diff --git a/hotspot/src/share/vm/oops/constMethodOop.cpp b/hotspot/src/share/vm/oops/constMethodOop.cpp
index b52e64e..cb9256d 100644
--- a/hotspot/src/share/vm/oops/constMethodOop.cpp
+++ b/hotspot/src/share/vm/oops/constMethodOop.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -35,6 +35,7 @@
 int constMethodOopDesc::object_size(int code_size,
                                     int compressed_line_number_size,
                                     int local_variable_table_length,
+                                    int exception_table_length,
                                     int checked_exceptions_length) {
   int extra_bytes = code_size;
   if (compressed_line_number_size > 0) {
@@ -49,10 +50,18 @@
     extra_bytes +=
               local_variable_table_length * sizeof(LocalVariableTableElement);
   }
+  if (exception_table_length > 0) {
+    extra_bytes += sizeof(u2);
+    extra_bytes += exception_table_length * sizeof(ExceptionTableElement);
+  }
   int extra_words = align_size_up(extra_bytes, BytesPerWord) / BytesPerWord;
   return align_object_size(header_size() + extra_words);
 }
 
+methodOop constMethodOopDesc::method() const {
+    return instanceKlass::cast(_constants->pool_holder())->method_with_idnum(
+                               _method_idnum);
+  }
 
 // linenumber table - note that length is unknown until decompression,
 // see class CompressedLineNumberReadStream.
@@ -69,23 +78,40 @@
   return last_u2_element();
 }
 
-u2* constMethodOopDesc::localvariable_table_length_addr() const {
-  assert(has_localvariable_table(), "called only if table is present");
+u2* constMethodOopDesc::exception_table_length_addr() const {
+  assert(has_exception_handler(), "called only if table is present");
   if (has_checked_exceptions()) {
     // If checked_exception present, locate immediately before them.
     return (u2*) checked_exceptions_start() - 1;
   } else {
-    // Else, the linenumber table is at the end of the constMethod.
+    // Else, the exception table is at the end of the constMethod.
     return last_u2_element();
   }
 }
 
+u2* constMethodOopDesc::localvariable_table_length_addr() const {
+  assert(has_localvariable_table(), "called only if table is present");
+  if (has_exception_handler()) {
+    // If exception_table present, locate immediately before them.
+    return (u2*) exception_table_start() - 1;
+  } else {
+    if (has_checked_exceptions()) {
+      // If checked_exception present, locate immediately before them.
+      return (u2*) checked_exceptions_start() - 1;
+    } else {
+      // Else, the linenumber table is at the end of the constMethod.
+      return last_u2_element();
+    }
+  }
+}
+
 
 // Update the flags to indicate the presence of these optional fields.
 void constMethodOopDesc::set_inlined_tables_length(
                                               int checked_exceptions_len,
                                               int compressed_line_number_size,
-                                              int localvariable_table_len) {
+                                              int localvariable_table_len,
+                                              int exception_table_len) {
   // Must be done in the order below, otherwise length_addr accessors
   // will not work. Only set bit in header if length is positive.
   assert(_flags == 0, "Error");
@@ -96,6 +122,10 @@
     _flags |= _has_checked_exceptions;
     *(checked_exceptions_length_addr()) = checked_exceptions_len;
   }
+  if (exception_table_len > 0) {
+    _flags |= _has_exception_table;
+    *(exception_table_length_addr()) = exception_table_len;
+  }
   if (localvariable_table_len > 0) {
     _flags |= _has_localvariable_table;
     *(localvariable_table_length_addr()) = localvariable_table_len;
@@ -129,3 +159,15 @@
   addr -= length * sizeof(LocalVariableTableElement) / sizeof(u2);
   return (LocalVariableTableElement*) addr;
 }
+
+int constMethodOopDesc::exception_table_length() const {
+  return has_exception_handler() ? *(exception_table_length_addr()) : 0;
+}
+
+ExceptionTableElement* constMethodOopDesc::exception_table_start() const {
+  u2* addr = exception_table_length_addr();
+  u2 length = *addr;
+  assert(length > 0, "should only be called if table is present");
+  addr -= length * sizeof(ExceptionTableElement) / sizeof(u2);
+  return (ExceptionTableElement*)addr;
+}
diff --git a/hotspot/src/share/vm/oops/constMethodOop.hpp b/hotspot/src/share/vm/oops/constMethodOop.hpp
index 91f9786..549192b 100644
--- a/hotspot/src/share/vm/oops/constMethodOop.hpp
+++ b/hotspot/src/share/vm/oops/constMethodOop.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -41,9 +41,8 @@
 // |------------------------------------------------------|
 // | fingerprint 1                                        |
 // | fingerprint 2                                        |
-// | method                         (oop)                 |
+// | constants                      (oop)                 |
 // | stackmap_data                  (oop)                 |
-// | exception_table                (oop)                 |
 // | constMethod_size                                     |
 // | interp_kind  | flags    | code_size                  |
 // | name index              | signature index            |
@@ -64,7 +63,13 @@
 // |  (length is u2, elements are 6-tuples of u2)         |
 // |  (see class LocalVariableTableElement)               |
 // |  (access flags bit tells whether table is present)   |
-// |  (indexed from end of contMethodOop)                 |
+// |  (indexed from end of constMethodOop)                |
+// |------------------------------------------------------|
+// | exception table + length (length last)               |
+// |  (length is u2, elements are 4-tuples of u2)         |
+// |  (see class ExceptionTableElement)                   |
+// |  (access flags bit tells whether table is present)   |
+// |  (indexed from end of constMethodOop)                |
 // |------------------------------------------------------|
 // | checked exceptions elements + length (length last)   |
 // |  (length is u2, elements are u2)                     |
@@ -93,6 +98,15 @@
 };
 
 
+// Utitily class describing elements in exception table
+class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {
+ public:
+  u2 start_pc;
+  u2 end_pc;
+  u2 handler_pc;
+  u2 catch_type_index;
+};
+
 class constMethodOopDesc : public oopDesc {
   friend class constMethodKlass;
   friend class VMStructs;
@@ -100,7 +114,8 @@
   enum {
     _has_linenumber_table = 1,
     _has_checked_exceptions = 2,
-    _has_localvariable_table = 4
+    _has_localvariable_table = 4,
+    _has_exception_table = 8
   };
 
   // Bit vector of signature
@@ -113,25 +128,19 @@
   volatile bool     _is_conc_safe; // if true, safe for concurrent GC processing
 
 public:
-  oop* oop_block_beg() const { return adr_method(); }
-  oop* oop_block_end() const { return adr_exception_table() + 1; }
+  oop* oop_block_beg() const { return adr_constants(); }
+  oop* oop_block_end() const { return adr_stackmap_data() + 1; }
 
 private:
   //
   // The oop block.  See comment in klass.hpp before making changes.
   //
 
-  // Backpointer to non-const methodOop (needed for some JVMTI operations)
-  methodOop         _method;
+  constantPoolOop   _constants;                  // Constant pool
 
   // Raw stackmap data for the method
   typeArrayOop      _stackmap_data;
 
-  // The exception handler table. 4-tuples of ints [start_pc, end_pc,
-  // handler_pc, catch_type index] For methods with no exceptions the
-  // table is pointing to Universe::the_empty_int_array
-  typeArrayOop      _exception_table;
-
   //
   // End of the oop block.
   //
@@ -153,7 +162,8 @@
   // Inlined tables
   void set_inlined_tables_length(int checked_exceptions_len,
                                  int compressed_line_number_size,
-                                 int localvariable_table_len);
+                                 int localvariable_table_len,
+                                 int exception_table_len);
 
   bool has_linenumber_table() const
     { return (_flags & _has_linenumber_table) != 0; }
@@ -164,13 +174,19 @@
   bool has_localvariable_table() const
     { return (_flags & _has_localvariable_table) != 0; }
 
+  bool has_exception_handler() const
+    { return (_flags & _has_exception_table) != 0; }
+
   void set_interpreter_kind(int kind)      { _interpreter_kind = kind; }
   int  interpreter_kind(void) const        { return _interpreter_kind; }
 
-  // backpointer to non-const methodOop
-  methodOop method() const                 { return _method; }
-  void set_method(methodOop m)             { oop_store_without_check((oop*)&_method, (oop) m); }
+  // constant pool
+  constantPoolOop constants() const        { return _constants; }
+  void set_constants(constantPoolOop c)    {
+    oop_store_without_check((oop*)&_constants, (oop)c);
+  }
 
+  methodOop method() const;
 
   // stackmap table data
   typeArrayOop stackmap_data() const { return _stackmap_data; }
@@ -179,11 +195,6 @@
   }
   bool has_stackmap_table() const { return _stackmap_data != NULL; }
 
-  // exception handler table
-  typeArrayOop exception_table() const           { return _exception_table; }
-  void set_exception_table(typeArrayOop e)       { oop_store_without_check((oop*) &_exception_table, (oop) e); }
-  bool has_exception_handler() const             { return exception_table() != NULL && exception_table()->length() > 0; }
-
   void init_fingerprint() {
     const uint64_t initval = CONST64(0x8000000000000000);
     _fingerprint = initval;
@@ -233,6 +244,7 @@
   // Object size needed
   static int object_size(int code_size, int compressed_line_number_size,
                          int local_variable_table_length,
+                         int exception_table_length,
                          int checked_exceptions_length);
 
   int object_size() const                 { return _constMethod_size; }
@@ -254,6 +266,7 @@
   u_char* compressed_linenumber_table() const;         // not preserved by gc
   u2* checked_exceptions_length_addr() const;
   u2* localvariable_table_length_addr() const;
+  u2* exception_table_length_addr() const;
 
   // checked exceptions
   int checked_exceptions_length() const;
@@ -263,6 +276,10 @@
   int localvariable_table_length() const;
   LocalVariableTableElement* localvariable_table_start() const;
 
+  // exception table
+  int exception_table_length() const;
+  ExceptionTableElement* exception_table_start() const;
+
   // byte codes
   void    set_code(address code) {
     if (code_size() > 0) {
@@ -278,13 +295,12 @@
                             { return in_ByteSize(sizeof(constMethodOopDesc)); }
 
   // interpreter support
-  static ByteSize exception_table_offset()
-               { return byte_offset_of(constMethodOopDesc, _exception_table); }
+  static ByteSize constants_offset()
+               { return byte_offset_of(constMethodOopDesc, _constants); }
 
   // Garbage collection support
-  oop*  adr_method() const             { return (oop*)&_method;          }
+  oop*  adr_constants() const          { return (oop*)&_constants; }
   oop*  adr_stackmap_data() const      { return (oop*)&_stackmap_data;   }
-  oop*  adr_exception_table() const    { return (oop*)&_exception_table; }
   bool is_conc_safe() { return _is_conc_safe; }
   void set_is_conc_safe(bool v) { _is_conc_safe = v; }
 
diff --git a/hotspot/src/share/vm/oops/constantPoolOop.cpp b/hotspot/src/share/vm/oops/constantPoolOop.cpp
index 493249d..25dde7a 100644
--- a/hotspot/src/share/vm/oops/constantPoolOop.cpp
+++ b/hotspot/src/share/vm/oops/constantPoolOop.cpp
@@ -267,25 +267,44 @@
 
 
 methodOop constantPoolOopDesc::method_at_if_loaded(constantPoolHandle cpool,
-                                                   int which, Bytecodes::Code invoke_code) {
+                                                   int which) {
   assert(!constantPoolCacheOopDesc::is_secondary_index(which), "no indy instruction here");
   if (cpool->cache() == NULL)  return NULL;  // nothing to load yet
-  int cache_index = which - CPCACHE_INDEX_TAG;
-  if (!(cache_index >= 0 && cache_index < cpool->cache()->length())) {
-    if (PrintMiscellaneous && (Verbose||WizardMode)) {
-      tty->print_cr("bad operand %d for %d in:", which, invoke_code); cpool->print();
-    }
-    return NULL;
-  }
+  int cache_index = decode_cpcache_index(which, true);
   ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
-  if (invoke_code != Bytecodes::_illegal)
-    return e->get_method_if_resolved(invoke_code, cpool);
-  Bytecodes::Code bc;
-  if ((bc = e->bytecode_1()) != (Bytecodes::Code)0)
-    return e->get_method_if_resolved(bc, cpool);
-  if ((bc = e->bytecode_2()) != (Bytecodes::Code)0)
-    return e->get_method_if_resolved(bc, cpool);
-  return NULL;
+  return e->method_if_resolved(cpool);
+}
+
+
+bool constantPoolOopDesc::has_appendix_at_if_loaded(constantPoolHandle cpool, int which) {
+  if (cpool->cache() == NULL)  return false;  // nothing to load yet
+  int cache_index = decode_cpcache_index(which, true);
+  ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
+  return e->has_appendix();
+}
+
+
+oop constantPoolOopDesc::appendix_at_if_loaded(constantPoolHandle cpool, int which) {
+  if (cpool->cache() == NULL)  return NULL;  // nothing to load yet
+  int cache_index = decode_cpcache_index(which, true);
+  ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
+  return e->appendix_if_resolved(cpool);
+}
+
+
+bool constantPoolOopDesc::has_method_type_at_if_loaded(constantPoolHandle cpool, int which) {
+  if (cpool->cache() == NULL)  return false;  // nothing to load yet
+  int cache_index = decode_cpcache_index(which, true);
+  ConstantPoolCacheEntry* e = cpool->cache()->entry_at(cache_index);
+  return e->has_method_type();
+}
+
+oop constantPoolOopDesc::method_type_at_if_loaded(constantPoolHandle cpool, int which) {
+  if (cpool->cache() == NULL)  return NULL;  // nothing to load yet
+  int cache_index = decode_cpcache_index(which, true);
+  ConstantPoolCacheEntry* e  = cpool->cache()->entry_at(cache_index);  // get next CPC entry
+  ConstantPoolCacheEntry* e2 = cpool->cache()->find_secondary_entry_for(e);
+  return e2->method_type_if_resolved(cpool);
 }
 
 
@@ -481,7 +500,7 @@
   if (cache_index >= 0) {
     assert(index == _no_index_sentinel, "only one kind of index at a time");
     ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
-    result_oop = cpc_entry->f1();
+    result_oop = cpc_entry->f1_as_instance();
     if (result_oop != NULL) {
       return decode_exception_from_f1(result_oop, THREAD);
       // That was easy...
@@ -553,12 +572,7 @@
                       index, this_oop->method_type_index_at(index),
                       signature->as_C_string());
       KlassHandle klass(THREAD, this_oop->pool_holder());
-      bool ignore_is_on_bcp = false;
-      Handle value = SystemDictionary::find_method_handle_type(signature,
-                                                               klass,
-                                                               false,
-                                                               ignore_is_on_bcp,
-                                                               THREAD);
+      Handle value = SystemDictionary::find_method_handle_type(signature, klass, THREAD);
       if (HAS_PENDING_EXCEPTION) {
         throw_exception = Handle(THREAD, PENDING_EXCEPTION);
         CLEAR_PENDING_EXCEPTION;
@@ -608,7 +622,7 @@
     result_oop = NULL;  // safety
     ObjectLocker ol(this_oop, THREAD);
     ConstantPoolCacheEntry* cpc_entry = this_oop->cache()->entry_at(cache_index);
-    result_oop = cpc_entry->f1();
+    result_oop = cpc_entry->f1_as_instance();
     // Benign race condition:  f1 may already be filled in while we were trying to lock.
     // The important thing here is that all threads pick up the same result.
     // It doesn't matter which racing thread wins, as long as only one
@@ -627,6 +641,45 @@
   }
 }
 
+
+oop constantPoolOopDesc::resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS) {
+  assert(this_oop->tag_at(index).is_invoke_dynamic(), "Corrupted constant pool");
+
+  Handle bsm;
+  int argc;
+  {
+    // JVM_CONSTANT_InvokeDynamic is an ordered pair of [bootm, name&type], plus optional arguments
+    // The bootm, being a JVM_CONSTANT_MethodHandle, has its own cache entry.
+    // It is accompanied by the optional arguments.
+    int bsm_index = this_oop->invoke_dynamic_bootstrap_method_ref_index_at(index);
+    oop bsm_oop = this_oop->resolve_possibly_cached_constant_at(bsm_index, CHECK_NULL);
+    if (!java_lang_invoke_MethodHandle::is_instance(bsm_oop)) {
+      THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "BSM not an MethodHandle");
+    }
+
+    // Extract the optional static arguments.
+    argc = this_oop->invoke_dynamic_argument_count_at(index);
+    if (argc == 0)  return bsm_oop;
+
+    bsm = Handle(THREAD, bsm_oop);
+  }
+
+  objArrayHandle info;
+  {
+    objArrayOop info_oop = oopFactory::new_objArray(SystemDictionary::Object_klass(), 1+argc, CHECK_NULL);
+    info = objArrayHandle(THREAD, info_oop);
+  }
+
+  info->obj_at_put(0, bsm());
+  for (int i = 0; i < argc; i++) {
+    int arg_index = this_oop->invoke_dynamic_argument_index_at(index, i);
+    oop arg_oop = this_oop->resolve_possibly_cached_constant_at(arg_index, CHECK_NULL);
+    info->obj_at_put(1+i, arg_oop);
+  }
+
+  return info();
+}
+
 oop constantPoolOopDesc::string_at_impl(constantPoolHandle this_oop, int which, TRAPS) {
   oop str = NULL;
   CPSlot entry = this_oop->slot_at(which);
diff --git a/hotspot/src/share/vm/oops/constantPoolOop.hpp b/hotspot/src/share/vm/oops/constantPoolOop.hpp
index c2f985d..ad72e2b 100644
--- a/hotspot/src/share/vm/oops/constantPoolOop.hpp
+++ b/hotspot/src/share/vm/oops/constantPoolOop.hpp
@@ -642,6 +642,11 @@
     return resolve_constant_at_impl(h_this, pool_index, _possible_index_sentinel, THREAD);
   }
 
+  oop resolve_bootstrap_specifier_at(int index, TRAPS) {
+    constantPoolHandle h_this(THREAD, this);
+    return resolve_bootstrap_specifier_at_impl(h_this, index, THREAD);
+  }
+
   // Klass name matches name at offset
   bool klass_name_at_matches(instanceKlassHandle k, int which);
 
@@ -666,12 +671,15 @@
   friend class SystemDictionary;
 
   // Used by compiler to prevent classloading.
-  static methodOop method_at_if_loaded        (constantPoolHandle this_oop, int which,
-                                               Bytecodes::Code bc = Bytecodes::_illegal);
-  static klassOop klass_at_if_loaded          (constantPoolHandle this_oop, int which);
-  static klassOop klass_ref_at_if_loaded      (constantPoolHandle this_oop, int which);
+  static methodOop       method_at_if_loaded      (constantPoolHandle this_oop, int which);
+  static bool      has_appendix_at_if_loaded      (constantPoolHandle this_oop, int which);
+  static oop           appendix_at_if_loaded      (constantPoolHandle this_oop, int which);
+  static bool   has_method_type_at_if_loaded      (constantPoolHandle this_oop, int which);
+  static oop        method_type_at_if_loaded      (constantPoolHandle this_oop, int which);
+  static klassOop         klass_at_if_loaded      (constantPoolHandle this_oop, int which);
+  static klassOop     klass_ref_at_if_loaded      (constantPoolHandle this_oop, int which);
   // Same as above - but does LinkResolving.
-  static klassOop klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS);
+  static klassOop     klass_ref_at_if_loaded_check(constantPoolHandle this_oop, int which, TRAPS);
 
   // Routines currently used for annotations (only called by jvm.cpp) but which might be used in the
   // future by other Java code. These take constant pool indices rather than
@@ -697,6 +705,14 @@
   enum { CPCACHE_INDEX_TAG = 0 };        // in product mode, this zero value is a no-op
 #endif //ASSERT
 
+  static int get_cpcache_index(int index) { return index - CPCACHE_INDEX_TAG; }
+  static int decode_cpcache_index(int raw_index, bool invokedynamic_ok = false) {
+    if (invokedynamic_ok && constantPoolCacheOopDesc::is_secondary_index(raw_index))
+      return constantPoolCacheOopDesc::decode_secondary_index(raw_index);
+    else
+      return get_cpcache_index(raw_index);
+  }
+
  private:
 
   Symbol* impl_name_ref_at(int which, bool uncached);
@@ -729,6 +745,7 @@
   static void resolve_string_constants_impl(constantPoolHandle this_oop, TRAPS);
 
   static oop resolve_constant_at_impl(constantPoolHandle this_oop, int index, int cache_index, TRAPS);
+  static oop resolve_bootstrap_specifier_at_impl(constantPoolHandle this_oop, int index, TRAPS);
 
  public:
   // Merging constantPoolOop support:
@@ -764,7 +781,7 @@
                         unsigned char *bytes);
 };
 
-class SymbolHashMapEntry : public CHeapObj {
+class SymbolHashMapEntry : public CHeapObj<mtSymbol> {
  private:
   unsigned int        _hash;   // 32-bit hash for item
   SymbolHashMapEntry* _next;   // Next element in the linked list for this bucket
@@ -790,7 +807,7 @@
 }; // End SymbolHashMapEntry class
 
 
-class SymbolHashMapBucket : public CHeapObj {
+class SymbolHashMapBucket : public CHeapObj<mtSymbol> {
 
 private:
   SymbolHashMapEntry*    _entry;
@@ -803,7 +820,7 @@
 }; // End SymbolHashMapBucket class
 
 
-class SymbolHashMap: public CHeapObj {
+class SymbolHashMap: public CHeapObj<mtSymbol> {
 
  private:
   // Default number of entries in the table
@@ -816,7 +833,7 @@
 
   void initialize_table(int table_size) {
     _table_size = table_size;
-    _buckets = NEW_C_HEAP_ARRAY(SymbolHashMapBucket, table_size);
+    _buckets = NEW_C_HEAP_ARRAY(SymbolHashMapBucket, table_size, mtSymbol);
     for (int index = 0; index < table_size; index++) {
       _buckets[index].clear();
     }
diff --git a/hotspot/src/share/vm/oops/cpCacheOop.cpp b/hotspot/src/share/vm/oops/cpCacheOop.cpp
index 678bc13..f9f8846 100644
--- a/hotspot/src/share/vm/oops/cpCacheOop.cpp
+++ b/hotspot/src/share/vm/oops/cpCacheOop.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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,6 +31,7 @@
 #include "oops/objArrayOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "prims/jvmtiRedefineClassesTrace.hpp"
+#include "prims/methodHandles.hpp"
 #include "runtime/handles.inline.hpp"
 
 
@@ -44,68 +45,61 @@
 
 void ConstantPoolCacheEntry::initialize_secondary_entry(int main_index) {
   assert(0 <= main_index && main_index < 0x10000, "sanity check");
-  _indices = (main_index << 16);
+  _indices = (main_index << main_cp_index_bits);
   assert(main_entry_index() == main_index, "");
 }
 
-int ConstantPoolCacheEntry::as_flags(TosState state, bool is_final,
-                    bool is_vfinal, bool is_volatile,
-                    bool is_method_interface, bool is_method) {
-  int f = state;
-
-  assert( state < number_of_states, "Invalid state in as_flags");
-
-  f <<= 1;
-  if (is_final) f |= 1;
-  f <<= 1;
-  if (is_vfinal) f |= 1;
-  f <<= 1;
-  if (is_volatile) f |= 1;
-  f <<= 1;
-  if (is_method_interface) f |= 1;
-  f <<= 1;
-  if (is_method) f |= 1;
-  f <<= ConstantPoolCacheEntry::hotSwapBit;
+int ConstantPoolCacheEntry::make_flags(TosState state,
+                                       int option_bits,
+                                       int field_index_or_method_params) {
+  assert(state < number_of_states, "Invalid state in make_flags");
+  int f = ((int)state << tos_state_shift) | option_bits | field_index_or_method_params;
   // Preserve existing flag bit values
+  // The low bits are a field offset, or else the method parameter size.
 #ifdef ASSERT
-  int old_state = ((_flags >> tosBits) & 0x0F);
-  assert(old_state == 0 || old_state == state,
+  TosState old_state = flag_state();
+  assert(old_state == (TosState)0 || old_state == state,
          "inconsistent cpCache flags state");
 #endif
   return (_flags | f) ;
 }
 
 void ConstantPoolCacheEntry::set_bytecode_1(Bytecodes::Code code) {
+  assert(!is_secondary_entry(), "must not overwrite main_entry_index");
 #ifdef ASSERT
   // Read once.
   volatile Bytecodes::Code c = bytecode_1();
   assert(c == 0 || c == code || code == 0, "update must be consistent");
 #endif
   // Need to flush pending stores here before bytecode is written.
-  OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << 16));
+  OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << bytecode_1_shift));
 }
 
 void ConstantPoolCacheEntry::set_bytecode_2(Bytecodes::Code code) {
+  assert(!is_secondary_entry(), "must not overwrite main_entry_index");
 #ifdef ASSERT
   // Read once.
   volatile Bytecodes::Code c = bytecode_2();
   assert(c == 0 || c == code || code == 0, "update must be consistent");
 #endif
   // Need to flush pending stores here before bytecode is written.
-  OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << 24));
+  OrderAccess::release_store_ptr(&_indices, _indices | ((u_char)code << bytecode_2_shift));
 }
 
-// Atomically sets f1 if it is still NULL, otherwise it keeps the
-// current value.
-void ConstantPoolCacheEntry::set_f1_if_null_atomic(oop f1) {
+// Sets f1, ordering with previous writes.
+void ConstantPoolCacheEntry::release_set_f1(oop f1) {
   // Use barriers as in oop_store
+  assert(f1 != NULL, "");
   oop* f1_addr = (oop*) &_f1;
   update_barrier_set_pre(f1_addr, f1);
-  void* result = Atomic::cmpxchg_ptr(f1, f1_addr, NULL);
-  bool success = (result == NULL);
-  if (success) {
-    update_barrier_set((void*) f1_addr, f1);
-  }
+  OrderAccess::release_store_ptr((intptr_t*)f1_addr, f1);
+  update_barrier_set((void*) f1_addr, f1);
+}
+
+// Sets flags, but only if the value was previously zero.
+bool ConstantPoolCacheEntry::init_flags_atomic(intptr_t flags) {
+  intptr_t result = Atomic::cmpxchg_ptr(flags, &_flags, 0);
+  return (result == 0);
 }
 
 #ifdef ASSERT
@@ -135,17 +129,32 @@
                                        bool is_volatile) {
   set_f1(field_holder()->java_mirror());
   set_f2(field_offset);
-  assert(field_index <= field_index_mask,
+  assert((field_index & field_index_mask) == field_index,
          "field index does not fit in low flag bits");
-  set_flags(as_flags(field_type, is_final, false, is_volatile, false, false) |
-            (field_index & field_index_mask));
+  set_field_flags(field_type,
+                  ((is_volatile ? 1 : 0) << is_volatile_shift) |
+                  ((is_final    ? 1 : 0) << is_final_shift),
+                  field_index);
   set_bytecode_1(get_code);
   set_bytecode_2(put_code);
   NOT_PRODUCT(verify(tty));
 }
 
-int  ConstantPoolCacheEntry::field_index() const {
-  return (_flags & field_index_mask);
+void ConstantPoolCacheEntry::set_parameter_size(int value) {
+  // This routine is called only in corner cases where the CPCE is not yet initialized.
+  // See AbstractInterpreter::deopt_continue_after_entry.
+  assert(_flags == 0 || parameter_size() == 0 || parameter_size() == value,
+         err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value));
+  // Setting the parameter size by itself is only safe if the
+  // current value of _flags is 0, otherwise another thread may have
+  // updated it and we don't want to overwrite that value.  Don't
+  // bother trying to update it once it's nonzero but always make
+  // sure that the final parameter size agrees with what was passed.
+  if (_flags == 0) {
+    Atomic::cmpxchg_ptr((value & parameter_size_mask), &_flags, 0);
+  }
+  guarantee(parameter_size() == value,
+            err_msg("size must not change: parameter_size=%d, value=%d", parameter_size(), value));
 }
 
 void ConstantPoolCacheEntry::set_method(Bytecodes::Code invoke_code,
@@ -154,51 +163,51 @@
   assert(!is_secondary_entry(), "");
   assert(method->interpreter_entry() != NULL, "should have been set at this point");
   assert(!method->is_obsolete(),  "attempt to write obsolete method to cpCache");
-  bool change_to_virtual = (invoke_code == Bytecodes::_invokeinterface);
 
   int byte_no = -1;
-  bool needs_vfinal_flag = false;
+  bool change_to_virtual = false;
+
   switch (invoke_code) {
+    case Bytecodes::_invokeinterface:
+      // We get here from InterpreterRuntime::resolve_invoke when an invokeinterface
+      // instruction somehow links to a non-interface method (in Object).
+      // In that case, the method has no itable index and must be invoked as a virtual.
+      // Set a flag to keep track of this corner case.
+      change_to_virtual = true;
+
+      // ...and fall through as if we were handling invokevirtual:
     case Bytecodes::_invokevirtual:
-    case Bytecodes::_invokeinterface: {
+      {
         if (method->can_be_statically_bound()) {
-          set_f2((intptr_t)method());
-          needs_vfinal_flag = true;
+          // set_f2_as_vfinal_method checks if is_vfinal flag is true.
+          set_method_flags(as_TosState(method->result_type()),
+                           (                             1      << is_vfinal_shift) |
+                           ((method->is_final_method() ? 1 : 0) << is_final_shift)  |
+                           ((change_to_virtual         ? 1 : 0) << is_forced_virtual_shift),
+                           method()->size_of_parameters());
+          set_f2_as_vfinal_method(method());
         } else {
           assert(vtable_index >= 0, "valid index");
+          assert(!method->is_final_method(), "sanity");
+          set_method_flags(as_TosState(method->result_type()),
+                           ((change_to_virtual ? 1 : 0) << is_forced_virtual_shift),
+                           method()->size_of_parameters());
           set_f2(vtable_index);
         }
         byte_no = 2;
         break;
-    }
-
-    case Bytecodes::_invokedynamic:  // similar to _invokevirtual
-      if (TraceInvokeDynamic) {
-        tty->print_cr("InvokeDynamic set_method%s method="PTR_FORMAT" index=%d",
-                      (is_secondary_entry() ? " secondary" : ""),
-                      (intptr_t)method(), vtable_index);
-        method->print();
-        this->print(tty, 0);
       }
-      assert(method->can_be_statically_bound(), "must be a MH invoker method");
-      assert(_f2 >= constantPoolOopDesc::CPCACHE_INDEX_TAG, "BSM index initialized");
-      // SystemDictionary::find_method_handle_invoke only caches
-      // methods which signature classes are on the boot classpath,
-      // otherwise the newly created method is returned.  To avoid
-      // races in that case we store the first one coming in into the
-      // cp-cache atomically if it's still unset.
-      set_f1_if_null_atomic(method());
-      needs_vfinal_flag = false;  // _f2 is not an oop
-      assert(!is_vfinal(), "f2 not an oop");
-      byte_no = 1;  // coordinate this with bytecode_number & is_resolved
-      break;
 
     case Bytecodes::_invokespecial:
-      // Preserve the value of the vfinal flag on invokevirtual bytecode
-      // which may be shared with this constant pool cache entry.
-      needs_vfinal_flag = is_resolved(Bytecodes::_invokevirtual) && is_vfinal();
-      // fall through
     case Bytecodes::_invokestatic:
+      // Note:  Read and preserve the value of the is_vfinal flag on any
+      // invokevirtual bytecode shared with this constant pool cache entry.
+      // It is cheap and safe to consult is_vfinal() at all times.
+      // Once is_vfinal is set, it must stay that way, lest we get a dangling oop.
+      set_method_flags(as_TosState(method->result_type()),
+                       ((is_vfinal()               ? 1 : 0) << is_vfinal_shift) |
+                       ((method->is_final_method() ? 1 : 0) << is_final_shift),
+                       method()->size_of_parameters());
       set_f1(method());
       byte_no = 1;
       break;
@@ -207,19 +216,14 @@
       break;
   }
 
-  set_flags(as_flags(as_TosState(method->result_type()),
-                     method->is_final_method(),
-                     needs_vfinal_flag,
-                     false,
-                     change_to_virtual,
-                     true)|
-            method()->size_of_parameters());
-
   // Note:  byte_no also appears in TemplateTable::resolve.
   if (byte_no == 1) {
+    assert(invoke_code != Bytecodes::_invokevirtual &&
+           invoke_code != Bytecodes::_invokeinterface, "");
     set_bytecode_1(invoke_code);
   } else if (byte_no == 2)  {
     if (change_to_virtual) {
+      assert(invoke_code == Bytecodes::_invokeinterface, "");
       // NOTE: THIS IS A HACK - BE VERY CAREFUL!!!
       //
       // Workaround for the case where we encounter an invokeinterface, but we
@@ -235,10 +239,11 @@
       // Otherwise, the method needs to be reresolved with caller for each
       // interface call.
       if (method->is_public()) set_bytecode_1(invoke_code);
-      set_bytecode_2(Bytecodes::_invokevirtual);
     } else {
-      set_bytecode_2(invoke_code);
+      assert(invoke_code == Bytecodes::_invokevirtual, "");
     }
+    // set up for invokevirtual, even if linking for invokeinterface also:
+    set_bytecode_2(Bytecodes::_invokevirtual);
   } else {
     ShouldNotReachHere();
   }
@@ -250,73 +255,155 @@
   assert(!is_secondary_entry(), "");
   klassOop interf = method->method_holder();
   assert(instanceKlass::cast(interf)->is_interface(), "must be an interface");
+  assert(!method->is_final_method(), "interfaces do not have final methods; cannot link to one here");
   set_f1(interf);
   set_f2(index);
-  set_flags(as_flags(as_TosState(method->result_type()), method->is_final_method(), false, false, false, true) | method()->size_of_parameters());
+  set_method_flags(as_TosState(method->result_type()),
+                   0,  // no option bits
+                   method()->size_of_parameters());
   set_bytecode_1(Bytecodes::_invokeinterface);
 }
 
 
-void ConstantPoolCacheEntry::initialize_bootstrap_method_index_in_cache(int bsm_cache_index) {
-  assert(!is_secondary_entry(), "only for JVM_CONSTANT_InvokeDynamic main entry");
-  assert(_f2 == 0, "initialize once");
-  assert(bsm_cache_index == (int)(u2)bsm_cache_index, "oob");
-  set_f2(bsm_cache_index + constantPoolOopDesc::CPCACHE_INDEX_TAG);
+void ConstantPoolCacheEntry::set_method_handle(constantPoolHandle cpool,
+                                               methodHandle adapter,
+                                               Handle appendix, Handle method_type) {
+  assert(!is_secondary_entry(), "");
+  set_method_handle_common(cpool, Bytecodes::_invokehandle, adapter, appendix, method_type);
 }
 
-int ConstantPoolCacheEntry::bootstrap_method_index_in_cache() {
-  assert(!is_secondary_entry(), "only for JVM_CONSTANT_InvokeDynamic main entry");
-  intptr_t bsm_cache_index = (intptr_t) _f2 - constantPoolOopDesc::CPCACHE_INDEX_TAG;
-  assert(bsm_cache_index == (intptr_t)(u2)bsm_cache_index, "oob");
-  return (int) bsm_cache_index;
-}
-
-void ConstantPoolCacheEntry::set_dynamic_call(Handle call_site, methodHandle signature_invoker) {
+void ConstantPoolCacheEntry::set_dynamic_call(constantPoolHandle cpool,
+                                              methodHandle adapter,
+                                              Handle appendix, Handle method_type) {
   assert(is_secondary_entry(), "");
-  // NOTE: it's important that all other values are set before f1 is
-  // set since some users short circuit on f1 being set
-  // (i.e. non-null) and that may result in uninitialized values for
-  // other racing threads (e.g. flags).
-  int param_size = signature_invoker->size_of_parameters();
-  assert(param_size >= 1, "method argument size must include MH.this");
-  param_size -= 1;  // do not count MH.this; it is not stacked for invokedynamic
-  bool is_final = true;
-  assert(signature_invoker->is_final_method(), "is_final");
-  int flags = as_flags(as_TosState(signature_invoker->result_type()), is_final, false, false, false, true) | param_size;
-  assert(_flags == 0 || _flags == flags, "flags should be the same");
-  set_flags(flags);
-  // do not do set_bytecode on a secondary CP cache entry
-  //set_bytecode_1(Bytecodes::_invokedynamic);
-  set_f1_if_null_atomic(call_site());  // This must be the last one to set (see NOTE above)!
+  set_method_handle_common(cpool, Bytecodes::_invokedynamic, adapter, appendix, method_type);
 }
 
+void ConstantPoolCacheEntry::set_method_handle_common(constantPoolHandle cpool,
+                                                      Bytecodes::Code invoke_code,
+                                                      methodHandle adapter,
+                                                      Handle appendix, Handle method_type) {
+  // NOTE: This CPCE can be the subject of data races.
+  // There are three words to update: flags, f2, f1 (in that order).
+  // Writers must store all other values before f1.
+  // Readers must test f1 first for non-null before reading other fields.
+  // Competing writers must acquire exclusive access via a lock.
+  // A losing writer waits on the lock until the winner writes f1 and leaves
+  // the lock, so that when the losing writer returns, he can use the linked
+  // cache entry.
 
-methodOop ConstantPoolCacheEntry::get_method_if_resolved(Bytecodes::Code invoke_code, constantPoolHandle cpool) {
-  assert(invoke_code > (Bytecodes::Code)0, "bad query");
+  Thread* THREAD = Thread::current();
+  ObjectLocker ol(cpool, THREAD);
+  if (!is_f1_null()) {
+    return;
+  }
+
+  const bool has_appendix    = appendix.not_null();
+  const bool has_method_type = method_type.not_null();
+
+  if (!has_appendix) {
+    // The extra argument is not used, but we need a non-null value to signify linkage state.
+    // Set it to something benign that will never leak memory.
+    appendix = Universe::void_mirror();
+  }
+
+  // Write the flags.
+  set_method_flags(as_TosState(adapter->result_type()),
+                   ((has_appendix    ? 1 : 0) << has_appendix_shift)    |
+                   ((has_method_type ? 1 : 0) << has_method_type_shift) |
+                   (                   1      << is_vfinal_shift)       |
+                   (                   1      << is_final_shift),
+                   adapter->size_of_parameters());
+
+  if (TraceInvokeDynamic) {
+    tty->print_cr("set_method_handle bc=%d appendix="PTR_FORMAT"%s method_type="PTR_FORMAT"%s method="PTR_FORMAT" ",
+                  invoke_code,
+                  (intptr_t)appendix(),    (has_appendix    ? "" : " (unused)"),
+                  (intptr_t)method_type(), (has_method_type ? "" : " (unused)"),
+                  (intptr_t)adapter());
+    adapter->print();
+    if (has_appendix)  appendix()->print();
+  }
+
+  // Method handle invokes and invokedynamic sites use both cp cache words.
+  // f1, if not null, contains a value passed as a trailing argument to the adapter.
+  // In the general case, this could be the call site's MethodType,
+  // for use with java.lang.Invokers.checkExactType, or else a CallSite object.
+  // f2 contains the adapter method which manages the actual call.
+  // In the general case, this is a compiled LambdaForm.
+  // (The Java code is free to optimize these calls by binding other
+  // sorts of methods and appendices to call sites.)
+  // JVM-level linking is via f2, as if for invokevfinal, and signatures are erased.
+  // The appendix argument (if any) is added to the signature, and is counted in the parameter_size bits.
+  // In principle this means that the method (with appendix) could take up to 256 parameter slots.
+  //
+  // This means that given a call site like (List)mh.invoke("foo"),
+  // the f2 method has signature '(Ljl/Object;Ljl/invoke/MethodType;)Ljl/Object;',
+  // not '(Ljava/lang/String;)Ljava/util/List;'.
+  // The fact that String and List are involved is encoded in the MethodType in f1.
+  // This allows us to create fewer method oops, while keeping type safety.
+  //
+
+  set_f2_as_vfinal_method(adapter());
+
+  // Store MethodType, if any.
+  if (has_method_type) {
+    ConstantPoolCacheEntry* e2 = cpool->cache()->find_secondary_entry_for(this);
+
+    // Write the flags.
+    e2->set_method_flags(as_TosState(adapter->result_type()),
+                     ((has_method_type ? 1 : 0) << has_method_type_shift) |
+                     (                   1      << is_vfinal_shift)       |
+                     (                   1      << is_final_shift),
+                     adapter->size_of_parameters());
+    e2->release_set_f1(method_type());
+  }
+
+  assert(appendix.not_null(), "needed for linkage state");
+  release_set_f1(appendix());  // This must be the last one to set (see NOTE above)!
+
+  if (!is_secondary_entry()) {
+    // The interpreter assembly code does not check byte_2,
+    // but it is used by is_resolved, method_if_resolved, etc.
+    set_bytecode_2(invoke_code);
+  }
+
+  NOT_PRODUCT(verify(tty));
+  if (TraceInvokeDynamic) {
+    this->print(tty, 0);
+  }
+}
+
+methodOop ConstantPoolCacheEntry::method_if_resolved(constantPoolHandle cpool) {
   if (is_secondary_entry()) {
-    return cpool->cache()->entry_at(main_entry_index())->get_method_if_resolved(invoke_code, cpool);
+    if (!is_f1_null())
+      return f2_as_vfinal_method();
+    return NULL;
   }
   // Decode the action of set_method and set_interface_call
-  if (bytecode_1() == invoke_code) {
+  Bytecodes::Code invoke_code = bytecode_1();
+  if (invoke_code != (Bytecodes::Code)0) {
     oop f1 = _f1;
     if (f1 != NULL) {
       switch (invoke_code) {
       case Bytecodes::_invokeinterface:
         assert(f1->is_klass(), "");
-        return klassItable::method_for_itable_index(klassOop(f1), (int) f2());
+        return klassItable::method_for_itable_index(klassOop(f1), f2_as_index());
       case Bytecodes::_invokestatic:
       case Bytecodes::_invokespecial:
+        assert(!has_appendix(), "");
         assert(f1->is_method(), "");
         return methodOop(f1);
       }
     }
   }
-  if (bytecode_2() == invoke_code) {
+  invoke_code = bytecode_2();
+  if (invoke_code != (Bytecodes::Code)0) {
     switch (invoke_code) {
     case Bytecodes::_invokevirtual:
       if (is_vfinal()) {
         // invokevirtual
-        methodOop m = methodOop((intptr_t) f2());
+        methodOop m = f2_as_vfinal_method();
         assert(m->is_method(), "");
         return m;
       } else {
@@ -325,15 +412,32 @@
           klassOop klass = cpool->resolved_klass_at(holder_index);
           if (!Klass::cast(klass)->oop_is_instance())
             klass = SystemDictionary::Object_klass();
-          return instanceKlass::cast(klass)->method_at_vtable((int) f2());
+          return instanceKlass::cast(klass)->method_at_vtable(f2_as_index());
         }
       }
+      break;
+    case Bytecodes::_invokehandle:
+    case Bytecodes::_invokedynamic:
+      return f2_as_vfinal_method();
     }
   }
   return NULL;
 }
 
 
+oop ConstantPoolCacheEntry::appendix_if_resolved(constantPoolHandle cpool) {
+  if (is_f1_null() || !has_appendix())
+    return NULL;
+  return f1_appendix();
+}
+
+
+oop ConstantPoolCacheEntry::method_type_if_resolved(constantPoolHandle cpool) {
+  if (is_f1_null() || !has_method_type())
+    return NULL;
+  return f1_as_instance();
+}
+
 
 class LocalOopClosure: public OopClosure {
  private:
@@ -419,9 +523,10 @@
        methodOop new_method, bool * trace_name_printed) {
 
   if (is_vfinal()) {
-    // virtual and final so f2() contains method ptr instead of vtable index
-    if (f2() == (intptr_t)old_method) {
+    // virtual and final so _f2 contains method ptr instead of vtable index
+    if (f2_as_vfinal_method() == old_method) {
       // match old_method so need an update
+      // NOTE: can't use set_f2_as_vfinal_method as it asserts on different values
       _f2 = (intptr_t)new_method;
       if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) {
         if (!(*trace_name_printed)) {
@@ -479,16 +584,17 @@
   methodOop m = NULL;
   if (is_vfinal()) {
     // virtual and final so _f2 contains method ptr instead of vtable index
-    m = (methodOop)_f2;
-  } else if ((oop)_f1 == NULL) {
+    m = f2_as_vfinal_method();
+  } else if (is_f1_null()) {
     // NULL _f1 means this is a virtual entry so also not interesting
     return false;
   } else {
-    if (!((oop)_f1)->is_method()) {
+    oop f1 = _f1;  // _f1 is volatile
+    if (!f1->is_method()) {
       // _f1 can also contain a klassOop for an interface
       return false;
     }
-    m = (methodOop)_f1;
+    m = f1_as_method();
   }
 
   assert(m != NULL && m->is_method(), "sanity check");
@@ -504,17 +610,17 @@
 
 void ConstantPoolCacheEntry::print(outputStream* st, int index) const {
   // print separator
-  if (index == 0) tty->print_cr("                 -------------");
+  if (index == 0) st->print_cr("                 -------------");
   // print entry
-  tty->print("%3d  ("PTR_FORMAT")  ", index, (intptr_t)this);
+  st->print("%3d  ("PTR_FORMAT")  ", index, (intptr_t)this);
   if (is_secondary_entry())
-    tty->print_cr("[%5d|secondary]", main_entry_index());
+    st->print_cr("[%5d|secondary]", main_entry_index());
   else
-    tty->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index());
-  tty->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)(oop)_f1);
-  tty->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f2);
-  tty->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_flags);
-  tty->print_cr("                 -------------");
+    st->print_cr("[%02x|%02x|%5d]", bytecode_2(), bytecode_1(), constant_pool_index());
+  st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)(oop)_f1);
+  st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_f2);
+  st->print_cr("                 [   "PTR_FORMAT"]", (intptr_t)_flags);
+  st->print_cr("                 -------------");
 }
 
 void ConstantPoolCacheEntry::verify(outputStream* st) const {
diff --git a/hotspot/src/share/vm/oops/cpCacheOop.hpp b/hotspot/src/share/vm/oops/cpCacheOop.hpp
index c3d1847..1ae9bb6 100644
--- a/hotspot/src/share/vm/oops/cpCacheOop.hpp
+++ b/hotspot/src/share/vm/oops/cpCacheOop.hpp
@@ -38,13 +38,14 @@
 // bit number |31                0|
 // bit length |-8--|-8--|---16----|
 // --------------------------------
-// _indices   [ b2 | b1 |  index  ]
-// _f1        [  entry specific   ]
-// _f2        [  entry specific   ]
-// _flags     [t|f|vf|v|m|h|unused|field_index] (for field entries)
-// bit length |4|1|1 |1|1|0|---7--|----16-----]
-// _flags     [t|f|vf|v|m|h|unused|eidx|psze] (for method entries)
-// bit length |4|1|1 |1|1|1|---7--|-8--|-8--]
+// _indices   [ b2 | b1 |  index  ]  index = constant_pool_index (!= 0, normal entries only)
+// _indices   [  index  |  00000  ]  index = main_entry_index (secondary entries only)
+// _f1        [  entry specific   ]  method, klass, or oop (MethodType or CallSite)
+// _f2        [  entry specific   ]  vtable index or vfinal method
+// _flags     [tos|0|00|00|00|f|v|f2|unused|field_index] (for field entries)
+// bit length [ 4 |1|1 |1 | 1|1|1| 1|---5--|----16-----]
+// _flags     [tos|M|vf|fv|ea|f|0|f2|unused|00000|psize] (for method entries)
+// bit length [ 4 |1|1 |1 | 1|1|1| 1|---5--|--8--|--8--]
 
 // --------------------------------
 //
@@ -52,24 +53,23 @@
 // index  = original constant pool index
 // b1     = bytecode 1
 // b2     = bytecode 2
-// psze   = parameters size (method entries only)
-// eidx   = interpreter entry index (method entries only)
+// psize  = parameters size (method entries only)
 // field_index = index into field information in holder instanceKlass
 //          The index max is 0xffff (max number of fields in constant pool)
 //          and is multiplied by (instanceKlass::next_offset) when accessing.
 // t      = TosState (see below)
 // f      = field is marked final (see below)
-// vf     = virtual, final (method entries only : is_vfinal())
+// f2     = virtual but final (method entries only: is_vfinal())
 // v      = field is volatile (see below)
 // m      = invokeinterface used for method in class Object (see below)
 // h      = RedefineClasses/Hotswap bit (see below)
 //
 // The flags after TosState have the following interpretation:
-// bit 27: f flag  true if field is marked final
-// bit 26: vf flag true if virtual final method
-// bit 25: v flag true if field is volatile (only for fields)
-// bit 24: m flag true if invokeinterface used for method in class Object
-// bit 23: 0 for fields, 1 for methods
+// bit 27: 0 for fields, 1 for methods
+// f  flag true if field is marked final
+// v  flag true if field is volatile (only for fields)
+// f2 flag true if f2 contains an oop (e.g., virtual final method)
+// fv flag true if invokeinterface used for method in class Object
 //
 // The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
 // following mapping to the TosState states:
@@ -86,25 +86,26 @@
 //
 // Entry specific: field entries:
 // _indices = get (b1 section) and put (b2 section) bytecodes, original constant pool index
-// _f1      = field holder
-// _f2      = field offset in words
-// _flags   = field type information, original field index in field holder
+// _f1      = field holder (as a java.lang.Class, not a klassOop)
+// _f2      = field offset in bytes
+// _flags   = field type information, original FieldInfo index in field holder
 //            (field_index section)
 //
 // Entry specific: method entries:
 // _indices = invoke code for f1 (b1 section), invoke code for f2 (b2 section),
 //            original constant pool index
-// _f1      = method for all but virtual calls, unused by virtual calls
-//            (note: for interface calls, which are essentially virtual,
-//             contains klassOop for the corresponding interface.
-//            for invokedynamic, f1 contains the CallSite object for the invocation
-// _f2      = method/vtable index for virtual calls only, unused by all other
-//            calls.  The vf flag indicates this is a method pointer not an
-//            index.
-// _flags   = field type info (f section),
-//            virtual final entry (vf),
-//            interpreter entry index (eidx section),
-//            parameter size (psze section)
+// _f1      = methodOop for non-virtual calls, unused by virtual calls.
+//            for interface calls, which are essentially virtual but need a klass,
+//            contains klassOop for the corresponding interface.
+//            for invokedynamic, f1 contains a site-specific CallSite object (as an appendix)
+//            for invokehandle, f1 contains a site-specific MethodType object (as an appendix)
+//            (upcoming metadata changes will move the appendix to a separate array)
+// _f2      = vtable/itable index (or final methodOop) for virtual calls only,
+//            unused by non-virtual.  The is_vfinal flag indicates this is a
+//            method pointer for a final method, not an index.
+// _flags   = method type info (t section),
+//            virtual final bit (vfinal),
+//            parameter size (psize section)
 //
 // Note: invokevirtual & invokespecial bytecodes can share the same constant
 //       pool entry and thus the same constant pool cache entry. All invoke
@@ -138,31 +139,63 @@
     assert(existing_f1 == NULL || existing_f1 == f1, "illegal field change");
     oop_store(&_f1, f1);
   }
-  void set_f1_if_null_atomic(oop f1);
-  void set_f2(intx f2)                           { assert(_f2 == 0    || _f2 == f2, "illegal field change"); _f2 = f2; }
-  int as_flags(TosState state, bool is_final, bool is_vfinal, bool is_volatile,
-               bool is_method_interface, bool is_method);
+  void release_set_f1(oop f1);
+  void set_f2(intx f2)                           { assert(_f2 == 0 || _f2 == f2,            "illegal field change"); _f2 = f2; }
+  void set_f2_as_vfinal_method(methodOop f2)     { assert(_f2 == 0 || _f2 == (intptr_t) f2, "illegal field change"); assert(is_vfinal(), "flags must be set"); _f2 = (intptr_t) f2; }
+  int make_flags(TosState state, int option_bits, int field_index_or_method_params);
   void set_flags(intx flags)                     { _flags = flags; }
+  bool init_flags_atomic(intx flags);
+  void set_field_flags(TosState field_type, int option_bits, int field_index) {
+    assert((field_index & field_index_mask) == field_index, "field_index in range");
+    set_flags(make_flags(field_type, option_bits | (1 << is_field_entry_shift), field_index));
+  }
+  void set_method_flags(TosState return_type, int option_bits, int method_params) {
+    assert((method_params & parameter_size_mask) == method_params, "method_params in range");
+    set_flags(make_flags(return_type, option_bits, method_params));
+  }
+  bool init_method_flags_atomic(TosState return_type, int option_bits, int method_params) {
+    assert((method_params & parameter_size_mask) == method_params, "method_params in range");
+    return init_flags_atomic(make_flags(return_type, option_bits, method_params));
+  }
 
  public:
-  // specific bit values in flag field
-  // Note: the interpreter knows this layout!
-  enum FlagBitValues {
-    hotSwapBit    = 23,
-    methodInterface = 24,
-    volatileField = 25,
-    vfinalMethod  = 26,
-    finalField    = 27
+  // specific bit definitions for the flags field:
+  // (Note: the interpreter must use these definitions to access the CP cache.)
+  enum {
+    // high order bits are the TosState corresponding to field type or method return type
+    tos_state_bits             = 4,
+    tos_state_mask             = right_n_bits(tos_state_bits),
+    tos_state_shift            = BitsPerInt - tos_state_bits,  // see verify_tos_state_shift below
+    // misc. option bits; can be any bit position in [16..27]
+    is_vfinal_shift            = 20,
+    is_volatile_shift          = 21,
+    is_final_shift             = 22,
+    has_appendix_shift         = 23,
+    has_method_type_shift      = 24,
+    is_forced_virtual_shift    = 25,
+    is_field_entry_shift       = 26,
+    // low order bits give field index (for FieldInfo) or method parameter size:
+    field_index_bits           = 16,
+    field_index_mask           = right_n_bits(field_index_bits),
+    parameter_size_bits        = 8,  // subset of field_index_mask, range is 0..255
+    parameter_size_mask        = right_n_bits(parameter_size_bits),
+    option_bits_mask           = ~(((-1) << tos_state_shift) | (field_index_mask | parameter_size_mask))
   };
 
-  enum { field_index_mask = 0xFFFF };
-
-  // start of type bits in flags
-  // Note: the interpreter knows this layout!
-  enum FlagValues {
-    tosBits      = 28
+  // specific bit definitions for the indices field:
+  enum {
+    main_cp_index_bits         = 2*BitsPerByte,
+    main_cp_index_mask         = right_n_bits(main_cp_index_bits),
+    bytecode_1_shift           = main_cp_index_bits,
+    bytecode_1_mask            = right_n_bits(BitsPerByte), // == (u1)0xFF
+    bytecode_2_shift           = main_cp_index_bits + BitsPerByte,
+    bytecode_2_mask            = right_n_bits(BitsPerByte), // == (u1)0xFF
+    // the secondary cp index overlaps with bytecodes 1 and 2:
+    secondary_cp_index_shift   = bytecode_1_shift,
+    secondary_cp_index_bits    = BitsPerInt - main_cp_index_bits
   };
 
+
   // Initialization
   void initialize_entry(int original_index);     // initialize primary entry
   void initialize_secondary_entry(int main_index); // initialize secondary entry
@@ -189,30 +222,48 @@
     int index                                    // Method index into interface
   );
 
-  void set_dynamic_call(
-    Handle call_site,                            // Resolved java.lang.invoke.CallSite (f1)
-    methodHandle signature_invoker               // determines signature information
+  void set_method_handle(
+    constantPoolHandle cpool,                    // holding constant pool (required for locking)
+    methodHandle method,                         // adapter for invokeExact, etc.
+    Handle appendix,                             // stored in f1; could be a java.lang.invoke.MethodType
+    Handle method_type                           // stored in f1 (of secondary entry); is a java.lang.invoke.MethodType
   );
 
-  methodOop get_method_if_resolved(Bytecodes::Code invoke_code, constantPoolHandle cpool);
+  void set_dynamic_call(
+    constantPoolHandle cpool,                    // holding constant pool (required for locking)
+    methodHandle method,                         // adapter for this call site
+    Handle appendix,                             // stored in f1; could be a java.lang.invoke.CallSite
+    Handle method_type                           // stored in f1 (of secondary entry); is a java.lang.invoke.MethodType
+  );
 
-  // For JVM_CONSTANT_InvokeDynamic cache entries:
-  void initialize_bootstrap_method_index_in_cache(int bsm_cache_index);
-  int  bootstrap_method_index_in_cache();
+  // Common code for invokedynamic and MH invocations.
 
-  void set_parameter_size(int value) {
-    assert(parameter_size() == 0 || parameter_size() == value,
-           "size must not change");
-    // Setting the parameter size by itself is only safe if the
-    // current value of _flags is 0, otherwise another thread may have
-    // updated it and we don't want to overwrite that value.  Don't
-    // bother trying to update it once it's nonzero but always make
-    // sure that the final parameter size agrees with what was passed.
-    if (_flags == 0) {
-      Atomic::cmpxchg_ptr((value & 0xFF), &_flags, 0);
-    }
-    guarantee(parameter_size() == value, "size must not change");
-  }
+  // The "appendix" is an optional call-site-specific parameter which is
+  // pushed by the JVM at the end of the argument list.  This argument may
+  // be a MethodType for the MH.invokes and a CallSite for an invokedynamic
+  // instruction.  However, its exact type and use depends on the Java upcall,
+  // which simply returns a compiled LambdaForm along with any reference
+  // that LambdaForm needs to complete the call.  If the upcall returns a
+  // null appendix, the argument is not passed at all.
+  //
+  // The appendix is *not* represented in the signature of the symbolic
+  // reference for the call site, but (if present) it *is* represented in
+  // the methodOop bound to the site.  This means that static and dynamic
+  // resolution logic needs to make slightly different assessments about the
+  // number and types of arguments.
+  void set_method_handle_common(
+    constantPoolHandle cpool,                    // holding constant pool (required for locking)
+    Bytecodes::Code invoke_code,                 // _invokehandle or _invokedynamic
+    methodHandle adapter,                        // invoker method (f2)
+    Handle appendix,                             // appendix such as CallSite, MethodType, etc. (f1)
+    Handle method_type                           // MethodType (f1 of secondary entry)
+  );
+
+  methodOop      method_if_resolved(constantPoolHandle cpool);
+  oop          appendix_if_resolved(constantPoolHandle cpool);
+  oop       method_type_if_resolved(constantPoolHandle cpool);
+
+  void set_parameter_size(int value);
 
   // Which bytecode number (1 or 2) in the index field is valid for this bytecode?
   // Returns -1 if neither is valid.
@@ -222,6 +273,7 @@
       case Bytecodes::_getfield        :    // fall through
       case Bytecodes::_invokespecial   :    // fall through
       case Bytecodes::_invokestatic    :    // fall through
+      case Bytecodes::_invokehandle    :    // fall through
       case Bytecodes::_invokedynamic   :    // fall through
       case Bytecodes::_invokeinterface : return 1;
       case Bytecodes::_putstatic       :    // fall through
@@ -242,31 +294,44 @@
   }
 
   // Accessors
-  bool is_secondary_entry() const                { return (_indices & 0xFFFF) == 0; }
-  int constant_pool_index() const                { assert((_indices & 0xFFFF) != 0, "must be main entry");
-                                                   return (_indices & 0xFFFF); }
-  int main_entry_index() const                   { assert((_indices & 0xFFFF) == 0, "must be secondary entry");
-                                                   return ((uintx)_indices >> 16); }
-  Bytecodes::Code bytecode_1() const             { return Bytecodes::cast((_indices >> 16) & 0xFF); }
-  Bytecodes::Code bytecode_2() const             { return Bytecodes::cast((_indices >> 24) & 0xFF); }
-  volatile oop  f1() const                       { return _f1; }
-  bool is_f1_null() const                        { return (oop)_f1 == NULL; }  // classifies a CPC entry as unbound
-  intx f2() const                                { return _f2; }
-  int  field_index() const;
-  int  parameter_size() const                    { return _flags & 0xFF; }
-  bool is_vfinal() const                         { return ((_flags & (1 << vfinalMethod)) == (1 << vfinalMethod)); }
-  bool is_volatile() const                       { return ((_flags & (1 << volatileField)) == (1 << volatileField)); }
-  bool is_methodInterface() const                { return ((_flags & (1 << methodInterface)) == (1 << methodInterface)); }
-  bool is_byte() const                           { return (((uintx) _flags >> tosBits) == btos); }
-  bool is_char() const                           { return (((uintx) _flags >> tosBits) == ctos); }
-  bool is_short() const                          { return (((uintx) _flags >> tosBits) == stos); }
-  bool is_int() const                            { return (((uintx) _flags >> tosBits) == itos); }
-  bool is_long() const                           { return (((uintx) _flags >> tosBits) == ltos); }
-  bool is_float() const                          { return (((uintx) _flags >> tosBits) == ftos); }
-  bool is_double() const                         { return (((uintx) _flags >> tosBits) == dtos); }
-  bool is_object() const                         { return (((uintx) _flags >> tosBits) == atos); }
-  TosState flag_state() const                    { assert( ( (_flags >> tosBits) & 0x0F ) < number_of_states, "Invalid state in as_flags");
-                                                   return (TosState)((_flags >> tosBits) & 0x0F); }
+  bool is_secondary_entry() const                { return (_indices & main_cp_index_mask) == 0; }
+  int main_entry_index() const                   { assert(is_secondary_entry(), "must be secondary entry");
+                                                   return ((uintx)_indices >> secondary_cp_index_shift); }
+  int primary_entry_indices() const              { assert(!is_secondary_entry(), "must be main entry");
+                                                   return _indices; }
+  int constant_pool_index() const                { return (primary_entry_indices() & main_cp_index_mask); }
+  Bytecodes::Code bytecode_1() const             { return Bytecodes::cast((primary_entry_indices() >> bytecode_1_shift)
+                                                                          & bytecode_1_mask); }
+  Bytecodes::Code bytecode_2() const             { return Bytecodes::cast((primary_entry_indices() >> bytecode_2_shift)
+                                                                          & bytecode_2_mask); }
+  methodOop f1_as_method() const                 { oop f1 = _f1; assert(f1 == NULL || f1->is_method(), ""); return methodOop(f1); }
+  klassOop  f1_as_klass() const                  { oop f1 = _f1; assert(f1 == NULL || f1->is_klass(), ""); return klassOop(f1); }
+  oop       f1_as_klass_mirror() const           { oop f1 = f1_as_instance(); return f1; }  // i.e., return a java_mirror
+  oop       f1_as_instance() const               { oop f1 = _f1; assert(f1 == NULL || f1->is_instance() || f1->is_array(), ""); return f1; }
+  oop       f1_appendix() const                  { assert(has_appendix(), ""); return f1_as_instance(); }
+  bool      is_f1_null() const                   { oop f1 = _f1; return f1 == NULL; }  // classifies a CPC entry as unbound
+  int       f2_as_index() const                  { assert(!is_vfinal(), ""); return (int) _f2; }
+  methodOop f2_as_vfinal_method() const          { assert(is_vfinal(), ""); return methodOop(_f2); }
+  int  field_index() const                       { assert(is_field_entry(),  ""); return (_flags & field_index_mask); }
+  int  parameter_size() const                    { assert(is_method_entry(), ""); return (_flags & parameter_size_mask); }
+  bool is_volatile() const                       { return (_flags & (1 << is_volatile_shift))       != 0; }
+  bool is_final() const                          { return (_flags & (1 << is_final_shift))          != 0; }
+  bool has_appendix() const                      { return (_flags & (1 << has_appendix_shift))      != 0; }
+  bool has_method_type() const                   { return (_flags & (1 << has_method_type_shift))   != 0; }
+  bool is_forced_virtual() const                 { return (_flags & (1 << is_forced_virtual_shift)) != 0; }
+  bool is_vfinal() const                         { return (_flags & (1 << is_vfinal_shift))         != 0; }
+  bool is_method_entry() const                   { return (_flags & (1 << is_field_entry_shift))    == 0; }
+  bool is_field_entry() const                    { return (_flags & (1 << is_field_entry_shift))    != 0; }
+  bool is_byte() const                           { return flag_state() == btos; }
+  bool is_char() const                           { return flag_state() == ctos; }
+  bool is_short() const                          { return flag_state() == stos; }
+  bool is_int() const                            { return flag_state() == itos; }
+  bool is_long() const                           { return flag_state() == ltos; }
+  bool is_float() const                          { return flag_state() == ftos; }
+  bool is_double() const                         { return flag_state() == dtos; }
+  bool is_object() const                         { return flag_state() == atos; }
+  TosState flag_state() const                    { assert((uint)number_of_states <= (uint)tos_state_mask+1, "");
+                                                   return (TosState)((_flags >> tos_state_shift) & tos_state_mask); }
 
   // Code generation support
   static WordSize size()                         { return in_WordSize(sizeof(ConstantPoolCacheEntry) / HeapWordSize); }
@@ -299,15 +364,14 @@
   bool adjust_method_entry(methodOop old_method, methodOop new_method,
          bool * trace_name_printed);
   bool is_interesting_method_entry(klassOop k);
-  bool is_field_entry() const                    { return (_flags & (1 << hotSwapBit)) == 0; }
-  bool is_method_entry() const                   { return (_flags & (1 << hotSwapBit)) != 0; }
 
   // Debugging & Printing
   void print (outputStream* st, int index) const;
   void verify(outputStream* st) const;
 
-  static void verify_tosBits() {
-    assert(tosBits == 28, "interpreter now assumes tosBits is 28");
+  static void verify_tos_state_shift() {
+    // When shifting flags as a 32-bit int, make sure we don't need an extra mask for tos_state:
+    assert((((u4)-1 >> tos_state_shift) & ~tos_state_mask) == 0, "no need for tos_state mask");
   }
 };
 
@@ -388,6 +452,29 @@
     return entry_at(primary_index);
   }
 
+  int index_of(ConstantPoolCacheEntry* e) {
+    assert(base() <= e && e < base() + length(), "oob");
+    int cpc_index = (e - base());
+    assert(entry_at(cpc_index) == e, "sanity");
+    return cpc_index;
+  }
+  ConstantPoolCacheEntry* find_secondary_entry_for(ConstantPoolCacheEntry* e) {
+    const int cpc_index = index_of(e);
+    if (e->is_secondary_entry()) {
+      ConstantPoolCacheEntry* e2 = entry_at(cpc_index + 1);
+      assert(e->main_entry_index() == e2->main_entry_index(), "");
+      return e2;
+    } else {
+      for (int i = length() - 1; i >= 0; i--) {
+        ConstantPoolCacheEntry* e2 = entry_at(i);
+        if (cpc_index == e2->main_entry_index())
+          return e2;
+      }
+    }
+    fatal("no secondary entry found");
+    return NULL;
+  }
+
   // Code generation
   static ByteSize base_offset()                  { return in_ByteSize(sizeof(constantPoolCacheOopDesc)); }
   static ByteSize entry_offset(int raw_index) {
diff --git a/hotspot/src/share/vm/oops/fieldInfo.hpp b/hotspot/src/share/vm/oops/fieldInfo.hpp
index 69de3ae..f4cf1a4 100644
--- a/hotspot/src/share/vm/oops/fieldInfo.hpp
+++ b/hotspot/src/share/vm/oops/fieldInfo.hpp
@@ -50,8 +50,7 @@
     initval_index_offset     = 3,
     low_offset               = 4,
     high_offset              = 5,
-    generic_signature_offset = 6,
-    field_slots              = 7
+    field_slots              = 6
   };
 
  private:
@@ -60,29 +59,28 @@
   void set_name_index(u2 val)                    { _shorts[name_index_offset] = val;         }
   void set_signature_index(u2 val)               { _shorts[signature_index_offset] = val;    }
   void set_initval_index(u2 val)                 { _shorts[initval_index_offset] = val;      }
-  void set_generic_signature_index(u2 val)       { _shorts[generic_signature_offset] = val;  }
 
   u2 name_index() const                          { return _shorts[name_index_offset];        }
   u2 signature_index() const                     { return _shorts[signature_index_offset];   }
   u2 initval_index() const                       { return _shorts[initval_index_offset];     }
-  u2 generic_signature_index() const             { return _shorts[generic_signature_offset]; }
 
  public:
   static FieldInfo* from_field_array(typeArrayOop fields, int index) {
     return ((FieldInfo*)fields->short_at_addr(index * field_slots));
   }
+  static FieldInfo* from_field_array(u2* fields, int index) {
+    return ((FieldInfo*)(fields + index * field_slots));
+  }
 
   void initialize(u2 access_flags,
                   u2 name_index,
                   u2 signature_index,
                   u2 initval_index,
-                  u2 generic_signature_index,
                   u4 offset) {
     _shorts[access_flags_offset] = access_flags;
     _shorts[name_index_offset] = name_index;
     _shorts[signature_index_offset] = signature_index;
     _shorts[initval_index_offset] = initval_index;
-    _shorts[generic_signature_offset] = generic_signature_index;
     set_offset(offset);
   }
 
@@ -105,14 +103,6 @@
     return cp->symbol_at(index);
   }
 
-  Symbol* generic_signature(constantPoolHandle cp) const {
-    int index = generic_signature_index();
-    if (index == 0) {
-      return NULL;
-    }
-    return cp->symbol_at(index);
-  }
-
   void set_access_flags(u2 val)                  { _shorts[access_flags_offset] = val;             }
   void set_offset(u4 val)                        {
     _shorts[low_offset] = extract_low_short_from_int(val);
diff --git a/hotspot/src/share/vm/oops/fieldStreams.hpp b/hotspot/src/share/vm/oops/fieldStreams.hpp
index 07c28f3..08127bfb 100644
--- a/hotspot/src/share/vm/oops/fieldStreams.hpp
+++ b/hotspot/src/share/vm/oops/fieldStreams.hpp
@@ -42,21 +42,57 @@
   constantPoolHandle  _constants;
   int                 _index;
   int                 _limit;
+  int                 _generic_signature_slot;
 
   FieldInfo* field() const { return FieldInfo::from_field_array(_fields(), _index); }
 
+  int init_generic_signature_start_slot() {
+    int length = _fields->length();
+    int num_fields = 0;
+    int skipped_generic_signature_slots = 0;
+    FieldInfo* fi;
+    AccessFlags flags;
+    /* Scan from 0 to the current _index. Count the number of generic
+       signature slots for field[0] to field[_index - 1]. */
+    for (int i = 0; i < _index; i++) {
+      fi = FieldInfo::from_field_array(_fields(), i);
+      flags.set_flags(fi->access_flags());
+      if (flags.field_has_generic_signature()) {
+        length --;
+        skipped_generic_signature_slots ++;
+      }
+    }
+    /* Scan from the current _index. */
+    for (int i = _index; i*FieldInfo::field_slots < length; i++) {
+      fi = FieldInfo::from_field_array(_fields(), i);
+      flags.set_flags(fi->access_flags());
+      if (flags.field_has_generic_signature()) {
+        length --;
+      }
+      num_fields ++;
+    }
+    _generic_signature_slot = length + skipped_generic_signature_slots;
+    assert(_generic_signature_slot <= _fields->length(), "");
+    return num_fields;
+  }
+
   FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants, int start, int limit) {
     _fields = fields;
     _constants = constants;
     _index = start;
-    _limit = limit;
+    int num_fields = init_generic_signature_start_slot();
+    if (limit < start) {
+      _limit = num_fields;
+    } else {
+      _limit = limit;
+    }
   }
 
   FieldStreamBase(typeArrayHandle fields, constantPoolHandle constants) {
     _fields = fields;
     _constants = constants;
     _index = 0;
-    _limit = fields->length() / FieldInfo::field_slots;
+    _limit = init_generic_signature_start_slot();
   }
 
  public:
@@ -65,18 +101,26 @@
     _constants = klass->constants();
     _index = 0;
     _limit = klass->java_fields_count();
+    init_generic_signature_start_slot();
   }
   FieldStreamBase(instanceKlassHandle klass) {
     _fields = klass->fields();
     _constants = klass->constants();
     _index = 0;
     _limit = klass->java_fields_count();
+    init_generic_signature_start_slot();
   }
 
   // accessors
   int index() const                 { return _index; }
 
-  void next() { _index += 1; }
+  void next() {
+    if (access_flags().field_has_generic_signature()) {
+      _generic_signature_slot ++;
+      assert(_generic_signature_slot <= _fields->length(), "");
+    }
+    _index += 1;
+  }
   bool done() const { return _index >= _limit; }
 
   // Accessors for current field
@@ -103,7 +147,13 @@
   }
 
   Symbol* generic_signature() const {
-    return field()->generic_signature(_constants);
+    if (access_flags().field_has_generic_signature()) {
+      assert(_generic_signature_slot < _fields->length(), "out of bounds");
+      int index = _fields->short_at(_generic_signature_slot);
+      return _constants->symbol_at(index);
+    } else {
+      return NULL;
+    }
   }
 
   int offset() const {
@@ -139,11 +189,19 @@
   }
   int generic_signature_index() const {
     assert(!field()->is_internal(), "regular only");
-    return field()->generic_signature_index();
+    if (access_flags().field_has_generic_signature()) {
+      assert(_generic_signature_slot < _fields->length(), "out of bounds");
+      return _fields->short_at(_generic_signature_slot);
+    } else {
+      return 0;
+    }
   }
   void set_generic_signature_index(int index) {
     assert(!field()->is_internal(), "regular only");
-    field()->set_generic_signature_index(index);
+    if (access_flags().field_has_generic_signature()) {
+      assert(_generic_signature_slot < _fields->length(), "out of bounds");
+      _fields->short_at_put(_generic_signature_slot, index);
+    }
   }
   int initval_index() const {
     assert(!field()->is_internal(), "regular only");
@@ -159,8 +217,8 @@
 // Iterate over only the internal fields
 class InternalFieldStream : public FieldStreamBase {
  public:
-  InternalFieldStream(instanceKlass* k):      FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), k->all_fields_count()) {}
-  InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), k->all_fields_count()) {}
+  InternalFieldStream(instanceKlass* k):      FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
+  InternalFieldStream(instanceKlassHandle k): FieldStreamBase(k->fields(), k->constants(), k->java_fields_count(), 0) {}
 };
 
 
diff --git a/hotspot/src/share/vm/oops/generateOopMap.cpp b/hotspot/src/share/vm/oops/generateOopMap.cpp
index 58ef931..b1a0db7 100644
--- a/hotspot/src/share/vm/oops/generateOopMap.cpp
+++ b/hotspot/src/share/vm/oops/generateOopMap.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,6 +31,7 @@
 #include "runtime/java.hpp"
 #include "runtime/relocator.hpp"
 #include "utilities/bitMap.inline.hpp"
+#include "prims/methodHandles.hpp"
 
 //
 //
@@ -400,10 +401,9 @@
   bool fellThrough = false;  // False to get first BB marked.
 
   // First mark all exception handlers as start of a basic-block
-  typeArrayOop excps = method()->exception_table();
-  for(int i = 0; i < excps->length(); i += 4) {
-    int handler_pc_idx = i+2;
-    bb_mark_fct(this, excps->int_at(handler_pc_idx), NULL);
+  ExceptionTable excps(method());
+  for(int i = 0; i < excps.length(); i ++) {
+    bb_mark_fct(this, excps.handler_pc(i), NULL);
   }
 
   // Then iterate through the code
@@ -450,10 +450,9 @@
 
   // Mark entry basic block as alive and all exception handlers
   _basic_blocks[0].mark_as_alive();
-  typeArrayOop excps = method()->exception_table();
-  for(int i = 0; i < excps->length(); i += 4) {
-    int handler_pc_idx = i+2;
-    BasicBlock *bb = get_basic_block_at(excps->int_at(handler_pc_idx));
+  ExceptionTable excps(method());
+  for(int i = 0; i < excps.length(); i++) {
+    BasicBlock *bb = get_basic_block_at(excps.handler_pc(i));
     // If block is not already alive (due to multiple exception handlers to same bb), then
     // make it alive
     if (bb->is_dead()) bb->mark_as_alive();
@@ -1181,12 +1180,12 @@
 
   if (_has_exceptions) {
     int bci = itr->bci();
-    typeArrayOop exct  = method()->exception_table();
-    for(int i = 0; i< exct->length(); i+=4) {
-      int start_pc   = exct->int_at(i);
-      int end_pc     = exct->int_at(i+1);
-      int handler_pc = exct->int_at(i+2);
-      int catch_type = exct->int_at(i+3);
+    ExceptionTable exct(method());
+    for(int i = 0; i< exct.length(); i++) {
+      int start_pc   = exct.start_pc(i);
+      int end_pc     = exct.end_pc(i);
+      int handler_pc = exct.handler_pc(i);
+      int catch_type = exct.catch_type_index(i);
 
       if (start_pc <= bci && bci < end_pc) {
         BasicBlock *excBB = get_basic_block_at(handler_pc);
@@ -2055,7 +2054,7 @@
   _conflict       = false;
   _max_locals     = method()->max_locals();
   _max_stack      = method()->max_stack();
-  _has_exceptions = (method()->exception_table()->length() > 0);
+  _has_exceptions = (method()->has_exception_handler());
   _nof_refval_conflicts = 0;
   _init_vars      = new GrowableArray<intptr_t>(5);  // There are seldom more than 5 init_vars
   _report_result  = false;
@@ -2070,9 +2069,10 @@
     if (Verbose) {
       _method->print_codes();
       tty->print_cr("Exception table:");
-      typeArrayOop excps = method()->exception_table();
-      for(int i = 0; i < excps->length(); i += 4) {
-        tty->print_cr("[%d - %d] -> %d", excps->int_at(i + 0), excps->int_at(i + 1), excps->int_at(i + 2));
+      ExceptionTable excps(method());
+      for(int i = 0; i < excps.length(); i ++) {
+        tty->print_cr("[%d - %d] -> %d",
+                      excps.start_pc(i), excps.end_pc(i), excps.handler_pc(i));
       }
     }
   }
diff --git a/hotspot/src/share/vm/oops/instanceKlass.cpp b/hotspot/src/share/vm/oops/instanceKlass.cpp
index eec2e23..4cc077f 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.cpp
@@ -567,8 +567,18 @@
   ol.notify_all(CHECK);
 }
 
+// The embedded _implementor field can only record one implementor.
+// When there are more than one implementors, the _implementor field
+// is set to the interface klassOop itself. Following are the possible
+// values for the _implementor field:
+//   NULL                  - no implementor
+//   implementor klassOop  - one implementor
+//   self                  - more than one implementor
+//
+// The _implementor field only exists for interfaces.
 void instanceKlass::add_implementor(klassOop k) {
   assert(Compile_lock->owned_by_self(), "");
+  assert(is_interface(), "not interface");
   // Filter out my subinterfaces.
   // (Note: Interfaces are never on the subklass list.)
   if (instanceKlass::cast(k)->is_interface()) return;
@@ -583,17 +593,13 @@
     // Any supers of the super have the same (or fewer) transitive_interfaces.
     return;
 
-  // Update number of implementors
-  int i = _nof_implementors++;
-
-  // Record this implementor, if there are not too many already
-  if (i < implementors_limit) {
-    assert(_implementors[i] == NULL, "should be exactly one implementor");
-    oop_store_without_check((oop*)&_implementors[i], k);
-  } else if (i == implementors_limit) {
-    // clear out the list on first overflow
-    for (int i2 = 0; i2 < implementors_limit; i2++)
-      oop_store_without_check((oop*)&_implementors[i2], NULL);
+  klassOop ik = implementor();
+  if (ik == NULL) {
+    set_implementor(k);
+  } else if (ik != this->as_klassOop()) {
+    // There is already an implementor. Use itself as an indicator of
+    // more than one implementors.
+    set_implementor(this->as_klassOop());
   }
 
   // The implementor also implements the transitive_interfaces
@@ -603,9 +609,9 @@
 }
 
 void instanceKlass::init_implementor() {
-  for (int i = 0; i < implementors_limit; i++)
-    oop_store_without_check((oop*)&_implementors[i], NULL);
-  _nof_implementors = 0;
+  if (is_interface()) {
+    set_implementor(NULL);
+  }
 }
 
 
@@ -841,7 +847,6 @@
   Klass::shared_symbols_iterate(closure);
   closure->do_symbol(&_generic_signature);
   closure->do_symbol(&_source_file_name);
-  closure->do_symbol(&_source_debug_extension);
 
   for (JavaFieldStream fs(this); !fs.done(); fs.next()) {
     int name_index = fs.name_index();
@@ -983,7 +988,7 @@
   fieldDescriptor fd;
   int length = java_fields_count();
   // In DebugInfo nonstatic fields are sorted by offset.
-  int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1));
+  int* fields_sorted = NEW_C_HEAP_ARRAY(int, 2*(length+1), mtClass);
   int j = 0;
   for (int i = 0; i < length; i += 1) {
     fd.initialize(as_klassOop(), i);
@@ -1003,7 +1008,7 @@
       cl->do_field(&fd);
     }
   }
-  FREE_C_HEAP_ARRAY(int, fields_sorted);
+  FREE_C_HEAP_ARRAY(int, fields_sorted, mtClass);
 }
 
 
@@ -1133,6 +1138,36 @@
   return probe;
 }
 
+u2 instanceKlass::enclosing_method_data(int offset) {
+  typeArrayOop inner_class_list = inner_classes();
+  if (inner_class_list == NULL) {
+    return 0;
+  }
+  int length = inner_class_list->length();
+  if (length % inner_class_next_offset == 0) {
+    return 0;
+  } else {
+    int index = length - enclosing_method_attribute_size;
+    typeArrayHandle inner_class_list_h(inner_class_list);
+    assert(offset < enclosing_method_attribute_size, "invalid offset");
+    return inner_class_list_h->ushort_at(index + offset);
+  }
+}
+
+void instanceKlass::set_enclosing_method_indices(u2 class_index,
+                                                 u2 method_index) {
+  typeArrayOop inner_class_list = inner_classes();
+  assert (inner_class_list != NULL, "_inner_classes list is not set up");
+  int length = inner_class_list->length();
+  if (length % inner_class_next_offset == enclosing_method_attribute_size) {
+    int index = length - enclosing_method_attribute_size;
+    typeArrayHandle inner_class_list_h(inner_class_list);
+    inner_class_list_h->ushort_at_put(
+      index + enclosing_method_class_index_offset, class_index);
+    inner_class_list_h->ushort_at_put(
+      index + enclosing_method_method_index_offset, method_index);
+  }
+}
 
 // Lookup or create a jmethodID.
 // This code is called by the VMThread and JavaThreads so the
@@ -1200,7 +1235,7 @@
     if (length <= idnum) {
       // allocate a new cache that might be used
       size_t size = MAX2(idnum+1, (size_t)ik_h->idnum_allocated_count());
-      new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1);
+      new_jmeths = NEW_C_HEAP_ARRAY(jmethodID, size+1, mtClass);
       memset(new_jmeths, 0, (size+1)*sizeof(jmethodID));
       // cache size is stored in element[0], other elements offset by one
       new_jmeths[0] = (jmethodID)size;
@@ -1361,7 +1396,7 @@
     // cache size is stored in element[0], other elements offset by one
     if (indices == NULL || (length = (size_t)indices[0]) <= idnum) {
       size_t size = MAX2(idnum+1, (size_t)idnum_allocated_count());
-      int* new_indices = NEW_C_HEAP_ARRAY(int, size+1);
+      int* new_indices = NEW_C_HEAP_ARRAY(int, size+1, mtClass);
       new_indices[0] = (int)size;
       // copy any existing entries
       size_t i;
@@ -1819,24 +1854,22 @@
 void instanceKlass::follow_weak_klass_links(
   BoolObjectClosure* is_alive, OopClosure* keep_alive) {
   assert(is_alive->do_object_b(as_klassOop()), "this oop should be live");
-  if (ClassUnloading) {
-    for (int i = 0; i < implementors_limit; i++) {
-      klassOop impl = _implementors[i];
-      if (impl == NULL)  break;  // no more in the list
-      if (!is_alive->do_object_b(impl)) {
-        // remove this guy from the list by overwriting him with the tail
-        int lasti = --_nof_implementors;
-        assert(lasti >= i && lasti < implementors_limit, "just checking");
-        _implementors[i] = _implementors[lasti];
-        _implementors[lasti] = NULL;
-        --i; // rerun the loop at this index
+
+  if (is_interface()) {
+    if (ClassUnloading) {
+      klassOop impl = implementor();
+      if (impl != NULL) {
+        if (!is_alive->do_object_b(impl)) {
+          // remove this guy
+          *adr_implementor() = NULL;
+        }
       }
-    }
-  } else {
-    for (int i = 0; i < implementors_limit; i++) {
-      keep_alive->do_oop(&adr_implementors()[i]);
+    } else {
+      assert(adr_implementor() != NULL, "just checking");
+      keep_alive->do_oop(adr_implementor());
     }
   }
+
   Klass::follow_weak_klass_links(is_alive, keep_alive);
 }
 
@@ -1899,7 +1932,7 @@
 
   // deallocate the cached class file
   if (_cached_class_file_bytes != NULL) {
-    os::free(_cached_class_file_bytes);
+    os::free(_cached_class_file_bytes, mtClass);
     _cached_class_file_bytes = NULL;
     _cached_class_file_len = 0;
   }
@@ -1910,9 +1943,10 @@
   // class can't be referenced anymore).
   if (_array_name != NULL)  _array_name->decrement_refcount();
   if (_source_file_name != NULL) _source_file_name->decrement_refcount();
-  if (_source_debug_extension != NULL) _source_debug_extension->decrement_refcount();
   // walk constant pool and decrement symbol reference counts
   _constants->unreference_symbols();
+
+  if (_source_debug_extension != NULL) FREE_C_HEAP_ARRAY(char, _source_debug_extension, mtClass);
 }
 
 void instanceKlass::set_source_file_name(Symbol* n) {
@@ -1920,9 +1954,22 @@
   if (_source_file_name != NULL) _source_file_name->increment_refcount();
 }
 
-void instanceKlass::set_source_debug_extension(Symbol* n) {
-  _source_debug_extension = n;
-  if (_source_debug_extension != NULL) _source_debug_extension->increment_refcount();
+void instanceKlass::set_source_debug_extension(char* array, int length) {
+  if (array == NULL) {
+    _source_debug_extension = NULL;
+  } else {
+    // Adding one to the attribute length in order to store a null terminator
+    // character could cause an overflow because the attribute length is
+    // already coded with an u4 in the classfile, but in practice, it's
+    // unlikely to happen.
+    assert((length+1) > length, "Overflow checking");
+    char* sde = NEW_C_HEAP_ARRAY(char, (length + 1), mtClass);
+    for (int i = 0; i < length; i++) {
+      sde[i] = array[i];
+    }
+    sde[length] = '\0';
+    _source_debug_extension = sde;
+  }
 }
 
 address instanceKlass::static_field_addr(int offset) {
@@ -2107,28 +2154,21 @@
   jint access = access_flags().as_int();
 
   // But check if it happens to be member class.
-  typeArrayOop inner_class_list = inner_classes();
-  int length = (inner_class_list == NULL) ? 0 : inner_class_list->length();
-  assert (length % instanceKlass::inner_class_next_offset == 0, "just checking");
-  if (length > 0) {
-    typeArrayHandle inner_class_list_h(THREAD, inner_class_list);
-    instanceKlassHandle ik(THREAD, k);
-    for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) {
-      int ioff = inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_inner_class_info_offset);
+  instanceKlassHandle ik(THREAD, k);
+  InnerClassesIterator iter(ik);
+  for (; !iter.done(); iter.next()) {
+    int ioff = iter.inner_class_info_index();
+    // Inner class attribute can be zero, skip it.
+    // Strange but true:  JVM spec. allows null inner class refs.
+    if (ioff == 0) continue;
 
-      // Inner class attribute can be zero, skip it.
-      // Strange but true:  JVM spec. allows null inner class refs.
-      if (ioff == 0) continue;
-
-      // only look at classes that are already loaded
-      // since we are looking for the flags for our self.
-      Symbol* inner_name = ik->constants()->klass_name_at(ioff);
-      if ((ik->name() == inner_name)) {
-        // This is really a member class.
-        access = inner_class_list_h->ushort_at(i + instanceKlass::inner_class_access_flags_offset);
-        break;
-      }
+    // only look at classes that are already loaded
+    // since we are looking for the flags for our self.
+    Symbol* inner_name = ik->constants()->klass_name_at(ioff);
+    if ((ik->name() == inner_name)) {
+      // This is really a member class.
+      access = iter.inner_access_flags();
+      break;
     }
   }
   // Remember to strip ACC_SUPER bit
@@ -2389,6 +2429,22 @@
   } else if (java_lang_boxing_object::is_instance(obj)) {
     st->print(" = ");
     java_lang_boxing_object::print(obj, st);
+  } else if (as_klassOop() == SystemDictionary::LambdaForm_klass()) {
+    oop vmentry = java_lang_invoke_LambdaForm::vmentry(obj);
+    if (vmentry != NULL) {
+      st->print(" => ");
+      vmentry->print_value_on(st);
+    }
+  } else if (as_klassOop() == SystemDictionary::MemberName_klass()) {
+    oop vmtarget = java_lang_invoke_MemberName::vmtarget(obj);
+    if (vmtarget != NULL) {
+      st->print(" = ");
+      vmtarget->print_value_on(st);
+    } else {
+      java_lang_invoke_MemberName::clazz(obj)->print_value_on(st);
+      st->print(".");
+      java_lang_invoke_MemberName::name(obj)->print_value_on(st);
+    }
   }
 }
 
@@ -2503,7 +2559,7 @@
     // This is the first previous version so make some space.
     // Start with 2 elements under the assumption that the class
     // won't be redefined much.
-    _previous_versions =  new (ResourceObj::C_HEAP)
+    _previous_versions =  new (ResourceObj::C_HEAP, mtClass)
                             GrowableArray<PreviousVersionNode *>(2, true);
   }
 
@@ -2529,7 +2585,7 @@
       ("add: all methods are obsolete; flushing any EMCP weak refs"));
   } else {
     int local_count = 0;
-    GrowableArray<jweak>* method_refs = new (ResourceObj::C_HEAP)
+    GrowableArray<jweak>* method_refs = new (ResourceObj::C_HEAP, mtClass)
       GrowableArray<jweak>(emcp_method_count, true);
     for (int i = 0; i < old_methods->length(); i++) {
       if (emcp_methods->at(i)) {
@@ -2921,7 +2977,7 @@
 
   while (_current_index < length) {
     PreviousVersionNode * pv_node = _previous_versions->at(_current_index++);
-    PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP)
+    PreviousVersionInfo * pv_info = new (ResourceObj::C_HEAP, mtClass)
                                           PreviousVersionInfo(pv_node);
 
     constantPoolHandle cp_h = pv_info->prev_constant_pool_handle();
diff --git a/hotspot/src/share/vm/oops/instanceKlass.hpp b/hotspot/src/share/vm/oops/instanceKlass.hpp
index e981cde..3c24b3f 100644
--- a/hotspot/src/share/vm/oops/instanceKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlass.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -56,8 +56,6 @@
 //    [methods                    ]
 //    [local interfaces           ]
 //    [transitive interfaces      ]
-//    [number of implementors     ]
-//    [implementors               ] klassOop[2]
 //    [fields                     ]
 //    [constants                  ]
 //    [class loader               ]
@@ -77,9 +75,10 @@
 //    [oop map cache (stack maps) ]
 //    [EMBEDDED Java vtable             ] size in words = vtable_len
 //    [EMBEDDED nonstatic oop-map blocks] size in words = nonstatic_oop_map_size
-//
-//    The embedded nonstatic oop-map blocks are short pairs (offset, length) indicating
-//    where oops are located in instances of this klass.
+//      The embedded nonstatic oop-map blocks are short pairs (offset, length)
+//      indicating where oops are located in instances of this klass.
+//    [EMBEDDED implementor of the interface] only exist for interface
+//    [EMBEDDED host klass        ] only exist for an anonymous class (JSR 292 enabled)
 
 
 // forward declaration for class -- see below for definition
@@ -153,10 +152,6 @@
   oop* oop_block_beg() const { return adr_array_klasses(); }
   oop* oop_block_end() const { return adr_methods_default_annotations() + 1; }
 
-  enum {
-    implementors_limit = 2              // how many implems can we track?
-  };
-
  protected:
   //
   // The oop block.  See comment in klass.hpp before making changes.
@@ -173,8 +168,19 @@
   objArrayOop     _local_interfaces;
   // Interface (klassOops) this class implements transitively.
   objArrayOop     _transitive_interfaces;
-  // Instance and static variable information, 5-tuples of shorts [access, name
-  // index, sig index, initval index, offset].
+  // Instance and static variable information, starts with 6-tuples of shorts
+  // [access, name index, sig index, initval index, low_offset, high_offset]
+  // for all fields, followed by the generic signature data at the end of
+  // the array. Only fields with generic signature attributes have the generic
+  // signature data set in the array. The fields array looks like following:
+  //
+  // f1: [access, name index, sig index, initial value index, low_offset, high_offset]
+  // f2: [access, name index, sig index, initial value index, low_offset, high_offset]
+  //      ...
+  // fn: [access, name index, sig index, initial value index, low_offset, high_offset]
+  //     [generic signature index]
+  //     [generic signature index]
+  //     ...
   typeArrayOop    _fields;
   // Constant pool for this class.
   constantPoolOop _constants;
@@ -182,16 +188,20 @@
   oop             _class_loader;
   // Protection domain.
   oop             _protection_domain;
-  // Host class, which grants its access privileges to this class also.
-  // This is only non-null for an anonymous class (JSR 292 enabled).
-  // The host class is either named, or a previously loaded anonymous class.
-  klassOop        _host_klass;
   // Class signers.
   objArrayOop     _signers;
-  // inner_classes attribute.
+  // The InnerClasses attribute and EnclosingMethod attribute. The
+  // _inner_classes is an array of shorts. If the class has InnerClasses
+  // attribute, then the _inner_classes array begins with 4-tuples of shorts
+  // [inner_class_info_index, outer_class_info_index,
+  // inner_name_index, inner_class_access_flags] for the InnerClasses
+  // attribute. If the EnclosingMethod attribute exists, it occupies the
+  // last two shorts [class_index, method_index] of the array. If only
+  // the InnerClasses attribute exists, the _inner_classes array length is
+  // number_of_inner_classes * 4. If the class has both InnerClasses
+  // and EnclosingMethod attributes the _inner_classes array length is
+  // number_of_inner_classes * 4 + enclosing_method_attribute_size.
   typeArrayOop    _inner_classes;
-  // Implementors of this interface (not valid if it overflows)
-  klassOop        _implementors[implementors_limit];
   // Annotations for this class, or null if none.
   typeArrayOop    _class_annotations;
   // Annotation objects (byte arrays) for fields, or null if no annotations.
@@ -216,7 +226,9 @@
   // Name of source file containing this klass, NULL if not specified.
   Symbol*         _source_file_name;
   // the source debug extension for this klass, NULL if not specified.
-  Symbol*         _source_debug_extension;
+  // Specified as UTF-8 string without terminating zero byte in the classfile,
+  // it is stored in the instanceklass as a NULL-terminated UTF-8 string
+  char*           _source_debug_extension;
   // Generic signature, or null if none.
   Symbol*         _generic_signature;
   // Array name derived from this class which needs unreferencing
@@ -232,9 +244,13 @@
   int             _nonstatic_oop_map_size;// size in words of nonstatic oop map blocks
 
   bool            _is_marked_dependent;  // used for marking during flushing and deoptimization
-  bool            _rewritten;            // methods rewritten.
-  bool            _has_nonstatic_fields; // for sizing with UseCompressedOops
-  bool            _should_verify_class;  // allow caching of preverification
+  enum {
+    _misc_rewritten            = 1 << 0, // methods rewritten.
+    _misc_has_nonstatic_fields = 1 << 1, // for sizing with UseCompressedOops
+    _misc_should_verify_class  = 1 << 2, // allow caching of preverification
+    _misc_is_anonymous         = 1 << 3  // has embedded _inner_classes field
+  };
+  u2              _misc_flags;
   u2              _minor_version;        // minor version number of class file
   u2              _major_version;        // major version number of class file
   Thread*         _init_thread;          // Pointer to current thread doing initialization (to handle recusive initialization)
@@ -247,12 +263,9 @@
   nmethodBucket*  _dependencies;         // list of dependent nmethods
   nmethod*        _osr_nmethods_head;    // Head of list of on-stack replacement nmethods for this class
   BreakpointInfo* _breakpoints;          // bpt lists, managed by methodOop
-  int             _nof_implementors;     // No of implementors of this interface (zero if not an interface)
   // Array of interesting part(s) of the previous version(s) of this
   // instanceKlass. See PreviousVersionWalker below.
   GrowableArray<PreviousVersionNode *>* _previous_versions;
-  u2              _enclosing_method_class_index;  // Constant pool index for class of enclosing method, or 0 if none
-  u2              _enclosing_method_method_index; // Constant pool index for name and type of enclosing method, or 0 if none
   // JVMTI fields can be moved to their own structure - see 6315920
   unsigned char * _cached_class_file_bytes;       // JVMTI: cached class file, before retransformable agent modified it in CFLH
   jint            _cached_class_file_len;         // JVMTI: length of above
@@ -270,13 +283,36 @@
   // embedded Java itables follows here
   // embedded static fields follows here
   // embedded nonstatic oop-map blocks follows here
+  // embedded implementor of this interface follows here
+  //   The embedded implementor only exists if the current klass is an
+  //   iterface. The possible values of the implementor fall into following
+  //   three cases:
+  //     NULL: no implementor.
+  //     A klassOop that's not itself: one implementor.
+  //     Itsef: more than one implementors.
+  // embedded host klass follows here
+  //   The embedded host klass only exists in an anonymous class for
+  //   dynamic language support (JSR 292 enabled). The host class grants
+  //   its access privileges to this class also. The host class is either
+  //   named, or a previously loaded anonymous class. A non-anonymous class
+  //   or an anonymous class loaded through normal classloading does not
+  //   have this embedded field.
+  //
 
   friend class instanceKlassKlass;
   friend class SystemDictionary;
 
  public:
-  bool has_nonstatic_fields() const        { return _has_nonstatic_fields; }
-  void set_has_nonstatic_fields(bool b)    { _has_nonstatic_fields = b; }
+  bool has_nonstatic_fields() const        {
+    return (_misc_flags & _misc_has_nonstatic_fields) != 0;
+  }
+  void set_has_nonstatic_fields(bool b)    {
+    if (b) {
+      _misc_flags |= _misc_has_nonstatic_fields;
+    } else {
+      _misc_flags &= ~_misc_has_nonstatic_fields;
+    }
+  }
 
   // field sizes
   int nonstatic_field_size() const         { return _nonstatic_field_size; }
@@ -328,9 +364,6 @@
   // Number of Java declared fields
   int java_fields_count() const           { return (int)_java_fields_count; }
 
-  // Number of fields including any injected fields
-  int all_fields_count() const            { return _fields->length() / sizeof(FieldInfo::field_slots); }
-
   typeArrayOop fields() const              { return _fields; }
 
   void set_fields(typeArrayOop f, u2 java_fields_count) {
@@ -351,6 +384,12 @@
     inner_class_next_offset = 4
   };
 
+  enum EnclosingMethodAttributeOffset {
+    enclosing_method_class_index_offset = 0,
+    enclosing_method_method_index_offset = 1,
+    enclosing_method_attribute_size = 2
+  };
+
   // method override check
   bool is_override(methodHandle super_method, Handle targetclassloader, Symbol* targetclassname, TRAPS);
 
@@ -384,11 +423,19 @@
   bool is_in_error_state() const           { return _init_state == initialization_error; }
   bool is_reentrant_initialization(Thread *thread)  { return thread == _init_thread; }
   ClassState  init_state()                 { return (ClassState)_init_state; }
-  bool is_rewritten() const                { return _rewritten; }
+  bool is_rewritten() const                { return (_misc_flags & _misc_rewritten) != 0; }
 
   // defineClass specified verification
-  bool should_verify_class() const         { return _should_verify_class; }
-  void set_should_verify_class(bool value) { _should_verify_class = value; }
+  bool should_verify_class() const         {
+    return (_misc_flags & _misc_should_verify_class) != 0;
+  }
+  void set_should_verify_class(bool value) {
+    if (value) {
+      _misc_flags |= _misc_should_verify_class;
+    } else {
+      _misc_flags &= ~_misc_should_verify_class;
+    }
+  }
 
   // marking
   bool is_marked_dependent() const         { return _is_marked_dependent; }
@@ -457,9 +504,30 @@
   void set_protection_domain(oop pd)       { oop_store((oop*) &_protection_domain, pd); }
 
   // host class
-  oop host_klass() const                   { return _host_klass; }
-  void set_host_klass(oop host)            { oop_store((oop*) &_host_klass, host); }
-  bool is_anonymous() const                { return _host_klass != NULL; }
+  oop host_klass() const                   {
+    oop* hk = adr_host_klass();
+    if (hk == NULL) {
+      return NULL;
+    } else {
+      return *hk;
+    }
+  }
+  void set_host_klass(oop host)            {
+    assert(is_anonymous(), "not anonymous");
+    oop* addr = adr_host_klass();
+    assert(addr != NULL, "no reversed space");
+    oop_store(addr, host);
+  }
+  bool is_anonymous() const                {
+    return (_misc_flags & _misc_is_anonymous) != 0;
+  }
+  void set_is_anonymous(bool value)        {
+    if (value) {
+      _misc_flags |= _misc_is_anonymous;
+    } else {
+      _misc_flags &= ~_misc_is_anonymous;
+    }
+  }
 
   // signers
   objArrayOop signers() const              { return _signers; }
@@ -476,8 +544,8 @@
   void set_major_version(u2 major_version) { _major_version = major_version; }
 
   // source debug extension
-  Symbol* source_debug_extension() const   { return _source_debug_extension; }
-  void set_source_debug_extension(Symbol* n);
+  char* source_debug_extension() const     { return _source_debug_extension; }
+  void set_source_debug_extension(char* array, int length);
 
   // symbol unloading support (refcount already added)
   Symbol* array_name()                     { return _array_name; }
@@ -533,11 +601,15 @@
   Symbol* generic_signature() const                   { return _generic_signature; }
   void set_generic_signature(Symbol* sig)             { _generic_signature = sig; }
 
-  u2 enclosing_method_class_index() const             { return _enclosing_method_class_index; }
-  u2 enclosing_method_method_index() const            { return _enclosing_method_method_index; }
+  u2 enclosing_method_data(int offset);
+  u2 enclosing_method_class_index() {
+    return enclosing_method_data(enclosing_method_class_index_offset);
+  }
+  u2 enclosing_method_method_index() {
+    return enclosing_method_data(enclosing_method_method_index_offset);
+  }
   void set_enclosing_method_indices(u2 class_index,
-                                    u2 method_index)  { _enclosing_method_class_index  = class_index;
-                                                        _enclosing_method_method_index = method_index; }
+                                    u2 method_index);
 
   // jmethodID support
   static jmethodID get_jmethod_id(instanceKlassHandle ik_h,
@@ -626,19 +698,40 @@
 
   // support for stub routines
   static ByteSize init_state_offset()  { return in_ByteSize(sizeof(klassOopDesc) + offset_of(instanceKlass, _init_state)); }
+  TRACE_DEFINE_OFFSET;
   static ByteSize init_thread_offset() { return in_ByteSize(sizeof(klassOopDesc) + offset_of(instanceKlass, _init_thread)); }
 
   // subclass/subinterface checks
   bool implements_interface(klassOop k) const;
 
-  // Access to implementors of an interface. We only store the count
-  // of implementors, and in case, there are only a few
-  // implementors, we store them in a short list.
-  // This accessor returns NULL if we walk off the end of the list.
-  klassOop implementor(int i) const {
-    return (i < implementors_limit)? _implementors[i]: (klassOop) NULL;
+  // Access to the implementor of an interface.
+  klassOop implementor() const
+  {
+    klassOop* k = (klassOop*)adr_implementor();
+    if (k == NULL) {
+      return NULL;
+    } else {
+      return *k;
+    }
   }
-  int  nof_implementors() const       { return _nof_implementors; }
+
+  void set_implementor(klassOop k) {
+    assert(is_interface(), "not interface");
+    oop* addr = adr_implementor();
+    oop_store_without_check(addr, k);
+  }
+
+  int  nof_implementors() const       {
+    klassOop k = implementor();
+    if (k == NULL) {
+      return 0;
+    } else if (k != this->as_klassOop()) {
+      return 1;
+    } else {
+      return 2;
+    }
+  }
+
   void add_implementor(klassOop k);  // k is a new class that implements this interface
   void init_implementor();           // initialize
 
@@ -675,7 +768,17 @@
 
   // Sizing (in words)
   static int header_size()            { return align_object_offset(oopDesc::header_size() + sizeof(instanceKlass)/HeapWordSize); }
-  int object_size() const             { return object_size(align_object_offset(vtable_length()) + align_object_offset(itable_length()) + nonstatic_oop_map_size()); }
+
+  int object_size() const
+  {
+    return object_size(align_object_offset(vtable_length()) +
+                       align_object_offset(itable_length()) +
+                       ((is_interface() || is_anonymous()) ?
+                         align_object_offset(nonstatic_oop_map_size()) :
+                         nonstatic_oop_map_size()) +
+                       (is_interface() ? (int)sizeof(klassOop)/HeapWordSize : 0) +
+                       (is_anonymous() ? (int)sizeof(klassOop)/HeapWordSize : 0));
+  }
   static int vtable_start_offset()    { return header_size(); }
   static int vtable_length_offset()   { return oopDesc::header_size() + offset_of(instanceKlass, _vtable_len) / HeapWordSize; }
   static int object_size(int extra)   { return align_object_size(header_size() + extra); }
@@ -692,6 +795,29 @@
     return (OopMapBlock*)(start_of_itable() + align_object_offset(itable_length()));
   }
 
+  oop* adr_implementor() const {
+    if (is_interface()) {
+      return (oop*)(start_of_nonstatic_oop_maps() +
+                    nonstatic_oop_map_count());
+    } else {
+      return NULL;
+    }
+  };
+
+  oop* adr_host_klass() const {
+    if (is_anonymous()) {
+      oop* adr_impl = adr_implementor();
+      if (adr_impl != NULL) {
+        return adr_impl + 1;
+      } else {
+        return (oop*)(start_of_nonstatic_oop_maps() +
+                      nonstatic_oop_map_count());
+      }
+    } else {
+      return NULL;
+    }
+  }
+
   // Allocation profiling support
   juint alloc_size() const            { return _alloc_count * size_helper(); }
   void set_alloc_size(juint n)        {}
@@ -765,7 +891,7 @@
 #else
   void set_init_state(ClassState state) { _init_state = (u1)state; }
 #endif
-  void set_rewritten()                  { _rewritten = true; }
+  void set_rewritten()                  { _misc_flags |= _misc_rewritten; }
   void set_init_thread(Thread *thread)  { _init_thread = thread; }
 
   u2 idnum_allocated_count() const      { return _idnum_allocated_count; }
@@ -798,10 +924,8 @@
   oop* adr_constants() const         { return (oop*)&this->_constants;}
   oop* adr_class_loader() const      { return (oop*)&this->_class_loader;}
   oop* adr_protection_domain() const { return (oop*)&this->_protection_domain;}
-  oop* adr_host_klass() const        { return (oop*)&this->_host_klass;}
   oop* adr_signers() const           { return (oop*)&this->_signers;}
   oop* adr_inner_classes() const     { return (oop*)&this->_inner_classes;}
-  oop* adr_implementors() const      { return (oop*)&this->_implementors[0];}
   oop* adr_methods_jmethod_ids() const             { return (oop*)&this->_methods_jmethod_ids;}
   oop* adr_methods_cached_itable_indices() const   { return (oop*)&this->_methods_cached_itable_indices;}
   oop* adr_class_annotations() const   { return (oop*)&this->_class_annotations;}
@@ -886,7 +1010,7 @@
 
 
 /* JNIid class for jfieldIDs only */
-class JNIid: public CHeapObj {
+class JNIid: public CHeapObj<mtClass> {
   friend class VMStructs;
  private:
   klassOop           _holder;
@@ -937,7 +1061,7 @@
 // reference must be used because a weak reference would be seen as
 // collectible. A GrowableArray of PreviousVersionNodes is attached
 // to the instanceKlass as needed. See PreviousVersionWalker below.
-class PreviousVersionNode : public CHeapObj {
+class PreviousVersionNode : public CHeapObj<mtClass> {
  private:
   // A shared ConstantPool is never collected so we'll always have
   // a reference to it so we can update items in the cache. We'll
@@ -1032,7 +1156,7 @@
 // noticed since an nmethod should be removed as many times are it's
 // added.
 //
-class nmethodBucket: public CHeapObj {
+class nmethodBucket: public CHeapObj<mtClass> {
   friend class VMStructs;
  private:
   nmethod*       _nmethod;
@@ -1053,4 +1177,83 @@
   nmethod* get_nmethod()                  { return _nmethod; }
 };
 
+// An iterator that's used to access the inner classes indices in the
+// instanceKlass::_inner_classes array.
+class InnerClassesIterator : public StackObj {
+ private:
+  typeArrayHandle _inner_classes;
+  int _length;
+  int _idx;
+ public:
+
+  InnerClassesIterator(instanceKlassHandle k) {
+    _inner_classes = k->inner_classes();
+    if (k->inner_classes() != NULL) {
+      _length = _inner_classes->length();
+      // The inner class array's length should be the multiple of
+      // inner_class_next_offset if it only contains the InnerClasses
+      // attribute data, or it should be
+      // n*inner_class_next_offset+enclosing_method_attribute_size
+      // if it also contains the EnclosingMethod data.
+      assert((_length % instanceKlass::inner_class_next_offset == 0 ||
+              _length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size),
+             "just checking");
+      // Remove the enclosing_method portion if exists.
+      if (_length % instanceKlass::inner_class_next_offset == instanceKlass::enclosing_method_attribute_size) {
+        _length -= instanceKlass::enclosing_method_attribute_size;
+      }
+    } else {
+      _length = 0;
+    }
+    _idx = 0;
+  }
+
+  int length() const {
+    return _length;
+  }
+
+  void next() {
+    _idx += instanceKlass::inner_class_next_offset;
+  }
+
+  bool done() const {
+    return (_idx >= _length);
+  }
+
+  u2 inner_class_info_index() const {
+    return _inner_classes->ushort_at(
+               _idx + instanceKlass::inner_class_inner_class_info_offset);
+  }
+
+  void set_inner_class_info_index(u2 index) {
+    _inner_classes->ushort_at_put(
+               _idx + instanceKlass::inner_class_inner_class_info_offset, index);
+  }
+
+  u2 outer_class_info_index() const {
+    return _inner_classes->ushort_at(
+               _idx + instanceKlass::inner_class_outer_class_info_offset);
+  }
+
+  void set_outer_class_info_index(u2 index) {
+    _inner_classes->ushort_at_put(
+               _idx + instanceKlass::inner_class_outer_class_info_offset, index);
+  }
+
+  u2 inner_name_index() const {
+    return _inner_classes->ushort_at(
+               _idx + instanceKlass::inner_class_inner_name_offset);
+  }
+
+  void set_inner_name_index(u2 index) {
+    _inner_classes->ushort_at_put(
+               _idx + instanceKlass::inner_class_inner_name_offset, index);
+  }
+
+  u2 inner_access_flags() const {
+    return _inner_classes->ushort_at(
+               _idx + instanceKlass::inner_class_access_flags_offset);
+  }
+};
+
 #endif // SHARE_VM_OOPS_INSTANCEKLASS_HPP
diff --git a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp
index fa13f17..d6ccd42 100644
--- a/hotspot/src/share/vm/oops/instanceKlassKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceKlassKlass.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -103,7 +103,9 @@
   MarkSweep::mark_and_push(ik->adr_class_loader());
   MarkSweep::mark_and_push(ik->adr_inner_classes());
   MarkSweep::mark_and_push(ik->adr_protection_domain());
-  MarkSweep::mark_and_push(ik->adr_host_klass());
+  if (ik->adr_host_klass() != NULL) {
+    MarkSweep::mark_and_push(ik->adr_host_klass());
+  }
   MarkSweep::mark_and_push(ik->adr_signers());
   MarkSweep::mark_and_push(ik->adr_class_annotations());
   MarkSweep::mark_and_push(ik->adr_fields_annotations());
@@ -111,7 +113,7 @@
   MarkSweep::mark_and_push(ik->adr_methods_parameter_annotations());
   MarkSweep::mark_and_push(ik->adr_methods_default_annotations());
 
-  // We do not follow adr_implementors() here. It is followed later
+  // We do not follow adr_implementor() here. It is followed later
   // in instanceKlass::follow_weak_klass_links()
 
   klassKlass::oop_follow_contents(obj);
@@ -139,7 +141,9 @@
   PSParallelCompact::mark_and_push(cm, ik->adr_class_loader());
   PSParallelCompact::mark_and_push(cm, ik->adr_inner_classes());
   PSParallelCompact::mark_and_push(cm, ik->adr_protection_domain());
-  PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
+  if (ik->adr_host_klass() != NULL) {
+    PSParallelCompact::mark_and_push(cm, ik->adr_host_klass());
+  }
   PSParallelCompact::mark_and_push(cm, ik->adr_signers());
   PSParallelCompact::mark_and_push(cm, ik->adr_class_annotations());
   PSParallelCompact::mark_and_push(cm, ik->adr_fields_annotations());
@@ -177,11 +181,13 @@
   blk->do_oop(ik->adr_constants());
   blk->do_oop(ik->adr_class_loader());
   blk->do_oop(ik->adr_protection_domain());
-  blk->do_oop(ik->adr_host_klass());
+  if (ik->adr_host_klass() != NULL) {
+    blk->do_oop(ik->adr_host_klass());
+  }
   blk->do_oop(ik->adr_signers());
   blk->do_oop(ik->adr_inner_classes());
-  for (int i = 0; i < instanceKlass::implementors_limit; i++) {
-    blk->do_oop(&ik->adr_implementors()[i]);
+  if (ik->adr_implementor() != NULL) {
+    blk->do_oop(ik->adr_implementor());
   }
   blk->do_oop(ik->adr_class_annotations());
   blk->do_oop(ik->adr_fields_annotations());
@@ -227,15 +233,13 @@
   adr = ik->adr_protection_domain();
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_host_klass();
-  if (mr.contains(adr)) blk->do_oop(adr);
+  if (adr != NULL && mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_signers();
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_inner_classes();
   if (mr.contains(adr)) blk->do_oop(adr);
-  adr = ik->adr_implementors();
-  for (int i = 0; i < instanceKlass::implementors_limit; i++) {
-    if (mr.contains(&adr[i])) blk->do_oop(&adr[i]);
-  }
+  adr = ik->adr_implementor();
+  if (adr != NULL && mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_class_annotations();
   if (mr.contains(adr)) blk->do_oop(adr);
   adr = ik->adr_fields_annotations();
@@ -270,11 +274,13 @@
   MarkSweep::adjust_pointer(ik->adr_constants());
   MarkSweep::adjust_pointer(ik->adr_class_loader());
   MarkSweep::adjust_pointer(ik->adr_protection_domain());
-  MarkSweep::adjust_pointer(ik->adr_host_klass());
+  if (ik->adr_host_klass() != NULL) {
+    MarkSweep::adjust_pointer(ik->adr_host_klass());
+  }
   MarkSweep::adjust_pointer(ik->adr_signers());
   MarkSweep::adjust_pointer(ik->adr_inner_classes());
-  for (int i = 0; i < instanceKlass::implementors_limit; i++) {
-    MarkSweep::adjust_pointer(&ik->adr_implementors()[i]);
+  if (ik->adr_implementor() != NULL) {
+    MarkSweep::adjust_pointer(ik->adr_implementor());
   }
   MarkSweep::adjust_pointer(ik->adr_class_annotations());
   MarkSweep::adjust_pointer(ik->adr_fields_annotations());
@@ -302,7 +308,7 @@
   }
 
   oop* hk_addr = ik->adr_host_klass();
-  if (PSScavenge::should_scavenge(hk_addr)) {
+  if (hk_addr != NULL && PSScavenge::should_scavenge(hk_addr)) {
     pm->claim_or_forward_depth(hk_addr);
   }
 
@@ -328,6 +334,13 @@
   for (oop* cur_oop = beg_oop; cur_oop < end_oop; ++cur_oop) {
     PSParallelCompact::adjust_pointer(cur_oop);
   }
+  // embedded oops
+  if (ik->adr_implementor() != NULL) {
+    PSParallelCompact::adjust_pointer(ik->adr_implementor());
+  }
+  if (ik->adr_host_klass() != NULL) {
+    PSParallelCompact::adjust_pointer(ik->adr_host_klass());
+  }
 
   OopClosure* closure = PSParallelCompact::adjust_root_pointer_closure();
   iterate_c_heap_oops(ik, closure);
@@ -342,11 +355,25 @@
 instanceKlassKlass::allocate_instance_klass(Symbol* name, int vtable_len, int itable_len,
                                             int static_field_size,
                                             unsigned nonstatic_oop_map_count,
-                                            ReferenceType rt, TRAPS) {
+                                            AccessFlags access_flags,
+                                            ReferenceType rt,
+                                            KlassHandle host_klass, TRAPS) {
 
   const int nonstatic_oop_map_size =
     instanceKlass::nonstatic_oop_map_size(nonstatic_oop_map_count);
-  int size = instanceKlass::object_size(align_object_offset(vtable_len) + align_object_offset(itable_len) + nonstatic_oop_map_size);
+  int size = align_object_offset(vtable_len) + align_object_offset(itable_len);
+  if (access_flags.is_interface() || !host_klass.is_null()) {
+    size += align_object_offset(nonstatic_oop_map_size);
+  } else {
+    size += nonstatic_oop_map_size;
+  }
+  if (access_flags.is_interface()) {
+    size += (int)sizeof(klassOop)/HeapWordSize;
+  }
+  if (!host_klass.is_null()) {
+    size += (int)sizeof(klassOop)/HeapWordSize;
+  }
+  size = instanceKlass::object_size(size);
 
   // Allocation
   KlassHandle h_this_klass(THREAD, as_klassOop());
@@ -378,6 +405,8 @@
     ik->set_itable_length(itable_len);
     ik->set_static_field_size(static_field_size);
     ik->set_nonstatic_oop_map_size(nonstatic_oop_map_size);
+    ik->set_access_flags(access_flags);
+    ik->set_is_anonymous(!host_klass.is_null());
     assert(k()->size() == size, "wrong size for object");
 
     ik->set_array_klasses(NULL);
@@ -390,11 +419,9 @@
     ik->set_constants(NULL);
     ik->set_class_loader(NULL);
     ik->set_protection_domain(NULL);
-    ik->set_host_klass(NULL);
     ik->set_signers(NULL);
     ik->set_source_file_name(NULL);
-    ik->set_source_debug_extension(NULL);
-    ik->set_source_debug_extension(NULL);
+    ik->set_source_debug_extension(NULL, 0);
     ik->set_array_name(NULL);
     ik->set_inner_classes(NULL);
     ik->set_static_oop_field_count(0);
@@ -416,7 +443,6 @@
     ik->set_methods_annotations(NULL);
     ik->set_methods_parameter_annotations(NULL);
     ik->set_methods_default_annotations(NULL);
-    ik->set_enclosing_method_indices(0, 0);
     ik->set_jvmti_cached_class_field_map(NULL);
     ik->set_initial_method_idnum(0);
     assert(k()->is_parsable(), "should be parsable here.");
@@ -471,16 +497,12 @@
 
   if (ik->is_interface()) {
     st->print_cr(BULLET"nof implementors:  %d", ik->nof_implementors());
-    int print_impl = 0;
-    for (int i = 0; i < instanceKlass::implementors_limit; i++) {
-      if (ik->implementor(i) != NULL) {
-        if (++print_impl == 1)
-          st->print_cr(BULLET"implementor:    ");
-        st->print("   ");
-        ik->implementor(i)->print_value_on(st);
-      }
+    if (ik->nof_implementors() == 1) {
+      st->print_cr(BULLET"implementor:    ");
+      st->print("   ");
+      ik->implementor()->print_value_on(st);
+      st->cr();
     }
-    if (print_impl > 0)  st->cr();
   }
 
   st->print(BULLET"arrays:            "); ik->array_klasses()->print_value_on(st);     st->cr();
@@ -497,7 +519,9 @@
   st->print(BULLET"constants:         "); ik->constants()->print_value_on(st);         st->cr();
   st->print(BULLET"class loader:      "); ik->class_loader()->print_value_on(st);      st->cr();
   st->print(BULLET"protection domain: "); ik->protection_domain()->print_value_on(st); st->cr();
-  st->print(BULLET"host class:        "); ik->host_klass()->print_value_on(st);        st->cr();
+  if (ik->host_klass() != NULL) {
+    st->print(BULLET"host class:        "); ik->host_klass()->print_value_on(st);        st->cr();
+  }
   st->print(BULLET"signers:           "); ik->signers()->print_value_on(st);           st->cr();
   if (ik->source_file_name() != NULL) {
     st->print(BULLET"source file:       ");
@@ -506,7 +530,7 @@
   }
   if (ik->source_debug_extension() != NULL) {
     st->print(BULLET"source debug extension:       ");
-    ik->source_debug_extension()->print_value_on(st);
+    st->print_cr("%s", ik->source_debug_extension());
     st->cr();
   }
 
@@ -641,16 +665,12 @@
     }
 
     // Verify implementor fields
-    bool saw_null_impl = false;
-    for (int i = 0; i < instanceKlass::implementors_limit; i++) {
-      klassOop im = ik->implementor(i);
-      if (im == NULL) { saw_null_impl = true; continue; }
-      guarantee(!saw_null_impl, "non-nulls must preceded all nulls");
+    klassOop im = ik->implementor();
+    if (im != NULL) {
       guarantee(ik->is_interface(), "only interfaces should have implementor set");
-      guarantee(i < ik->nof_implementors(), "should only have one implementor");
       guarantee(im->is_perm(),  "should be in permspace");
       guarantee(im->is_klass(), "should be klass");
-      guarantee(!Klass::cast(klassOop(im))->is_interface(), "implementors cannot be interfaces");
+      guarantee(!Klass::cast(klassOop(im))->is_interface() || im == ik->as_klassOop(), "implementors cannot be interfaces");
     }
 
     // Verify local interfaces
diff --git a/hotspot/src/share/vm/oops/instanceKlassKlass.hpp b/hotspot/src/share/vm/oops/instanceKlassKlass.hpp
index 9cbabe2..e360d13 100644
--- a/hotspot/src/share/vm/oops/instanceKlassKlass.hpp
+++ b/hotspot/src/share/vm/oops/instanceKlassKlass.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,7 +46,9 @@
                                    int itable_len,
                                    int static_field_size,
                                    unsigned int nonstatic_oop_map_count,
+                                   AccessFlags access_flags,
                                    ReferenceType rt,
+                                   KlassHandle host_klass,
                                    TRAPS);
 
   // Casting from klassOop
diff --git a/hotspot/src/share/vm/oops/instanceRefKlass.cpp b/hotspot/src/share/vm/oops/instanceRefKlass.cpp
index 71a7a1f..7db4f03 100644
--- a/hotspot/src/share/vm/oops/instanceRefKlass.cpp
+++ b/hotspot/src/share/vm/oops/instanceRefKlass.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -497,36 +497,12 @@
 
   if (referent != NULL) {
     guarantee(referent->is_oop(), "referent field heap failed");
-    if (gch != NULL && !gch->is_in_young(obj)) {
-      // We do a specific remembered set check here since the referent
-      // field is not part of the oop mask and therefore skipped by the
-      // regular verify code.
-      if (UseCompressedOops) {
-        narrowOop* referent_addr = (narrowOop*)java_lang_ref_Reference::referent_addr(obj);
-        obj->verify_old_oop(referent_addr, true);
-      } else {
-        oop* referent_addr = (oop*)java_lang_ref_Reference::referent_addr(obj);
-        obj->verify_old_oop(referent_addr, true);
-      }
-    }
   }
   // Verify next field
   oop next = java_lang_ref_Reference::next(obj);
   if (next != NULL) {
     guarantee(next->is_oop(), "next field verify failed");
     guarantee(next->is_instanceRef(), "next field verify failed");
-    if (gch != NULL && !gch->is_in_young(obj)) {
-      // We do a specific remembered set check here since the next field is
-      // not part of the oop mask and therefore skipped by the regular
-      // verify code.
-      if (UseCompressedOops) {
-        narrowOop* next_addr = (narrowOop*)java_lang_ref_Reference::next_addr(obj);
-        obj->verify_old_oop(next_addr, true);
-      } else {
-        oop* next_addr = (oop*)java_lang_ref_Reference::next_addr(obj);
-        obj->verify_old_oop(next_addr, true);
-      }
-    }
   }
 }
 
@@ -539,6 +515,12 @@
 void instanceRefKlass::acquire_pending_list_lock(BasicLock *pending_list_basic_lock) {
   // we may enter this with pending exception set
   PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
+
+  // Create a HandleMark in case we retry a GC multiple times.
+  // Each time we attempt the GC, we allocate the handle below
+  // to hold the pending list lock. We want to free this handle.
+  HandleMark hm;
+
   Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
   ObjectSynchronizer::fast_enter(h_lock, pending_list_basic_lock, false, THREAD);
   assert(ObjectSynchronizer::current_thread_holds_lock(
@@ -551,7 +533,12 @@
   BasicLock *pending_list_basic_lock) {
   // we may enter this with pending exception set
   PRESERVE_EXCEPTION_MARK;  // exceptions are never thrown, needed for TRAPS argument
-  //
+
+  // Create a HandleMark in case we retry a GC multiple times.
+  // Each time we attempt the GC, we allocate the handle below
+  // to hold the pending list lock. We want to free this handle.
+  HandleMark hm;
+
   Handle h_lock(THREAD, java_lang_ref_Reference::pending_list_lock());
   assert(ObjectSynchronizer::current_thread_holds_lock(
            JavaThread::current(), h_lock),
diff --git a/hotspot/src/share/vm/oops/klass.cpp b/hotspot/src/share/vm/oops/klass.cpp
index 345d0b2..8b21fdd 100644
--- a/hotspot/src/share/vm/oops/klass.cpp
+++ b/hotspot/src/share/vm/oops/klass.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -174,10 +174,9 @@
 }
 
 void Klass_vtbl::post_new_init_klass(KlassHandle& klass,
-                                     klassOop new_klass,
-                                     int size) const {
+                                     klassOop new_klass) const {
   assert(!new_klass->klass_part()->null_vtbl(), "Not a complete klass");
-  CollectedHeap::post_allocation_install_obj_klass(klass, new_klass, size);
+  CollectedHeap::post_allocation_install_obj_klass(klass, new_klass);
 }
 
 void* Klass_vtbl::operator new(size_t ignored, KlassHandle& klass,
@@ -582,14 +581,6 @@
   guarantee(obj->klass()->is_klass(), "klass field is not a klass");
 }
 
-
-void Klass::oop_verify_old_oop(oop obj, oop* p, bool allow_dirty) {
-  /* $$$ I think this functionality should be handled by verification of
-  RememberedSet::verify_old_oop(obj, p, allow_dirty, false);
-  the card table. */
-}
-void Klass::oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty) { }
-
 #ifndef PRODUCT
 
 void Klass::verify_vtable_index(int i) {
diff --git a/hotspot/src/share/vm/oops/klass.hpp b/hotspot/src/share/vm/oops/klass.hpp
index 035f44c..bcbd4e7 100644
--- a/hotspot/src/share/vm/oops/klass.hpp
+++ b/hotspot/src/share/vm/oops/klass.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -149,7 +149,7 @@
   // by the shared "base_create" subroutines.
   //
   virtual void* allocate_permanent(KlassHandle& klass, int size, TRAPS) const = 0;
-  void post_new_init_klass(KlassHandle& klass, klassOop obj, int size) const;
+  void post_new_init_klass(KlassHandle& klass, klassOop obj) const;
 
   // Every subclass on which vtbl_value is called must include this macro.
   // Delay the installation of the klassKlass pointer until after the
@@ -160,7 +160,7 @@
     if (HAS_PENDING_EXCEPTION) return NULL;                                   \
     klassOop new_klass = ((Klass*) result)->as_klassOop();                    \
     OrderAccess::storestore();                                                \
-    post_new_init_klass(klass_klass, new_klass, size);                        \
+    post_new_init_klass(klass_klass, new_klass);                              \
     return result;                                                            \
   }
 
@@ -805,8 +805,6 @@
   // Verification
   virtual const char* internal_name() const = 0;
   virtual void oop_verify_on(oop obj, outputStream* st);
-  virtual void oop_verify_old_oop(oop obj, oop* p, bool allow_dirty);
-  virtual void oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty);
   // tells whether obj is partially constructed (gc during class loading)
   virtual bool oop_partially_loaded(oop obj) const { return false; }
   virtual void oop_set_partially_loaded(oop obj) {};
diff --git a/hotspot/src/share/vm/oops/methodKlass.cpp b/hotspot/src/share/vm/oops/methodKlass.cpp
index b2d6235..75d0b09 100644
--- a/hotspot/src/share/vm/oops/methodKlass.cpp
+++ b/hotspot/src/share/vm/oops/methodKlass.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,11 +112,6 @@
 
   assert(m->is_parsable(), "must be parsable here.");
   assert(m->size() == size, "wrong size for object");
-  // We should not publish an uprasable object's reference
-  // into one that is parsable, since that presents problems
-  // for the concurrent parallel marking and precleaning phases
-  // of concurrent gc (CMS).
-  xconst->set_method(m);
   return m;
 }
 
@@ -127,7 +122,6 @@
   // Performance tweak: We skip iterating over the klass pointer since we
   // know that Universe::methodKlassObj never moves.
   MarkSweep::mark_and_push(m->adr_constMethod());
-  MarkSweep::mark_and_push(m->adr_constants());
   if (m->method_data() != NULL) {
     MarkSweep::mark_and_push(m->adr_method_data());
   }
@@ -141,7 +135,6 @@
   // Performance tweak: We skip iterating over the klass pointer since we
   // know that Universe::methodKlassObj never moves.
   PSParallelCompact::mark_and_push(cm, m->adr_constMethod());
-  PSParallelCompact::mark_and_push(cm, m->adr_constants());
 #ifdef COMPILER2
   if (m->method_data() != NULL) {
     PSParallelCompact::mark_and_push(cm, m->adr_method_data());
@@ -159,7 +152,6 @@
   // Performance tweak: We skip iterating over the klass pointer since we
   // know that Universe::methodKlassObj never moves
   blk->do_oop(m->adr_constMethod());
-  blk->do_oop(m->adr_constants());
   if (m->method_data() != NULL) {
     blk->do_oop(m->adr_method_data());
   }
@@ -178,8 +170,6 @@
   oop* adr;
   adr = m->adr_constMethod();
   if (mr.contains(adr)) blk->do_oop(adr);
-  adr = m->adr_constants();
-  if (mr.contains(adr)) blk->do_oop(adr);
   if (m->method_data() != NULL) {
     adr = m->adr_method_data();
     if (mr.contains(adr)) blk->do_oop(adr);
@@ -197,7 +187,6 @@
   // Performance tweak: We skip iterating over the klass pointer since we
   // know that Universe::methodKlassObj never moves.
   MarkSweep::adjust_pointer(m->adr_constMethod());
-  MarkSweep::adjust_pointer(m->adr_constants());
   if (m->method_data() != NULL) {
     MarkSweep::adjust_pointer(m->adr_method_data());
   }
@@ -213,7 +202,6 @@
   assert(obj->is_method(), "should be method");
   methodOop m = methodOop(obj);
   PSParallelCompact::adjust_pointer(m->adr_constMethod());
-  PSParallelCompact::adjust_pointer(m->adr_constants());
 #ifdef COMPILER2
   if (m->method_data() != NULL) {
     PSParallelCompact::adjust_pointer(m->adr_method_data());
@@ -250,7 +238,11 @@
     st->print_cr(" - highest level:     %d", m->highest_comp_level());
   st->print_cr(" - vtable index:      %d",   m->_vtable_index);
   st->print_cr(" - i2i entry:         " INTPTR_FORMAT, m->interpreter_entry());
-  st->print_cr(" - adapter:           " INTPTR_FORMAT, m->adapter());
+  st->print(   " - adapters:          ");
+  if (m->adapter() == NULL)
+    st->print_cr(INTPTR_FORMAT, m->adapter());
+  else
+    m->adapter()->print_adapter_on(st);
   st->print_cr(" - compiled entry     " INTPTR_FORMAT, m->from_compiled_entry());
   st->print_cr(" - code size:         %d",   m->code_size());
   if (m->code_size() != 0) {
@@ -298,13 +290,8 @@
   if (m->code() != NULL) {
     st->print   (" - compiled code: ");
     m->code()->print_value_on(st);
-    st->cr();
   }
-  if (m->is_method_handle_invoke()) {
-    st->print_cr(" - invoke method type: " INTPTR_FORMAT, (address) m->method_handle_type());
-    // m is classified as native, but it does not have an interesting
-    // native_function or signature handler
-  } else if (m->is_native()) {
+  if (m->is_native()) {
     st->print_cr(" - native function:   " INTPTR_FORMAT, m->native_function());
     st->print_cr(" - signature handler: " INTPTR_FORMAT, m->signature_handler());
   }
@@ -339,8 +326,6 @@
   if (!obj->partially_loaded()) {
     methodOop m = methodOop(obj);
     guarantee(m->is_perm(),  "should be in permspace");
-    guarantee(m->constants()->is_perm(), "should be in permspace");
-    guarantee(m->constants()->is_constantPool(), "should be constant pool");
     guarantee(m->constMethod()->is_constMethod(), "should be constMethodOop");
     guarantee(m->constMethod()->is_perm(), "should be in permspace");
     methodDataOop method_data = m->method_data();
diff --git a/hotspot/src/share/vm/oops/methodOop.cpp b/hotspot/src/share/vm/oops/methodOop.cpp
index 0a7850f..4b9762d 100644
--- a/hotspot/src/share/vm/oops/methodOop.cpp
+++ b/hotspot/src/share/vm/oops/methodOop.cpp
@@ -40,7 +40,7 @@
 #include "oops/oop.inline.hpp"
 #include "oops/symbol.hpp"
 #include "prims/jvmtiExport.hpp"
-#include "prims/methodHandleWalk.hpp"
+#include "prims/methodHandles.hpp"
 #include "prims/nativeLookup.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/compilationPolicy.hpp"
@@ -111,25 +111,21 @@
 
 int  methodOopDesc::fast_exception_handler_bci_for(KlassHandle ex_klass, int throw_bci, TRAPS) {
   // exception table holds quadruple entries of the form (beg_bci, end_bci, handler_bci, klass_index)
-  const int beg_bci_offset     = 0;
-  const int end_bci_offset     = 1;
-  const int handler_bci_offset = 2;
-  const int klass_index_offset = 3;
-  const int entry_size         = 4;
   // access exception table
-  typeArrayHandle table (THREAD, constMethod()->exception_table());
-  int length = table->length();
-  assert(length % entry_size == 0, "exception table format has changed");
+  ExceptionTable table(this);
+  int length = table.length();
   // iterate through all entries sequentially
   constantPoolHandle pool(THREAD, constants());
-  for (int i = 0; i < length; i += entry_size) {
-    int beg_bci = table->int_at(i + beg_bci_offset);
-    int end_bci = table->int_at(i + end_bci_offset);
+  for (int i = 0; i < length; i ++) {
+    //reacquire the table in case a GC happened
+    ExceptionTable table(this);
+    int beg_bci = table.start_pc(i);
+    int end_bci = table.end_pc(i);
     assert(beg_bci <= end_bci, "inconsistent exception table");
     if (beg_bci <= throw_bci && throw_bci < end_bci) {
       // exception handler bci range covers throw_bci => investigate further
-      int handler_bci = table->int_at(i + handler_bci_offset);
-      int klass_index = table->int_at(i + klass_index_offset);
+      int handler_bci = table.handler_pc(i);
+      int klass_index = table.catch_type_index(i);
       if (klass_index == 0) {
         return handler_bci;
       } else if (ex_klass.is_null()) {
@@ -177,8 +173,12 @@
 
 
 int methodOopDesc::bci_from(address bcp) const {
+#ifdef ASSERT
+  { ResourceMark rm;
   assert(is_native() && bcp == code_base() || contains(bcp) || is_error_reported(),
          err_msg("bcp doesn't belong to this method: bcp: " INTPTR_FORMAT ", method: %s", bcp, name_and_sig_as_C_string()));
+  }
+#endif
   return bcp - code_base();
 }
 
@@ -532,9 +532,9 @@
 
 
 bool methodOopDesc::is_klass_loaded_by_klass_index(int klass_index) const {
-  if( _constants->tag_at(klass_index).is_unresolved_klass() ) {
+  if( constants()->tag_at(klass_index).is_unresolved_klass() ) {
     Thread *thread = Thread::current();
-    Symbol* klass_name = _constants->klass_name_at(klass_index);
+    Symbol* klass_name = constants()->klass_name_at(klass_index);
     Handle loader(thread, instanceKlass::cast(method_holder())->class_loader());
     Handle prot  (thread, Klass::cast(method_holder())->protection_domain());
     return SystemDictionary::find(klass_name, loader, prot, thread) != NULL;
@@ -545,7 +545,7 @@
 
 
 bool methodOopDesc::is_klass_loaded(int refinfo_index, bool must_be_resolved) const {
-  int klass_index = _constants->klass_ref_index_at(refinfo_index);
+  int klass_index = constants()->klass_ref_index_at(refinfo_index);
   if (must_be_resolved) {
     // Make sure klass is resolved in constantpool.
     if (constants()->tag_at(klass_index).is_unresolved_klass()) return false;
@@ -556,6 +556,7 @@
 
 void methodOopDesc::set_native_function(address function, bool post_event_flag) {
   assert(function != NULL, "use clear_native_function to unregister natives");
+  assert(!is_method_handle_intrinsic() || function == SharedRuntime::native_method_throw_unsatisfied_link_error_entry(), "");
   address* native_function = native_function_addr();
 
   // We can see racers trying to place the same native function into place. Once
@@ -585,12 +586,15 @@
 
 
 bool methodOopDesc::has_native_function() const {
+  if (is_method_handle_intrinsic())
+    return false;  // special-cased in SharedRuntime::generate_native_wrapper
   address func = native_function();
   return (func != NULL && func != SharedRuntime::native_method_throw_unsatisfied_link_error_entry());
 }
 
 
 void methodOopDesc::clear_native_function() {
+  // Note: is_method_handle_intrinsic() is allowed here.
   set_native_function(
     SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
     !native_bind_event_is_interesting);
@@ -609,31 +613,18 @@
 }
 
 
-bool methodOopDesc::is_not_compilable(int comp_level) const {
-  if (is_method_handle_invoke()) {
-    // compilers must recognize this method specially, or not at all
-    return true;
-  }
-  if (number_of_breakpoints() > 0) {
-    return true;
-  }
-  if (comp_level == CompLevel_any) {
-    return is_not_c1_compilable() || is_not_c2_compilable();
-  }
-  if (is_c1_compile(comp_level)) {
-    return is_not_c1_compilable();
-  }
-  if (is_c2_compile(comp_level)) {
-    return is_not_c2_compilable();
-  }
-  return false;
-}
-
-// call this when compiler finds that this method is not compilable
-void methodOopDesc::set_not_compilable(int comp_level, bool report) {
+void methodOopDesc::print_made_not_compilable(int comp_level, bool is_osr, bool report) {
   if (PrintCompilation && report) {
     ttyLocker ttyl;
-    tty->print("made not compilable ");
+    tty->print("made not %scompilable on ", is_osr ? "OSR " : "");
+    if (comp_level == CompLevel_all) {
+      tty->print("all levels ");
+    } else {
+      tty->print("levels ");
+      for (int i = (int)CompLevel_none; i <= comp_level; i++) {
+        tty->print("%d ", i);
+      }
+    }
     this->print_short_name(tty);
     int size = this->code_size();
     if (size > 0)
@@ -642,21 +633,65 @@
   }
   if ((TraceDeoptimization || LogCompilation) && (xtty != NULL)) {
     ttyLocker ttyl;
-    xtty->begin_elem("make_not_compilable thread='%d'", (int) os::current_thread_id());
+    xtty->begin_elem("make_not_%scompilable thread='" UINTX_FORMAT "'",
+                     is_osr ? "osr_" : "", os::current_thread_id());
     xtty->method(methodOop(this));
     xtty->stamp();
     xtty->end_elem();
   }
+}
+
+bool methodOopDesc::is_not_compilable(int comp_level) const {
+  if (number_of_breakpoints() > 0)
+    return true;
+  if (is_method_handle_intrinsic())
+    return !is_synthetic();  // the generated adapters must be compiled
+  if (comp_level == CompLevel_any)
+    return is_not_c1_compilable() || is_not_c2_compilable();
+  if (is_c1_compile(comp_level))
+    return is_not_c1_compilable();
+  if (is_c2_compile(comp_level))
+    return is_not_c2_compilable();
+  return false;
+}
+
+// call this when compiler finds that this method is not compilable
+void methodOopDesc::set_not_compilable(int comp_level, bool report) {
+  print_made_not_compilable(comp_level, /*is_osr*/ false, report);
   if (comp_level == CompLevel_all) {
     set_not_c1_compilable();
     set_not_c2_compilable();
   } else {
-    if (is_c1_compile(comp_level)) {
+    if (is_c1_compile(comp_level))
       set_not_c1_compilable();
-    } else
-      if (is_c2_compile(comp_level)) {
-        set_not_c2_compilable();
-      }
+    if (is_c2_compile(comp_level))
+      set_not_c2_compilable();
+  }
+  CompilationPolicy::policy()->disable_compilation(this);
+}
+
+bool methodOopDesc::is_not_osr_compilable(int comp_level) const {
+  if (is_not_compilable(comp_level))
+    return true;
+  if (comp_level == CompLevel_any)
+    return is_not_c1_osr_compilable() || is_not_c2_osr_compilable();
+  if (is_c1_compile(comp_level))
+    return is_not_c1_osr_compilable();
+  if (is_c2_compile(comp_level))
+    return is_not_c2_osr_compilable();
+  return false;
+}
+
+void methodOopDesc::set_not_osr_compilable(int comp_level, bool report) {
+  print_made_not_compilable(comp_level, /*is_osr*/ true, report);
+  if (comp_level == CompLevel_all) {
+    set_not_c1_osr_compilable();
+    set_not_c2_osr_compilable();
+  } else {
+    if (is_c1_compile(comp_level))
+      set_not_c1_osr_compilable();
+    if (is_c2_compile(comp_level))
+      set_not_c2_osr_compilable();
   }
   CompilationPolicy::policy()->disable_compilation(this);
 }
@@ -713,7 +748,7 @@
   assert(entry != NULL, "interpreter entry must be non-null");
   // Sets both _i2i_entry and _from_interpreted_entry
   set_interpreter_entry(entry);
-  if (is_native() && !is_method_handle_invoke()) {
+  if (is_native() && !is_method_handle_intrinsic()) {
     set_native_function(
       SharedRuntime::native_method_throw_unsatisfied_link_error_entry(),
       !native_bind_event_is_interesting);
@@ -801,13 +836,13 @@
   OrderAccess::storestore();
 #ifdef SHARK
   mh->_from_interpreted_entry = code->insts_begin();
-#else
+#else //!SHARK
   mh->_from_compiled_entry = code->verified_entry_point();
   OrderAccess::storestore();
   // Instantly compiled code can execute.
-  mh->_from_interpreted_entry = mh->get_i2c_entry();
-#endif // SHARK
-
+  if (!mh->is_method_handle_intrinsic())
+    mh->_from_interpreted_entry = mh->get_i2c_entry();
+#endif //!SHARK
 }
 
 
@@ -859,104 +894,51 @@
   return false;
 }
 
-bool methodOopDesc::is_method_handle_invoke_name(vmSymbols::SID name_sid) {
-  switch (name_sid) {
-  case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name):
-  case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
-    return true;
-  }
-  if (AllowInvokeGeneric
-      && name_sid == vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name))
-    return true;
-  return false;
-}
-
 // Constant pool structure for invoke methods:
 enum {
-  _imcp_invoke_name = 1,        // utf8: 'invokeExact' or 'invokeGeneric'
+  _imcp_invoke_name = 1,        // utf8: 'invokeExact', etc.
   _imcp_invoke_signature,       // utf8: (variable Symbol*)
-  _imcp_method_type_value,      // string: (variable java/lang/invoke/MethodType, sic)
   _imcp_limit
 };
 
-oop methodOopDesc::method_handle_type() const {
-  if (!is_method_handle_invoke()) { assert(false, "caller resp."); return NULL; }
-  oop mt = constants()->resolved_string_at(_imcp_method_type_value);
-  assert(mt->klass() == SystemDictionary::MethodType_klass(), "");
-  return mt;
+// Test if this method is an MH adapter frame generated by Java code.
+// Cf. java/lang/invoke/InvokerBytecodeGenerator
+bool methodOopDesc::is_compiled_lambda_form() const {
+  return intrinsic_id() == vmIntrinsics::_compiledLambdaForm;
 }
 
-jint* methodOopDesc::method_type_offsets_chain() {
-  static jint pchase[] = { -1, -1, -1 };
-  if (pchase[0] == -1) {
-    jint step0 = in_bytes(constants_offset());
-    jint step1 = (constantPoolOopDesc::header_size() + _imcp_method_type_value) * HeapWordSize;
-    // do this in reverse to avoid races:
-    OrderAccess::release_store(&pchase[1], step1);
-    OrderAccess::release_store(&pchase[0], step0);
-  }
-  return pchase;
+// Test if this method is an internal MH primitive method.
+bool methodOopDesc::is_method_handle_intrinsic() const {
+  vmIntrinsics::ID iid = intrinsic_id();
+  return (MethodHandles::is_signature_polymorphic(iid) &&
+          MethodHandles::is_signature_polymorphic_intrinsic(iid));
 }
 
-//------------------------------------------------------------------------------
-// methodOopDesc::is_method_handle_adapter
-//
-// Tests if this method is an internal adapter frame from the
-// MethodHandleCompiler.
-// Must be consistent with MethodHandleCompiler::get_method_oop().
-bool methodOopDesc::is_method_handle_adapter() const {
-  if (is_synthetic() &&
-      !is_native() &&   // has code from MethodHandleCompiler
-      is_method_handle_invoke_name(name()) &&
-      MethodHandleCompiler::klass_is_method_handle_adapter_holder(method_holder())) {
-    assert(!is_method_handle_invoke(), "disjoint");
-    return true;
-  } else {
-    return false;
-  }
+bool methodOopDesc::has_member_arg() const {
+  vmIntrinsics::ID iid = intrinsic_id();
+  return (MethodHandles::is_signature_polymorphic(iid) &&
+          MethodHandles::has_member_arg(iid));
 }
 
-methodHandle methodOopDesc::make_invoke_method(KlassHandle holder,
-                                               Symbol* name,
-                                               Symbol* signature,
-                                               Handle method_type, TRAPS) {
+// Make an instance of a signature-polymorphic internal MH primitive.
+methodHandle methodOopDesc::make_method_handle_intrinsic(vmIntrinsics::ID iid,
+                                                         Symbol* signature,
+                                                         TRAPS) {
   ResourceMark rm;
   methodHandle empty;
 
-  assert(holder() == SystemDictionary::MethodHandle_klass(),
-         "must be a JSR 292 magic type");
-
+  KlassHandle holder = SystemDictionary::MethodHandle_klass();
+  Symbol* name = MethodHandles::signature_polymorphic_intrinsic_name(iid);
+  assert(iid == MethodHandles::signature_polymorphic_name_id(name), "");
   if (TraceMethodHandles) {
-    tty->print("Creating invoke method for ");
-    signature->print_value();
-    tty->cr();
+    tty->print_cr("make_method_handle_intrinsic MH.%s%s", name->as_C_string(), signature->as_C_string());
   }
 
   // invariant:   cp->symbol_at_put is preceded by a refcount increment (more usually a lookup)
   name->increment_refcount();
   signature->increment_refcount();
 
-  // record non-BCP method types in the constant pool
-  GrowableArray<KlassHandle>* extra_klasses = NULL;
-  for (int i = -1, len = java_lang_invoke_MethodType::ptype_count(method_type()); i < len; i++) {
-    oop ptype = (i == -1
-                 ? java_lang_invoke_MethodType::rtype(method_type())
-                 : java_lang_invoke_MethodType::ptype(method_type(), i));
-    klassOop klass = check_non_bcp_klass(java_lang_Class::as_klassOop(ptype));
-    if (klass != NULL) {
-      if (extra_klasses == NULL)
-        extra_klasses = new GrowableArray<KlassHandle>(len+1);
-      bool dup = false;
-      for (int j = 0; j < extra_klasses->length(); j++) {
-        if (extra_klasses->at(j) == klass) { dup = true; break; }
-      }
-      if (!dup)
-        extra_klasses->append(KlassHandle(THREAD, klass));
-    }
-  }
-
-  int extra_klass_count = (extra_klasses == NULL ? 0 : extra_klasses->length());
-  int cp_length = _imcp_limit + extra_klass_count;
+  int cp_length = _imcp_limit;
   constantPoolHandle cp;
   {
     constantPoolOop cp_oop = oopFactory::new_constantPool(cp_length, IsSafeConc, CHECK_(empty));
@@ -964,54 +946,44 @@
   }
   cp->symbol_at_put(_imcp_invoke_name,       name);
   cp->symbol_at_put(_imcp_invoke_signature,  signature);
-  cp->string_at_put(_imcp_method_type_value, Universe::the_null_string());
-  for (int j = 0; j < extra_klass_count; j++) {
-    KlassHandle klass = extra_klasses->at(j);
-    cp->klass_at_put(_imcp_limit + j, klass());
-  }
   cp->set_preresolution();
   cp->set_pool_holder(holder());
 
-  // set up the fancy stuff:
-  cp->pseudo_string_at_put(_imcp_method_type_value, method_type());
+  // decide on access bits:  public or not?
+  int flags_bits = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_FINAL);
+  bool must_be_static = MethodHandles::is_signature_polymorphic_static(iid);
+  if (must_be_static)  flags_bits |= JVM_ACC_STATIC;
+  assert((flags_bits & JVM_ACC_PUBLIC) == 0, "do not expose these methods");
+
   methodHandle m;
   {
-    int flags_bits = (JVM_MH_INVOKE_BITS | JVM_ACC_PUBLIC | JVM_ACC_FINAL);
     methodOop m_oop = oopFactory::new_method(0, accessFlags_from(flags_bits),
-                                             0, 0, 0, IsSafeConc, CHECK_(empty));
+                                             0, 0, 0, 0, IsSafeConc, CHECK_(empty));
     m = methodHandle(THREAD, m_oop);
   }
   m->set_constants(cp());
   m->set_name_index(_imcp_invoke_name);
   m->set_signature_index(_imcp_invoke_signature);
-  assert(is_method_handle_invoke_name(m->name()), "");
+  assert(MethodHandles::is_signature_polymorphic_name(m->name()), "");
   assert(m->signature() == signature, "");
-  assert(m->is_method_handle_invoke(), "");
 #ifdef CC_INTERP
   ResultTypeFinder rtf(signature);
   m->set_result_index(rtf.type());
 #endif
   m->compute_size_of_parameters(THREAD);
-  m->set_exception_table(Universe::the_empty_int_array());
   m->init_intrinsic_id();
-  assert(m->intrinsic_id() == vmIntrinsics::_invokeExact ||
-         m->intrinsic_id() == vmIntrinsics::_invokeGeneric, "must be an invoker");
+  assert(m->is_method_handle_intrinsic(), "");
+#ifdef ASSERT
+  if (!MethodHandles::is_signature_polymorphic(m->intrinsic_id()))  m->print();
+  assert(MethodHandles::is_signature_polymorphic(m->intrinsic_id()), "must be an invoker");
+  assert(m->intrinsic_id() == iid, "correctly predicted iid");
+#endif //ASSERT
 
   // Finally, set up its entry points.
-  assert(m->method_handle_type() == method_type(), "");
   assert(m->can_be_statically_bound(), "");
   m->set_vtable_index(methodOopDesc::nonvirtual_vtable_index);
   m->link_method(m, CHECK_(empty));
 
-#ifdef ASSERT
-  // Make sure the pointer chase works.
-  address p = (address) m();
-  for (jint* pchase = method_type_offsets_chain(); (*pchase) != -1; pchase++) {
-    p = *(address*)(p + (*pchase));
-  }
-  assert((oop)p == method_type(), "pointer chase is correct");
-#endif
-
   if (TraceMethodHandles && (Verbose || WizardMode))
     m->print_on(tty);
 
@@ -1028,7 +1000,7 @@
 }
 
 
-methodHandle methodOopDesc:: clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
+methodHandle methodOopDesc::clone_with_new_data(methodHandle m, u_char* new_code, int new_code_length,
                                                 u_char* new_compressed_linenumber_table, int new_compressed_linenumber_size, TRAPS) {
   // Code below does not work for native methods - they should never get rewritten anyway
   assert(!m->is_native(), "cannot rewrite native methods");
@@ -1036,6 +1008,7 @@
   AccessFlags flags = m->access_flags();
   int checked_exceptions_len = m->checked_exceptions_length();
   int localvariable_len = m->localvariable_table_length();
+  int exception_table_len = m->exception_table_length();
   // Allocate newm_oop with the is_conc_safe parameter set
   // to IsUnsafeConc to indicate that newm_oop is not yet
   // safe for concurrent processing by a GC.
@@ -1043,6 +1016,7 @@
                                               flags,
                                               new_compressed_linenumber_size,
                                               localvariable_len,
+                                              exception_table_len,
                                               checked_exceptions_len,
                                               IsUnsafeConc,
                                               CHECK_(methodHandle()));
@@ -1077,14 +1051,13 @@
   assert(m->constMethod()->is_parsable(), "Should remain parsable");
 
   // Reset correct method/const method, method size, and parameter info
-  newcm->set_method(newm());
   newm->set_constMethod(newcm);
-  assert(newcm->method() == newm(), "check");
   newm->constMethod()->set_code_size(new_code_length);
   newm->constMethod()->set_constMethod_size(new_const_method_size);
   newm->set_method_size(new_method_size);
   assert(newm->code_size() == new_code_length, "check");
   assert(newm->checked_exceptions_length() == checked_exceptions_len, "check");
+  assert(newm->exception_table_length() == exception_table_len, "check");
   assert(newm->localvariable_table_length() == localvariable_len, "check");
   // Copy new byte codes
   memcpy(newm->code_base(), new_code, new_code_length);
@@ -1100,6 +1073,12 @@
            m->checked_exceptions_start(),
            checked_exceptions_len * sizeof(CheckedExceptionElement));
   }
+  // Copy exception table
+  if (exception_table_len > 0) {
+    memcpy(newm->exception_table_start(),
+           m->exception_table_start(),
+           exception_table_len * sizeof(ExceptionTableElement));
+  }
   // Copy local variable number table
   if (localvariable_len > 0) {
     memcpy(newm->localvariable_table_start(),
@@ -1118,8 +1097,12 @@
 vmSymbols::SID methodOopDesc::klass_id_for_intrinsics(klassOop holder) {
   // if loader is not the default loader (i.e., != NULL), we can't know the intrinsics
   // because we are not loading from core libraries
-  if (instanceKlass::cast(holder)->class_loader() != NULL)
+  // exception: the AES intrinsics come from lib/ext/sunjce_provider.jar
+  // which does not use the class default class loader so we check for its loader here
+  if ((instanceKlass::cast(holder)->class_loader() != NULL) &&
+       instanceKlass::cast(holder)->class_loader()->klass()->klass_part()->name() != vmSymbols::sun_misc_Launcher_ExtClassLoader()) {
     return vmSymbols::NO_SID;   // regardless of name, no intrinsics here
+  }
 
   // see if the klass name is well-known:
   Symbol* klass_name = instanceKlass::cast(holder)->name();
@@ -1138,7 +1121,9 @@
 
   // ditto for method and signature:
   vmSymbols::SID  name_id = vmSymbols::find_sid(name());
-  if (name_id == vmSymbols::NO_SID)  return;
+  if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle)
+      && name_id == vmSymbols::NO_SID)
+    return;
   vmSymbols::SID   sig_id = vmSymbols::find_sid(signature());
   if (klass_id != vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle)
       && sig_id == vmSymbols::NO_SID)  return;
@@ -1167,21 +1152,10 @@
 
   // Signature-polymorphic methods: MethodHandle.invoke*, InvokeDynamic.*.
   case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_MethodHandle):
-    if (is_static() || !is_native())  break;
-    switch (name_id) {
-    case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeGeneric_name):
-      if (!AllowInvokeGeneric)  break;
-    case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):
-      id = vmIntrinsics::_invokeGeneric;
-      break;
-    case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeExact_name):
-      id = vmIntrinsics::_invokeExact;
-      break;
-    }
-    break;
-  case vmSymbols::VM_SYMBOL_ENUM_NAME(java_lang_invoke_InvokeDynamic):
-    if (!is_static() || !is_native())  break;
-    id = vmIntrinsics::_invokeDynamic;
+    if (!is_native())  break;
+    id = MethodHandles::signature_polymorphic_name_id(method_holder(), name());
+    if (is_static() != MethodHandles::is_signature_polymorphic_static(id))
+      id = vmIntrinsics::_none;
     break;
   }
 
@@ -1194,6 +1168,12 @@
 
 // These two methods are static since a GC may move the methodOopDesc
 bool methodOopDesc::load_signature_classes(methodHandle m, TRAPS) {
+  if (THREAD->is_Compiler_thread()) {
+    // There is nothing useful this routine can do from within the Compile thread.
+    // Hopefully, the signature contains only well-known classes.
+    // We could scan for this and return true/false, but the caller won't care.
+    return false;
+  }
   bool sig_is_loaded = true;
   Handle class_loader(THREAD, instanceKlass::cast(m->method_holder())->class_loader());
   Handle protection_domain(THREAD, Klass::cast(m->method_holder())->protection_domain());
@@ -1247,6 +1227,8 @@
 #endif
   name()->print_symbol_on(st);
   if (WizardMode) signature()->print_symbol_on(st);
+  else if (MethodHandles::is_signature_polymorphic(intrinsic_id()))
+    MethodHandles::print_as_basic_type_signature_on(st, signature(), true);
 }
 
 // This is only done during class loading, so it is OK to assume method_idnum matches the methods() array
diff --git a/hotspot/src/share/vm/oops/methodOop.hpp b/hotspot/src/share/vm/oops/methodOop.hpp
index 03f62f6..0782bb9 100644
--- a/hotspot/src/share/vm/oops/methodOop.hpp
+++ b/hotspot/src/share/vm/oops/methodOop.hpp
@@ -64,7 +64,6 @@
 // | klass                                                |
 // |------------------------------------------------------|
 // | constMethodOop                 (oop)                 |
-// | constants                      (oop)                 |
 // |------------------------------------------------------|
 // | methodData                     (oop)                 |
 // | interp_invocation_count                              |
@@ -110,7 +109,6 @@
  friend class VMStructs;
  private:
   constMethodOop    _constMethod;                // Method read-only data.
-  constantPoolOop   _constants;                  // Constant pool
   methodDataOop     _method_data;
   int               _interpreter_invocation_count; // Count of times invoked (reused as prev_event_count in tiered)
   AccessFlags       _access_flags;               // Access flags
@@ -124,8 +122,11 @@
   u2                _max_locals;                 // Number of local variables used by this method
   u2                _size_of_parameters;         // size of the parameter block (receiver + arguments) in words
   u1                _intrinsic_id;               // vmSymbols::intrinsic_id (0 == _none)
-  u1                _jfr_towrite : 1,            // Flags
-                                 : 7;
+  u1                _jfr_towrite  : 1,           // Flags
+                    _force_inline : 1,
+                    _hidden       : 1,
+                    _dont_inline  : 1,
+                                  : 4;
   u2                _interpreter_throwout_count; // Count of times method was exited via exception while interpreting
   u2                _number_of_breakpoints;      // fullspeed debugging support
   InvocationCounter _invocation_counter;         // Incremented before each activation of the method - used to trigger frequency-based optimizations
@@ -170,17 +171,17 @@
   void set_access_flags(AccessFlags flags)       { _access_flags = flags; }
 
   // name
-  Symbol* name() const                           { return _constants->symbol_at(name_index()); }
+  Symbol* name() const                           { return constants()->symbol_at(name_index()); }
   int name_index() const                         { return constMethod()->name_index();         }
   void set_name_index(int index)                 { constMethod()->set_name_index(index);       }
 
   // signature
-  Symbol* signature() const                      { return _constants->symbol_at(signature_index()); }
+  Symbol* signature() const                      { return constants()->symbol_at(signature_index()); }
   int signature_index() const                    { return constMethod()->signature_index();         }
   void set_signature_index(int index)            { constMethod()->set_signature_index(index);       }
 
   // generics support
-  Symbol* generic_signature() const              { int idx = generic_signature_index(); return ((idx != 0) ? _constants->symbol_at(idx) : (Symbol*)NULL); }
+  Symbol* generic_signature() const              { int idx = generic_signature_index(); return ((idx != 0) ? constants()->symbol_at(idx) : (Symbol*)NULL); }
   int generic_signature_index() const            { return constMethod()->generic_signature_index(); }
   void set_generic_signature_index(int index)    { constMethod()->set_generic_signature_index(index); }
 
@@ -242,12 +243,14 @@
   }
 
   // constant pool for klassOop holding this method
-  constantPoolOop constants() const              { return _constants; }
-  void set_constants(constantPoolOop c)          { oop_store_without_check((oop*)&_constants, c); }
+  constantPoolOop constants() const              { return constMethod()->constants(); }
+  void set_constants(constantPoolOop c)          { constMethod()->set_constants(c); }
 
   // max stack
-  int  max_stack() const                         { return _max_stack; }
-  void set_max_stack(int size)                   { _max_stack = size; }
+  // return original max stack size for method verification
+  int  verifier_max_stack() const                { return _max_stack; }
+  int           max_stack() const                { return _max_stack + extra_stack_entries(); }
+  void      set_max_stack(int size)              {        _max_stack = size; }
 
   // max locals
   int  max_locals() const                        { return _max_locals; }
@@ -284,12 +287,12 @@
   }
 
   // exception handler table
-  typeArrayOop exception_table() const
-                                   { return constMethod()->exception_table(); }
-  void set_exception_table(typeArrayOop e)
-                                     { constMethod()->set_exception_table(e); }
   bool has_exception_handler() const
                              { return constMethod()->has_exception_handler(); }
+  int exception_table_length() const
+                             { return constMethod()->exception_table_length(); }
+  ExceptionTableElement* exception_table_start() const
+                             { return constMethod()->exception_table_start(); }
 
   // Finds the first entry point bci of an exception handler for an
   // exception of klass ex_klass thrown at throw_bci. A value of NULL
@@ -453,7 +456,7 @@
                        { return constMethod()->compressed_linenumber_table(); }
 
   // method holder (the klassOop holding this method)
-  klassOop method_holder() const                 { return _constants->pool_holder(); }
+  klassOop method_holder() const                 { return constants()->pool_holder(); }
 
   void compute_size_of_parameters(Thread *thread); // word size of parameters (receiver if any + arguments)
   Symbol* klass_name() const;                    // returns the name of the method holder
@@ -544,7 +547,6 @@
 
   // interpreter support
   static ByteSize const_offset()                 { return byte_offset_of(methodOopDesc, _constMethod       ); }
-  static ByteSize constants_offset()             { return byte_offset_of(methodOopDesc, _constants         ); }
   static ByteSize access_flags_offset()          { return byte_offset_of(methodOopDesc, _access_flags      ); }
 #ifdef CC_INTERP
   static ByteSize result_index_offset()          { return byte_offset_of(methodOopDesc, _result_index ); }
@@ -592,28 +594,19 @@
   bool is_overridden_in(klassOop k) const;
 
   // JSR 292 support
-  bool is_method_handle_invoke() const              { return access_flags().is_method_handle_invoke(); }
-  static bool is_method_handle_invoke_name(vmSymbols::SID name_sid);
-  static bool is_method_handle_invoke_name(Symbol* name) {
-    return is_method_handle_invoke_name(vmSymbols::find_sid(name));
-  }
-  // Tests if this method is an internal adapter frame from the
-  // MethodHandleCompiler.
-  bool is_method_handle_adapter() const;
-  static methodHandle make_invoke_method(KlassHandle holder,
-                                         Symbol* name, //invokeExact or invokeGeneric
-                                         Symbol* signature, //anything at all
-                                         Handle method_type,
-                                         TRAPS);
+  bool is_method_handle_intrinsic() const;          // MethodHandles::is_signature_polymorphic_intrinsic(intrinsic_id)
+  bool is_compiled_lambda_form() const;             // intrinsic_id() == vmIntrinsics::_compiledLambdaForm
+  bool has_member_arg() const;                      // intrinsic_id() == vmIntrinsics::_linkToSpecial, etc.
+  static methodHandle make_method_handle_intrinsic(vmIntrinsics::ID iid, // _invokeBasic, _linkToVirtual
+                                                   Symbol* signature, //anything at all
+                                                   TRAPS);
   static klassOop check_non_bcp_klass(klassOop klass);
   // these operate only on invoke methods:
-  oop method_handle_type() const;
-  static jint* method_type_offsets_chain();  // series of pointer-offsets, terminated by -1
   // presize interpreter frames for extra interpreter stack entries, if needed
   // method handles want to be able to push a few extra values (e.g., a bound receiver), and
   // invokedynamic sometimes needs to push a bootstrap method, call site, and arglist,
   // all without checking for a stack overflow
-  static int extra_stack_entries() { return EnableInvokeDynamic ? (int) MethodHandlePushLimit + 3 : 0; }
+  static int extra_stack_entries() { return EnableInvokeDynamic ? 2 : 0; }
   static int extra_stack_words();  // = extra_stack_entries() * Interpreter::stackElementSize()
 
   // RedefineClasses() support:
@@ -658,6 +651,13 @@
   bool jfr_towrite()                 { return _jfr_towrite; }
   void set_jfr_towrite(bool towrite) { _jfr_towrite = towrite; }
 
+  bool     force_inline()       { return _force_inline;     }
+  void set_force_inline(bool x) {        _force_inline = x; }
+  bool     dont_inline()        { return _dont_inline;      }
+  void set_dont_inline(bool x)  {        _dont_inline = x;  }
+  bool  is_hidden()             { return _hidden;           }
+  void set_hidden(bool x)       {        _hidden = x;       }
+
   // On-stack replacement support
   bool has_osr_nmethod(int level, bool match_level) {
    return instanceKlass::cast(method_holder())->lookup_osr_nmethod(this, InvocationEntryBci, level, match_level) != NULL;
@@ -677,19 +677,30 @@
   // Indicates whether compilation failed earlier for this method, or
   // whether it is not compilable for another reason like having a
   // breakpoint set in it.
-  bool is_not_compilable(int comp_level = CompLevel_any) const;
+  bool  is_not_compilable(int comp_level = CompLevel_any) const;
   void set_not_compilable(int comp_level = CompLevel_all, bool report = true);
   void set_not_compilable_quietly(int comp_level = CompLevel_all) {
     set_not_compilable(comp_level, false);
   }
-  bool is_not_osr_compilable(int comp_level = CompLevel_any) const {
-    return is_not_compilable(comp_level) || access_flags().is_not_osr_compilable();
+  bool  is_not_osr_compilable(int comp_level = CompLevel_any) const;
+  void set_not_osr_compilable(int comp_level = CompLevel_all, bool report = true);
+  void set_not_osr_compilable_quietly(int comp_level = CompLevel_all) {
+    set_not_osr_compilable(comp_level, false);
   }
-  void set_not_osr_compilable()               { _access_flags.set_not_osr_compilable();       }
-  bool is_not_c1_compilable() const           { return access_flags().is_not_c1_compilable(); }
-  void set_not_c1_compilable()                { _access_flags.set_not_c1_compilable();        }
-  bool is_not_c2_compilable() const           { return access_flags().is_not_c2_compilable(); }
-  void set_not_c2_compilable()                { _access_flags.set_not_c2_compilable();        }
+
+ private:
+  void print_made_not_compilable(int comp_level, bool is_osr, bool report);
+
+ public:
+  bool  is_not_c1_compilable() const          { return access_flags().is_not_c1_compilable(); }
+  void set_not_c1_compilable()                {       _access_flags.set_not_c1_compilable();  }
+  bool  is_not_c2_compilable() const          { return access_flags().is_not_c2_compilable(); }
+  void set_not_c2_compilable()                {       _access_flags.set_not_c2_compilable();  }
+
+  bool  is_not_c1_osr_compilable() const      { return is_not_c1_compilable(); }  // don't waste an accessFlags bit
+  void set_not_c1_osr_compilable()            {       set_not_c1_compilable(); }  // don't waste an accessFlags bit
+  bool  is_not_c2_osr_compilable() const      { return access_flags().is_not_c2_osr_compilable(); }
+  void set_not_c2_osr_compilable()            {       _access_flags.set_not_c2_osr_compilable();  }
 
   // Background compilation support
   bool queued_for_compilation() const  { return access_flags().queued_for_compilation(); }
@@ -703,8 +714,8 @@
   static bool has_unloaded_classes_in_signature(methodHandle m, TRAPS);
 
   // Printing
-  void print_short_name(outputStream* st)        /*PRODUCT_RETURN*/; // prints as klassname::methodname; Exposed so field engineers can debug VM
-  void print_name(outputStream* st)              PRODUCT_RETURN; // prints as "virtual void foo(int)"
+  void print_short_name(outputStream* st = tty)  /*PRODUCT_RETURN*/; // prints as klassname::methodname; Exposed so field engineers can debug VM
+  void print_name(outputStream* st = tty)        PRODUCT_RETURN; // prints as "virtual void foo(int)"
 
   // Helper routine used for method sorting
   static void sort_methods(objArrayOop methods,
@@ -723,7 +734,6 @@
 
   // Garbage collection support
   oop*  adr_constMethod() const                  { return (oop*)&_constMethod;     }
-  oop*  adr_constants() const                    { return (oop*)&_constants;       }
   oop*  adr_method_data() const                  { return (oop*)&_method_data;     }
 };
 
@@ -805,7 +815,7 @@
 // breakpoints are written only at safepoints, and are read
 // concurrently only outside of safepoints.
 
-class BreakpointInfo : public CHeapObj {
+class BreakpointInfo : public CHeapObj<mtClass> {
   friend class VMStructs;
  private:
   Bytecodes::Code  _orig_bytecode;
@@ -839,4 +849,66 @@
   void clear(methodOop method);
 };
 
+// Utility class for access exception handlers
+class ExceptionTable : public StackObj {
+ private:
+  ExceptionTableElement* _table;
+  u2  _length;
+
+ public:
+  ExceptionTable(methodOop m) {
+    if (m->has_exception_handler()) {
+      _table = m->exception_table_start();
+      _length = m->exception_table_length();
+    } else {
+      _table = NULL;
+      _length = 0;
+    }
+  }
+
+  int length() const {
+    return _length;
+  }
+
+  u2 start_pc(int idx) const {
+    assert(idx < _length, "out of bounds");
+    return _table[idx].start_pc;
+  }
+
+  void set_start_pc(int idx, u2 value) {
+    assert(idx < _length, "out of bounds");
+    _table[idx].start_pc = value;
+  }
+
+  u2 end_pc(int idx) const {
+    assert(idx < _length, "out of bounds");
+    return _table[idx].end_pc;
+  }
+
+  void set_end_pc(int idx, u2 value) {
+    assert(idx < _length, "out of bounds");
+    _table[idx].end_pc = value;
+  }
+
+  u2 handler_pc(int idx) const {
+    assert(idx < _length, "out of bounds");
+    return _table[idx].handler_pc;
+  }
+
+  void set_handler_pc(int idx, u2 value) {
+    assert(idx < _length, "out of bounds");
+    _table[idx].handler_pc = value;
+  }
+
+  u2 catch_type_index(int idx) const {
+    assert(idx < _length, "out of bounds");
+    return _table[idx].catch_type_index;
+  }
+
+  void set_catch_type_index(int idx, u2 value) {
+    assert(idx < _length, "out of bounds");
+    _table[idx].catch_type_index = value;
+  }
+};
+
 #endif // SHARE_VM_OOPS_METHODOOP_HPP
diff --git a/hotspot/src/share/vm/oops/objArrayKlass.cpp b/hotspot/src/share/vm/oops/objArrayKlass.cpp
index 79b1df2..c152664 100644
--- a/hotspot/src/share/vm/oops/objArrayKlass.cpp
+++ b/hotspot/src/share/vm/oops/objArrayKlass.cpp
@@ -545,10 +545,3 @@
     guarantee(oa->obj_at(index)->is_oop_or_null(), "should be oop");
   }
 }
-
-void objArrayKlass::oop_verify_old_oop(oop obj, oop* p, bool allow_dirty) {
-  /* $$$ move into remembered set verification?
-  RememberedSet::verify_old_oop(obj, p, allow_dirty, true);
-  */
-}
-void objArrayKlass::oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty) {}
diff --git a/hotspot/src/share/vm/oops/objArrayKlass.hpp b/hotspot/src/share/vm/oops/objArrayKlass.hpp
index 44717ec..ebf6a9e 100644
--- a/hotspot/src/share/vm/oops/objArrayKlass.hpp
+++ b/hotspot/src/share/vm/oops/objArrayKlass.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -144,8 +144,6 @@
   // Verification
   const char* internal_name() const;
   void oop_verify_on(oop obj, outputStream* st);
-  void oop_verify_old_oop(oop obj, oop* p, bool allow_dirty);
-  void oop_verify_old_oop(oop obj, narrowOop* p, bool allow_dirty);
 };
 
 #endif // SHARE_VM_OOPS_OBJARRAYKLASS_HPP
diff --git a/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp b/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp
index dedd3f8..802ffef 100644
--- a/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp
+++ b/hotspot/src/share/vm/oops/objArrayKlassKlass.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -137,7 +137,7 @@
       new_str[idx++] = ';';
     }
     new_str[idx++] = '\0';
-    name = SymbolTable::new_symbol(new_str, CHECK_0);
+    name = SymbolTable::new_permanent_symbol(new_str, CHECK_0);
     if (element_klass->oop_is_instance()) {
       instanceKlass* ik = instanceKlass::cast(element_klass());
       ik->set_array_name(name);
diff --git a/hotspot/src/share/vm/oops/oop.cpp b/hotspot/src/share/vm/oops/oop.cpp
index f836fb7..61cf38d 100644
--- a/hotspot/src/share/vm/oops/oop.cpp
+++ b/hotspot/src/share/vm/oops/oop.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -107,16 +107,6 @@
   verify_on(tty);
 }
 
-
-// XXX verify_old_oop doesn't do anything (should we remove?)
-void oopDesc::verify_old_oop(oop* p, bool allow_dirty) {
-  blueprint()->oop_verify_old_oop(this, p, allow_dirty);
-}
-
-void oopDesc::verify_old_oop(narrowOop* p, bool allow_dirty) {
-  blueprint()->oop_verify_old_oop(this, p, allow_dirty);
-}
-
 bool oopDesc::partially_loaded() {
   return blueprint()->oop_partially_loaded(this);
 }
diff --git a/hotspot/src/share/vm/oops/oop.hpp b/hotspot/src/share/vm/oops/oop.hpp
index 4d2f453..694d921 100644
--- a/hotspot/src/share/vm/oops/oop.hpp
+++ b/hotspot/src/share/vm/oops/oop.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -293,8 +293,6 @@
   // verification operations
   void verify_on(outputStream* st);
   void verify();
-  void verify_old_oop(oop* p, bool allow_dirty);
-  void verify_old_oop(narrowOop* p, bool allow_dirty);
 
   // tells whether this oop is partially constructed (gc during class loading)
   bool partially_loaded();
diff --git a/hotspot/src/share/vm/oops/symbol.cpp b/hotspot/src/share/vm/oops/symbol.cpp
index 4c50847..af7ba42 100644
--- a/hotspot/src/share/vm/oops/symbol.cpp
+++ b/hotspot/src/share/vm/oops/symbol.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -29,15 +29,25 @@
 #include "runtime/os.hpp"
 #include "memory/allocation.inline.hpp"
 
-Symbol::Symbol(const u1* name, int length) : _refcount(0), _length(length) {
+Symbol::Symbol(const u1* name, int length, int refcount) : _refcount(refcount), _length(length) {
   _identity_hash = os::random();
   for (int i = 0; i < _length; i++) {
     byte_at_put(i, name[i]);
   }
 }
 
-void* Symbol::operator new(size_t size, int len) {
-  return (void *) AllocateHeap(object_size(len) * HeapWordSize, "symbol");
+void* Symbol::operator new(size_t sz, int len, TRAPS) {
+  int alloc_size = object_size(len)*HeapWordSize;
+  address res = (address) AllocateHeap(alloc_size, mtSymbol);
+  DEBUG_ONLY(set_allocation_type(res, ResourceObj::C_HEAP);)
+  return res;
+}
+
+void* Symbol::operator new(size_t sz, int len, Arena* arena, TRAPS) {
+  int alloc_size = object_size(len)*HeapWordSize;
+  address res = (address)arena->Amalloc(alloc_size);
+  DEBUG_ONLY(set_allocation_type(res, ResourceObj::ARENA);)
+  return res;
 }
 
 // ------------------------------------------------------------------
@@ -86,7 +96,7 @@
   address scan = bytes + i;
   if (scan > limit)
     return -1;
-  for (;;) {
+  for (; scan <= limit; scan++) {
     scan = (address) memchr(scan, first_char, (limit + 1 - scan));
     if (scan == NULL)
       return -1;  // not found
@@ -94,6 +104,7 @@
     if (memcmp(scan, str, len) == 0)
       return (int)(scan - bytes);
   }
+  return -1;
 }
 
 
@@ -206,26 +217,5 @@
   }
 }
 
-void Symbol::increment_refcount() {
-  // Only increment the refcount if positive.  If negative either
-  // overflow has occurred or it is a permanent symbol in a read only
-  // shared archive.
-  if (_refcount >= 0) {
-    Atomic::inc(&_refcount);
-    NOT_PRODUCT(Atomic::inc(&_total_count);)
-  }
-}
-
-void Symbol::decrement_refcount() {
-  if (_refcount >= 0) {
-    Atomic::dec(&_refcount);
-#ifdef ASSERT
-    if (_refcount < 0) {
-      print();
-      assert(false, "reference count underflow for symbol");
-    }
-#endif
-  }
-}
-
+// SymbolTable prints this in its statistics
 NOT_PRODUCT(int Symbol::_total_count = 0;)
diff --git a/hotspot/src/share/vm/oops/symbol.hpp b/hotspot/src/share/vm/oops/symbol.hpp
index 269c2b7..fba0cc9 100644
--- a/hotspot/src/share/vm/oops/symbol.hpp
+++ b/hotspot/src/share/vm/oops/symbol.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 
 #include "utilities/utf8.hpp"
 #include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
 
 // A Symbol is a canonicalized string.
 // All Symbols reside in global SymbolTable and are reference counted.
@@ -95,7 +96,7 @@
 // TempNewSymbol (passed in as a parameter) so the reference count on its symbol
 // will be decremented when it goes out of scope.
 
-class Symbol : public CHeapObj {
+class Symbol : public ResourceObj {
   friend class VMStructs;
   friend class SymbolTable;
   friend class MoveSymbols;
@@ -111,7 +112,7 @@
   };
 
   static int object_size(int length) {
-    size_t size = heap_word_size(sizeof(Symbol) + length);
+    size_t size = heap_word_size(sizeof(Symbol) + (length > 0 ? length - 1 : 0));
     return align_object_size(size);
   }
 
@@ -120,28 +121,25 @@
     _body[index] = value;
   }
 
-  Symbol(const u1* name, int length);
-  void* operator new(size_t size, int len);
+  Symbol(const u1* name, int length, int refcount);
+  void* operator new(size_t size, int len, TRAPS);
+  void* operator new(size_t size, int len, Arena* arena, TRAPS);
 
  public:
   // Low-level access (used with care, since not GC-safe)
   const jbyte* base() const { return &_body[0]; }
 
-  int object_size() { return object_size(utf8_length()); }
+  int object_size()         { return object_size(utf8_length()); }
 
   // Returns the largest size symbol we can safely hold.
-  static int max_length() {
-    return max_symbol_length;
-  }
+  static int max_length()   { return max_symbol_length; }
 
-  int identity_hash() {
-    return _identity_hash;
-  }
+  int identity_hash()       { return _identity_hash; }
 
   // Reference counting.  See comments above this class for when to use.
-  int refcount() const { return _refcount; }
-  void increment_refcount();
-  void decrement_refcount();
+  int refcount() const      { return _refcount; }
+  inline void increment_refcount();
+  inline void decrement_refcount();
 
   int byte_at(int index) const {
     assert(index >=0 && index < _length, "symbol index overflow");
@@ -220,4 +218,26 @@
  return (((uintptr_t)this < (uintptr_t)other) ? -1
    : ((uintptr_t)this == (uintptr_t) other) ? 0 : 1);
 }
+
+inline void Symbol::increment_refcount() {
+  // Only increment the refcount if positive.  If negative either
+  // overflow has occurred or it is a permanent symbol in a read only
+  // shared archive.
+  if (_refcount >= 0) {
+    Atomic::inc(&_refcount);
+    NOT_PRODUCT(Atomic::inc(&_total_count);)
+  }
+}
+
+inline void Symbol::decrement_refcount() {
+  if (_refcount >= 0) {
+    Atomic::dec(&_refcount);
+#ifdef ASSERT
+    if (_refcount < 0) {
+      print();
+      assert(false, "reference count underflow for symbol");
+    }
+#endif
+  }
+}
 #endif // SHARE_VM_OOPS_SYMBOL_HPP
diff --git a/hotspot/src/share/vm/oops/typeArrayKlass.cpp b/hotspot/src/share/vm/oops/typeArrayKlass.cpp
index 70aed0d..5beff55 100644
--- a/hotspot/src/share/vm/oops/typeArrayKlass.cpp
+++ b/hotspot/src/share/vm/oops/typeArrayKlass.cpp
@@ -55,7 +55,7 @@
 
   Symbol* sym = NULL;
   if (name_str != NULL) {
-    sym = SymbolTable::new_symbol(name_str, CHECK_NULL);
+    sym = SymbolTable::new_permanent_symbol(name_str, CHECK_NULL);
   }
   KlassHandle klassklass (THREAD, Universe::typeArrayKlassKlassObj());
 
diff --git a/hotspot/src/share/vm/opto/addnode.cpp b/hotspot/src/share/vm/opto/addnode.cpp
index ee6f6bc..b3b92ec 100644
--- a/hotspot/src/share/vm/opto/addnode.cpp
+++ b/hotspot/src/share/vm/opto/addnode.cpp
@@ -248,47 +248,47 @@
     const Type *t_sub1 = phase->type( in1->in(1) );
     const Type *t_2    = phase->type( in2        );
     if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP )
-      return new (phase->C, 3) SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ),
+      return new (phase->C) SubINode(phase->makecon( add_ring( t_sub1, t_2 ) ),
                               in1->in(2) );
     // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)"
     if( op2 == Op_SubI ) {
       // Check for dead cycle: d = (a-b)+(c-d)
       assert( in1->in(2) != this && in2->in(2) != this,
               "dead loop in AddINode::Ideal" );
-      Node *sub  = new (phase->C, 3) SubINode(NULL, NULL);
-      sub->init_req(1, phase->transform(new (phase->C, 3) AddINode(in1->in(1), in2->in(1) ) ));
-      sub->init_req(2, phase->transform(new (phase->C, 3) AddINode(in1->in(2), in2->in(2) ) ));
+      Node *sub  = new (phase->C) SubINode(NULL, NULL);
+      sub->init_req(1, phase->transform(new (phase->C) AddINode(in1->in(1), in2->in(1) ) ));
+      sub->init_req(2, phase->transform(new (phase->C) AddINode(in1->in(2), in2->in(2) ) ));
       return sub;
     }
     // Convert "(a-b)+(b+c)" into "(a+c)"
     if( op2 == Op_AddI && in1->in(2) == in2->in(1) ) {
       assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal");
-      return new (phase->C, 3) AddINode(in1->in(1), in2->in(2));
+      return new (phase->C) AddINode(in1->in(1), in2->in(2));
     }
     // Convert "(a-b)+(c+b)" into "(a+c)"
     if( op2 == Op_AddI && in1->in(2) == in2->in(2) ) {
       assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddINode::Ideal");
-      return new (phase->C, 3) AddINode(in1->in(1), in2->in(1));
+      return new (phase->C) AddINode(in1->in(1), in2->in(1));
     }
     // Convert "(a-b)+(b-c)" into "(a-c)"
     if( op2 == Op_SubI && in1->in(2) == in2->in(1) ) {
       assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddINode::Ideal");
-      return new (phase->C, 3) SubINode(in1->in(1), in2->in(2));
+      return new (phase->C) SubINode(in1->in(1), in2->in(2));
     }
     // Convert "(a-b)+(c-a)" into "(c-b)"
     if( op2 == Op_SubI && in1->in(1) == in2->in(2) ) {
       assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddINode::Ideal");
-      return new (phase->C, 3) SubINode(in2->in(1), in1->in(2));
+      return new (phase->C) SubINode(in2->in(1), in1->in(2));
     }
   }
 
   // Convert "x+(0-y)" into "(x-y)"
   if( op2 == Op_SubI && phase->type(in2->in(1)) == TypeInt::ZERO )
-    return new (phase->C, 3) SubINode(in1, in2->in(2) );
+    return new (phase->C) SubINode(in1, in2->in(2) );
 
   // Convert "(0-y)+x" into "(x-y)"
   if( op1 == Op_SubI && phase->type(in1->in(1)) == TypeInt::ZERO )
-    return new (phase->C, 3) SubINode( in2, in1->in(2) );
+    return new (phase->C) SubINode( in2, in1->in(2) );
 
   // Convert (x>>>z)+y into (x+(y<<z))>>>z for small constant z and y.
   // Helps with array allocation math constant folding
@@ -309,8 +309,8 @@
     if( z < 5 && -5 < y && y < 0 ) {
       const Type *t_in11 = phase->type(in1->in(1));
       if( t_in11 != Type::TOP && (t_in11->is_int()->_lo >= -(y << z)) ) {
-        Node *a = phase->transform( new (phase->C, 3) AddINode( in1->in(1), phase->intcon(y<<z) ) );
-        return new (phase->C, 3) URShiftINode( a, in1->in(2) );
+        Node *a = phase->transform( new (phase->C) AddINode( in1->in(1), phase->intcon(y<<z) ) );
+        return new (phase->C) URShiftINode( a, in1->in(2) );
       }
     }
   }
@@ -381,47 +381,47 @@
     const Type *t_sub1 = phase->type( in1->in(1) );
     const Type *t_2    = phase->type( in2        );
     if( t_sub1->singleton() && t_2->singleton() && t_sub1 != Type::TOP && t_2 != Type::TOP )
-      return new (phase->C, 3) SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ),
+      return new (phase->C) SubLNode(phase->makecon( add_ring( t_sub1, t_2 ) ),
                               in1->in(2) );
     // Convert "(a-b)+(c-d)" into "(a+c)-(b+d)"
     if( op2 == Op_SubL ) {
       // Check for dead cycle: d = (a-b)+(c-d)
       assert( in1->in(2) != this && in2->in(2) != this,
               "dead loop in AddLNode::Ideal" );
-      Node *sub  = new (phase->C, 3) SubLNode(NULL, NULL);
-      sub->init_req(1, phase->transform(new (phase->C, 3) AddLNode(in1->in(1), in2->in(1) ) ));
-      sub->init_req(2, phase->transform(new (phase->C, 3) AddLNode(in1->in(2), in2->in(2) ) ));
+      Node *sub  = new (phase->C) SubLNode(NULL, NULL);
+      sub->init_req(1, phase->transform(new (phase->C) AddLNode(in1->in(1), in2->in(1) ) ));
+      sub->init_req(2, phase->transform(new (phase->C) AddLNode(in1->in(2), in2->in(2) ) ));
       return sub;
     }
     // Convert "(a-b)+(b+c)" into "(a+c)"
     if( op2 == Op_AddL && in1->in(2) == in2->in(1) ) {
       assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal");
-      return new (phase->C, 3) AddLNode(in1->in(1), in2->in(2));
+      return new (phase->C) AddLNode(in1->in(1), in2->in(2));
     }
     // Convert "(a-b)+(c+b)" into "(a+c)"
     if( op2 == Op_AddL && in1->in(2) == in2->in(2) ) {
       assert(in1->in(1) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal");
-      return new (phase->C, 3) AddLNode(in1->in(1), in2->in(1));
+      return new (phase->C) AddLNode(in1->in(1), in2->in(1));
     }
     // Convert "(a-b)+(b-c)" into "(a-c)"
     if( op2 == Op_SubL && in1->in(2) == in2->in(1) ) {
       assert(in1->in(1) != this && in2->in(2) != this,"dead loop in AddLNode::Ideal");
-      return new (phase->C, 3) SubLNode(in1->in(1), in2->in(2));
+      return new (phase->C) SubLNode(in1->in(1), in2->in(2));
     }
     // Convert "(a-b)+(c-a)" into "(c-b)"
     if( op2 == Op_SubL && in1->in(1) == in1->in(2) ) {
       assert(in1->in(2) != this && in2->in(1) != this,"dead loop in AddLNode::Ideal");
-      return new (phase->C, 3) SubLNode(in2->in(1), in1->in(2));
+      return new (phase->C) SubLNode(in2->in(1), in1->in(2));
     }
   }
 
   // Convert "x+(0-y)" into "(x-y)"
   if( op2 == Op_SubL && phase->type(in2->in(1)) == TypeLong::ZERO )
-    return new (phase->C, 3) SubLNode( in1, in2->in(2) );
+    return new (phase->C) SubLNode( in1, in2->in(2) );
 
   // Convert "(0-y)+x" into "(x-y)"
   if( op1 == Op_SubL && phase->type(in1->in(1)) == TypeInt::ZERO )
-    return new (phase->C, 3) SubLNode( in2, in1->in(2) );
+    return new (phase->C) SubLNode( in2, in1->in(2) );
 
   // Convert "X+X+X+X+X...+X+Y" into "k*X+Y" or really convert "X+(X+Y)"
   // into "(X<<1)+Y" and let shift-folding happen.
@@ -429,8 +429,8 @@
       in2->in(1) == in1 &&
       op1 != Op_ConL &&
       0 ) {
-    Node *shift = phase->transform(new (phase->C, 3) LShiftLNode(in1,phase->intcon(1)));
-    return new (phase->C, 3) AddLNode(shift,in2->in(2));
+    Node *shift = phase->transform(new (phase->C) LShiftLNode(in1,phase->intcon(1)));
+    return new (phase->C) AddLNode(shift,in2->in(2));
   }
 
   return AddNode::Ideal(phase, can_reshape);
@@ -590,7 +590,7 @@
         offset  = phase->MakeConX(t2->get_con() + t12->get_con());
       } else {
         // Else move the constant to the right.  ((A+con)+B) into ((A+B)+con)
-        address = phase->transform(new (phase->C, 4) AddPNode(in(Base),addp->in(Address),in(Offset)));
+        address = phase->transform(new (phase->C) AddPNode(in(Base),addp->in(Address),in(Offset)));
         offset  = addp->in(Offset);
       }
       PhaseIterGVN *igvn = phase->is_IterGVN();
@@ -610,7 +610,7 @@
     // If this is a NULL+long form (from unsafe accesses), switch to a rawptr.
     if (phase->type(in(Address)) == TypePtr::NULL_PTR) {
       Node* offset = in(Offset);
-      return new (phase->C, 2) CastX2PNode(offset);
+      return new (phase->C) CastX2PNode(offset);
     }
   }
 
@@ -622,7 +622,7 @@
   if( add->Opcode() == Op_AddX && add->in(1) != add ) {
     const Type *t22 = phase->type( add->in(2) );
     if( t22->singleton() && (t22 != Type::TOP) ) {  // Right input is an add of a constant?
-      set_req(Address, phase->transform(new (phase->C, 4) AddPNode(in(Base),in(Address),add->in(1))));
+      set_req(Address, phase->transform(new (phase->C) AddPNode(in(Base),in(Address),add->in(1))));
       set_req(Offset, add->in(2));
       return this;              // Made progress
     }
@@ -847,7 +847,7 @@
   // to force a right-spline graph for the rest of MinINode::Ideal().
   if( l->Opcode() == Op_MinI ) {
     assert( l != l->in(1), "dead loop in MinINode::Ideal" );
-    r = phase->transform(new (phase->C, 3) MinINode(l->in(2),r));
+    r = phase->transform(new (phase->C) MinINode(l->in(2),r));
     l = l->in(1);
     set_req(1, l);
     set_req(2, r);
@@ -895,18 +895,18 @@
     }
 
     if( x->_idx > y->_idx )
-      return new (phase->C, 3) MinINode(r->in(1),phase->transform(new (phase->C, 3) MinINode(l,r->in(2))));
+      return new (phase->C) MinINode(r->in(1),phase->transform(new (phase->C) MinINode(l,r->in(2))));
 
     // See if covers: MIN2(x+c0,MIN2(y+c1,z))
     if( !phase->eqv(x,y) ) return NULL;
     // If (y == x) transform MIN2(x+c0, MIN2(x+c1,z)) into
     // MIN2(x+c0 or x+c1 which less, z).
-    return new (phase->C, 3) MinINode(phase->transform(new (phase->C, 3) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2));
+    return new (phase->C) MinINode(phase->transform(new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)))),r->in(2));
   } else {
     // See if covers: MIN2(x+c0,y+c1)
     if( !phase->eqv(x,y) ) return NULL;
     // If (y == x) transform MIN2(x+c0,x+c1) into x+c0 or x+c1 which less.
-    return new (phase->C, 3) AddINode(x,phase->intcon(MIN2(x_off,y_off)));
+    return new (phase->C) AddINode(x,phase->intcon(MIN2(x_off,y_off)));
   }
 
 }
diff --git a/hotspot/src/share/vm/opto/block.cpp b/hotspot/src/share/vm/opto/block.cpp
index 3e6b7bf..60b0aa9 100644
--- a/hotspot/src/share/vm/opto/block.cpp
+++ b/hotspot/src/share/vm/opto/block.cpp
@@ -378,7 +378,7 @@
   // I'll need a few machine-specific GotoNodes.  Make an Ideal GotoNode,
   // then Match it into a machine-specific Node.  Then clone the machine
   // Node on demand.
-  Node *x = new (C, 1) GotoNode(NULL);
+  Node *x = new (C) GotoNode(NULL);
   x->init_req(0, x);
   _goto = m.match_tree(x);
   assert(_goto != NULL, "");
@@ -432,7 +432,7 @@
                !p->is_block_start() );
       // Make the block begin with one of Region or StartNode.
       if( !p->is_block_start() ) {
-        RegionNode *r = new (C, 2) RegionNode( 2 );
+        RegionNode *r = new (C) RegionNode( 2 );
         r->init_req(1, p);         // Insert RegionNode in the way
         proj->set_req(0, r);        // Insert RegionNode in the way
         p = r;
@@ -508,7 +508,7 @@
   // get ProjNode corresponding to the succ_no'th successor of the in block
   ProjNode* proj = in->_nodes[in->_nodes.size() - in->_num_succs + succ_no]->as_Proj();
   // create region for basic block
-  RegionNode* region = new (C, 2) RegionNode(2);
+  RegionNode* region = new (C) RegionNode(2);
   region->init_req(1, proj);
   // setup corresponding basic block
   Block* block = new (_bbs._arena) Block(_bbs._arena, region);
diff --git a/hotspot/src/share/vm/opto/bytecodeInfo.cpp b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
index 7175427..a357cce 100644
--- a/hotspot/src/share/vm/opto/bytecodeInfo.cpp
+++ b/hotspot/src/share/vm/opto/bytecodeInfo.cpp
@@ -93,7 +93,7 @@
          );
 }
 
-// positive filter: should send be inlined?  returns NULL, if yes, or rejection msg
+// positive filter: should callee be inlined?  returns NULL, if yes, or rejection msg
 const char* InlineTree::should_inline(ciMethod* callee_method, ciMethod* caller_method, int caller_bci, ciCallProfile& profile, WarmCallInfo* wci_result) const {
   // Allows targeted inlining
   if(callee_method->should_inline()) {
@@ -131,33 +131,6 @@
   int call_site_count  = method()->scale_count(profile.count());
   int invoke_count     = method()->interpreter_invocation_count();
 
-  // Bytecoded method handle adapters do not have interpreter
-  // profiling data but only made up MDO data.  Get the counter from
-  // there.
-  if (caller_method->is_method_handle_adapter()) {
-    assert(method()->method_data_or_null(), "must have an MDO");
-    ciMethodData* mdo = method()->method_data();
-    ciProfileData* mha_profile = mdo->bci_to_data(caller_bci);
-    assert(mha_profile, "must exist");
-    CounterData* cd = mha_profile->as_CounterData();
-    invoke_count = cd->count();
-    if (invoke_count == 0) {
-      return "method handle not reached";
-    }
-
-    if (_caller_jvms != NULL && _caller_jvms->method() != NULL &&
-        _caller_jvms->method()->method_data() != NULL &&
-        !_caller_jvms->method()->method_data()->is_empty()) {
-      ciMethodData* mdo = _caller_jvms->method()->method_data();
-      ciProfileData* mha_profile = mdo->bci_to_data(_caller_jvms->bci());
-      assert(mha_profile, "must exist");
-      CounterData* cd = mha_profile->as_CounterData();
-      call_site_count = cd->count();
-    } else {
-      call_site_count = invoke_count;  // use the same value
-    }
-  }
-
   assert(invoke_count != 0, "require invocation count greater than zero");
   int freq = call_site_count / invoke_count;
 
@@ -189,15 +162,16 @@
 }
 
 
-// negative filter: should send NOT be inlined?  returns NULL, ok to inline, or rejection msg
+// negative filter: should callee NOT be inlined?  returns NULL, ok to inline, or rejection msg
 const char* InlineTree::should_not_inline(ciMethod *callee_method, ciMethod* caller_method, WarmCallInfo* wci_result) const {
   // negative filter: should send NOT be inlined?  returns NULL (--> inline) or rejection msg
   if (!UseOldInlining) {
     const char* fail = NULL;
-    if (callee_method->is_abstract())               fail = "abstract method";
+    if ( callee_method->is_abstract())               fail = "abstract method";
     // note: we allow ik->is_abstract()
-    if (!callee_method->holder()->is_initialized()) fail = "method holder not initialized";
-    if (callee_method->is_native())                 fail = "native method";
+    if (!callee_method->holder()->is_initialized())  fail = "method holder not initialized";
+    if ( callee_method->is_native())                 fail = "native method";
+    if ( callee_method->dont_inline())               fail = "don't inline by annotation";
 
     if (fail) {
       *wci_result = *(WarmCallInfo::always_cold());
@@ -217,7 +191,8 @@
       }
     }
 
-    if (callee_method->has_compiled_code() && callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode) {
+    if (callee_method->has_compiled_code() &&
+        callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode) {
       wci_result->set_profit(wci_result->profit() * 0.1);
       // %%% adjust wci_result->size()?
     }
@@ -225,26 +200,25 @@
     return NULL;
   }
 
-  // Always inline MethodHandle methods and generated MethodHandle adapters.
-  if (callee_method->is_method_handle_invoke() || callee_method->is_method_handle_adapter())
-    return NULL;
-
   // First check all inlining restrictions which are required for correctness
-  if (callee_method->is_abstract())               return "abstract method";
+  if ( callee_method->is_abstract())                        return "abstract method";
   // note: we allow ik->is_abstract()
-  if (!callee_method->holder()->is_initialized()) return "method holder not initialized";
-  if (callee_method->is_native())                 return "native method";
-  if (callee_method->has_unloaded_classes_in_signature()) return "unloaded signature classes";
+  if (!callee_method->holder()->is_initialized())           return "method holder not initialized";
+  if ( callee_method->is_native())                          return "native method";
+  if ( callee_method->dont_inline())                        return "don't inline by annotation";
+  if ( callee_method->has_unloaded_classes_in_signature())  return "unloaded signature classes";
 
-  if (callee_method->should_inline()) {
+  if (callee_method->force_inline() || callee_method->should_inline()) {
     // ignore heuristic controls on inlining
     return NULL;
   }
 
   // Now perform checks which are heuristic
 
-  if( callee_method->has_compiled_code() && callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode )
+  if (callee_method->has_compiled_code() &&
+      callee_method->instructions_size(CompLevel_full_optimization) > InlineSmallCode) {
     return "already compiled into a big method";
+  }
 
   // don't inline exception code unless the top method belongs to an
   // exception class
@@ -257,8 +231,20 @@
       return "exception method";
   }
 
+  if (callee_method->should_not_inline()) {
+    return "disallowed by CompilerOracle";
+  }
+
+  if (UseStringCache) {
+    // Do not inline StringCache::profile() method used only at the beginning.
+    if (callee_method->name() == ciSymbol::profile_name() &&
+        callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
+      return "profiling method";
+    }
+  }
+
   // use frequency-based objections only for non-trivial methods
-  if (callee_method->code_size_for_inlining() <= MaxTrivialSize) return NULL;
+  if (callee_method->code_size() <= MaxTrivialSize) return NULL;
 
   // don't use counts with -Xcomp or CTW
   if (UseInterpreter && !CompileTheWorld) {
@@ -278,18 +264,6 @@
     }
   }
 
-  if (callee_method->should_not_inline()) {
-    return "disallowed by CompilerOracle";
-  }
-
-  if (UseStringCache) {
-    // Do not inline StringCache::profile() method used only at the beginning.
-    if (callee_method->name() == ciSymbol::profile_name() &&
-        callee_method->holder()->name() == ciSymbol::java_lang_StringCache()) {
-      return "profiling method";
-    }
-  }
-
   return NULL;
 }
 
@@ -319,7 +293,7 @@
   }
 
   // suppress a few checks for accessors and trivial methods
-  if (callee_method->code_size_for_inlining() > MaxTrivialSize) {
+  if (callee_method->code_size() > MaxTrivialSize) {
 
     // don't inline into giant methods
     if (C->unique() > (uint)NodeCountInliningCutoff) {
@@ -346,7 +320,7 @@
   }
 
   // detect direct and indirect recursive inlining
-  {
+  if (!callee_method->is_compiled_lambda_form()) {
     // count the current method and the callee
     int inline_level = (method() == callee_method) ? 1 : 0;
     if (inline_level > MaxRecursiveInlineLevel)
@@ -412,6 +386,7 @@
 const char* InlineTree::check_can_parse(ciMethod* callee) {
   // Certain methods cannot be parsed at all:
   if ( callee->is_native())                     return "native method";
+  if ( callee->is_abstract())                   return "abstract method";
   if (!callee->can_be_compiled())               return "not compilable (disabled)";
   if (!callee->has_balanced_monitors())         return "not compilable (unbalanced monitors)";
   if ( callee->get_flow_analysis()->failing())  return "not compilable (flow analysis failed)";
@@ -426,7 +401,7 @@
   if (Verbose && callee_method) {
     const InlineTree *top = this;
     while( top->caller_tree() != NULL ) { top = top->caller_tree(); }
-    tty->print("  bcs: %d+%d  invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
+    //tty->print("  bcs: %d+%d  invoked: %d", top->count_inline_bcs(), callee_method->code_size(), callee_method->interpreter_invocation_count());
   }
 }
 
@@ -449,10 +424,7 @@
 
   // Do some initial checks.
   if (!pass_initial_checks(caller_method, caller_bci, callee_method)) {
-    if (PrintInlining) {
-      failure_msg = "failed_initial_checks";
-      print_inlining(callee_method, caller_bci, failure_msg);
-    }
+    if (PrintInlining)  print_inlining(callee_method, caller_bci, "failed initial checks");
     return NULL;
   }
 
@@ -467,9 +439,7 @@
   WarmCallInfo wci = *(initial_wci);
   failure_msg = try_to_inline(callee_method, caller_method, caller_bci, profile, &wci);
   if (failure_msg != NULL && C->log() != NULL) {
-    C->log()->begin_elem("inline_fail reason='");
-    C->log()->text("%s", failure_msg);
-    C->log()->end_elem("'");
+    C->log()->inline_fail(failure_msg);
   }
 
 #ifndef PRODUCT
@@ -539,9 +509,10 @@
   }
   int max_inline_level_adjust = 0;
   if (caller_jvms->method() != NULL) {
-    if (caller_jvms->method()->is_method_handle_adapter())
+    if (caller_jvms->method()->is_compiled_lambda_form())
       max_inline_level_adjust += 1;  // don't count actions in MH or indy adapter frames
-    else if (callee_method->is_method_handle_invoke()) {
+    else if (callee_method->is_method_handle_intrinsic() ||
+             callee_method->is_compiled_lambda_form()) {
       max_inline_level_adjust += 1;  // don't count method handle calls from java.lang.invoke implem
     }
     if (max_inline_level_adjust != 0 && PrintInlining && (Verbose || WizardMode)) {
@@ -590,7 +561,7 @@
 // Given a jvms, which determines a call chain from the root method,
 // find the corresponding inline tree.
 // Note: This method will be removed or replaced as InlineTree goes away.
-InlineTree* InlineTree::find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found) {
+InlineTree* InlineTree::find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee) {
   InlineTree* iltp = root;
   uint depth = jvms && jvms->has_method() ? jvms->depth() : 0;
   for (uint d = 1; d <= depth; d++) {
@@ -599,12 +570,12 @@
     assert(jvmsp->method() == iltp->method(), "tree still in sync");
     ciMethod* d_callee = (d == depth) ? callee : jvms->of_depth(d+1)->method();
     InlineTree* sub = iltp->callee_at(jvmsp->bci(), d_callee);
-    if (!sub) {
-      if (create_if_not_found && d == depth) {
-        return iltp->build_inline_tree_for_callee(d_callee, jvmsp, jvmsp->bci());
+    if (sub == NULL) {
+      if (d == depth) {
+        sub = iltp->build_inline_tree_for_callee(d_callee, jvmsp, jvmsp->bci());
       }
-      assert(sub != NULL, "should be a sub-ilt here");
-      return NULL;
+      guarantee(sub != NULL, "should be a sub-ilt here");
+      return sub;
     }
     iltp = sub;
   }
diff --git a/hotspot/src/share/vm/opto/c2_globals.hpp b/hotspot/src/share/vm/opto/c2_globals.hpp
index f73dcbd..4fdebf5 100644
--- a/hotspot/src/share/vm/opto/c2_globals.hpp
+++ b/hotspot/src/share/vm/opto/c2_globals.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -81,6 +81,13 @@
   product(intx, MaxLoopPad, (OptoLoopAlignment-1),                          \
           "Align a loop if padding size in bytes is less or equal to this value") \
                                                                             \
+  product(intx, MaxVectorSize, 32,                                          \
+          "Max vector size in bytes, "                                      \
+          "actual size could be less depending on elements type")           \
+                                                                            \
+  product(bool, AlignVector, true,                                          \
+          "Perform vector store/load alignment in loop")                    \
+                                                                            \
   product(intx, NumberOfLoopInstrToAlign, 4,                                \
           "Number of first instructions in a loop to align")                \
                                                                             \
@@ -292,9 +299,12 @@
   develop(bool, SuperWordRTDepCheck, false,                                 \
           "Enable runtime dependency checks.")                              \
                                                                             \
-  product(bool, TraceSuperWord, false,                                      \
+  notproduct(bool, TraceSuperWord, false,                                   \
           "Trace superword transforms")                                     \
                                                                             \
+  notproduct(bool, TraceNewVectors, false,                                  \
+          "Trace creation of Vector nodes")                                 \
+                                                                            \
   product_pd(bool, OptoBundling,                                            \
           "Generate nops to fill i-cache lines")                            \
                                                                             \
@@ -343,27 +353,9 @@
   develop(bool, StressRecompilation, false,                                 \
           "Recompile each compiled method without subsuming loads or escape analysis.") \
                                                                             \
-  /* controls for tier 1 compilations */                                    \
-                                                                            \
-  develop(bool, Tier1CountInvocations, true,                                \
-          "Generate code, during tier 1, to update invocation counter")     \
-                                                                            \
-  product(intx, Tier1Inline, false,                                         \
-          "enable inlining during tier 1")                                  \
-                                                                            \
-  product(intx, Tier1MaxInlineSize, 8,                                      \
-          "maximum bytecode size of a method to be inlined, during tier 1") \
-                                                                            \
-  product(intx, Tier1FreqInlineSize, 35,                                    \
-          "max bytecode size of a frequent method to be inlined, tier 1")   \
-                                                                            \
   develop(intx, ImplicitNullCheckThreshold, 3,                              \
           "Don't do implicit null checks if NPE's in a method exceeds limit") \
                                                                             \
- /* controls for loop optimization */                                       \
-  product(intx, Tier1LoopOptsCount, 0,                                      \
-          "Set level of loop optimization for tier 1 compiles")             \
-                                                                            \
   product(intx, LoopOptsCount, 43,                                          \
           "Set level of loop optimization for tier 1 compiles")             \
                                                                             \
@@ -447,6 +439,9 @@
   product(bool, DoEscapeAnalysis, true,                                     \
           "Perform escape analysis")                                        \
                                                                             \
+  develop(bool, ExitEscapeAnalysisOnTimeout, true,                          \
+          "Exit or throw assert in EA when it reaches time limit")          \
+                                                                            \
   notproduct(bool, PrintEscapeAnalysis, false,                              \
           "Print the results of escape analysis")                           \
                                                                             \
@@ -465,6 +460,9 @@
   notproduct(bool, PrintOptimizePtrCompare, false,                          \
           "Print information about optimized pointers compare")             \
                                                                             \
+  notproduct(bool, VerifyConnectionGraph , true,                            \
+          "Verify Connection Graph construction in Escape Analysis")        \
+                                                                            \
   product(bool, UseOptoBiasInlining, true,                                  \
           "Generate biased locking code in C2 ideal graph")                 \
                                                                             \
@@ -492,6 +490,116 @@
                                                                             \
   product(bool, BlockLayoutRotateLoops, true,                               \
           "Allow back branches to be fall throughs in the block layour")    \
+                                                                            \
+  develop(bool, InlineReflectionGetCallerClass, true,                       \
+          "inline sun.reflect.Reflection.getCallerClass(), known to be part "\
+          "of base library DLL")                                            \
+                                                                            \
+  develop(bool, InlineObjectCopy, true,                                     \
+          "inline Object.clone and Arrays.copyOf[Range] intrinsics")        \
+                                                                            \
+  develop(bool, SpecialStringCompareTo, true,                               \
+          "special version of string compareTo")                            \
+                                                                            \
+  develop(bool, SpecialStringIndexOf, true,                                 \
+          "special version of string indexOf")                              \
+                                                                            \
+  develop(bool, SpecialStringEquals, true,                                  \
+          "special version of string equals")                               \
+                                                                            \
+  develop(bool, SpecialArraysEquals, true,                                  \
+          "special version of Arrays.equals(char[],char[])")                \
+                                                                            \
+  develop(bool, BailoutToInterpreterForThrows, false,                       \
+          "Compiled methods which throws/catches exceptions will be "       \
+          "deopt and intp.")                                                \
+                                                                            \
+  develop(bool, ConvertCmpD2CmpF, true,                                     \
+          "Convert cmpD to cmpF when one input is constant in float range") \
+                                                                            \
+  develop(bool, ConvertFloat2IntClipping, true,                             \
+          "Convert float2int clipping idiom to integer clipping")           \
+                                                                            \
+  develop(bool, Use24BitFPMode, true,                                       \
+          "Set 24-bit FPU mode on a per-compile basis ")                    \
+                                                                            \
+  develop(bool, Use24BitFP, true,                                           \
+          "use FP instructions that produce 24-bit precise results")        \
+                                                                            \
+  develop(bool, MonomorphicArrayCheck, true,                                \
+          "Uncommon-trap array store checks that require full type check")  \
+                                                                            \
+  notproduct(bool, TracePhaseCCP, false,                                    \
+          "Print progress during Conditional Constant Propagation")         \
+                                                                            \
+  develop(bool, PrintDominators, false,                                     \
+          "Print out dominator trees for GVN")                              \
+                                                                            \
+  notproduct(bool, TraceSpilling, false,                                    \
+          "Trace spilling")                                                 \
+                                                                            \
+  diagnostic(bool, TraceTypeProfile, false,                                 \
+          "Trace type profile")                                             \
+                                                                            \
+  develop(bool, PoisonOSREntry, true,                                       \
+           "Detect abnormal calls to OSR code")                             \
+                                                                            \
+  product(bool, UseCondCardMark, false,                                     \
+          "Check for already marked card before updating card table")       \
+                                                                            \
+  develop(bool, SoftMatchFailure, trueInProduct,                            \
+          "If the DFA fails to match a node, print a message and bail out") \
+                                                                            \
+  develop(bool, InlineAccessors, true,                                      \
+          "inline accessor methods (get/set)")                              \
+                                                                            \
+  product(intx, TypeProfileMajorReceiverPercent, 90,                        \
+          "% of major receiver type to all profiled receivers")             \
+                                                                            \
+  notproduct(bool, TimeCompiler2, false,                                    \
+          "detailed time the compiler (requires +TimeCompiler)")            \
+                                                                            \
+  diagnostic(bool, PrintIntrinsics, false,                                  \
+          "prints attempted and successful inlining of intrinsics")         \
+                                                                            \
+  diagnostic(ccstrlist, DisableIntrinsic, "",                               \
+          "do not expand intrinsics whose (internal) names appear here")    \
+                                                                            \
+  develop(bool, StressReflectiveCode, false,                                \
+          "Use inexact types at allocations, etc., to test reflection")     \
+                                                                            \
+  diagnostic(bool, DebugInlinedCalls, true,                                 \
+         "If false, restricts profiled locations to the root method only")  \
+                                                                            \
+  notproduct(bool, VerifyLoopOptimizations, false,                          \
+          "verify major loop optimizations")                                \
+                                                                            \
+  diagnostic(bool, ProfileDynamicTypes, true,                               \
+          "do extra type profiling and use it more aggressively")           \
+                                                                            \
+  develop(bool, TraceIterativeGVN, false,                                   \
+          "Print progress during Iterative Global Value Numbering")         \
+                                                                            \
+  develop(bool, VerifyIterativeGVN, false,                                  \
+          "Verify Def-Use modifications during sparse Iterative Global "    \
+          "Value Numbering")                                                \
+                                                                            \
+  notproduct(bool, TraceCISCSpill, false,                                   \
+          "Trace allocators use of cisc spillable instructions")            \
+                                                                            \
+  product(bool, SplitIfBlocks, true,                                        \
+          "Clone compares and control flow through merge points to fold "   \
+          "some branches")                                                  \
+                                                                            \
+  develop(intx, FreqCountInvocations,  1,                                   \
+          "Scaling factor for branch frequencies (deprecated)")             \
+                                                                            \
+  product(intx, AliasLevel,     3,                                          \
+          "0 for no aliasing, 1 for oop/field/static/array split, "         \
+          "2 for class split, 3 for unique instances")                      \
+                                                                            \
+  develop(bool, VerifyAliases, false,                                       \
+          "perform extra checks on the results of alias analysis")          \
 
 C2_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
 
diff --git a/hotspot/src/share/vm/opto/callGenerator.cpp b/hotspot/src/share/vm/opto/callGenerator.cpp
index c4f9ae1..4346273 100644
--- a/hotspot/src/share/vm/opto/callGenerator.cpp
+++ b/hotspot/src/share/vm/opto/callGenerator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,7 @@
 #include "ci/bcEscapeAnalyzer.hpp"
 #include "ci/ciCallSite.hpp"
 #include "ci/ciCPCache.hpp"
+#include "ci/ciMemberName.hpp"
 #include "ci/ciMethodHandle.hpp"
 #include "classfile/javaClasses.hpp"
 #include "compiler/compileLog.hpp"
@@ -39,9 +40,6 @@
 #include "opto/runtime.hpp"
 #include "opto/subnode.hpp"
 
-CallGenerator::CallGenerator(ciMethod* method) {
-  _method = method;
-}
 
 // Utility function.
 const TypeFunc* CallGenerator::tf() const {
@@ -136,7 +134,8 @@
     kit.C->log()->elem("direct_call bci='%d'", jvms->bci());
   }
 
-  CallStaticJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), target, method(), kit.bci());
+  CallStaticJavaNode *call = new (kit.C) CallStaticJavaNode(tf(), target, method(), kit.bci());
+  _call_node = call;  // Save the call node in case we need it later
   if (!is_static) {
     // Make an explicit receiver null_check as part of this call.
     // Since we share a map with the caller, his JVMS gets adjusted.
@@ -147,7 +146,8 @@
     }
     // Mark the call node as virtual, sort of:
     call->set_optimized_virtual(true);
-    if (method()->is_method_handle_invoke()) {
+    if (method()->is_method_handle_intrinsic() ||
+        method()->is_compiled_lambda_form()) {
       call->set_method_handle_invoke(true);
     }
   }
@@ -155,75 +155,6 @@
   kit.set_edges_for_java_call(call, false, _separate_io_proj);
   Node* ret = kit.set_results_for_java_call(call, _separate_io_proj);
   kit.push_node(method()->return_type()->basic_type(), ret);
-  _call_node = call;  // Save the call node in case we need it later
-  return kit.transfer_exceptions_into_jvms();
-}
-
-//---------------------------DynamicCallGenerator-----------------------------
-// Internal class which handles all out-of-line invokedynamic calls.
-class DynamicCallGenerator : public CallGenerator {
-public:
-  DynamicCallGenerator(ciMethod* method)
-    : CallGenerator(method)
-  {
-  }
-  virtual JVMState* generate(JVMState* jvms);
-};
-
-JVMState* DynamicCallGenerator::generate(JVMState* jvms) {
-  GraphKit kit(jvms);
-  Compile* C = kit.C;
-  PhaseGVN& gvn = kit.gvn();
-
-  if (C->log() != NULL) {
-    C->log()->elem("dynamic_call bci='%d'", jvms->bci());
-  }
-
-  // Get the constant pool cache from the caller class.
-  ciMethod* caller_method = jvms->method();
-  ciBytecodeStream str(caller_method);
-  str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
-  assert(str.cur_bc() == Bytecodes::_invokedynamic, "wrong place to issue a dynamic call!");
-  ciCPCache* cpcache = str.get_cpcache();
-
-  // Get the offset of the CallSite from the constant pool cache
-  // pointer.
-  int index = str.get_method_index();
-  size_t call_site_offset = cpcache->get_f1_offset(index);
-
-  // Load the CallSite object from the constant pool cache.
-  const TypeOopPtr* cpcache_type   = TypeOopPtr::make_from_constant(cpcache);  // returns TypeAryPtr of type T_OBJECT
-  const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
-  Node* cpcache_adr   = kit.makecon(cpcache_type);
-  Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset);
-  // The oops in the constant pool cache are not compressed; load then as raw pointers.
-  Node* call_site     = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw);
-
-  // Load the target MethodHandle from the CallSite object.
-  const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass());
-  Node* target_mh_adr = kit.basic_plus_adr(call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
-  Node* target_mh     = kit.make_load(kit.control(), target_mh_adr, target_type, T_OBJECT);
-
-  address resolve_stub = SharedRuntime::get_resolve_opt_virtual_call_stub();
-
-  CallStaticJavaNode* call = new (C, tf()->domain()->cnt()) CallStaticJavaNode(tf(), resolve_stub, method(), kit.bci());
-  // invokedynamic is treated as an optimized invokevirtual.
-  call->set_optimized_virtual(true);
-  // Take extra care (in the presence of argument motion) not to trash the SP:
-  call->set_method_handle_invoke(true);
-
-  // Pass the target MethodHandle as first argument and shift the
-  // other arguments.
-  call->init_req(0 + TypeFunc::Parms, target_mh);
-  uint nargs = call->method()->arg_size();
-  for (uint i = 1; i < nargs; i++) {
-    Node* arg = kit.argument(i - 1);
-    call->init_req(i + TypeFunc::Parms, arg);
-  }
-
-  kit.set_edges_for_java_call(call);
-  Node* ret = kit.set_results_for_java_call(call);
-  kit.push_node(method()->return_type()->basic_type(), ret);
   return kit.transfer_exceptions_into_jvms();
 }
 
@@ -290,7 +221,7 @@
          "no vtable calls if +UseInlineCaches ");
   address target = SharedRuntime::get_resolve_virtual_call_stub();
   // Normal inline cache used for call
-  CallDynamicJavaNode *call = new (kit.C, tf()->domain()->cnt()) CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci());
+  CallDynamicJavaNode *call = new (kit.C) CallDynamicJavaNode(tf(), target, method(), _vtable_index, kit.bci());
   kit.set_arguments_for_java_call(call);
   kit.set_edges_for_java_call(call);
   Node* ret = kit.set_results_for_java_call(call);
@@ -325,15 +256,10 @@
 
 CallGenerator* CallGenerator::for_virtual_call(ciMethod* m, int vtable_index) {
   assert(!m->is_static(), "for_virtual_call mismatch");
-  assert(!m->is_method_handle_invoke(), "should be a direct call");
+  assert(!m->is_method_handle_intrinsic(), "should be a direct call");
   return new VirtualCallGenerator(m, vtable_index);
 }
 
-CallGenerator* CallGenerator::for_dynamic_call(ciMethod* m) {
-  assert(m->is_method_handle_invoke() || m->is_method_handle_adapter(), "for_dynamic_call mismatch");
-  return new DynamicCallGenerator(m);
-}
-
 // Allow inlining decisions to be delayed
 class LateInlineCallGenerator : public DirectCallGenerator {
   CallGenerator* _inline_cg;
@@ -347,7 +273,7 @@
   // Convert the CallStaticJava into an inline
   virtual void do_late_inline();
 
-  JVMState* generate(JVMState* jvms) {
+  virtual JVMState* generate(JVMState* jvms) {
     // Record that this call site should be revisited once the main
     // parse is finished.
     Compile::current()->add_late_inline(this);
@@ -374,7 +300,7 @@
   Compile* C = Compile::current();
   JVMState* jvms     = call->jvms()->clone_shallow(C);
   uint size = call->req();
-  SafePointNode* map = new (C, size) SafePointNode(size, jvms);
+  SafePointNode* map = new (C) SafePointNode(size, jvms);
   for (uint i1 = 0; i1 < size; i1++) {
     map->init_req(i1, call->in(i1));
   }
@@ -625,7 +551,7 @@
 
   // Finish the diamond.
   kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
-  RegionNode* region = new (kit.C, 3) RegionNode(3);
+  RegionNode* region = new (kit.C) RegionNode(3);
   region->init_req(1, kit.control());
   region->init_req(2, slow_map->control());
   kit.set_control(gvn.transform(region));
@@ -654,202 +580,146 @@
 }
 
 
-//------------------------PredictedDynamicCallGenerator-----------------------
-// Internal class which handles all out-of-line calls checking receiver type.
-class PredictedDynamicCallGenerator : public CallGenerator {
-  ciMethodHandle* _predicted_method_handle;
-  CallGenerator*  _if_missed;
-  CallGenerator*  _if_hit;
-  float           _hit_prob;
-
-public:
-  PredictedDynamicCallGenerator(ciMethodHandle* predicted_method_handle,
-                                CallGenerator* if_missed,
-                                CallGenerator* if_hit,
-                                float hit_prob)
-    : CallGenerator(if_missed->method()),
-      _predicted_method_handle(predicted_method_handle),
-      _if_missed(if_missed),
-      _if_hit(if_hit),
-      _hit_prob(hit_prob)
-  {}
-
-  virtual bool is_inline()   const { return _if_hit->is_inline(); }
-  virtual bool is_deferred() const { return _if_hit->is_deferred(); }
-
-  virtual JVMState* generate(JVMState* jvms);
-};
-
-
-CallGenerator* CallGenerator::for_predicted_dynamic_call(ciMethodHandle* predicted_method_handle,
-                                                         CallGenerator* if_missed,
-                                                         CallGenerator* if_hit,
-                                                         float hit_prob) {
-  return new PredictedDynamicCallGenerator(predicted_method_handle, if_missed, if_hit, hit_prob);
-}
-
-
-CallGenerator* CallGenerator::for_method_handle_call(Node* method_handle, JVMState* jvms,
-                                                     ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
-  assert(callee->is_method_handle_invoke() || callee->is_method_handle_adapter(), "for_method_handle_call mismatch");
-  CallGenerator* cg = CallGenerator::for_method_handle_inline(method_handle, jvms, caller, callee, profile);
+CallGenerator* CallGenerator::for_method_handle_call(JVMState* jvms, ciMethod* caller, ciMethod* callee) {
+  assert(callee->is_method_handle_intrinsic() ||
+         callee->is_compiled_lambda_form(), "for_method_handle_call mismatch");
+  CallGenerator* cg = CallGenerator::for_method_handle_inline(jvms, caller, callee);
   if (cg != NULL)
     return cg;
   return CallGenerator::for_direct_call(callee);
 }
 
-CallGenerator* CallGenerator::for_method_handle_inline(Node* method_handle, JVMState* jvms,
-                                                       ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
-  if (method_handle->Opcode() == Op_ConP) {
-    const TypeOopPtr* oop_ptr = method_handle->bottom_type()->is_oopptr();
-    ciObject* const_oop = oop_ptr->const_oop();
-    ciMethodHandle* method_handle = const_oop->as_method_handle();
-
-    // Set the callee to have access to the class and signature in
-    // the MethodHandleCompiler.
-    method_handle->set_callee(callee);
-    method_handle->set_caller(caller);
-    method_handle->set_call_profile(profile);
-
-    // Get an adapter for the MethodHandle.
-    ciMethod* target_method = method_handle->get_method_handle_adapter();
-    if (target_method != NULL) {
-      CallGenerator* cg = Compile::current()->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
-      if (cg != NULL && cg->is_inline())
-        return cg;
-    }
-  } else if (method_handle->Opcode() == Op_Phi && method_handle->req() == 3 &&
-             method_handle->in(1)->Opcode() == Op_ConP && method_handle->in(2)->Opcode() == Op_ConP) {
-    float prob = PROB_FAIR;
-    Node* meth_region = method_handle->in(0);
-    if (meth_region->is_Region() &&
-        meth_region->in(1)->is_Proj() && meth_region->in(2)->is_Proj() &&
-        meth_region->in(1)->in(0) == meth_region->in(2)->in(0) &&
-        meth_region->in(1)->in(0)->is_If()) {
-      // If diamond, so grab the probability of the test to drive the inlining below
-      prob = meth_region->in(1)->in(0)->as_If()->_prob;
-      if (meth_region->in(1)->is_IfTrue()) {
-        prob = 1 - prob;
-      }
-    }
-
-    // selectAlternative idiom merging two constant MethodHandles.
-    // Generate a guard so that each can be inlined.  We might want to
-    // do more inputs at later point but this gets the most common
-    // case.
-    CallGenerator* cg1 = for_method_handle_call(method_handle->in(1), jvms, caller, callee, profile.rescale(1.0 - prob));
-    CallGenerator* cg2 = for_method_handle_call(method_handle->in(2), jvms, caller, callee, profile.rescale(prob));
-    if (cg1 != NULL && cg2 != NULL) {
-      const TypeOopPtr* oop_ptr = method_handle->in(1)->bottom_type()->is_oopptr();
-      ciObject* const_oop = oop_ptr->const_oop();
-      ciMethodHandle* mh = const_oop->as_method_handle();
-      return new PredictedDynamicCallGenerator(mh, cg2, cg1, prob);
-    }
-  }
-  return NULL;
-}
-
-CallGenerator* CallGenerator::for_invokedynamic_call(JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
-  assert(callee->is_method_handle_invoke() || callee->is_method_handle_adapter(), "for_invokedynamic_call mismatch");
-  // Get the CallSite object.
-  ciBytecodeStream str(caller);
-  str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
-  ciCallSite* call_site = str.get_call_site();
-  CallGenerator* cg = CallGenerator::for_invokedynamic_inline(call_site, jvms, caller, callee, profile);
-  if (cg != NULL)
-    return cg;
-  return CallGenerator::for_dynamic_call(callee);
-}
-
-CallGenerator* CallGenerator::for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms,
-                                                       ciMethod* caller, ciMethod* callee, ciCallProfile profile) {
-  ciMethodHandle* method_handle = call_site->get_target();
-
-  // Set the callee to have access to the class and signature in the
-  // MethodHandleCompiler.
-  method_handle->set_callee(callee);
-  method_handle->set_caller(caller);
-  method_handle->set_call_profile(profile);
-
-  // Get an adapter for the MethodHandle.
-  ciMethod* target_method = method_handle->get_invokedynamic_adapter();
-  if (target_method != NULL) {
-    Compile *C = Compile::current();
-    CallGenerator* cg = C->call_generator(target_method, -1, false, jvms, true, PROB_ALWAYS);
-    if (cg != NULL && cg->is_inline()) {
-      // Add a dependence for invalidation of the optimization.
-      if (!call_site->is_constant_call_site()) {
-        C->dependencies()->assert_call_site_target_value(call_site, method_handle);
-      }
-      return cg;
-    }
-  }
-  return NULL;
-}
-
-
-JVMState* PredictedDynamicCallGenerator::generate(JVMState* jvms) {
+CallGenerator* CallGenerator::for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee) {
   GraphKit kit(jvms);
+  PhaseGVN& gvn = kit.gvn();
   Compile* C = kit.C;
+  vmIntrinsics::ID iid = callee->intrinsic_id();
+  switch (iid) {
+  case vmIntrinsics::_invokeBasic:
+    {
+      // get MethodHandle receiver
+      Node* receiver = kit.argument(0);
+      if (receiver->Opcode() == Op_ConP) {
+        const TypeOopPtr* oop_ptr = receiver->bottom_type()->is_oopptr();
+        ciMethod* target = oop_ptr->const_oop()->as_method_handle()->get_vmtarget();
+        guarantee(!target->is_method_handle_intrinsic(), "should not happen");  // XXX remove
+        const int vtable_index = methodOopDesc::invalid_vtable_index;
+        CallGenerator* cg = C->call_generator(target, vtable_index, false, jvms, true, PROB_ALWAYS);
+        if (cg != NULL && cg->is_inline())
+          return cg;
+      } else {
+        if (PrintInlining)  CompileTask::print_inlining(callee, jvms->depth() - 1, jvms->bci(), "receiver not constant");
+      }
+    }
+    break;
+
+  case vmIntrinsics::_linkToVirtual:
+  case vmIntrinsics::_linkToStatic:
+  case vmIntrinsics::_linkToSpecial:
+  case vmIntrinsics::_linkToInterface:
+    {
+      // pop MemberName argument
+      Node* member_name = kit.argument(callee->arg_size() - 1);
+      if (member_name->Opcode() == Op_ConP) {
+        const TypeOopPtr* oop_ptr = member_name->bottom_type()->is_oopptr();
+        ciMethod* target = oop_ptr->const_oop()->as_member_name()->get_vmtarget();
+
+        // In lamda forms we erase signature types to avoid resolving issues
+        // involving class loaders.  When we optimize a method handle invoke
+        // to a direct call we must cast the receiver and arguments to its
+        // actual types.
+        ciSignature* signature = target->signature();
+        const int receiver_skip = target->is_static() ? 0 : 1;
+        // Cast receiver to its type.
+        if (!target->is_static()) {
+          Node* arg = kit.argument(0);
+          const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr();
+          const Type*       sig_type = TypeOopPtr::make_from_klass(signature->accessing_klass());
+          if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
+            Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type));
+            kit.set_argument(0, cast_obj);
+          }
+        }
+        // Cast reference arguments to its type.
+        for (int i = 0; i < signature->count(); i++) {
+          ciType* t = signature->type_at(i);
+          if (t->is_klass()) {
+            Node* arg = kit.argument(receiver_skip + i);
+            const TypeOopPtr* arg_type = arg->bottom_type()->isa_oopptr();
+            const Type*       sig_type = TypeOopPtr::make_from_klass(t->as_klass());
+            if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
+              Node* cast_obj = gvn.transform(new (C) CheckCastPPNode(kit.control(), arg, sig_type));
+              kit.set_argument(receiver_skip + i, cast_obj);
+            }
+          }
+        }
+        const int vtable_index = methodOopDesc::invalid_vtable_index;
+        const bool call_is_virtual = target->is_abstract();  // FIXME workaround
+        CallGenerator* cg = C->call_generator(target, vtable_index, call_is_virtual, jvms, true, PROB_ALWAYS);
+        if (cg != NULL && cg->is_inline())
+          return cg;
+      }
+    }
+    break;
+
+  default:
+    fatal(err_msg_res("unexpected intrinsic %d: %s", iid, vmIntrinsics::name_at(iid)));
+    break;
+  }
+  return NULL;
+}
+
+
+//------------------------PredictedIntrinsicGenerator------------------------------
+// Internal class which handles all predicted Intrinsic calls.
+class PredictedIntrinsicGenerator : public CallGenerator {
+  CallGenerator* _intrinsic;
+  CallGenerator* _cg;
+
+public:
+  PredictedIntrinsicGenerator(CallGenerator* intrinsic,
+                              CallGenerator* cg)
+    : CallGenerator(cg->method())
+  {
+    _intrinsic = intrinsic;
+    _cg        = cg;
+  }
+
+  virtual bool      is_virtual()   const    { return true; }
+  virtual bool      is_inlined()   const    { return true; }
+  virtual bool      is_intrinsic() const    { return true; }
+
+  virtual JVMState* generate(JVMState* jvms);
+};
+
+
+CallGenerator* CallGenerator::for_predicted_intrinsic(CallGenerator* intrinsic,
+                                                      CallGenerator* cg) {
+  return new PredictedIntrinsicGenerator(intrinsic, cg);
+}
+
+
+JVMState* PredictedIntrinsicGenerator::generate(JVMState* jvms) {
+  GraphKit kit(jvms);
   PhaseGVN& gvn = kit.gvn();
 
-  CompileLog* log = C->log();
+  CompileLog* log = kit.C->log();
   if (log != NULL) {
-    log->elem("predicted_dynamic_call bci='%d'", jvms->bci());
+    log->elem("predicted_intrinsic bci='%d' method='%d'",
+              jvms->bci(), log->identify(method()));
   }
 
-  const TypeOopPtr* predicted_mh_ptr = TypeOopPtr::make_from_constant(_predicted_method_handle, true);
-  Node* predicted_mh = kit.makecon(predicted_mh_ptr);
-
-  Node* bol = NULL;
-  int bc = jvms->method()->java_code_at_bci(jvms->bci());
-  if (bc != Bytecodes::_invokedynamic) {
-    // This is the selectAlternative idiom for guardWithTest or
-    // similar idioms.
-    Node* receiver = kit.argument(0);
-
-    // Check if the MethodHandle is the expected one
-    Node* cmp = gvn.transform(new (C, 3) CmpPNode(receiver, predicted_mh));
-    bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) );
-  } else {
-    // Get the constant pool cache from the caller class.
-    ciMethod* caller_method = jvms->method();
-    ciBytecodeStream str(caller_method);
-    str.force_bci(jvms->bci());  // Set the stream to the invokedynamic bci.
-    ciCPCache* cpcache = str.get_cpcache();
-
-    // Get the offset of the CallSite from the constant pool cache
-    // pointer.
-    int index = str.get_method_index();
-    size_t call_site_offset = cpcache->get_f1_offset(index);
-
-    // Load the CallSite object from the constant pool cache.
-    const TypeOopPtr* cpcache_type   = TypeOopPtr::make_from_constant(cpcache);  // returns TypeAryPtr of type T_OBJECT
-    const TypeOopPtr* call_site_type = TypeOopPtr::make_from_klass(C->env()->CallSite_klass());
-    Node* cpcache_adr   = kit.makecon(cpcache_type);
-    Node* call_site_adr = kit.basic_plus_adr(cpcache_adr, call_site_offset);
-    // The oops in the constant pool cache are not compressed; load then as raw pointers.
-    Node* call_site     = kit.make_load(kit.control(), call_site_adr, call_site_type, T_ADDRESS, Compile::AliasIdxRaw);
-
-    // Load the target MethodHandle from the CallSite object.
-    const TypeOopPtr* target_type = TypeOopPtr::make_from_klass(C->env()->MethodHandle_klass());
-    Node* target_adr = kit.basic_plus_adr(call_site, call_site, java_lang_invoke_CallSite::target_offset_in_bytes());
-    Node* target_mh  = kit.make_load(kit.control(), target_adr, target_type, T_OBJECT);
-
-    // Check if the MethodHandle is still the same.
-    Node* cmp = gvn.transform(new (C, 3) CmpPNode(target_mh, predicted_mh));
-    bol = gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq) );
-  }
-  IfNode* iff = kit.create_and_xform_if(kit.control(), bol, _hit_prob, COUNT_UNKNOWN);
-  kit.set_control( gvn.transform(new (C, 1) IfTrueNode (iff)));
-  Node* slow_ctl = gvn.transform(new (C, 1) IfFalseNode(iff));
+  Node* slow_ctl = _intrinsic->generate_predicate(kit.sync_jvms());
+  if (kit.failing())
+    return NULL;  // might happen because of NodeCountInliningCutoff
 
   SafePointNode* slow_map = NULL;
   JVMState* slow_jvms;
-  { PreserveJVMState pjvms(&kit);
+  if (slow_ctl != NULL) {
+    PreserveJVMState pjvms(&kit);
     kit.set_control(slow_ctl);
     if (!kit.stopped()) {
-      slow_jvms = _if_missed->generate(kit.sync_jvms());
+      slow_jvms = _cg->generate(kit.sync_jvms());
       if (kit.failing())
         return NULL;  // might happen because of NodeCountInliningCutoff
       assert(slow_jvms != NULL, "must be");
@@ -861,18 +731,22 @@
   }
 
   if (kit.stopped()) {
-    // Instance exactly does not matches the desired type.
+    // Predicate is always false.
     kit.set_jvms(slow_jvms);
     return kit.transfer_exceptions_into_jvms();
   }
 
-  // Make the hot call:
-  JVMState* new_jvms = _if_hit->generate(kit.sync_jvms());
+  // Generate intrinsic code:
+  JVMState* new_jvms = _intrinsic->generate(kit.sync_jvms());
   if (new_jvms == NULL) {
-    // Inline failed, so make a direct call.
-    assert(_if_hit->is_inline(), "must have been a failed inline");
-    CallGenerator* cg = CallGenerator::for_direct_call(_if_hit->method());
-    new_jvms = cg->generate(kit.sync_jvms());
+    // Intrinsic failed, so use slow code or make a direct call.
+    if (slow_map == NULL) {
+      CallGenerator* cg = CallGenerator::for_direct_call(method());
+      new_jvms = cg->generate(kit.sync_jvms());
+    } else {
+      kit.set_jvms(slow_jvms);
+      return kit.transfer_exceptions_into_jvms();
+    }
   }
   kit.add_exception_states_from(new_jvms);
   kit.set_jvms(new_jvms);
@@ -884,14 +758,14 @@
   }
 
   if (kit.stopped()) {
-    // Inlined method threw an exception, so it's just the slow path after all.
+    // Intrinsic method threw an exception, so it's just the slow path after all.
     kit.set_jvms(slow_jvms);
     return kit.transfer_exceptions_into_jvms();
   }
 
   // Finish the diamond.
   kit.C->set_has_split_ifs(true); // Has chance for split-if optimization
-  RegionNode* region = new (C, 3) RegionNode(3);
+  RegionNode* region = new (kit.C) RegionNode(3);
   region->init_req(1, kit.control());
   region->init_req(2, slow_map->control());
   kit.set_control(gvn.transform(region));
@@ -919,7 +793,6 @@
   return kit.transfer_exceptions_into_jvms();
 }
 
-
 //-------------------------UncommonTrapCallGenerator-----------------------------
 // Internal class which handles all out-of-line calls checking receiver type.
 class UncommonTrapCallGenerator : public CallGenerator {
diff --git a/hotspot/src/share/vm/opto/callGenerator.hpp b/hotspot/src/share/vm/opto/callGenerator.hpp
index 6247f7a..9022ff1 100644
--- a/hotspot/src/share/vm/opto/callGenerator.hpp
+++ b/hotspot/src/share/vm/opto/callGenerator.hpp
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_OPTO_CALLGENERATOR_HPP
 #define SHARE_VM_OPTO_CALLGENERATOR_HPP
 
+#include "compiler/compileBroker.hpp"
 #include "opto/callnode.hpp"
 #include "opto/compile.hpp"
 #include "opto/type.hpp"
@@ -44,7 +45,7 @@
   ciMethod*             _method;                // The method being called.
 
  protected:
-  CallGenerator(ciMethod* method);
+  CallGenerator(ciMethod* method) : _method(method) {}
 
  public:
   // Accessors
@@ -111,11 +112,8 @@
   static CallGenerator* for_virtual_call(ciMethod* m, int vtable_index);  // virtual, interface
   static CallGenerator* for_dynamic_call(ciMethod* m);   // invokedynamic
 
-  static CallGenerator* for_method_handle_call(Node* method_handle, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile);
-  static CallGenerator* for_invokedynamic_call(                     JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile);
-
-  static CallGenerator* for_method_handle_inline(Node* method_handle,   JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile);
-  static CallGenerator* for_invokedynamic_inline(ciCallSite* call_site, JVMState* jvms, ciMethod* caller, ciMethod* callee, ciCallProfile profile);
+  static CallGenerator* for_method_handle_call(  JVMState* jvms, ciMethod* caller, ciMethod* callee);
+  static CallGenerator* for_method_handle_inline(JVMState* jvms, ciMethod* caller, ciMethod* callee);
 
   // How to generate a replace a direct call with an inline version
   static CallGenerator* for_late_inline(ciMethod* m, CallGenerator* inline_cg);
@@ -145,13 +143,24 @@
   // Registry for intrinsics:
   static CallGenerator* for_intrinsic(ciMethod* m);
   static void register_intrinsic(ciMethod* m, CallGenerator* cg);
+  static CallGenerator* for_predicted_intrinsic(CallGenerator* intrinsic,
+                                                CallGenerator* cg);
+  virtual Node* generate_predicate(JVMState* jvms) { return NULL; };
+
+  static void print_inlining(ciMethod* callee, int inline_level, int bci, const char* msg) {
+    if (PrintInlining)
+      CompileTask::print_inlining(callee, inline_level, bci, msg);
+  }
 };
 
-class InlineCallGenerator : public CallGenerator {
-  virtual bool      is_inline() const           { return true; }
 
+//------------------------InlineCallGenerator----------------------------------
+class InlineCallGenerator : public CallGenerator {
  protected:
-  InlineCallGenerator(ciMethod* method) : CallGenerator(method) { }
+  InlineCallGenerator(ciMethod* method) : CallGenerator(method) {}
+
+ public:
+  virtual bool      is_inline() const           { return true; }
 };
 
 
diff --git a/hotspot/src/share/vm/opto/callnode.cpp b/hotspot/src/share/vm/opto/callnode.cpp
index 2811264..2429f89 100644
--- a/hotspot/src/share/vm/opto/callnode.cpp
+++ b/hotspot/src/share/vm/opto/callnode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -72,20 +72,20 @@
   case TypeFunc::Control:
   case TypeFunc::I_O:
   case TypeFunc::Memory:
-    return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
+    return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
   case TypeFunc::FramePtr:
-    return new (match->C, 1) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP);
+    return new (match->C) MachProjNode(this,proj->_con,Matcher::c_frame_ptr_mask, Op_RegP);
   case TypeFunc::ReturnAdr:
-    return new (match->C, 1) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP);
+    return new (match->C) MachProjNode(this,proj->_con,match->_return_addr_mask,Op_RegP);
   case TypeFunc::Parms:
   default: {
       uint parm_num = proj->_con - TypeFunc::Parms;
       const Type *t = _domain->field_at(proj->_con);
       if (t->base() == Type::Half)  // 2nd half of Longs and Doubles
-        return new (match->C, 1) ConNode(Type::TOP);
+        return new (match->C) ConNode(Type::TOP);
       uint ideal_reg = Matcher::base2reg[t->base()];
       RegMask &rm = match->_calling_convention_mask[parm_num];
-      return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg);
+      return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg);
     }
   }
   return NULL;
@@ -231,9 +231,9 @@
 }
 
 //=============================================================================
-JVMState::JVMState(ciMethod* method, JVMState* caller) {
+JVMState::JVMState(ciMethod* method, JVMState* caller) :
+  _method(method) {
   assert(method != NULL, "must be valid call site");
-  _method = method;
   _reexecute = Reexecute_Undefined;
   debug_only(_bci = -99);  // random garbage value
   debug_only(_map = (SafePointNode*)-1);
@@ -246,8 +246,8 @@
   _endoff = _monoff;
   _sp = 0;
 }
-JVMState::JVMState(int stack_size) {
-  _method = NULL;
+JVMState::JVMState(int stack_size) :
+  _method(NULL) {
   _bci = InvocationEntryBci;
   _reexecute = Reexecute_Undefined;
   debug_only(_map = (SafePointNode*)-1);
@@ -526,8 +526,8 @@
     }
     _map->dump(2);
   }
-  st->print("JVMS depth=%d loc=%d stk=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d reexecute=%s method=",
-             depth(), locoff(), stkoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci(), should_reexecute()?"true":"false");
+  st->print("JVMS depth=%d loc=%d stk=%d arg=%d mon=%d scalar=%d end=%d mondepth=%d sp=%d bci=%d reexecute=%s method=",
+             depth(), locoff(), stkoff(), argoff(), monoff(), scloff(), endoff(), monitor_depth(), sp(), bci(), should_reexecute()?"true":"false");
   if (_method == NULL) {
     st->print_cr("(none)");
   } else {
@@ -620,12 +620,12 @@
   case TypeFunc::Control:
   case TypeFunc::I_O:
   case TypeFunc::Memory:
-    return new (match->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
+    return new (match->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
 
   case TypeFunc::Parms+1:       // For LONG & DOUBLE returns
     assert(tf()->_range->field_at(TypeFunc::Parms+1) == Type::HALF, "");
     // 2nd half of doubles and longs
-    return new (match->C, 1) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad);
+    return new (match->C) MachProjNode(this,proj->_con, RegMask::Empty, (uint)OptoReg::Bad);
 
   case TypeFunc::Parms: {       // Normal returns
     uint ideal_reg = Matcher::base2reg[tf()->range()->field_at(TypeFunc::Parms)->base()];
@@ -635,7 +635,7 @@
     RegMask rm = RegMask(regs.first());
     if( OptoReg::is_valid(regs.second()) )
       rm.Insert( regs.second() );
-    return new (match->C, 1) MachProjNode(this,proj->_con,rm,ideal_reg);
+    return new (match->C) MachProjNode(this,proj->_con,rm,ideal_reg);
   }
 
   case TypeFunc::ReturnAdr:
@@ -1170,10 +1170,10 @@
         Node* nproj = catchproj->clone();
         igvn->register_new_node_with_optimizer(nproj);
 
-        Node *frame = new (phase->C, 1) ParmNode( phase->C->start(), TypeFunc::FramePtr );
+        Node *frame = new (phase->C) ParmNode( phase->C->start(), TypeFunc::FramePtr );
         frame = phase->transform(frame);
         // Halt & Catch Fire
-        Node *halt = new (phase->C, TypeFunc::Parms) HaltNode( nproj, frame );
+        Node *halt = new (phase->C) HaltNode( nproj, frame );
         phase->C->root()->add_req(halt);
         phase->transform(halt);
 
@@ -1213,7 +1213,7 @@
       if (!allow_new_nodes) return NULL;
       // Create a cast which is control dependent on the initialization to
       // propagate the fact that the array length must be positive.
-      length = new (phase->C, 2) CastIINode(length, narrow_length_type);
+      length = new (phase->C) CastIINode(length, narrow_length_type);
       length->set_req(0, initialization()->proj_out(0));
     }
   }
@@ -1538,10 +1538,7 @@
     // If we are locking an unescaped object, the lock/unlock is unnecessary
     //
     ConnectionGraph *cgr = phase->C->congraph();
-    PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
-    if (cgr != NULL)
-      es = cgr->escape_state(obj_node());
-    if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
+    if (cgr != NULL && cgr->not_global_escape(obj_node())) {
       assert(!is_eliminated() || is_coarsened(), "sanity");
       // The lock could be marked eliminated by lock coarsening
       // code during first IGVN before EA. Replace coarsened flag
@@ -1680,10 +1677,7 @@
     // If we are unlocking an unescaped object, the lock/unlock is unnecessary.
     //
     ConnectionGraph *cgr = phase->C->congraph();
-    PointsToNode::EscapeState es = PointsToNode::GlobalEscape;
-    if (cgr != NULL)
-      es = cgr->escape_state(obj_node());
-    if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
+    if (cgr != NULL && cgr->not_global_escape(obj_node())) {
       assert(!is_eliminated() || is_coarsened(), "sanity");
       // The lock could be marked eliminated by lock coarsening
       // code during first IGVN before EA. Replace coarsened flag
diff --git a/hotspot/src/share/vm/opto/callnode.hpp b/hotspot/src/share/vm/opto/callnode.hpp
index fa9af0c..a412e2b 100644
--- a/hotspot/src/share/vm/opto/callnode.hpp
+++ b/hotspot/src/share/vm/opto/callnode.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -197,7 +197,7 @@
 
 private:
   JVMState*         _caller;    // List pointer for forming scope chains
-  uint              _depth;     // One mroe than caller depth, or one.
+  uint              _depth;     // One more than caller depth, or one.
   uint              _locoff;    // Offset to locals in input edge mapping
   uint              _stkoff;    // Offset to stack in input edge mapping
   uint              _monoff;    // Offset to monitors in input edge mapping
@@ -223,6 +223,8 @@
   JVMState(int stack_size);  // root state; has a null method
 
   // Access functions for the JVM
+  // ... --|--- loc ---|--- stk ---|--- arg ---|--- mon ---|--- scl ---|
+  //       \ locoff    \ stkoff    \ argoff    \ monoff    \ scloff    \ endoff
   uint              locoff() const { return _locoff; }
   uint              stkoff() const { return _stkoff; }
   uint              argoff() const { return _stkoff + _sp; }
@@ -231,15 +233,16 @@
   uint              endoff() const { return _endoff; }
   uint              oopoff() const { return debug_end(); }
 
-  int            loc_size() const { return _stkoff - _locoff; }
-  int            stk_size() const { return _monoff - _stkoff; }
-  int            mon_size() const { return _scloff - _monoff; }
-  int            scl_size() const { return _endoff - _scloff; }
+  int            loc_size() const { return stkoff() - locoff(); }
+  int            stk_size() const { return monoff() - stkoff(); }
+  int            arg_size() const { return monoff() - argoff(); }
+  int            mon_size() const { return scloff() - monoff(); }
+  int            scl_size() const { return endoff() - scloff(); }
 
-  bool        is_loc(uint i) const { return i >= _locoff && i < _stkoff; }
-  bool        is_stk(uint i) const { return i >= _stkoff && i < _monoff; }
-  bool        is_mon(uint i) const { return i >= _monoff && i < _scloff; }
-  bool        is_scl(uint i) const { return i >= _scloff && i < _endoff; }
+  bool        is_loc(uint i) const { return locoff() <= i && i < stkoff(); }
+  bool        is_stk(uint i) const { return stkoff() <= i && i < monoff(); }
+  bool        is_mon(uint i) const { return monoff() <= i && i < scloff(); }
+  bool        is_scl(uint i) const { return scloff() <= i && i < endoff(); }
 
   uint                      sp() const { return _sp; }
   int                      bci() const { return _bci; }
@@ -546,6 +549,12 @@
   // or result projection is there are several CheckCastPP
   // or returns NULL if there is no one.
   Node *result_cast();
+  // Does this node returns pointer?
+  bool returns_pointer() const {
+    const TypeTuple *r = tf()->range();
+    return (r->cnt() > TypeFunc::Parms &&
+            r->field_at(TypeFunc::Parms)->isa_ptr());
+  }
 
   // Collect all the interesting edges from a call for use in
   // replacing the call by something else.  Used by macro expansion
diff --git a/hotspot/src/share/vm/opto/cfgnode.cpp b/hotspot/src/share/vm/opto/cfgnode.cpp
index 4f01e85..41033e5 100644
--- a/hotspot/src/share/vm/opto/cfgnode.cpp
+++ b/hotspot/src/share/vm/opto/cfgnode.cpp
@@ -612,17 +612,17 @@
                 convf2i->in(1) == bot_in ) {
                 // Matched pattern, including LShiftI; RShiftI, replace with integer compares
                 // max test
-                Node *cmp   = gvn->register_new_node_with_optimizer(new (phase->C, 3) CmpINode( convf2i, min ));
-                Node *boo   = gvn->register_new_node_with_optimizer(new (phase->C, 2) BoolNode( cmp, BoolTest::lt ));
-                IfNode *iff = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C, 2) IfNode( top_if->in(0), boo, PROB_UNLIKELY_MAG(5), top_if->_fcnt ));
-                Node *if_min= gvn->register_new_node_with_optimizer(new (phase->C, 1) IfTrueNode (iff));
-                Node *ifF   = gvn->register_new_node_with_optimizer(new (phase->C, 1) IfFalseNode(iff));
+                Node *cmp   = gvn->register_new_node_with_optimizer(new (phase->C) CmpINode( convf2i, min ));
+                Node *boo   = gvn->register_new_node_with_optimizer(new (phase->C) BoolNode( cmp, BoolTest::lt ));
+                IfNode *iff = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C) IfNode( top_if->in(0), boo, PROB_UNLIKELY_MAG(5), top_if->_fcnt ));
+                Node *if_min= gvn->register_new_node_with_optimizer(new (phase->C) IfTrueNode (iff));
+                Node *ifF   = gvn->register_new_node_with_optimizer(new (phase->C) IfFalseNode(iff));
                 // min test
-                cmp         = gvn->register_new_node_with_optimizer(new (phase->C, 3) CmpINode( convf2i, max ));
-                boo         = gvn->register_new_node_with_optimizer(new (phase->C, 2) BoolNode( cmp, BoolTest::gt ));
-                iff         = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C, 2) IfNode( ifF, boo, PROB_UNLIKELY_MAG(5), bot_if->_fcnt ));
-                Node *if_max= gvn->register_new_node_with_optimizer(new (phase->C, 1) IfTrueNode (iff));
-                ifF         = gvn->register_new_node_with_optimizer(new (phase->C, 1) IfFalseNode(iff));
+                cmp         = gvn->register_new_node_with_optimizer(new (phase->C) CmpINode( convf2i, max ));
+                boo         = gvn->register_new_node_with_optimizer(new (phase->C) BoolNode( cmp, BoolTest::gt ));
+                iff         = (IfNode*)gvn->register_new_node_with_optimizer(new (phase->C) IfNode( ifF, boo, PROB_UNLIKELY_MAG(5), bot_if->_fcnt ));
+                Node *if_max= gvn->register_new_node_with_optimizer(new (phase->C) IfTrueNode (iff));
+                ifF         = gvn->register_new_node_with_optimizer(new (phase->C) IfFalseNode(iff));
                 // update input edges to region node
                 set_req_X( min_idx, if_min, gvn );
                 set_req_X( max_idx, if_max, gvn );
@@ -681,7 +681,7 @@
 PhiNode* PhiNode::make(Node* r, Node* x, const Type *t, const TypePtr* at) {
   uint preds = r->req();   // Number of predecessor paths
   assert(t != Type::MEMORY || at == flatten_phi_adr_type(at), "flatten at");
-  PhiNode* p = new (Compile::current(), preds) PhiNode(r, t, at);
+  PhiNode* p = new (Compile::current()) PhiNode(r, t, at);
   for (uint j = 1; j < preds; j++) {
     // Fill in all inputs, except those which the region does not yet have
     if (r->in(j) != NULL)
@@ -699,7 +699,7 @@
   const Type*    t  = x->bottom_type();
   const TypePtr* at = NULL;
   if (t == Type::MEMORY)  at = flatten_phi_adr_type(x->adr_type());
-  return new (Compile::current(), r->req()) PhiNode(r, t, at);
+  return new (Compile::current()) PhiNode(r, t, at);
 }
 
 
@@ -1205,9 +1205,9 @@
   } else return NULL;
 
   // Build int->bool conversion
-  Node *n = new (phase->C, 2) Conv2BNode( cmp->in(1) );
+  Node *n = new (phase->C) Conv2BNode( cmp->in(1) );
   if( flipped )
-    n = new (phase->C, 3) XorINode( phase->transform(n), phase->intcon(1) );
+    n = new (phase->C) XorINode( phase->transform(n), phase->intcon(1) );
 
   return n;
 }
@@ -1266,9 +1266,9 @@
   if( q->is_Con() && phase->type(q) != TypeInt::ZERO && y->is_Con() )
     return NULL;
 
-  Node *cmplt = phase->transform( new (phase->C, 3) CmpLTMaskNode(p,q) );
-  Node *j_and   = phase->transform( new (phase->C, 3) AndINode(cmplt,y) );
-  return new (phase->C, 3) AddINode(j_and,x);
+  Node *cmplt = phase->transform( new (phase->C) CmpLTMaskNode(p,q) );
+  Node *j_and   = phase->transform( new (phase->C) AndINode(cmplt,y) );
+  return new (phase->C) AddINode(j_and,x);
 }
 
 //------------------------------is_absolute------------------------------------
@@ -1330,17 +1330,17 @@
     if( sub->Opcode() != Op_SubF ||
         sub->in(2) != x ||
         phase->type(sub->in(1)) != tzero ) return NULL;
-    x = new (phase->C, 2) AbsFNode(x);
+    x = new (phase->C) AbsFNode(x);
     if (flip) {
-      x = new (phase->C, 3) SubFNode(sub->in(1), phase->transform(x));
+      x = new (phase->C) SubFNode(sub->in(1), phase->transform(x));
     }
   } else {
     if( sub->Opcode() != Op_SubD ||
         sub->in(2) != x ||
         phase->type(sub->in(1)) != tzero ) return NULL;
-    x = new (phase->C, 2) AbsDNode(x);
+    x = new (phase->C) AbsDNode(x);
     if (flip) {
-      x = new (phase->C, 3) SubDNode(sub->in(1), phase->transform(x));
+      x = new (phase->C) SubDNode(sub->in(1), phase->transform(x));
     }
   }
 
@@ -1415,7 +1415,7 @@
   // Now start splitting out the flow paths that merge the same value.
   // Split first the RegionNode.
   PhaseIterGVN *igvn = phase->is_IterGVN();
-  RegionNode *newr = new (phase->C, hit+1) RegionNode(hit+1);
+  RegionNode *newr = new (phase->C) RegionNode(hit+1);
   split_once(igvn, phi, val, r, newr);
 
   // Now split all other Phis than this one
@@ -1723,13 +1723,13 @@
       }
       if (doit) {
         if (base == NULL) {
-          base = new (phase->C, in(0)->req()) PhiNode(in(0), type, NULL);
+          base = new (phase->C) PhiNode(in(0), type, NULL);
           for (uint i = 1; i < req(); i++) {
             base->init_req(i, in(i)->in(AddPNode::Base));
           }
           phase->is_IterGVN()->register_new_node_with_optimizer(base);
         }
-        return new (phase->C, 4) AddPNode(base, base, y);
+        return new (phase->C) AddPNode(base, base, y);
       }
     }
   }
@@ -1806,7 +1806,7 @@
         // Phi(...MergeMem(m0, m1:AT1, m2:AT2)...) into
         //     MergeMem(Phi(...m0...), Phi:AT1(...m1...), Phi:AT2(...m2...))
         PhaseIterGVN *igvn = phase->is_IterGVN();
-        Node* hook = new (phase->C, 1) Node(1);
+        Node* hook = new (phase->C) Node(1);
         PhiNode* new_base = (PhiNode*) clone();
         // Must eagerly register phis, since they participate in loops.
         if (igvn) {
@@ -1896,7 +1896,7 @@
       PhaseIterGVN *igvn = phase->is_IterGVN();
       // Make narrow type for new phi.
       const Type* narrow_t = TypeNarrowOop::make(this->bottom_type()->is_ptr());
-      PhiNode* new_phi = new (phase->C, r->req()) PhiNode(r, narrow_t);
+      PhiNode* new_phi = new (phase->C) PhiNode(r, narrow_t);
       uint orig_cnt = req();
       for (uint i=1; i<req(); ++i) {// For all paths in
         Node *ii = in(i);
@@ -1909,14 +1909,14 @@
           if (ii->as_Phi() == this) {
             new_ii = new_phi;
           } else {
-            new_ii = new (phase->C, 2) EncodePNode(ii, narrow_t);
+            new_ii = new (phase->C) EncodePNode(ii, narrow_t);
             igvn->register_new_node_with_optimizer(new_ii);
           }
         }
         new_phi->set_req(i, new_ii);
       }
       igvn->register_new_node_with_optimizer(new_phi, this);
-      progress = new (phase->C, 2) DecodeNNode(new_phi, bottom_type());
+      progress = new (phase->C) DecodeNNode(new_phi, bottom_type());
     }
   }
 #endif
diff --git a/hotspot/src/share/vm/opto/chaitin.cpp b/hotspot/src/share/vm/opto/chaitin.cpp
index cf9cc05..e626a10 100644
--- a/hotspot/src/share/vm/opto/chaitin.cpp
+++ b/hotspot/src/share/vm/opto/chaitin.cpp
@@ -75,6 +75,7 @@
   // Flags
   if( _is_oop ) tty->print("Oop ");
   if( _is_float ) tty->print("Float ");
+  if( _is_vector ) tty->print("Vector ");
   if( _was_spilled1 ) tty->print("Spilled ");
   if( _was_spilled2 ) tty->print("Spilled2 ");
   if( _direct_conflict ) tty->print("Direct_conflict ");
@@ -221,6 +222,7 @@
   _alternate = 0;
   _matcher._allocation_started = true;
 
+  ResourceArea split_arena;     // Arena for Split local resources
   ResourceArea live_arena;      // Arena for liveness & IFG info
   ResourceMark rm(&live_arena);
 
@@ -323,7 +325,7 @@
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit)
     C->check_node_count(10*must_spill, "out of nodes before split");
     if (C->failing())  return;
-    _maxlrg = Split( _maxlrg );        // Split spilling LRG everywhere
+    _maxlrg = Split(_maxlrg, &split_arena);  // Split spilling LRG everywhere
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
     // or we failed to split
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after physical split");
@@ -389,7 +391,7 @@
     }
 
     if( !_maxlrg ) return;
-    _maxlrg = Split( _maxlrg );        // Split spilling LRG everywhere
+    _maxlrg = Split(_maxlrg, &split_arena);  // Split spilling LRG everywhere
     // Bail out if unique gets too large (ie - unique > MaxNodeLimit - 2*NodeLimitFudgeFactor)
     C->check_node_count(2*NodeLimitFudgeFactor, "out of nodes after split");
     if (C->failing())  return;
@@ -479,26 +481,37 @@
 
   // Move important info out of the live_arena to longer lasting storage.
   alloc_node_regs(_names.Size());
-  for( uint i=0; i < _names.Size(); i++ ) {
-    if( _names[i] ) {           // Live range associated with Node?
-      LRG &lrg = lrgs( _names[i] );
-      if( lrg.num_regs() == 1 ) {
-        _node_regs[i].set1( lrg.reg() );
-      } else {                  // Must be a register-pair
-        if( !lrg._fat_proj ) {  // Must be aligned adjacent register pair
+  for (uint i=0; i < _names.Size(); i++) {
+    if (_names[i]) {           // Live range associated with Node?
+      LRG &lrg = lrgs(_names[i]);
+      if (!lrg.alive()) {
+        set_bad(i);
+      } else if (lrg.num_regs() == 1) {
+        set1(i, lrg.reg());
+      } else {                  // Must be a register-set
+        if (!lrg._fat_proj) {   // Must be aligned adjacent register set
           // Live ranges record the highest register in their mask.
           // We want the low register for the AD file writer's convenience.
-          _node_regs[i].set2( OptoReg::add(lrg.reg(),-1) );
+          OptoReg::Name hi = lrg.reg(); // Get hi register
+          OptoReg::Name lo = OptoReg::add(hi, (1-lrg.num_regs())); // Find lo
+          // We have to use pair [lo,lo+1] even for wide vectors because
+          // the rest of code generation works only with pairs. It is safe
+          // since for registers encoding only 'lo' is used.
+          // Second reg from pair is used in ScheduleAndBundle on SPARC where
+          // vector max size is 8 which corresponds to registers pair.
+          // It is also used in BuildOopMaps but oop operations are not
+          // vectorized.
+          set2(i, lo);
         } else {                // Misaligned; extract 2 bits
           OptoReg::Name hi = lrg.reg(); // Get hi register
           lrg.Remove(hi);       // Yank from mask
           int lo = lrg.mask().find_first_elem(); // Find lo
-          _node_regs[i].set_pair( hi, lo );
+          set_pair(i, hi, lo);
         }
       }
       if( lrg._is_oop ) _node_oops.set(i);
     } else {
-      _node_regs[i].set_bad();
+      set_bad(i);
     }
   }
 
@@ -568,7 +581,7 @@
         // Check for float-vs-int live range (used in register-pressure
         // calculations)
         const Type *n_type = n->bottom_type();
-        if( n_type->is_floatingpoint() )
+        if (n_type->is_floatingpoint())
           lrg._is_float = 1;
 
         // Check for twice prior spilling.  Once prior spilling might have
@@ -599,18 +612,28 @@
         // Limit result register mask to acceptable registers
         const RegMask &rm = n->out_RegMask();
         lrg.AND( rm );
-        // Check for bound register masks
-        const RegMask &lrgmask = lrg.mask();
-        if( lrgmask.is_bound1() || lrgmask.is_bound2() )
-          lrg._is_bound = 1;
-
-        // Check for maximum frequency value
-        if( lrg._maxfreq < b->_freq )
-          lrg._maxfreq = b->_freq;
 
         int ireg = n->ideal_reg();
         assert( !n->bottom_type()->isa_oop_ptr() || ireg == Op_RegP,
                 "oops must be in Op_RegP's" );
+
+        // Check for vector live range (only if vector register is used).
+        // On SPARC vector uses RegD which could be misaligned so it is not
+        // processes as vector in RA.
+        if (RegMask::is_vector(ireg))
+          lrg._is_vector = 1;
+        assert(n_type->isa_vect() == NULL || lrg._is_vector || ireg == Op_RegD,
+               "vector must be in vector registers");
+
+        // Check for bound register masks
+        const RegMask &lrgmask = lrg.mask();
+        if (lrgmask.is_bound(ireg))
+          lrg._is_bound = 1;
+
+        // Check for maximum frequency value
+        if (lrg._maxfreq < b->_freq)
+          lrg._maxfreq = b->_freq;
+
         // Check for oop-iness, or long/double
         // Check for multi-kill projection
         switch( ireg ) {
@@ -689,7 +712,7 @@
           // AND changes how we count interferences.  A mis-aligned
           // double can interfere with TWO aligned pairs, or effectively
           // FOUR registers!
-          if( rm.is_misaligned_Pair() ) {
+          if (rm.is_misaligned_pair()) {
             lrg._fat_proj = 1;
             lrg._is_bound = 1;
           }
@@ -706,6 +729,33 @@
           lrg.set_reg_pressure(1);
 #endif
           break;
+        case Op_VecS:
+          assert(Matcher::vector_size_supported(T_BYTE,4), "sanity");
+          assert(RegMask::num_registers(Op_VecS) == RegMask::SlotsPerVecS, "sanity");
+          lrg.set_num_regs(RegMask::SlotsPerVecS);
+          lrg.set_reg_pressure(1);
+          break;
+        case Op_VecD:
+          assert(Matcher::vector_size_supported(T_FLOAT,RegMask::SlotsPerVecD), "sanity");
+          assert(RegMask::num_registers(Op_VecD) == RegMask::SlotsPerVecD, "sanity");
+          assert(lrgmask.is_aligned_sets(RegMask::SlotsPerVecD), "vector should be aligned");
+          lrg.set_num_regs(RegMask::SlotsPerVecD);
+          lrg.set_reg_pressure(1);
+          break;
+        case Op_VecX:
+          assert(Matcher::vector_size_supported(T_FLOAT,RegMask::SlotsPerVecX), "sanity");
+          assert(RegMask::num_registers(Op_VecX) == RegMask::SlotsPerVecX, "sanity");
+          assert(lrgmask.is_aligned_sets(RegMask::SlotsPerVecX), "vector should be aligned");
+          lrg.set_num_regs(RegMask::SlotsPerVecX);
+          lrg.set_reg_pressure(1);
+          break;
+        case Op_VecY:
+          assert(Matcher::vector_size_supported(T_FLOAT,RegMask::SlotsPerVecY), "sanity");
+          assert(RegMask::num_registers(Op_VecY) == RegMask::SlotsPerVecY, "sanity");
+          assert(lrgmask.is_aligned_sets(RegMask::SlotsPerVecY), "vector should be aligned");
+          lrg.set_num_regs(RegMask::SlotsPerVecY);
+          lrg.set_reg_pressure(1);
+          break;
         default:
           ShouldNotReachHere();
         }
@@ -763,24 +813,38 @@
         } else {
           lrg.AND( rm );
         }
+
         // Check for bound register masks
         const RegMask &lrgmask = lrg.mask();
-        if( lrgmask.is_bound1() || lrgmask.is_bound2() )
+        int kreg = n->in(k)->ideal_reg();
+        bool is_vect = RegMask::is_vector(kreg);
+        assert(n->in(k)->bottom_type()->isa_vect() == NULL ||
+               is_vect || kreg == Op_RegD,
+               "vector must be in vector registers");
+        if (lrgmask.is_bound(kreg))
           lrg._is_bound = 1;
+
         // If this use of a double forces a mis-aligned double,
         // flag as '_fat_proj' - really flag as allowing misalignment
         // AND changes how we count interferences.  A mis-aligned
         // double can interfere with TWO aligned pairs, or effectively
         // FOUR registers!
-        if( lrg.num_regs() == 2 && !lrg._fat_proj && rm.is_misaligned_Pair() ) {
+#ifdef ASSERT
+        if (is_vect) {
+          assert(lrgmask.is_aligned_sets(lrg.num_regs()), "vector should be aligned");
+          assert(!lrg._fat_proj, "sanity");
+          assert(RegMask::num_registers(kreg) == lrg.num_regs(), "sanity");
+        }
+#endif
+        if (!is_vect && lrg.num_regs() == 2 && !lrg._fat_proj && rm.is_misaligned_pair()) {
           lrg._fat_proj = 1;
           lrg._is_bound = 1;
         }
         // if the LRG is an unaligned pair, we will have to spill
         // so clear the LRG's register mask if it is not already spilled
-        if ( !n->is_SpillCopy() &&
-               (lrg._def == NULL || lrg.is_multidef() || !lrg._def->is_SpillCopy()) &&
-               lrgmask.is_misaligned_Pair()) {
+        if (!is_vect && !n->is_SpillCopy() &&
+            (lrg._def == NULL || lrg.is_multidef() || !lrg._def->is_SpillCopy()) &&
+            lrgmask.is_misaligned_pair()) {
           lrg.Clear();
         }
 
@@ -793,12 +857,14 @@
   } // end for all blocks
 
   // Final per-liverange setup
-  for( uint i2=0; i2<_maxlrg; i2++ ) {
+  for (uint i2=0; i2<_maxlrg; i2++) {
     LRG &lrg = lrgs(i2);
-    if( lrg.num_regs() == 2 && !lrg._fat_proj )
-      lrg.ClearToPairs();
+    assert(!lrg._is_vector || !lrg._fat_proj, "sanity");
+    if (lrg.num_regs() > 1 && !lrg._fat_proj) {
+      lrg.clear_to_sets();
+    }
     lrg.compute_set_mask_size();
-    if( lrg.not_free() ) {      // Handle case where we lose from the start
+    if (lrg.not_free()) {      // Handle case where we lose from the start
       lrg.set_reg(OptoReg::Name(LRG::SPILL_REG));
       lrg._direct_conflict = 1;
     }
@@ -1065,6 +1131,33 @@
 
 }
 
+//------------------------------is_legal_reg-----------------------------------
+// Is 'reg' register legal for 'lrg'?
+static bool is_legal_reg(LRG &lrg, OptoReg::Name reg, int chunk) {
+  if (reg >= chunk && reg < (chunk + RegMask::CHUNK_SIZE) &&
+      lrg.mask().Member(OptoReg::add(reg,-chunk))) {
+    // RA uses OptoReg which represent the highest element of a registers set.
+    // For example, vectorX (128bit) on x86 uses [XMM,XMMb,XMMc,XMMd] set
+    // in which XMMd is used by RA to represent such vectors. A double value
+    // uses [XMM,XMMb] pairs and XMMb is used by RA for it.
+    // The register mask uses largest bits set of overlapping register sets.
+    // On x86 with AVX it uses 8 bits for each XMM registers set.
+    //
+    // The 'lrg' already has cleared-to-set register mask (done in Select()
+    // before calling choose_color()). Passing mask.Member(reg) check above
+    // indicates that the size (num_regs) of 'reg' set is less or equal to
+    // 'lrg' set size.
+    // For set size 1 any register which is member of 'lrg' mask is legal.
+    if (lrg.num_regs()==1)
+      return true;
+    // For larger sets only an aligned register with the same set size is legal.
+    int mask = lrg.num_regs()-1;
+    if ((reg&mask) == mask)
+      return true;
+  }
+  return false;
+}
+
 //------------------------------bias_color-------------------------------------
 // Choose a color using the biasing heuristic
 OptoReg::Name PhaseChaitin::bias_color( LRG &lrg, int chunk ) {
@@ -1081,10 +1174,7 @@
     while ((datum = elements.next()) != 0) {
       OptoReg::Name reg = lrgs(datum).reg();
       // If this LRG's register is legal for us, choose it
-      if( reg >= chunk && reg < chunk + RegMask::CHUNK_SIZE &&
-          lrg.mask().Member(OptoReg::add(reg,-chunk)) &&
-          (lrg.num_regs()==1 || // either size 1
-           (reg&1) == 1) )      // or aligned (adjacent reg is available since we already cleared-to-pairs)
+      if (is_legal_reg(lrg, reg, chunk))
         return reg;
     }
   }
@@ -1095,31 +1185,23 @@
     if( !(*(_ifg->_yanked))[copy_lrg] ) {
       OptoReg::Name reg = lrgs(copy_lrg).reg();
       //  And it is legal for you,
-      if( reg >= chunk && reg < chunk + RegMask::CHUNK_SIZE &&
-          lrg.mask().Member(OptoReg::add(reg,-chunk)) &&
-          (lrg.num_regs()==1 || // either size 1
-           (reg&1) == 1) )      // or aligned (adjacent reg is available since we already cleared-to-pairs)
+      if (is_legal_reg(lrg, reg, chunk))
         return reg;
     } else if( chunk == 0 ) {
       // Choose a color which is legal for him
       RegMask tempmask = lrg.mask();
       tempmask.AND(lrgs(copy_lrg).mask());
-      OptoReg::Name reg;
-      if( lrg.num_regs() == 1 ) {
-        reg = tempmask.find_first_elem();
-      } else {
-        tempmask.ClearToPairs();
-        reg = tempmask.find_first_pair();
-      }
-      if( OptoReg::is_valid(reg) )
+      tempmask.clear_to_sets(lrg.num_regs());
+      OptoReg::Name reg = tempmask.find_first_set(lrg.num_regs());
+      if (OptoReg::is_valid(reg))
         return reg;
     }
   }
 
   // If no bias info exists, just go with the register selection ordering
-  if( lrg.num_regs() == 2 ) {
-    // Find an aligned pair
-    return OptoReg::add(lrg.mask().find_first_pair(),chunk);
+  if (lrg._is_vector || lrg.num_regs() == 2) {
+    // Find an aligned set
+    return OptoReg::add(lrg.mask().find_first_set(lrg.num_regs()),chunk);
   }
 
   // CNC - Fun hack.  Alternate 1st and 2nd selection.  Enables post-allocate
@@ -1149,6 +1231,7 @@
     // Use a heuristic to "bias" the color choice
     return bias_color(lrg, chunk);
 
+  assert(!lrg._is_vector, "should be not vector here" );
   assert( lrg.num_regs() >= 2, "dead live ranges do not color" );
 
   // Fat-proj case or misaligned double argument.
@@ -1238,14 +1321,16 @@
     }
     //assert(is_allstack == lrg->mask().is_AllStack(), "nbrs must not change AllStackedness");
     // Aligned pairs need aligned masks
-    if( lrg->num_regs() == 2 && !lrg->_fat_proj )
-      lrg->ClearToPairs();
+    assert(!lrg->_is_vector || !lrg->_fat_proj, "sanity");
+    if (lrg->num_regs() > 1 && !lrg->_fat_proj) {
+      lrg->clear_to_sets();
+    }
 
     // Check if a color is available and if so pick the color
     OptoReg::Name reg = choose_color( *lrg, chunk );
 #ifdef SPARC
     debug_only(lrg->compute_set_mask_size());
-    assert(lrg->num_regs() != 2 || lrg->is_bound() || is_even(reg-1), "allocate all doubles aligned");
+    assert(lrg->num_regs() < 2 || lrg->is_bound() || is_even(reg-1), "allocate all doubles aligned");
 #endif
 
     //---------------
@@ -1277,17 +1362,16 @@
       // If the live range is not bound, then we actually had some choices
       // to make.  In this case, the mask has more bits in it than the colors
       // chosen.  Restrict the mask to just what was picked.
-      if( lrg->num_regs() == 1 ) { // Size 1 live range
+      int n_regs = lrg->num_regs();
+      assert(!lrg->_is_vector || !lrg->_fat_proj, "sanity");
+      if (n_regs == 1 || !lrg->_fat_proj) {
+        assert(!lrg->_is_vector || n_regs <= RegMask::SlotsPerVecY, "sanity");
         lrg->Clear();           // Clear the mask
         lrg->Insert(reg);       // Set regmask to match selected reg
-        lrg->set_mask_size(1);
-      } else if( !lrg->_fat_proj ) {
-        // For pairs, also insert the low bit of the pair
-        assert( lrg->num_regs() == 2, "unbound fatproj???" );
-        lrg->Clear();           // Clear the mask
-        lrg->Insert(reg);       // Set regmask to match selected reg
-        lrg->Insert(OptoReg::add(reg,-1));
-        lrg->set_mask_size(2);
+        // For vectors and pairs, also insert the low bit of the pair
+        for (int i = 1; i < n_regs; i++)
+          lrg->Insert(OptoReg::add(reg,-i));
+        lrg->set_mask_size(n_regs);
       } else {                  // Else fatproj
         // mask must be equal to fatproj bits, by definition
       }
@@ -1483,7 +1567,7 @@
 
   // Check for AddP-related opcodes
   if( !derived->is_Phi() ) {
-    assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, err_msg("but is: %s", derived->Name()));
+    assert(derived->as_Mach()->ideal_Opcode() == Op_AddP, err_msg_res("but is: %s", derived->Name()));
     Node *base = derived->in(AddPNode::Base);
     derived_base_map[derived->_idx] = base;
     return base;
@@ -1504,7 +1588,7 @@
 
   // Now we see we need a base-Phi here to merge the bases
   const Type *t = base->bottom_type();
-  base = new (C, derived->req()) PhiNode( derived->in(0), t );
+  base = new (C) PhiNode( derived->in(0), t );
   for( i = 1; i < derived->req(); i++ ) {
     base->init_req(i, find_base_for_derived(derived_base_map, derived->in(i), maxlrg));
     t = t->meet(base->in(i)->bottom_type());
@@ -1860,12 +1944,20 @@
       sprintf(buf,"L%d",lidx);  // No register binding yet
     } else if( !lidx ) {        // Special, not allocated value
       strcpy(buf,"Special");
-    } else if( (lrgs(lidx).num_regs() == 1)
-                ? !lrgs(lidx).mask().is_bound1()
-                : !lrgs(lidx).mask().is_bound2() ) {
-      sprintf(buf,"L%d",lidx); // No register binding yet
-    } else {                    // Hah!  We have a bound machine register
-      print_reg( lrgs(lidx).reg(), this, buf );
+    } else {
+      if (lrgs(lidx)._is_vector) {
+        if (lrgs(lidx).mask().is_bound_set(lrgs(lidx).num_regs()))
+          print_reg( lrgs(lidx).reg(), this, buf ); // a bound machine register
+        else
+          sprintf(buf,"L%d",lidx); // No register binding yet
+      } else if( (lrgs(lidx).num_regs() == 1)
+                 ? lrgs(lidx).mask().is_bound1()
+                 : lrgs(lidx).mask().is_bound_pair() ) {
+        // Hah!  We have a bound machine register
+        print_reg( lrgs(lidx).reg(), this, buf );
+      } else {
+        sprintf(buf,"L%d",lidx); // No register binding yet
+      }
     }
   }
   return buf+strlen(buf);
diff --git a/hotspot/src/share/vm/opto/chaitin.hpp b/hotspot/src/share/vm/opto/chaitin.hpp
index 1e6be63..340e46d 100644
--- a/hotspot/src/share/vm/opto/chaitin.hpp
+++ b/hotspot/src/share/vm/opto/chaitin.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,8 +99,15 @@
   void set_mask_size( int size ) {
     assert((size == 65535) || (size == (int)_mask.Size()), "");
     _mask_size = size;
-    debug_only(_msize_valid=1;)
-    debug_only( if( _num_regs == 2 && !_fat_proj ) _mask.VerifyPairs(); )
+#ifdef ASSERT
+    _msize_valid=1;
+    if (_is_vector) {
+      assert(!_fat_proj, "sanity");
+      _mask.verify_sets(_num_regs);
+    } else if (_num_regs == 2 && !_fat_proj) {
+      _mask.verify_pairs();
+    }
+#endif
   }
   void compute_set_mask_size() { set_mask_size(compute_mask_size()); }
   int mask_size() const { assert( _msize_valid, "mask size not valid" );
@@ -116,7 +123,8 @@
   void Set_All() { _mask.Set_All(); debug_only(_msize_valid=1); _mask_size = RegMask::CHUNK_SIZE; }
   void Insert( OptoReg::Name reg ) { _mask.Insert(reg);  debug_only(_msize_valid=0;) }
   void Remove( OptoReg::Name reg ) { _mask.Remove(reg);  debug_only(_msize_valid=0;) }
-  void ClearToPairs() { _mask.ClearToPairs(); debug_only(_msize_valid=0;) }
+  void clear_to_pairs() { _mask.clear_to_pairs(); debug_only(_msize_valid=0;) }
+  void clear_to_sets()  { _mask.clear_to_sets(_num_regs); debug_only(_msize_valid=0;) }
 
   // Number of registers this live range uses when it colors
 private:
@@ -150,6 +158,7 @@
 
   uint   _is_oop:1,             // Live-range holds an oop
          _is_float:1,           // True if in float registers
+         _is_vector:1,          // True if in vector registers
          _was_spilled1:1,       // True if prior spilling on def
          _was_spilled2:1,       // True if twice prior spilling on def
          _is_bound:1,           // live range starts life with no
@@ -461,7 +470,7 @@
 
   // Split uncolorable live ranges
   // Return new number of live ranges
-  uint Split( uint maxlrg );
+  uint Split(uint maxlrg, ResourceArea* split_arena);
 
   // Copy 'was_spilled'-edness from one Node to another.
   void copy_was_spilled( Node *src, Node *dst );
diff --git a/hotspot/src/share/vm/opto/classes.hpp b/hotspot/src/share/vm/opto/classes.hpp
index 19ade90..622988a 100644
--- a/hotspot/src/share/vm/opto/classes.hpp
+++ b/hotspot/src/share/vm/opto/classes.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -83,6 +83,12 @@
 macro(CompareAndSwapL)
 macro(CompareAndSwapP)
 macro(CompareAndSwapN)
+macro(GetAndAddI)
+macro(GetAndAddL)
+macro(GetAndSetI)
+macro(GetAndSetL)
+macro(GetAndSetP)
+macro(GetAndSetN)
 macro(Con)
 macro(ConN)
 macro(ConD)
@@ -141,13 +147,11 @@
 macro(LoadD_unaligned)
 macro(LoadF)
 macro(LoadI)
-macro(LoadUI2L)
 macro(LoadKlass)
 macro(LoadNKlass)
 macro(LoadL)
 macro(LoadL_unaligned)
 macro(LoadPLocked)
-macro(LoadLLocked)
 macro(LoadP)
 macro(LoadN)
 macro(LoadRange)
@@ -246,92 +250,62 @@
 macro(XorL)
 macro(Vector)
 macro(AddVB)
-macro(AddVC)
 macro(AddVS)
 macro(AddVI)
 macro(AddVL)
 macro(AddVF)
 macro(AddVD)
 macro(SubVB)
-macro(SubVC)
 macro(SubVS)
 macro(SubVI)
 macro(SubVL)
 macro(SubVF)
 macro(SubVD)
+macro(MulVS)
+macro(MulVI)
 macro(MulVF)
 macro(MulVD)
 macro(DivVF)
 macro(DivVD)
+macro(LShiftCntV)
+macro(RShiftCntV)
 macro(LShiftVB)
-macro(LShiftVC)
 macro(LShiftVS)
 macro(LShiftVI)
+macro(LShiftVL)
+macro(RShiftVB)
+macro(RShiftVS)
+macro(RShiftVI)
+macro(RShiftVL)
 macro(URShiftVB)
-macro(URShiftVC)
 macro(URShiftVS)
 macro(URShiftVI)
+macro(URShiftVL)
 macro(AndV)
 macro(OrV)
 macro(XorV)
-macro(VectorLoad)
-macro(Load16B)
-macro(Load8B)
-macro(Load4B)
-macro(Load8C)
-macro(Load4C)
-macro(Load2C)
-macro(Load8S)
-macro(Load4S)
-macro(Load2S)
-macro(Load4I)
-macro(Load2I)
-macro(Load2L)
-macro(Load4F)
-macro(Load2F)
-macro(Load2D)
-macro(VectorStore)
-macro(Store16B)
-macro(Store8B)
-macro(Store4B)
-macro(Store8C)
-macro(Store4C)
-macro(Store2C)
-macro(Store4I)
-macro(Store2I)
-macro(Store2L)
-macro(Store4F)
-macro(Store2F)
-macro(Store2D)
+macro(LoadVector)
+macro(StoreVector)
 macro(Pack)
 macro(PackB)
 macro(PackS)
-macro(PackC)
 macro(PackI)
 macro(PackL)
 macro(PackF)
 macro(PackD)
-macro(Pack2x1B)
-macro(Pack2x2B)
-macro(Replicate16B)
-macro(Replicate8B)
-macro(Replicate4B)
-macro(Replicate8S)
-macro(Replicate4S)
-macro(Replicate2S)
-macro(Replicate8C)
-macro(Replicate4C)
-macro(Replicate2C)
-macro(Replicate4I)
-macro(Replicate2I)
-macro(Replicate2L)
-macro(Replicate4F)
-macro(Replicate2F)
-macro(Replicate2D)
+macro(Pack2L)
+macro(Pack2D)
+macro(ReplicateB)
+macro(ReplicateS)
+macro(ReplicateI)
+macro(ReplicateL)
+macro(ReplicateF)
+macro(ReplicateD)
 macro(Extract)
 macro(ExtractB)
-macro(ExtractS)
+macro(ExtractUB)
 macro(ExtractC)
+macro(ExtractS)
 macro(ExtractI)
 macro(ExtractL)
 macro(ExtractF)
diff --git a/hotspot/src/share/vm/opto/compile.cpp b/hotspot/src/share/vm/opto/compile.cpp
index 2b9051c..7ac93ae 100644
--- a/hotspot/src/share/vm/opto/compile.cpp
+++ b/hotspot/src/share/vm/opto/compile.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -654,14 +654,14 @@
       const TypeTuple *domain = StartOSRNode::osr_domain();
       const TypeTuple *range = TypeTuple::make_range(method()->signature());
       init_tf(TypeFunc::make(domain, range));
-      StartNode* s = new (this, 2) StartOSRNode(root(), domain);
+      StartNode* s = new (this) StartOSRNode(root(), domain);
       initial_gvn()->set_type_bottom(s);
       init_start(s);
       cg = CallGenerator::for_osr(method(), entry_bci());
     } else {
       // Normal case.
       init_tf(TypeFunc::make(method()));
-      StartNode* s = new (this, 2) StartNode(root(), tf()->domain());
+      StartNode* s = new (this) StartNode(root(), tf()->domain());
       initial_gvn()->set_type_bottom(s);
       init_start(s);
       if (method()->intrinsic_id() == vmIntrinsics::_Reference_get && UseG1GC) {
@@ -825,8 +825,12 @@
                            &_handler_table, &_inc_table,
                            compiler,
                            env()->comp_level(),
-                           has_unsafe_access()
+                           has_unsafe_access(),
+                           SharedRuntime::is_wide_vector(max_vector_size())
                            );
+
+    if (log() != NULL) // Print code cache state into compiler log
+      log()->code_cache_state();
   }
 }
 
@@ -957,9 +961,9 @@
   // Globally visible Nodes
   // First set TOP to NULL to give safe behavior during creation of RootNode
   set_cached_top_node(NULL);
-  set_root(new (this, 3) RootNode());
+  set_root(new (this) RootNode());
   // Now that you have a Root to point to, create the real TOP
-  set_cached_top_node( new (this, 1) ConNode(Type::TOP) );
+  set_cached_top_node( new (this) ConNode(Type::TOP) );
   set_recent_alloc(NULL, NULL);
 
   // Create Debug Information Recorder to record scopes, oopmaps, etc.
@@ -974,6 +978,7 @@
   _trap_can_recompile = false;  // no traps emitted yet
   _major_progress = true; // start out assuming good things will happen
   set_has_unsafe_access(false);
+  set_max_vector_size(0);
   Copy::zero_to_bytes(_trap_hist, sizeof(_trap_hist));
   set_decompile_count(0);
 
@@ -1707,7 +1712,6 @@
       if (major_progress()) print_method("PhaseIdealLoop before EA", 2);
       if (failing())  return;
     }
-    TracePhase t2("escapeAnalysis", &_t_escapeAnalysis, true);
     ConnectionGraph::do_analysis(this, &igvn);
 
     if (failing())  return;
@@ -1719,6 +1723,7 @@
     if (failing())  return;
 
     if (congraph() != NULL && macro_count() > 0) {
+      NOT_PRODUCT( TracePhase t2("macroEliminate", &_t_macroEliminate, TimeCompiler); )
       PhaseMacroExpand mexp(igvn);
       mexp.eliminate_macro_nodes();
       igvn.set_delay_transform(false);
@@ -1875,10 +1880,10 @@
 
     cfg.Estimate_Block_Frequency();
     cfg.GlobalCodeMotion(m,unique(),proj_list);
+    if (failing())  return;
 
     print_method("Global code motion", 2);
 
-    if (failing())  return;
     NOT_PRODUCT( verify_graph_edges(); )
 
     debug_only( cfg.verify(); )
@@ -2285,19 +2290,23 @@
   case Op_CompareAndSwapL:
   case Op_CompareAndSwapP:
   case Op_CompareAndSwapN:
+  case Op_GetAndAddI:
+  case Op_GetAndAddL:
+  case Op_GetAndSetI:
+  case Op_GetAndSetL:
+  case Op_GetAndSetP:
+  case Op_GetAndSetN:
   case Op_StoreP:
   case Op_StoreN:
   case Op_LoadB:
   case Op_LoadUB:
   case Op_LoadUS:
   case Op_LoadI:
-  case Op_LoadUI2L:
   case Op_LoadKlass:
   case Op_LoadNKlass:
   case Op_LoadL:
   case Op_LoadL_unaligned:
   case Op_LoadPLocked:
-  case Op_LoadLLocked:
   case Op_LoadP:
   case Op_LoadN:
   case Op_LoadRange:
@@ -2349,7 +2358,7 @@
         if (nn != NULL) {
           // Decode a narrow oop to match address
           // [R12 + narrow_oop_reg<<3 + offset]
-          nn = new (C,  2) DecodeNNode(nn, t);
+          nn = new (C) DecodeNNode(nn, t);
           n->set_req(AddPNode::Base, nn);
           n->set_req(AddPNode::Address, nn);
           if (addp->outcnt() == 0) {
@@ -2467,7 +2476,7 @@
         }
       }
       if (new_in2 != NULL) {
-        Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2);
+        Node* cmpN = new (C) CmpNNode(in1->in(1), new_in2);
         n->subsume_by( cmpN );
         if (in1->outcnt() == 0) {
           in1->disconnect_inputs(NULL);
@@ -2563,8 +2572,8 @@
           n->subsume_by(divmod->mod_proj());
         } else {
           // replace a%b with a-((a/b)*b)
-          Node* mult = new (C, 3) MulINode(d, d->in(2));
-          Node* sub  = new (C, 3) SubINode(d->in(1), mult);
+          Node* mult = new (C) MulINode(d, d->in(2));
+          Node* sub  = new (C) SubINode(d->in(1), mult);
           n->subsume_by( sub );
         }
       }
@@ -2584,46 +2593,20 @@
           n->subsume_by(divmod->mod_proj());
         } else {
           // replace a%b with a-((a/b)*b)
-          Node* mult = new (C, 3) MulLNode(d, d->in(2));
-          Node* sub  = new (C, 3) SubLNode(d->in(1), mult);
+          Node* mult = new (C) MulLNode(d, d->in(2));
+          Node* sub  = new (C) SubLNode(d->in(1), mult);
           n->subsume_by( sub );
         }
       }
     }
     break;
 
-  case Op_Load16B:
-  case Op_Load8B:
-  case Op_Load4B:
-  case Op_Load8S:
-  case Op_Load4S:
-  case Op_Load2S:
-  case Op_Load8C:
-  case Op_Load4C:
-  case Op_Load2C:
-  case Op_Load4I:
-  case Op_Load2I:
-  case Op_Load2L:
-  case Op_Load4F:
-  case Op_Load2F:
-  case Op_Load2D:
-  case Op_Store16B:
-  case Op_Store8B:
-  case Op_Store4B:
-  case Op_Store8C:
-  case Op_Store4C:
-  case Op_Store2C:
-  case Op_Store4I:
-  case Op_Store2I:
-  case Op_Store2L:
-  case Op_Store4F:
-  case Op_Store2F:
-  case Op_Store2D:
+  case Op_LoadVector:
+  case Op_StoreVector:
     break;
 
   case Op_PackB:
   case Op_PackS:
-  case Op_PackC:
   case Op_PackI:
   case Op_PackF:
   case Op_PackL:
@@ -2631,7 +2614,7 @@
     if (n->req()-1 > 2) {
       // Replace many operand PackNodes with a binary tree for matching
       PackNode* p = (PackNode*) n;
-      Node* btp = p->binaryTreePack(Compile::current(), 1, n->req());
+      Node* btp = p->binary_tree_pack(Compile::current(), 1, n->req());
       n->subsume_by(btp);
     }
     break;
@@ -2662,7 +2645,7 @@
       } else {
         if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) {
           Compile* C = Compile::current();
-          Node* shift = new (C, 3) AndINode(in2, ConNode::make(C, TypeInt::make(mask)));
+          Node* shift = new (C) AndINode(in2, ConNode::make(C, TypeInt::make(mask)));
           n->set_req(2, shift);
         }
       }
@@ -3165,7 +3148,7 @@
     default: ShouldNotReachHere();
     }
     assert(constant_addr, "consts section too small");
-    assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset()));
+    assert((constant_addr - _masm.code()->consts()->start()) == con.offset(), err_msg_res("must be: %d == %d", constant_addr - _masm.code()->consts()->start(), con.offset()));
   }
 }
 
@@ -3226,7 +3209,7 @@
   if (Compile::current()->in_scratch_emit_size())  return;
 
   assert(labels.is_nonempty(), "must be");
-  assert((uint) labels.length() == n->outcnt(), err_msg("must be equal: %d == %d", labels.length(), n->outcnt()));
+  assert((uint) labels.length() == n->outcnt(), err_msg_res("must be equal: %d == %d", labels.length(), n->outcnt()));
 
   // Since MachConstantNode::constant_offset() also contains
   // table_base_offset() we need to subtract the table_base_offset()
@@ -3238,7 +3221,7 @@
 
   for (uint i = 0; i < n->outcnt(); i++) {
     address* constant_addr = &jump_table_base[i];
-    assert(*constant_addr == (((address) n) + i), err_msg("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i)));
+    assert(*constant_addr == (((address) n) + i), err_msg_res("all jump-table entries must contain adjusted node pointer: " INTPTR_FORMAT " == " INTPTR_FORMAT, *constant_addr, (((address) n) + i)));
     *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
     cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
   }
diff --git a/hotspot/src/share/vm/opto/compile.hpp b/hotspot/src/share/vm/opto/compile.hpp
index 8254aab..f57447f 100644
--- a/hotspot/src/share/vm/opto/compile.hpp
+++ b/hotspot/src/share/vm/opto/compile.hpp
@@ -263,6 +263,7 @@
   bool                  _has_split_ifs;         // True if the method _may_ have some split-if
   bool                  _has_unsafe_access;     // True if the method _may_ produce faults in unsafe loads or stores.
   bool                  _has_stringbuilder;     // True StringBuffers or StringBuilders are allocated
+  int                   _max_vector_size;       // Maximum size of generated vectors
   uint                  _trap_hist[trapHistLength];  // Cumulative traps
   bool                  _trap_can_recompile;    // Have we emitted a recompiling trap?
   uint                  _decompile_count;       // Cumulative decompilation counts.
@@ -427,6 +428,8 @@
   void          set_has_unsafe_access(bool z)   { _has_unsafe_access = z; }
   bool              has_stringbuilder() const   { return _has_stringbuilder; }
   void          set_has_stringbuilder(bool z)   { _has_stringbuilder = z; }
+  int               max_vector_size() const     { return _max_vector_size; }
+  void          set_max_vector_size(int s)      { _max_vector_size = s; }
   void          set_trap_count(uint r, uint c)  { assert(r < trapHistLength, "oob");        _trap_hist[r] = c; }
   uint              trap_count(uint r) const    { assert(r < trapHistLength, "oob"); return _trap_hist[r]; }
   bool              trap_can_recompile() const  { return _trap_can_recompile; }
@@ -631,7 +634,7 @@
 
   // Decide how to build a call.
   // The profile factor is a discount to apply to this site's interp. profile.
-  CallGenerator*    call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor);
+  CallGenerator*    call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual, JVMState* jvms, bool allow_inline, float profile_factor, bool allow_intrinsics = true);
   bool should_delay_inlining(ciMethod* call_method, JVMState* jvms);
 
   // Report if there were too many traps at a current method and bci.
diff --git a/hotspot/src/share/vm/opto/connode.cpp b/hotspot/src/share/vm/opto/connode.cpp
index 7e072ff..6d5e0e5 100644
--- a/hotspot/src/share/vm/opto/connode.cpp
+++ b/hotspot/src/share/vm/opto/connode.cpp
@@ -45,15 +45,15 @@
 //------------------------------make-------------------------------------------
 ConNode *ConNode::make( Compile* C, const Type *t ) {
   switch( t->basic_type() ) {
-  case T_INT:       return new (C, 1) ConINode( t->is_int() );
-  case T_LONG:      return new (C, 1) ConLNode( t->is_long() );
-  case T_FLOAT:     return new (C, 1) ConFNode( t->is_float_constant() );
-  case T_DOUBLE:    return new (C, 1) ConDNode( t->is_double_constant() );
-  case T_VOID:      return new (C, 1) ConNode ( Type::TOP );
-  case T_OBJECT:    return new (C, 1) ConPNode( t->is_oopptr() );
-  case T_ARRAY:     return new (C, 1) ConPNode( t->is_aryptr() );
-  case T_ADDRESS:   return new (C, 1) ConPNode( t->is_ptr() );
-  case T_NARROWOOP: return new (C, 1) ConNNode( t->is_narrowoop() );
+  case T_INT:       return new (C) ConINode( t->is_int() );
+  case T_LONG:      return new (C) ConLNode( t->is_long() );
+  case T_FLOAT:     return new (C) ConFNode( t->is_float_constant() );
+  case T_DOUBLE:    return new (C) ConDNode( t->is_double_constant() );
+  case T_VOID:      return new (C) ConNode ( Type::TOP );
+  case T_OBJECT:    return new (C) ConPNode( t->is_oopptr() );
+  case T_ARRAY:     return new (C) ConPNode( t->is_aryptr() );
+  case T_ADDRESS:   return new (C) ConPNode( t->is_ptr() );
+  case T_NARROWOOP: return new (C) ConNNode( t->is_narrowoop() );
     // Expected cases:  TypePtr::NULL_PTR, any is_rawptr()
     // Also seen: AnyPtr(TopPTR *+top); from command line:
     //   r -XX:+PrintOpto -XX:CIStart=285 -XX:+CompileTheWorld -XX:CompileTheWorldStartAt=660
@@ -194,13 +194,13 @@
 // from the inputs we do not need to specify it here.
 CMoveNode *CMoveNode::make( Compile *C, Node *c, Node *bol, Node *left, Node *right, const Type *t ) {
   switch( t->basic_type() ) {
-  case T_INT:     return new (C, 4) CMoveINode( bol, left, right, t->is_int() );
-  case T_FLOAT:   return new (C, 4) CMoveFNode( bol, left, right, t );
-  case T_DOUBLE:  return new (C, 4) CMoveDNode( bol, left, right, t );
-  case T_LONG:    return new (C, 4) CMoveLNode( bol, left, right, t->is_long() );
-  case T_OBJECT:  return new (C, 4) CMovePNode( c, bol, left, right, t->is_oopptr() );
-  case T_ADDRESS: return new (C, 4) CMovePNode( c, bol, left, right, t->is_ptr() );
-  case T_NARROWOOP: return new (C, 4) CMoveNNode( c, bol, left, right, t );
+  case T_INT:     return new (C) CMoveINode( bol, left, right, t->is_int() );
+  case T_FLOAT:   return new (C) CMoveFNode( bol, left, right, t );
+  case T_DOUBLE:  return new (C) CMoveDNode( bol, left, right, t );
+  case T_LONG:    return new (C) CMoveLNode( bol, left, right, t->is_long() );
+  case T_OBJECT:  return new (C) CMovePNode( c, bol, left, right, t->is_oopptr() );
+  case T_ADDRESS: return new (C) CMovePNode( c, bol, left, right, t->is_ptr() );
+  case T_NARROWOOP: return new (C) CMoveNNode( c, bol, left, right, t );
   default:
     ShouldNotReachHere();
     return NULL;
@@ -267,9 +267,9 @@
 #ifndef PRODUCT
   if( PrintOpto ) tty->print_cr("CMOV to I2B");
 #endif
-  Node *n = new (phase->C, 2) Conv2BNode( cmp->in(1) );
+  Node *n = new (phase->C) Conv2BNode( cmp->in(1) );
   if( flip )
-    n = new (phase->C, 3) XorINode( phase->transform(n), phase->intcon(1) );
+    n = new (phase->C) XorINode( phase->transform(n), phase->intcon(1) );
 
   return n;
 }
@@ -323,9 +323,9 @@
       sub->in(2) != X ||
       phase->type(sub->in(1)) != TypeF::ZERO ) return NULL;
 
-  Node *abs = new (phase->C, 2) AbsFNode( X );
+  Node *abs = new (phase->C) AbsFNode( X );
   if( flip )
-    abs = new (phase->C, 3) SubFNode(sub->in(1), phase->transform(abs));
+    abs = new (phase->C) SubFNode(sub->in(1), phase->transform(abs));
 
   return abs;
 }
@@ -379,9 +379,9 @@
       sub->in(2) != X ||
       phase->type(sub->in(1)) != TypeD::ZERO ) return NULL;
 
-  Node *abs = new (phase->C, 2) AbsDNode( X );
+  Node *abs = new (phase->C) AbsDNode( X );
   if( flip )
-    abs = new (phase->C, 3) SubDNode(sub->in(1), phase->transform(abs));
+    abs = new (phase->C) SubDNode(sub->in(1), phase->transform(abs));
 
   return abs;
 }
@@ -479,7 +479,9 @@
         opc == Op_CheckCastPP ||
         opc == Op_StorePConditional ||
         opc == Op_CompareAndSwapP ||
-        opc == Op_CompareAndSwapN;
+        opc == Op_CompareAndSwapN ||
+        opc == Op_GetAndSetP ||
+        opc == Op_GetAndSetN;
   }
   return possible_alias;
 }
@@ -958,11 +960,11 @@
       ryhi = -rylo0;
     }
 
-    Node* cx = phase->transform( new (phase->C, 2) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) );
-    Node* cy = phase->transform( new (phase->C, 2) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) );
+    Node* cx = phase->transform( new (phase->C) ConvI2LNode(x, TypeLong::make(rxlo, rxhi, widen)) );
+    Node* cy = phase->transform( new (phase->C) ConvI2LNode(y, TypeLong::make(rylo, ryhi, widen)) );
     switch (op) {
-    case Op_AddI:  return new (phase->C, 3) AddLNode(cx, cy);
-    case Op_SubI:  return new (phase->C, 3) SubLNode(cx, cy);
+    case Op_AddI:  return new (phase->C) AddLNode(cx, cy);
+    case Op_SubI:  return new (phase->C) SubLNode(cx, cy);
     default:       ShouldNotReachHere();
     }
   }
@@ -1036,9 +1038,9 @@
     assert( x != andl && y != andl, "dead loop in ConvL2INode::Ideal" );
     if (phase->type(x) == Type::TOP)  return NULL;
     if (phase->type(y) == Type::TOP)  return NULL;
-    Node *add1 = phase->transform(new (phase->C, 2) ConvL2INode(x));
-    Node *add2 = phase->transform(new (phase->C, 2) ConvL2INode(y));
-    return new (phase->C, 3) AddINode(add1,add2);
+    Node *add1 = phase->transform(new (phase->C) ConvL2INode(x));
+    Node *add2 = phase->transform(new (phase->C) ConvL2INode(y));
+    return new (phase->C) AddINode(add1,add2);
   }
 
   // Disable optimization: LoadL->ConvL2I ==> LoadI.
@@ -1075,10 +1077,10 @@
                                 Node* dispX,
                                 bool negate = false) {
   if (negate) {
-    dispX = new (phase->C, 3) SubXNode(phase->MakeConX(0), phase->transform(dispX));
+    dispX = new (phase->C) SubXNode(phase->MakeConX(0), phase->transform(dispX));
   }
-  return new (phase->C, 4) AddPNode(phase->C->top(),
-                          phase->transform(new (phase->C, 2) CastX2PNode(base)),
+  return new (phase->C) AddPNode(phase->C->top(),
+                          phase->transform(new (phase->C) CastX2PNode(base)),
                           phase->transform(dispX));
 }
 
diff --git a/hotspot/src/share/vm/opto/connode.hpp b/hotspot/src/share/vm/opto/connode.hpp
index 78a4427..2f8c79a 100644
--- a/hotspot/src/share/vm/opto/connode.hpp
+++ b/hotspot/src/share/vm/opto/connode.hpp
@@ -58,7 +58,7 @@
 
   // Factory method:
   static ConINode* make( Compile* C, int con ) {
-    return new (C, 1) ConINode( TypeInt::make(con) );
+    return new (C) ConINode( TypeInt::make(con) );
   }
 
 };
@@ -73,9 +73,9 @@
   // Factory methods:
   static ConPNode* make( Compile *C ,address con ) {
     if (con == NULL)
-      return new (C, 1) ConPNode( TypePtr::NULL_PTR ) ;
+      return new (C) ConPNode( TypePtr::NULL_PTR ) ;
     else
-      return new (C, 1) ConPNode( TypeRawPtr::make(con) );
+      return new (C) ConPNode( TypeRawPtr::make(con) );
   }
 };
 
@@ -98,7 +98,7 @@
 
   // Factory method:
   static ConLNode* make( Compile *C ,jlong con ) {
-    return new (C, 1) ConLNode( TypeLong::make(con) );
+    return new (C) ConLNode( TypeLong::make(con) );
   }
 
 };
@@ -112,7 +112,7 @@
 
   // Factory method:
   static ConFNode* make( Compile *C, float con  ) {
-    return new (C, 1) ConFNode( TypeF::make(con) );
+    return new (C) ConFNode( TypeF::make(con) );
   }
 
 };
@@ -126,7 +126,7 @@
 
   // Factory method:
   static ConDNode* make( Compile *C, double con ) {
-    return new (C, 1) ConDNode( TypeD::make(con) );
+    return new (C) ConDNode( TypeD::make(con) );
   }
 
 };
diff --git a/hotspot/src/share/vm/opto/divnode.cpp b/hotspot/src/share/vm/opto/divnode.cpp
index 14fa079..c222412 100644
--- a/hotspot/src/share/vm/opto/divnode.cpp
+++ b/hotspot/src/share/vm/opto/divnode.cpp
@@ -104,7 +104,7 @@
     // division by +/- 1
     if (!d_pos) {
       // Just negate the value
-      q = new (phase->C, 3) SubINode(phase->intcon(0), dividend);
+      q = new (phase->C) SubINode(phase->intcon(0), dividend);
     }
   } else if ( is_power_of_2(d) ) {
     // division by +/- a power of 2
@@ -141,18 +141,18 @@
       // (-2+3)>>2 becomes 0, etc.
 
       // Compute 0 or -1, based on sign bit
-      Node *sign = phase->transform(new (phase->C, 3) RShiftINode(dividend, phase->intcon(N - 1)));
+      Node *sign = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N - 1)));
       // Mask sign bit to the low sign bits
-      Node *round = phase->transform(new (phase->C, 3) URShiftINode(sign, phase->intcon(N - l)));
+      Node *round = phase->transform(new (phase->C) URShiftINode(sign, phase->intcon(N - l)));
       // Round up before shifting
-      dividend = phase->transform(new (phase->C, 3) AddINode(dividend, round));
+      dividend = phase->transform(new (phase->C) AddINode(dividend, round));
     }
 
     // Shift for division
-    q = new (phase->C, 3) RShiftINode(dividend, phase->intcon(l));
+    q = new (phase->C) RShiftINode(dividend, phase->intcon(l));
 
     if (!d_pos) {
-      q = new (phase->C, 3) SubINode(phase->intcon(0), phase->transform(q));
+      q = new (phase->C) SubINode(phase->intcon(0), phase->transform(q));
     }
   } else {
     // Attempt the jint constant divide -> multiply transform found in
@@ -164,33 +164,33 @@
     jint shift_const;
     if (magic_int_divide_constants(d, magic_const, shift_const)) {
       Node *magic = phase->longcon(magic_const);
-      Node *dividend_long = phase->transform(new (phase->C, 2) ConvI2LNode(dividend));
+      Node *dividend_long = phase->transform(new (phase->C) ConvI2LNode(dividend));
 
       // Compute the high half of the dividend x magic multiplication
-      Node *mul_hi = phase->transform(new (phase->C, 3) MulLNode(dividend_long, magic));
+      Node *mul_hi = phase->transform(new (phase->C) MulLNode(dividend_long, magic));
 
       if (magic_const < 0) {
-        mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(N)));
-        mul_hi = phase->transform(new (phase->C, 2) ConvL2INode(mul_hi));
+        mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N)));
+        mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi));
 
         // The magic multiplier is too large for a 32 bit constant. We've adjusted
         // it down by 2^32, but have to add 1 dividend back in after the multiplication.
         // This handles the "overflow" case described by Granlund and Montgomery.
-        mul_hi = phase->transform(new (phase->C, 3) AddINode(dividend, mul_hi));
+        mul_hi = phase->transform(new (phase->C) AddINode(dividend, mul_hi));
 
         // Shift over the (adjusted) mulhi
         if (shift_const != 0) {
-          mul_hi = phase->transform(new (phase->C, 3) RShiftINode(mul_hi, phase->intcon(shift_const)));
+          mul_hi = phase->transform(new (phase->C) RShiftINode(mul_hi, phase->intcon(shift_const)));
         }
       } else {
         // No add is required, we can merge the shifts together.
-        mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(N + shift_const)));
-        mul_hi = phase->transform(new (phase->C, 2) ConvL2INode(mul_hi));
+        mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(N + shift_const)));
+        mul_hi = phase->transform(new (phase->C) ConvL2INode(mul_hi));
       }
 
       // Get a 0 or -1 from the sign of the dividend.
       Node *addend0 = mul_hi;
-      Node *addend1 = phase->transform(new (phase->C, 3) RShiftINode(dividend, phase->intcon(N-1)));
+      Node *addend1 = phase->transform(new (phase->C) RShiftINode(dividend, phase->intcon(N-1)));
 
       // If the divisor is negative, swap the order of the input addends;
       // this has the effect of negating the quotient.
@@ -200,7 +200,7 @@
 
       // Adjust the final quotient by subtracting -1 (adding 1)
       // from the mul_hi.
-      q = new (phase->C, 3) SubINode(addend0, addend1);
+      q = new (phase->C) SubINode(addend0, addend1);
     }
   }
 
@@ -259,7 +259,7 @@
   // no need to synthesize it in ideal nodes.
   if (Matcher::has_match_rule(Op_MulHiL)) {
     Node* v = phase->longcon(magic_const);
-    return new (phase->C, 3) MulHiLNode(dividend, v);
+    return new (phase->C) MulHiLNode(dividend, v);
   }
 
   // Taken from Hacker's Delight, Fig. 8-2. Multiply high signed.
@@ -285,11 +285,11 @@
   const int N = 64;
 
   // Dummy node to keep intermediate nodes alive during construction
-  Node* hook = new (phase->C, 4) Node(4);
+  Node* hook = new (phase->C) Node(4);
 
   // u0 = u & 0xFFFFFFFF;  u1 = u >> 32;
-  Node* u0 = phase->transform(new (phase->C, 3) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
-  Node* u1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N / 2)));
+  Node* u0 = phase->transform(new (phase->C) AndLNode(dividend, phase->longcon(0xFFFFFFFF)));
+  Node* u1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N / 2)));
   hook->init_req(0, u0);
   hook->init_req(1, u1);
 
@@ -298,29 +298,29 @@
   Node* v1 = phase->longcon(magic_const >> (N / 2));
 
   // w0 = u0*v0;
-  Node* w0 = phase->transform(new (phase->C, 3) MulLNode(u0, v0));
+  Node* w0 = phase->transform(new (phase->C) MulLNode(u0, v0));
 
   // t = u1*v0 + (w0 >> 32);
-  Node* u1v0 = phase->transform(new (phase->C, 3) MulLNode(u1, v0));
-  Node* temp = phase->transform(new (phase->C, 3) URShiftLNode(w0, phase->intcon(N / 2)));
-  Node* t    = phase->transform(new (phase->C, 3) AddLNode(u1v0, temp));
+  Node* u1v0 = phase->transform(new (phase->C) MulLNode(u1, v0));
+  Node* temp = phase->transform(new (phase->C) URShiftLNode(w0, phase->intcon(N / 2)));
+  Node* t    = phase->transform(new (phase->C) AddLNode(u1v0, temp));
   hook->init_req(2, t);
 
   // w1 = t & 0xFFFFFFFF;
-  Node* w1 = phase->transform(new (phase->C, 3) AndLNode(t, phase->longcon(0xFFFFFFFF)));
+  Node* w1 = phase->transform(new (phase->C) AndLNode(t, phase->longcon(0xFFFFFFFF)));
   hook->init_req(3, w1);
 
   // w2 = t >> 32;
-  Node* w2 = phase->transform(new (phase->C, 3) RShiftLNode(t, phase->intcon(N / 2)));
+  Node* w2 = phase->transform(new (phase->C) RShiftLNode(t, phase->intcon(N / 2)));
 
   // w1 = u0*v1 + w1;
-  Node* u0v1 = phase->transform(new (phase->C, 3) MulLNode(u0, v1));
-  w1         = phase->transform(new (phase->C, 3) AddLNode(u0v1, w1));
+  Node* u0v1 = phase->transform(new (phase->C) MulLNode(u0, v1));
+  w1         = phase->transform(new (phase->C) AddLNode(u0v1, w1));
 
   // return u1*v1 + w2 + (w1 >> 32);
-  Node* u1v1  = phase->transform(new (phase->C, 3) MulLNode(u1, v1));
-  Node* temp1 = phase->transform(new (phase->C, 3) AddLNode(u1v1, w2));
-  Node* temp2 = phase->transform(new (phase->C, 3) RShiftLNode(w1, phase->intcon(N / 2)));
+  Node* u1v1  = phase->transform(new (phase->C) MulLNode(u1, v1));
+  Node* temp1 = phase->transform(new (phase->C) AddLNode(u1v1, w2));
+  Node* temp2 = phase->transform(new (phase->C) RShiftLNode(w1, phase->intcon(N / 2)));
 
   // Remove the bogus extra edges used to keep things alive
   PhaseIterGVN* igvn = phase->is_IterGVN();
@@ -332,7 +332,7 @@
     }
   }
 
-  return new (phase->C, 3) AddLNode(temp1, temp2);
+  return new (phase->C) AddLNode(temp1, temp2);
 }
 
 
@@ -355,7 +355,7 @@
     // division by +/- 1
     if (!d_pos) {
       // Just negate the value
-      q = new (phase->C, 3) SubLNode(phase->longcon(0), dividend);
+      q = new (phase->C) SubLNode(phase->longcon(0), dividend);
     }
   } else if ( is_power_of_2_long(d) ) {
 
@@ -394,18 +394,18 @@
       // (-2+3)>>2 becomes 0, etc.
 
       // Compute 0 or -1, based on sign bit
-      Node *sign = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N - 1)));
+      Node *sign = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N - 1)));
       // Mask sign bit to the low sign bits
-      Node *round = phase->transform(new (phase->C, 3) URShiftLNode(sign, phase->intcon(N - l)));
+      Node *round = phase->transform(new (phase->C) URShiftLNode(sign, phase->intcon(N - l)));
       // Round up before shifting
-      dividend = phase->transform(new (phase->C, 3) AddLNode(dividend, round));
+      dividend = phase->transform(new (phase->C) AddLNode(dividend, round));
     }
 
     // Shift for division
-    q = new (phase->C, 3) RShiftLNode(dividend, phase->intcon(l));
+    q = new (phase->C) RShiftLNode(dividend, phase->intcon(l));
 
     if (!d_pos) {
-      q = new (phase->C, 3) SubLNode(phase->longcon(0), phase->transform(q));
+      q = new (phase->C) SubLNode(phase->longcon(0), phase->transform(q));
     }
   } else if ( !Matcher::use_asm_for_ldiv_by_con(d) ) { // Use hardware DIV instruction when
                                                        // it is faster than code generated below.
@@ -425,17 +425,17 @@
         // The magic multiplier is too large for a 64 bit constant. We've adjusted
         // it down by 2^64, but have to add 1 dividend back in after the multiplication.
         // This handles the "overflow" case described by Granlund and Montgomery.
-        mul_hi = phase->transform(new (phase->C, 3) AddLNode(dividend, mul_hi));
+        mul_hi = phase->transform(new (phase->C) AddLNode(dividend, mul_hi));
       }
 
       // Shift over the (adjusted) mulhi
       if (shift_const != 0) {
-        mul_hi = phase->transform(new (phase->C, 3) RShiftLNode(mul_hi, phase->intcon(shift_const)));
+        mul_hi = phase->transform(new (phase->C) RShiftLNode(mul_hi, phase->intcon(shift_const)));
       }
 
       // Get a 0 or -1 from the sign of the dividend.
       Node *addend0 = mul_hi;
-      Node *addend1 = phase->transform(new (phase->C, 3) RShiftLNode(dividend, phase->intcon(N-1)));
+      Node *addend1 = phase->transform(new (phase->C) RShiftLNode(dividend, phase->intcon(N-1)));
 
       // If the divisor is negative, swap the order of the input addends;
       // this has the effect of negating the quotient.
@@ -445,7 +445,7 @@
 
       // Adjust the final quotient by subtracting -1 (adding 1)
       // from the mul_hi.
-      q = new (phase->C, 3) SubLNode(addend0, addend1);
+      q = new (phase->C) SubLNode(addend0, addend1);
     }
   }
 
@@ -735,7 +735,7 @@
   assert( frexp((double)reciprocal, &exp) == 0.5, "reciprocal should be power of 2" );
 
   // return multiplication by the reciprocal
-  return (new (phase->C, 3) MulFNode(in(1), phase->makecon(TypeF::make(reciprocal))));
+  return (new (phase->C) MulFNode(in(1), phase->makecon(TypeF::make(reciprocal))));
 }
 
 //=============================================================================
@@ -829,7 +829,7 @@
   assert( frexp(reciprocal, &exp) == 0.5, "reciprocal should be power of 2" );
 
   // return multiplication by the reciprocal
-  return (new (phase->C, 3) MulDNode(in(1), phase->makecon(TypeD::make(reciprocal))));
+  return (new (phase->C) MulDNode(in(1), phase->makecon(TypeD::make(reciprocal))));
 }
 
 //=============================================================================
@@ -856,7 +856,7 @@
   if( !ti->is_con() ) return NULL;
   jint con = ti->get_con();
 
-  Node *hook = new (phase->C, 1) Node(1);
+  Node *hook = new (phase->C) Node(1);
 
   // First, special check for modulo 2^k-1
   if( con >= 0 && con < max_jint && is_power_of_2(con+1) ) {
@@ -876,24 +876,24 @@
       hook->init_req(0, x);       // Add a use to x to prevent him from dying
       // Generate code to reduce X rapidly to nearly 2^k-1.
       for( int i = 0; i < trip_count; i++ ) {
-        Node *xl = phase->transform( new (phase->C, 3) AndINode(x,divisor) );
-        Node *xh = phase->transform( new (phase->C, 3) RShiftINode(x,phase->intcon(k)) ); // Must be signed
-        x = phase->transform( new (phase->C, 3) AddINode(xh,xl) );
+        Node *xl = phase->transform( new (phase->C) AndINode(x,divisor) );
+        Node *xh = phase->transform( new (phase->C) RShiftINode(x,phase->intcon(k)) ); // Must be signed
+        x = phase->transform( new (phase->C) AddINode(xh,xl) );
         hook->set_req(0, x);
       }
 
       // Generate sign-fixup code.  Was original value positive?
       // int hack_res = (i >= 0) ? divisor : 1;
-      Node *cmp1 = phase->transform( new (phase->C, 3) CmpINode( in(1), phase->intcon(0) ) );
-      Node *bol1 = phase->transform( new (phase->C, 2) BoolNode( cmp1, BoolTest::ge ) );
-      Node *cmov1= phase->transform( new (phase->C, 4) CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) );
+      Node *cmp1 = phase->transform( new (phase->C) CmpINode( in(1), phase->intcon(0) ) );
+      Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) );
+      Node *cmov1= phase->transform( new (phase->C) CMoveINode(bol1, phase->intcon(1), divisor, TypeInt::POS) );
       // if( x >= hack_res ) x -= divisor;
-      Node *sub  = phase->transform( new (phase->C, 3) SubINode( x, divisor ) );
-      Node *cmp2 = phase->transform( new (phase->C, 3) CmpINode( x, cmov1 ) );
-      Node *bol2 = phase->transform( new (phase->C, 2) BoolNode( cmp2, BoolTest::ge ) );
+      Node *sub  = phase->transform( new (phase->C) SubINode( x, divisor ) );
+      Node *cmp2 = phase->transform( new (phase->C) CmpINode( x, cmov1 ) );
+      Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) );
       // Convention is to not transform the return value of an Ideal
       // since Ideal is expected to return a modified 'this' or a new node.
-      Node *cmov2= new (phase->C, 4) CMoveINode(bol2, x, sub, TypeInt::INT);
+      Node *cmov2= new (phase->C) CMoveINode(bol2, x, sub, TypeInt::INT);
       // cmov2 is now the mod
 
       // Now remove the bogus extra edges used to keep things alive
@@ -916,7 +916,7 @@
   jint pos_con = (con >= 0) ? con : -con;
 
   // integer Mod 1 is always 0
-  if( pos_con == 1 ) return new (phase->C, 1) ConINode(TypeInt::ZERO);
+  if( pos_con == 1 ) return new (phase->C) ConINode(TypeInt::ZERO);
 
   int log2_con = -1;
 
@@ -929,7 +929,7 @@
 
     // See if this can be masked, if the dividend is non-negative
     if( dti && dti->_lo >= 0 )
-      return ( new (phase->C, 3) AndINode( in(1), phase->intcon( pos_con-1 ) ) );
+      return ( new (phase->C) AndINode( in(1), phase->intcon( pos_con-1 ) ) );
   }
 
   // Save in(1) so that it cannot be changed or deleted
@@ -944,12 +944,12 @@
     Node *mult = NULL;
 
     if( log2_con >= 0 )
-      mult = phase->transform( new (phase->C, 3) LShiftINode( divide, phase->intcon( log2_con ) ) );
+      mult = phase->transform( new (phase->C) LShiftINode( divide, phase->intcon( log2_con ) ) );
     else
-      mult = phase->transform( new (phase->C, 3) MulINode( divide, phase->intcon( pos_con ) ) );
+      mult = phase->transform( new (phase->C) MulINode( divide, phase->intcon( pos_con ) ) );
 
     // Finally, subtract the multiplied divided value from the original
-    result = new (phase->C, 3) SubINode( in(1), mult );
+    result = new (phase->C) SubINode( in(1), mult );
   }
 
   // Now remove the bogus extra edges used to keep things alive
@@ -1027,7 +1027,7 @@
   if( !tl->is_con() ) return NULL;
   jlong con = tl->get_con();
 
-  Node *hook = new (phase->C, 1) Node(1);
+  Node *hook = new (phase->C) Node(1);
 
   // Expand mod
   if( con >= 0 && con < max_jlong && is_power_of_2_long(con+1) ) {
@@ -1049,24 +1049,24 @@
       hook->init_req(0, x);       // Add a use to x to prevent him from dying
       // Generate code to reduce X rapidly to nearly 2^k-1.
       for( int i = 0; i < trip_count; i++ ) {
-        Node *xl = phase->transform( new (phase->C, 3) AndLNode(x,divisor) );
-        Node *xh = phase->transform( new (phase->C, 3) RShiftLNode(x,phase->intcon(k)) ); // Must be signed
-        x = phase->transform( new (phase->C, 3) AddLNode(xh,xl) );
+        Node *xl = phase->transform( new (phase->C) AndLNode(x,divisor) );
+        Node *xh = phase->transform( new (phase->C) RShiftLNode(x,phase->intcon(k)) ); // Must be signed
+        x = phase->transform( new (phase->C) AddLNode(xh,xl) );
         hook->set_req(0, x);    // Add a use to x to prevent him from dying
       }
 
       // Generate sign-fixup code.  Was original value positive?
       // long hack_res = (i >= 0) ? divisor : CONST64(1);
-      Node *cmp1 = phase->transform( new (phase->C, 3) CmpLNode( in(1), phase->longcon(0) ) );
-      Node *bol1 = phase->transform( new (phase->C, 2) BoolNode( cmp1, BoolTest::ge ) );
-      Node *cmov1= phase->transform( new (phase->C, 4) CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) );
+      Node *cmp1 = phase->transform( new (phase->C) CmpLNode( in(1), phase->longcon(0) ) );
+      Node *bol1 = phase->transform( new (phase->C) BoolNode( cmp1, BoolTest::ge ) );
+      Node *cmov1= phase->transform( new (phase->C) CMoveLNode(bol1, phase->longcon(1), divisor, TypeLong::LONG) );
       // if( x >= hack_res ) x -= divisor;
-      Node *sub  = phase->transform( new (phase->C, 3) SubLNode( x, divisor ) );
-      Node *cmp2 = phase->transform( new (phase->C, 3) CmpLNode( x, cmov1 ) );
-      Node *bol2 = phase->transform( new (phase->C, 2) BoolNode( cmp2, BoolTest::ge ) );
+      Node *sub  = phase->transform( new (phase->C) SubLNode( x, divisor ) );
+      Node *cmp2 = phase->transform( new (phase->C) CmpLNode( x, cmov1 ) );
+      Node *bol2 = phase->transform( new (phase->C) BoolNode( cmp2, BoolTest::ge ) );
       // Convention is to not transform the return value of an Ideal
       // since Ideal is expected to return a modified 'this' or a new node.
-      Node *cmov2= new (phase->C, 4) CMoveLNode(bol2, x, sub, TypeLong::LONG);
+      Node *cmov2= new (phase->C) CMoveLNode(bol2, x, sub, TypeLong::LONG);
       // cmov2 is now the mod
 
       // Now remove the bogus extra edges used to keep things alive
@@ -1089,7 +1089,7 @@
   jlong pos_con = (con >= 0) ? con : -con;
 
   // integer Mod 1 is always 0
-  if( pos_con == 1 ) return new (phase->C, 1) ConLNode(TypeLong::ZERO);
+  if( pos_con == 1 ) return new (phase->C) ConLNode(TypeLong::ZERO);
 
   int log2_con = -1;
 
@@ -1102,7 +1102,7 @@
 
     // See if this can be masked, if the dividend is non-negative
     if( dtl && dtl->_lo >= 0 )
-      return ( new (phase->C, 3) AndLNode( in(1), phase->longcon( pos_con-1 ) ) );
+      return ( new (phase->C) AndLNode( in(1), phase->longcon( pos_con-1 ) ) );
   }
 
   // Save in(1) so that it cannot be changed or deleted
@@ -1117,12 +1117,12 @@
     Node *mult = NULL;
 
     if( log2_con >= 0 )
-      mult = phase->transform( new (phase->C, 3) LShiftLNode( divide, phase->intcon( log2_con ) ) );
+      mult = phase->transform( new (phase->C) LShiftLNode( divide, phase->intcon( log2_con ) ) );
     else
-      mult = phase->transform( new (phase->C, 3) MulLNode( divide, phase->longcon( pos_con ) ) );
+      mult = phase->transform( new (phase->C) MulLNode( divide, phase->longcon( pos_con ) ) );
 
     // Finally, subtract the multiplied divided value from the original
-    result = new (phase->C, 3) SubLNode( in(1), mult );
+    result = new (phase->C) SubLNode( in(1), mult );
   }
 
   // Now remove the bogus extra edges used to keep things alive
@@ -1277,9 +1277,9 @@
   assert(n->Opcode() == Op_DivI || n->Opcode() == Op_ModI,
          "only div or mod input pattern accepted");
 
-  DivModINode* divmod = new (C, 3) DivModINode(n->in(0), n->in(1), n->in(2));
-  Node*        dproj  = new (C, 1) ProjNode(divmod, DivModNode::div_proj_num);
-  Node*        mproj  = new (C, 1) ProjNode(divmod, DivModNode::mod_proj_num);
+  DivModINode* divmod = new (C) DivModINode(n->in(0), n->in(1), n->in(2));
+  Node*        dproj  = new (C) ProjNode(divmod, DivModNode::div_proj_num);
+  Node*        mproj  = new (C) ProjNode(divmod, DivModNode::mod_proj_num);
   return divmod;
 }
 
@@ -1289,9 +1289,9 @@
   assert(n->Opcode() == Op_DivL || n->Opcode() == Op_ModL,
          "only div or mod input pattern accepted");
 
-  DivModLNode* divmod = new (C, 3) DivModLNode(n->in(0), n->in(1), n->in(2));
-  Node*        dproj  = new (C, 1) ProjNode(divmod, DivModNode::div_proj_num);
-  Node*        mproj  = new (C, 1) ProjNode(divmod, DivModNode::mod_proj_num);
+  DivModLNode* divmod = new (C) DivModLNode(n->in(0), n->in(1), n->in(2));
+  Node*        dproj  = new (C) ProjNode(divmod, DivModNode::div_proj_num);
+  Node*        mproj  = new (C) ProjNode(divmod, DivModNode::mod_proj_num);
   return divmod;
 }
 
@@ -1306,7 +1306,7 @@
     assert(proj->_con == mod_proj_num, "must be div or mod projection");
     rm = match->modI_proj_mask();
   }
-  return new (match->C, 1)MachProjNode(this, proj->_con, rm, ideal_reg);
+  return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg);
 }
 
 
@@ -1321,5 +1321,5 @@
     assert(proj->_con == mod_proj_num, "must be div or mod projection");
     rm = match->modL_proj_mask();
   }
-  return new (match->C, 1)MachProjNode(this, proj->_con, rm, ideal_reg);
+  return new (match->C)MachProjNode(this, proj->_con, rm, ideal_reg);
 }
diff --git a/hotspot/src/share/vm/opto/doCall.cpp b/hotspot/src/share/vm/opto/doCall.cpp
index 9ff9a89..a092bc0 100644
--- a/hotspot/src/share/vm/opto/doCall.cpp
+++ b/hotspot/src/share/vm/opto/doCall.cpp
@@ -41,11 +41,10 @@
 #include "prims/nativeLookup.hpp"
 #include "runtime/sharedRuntime.hpp"
 
-#ifndef PRODUCT
 void trace_type_profile(ciMethod *method, int depth, int bci, ciMethod *prof_method, ciKlass *prof_klass, int site_count, int receiver_count) {
-  if (TraceTypeProfile || PrintInlining || PrintOptoInlining) {
+  if (TraceTypeProfile || PrintInlining NOT_PRODUCT(|| PrintOptoInlining)) {
     if (!PrintInlining) {
-      if (!PrintOpto && !PrintCompilation) {
+      if (NOT_PRODUCT(!PrintOpto &&) !PrintCompilation) {
         method->print_short_name();
         tty->cr();
       }
@@ -57,15 +56,14 @@
     tty->cr();
   }
 }
-#endif
 
-CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index, bool call_is_virtual,
+CallGenerator* Compile::call_generator(ciMethod* callee, int vtable_index, bool call_is_virtual,
                                        JVMState* jvms, bool allow_inline,
-                                       float prof_factor) {
+                                       float prof_factor, bool allow_intrinsics) {
   ciMethod*       caller   = jvms->method();
   int             bci      = jvms->bci();
   Bytecodes::Code bytecode = caller->java_code_at_bci(bci);
-  guarantee(call_method != NULL, "failed method resolution");
+  guarantee(callee != NULL, "failed method resolution");
 
   // Dtrace currently doesn't work unless all calls are vanilla
   if (env()->dtrace_method_probes()) {
@@ -91,7 +89,7 @@
     int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
     int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
     log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
-                    log->identify(call_method), site_count, prof_factor);
+                    log->identify(callee), site_count, prof_factor);
     if (call_is_virtual)  log->print(" virtual='1'");
     if (allow_inline)     log->print(" inline='1'");
     if (receiver_count >= 0) {
@@ -108,28 +106,31 @@
   // then we return it as the inlined version of the call.
   // We do this before the strict f.p. check below because the
   // intrinsics handle strict f.p. correctly.
-  if (allow_inline) {
-    CallGenerator* cg = find_intrinsic(call_method, call_is_virtual);
-    if (cg != NULL)  return cg;
+  if (allow_inline && allow_intrinsics) {
+    CallGenerator* cg = find_intrinsic(callee, call_is_virtual);
+    if (cg != NULL) {
+      if (cg->is_predicted()) {
+        // Code without intrinsic but, hopefully, inlined.
+        CallGenerator* inline_cg = this->call_generator(callee,
+              vtable_index, call_is_virtual, jvms, allow_inline, prof_factor, false);
+        if (inline_cg != NULL) {
+          cg = CallGenerator::for_predicted_intrinsic(cg, inline_cg);
+        }
+      }
+      return cg;
+    }
   }
 
   // Do method handle calls.
   // NOTE: This must happen before normal inlining logic below since
   // MethodHandle.invoke* are native methods which obviously don't
   // have bytecodes and so normal inlining fails.
-  if (call_method->is_method_handle_invoke()) {
-    if (bytecode != Bytecodes::_invokedynamic) {
-      GraphKit kit(jvms);
-      Node* method_handle = kit.argument(0);
-      return CallGenerator::for_method_handle_call(method_handle, jvms, caller, call_method, profile);
-    }
-    else {
-      return CallGenerator::for_invokedynamic_call(jvms, caller, call_method, profile);
-    }
+  if (callee->is_method_handle_intrinsic()) {
+    return CallGenerator::for_method_handle_call(jvms, caller, callee);
   }
 
   // Do not inline strict fp into non-strict code, or the reverse
-  if (caller->is_strict() ^ call_method->is_strict()) {
+  if (caller->is_strict() ^ callee->is_strict()) {
     allow_inline = false;
   }
 
@@ -155,26 +156,26 @@
       }
       WarmCallInfo scratch_ci;
       if (!UseOldInlining)
-        scratch_ci.init(jvms, call_method, profile, prof_factor);
-      WarmCallInfo* ci = ilt->ok_to_inline(call_method, jvms, profile, &scratch_ci);
+        scratch_ci.init(jvms, callee, profile, prof_factor);
+      WarmCallInfo* ci = ilt->ok_to_inline(callee, jvms, profile, &scratch_ci);
       assert(ci != &scratch_ci, "do not let this pointer escape");
       bool allow_inline   = (ci != NULL && !ci->is_cold());
       bool require_inline = (allow_inline && ci->is_hot());
 
       if (allow_inline) {
-        CallGenerator* cg = CallGenerator::for_inline(call_method, expected_uses);
-        if (require_inline && cg != NULL && should_delay_inlining(call_method, jvms)) {
+        CallGenerator* cg = CallGenerator::for_inline(callee, expected_uses);
+        if (require_inline && cg != NULL && should_delay_inlining(callee, jvms)) {
           // Delay the inlining of this method to give us the
           // opportunity to perform some high level optimizations
           // first.
-          return CallGenerator::for_late_inline(call_method, cg);
+          return CallGenerator::for_late_inline(callee, cg);
         }
         if (cg == NULL) {
           // Fall through.
         } else if (require_inline || !InlineWarmCalls) {
           return cg;
         } else {
-          CallGenerator* cold_cg = call_generator(call_method, vtable_index, call_is_virtual, jvms, false, prof_factor);
+          CallGenerator* cold_cg = call_generator(callee, vtable_index, call_is_virtual, jvms, false, prof_factor);
           return CallGenerator::for_warm_call(ci, cold_cg, cg);
         }
       }
@@ -189,7 +190,7 @@
           (profile.morphism() == 2 && UseBimorphicInlining)) {
         // receiver_method = profile.method();
         // Profiles do not suggest methods now.  Look it up in the major receiver.
-        receiver_method = call_method->resolve_invoke(jvms->method()->holder(),
+        receiver_method = callee->resolve_invoke(jvms->method()->holder(),
                                                       profile.receiver(0));
       }
       if (receiver_method != NULL) {
@@ -201,7 +202,7 @@
           CallGenerator* next_hit_cg = NULL;
           ciMethod* next_receiver_method = NULL;
           if (profile.morphism() == 2 && UseBimorphicInlining) {
-            next_receiver_method = call_method->resolve_invoke(jvms->method()->holder(),
+            next_receiver_method = callee->resolve_invoke(jvms->method()->holder(),
                                                                profile.receiver(1));
             if (next_receiver_method != NULL) {
               next_hit_cg = this->call_generator(next_receiver_method,
@@ -224,22 +225,22 @@
              ) {
             // Generate uncommon trap for class check failure path
             // in case of monomorphic or bimorphic virtual call site.
-            miss_cg = CallGenerator::for_uncommon_trap(call_method, reason,
+            miss_cg = CallGenerator::for_uncommon_trap(callee, reason,
                         Deoptimization::Action_maybe_recompile);
           } else {
             // Generate virtual call for class check failure path
             // in case of polymorphic virtual call site.
-            miss_cg = CallGenerator::for_virtual_call(call_method, vtable_index);
+            miss_cg = CallGenerator::for_virtual_call(callee, vtable_index);
           }
           if (miss_cg != NULL) {
             if (next_hit_cg != NULL) {
-              NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1)));
+              trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), next_receiver_method, profile.receiver(1), site_count, profile.receiver_count(1));
               // We don't need to record dependency on a receiver here and below.
               // Whenever we inline, the dependency is added by Parse::Parse().
               miss_cg = CallGenerator::for_predicted_call(profile.receiver(1), miss_cg, next_hit_cg, PROB_MAX);
             }
             if (miss_cg != NULL) {
-              NOT_PRODUCT(trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count));
+              trace_type_profile(jvms->method(), jvms->depth() - 1, jvms->bci(), receiver_method, profile.receiver(0), site_count, receiver_count);
               CallGenerator* cg = CallGenerator::for_predicted_call(profile.receiver(0), miss_cg, hit_cg, profile.receiver_prob(0));
               if (cg != NULL)  return cg;
             }
@@ -252,11 +253,11 @@
   // There was no special inlining tactic, or it bailed out.
   // Use a more generic tactic, like a simple call.
   if (call_is_virtual) {
-    return CallGenerator::for_virtual_call(call_method, vtable_index);
+    return CallGenerator::for_virtual_call(callee, vtable_index);
   } else {
     // Class Hierarchy Analysis or Type Profile reveals a unique target,
     // or it is a static or special call.
-    return CallGenerator::for_direct_call(call_method, should_delay_inlining(call_method, jvms));
+    return CallGenerator::for_direct_call(callee, should_delay_inlining(callee, jvms));
   }
 }
 
@@ -348,40 +349,48 @@
   kill_dead_locals();
 
   // Set frequently used booleans
-  bool is_virtual = bc() == Bytecodes::_invokevirtual;
-  bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
-  bool has_receiver = is_virtual_or_interface || bc() == Bytecodes::_invokespecial;
-  bool is_invokedynamic = bc() == Bytecodes::_invokedynamic;
+  const bool is_virtual = bc() == Bytecodes::_invokevirtual;
+  const bool is_virtual_or_interface = is_virtual || bc() == Bytecodes::_invokeinterface;
+  const bool has_receiver = is_virtual_or_interface || bc() == Bytecodes::_invokespecial;
 
   // Find target being called
   bool             will_link;
-  ciMethod*        dest_method   = iter().get_method(will_link);
-  ciInstanceKlass* holder_klass  = dest_method->holder();
-  ciKlass* holder = iter().get_declared_method_holder();
+  ciSignature*     declared_signature = NULL;
+  ciMethod*        orig_callee  = iter().get_method(will_link, &declared_signature);  // callee in the bytecode
+  ciInstanceKlass* holder_klass = orig_callee->holder();
+  ciKlass*         holder       = iter().get_declared_method_holder();
   ciInstanceKlass* klass = ciEnv::get_instance_klass_for_declared_method_holder(holder);
-
-  int nargs = dest_method->arg_size();
-  if (is_invokedynamic)  nargs -= 1;
+  assert(declared_signature != NULL, "cannot be null");
 
   // uncommon-trap when callee is unloaded, uninitialized or will not link
   // bailout when too many arguments for register representation
-  if (!will_link || can_not_compile_call_site(dest_method, klass)) {
+  if (!will_link || can_not_compile_call_site(orig_callee, klass)) {
 #ifndef PRODUCT
     if (PrintOpto && (Verbose || WizardMode)) {
       method()->print_name(); tty->print_cr(" can not compile call at bci %d to:", bci());
-      dest_method->print_name(); tty->cr();
+      orig_callee->print_name(); tty->cr();
     }
 #endif
     return;
   }
   assert(holder_klass->is_loaded(), "");
-  assert((dest_method->is_static() || is_invokedynamic) == !has_receiver , "must match bc");
+  //assert((bc_callee->is_static() || is_invokedynamic) == !has_receiver , "must match bc");  // XXX invokehandle (cur_bc_raw)
   // Note: this takes into account invokeinterface of methods declared in java/lang/Object,
   // which should be invokevirtuals but according to the VM spec may be invokeinterfaces
   assert(holder_klass->is_interface() || holder_klass->super() == NULL || (bc() != Bytecodes::_invokeinterface), "must match bc");
   // Note:  In the absence of miranda methods, an abstract class K can perform
   // an invokevirtual directly on an interface method I.m if K implements I.
 
+  const int nargs = orig_callee->arg_size();
+
+  // Push appendix argument (MethodType, CallSite, etc.), if one.
+  if (iter().has_appendix()) {
+    ciObject* appendix_arg = iter().get_appendix();
+    const TypeOopPtr* appendix_arg_type = TypeOopPtr::make_from_constant(appendix_arg);
+    Node* appendix_arg_node = _gvn.makecon(appendix_arg_type);
+    push(appendix_arg_node);
+  }
+
   // ---------------------
   // Does Class Hierarchy Analysis reveal only a single target of a v-call?
   // Then we may inline or make a static call, but become dependent on there being only 1 target.
@@ -392,21 +401,21 @@
   // Choose call strategy.
   bool call_is_virtual = is_virtual_or_interface;
   int vtable_index = methodOopDesc::invalid_vtable_index;
-  ciMethod* call_method = dest_method;
+  ciMethod* callee = orig_callee;
 
   // Try to get the most accurate receiver type
   if (is_virtual_or_interface) {
     Node*             receiver_node = stack(sp() - nargs);
     const TypeOopPtr* receiver_type = _gvn.type(receiver_node)->isa_oopptr();
-    ciMethod* optimized_virtual_method = optimize_inlining(method(), bci(), klass, dest_method, receiver_type);
+    ciMethod* optimized_virtual_method = optimize_inlining(method(), bci(), klass, orig_callee, receiver_type);
 
     // Have the call been sufficiently improved such that it is no longer a virtual?
     if (optimized_virtual_method != NULL) {
-      call_method     = optimized_virtual_method;
+      callee          = optimized_virtual_method;
       call_is_virtual = false;
-    } else if (!UseInlineCaches && is_virtual && call_method->is_loaded()) {
+    } else if (!UseInlineCaches && is_virtual && callee->is_loaded()) {
       // We can make a vtable call at this site
-      vtable_index = call_method->resolve_vtable_index(method()->holder(), klass);
+      vtable_index = callee->resolve_vtable_index(method()->holder(), klass);
     }
   }
 
@@ -416,22 +425,25 @@
   bool try_inline = (C->do_inlining() || InlineAccessors);
 
   // ---------------------
-  inc_sp(- nargs);              // Temporarily pop args for JVM state of call
+  dec_sp(nargs);              // Temporarily pop args for JVM state of call
   JVMState* jvms = sync_jvms();
 
   // ---------------------
   // Decide call tactic.
   // This call checks with CHA, the interpreter profile, intrinsics table, etc.
   // It decides whether inlining is desirable or not.
-  CallGenerator* cg = C->call_generator(call_method, vtable_index, call_is_virtual, jvms, try_inline, prof_factor());
+  CallGenerator* cg = C->call_generator(callee, vtable_index, call_is_virtual, jvms, try_inline, prof_factor());
+
+  // NOTE:  Don't use orig_callee and callee after this point!  Use cg->method() instead.
+  orig_callee = callee = NULL;
 
   // ---------------------
   // Round double arguments before call
-  round_double_arguments(dest_method);
+  round_double_arguments(cg->method());
 
 #ifndef PRODUCT
   // bump global counters for calls
-  count_compiled_calls(false/*at_method_entry*/, cg->is_inline());
+  count_compiled_calls(/*at_method_entry*/ false, cg->is_inline());
 
   // Record first part of parsing work for this call
   parse_histogram()->record_change();
@@ -447,29 +459,20 @@
   // because exceptions don't return to the call site.)
   profile_call(receiver);
 
-  JVMState* new_jvms;
-  if ((new_jvms = cg->generate(jvms)) == NULL) {
+  JVMState* new_jvms = cg->generate(jvms);
+  if (new_jvms == NULL) {
     // When inlining attempt fails (e.g., too many arguments),
     // it may contaminate the current compile state, making it
     // impossible to pull back and try again.  Once we call
     // cg->generate(), we are committed.  If it fails, the whole
     // compilation task is compromised.
     if (failing())  return;
-#ifndef PRODUCT
-    if (PrintOpto || PrintOptoInlining || PrintInlining) {
-      // Only one fall-back, so if an intrinsic fails, ignore any bytecodes.
-      if (cg->is_intrinsic() && call_method->code_size() > 0) {
-        tty->print("Bailed out of intrinsic, will not inline: ");
-        call_method->print_name(); tty->cr();
-      }
-    }
-#endif
+
     // This can happen if a library intrinsic is available, but refuses
     // the call site, perhaps because it did not match a pattern the
-    // intrinsic was expecting to optimize.  The fallback position is
-    // to call out-of-line.
-    try_inline = false;  // Inline tactic bailed out.
-    cg = C->call_generator(call_method, vtable_index, call_is_virtual, jvms, try_inline, prof_factor());
+    // intrinsic was expecting to optimize. Should always be possible to
+    // get a normal java call that may inline in that case
+    cg = C->call_generator(cg->method(), vtable_index, call_is_virtual, jvms, try_inline, prof_factor(), /* allow_intrinsics= */ false);
     if ((new_jvms = cg->generate(jvms)) == NULL) {
       guarantee(failing(), "call failed to generate:  calls should work");
       return;
@@ -478,8 +481,8 @@
 
   if (cg->is_inline()) {
     // Accumulate has_loops estimate
-    C->set_has_loops(C->has_loops() || call_method->has_loops());
-    C->env()->notice_inlined_method(call_method);
+    C->set_has_loops(C->has_loops() || cg->method()->has_loops());
+    C->env()->notice_inlined_method(cg->method());
   }
 
   // Reset parser state from [new_]jvms, which now carries results of the call.
@@ -501,20 +504,72 @@
     }
 
     // Round double result after a call from strict to non-strict code
-    round_double_result(dest_method);
+    round_double_result(cg->method());
+
+    ciType* rtype = cg->method()->return_type();
+    if (Bytecodes::has_optional_appendix(iter().cur_bc_raw())) {
+      // Be careful here with return types.
+      ciType* ctype = declared_signature->return_type();
+      if (ctype != rtype) {
+        BasicType rt = rtype->basic_type();
+        BasicType ct = ctype->basic_type();
+        Node* retnode = peek();
+        if (ct == T_VOID) {
+          // It's OK for a method  to return a value that is discarded.
+          // The discarding does not require any special action from the caller.
+          // The Java code knows this, at VerifyType.isNullConversion.
+          pop_node(rt);  // whatever it was, pop it
+          retnode = top();
+        } else if (rt == T_INT || is_subword_type(rt)) {
+          // FIXME: This logic should be factored out.
+          if (ct == T_BOOLEAN) {
+            retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0x1)) );
+          } else if (ct == T_CHAR) {
+            retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) );
+          } else if (ct == T_BYTE) {
+            retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) );
+            retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) );
+          } else if (ct == T_SHORT) {
+            retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) );
+            retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) );
+          } else {
+            assert(ct == T_INT, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct)));
+          }
+        } else if (rt == T_OBJECT || rt == T_ARRAY) {
+          assert(ct == T_OBJECT || ct == T_ARRAY, err_msg_res("rt=%s, ct=%s", type2name(rt), type2name(ct)));
+          if (ctype->is_loaded()) {
+            const TypeOopPtr* arg_type = TypeOopPtr::make_from_klass(rtype->as_klass());
+            const Type*       sig_type = TypeOopPtr::make_from_klass(ctype->as_klass());
+            if (arg_type != NULL && !arg_type->higher_equal(sig_type)) {
+              Node* cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(), retnode, sig_type));
+              pop();
+              push(cast_obj);
+            }
+          }
+        } else {
+          assert(ct == rt, err_msg_res("unexpected mismatch rt=%d, ct=%d", rt, ct));
+          // push a zero; it's better than getting an oop/int mismatch
+          retnode = pop_node(rt);
+          retnode = zerocon(ct);
+          push_node(ct, retnode);
+        }
+        // Now that the value is well-behaved, continue with the call-site type.
+        rtype = ctype;
+      }
+    }
 
     // If the return type of the method is not loaded, assert that the
     // value we got is a null.  Otherwise, we need to recompile.
-    if (!dest_method->return_type()->is_loaded()) {
+    if (!rtype->is_loaded()) {
 #ifndef PRODUCT
       if (PrintOpto && (Verbose || WizardMode)) {
         method()->print_name(); tty->print_cr(" asserting nullness of result at bci: %d", bci());
-        dest_method->print_name(); tty->cr();
+        cg->method()->print_name(); tty->cr();
       }
 #endif
       if (C->log() != NULL) {
         C->log()->elem("assert_null reason='return' klass='%d'",
-                       C->log()->identify(dest_method->return_type()));
+                       C->log()->identify(rtype));
       }
       // If there is going to be a trap, put it at the next bytecode:
       set_bci(iter().next_bci());
@@ -568,7 +623,7 @@
   }
 
   int len = bcis->length();
-  CatchNode *cn = new (C, 2) CatchNode(control(), i_o, len+1);
+  CatchNode *cn = new (C) CatchNode(control(), i_o, len+1);
   Node *catch_ = _gvn.transform(cn);
 
   // now branch with the exception state to each of the (potential)
@@ -579,14 +634,14 @@
     // Locals are just copied from before the call.
     // Get control from the CatchNode.
     int handler_bci = bcis->at(i);
-    Node* ctrl = _gvn.transform( new (C, 1) CatchProjNode(catch_, i+1,handler_bci));
+    Node* ctrl = _gvn.transform( new (C) CatchProjNode(catch_, i+1,handler_bci));
     // This handler cannot happen?
     if (ctrl == top())  continue;
     set_control(ctrl);
 
     // Create exception oop
     const TypeInstPtr* extype = extypes->at(i)->is_instptr();
-    Node *ex_oop = _gvn.transform(new (C, 2) CreateExNode(extypes->at(i), ctrl, i_o));
+    Node *ex_oop = _gvn.transform(new (C) CreateExNode(extypes->at(i), ctrl, i_o));
 
     // Handle unloaded exception classes.
     if (saw_unloaded->contains(handler_bci)) {
@@ -594,8 +649,8 @@
 #ifndef PRODUCT
       // We do not expect the same handler bci to take both cold unloaded
       // and hot loaded exceptions.  But, watch for it.
-      if (extype->is_loaded()) {
-        tty->print_cr("Warning: Handler @%d takes mixed loaded/unloaded exceptions in ");
+      if ((Verbose || WizardMode) && extype->is_loaded()) {
+        tty->print("Warning: Handler @%d takes mixed loaded/unloaded exceptions in ", bci());
         method()->print_name(); tty->cr();
       } else if (PrintOpto && (Verbose || WizardMode)) {
         tty->print("Bailing out on unloaded exception type ");
@@ -625,7 +680,7 @@
 
   // The first CatchProj is for the normal return.
   // (Note:  If this is a call to rethrow_Java, this node goes dead.)
-  set_control(_gvn.transform( new (C, 1) CatchProjNode(catch_, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci)));
+  set_control(_gvn.transform( new (C) CatchProjNode(catch_, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci)));
 }
 
 
@@ -676,7 +731,7 @@
     // I'm loading the class from, I can replace the LoadKlass with the
     // klass constant for the exception oop.
     if( ex_node->is_Phi() ) {
-      ex_klass_node = new (C, ex_node->req()) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT );
+      ex_klass_node = new (C) PhiNode( ex_node->in(0), TypeKlassPtr::OBJECT );
       for( uint i = 1; i < ex_node->req(); i++ ) {
         Node* p = basic_plus_adr( ex_node->in(i), ex_node->in(i), oopDesc::klass_offset_in_bytes() );
         Node* k = _gvn.transform( LoadKlassNode::make(_gvn, immutable_memory(), p, TypeInstPtr::KLASS, TypeKlassPtr::OBJECT) );
@@ -742,7 +797,7 @@
       PreserveJVMState pjvms(this);
       const TypeInstPtr* tinst = TypeOopPtr::make_from_klass_unique(klass)->cast_to_ptr_type(TypePtr::NotNull)->is_instptr();
       assert(klass->has_subklass() || tinst->klass_is_exact(), "lost exactness");
-      Node* ex_oop = _gvn.transform(new (C, 2) CheckCastPPNode(control(), ex_node, tinst));
+      Node* ex_oop = _gvn.transform(new (C) CheckCastPPNode(control(), ex_node, tinst));
       push_ex_oop(ex_oop);      // Push exception oop for handler
 #ifndef PRODUCT
       if (PrintOpto && WizardMode) {
@@ -789,7 +844,7 @@
     if( at_method_entry ) {
       // bump invocation counter if top method (for statistics)
       if (CountCompiledCalls && depth() == 1) {
-        const TypeInstPtr* addr_type = TypeInstPtr::make(method());
+        const TypeOopPtr* addr_type = TypeOopPtr::make_from_constant(method());
         Node* adr1 = makecon(addr_type);
         Node* adr2 = basic_plus_adr(adr1, adr1, in_bytes(methodOopDesc::compiled_invocation_counter_offset()));
         increment_counter(adr2);
diff --git a/hotspot/src/share/vm/opto/domgraph.cpp b/hotspot/src/share/vm/opto/domgraph.cpp
index ef4e1b1..b3a367d 100644
--- a/hotspot/src/share/vm/opto/domgraph.cpp
+++ b/hotspot/src/share/vm/opto/domgraph.cpp
@@ -465,15 +465,11 @@
           // Kill dead input path
           assert( !visited.test(whead->in(i)->_idx),
                   "input with no loop must be dead" );
-          _igvn.hash_delete(whead);
-          whead->del_req(i);
-          _igvn._worklist.push(whead);
+          _igvn.delete_input_of(whead, i);
           for (DUIterator_Fast jmax, j = whead->fast_outs(jmax); j < jmax; j++) {
             Node* p = whead->fast_out(j);
             if( p->is_Phi() ) {
-              _igvn.hash_delete(p);
-              p->del_req(i);
-              _igvn._worklist.push(p);
+              _igvn.delete_input_of(p, i);
             }
           }
           i--;                  // Rerun same iteration
diff --git a/hotspot/src/share/vm/opto/escape.cpp b/hotspot/src/share/vm/opto/escape.cpp
index d7c67e2..bdc9829 100644
--- a/hotspot/src/share/vm/opto/escape.cpp
+++ b/hotspot/src/share/vm/opto/escape.cpp
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "ci/bcEscapeAnalyzer.hpp"
+#include "compiler/compileLog.hpp"
 #include "libadt/vectset.hpp"
 #include "memory/allocation.hpp"
 #include "opto/c2compiler.hpp"
@@ -34,125 +35,2034 @@
 #include "opto/phaseX.hpp"
 #include "opto/rootnode.hpp"
 
-void PointsToNode::add_edge(uint targIdx, PointsToNode::EdgeType et) {
-  uint v = (targIdx << EdgeShift) + ((uint) et);
-  if (_edges == NULL) {
-     Arena *a = Compile::current()->comp_arena();
-    _edges = new(a) GrowableArray<uint>(a, INITIAL_EDGE_COUNT, 0, 0);
-  }
-  _edges->append_if_missing(v);
-}
-
-void PointsToNode::remove_edge(uint targIdx, PointsToNode::EdgeType et) {
-  uint v = (targIdx << EdgeShift) + ((uint) et);
-
-  _edges->remove(v);
-}
-
-#ifndef PRODUCT
-static const char *node_type_names[] = {
-  "UnknownType",
-  "JavaObject",
-  "LocalVar",
-  "Field"
-};
-
-static const char *esc_names[] = {
-  "UnknownEscape",
-  "NoEscape",
-  "ArgEscape",
-  "GlobalEscape"
-};
-
-static const char *edge_type_suffix[] = {
- "?", // UnknownEdge
- "P", // PointsToEdge
- "D", // DeferredEdge
- "F"  // FieldEdge
-};
-
-void PointsToNode::dump(bool print_state) const {
-  NodeType nt = node_type();
-  tty->print("%s ", node_type_names[(int) nt]);
-  if (print_state) {
-    EscapeState es = escape_state();
-    tty->print("%s %s ", esc_names[(int) es], _scalar_replaceable ? "":"NSR");
-  }
-  tty->print("[[");
-  for (uint i = 0; i < edge_count(); i++) {
-    tty->print(" %d%s", edge_target(i), edge_type_suffix[(int) edge_type(i)]);
-  }
-  tty->print("]]  ");
-  if (_node == NULL)
-    tty->print_cr("<null>");
-  else
-    _node->dump();
-}
-#endif
-
 ConnectionGraph::ConnectionGraph(Compile * C, PhaseIterGVN *igvn) :
-  _nodes(C->comp_arena(), C->unique(), C->unique(), PointsToNode()),
-  _processed(C->comp_arena()),
-  pt_ptset(C->comp_arena()),
-  pt_visited(C->comp_arena()),
-  pt_worklist(C->comp_arena(), 4, 0, 0),
+  _nodes(C->comp_arena(), C->unique(), C->unique(), NULL),
   _collecting(true),
-  _progress(false),
+  _verify(false),
   _compile(C),
   _igvn(igvn),
   _node_map(C->comp_arena()) {
-
-  _phantom_object = C->top()->_idx,
-  add_node(C->top(), PointsToNode::JavaObject, PointsToNode::GlobalEscape,true);
-
+  // Add unknown java object.
+  add_java_object(C->top(), PointsToNode::GlobalEscape);
+  phantom_obj = ptnode_adr(C->top()->_idx)->as_JavaObject();
   // Add ConP(#NULL) and ConN(#NULL) nodes.
   Node* oop_null = igvn->zerocon(T_OBJECT);
-  _oop_null = oop_null->_idx;
-  assert(_oop_null < nodes_size(), "should be created already");
-  add_node(oop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
-
+  assert(oop_null->_idx < nodes_size(), "should be created already");
+  add_java_object(oop_null, PointsToNode::NoEscape);
+  null_obj = ptnode_adr(oop_null->_idx)->as_JavaObject();
   if (UseCompressedOops) {
     Node* noop_null = igvn->zerocon(T_NARROWOOP);
-    _noop_null = noop_null->_idx;
-    assert(_noop_null < nodes_size(), "should be created already");
-    add_node(noop_null, PointsToNode::JavaObject, PointsToNode::NoEscape, true);
-  } else {
-    _noop_null = _oop_null; // Should be initialized
+    assert(noop_null->_idx < nodes_size(), "should be created already");
+    map_ideal_node(noop_null, null_obj);
   }
   _pcmp_neq = NULL; // Should be initialized
   _pcmp_eq  = NULL;
 }
 
-void ConnectionGraph::add_pointsto_edge(uint from_i, uint to_i) {
-  PointsToNode *f = ptnode_adr(from_i);
-  PointsToNode *t = ptnode_adr(to_i);
-
-  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
-  assert(f->node_type() == PointsToNode::LocalVar || f->node_type() == PointsToNode::Field, "invalid source of PointsTo edge");
-  assert(t->node_type() == PointsToNode::JavaObject, "invalid destination of PointsTo edge");
-  if (to_i == _phantom_object) { // Quick test for most common object
-    if (f->has_unknown_ptr()) {
-      return;
-    } else {
-      f->set_has_unknown_ptr();
+bool ConnectionGraph::has_candidates(Compile *C) {
+  // EA brings benefits only when the code has allocations and/or locks which
+  // are represented by ideal Macro nodes.
+  int cnt = C->macro_count();
+  for( int i=0; i < cnt; i++ ) {
+    Node *n = C->macro_node(i);
+    if ( n->is_Allocate() )
+      return true;
+    if( n->is_Lock() ) {
+      Node* obj = n->as_Lock()->obj_node()->uncast();
+      if( !(obj->is_Parm() || obj->is_Con()) )
+        return true;
     }
   }
-  add_edge(f, to_i, PointsToNode::PointsToEdge);
+  return false;
 }
 
-void ConnectionGraph::add_deferred_edge(uint from_i, uint to_i) {
-  PointsToNode *f = ptnode_adr(from_i);
-  PointsToNode *t = ptnode_adr(to_i);
+void ConnectionGraph::do_analysis(Compile *C, PhaseIterGVN *igvn) {
+  Compile::TracePhase t2("escapeAnalysis", &Phase::_t_escapeAnalysis, true);
+  ResourceMark rm;
 
-  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
-  assert(f->node_type() == PointsToNode::LocalVar || f->node_type() == PointsToNode::Field, "invalid source of Deferred edge");
-  assert(t->node_type() == PointsToNode::LocalVar || t->node_type() == PointsToNode::Field, "invalid destination of Deferred edge");
-  // don't add a self-referential edge, this can occur during removal of
-  // deferred edges
-  if (from_i != to_i)
-    add_edge(f, to_i, PointsToNode::DeferredEdge);
+  // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction
+  // to create space for them in ConnectionGraph::_nodes[].
+  Node* oop_null = igvn->zerocon(T_OBJECT);
+  Node* noop_null = igvn->zerocon(T_NARROWOOP);
+  ConnectionGraph* congraph = new(C->comp_arena()) ConnectionGraph(C, igvn);
+  // Perform escape analysis
+  if (congraph->compute_escape()) {
+    // There are non escaping objects.
+    C->set_congraph(congraph);
+  }
+  // Cleanup.
+  if (oop_null->outcnt() == 0)
+    igvn->hash_delete(oop_null);
+  if (noop_null->outcnt() == 0)
+    igvn->hash_delete(noop_null);
 }
 
+bool ConnectionGraph::compute_escape() {
+  Compile* C = _compile;
+  PhaseGVN* igvn = _igvn;
+
+  // Worklists used by EA.
+  Unique_Node_List delayed_worklist;
+  GrowableArray<Node*> alloc_worklist;
+  GrowableArray<Node*> ptr_cmp_worklist;
+  GrowableArray<Node*> storestore_worklist;
+  GrowableArray<PointsToNode*>   ptnodes_worklist;
+  GrowableArray<JavaObjectNode*> java_objects_worklist;
+  GrowableArray<JavaObjectNode*> non_escaped_worklist;
+  GrowableArray<FieldNode*>      oop_fields_worklist;
+  DEBUG_ONLY( GrowableArray<Node*> addp_worklist; )
+
+  { Compile::TracePhase t3("connectionGraph", &Phase::_t_connectionGraph, true);
+
+  // 1. Populate Connection Graph (CG) with PointsTo nodes.
+  ideal_nodes.map(C->unique(), NULL);  // preallocate space
+  // Initialize worklist
+  if (C->root() != NULL) {
+    ideal_nodes.push(C->root());
+  }
+  for( uint next = 0; next < ideal_nodes.size(); ++next ) {
+    Node* n = ideal_nodes.at(next);
+    // Create PointsTo nodes and add them to Connection Graph. Called
+    // only once per ideal node since ideal_nodes is Unique_Node list.
+    add_node_to_connection_graph(n, &delayed_worklist);
+    PointsToNode* ptn = ptnode_adr(n->_idx);
+    if (ptn != NULL) {
+      ptnodes_worklist.append(ptn);
+      if (ptn->is_JavaObject()) {
+        java_objects_worklist.append(ptn->as_JavaObject());
+        if ((n->is_Allocate() || n->is_CallStaticJava()) &&
+            (ptn->escape_state() < PointsToNode::GlobalEscape)) {
+          // Only allocations and java static calls results are interesting.
+          non_escaped_worklist.append(ptn->as_JavaObject());
+        }
+      } else if (ptn->is_Field() && ptn->as_Field()->is_oop()) {
+        oop_fields_worklist.append(ptn->as_Field());
+      }
+    }
+    if (n->is_MergeMem()) {
+      // Collect all MergeMem nodes to add memory slices for
+      // scalar replaceable objects in split_unique_types().
+      _mergemem_worklist.append(n->as_MergeMem());
+    } else if (OptimizePtrCompare && n->is_Cmp() &&
+               (n->Opcode() == Op_CmpP || n->Opcode() == Op_CmpN)) {
+      // Collect compare pointers nodes.
+      ptr_cmp_worklist.append(n);
+    } else if (n->is_MemBarStoreStore()) {
+      // Collect all MemBarStoreStore nodes so that depending on the
+      // escape status of the associated Allocate node some of them
+      // may be eliminated.
+      storestore_worklist.append(n);
+#ifdef ASSERT
+    } else if(n->is_AddP()) {
+      // Collect address nodes for graph verification.
+      addp_worklist.append(n);
+#endif
+    }
+    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+      Node* m = n->fast_out(i);   // Get user
+      ideal_nodes.push(m);
+    }
+  }
+  if (non_escaped_worklist.length() == 0) {
+    _collecting = false;
+    return false; // Nothing to do.
+  }
+  // Add final simple edges to graph.
+  while(delayed_worklist.size() > 0) {
+    Node* n = delayed_worklist.pop();
+    add_final_edges(n);
+  }
+  int ptnodes_length = ptnodes_worklist.length();
+
+#ifdef ASSERT
+  if (VerifyConnectionGraph) {
+    // Verify that no new simple edges could be created and all
+    // local vars has edges.
+    _verify = true;
+    for (int next = 0; next < ptnodes_length; ++next) {
+      PointsToNode* ptn = ptnodes_worklist.at(next);
+      add_final_edges(ptn->ideal_node());
+      if (ptn->is_LocalVar() && ptn->edge_count() == 0) {
+        ptn->dump();
+        assert(ptn->as_LocalVar()->edge_count() > 0, "sanity");
+      }
+    }
+    _verify = false;
+  }
+#endif
+
+  // 2. Finish Graph construction by propagating references to all
+  //    java objects through graph.
+  if (!complete_connection_graph(ptnodes_worklist, non_escaped_worklist,
+                                 java_objects_worklist, oop_fields_worklist)) {
+    // All objects escaped or hit time or iterations limits.
+    _collecting = false;
+    return false;
+  }
+
+  // 3. Adjust scalar_replaceable state of nonescaping objects and push
+  //    scalar replaceable allocations on alloc_worklist for processing
+  //    in split_unique_types().
+  int non_escaped_length = non_escaped_worklist.length();
+  for (int next = 0; next < non_escaped_length; next++) {
+    JavaObjectNode* ptn = non_escaped_worklist.at(next);
+    if (ptn->escape_state() == PointsToNode::NoEscape &&
+        ptn->scalar_replaceable()) {
+      adjust_scalar_replaceable_state(ptn);
+      if (ptn->scalar_replaceable()) {
+        alloc_worklist.append(ptn->ideal_node());
+      }
+    }
+  }
+
+#ifdef ASSERT
+  if (VerifyConnectionGraph) {
+    // Verify that graph is complete - no new edges could be added or needed.
+    verify_connection_graph(ptnodes_worklist, non_escaped_worklist,
+                            java_objects_worklist, addp_worklist);
+  }
+  assert(C->unique() == nodes_size(), "no new ideal nodes should be added during ConnectionGraph build");
+  assert(null_obj->escape_state() == PointsToNode::NoEscape &&
+         null_obj->edge_count() == 0 &&
+         !null_obj->arraycopy_src() &&
+         !null_obj->arraycopy_dst(), "sanity");
+#endif
+
+  _collecting = false;
+
+  } // TracePhase t3("connectionGraph")
+
+  // 4. Optimize ideal graph based on EA information.
+  bool has_non_escaping_obj = (non_escaped_worklist.length() > 0);
+  if (has_non_escaping_obj) {
+    optimize_ideal_graph(ptr_cmp_worklist, storestore_worklist);
+  }
+
+#ifndef PRODUCT
+  if (PrintEscapeAnalysis) {
+    dump(ptnodes_worklist); // Dump ConnectionGraph
+  }
+#endif
+
+  bool has_scalar_replaceable_candidates = (alloc_worklist.length() > 0);
+#ifdef ASSERT
+  if (VerifyConnectionGraph) {
+    int alloc_length = alloc_worklist.length();
+    for (int next = 0; next < alloc_length; ++next) {
+      Node* n = alloc_worklist.at(next);
+      PointsToNode* ptn = ptnode_adr(n->_idx);
+      assert(ptn->escape_state() == PointsToNode::NoEscape && ptn->scalar_replaceable(), "sanity");
+    }
+  }
+#endif
+
+  // 5. Separate memory graph for scalar replaceable allcations.
+  if (has_scalar_replaceable_candidates &&
+      C->AliasLevel() >= 3 && EliminateAllocations) {
+    // Now use the escape information to create unique types for
+    // scalar replaceable objects.
+    split_unique_types(alloc_worklist);
+    if (C->failing())  return false;
+    C->print_method("After Escape Analysis", 2);
+
+#ifdef ASSERT
+  } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
+    tty->print("=== No allocations eliminated for ");
+    C->method()->print_short_name();
+    if(!EliminateAllocations) {
+      tty->print(" since EliminateAllocations is off ===");
+    } else if(!has_scalar_replaceable_candidates) {
+      tty->print(" since there are no scalar replaceable candidates ===");
+    } else if(C->AliasLevel() < 3) {
+      tty->print(" since AliasLevel < 3 ===");
+    }
+    tty->cr();
+#endif
+  }
+  return has_non_escaping_obj;
+}
+
+// Utility function for nodes that load an object
+void ConnectionGraph::add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
+  // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+  // ThreadLocal has RawPtr type.
+  const Type* t = _igvn->type(n);
+  if (t->make_ptr() != NULL) {
+    Node* adr = n->in(MemNode::Address);
+#ifdef ASSERT
+    if (!adr->is_AddP()) {
+      assert(_igvn->type(adr)->isa_rawptr(), "sanity");
+    } else {
+      assert((ptnode_adr(adr->_idx) == NULL ||
+              ptnode_adr(adr->_idx)->as_Field()->is_oop()), "sanity");
+    }
+#endif
+    add_local_var_and_edge(n, PointsToNode::NoEscape,
+                           adr, delayed_worklist);
+  }
+}
+
+// Populate Connection Graph with PointsTo nodes and create simple
+// connection graph edges.
+void ConnectionGraph::add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist) {
+  assert(!_verify, "this method sould not be called for verification");
+  PhaseGVN* igvn = _igvn;
+  uint n_idx = n->_idx;
+  PointsToNode* n_ptn = ptnode_adr(n_idx);
+  if (n_ptn != NULL)
+    return; // No need to redefine PointsTo node during first iteration.
+
+  if (n->is_Call()) {
+    // Arguments to allocation and locking don't escape.
+    if (n->is_AbstractLock()) {
+      // Put Lock and Unlock nodes on IGVN worklist to process them during
+      // first IGVN optimization when escape information is still available.
+      record_for_optimizer(n);
+    } else if (n->is_Allocate()) {
+      add_call_node(n->as_Call());
+      record_for_optimizer(n);
+    } else {
+      if (n->is_CallStaticJava()) {
+        const char* name = n->as_CallStaticJava()->_name;
+        if (name != NULL && strcmp(name, "uncommon_trap") == 0)
+          return; // Skip uncommon traps
+      }
+      // Don't mark as processed since call's arguments have to be processed.
+      delayed_worklist->push(n);
+      // Check if a call returns an object.
+      if (n->as_Call()->returns_pointer() &&
+          n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
+        add_call_node(n->as_Call());
+      }
+    }
+    return;
+  }
+  // Put this check here to process call arguments since some call nodes
+  // point to phantom_obj.
+  if (n_ptn == phantom_obj || n_ptn == null_obj)
+    return; // Skip predefined nodes.
+
+  int opcode = n->Opcode();
+  switch (opcode) {
+    case Op_AddP: {
+      Node* base = get_addp_base(n);
+      PointsToNode* ptn_base = ptnode_adr(base->_idx);
+      // Field nodes are created for all field types. They are used in
+      // adjust_scalar_replaceable_state() and split_unique_types().
+      // Note, non-oop fields will have only base edges in Connection
+      // Graph because such fields are not used for oop loads and stores.
+      int offset = address_offset(n, igvn);
+      add_field(n, PointsToNode::NoEscape, offset);
+      if (ptn_base == NULL) {
+        delayed_worklist->push(n); // Process it later.
+      } else {
+        n_ptn = ptnode_adr(n_idx);
+        add_base(n_ptn->as_Field(), ptn_base);
+      }
+      break;
+    }
+    case Op_CastX2P: {
+      map_ideal_node(n, phantom_obj);
+      break;
+    }
+    case Op_CastPP:
+    case Op_CheckCastPP:
+    case Op_EncodeP:
+    case Op_DecodeN: {
+      add_local_var_and_edge(n, PointsToNode::NoEscape,
+                             n->in(1), delayed_worklist);
+      break;
+    }
+    case Op_CMoveP: {
+      add_local_var(n, PointsToNode::NoEscape);
+      // Do not add edges during first iteration because some could be
+      // not defined yet.
+      delayed_worklist->push(n);
+      break;
+    }
+    case Op_ConP:
+    case Op_ConN: {
+      // assume all oop constants globally escape except for null
+      PointsToNode::EscapeState es;
+      if (igvn->type(n) == TypePtr::NULL_PTR ||
+          igvn->type(n) == TypeNarrowOop::NULL_PTR) {
+        es = PointsToNode::NoEscape;
+      } else {
+        es = PointsToNode::GlobalEscape;
+      }
+      add_java_object(n, es);
+      break;
+    }
+    case Op_CreateEx: {
+      // assume that all exception objects globally escape
+      add_java_object(n, PointsToNode::GlobalEscape);
+      break;
+    }
+    case Op_LoadKlass:
+    case Op_LoadNKlass: {
+      // Unknown class is loaded
+      map_ideal_node(n, phantom_obj);
+      break;
+    }
+    case Op_LoadP:
+    case Op_LoadN:
+    case Op_LoadPLocked: {
+      add_objload_to_connection_graph(n, delayed_worklist);
+      break;
+    }
+    case Op_Parm: {
+      map_ideal_node(n, phantom_obj);
+      break;
+    }
+    case Op_PartialSubtypeCheck: {
+      // Produces Null or notNull and is used in only in CmpP so
+      // phantom_obj could be used.
+      map_ideal_node(n, phantom_obj); // Result is unknown
+      break;
+    }
+    case Op_Phi: {
+      // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+      // ThreadLocal has RawPtr type.
+      const Type* t = n->as_Phi()->type();
+      if (t->make_ptr() != NULL) {
+        add_local_var(n, PointsToNode::NoEscape);
+        // Do not add edges during first iteration because some could be
+        // not defined yet.
+        delayed_worklist->push(n);
+      }
+      break;
+    }
+    case Op_Proj: {
+      // we are only interested in the oop result projection from a call
+      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() &&
+          n->in(0)->as_Call()->returns_pointer()) {
+        add_local_var_and_edge(n, PointsToNode::NoEscape,
+                               n->in(0), delayed_worklist);
+      }
+      break;
+    }
+    case Op_Rethrow: // Exception object escapes
+    case Op_Return: {
+      if (n->req() > TypeFunc::Parms &&
+          igvn->type(n->in(TypeFunc::Parms))->isa_oopptr()) {
+        // Treat Return value as LocalVar with GlobalEscape escape state.
+        add_local_var_and_edge(n, PointsToNode::GlobalEscape,
+                               n->in(TypeFunc::Parms), delayed_worklist);
+      }
+      break;
+    }
+    case Op_GetAndSetP:
+    case Op_GetAndSetN: {
+      add_objload_to_connection_graph(n, delayed_worklist);
+      // fallthrough
+    }
+    case Op_StoreP:
+    case Op_StoreN:
+    case Op_StorePConditional:
+    case Op_CompareAndSwapP:
+    case Op_CompareAndSwapN: {
+      Node* adr = n->in(MemNode::Address);
+      const Type *adr_type = igvn->type(adr);
+      adr_type = adr_type->make_ptr();
+      if (adr_type->isa_oopptr() ||
+          (opcode == Op_StoreP || opcode == Op_StoreN) &&
+                        (adr_type == TypeRawPtr::NOTNULL &&
+                         adr->in(AddPNode::Address)->is_Proj() &&
+                         adr->in(AddPNode::Address)->in(0)->is_Allocate())) {
+        delayed_worklist->push(n); // Process it later.
+#ifdef ASSERT
+        assert(adr->is_AddP(), "expecting an AddP");
+        if (adr_type == TypeRawPtr::NOTNULL) {
+          // Verify a raw address for a store captured by Initialize node.
+          int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
+          assert(offs != Type::OffsetBot, "offset must be a constant");
+        }
+#endif
+      } else {
+        // Ignore copy the displaced header to the BoxNode (OSR compilation).
+        if (adr->is_BoxLock())
+          break;
+        // Stored value escapes in unsafe access.
+        if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) {
+          // Pointer stores in G1 barriers looks like unsafe access.
+          // Ignore such stores to be able scalar replace non-escaping
+          // allocations.
+          if (UseG1GC && adr->is_AddP()) {
+            Node* base = get_addp_base(adr);
+            if (base->Opcode() == Op_LoadP &&
+                base->in(MemNode::Address)->is_AddP()) {
+              adr = base->in(MemNode::Address);
+              Node* tls = get_addp_base(adr);
+              if (tls->Opcode() == Op_ThreadLocal) {
+                int offs = (int)igvn->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
+                if (offs == in_bytes(JavaThread::satb_mark_queue_offset() +
+                                     PtrQueue::byte_offset_of_buf())) {
+                  break; // G1 pre barier previous oop value store.
+                }
+                if (offs == in_bytes(JavaThread::dirty_card_queue_offset() +
+                                     PtrQueue::byte_offset_of_buf())) {
+                  break; // G1 post barier card address store.
+                }
+              }
+            }
+          }
+          delayed_worklist->push(n); // Process unsafe access later.
+          break;
+        }
+#ifdef ASSERT
+        n->dump(1);
+        assert(false, "not unsafe or G1 barrier raw StoreP");
+#endif
+      }
+      break;
+    }
+    case Op_AryEq:
+    case Op_StrComp:
+    case Op_StrEquals:
+    case Op_StrIndexOf: {
+      add_local_var(n, PointsToNode::ArgEscape);
+      delayed_worklist->push(n); // Process it later.
+      break;
+    }
+    case Op_ThreadLocal: {
+      add_java_object(n, PointsToNode::ArgEscape);
+      break;
+    }
+    default:
+      ; // Do nothing for nodes not related to EA.
+  }
+  return;
+}
+
+#ifdef ASSERT
+#define ELSE_FAIL(name)                               \
+      /* Should not be called for not pointer type. */  \
+      n->dump(1);                                       \
+      assert(false, name);                              \
+      break;
+#else
+#define ELSE_FAIL(name) \
+      break;
+#endif
+
+// Add final simple edges to graph.
+void ConnectionGraph::add_final_edges(Node *n) {
+  PointsToNode* n_ptn = ptnode_adr(n->_idx);
+#ifdef ASSERT
+  if (_verify && n_ptn->is_JavaObject())
+    return; // This method does not change graph for JavaObject.
+#endif
+
+  if (n->is_Call()) {
+    process_call_arguments(n->as_Call());
+    return;
+  }
+  assert(n->is_Store() || n->is_LoadStore() ||
+         (n_ptn != NULL) && (n_ptn->ideal_node() != NULL),
+         "node should be registered already");
+  int opcode = n->Opcode();
+  switch (opcode) {
+    case Op_AddP: {
+      Node* base = get_addp_base(n);
+      PointsToNode* ptn_base = ptnode_adr(base->_idx);
+      assert(ptn_base != NULL, "field's base should be registered");
+      add_base(n_ptn->as_Field(), ptn_base);
+      break;
+    }
+    case Op_CastPP:
+    case Op_CheckCastPP:
+    case Op_EncodeP:
+    case Op_DecodeN: {
+      add_local_var_and_edge(n, PointsToNode::NoEscape,
+                             n->in(1), NULL);
+      break;
+    }
+    case Op_CMoveP: {
+      for (uint i = CMoveNode::IfFalse; i < n->req(); i++) {
+        Node* in = n->in(i);
+        if (in == NULL)
+          continue;  // ignore NULL
+        Node* uncast_in = in->uncast();
+        if (uncast_in->is_top() || uncast_in == n)
+          continue;  // ignore top or inputs which go back this node
+        PointsToNode* ptn = ptnode_adr(in->_idx);
+        assert(ptn != NULL, "node should be registered");
+        add_edge(n_ptn, ptn);
+      }
+      break;
+    }
+    case Op_LoadP:
+    case Op_LoadN:
+    case Op_LoadPLocked: {
+      // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+      // ThreadLocal has RawPtr type.
+      const Type* t = _igvn->type(n);
+      if (t->make_ptr() != NULL) {
+        Node* adr = n->in(MemNode::Address);
+        add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
+        break;
+      }
+      ELSE_FAIL("Op_LoadP");
+    }
+    case Op_Phi: {
+      // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
+      // ThreadLocal has RawPtr type.
+      const Type* t = n->as_Phi()->type();
+      if (t->make_ptr() != NULL) {
+        for (uint i = 1; i < n->req(); i++) {
+          Node* in = n->in(i);
+          if (in == NULL)
+            continue;  // ignore NULL
+          Node* uncast_in = in->uncast();
+          if (uncast_in->is_top() || uncast_in == n)
+            continue;  // ignore top or inputs which go back this node
+          PointsToNode* ptn = ptnode_adr(in->_idx);
+          assert(ptn != NULL, "node should be registered");
+          add_edge(n_ptn, ptn);
+        }
+        break;
+      }
+      ELSE_FAIL("Op_Phi");
+    }
+    case Op_Proj: {
+      // we are only interested in the oop result projection from a call
+      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() &&
+          n->in(0)->as_Call()->returns_pointer()) {
+        add_local_var_and_edge(n, PointsToNode::NoEscape, n->in(0), NULL);
+        break;
+      }
+      ELSE_FAIL("Op_Proj");
+    }
+    case Op_Rethrow: // Exception object escapes
+    case Op_Return: {
+      if (n->req() > TypeFunc::Parms &&
+          _igvn->type(n->in(TypeFunc::Parms))->isa_oopptr()) {
+        // Treat Return value as LocalVar with GlobalEscape escape state.
+        add_local_var_and_edge(n, PointsToNode::GlobalEscape,
+                               n->in(TypeFunc::Parms), NULL);
+        break;
+      }
+      ELSE_FAIL("Op_Return");
+    }
+    case Op_StoreP:
+    case Op_StoreN:
+    case Op_StorePConditional:
+    case Op_CompareAndSwapP:
+    case Op_CompareAndSwapN:
+    case Op_GetAndSetP:
+    case Op_GetAndSetN: {
+      Node* adr = n->in(MemNode::Address);
+      if (opcode == Op_GetAndSetP || opcode == Op_GetAndSetN) {
+        const Type* t = _igvn->type(n);
+        if (t->make_ptr() != NULL) {
+          add_local_var_and_edge(n, PointsToNode::NoEscape, adr, NULL);
+        }
+      }
+      const Type *adr_type = _igvn->type(adr);
+      adr_type = adr_type->make_ptr();
+      if (adr_type->isa_oopptr() ||
+          (opcode == Op_StoreP || opcode == Op_StoreN) &&
+                        (adr_type == TypeRawPtr::NOTNULL &&
+                         adr->in(AddPNode::Address)->is_Proj() &&
+                         adr->in(AddPNode::Address)->in(0)->is_Allocate())) {
+        // Point Address to Value
+        PointsToNode* adr_ptn = ptnode_adr(adr->_idx);
+        assert(adr_ptn != NULL &&
+               adr_ptn->as_Field()->is_oop(), "node should be registered");
+        Node *val = n->in(MemNode::ValueIn);
+        PointsToNode* ptn = ptnode_adr(val->_idx);
+        assert(ptn != NULL, "node should be registered");
+        add_edge(adr_ptn, ptn);
+        break;
+      } else if ((opcode == Op_StoreP) && (adr_type == TypeRawPtr::BOTTOM)) {
+        // Stored value escapes in unsafe access.
+        Node *val = n->in(MemNode::ValueIn);
+        PointsToNode* ptn = ptnode_adr(val->_idx);
+        assert(ptn != NULL, "node should be registered");
+        ptn->set_escape_state(PointsToNode::GlobalEscape);
+        // Add edge to object for unsafe access with offset.
+        PointsToNode* adr_ptn = ptnode_adr(adr->_idx);
+        assert(adr_ptn != NULL, "node should be registered");
+        if (adr_ptn->is_Field()) {
+          assert(adr_ptn->as_Field()->is_oop(), "should be oop field");
+          add_edge(adr_ptn, ptn);
+        }
+        break;
+      }
+      ELSE_FAIL("Op_StoreP");
+    }
+    case Op_AryEq:
+    case Op_StrComp:
+    case Op_StrEquals:
+    case Op_StrIndexOf: {
+      // char[] arrays passed to string intrinsic do not escape but
+      // they are not scalar replaceable. Adjust escape state for them.
+      // Start from in(2) edge since in(1) is memory edge.
+      for (uint i = 2; i < n->req(); i++) {
+        Node* adr = n->in(i);
+        const Type* at = _igvn->type(adr);
+        if (!adr->is_top() && at->isa_ptr()) {
+          assert(at == Type::TOP || at == TypePtr::NULL_PTR ||
+                 at->isa_ptr() != NULL, "expecting a pointer");
+          if (adr->is_AddP()) {
+            adr = get_addp_base(adr);
+          }
+          PointsToNode* ptn = ptnode_adr(adr->_idx);
+          assert(ptn != NULL, "node should be registered");
+          add_edge(n_ptn, ptn);
+        }
+      }
+      break;
+    }
+    default: {
+      // This method should be called only for EA specific nodes which may
+      // miss some edges when they were created.
+#ifdef ASSERT
+      n->dump(1);
+#endif
+      guarantee(false, "unknown node");
+    }
+  }
+  return;
+}
+
+void ConnectionGraph::add_call_node(CallNode* call) {
+  assert(call->returns_pointer(), "only for call which returns pointer");
+  uint call_idx = call->_idx;
+  if (call->is_Allocate()) {
+    Node* k = call->in(AllocateNode::KlassNode);
+    const TypeKlassPtr* kt = k->bottom_type()->isa_klassptr();
+    assert(kt != NULL, "TypeKlassPtr  required.");
+    ciKlass* cik = kt->klass();
+    PointsToNode::EscapeState es = PointsToNode::NoEscape;
+    bool scalar_replaceable = true;
+    if (call->is_AllocateArray()) {
+      if (!cik->is_array_klass()) { // StressReflectiveCode
+        es = PointsToNode::GlobalEscape;
+      } else {
+        int length = call->in(AllocateNode::ALength)->find_int_con(-1);
+        if (length < 0 || length > EliminateAllocationArraySizeLimit) {
+          // Not scalar replaceable if the length is not constant or too big.
+          scalar_replaceable = false;
+        }
+      }
+    } else {  // Allocate instance
+      if (cik->is_subclass_of(_compile->env()->Thread_klass()) ||
+         !cik->is_instance_klass() || // StressReflectiveCode
+          cik->as_instance_klass()->has_finalizer()) {
+        es = PointsToNode::GlobalEscape;
+      }
+    }
+    add_java_object(call, es);
+    PointsToNode* ptn = ptnode_adr(call_idx);
+    if (!scalar_replaceable && ptn->scalar_replaceable()) {
+      ptn->set_scalar_replaceable(false);
+    }
+  } else if (call->is_CallStaticJava()) {
+    // Call nodes could be different types:
+    //
+    // 1. CallDynamicJavaNode (what happened during call is unknown):
+    //
+    //    - mapped to GlobalEscape JavaObject node if oop is returned;
+    //
+    //    - all oop arguments are escaping globally;
+    //
+    // 2. CallStaticJavaNode (execute bytecode analysis if possible):
+    //
+    //    - the same as CallDynamicJavaNode if can't do bytecode analysis;
+    //
+    //    - mapped to GlobalEscape JavaObject node if unknown oop is returned;
+    //    - mapped to NoEscape JavaObject node if non-escaping object allocated
+    //      during call is returned;
+    //    - mapped to ArgEscape LocalVar node pointed to object arguments
+    //      which are returned and does not escape during call;
+    //
+    //    - oop arguments escaping status is defined by bytecode analysis;
+    //
+    // For a static call, we know exactly what method is being called.
+    // Use bytecode estimator to record whether the call's return value escapes.
+    ciMethod* meth = call->as_CallJava()->method();
+    if (meth == NULL) {
+      const char* name = call->as_CallStaticJava()->_name;
+      assert(strncmp(name, "_multianewarray", 15) == 0, "TODO: add failed case check");
+      // Returns a newly allocated unescaped object.
+      add_java_object(call, PointsToNode::NoEscape);
+      ptnode_adr(call_idx)->set_scalar_replaceable(false);
+    } else {
+      BCEscapeAnalyzer* call_analyzer = meth->get_bcea();
+      call_analyzer->copy_dependencies(_compile->dependencies());
+      if (call_analyzer->is_return_allocated()) {
+        // Returns a newly allocated unescaped object, simply
+        // update dependency information.
+        // Mark it as NoEscape so that objects referenced by
+        // it's fields will be marked as NoEscape at least.
+        add_java_object(call, PointsToNode::NoEscape);
+        ptnode_adr(call_idx)->set_scalar_replaceable(false);
+      } else {
+        // Determine whether any arguments are returned.
+        const TypeTuple* d = call->tf()->domain();
+        bool ret_arg = false;
+        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+          if (d->field_at(i)->isa_ptr() != NULL &&
+              call_analyzer->is_arg_returned(i - TypeFunc::Parms)) {
+            ret_arg = true;
+            break;
+          }
+        }
+        if (ret_arg) {
+          add_local_var(call, PointsToNode::ArgEscape);
+        } else {
+          // Returns unknown object.
+          map_ideal_node(call, phantom_obj);
+        }
+      }
+    }
+  } else {
+    // An other type of call, assume the worst case:
+    // returned value is unknown and globally escapes.
+    assert(call->Opcode() == Op_CallDynamicJava, "add failed case check");
+    map_ideal_node(call, phantom_obj);
+  }
+}
+
+void ConnectionGraph::process_call_arguments(CallNode *call) {
+    bool is_arraycopy = false;
+    switch (call->Opcode()) {
+#ifdef ASSERT
+    case Op_Allocate:
+    case Op_AllocateArray:
+    case Op_Lock:
+    case Op_Unlock:
+      assert(false, "should be done already");
+      break;
+#endif
+    case Op_CallLeafNoFP:
+      is_arraycopy = (call->as_CallLeaf()->_name != NULL &&
+                      strstr(call->as_CallLeaf()->_name, "arraycopy") != 0);
+      // fall through
+    case Op_CallLeaf: {
+      // Stub calls, objects do not escape but they are not scale replaceable.
+      // Adjust escape state for outgoing arguments.
+      const TypeTuple * d = call->tf()->domain();
+      bool src_has_oops = false;
+      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+        const Type* at = d->field_at(i);
+        Node *arg = call->in(i);
+        const Type *aat = _igvn->type(arg);
+        if (arg->is_top() || !at->isa_ptr() || !aat->isa_ptr())
+          continue;
+        if (arg->is_AddP()) {
+          //
+          // The inline_native_clone() case when the arraycopy stub is called
+          // after the allocation before Initialize and CheckCastPP nodes.
+          // Or normal arraycopy for object arrays case.
+          //
+          // Set AddP's base (Allocate) as not scalar replaceable since
+          // pointer to the base (with offset) is passed as argument.
+          //
+          arg = get_addp_base(arg);
+        }
+        PointsToNode* arg_ptn = ptnode_adr(arg->_idx);
+        assert(arg_ptn != NULL, "should be registered");
+        PointsToNode::EscapeState arg_esc = arg_ptn->escape_state();
+        if (is_arraycopy || arg_esc < PointsToNode::ArgEscape) {
+          assert(aat == Type::TOP || aat == TypePtr::NULL_PTR ||
+                 aat->isa_ptr() != NULL, "expecting an Ptr");
+          bool arg_has_oops = aat->isa_oopptr() &&
+                              (aat->isa_oopptr()->klass() == NULL || aat->isa_instptr() ||
+                               (aat->isa_aryptr() && aat->isa_aryptr()->klass()->is_obj_array_klass()));
+          if (i == TypeFunc::Parms) {
+            src_has_oops = arg_has_oops;
+          }
+          //
+          // src or dst could be j.l.Object when other is basic type array:
+          //
+          //   arraycopy(char[],0,Object*,0,size);
+          //   arraycopy(Object*,0,char[],0,size);
+          //
+          // Don't add edges in such cases.
+          //
+          bool arg_is_arraycopy_dest = src_has_oops && is_arraycopy &&
+                                       arg_has_oops && (i > TypeFunc::Parms);
+#ifdef ASSERT
+          if (!(is_arraycopy ||
+                (call->as_CallLeaf()->_name != NULL &&
+                 (strcmp(call->as_CallLeaf()->_name, "g1_wb_pre")  == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "g1_wb_post") == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "aescrypt_encryptBlock") == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "aescrypt_decryptBlock") == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_encryptAESCrypt") == 0 ||
+                  strcmp(call->as_CallLeaf()->_name, "cipherBlockChaining_decryptAESCrypt") == 0)
+                  ))) {
+            call->dump();
+            fatal(err_msg_res("EA unexpected CallLeaf %s", call->as_CallLeaf()->_name));
+          }
+#endif
+          // Always process arraycopy's destination object since
+          // we need to add all possible edges to references in
+          // source object.
+          if (arg_esc >= PointsToNode::ArgEscape &&
+              !arg_is_arraycopy_dest) {
+            continue;
+          }
+          set_escape_state(arg_ptn, PointsToNode::ArgEscape);
+          if (arg_is_arraycopy_dest) {
+            Node* src = call->in(TypeFunc::Parms);
+            if (src->is_AddP()) {
+              src = get_addp_base(src);
+            }
+            PointsToNode* src_ptn = ptnode_adr(src->_idx);
+            assert(src_ptn != NULL, "should be registered");
+            if (arg_ptn != src_ptn) {
+              // Special arraycopy edge:
+              // A destination object's field can't have the source object
+              // as base since objects escape states are not related.
+              // Only escape state of destination object's fields affects
+              // escape state of fields in source object.
+              add_arraycopy(call, PointsToNode::ArgEscape, src_ptn, arg_ptn);
+            }
+          }
+        }
+      }
+      break;
+    }
+    case Op_CallStaticJava: {
+      // For a static call, we know exactly what method is being called.
+      // Use bytecode estimator to record the call's escape affects
+#ifdef ASSERT
+      const char* name = call->as_CallStaticJava()->_name;
+      assert((name == NULL || strcmp(name, "uncommon_trap") != 0), "normal calls only");
+#endif
+      ciMethod* meth = call->as_CallJava()->method();
+      BCEscapeAnalyzer* call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL;
+      // fall-through if not a Java method or no analyzer information
+      if (call_analyzer != NULL) {
+        PointsToNode* call_ptn = ptnode_adr(call->_idx);
+        const TypeTuple* d = call->tf()->domain();
+        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+          const Type* at = d->field_at(i);
+          int k = i - TypeFunc::Parms;
+          Node* arg = call->in(i);
+          PointsToNode* arg_ptn = ptnode_adr(arg->_idx);
+          if (at->isa_ptr() != NULL &&
+              call_analyzer->is_arg_returned(k)) {
+            // The call returns arguments.
+            if (call_ptn != NULL) { // Is call's result used?
+              assert(call_ptn->is_LocalVar(), "node should be registered");
+              assert(arg_ptn != NULL, "node should be registered");
+              add_edge(call_ptn, arg_ptn);
+            }
+          }
+          if (at->isa_oopptr() != NULL &&
+              arg_ptn->escape_state() < PointsToNode::GlobalEscape) {
+            if (!call_analyzer->is_arg_stack(k)) {
+              // The argument global escapes
+              set_escape_state(arg_ptn, PointsToNode::GlobalEscape);
+            } else {
+              set_escape_state(arg_ptn, PointsToNode::ArgEscape);
+              if (!call_analyzer->is_arg_local(k)) {
+                // The argument itself doesn't escape, but any fields might
+                set_fields_escape_state(arg_ptn, PointsToNode::GlobalEscape);
+              }
+            }
+          }
+        }
+        if (call_ptn != NULL && call_ptn->is_LocalVar()) {
+          // The call returns arguments.
+          assert(call_ptn->edge_count() > 0, "sanity");
+          if (!call_analyzer->is_return_local()) {
+            // Returns also unknown object.
+            add_edge(call_ptn, phantom_obj);
+          }
+        }
+        break;
+      }
+    }
+    default: {
+      // Fall-through here if not a Java method or no analyzer information
+      // or some other type of call, assume the worst case: all arguments
+      // globally escape.
+      const TypeTuple* d = call->tf()->domain();
+      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
+        const Type* at = d->field_at(i);
+        if (at->isa_oopptr() != NULL) {
+          Node* arg = call->in(i);
+          if (arg->is_AddP()) {
+            arg = get_addp_base(arg);
+          }
+          assert(ptnode_adr(arg->_idx) != NULL, "should be defined already");
+          set_escape_state(ptnode_adr(arg->_idx), PointsToNode::GlobalEscape);
+        }
+      }
+    }
+  }
+}
+
+
+// Finish Graph construction.
+bool ConnectionGraph::complete_connection_graph(
+                         GrowableArray<PointsToNode*>&   ptnodes_worklist,
+                         GrowableArray<JavaObjectNode*>& non_escaped_worklist,
+                         GrowableArray<JavaObjectNode*>& java_objects_worklist,
+                         GrowableArray<FieldNode*>&      oop_fields_worklist) {
+  // Normally only 1-3 passes needed to build Connection Graph depending
+  // on graph complexity. Observed 8 passes in jvm2008 compiler.compiler.
+  // Set limit to 20 to catch situation when something did go wrong and
+  // bailout Escape Analysis.
+  // Also limit build time to 30 sec (60 in debug VM).
+#define CG_BUILD_ITER_LIMIT 20
+#ifdef ASSERT
+#define CG_BUILD_TIME_LIMIT 60.0
+#else
+#define CG_BUILD_TIME_LIMIT 30.0
+#endif
+
+  // Propagate GlobalEscape and ArgEscape escape states and check that
+  // we still have non-escaping objects. The method pushs on _worklist
+  // Field nodes which reference phantom_object.
+  if (!find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist)) {
+    return false; // Nothing to do.
+  }
+  // Now propagate references to all JavaObject nodes.
+  int java_objects_length = java_objects_worklist.length();
+  elapsedTimer time;
+  int new_edges = 1;
+  int iterations = 0;
+  do {
+    while ((new_edges > 0) &&
+          (iterations++   < CG_BUILD_ITER_LIMIT) &&
+          (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+      time.start();
+      new_edges = 0;
+      // Propagate references to phantom_object for nodes pushed on _worklist
+      // by find_non_escaped_objects() and find_field_value().
+      new_edges += add_java_object_edges(phantom_obj, false);
+      for (int next = 0; next < java_objects_length; ++next) {
+        JavaObjectNode* ptn = java_objects_worklist.at(next);
+        new_edges += add_java_object_edges(ptn, true);
+      }
+      if (new_edges > 0) {
+        // Update escape states on each iteration if graph was updated.
+        if (!find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist)) {
+          return false; // Nothing to do.
+        }
+      }
+      time.stop();
+    }
+    if ((iterations     < CG_BUILD_ITER_LIMIT) &&
+        (time.seconds() < CG_BUILD_TIME_LIMIT)) {
+      time.start();
+      // Find fields which have unknown value.
+      int fields_length = oop_fields_worklist.length();
+      for (int next = 0; next < fields_length; next++) {
+        FieldNode* field = oop_fields_worklist.at(next);
+        if (field->edge_count() == 0) {
+          new_edges += find_field_value(field);
+          // This code may added new edges to phantom_object.
+          // Need an other cycle to propagate references to phantom_object.
+        }
+      }
+      time.stop();
+    } else {
+      new_edges = 0; // Bailout
+    }
+  } while (new_edges > 0);
+
+  // Bailout if passed limits.
+  if ((iterations     >= CG_BUILD_ITER_LIMIT) ||
+      (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
+    Compile* C = _compile;
+    if (C->log() != NULL) {
+      C->log()->begin_elem("connectionGraph_bailout reason='reached ");
+      C->log()->text("%s", (iterations >= CG_BUILD_ITER_LIMIT) ? "iterations" : "time");
+      C->log()->end_elem(" limit'");
+    }
+    assert(ExitEscapeAnalysisOnTimeout, err_msg_res("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
+           time.seconds(), iterations, nodes_size(), ptnodes_worklist.length()));
+    // Possible infinite build_connection_graph loop,
+    // bailout (no changes to ideal graph were made).
+    return false;
+  }
+#ifdef ASSERT
+  if (Verbose && PrintEscapeAnalysis) {
+    tty->print_cr("EA: %d iterations to build connection graph with %d nodes and worklist size %d",
+                  iterations, nodes_size(), ptnodes_worklist.length());
+  }
+#endif
+
+#undef CG_BUILD_ITER_LIMIT
+#undef CG_BUILD_TIME_LIMIT
+
+  // Find fields initialized by NULL for non-escaping Allocations.
+  int non_escaped_length = non_escaped_worklist.length();
+  for (int next = 0; next < non_escaped_length; next++) {
+    JavaObjectNode* ptn = non_escaped_worklist.at(next);
+    PointsToNode::EscapeState es = ptn->escape_state();
+    assert(es <= PointsToNode::ArgEscape, "sanity");
+    if (es == PointsToNode::NoEscape) {
+      if (find_init_values(ptn, null_obj, _igvn) > 0) {
+        // Adding references to NULL object does not change escape states
+        // since it does not escape. Also no fields are added to NULL object.
+        add_java_object_edges(null_obj, false);
+      }
+    }
+    Node* n = ptn->ideal_node();
+    if (n->is_Allocate()) {
+      // The object allocated by this Allocate node will never be
+      // seen by an other thread. Mark it so that when it is
+      // expanded no MemBarStoreStore is added.
+      InitializeNode* ini = n->as_Allocate()->initialization();
+      if (ini != NULL)
+        ini->set_does_not_escape();
+    }
+  }
+  return true; // Finished graph construction.
+}
+
+// Propagate GlobalEscape and ArgEscape escape states to all nodes
+// and check that we still have non-escaping java objects.
+bool ConnectionGraph::find_non_escaped_objects(GrowableArray<PointsToNode*>& ptnodes_worklist,
+                                               GrowableArray<JavaObjectNode*>& non_escaped_worklist) {
+  GrowableArray<PointsToNode*> escape_worklist;
+  // First, put all nodes with GlobalEscape and ArgEscape states on worklist.
+  int ptnodes_length = ptnodes_worklist.length();
+  for (int next = 0; next < ptnodes_length; ++next) {
+    PointsToNode* ptn = ptnodes_worklist.at(next);
+    if (ptn->escape_state() >= PointsToNode::ArgEscape ||
+        ptn->fields_escape_state() >= PointsToNode::ArgEscape) {
+      escape_worklist.push(ptn);
+    }
+  }
+  // Set escape states to referenced nodes (edges list).
+  while (escape_worklist.length() > 0) {
+    PointsToNode* ptn = escape_worklist.pop();
+    PointsToNode::EscapeState es  = ptn->escape_state();
+    PointsToNode::EscapeState field_es = ptn->fields_escape_state();
+    if (ptn->is_Field() && ptn->as_Field()->is_oop() &&
+        es >= PointsToNode::ArgEscape) {
+      // GlobalEscape or ArgEscape state of field means it has unknown value.
+      if (add_edge(ptn, phantom_obj)) {
+        // New edge was added
+        add_field_uses_to_worklist(ptn->as_Field());
+      }
+    }
+    for (EdgeIterator i(ptn); i.has_next(); i.next()) {
+      PointsToNode* e = i.get();
+      if (e->is_Arraycopy()) {
+        assert(ptn->arraycopy_dst(), "sanity");
+        // Propagate only fields escape state through arraycopy edge.
+        if (e->fields_escape_state() < field_es) {
+          set_fields_escape_state(e, field_es);
+          escape_worklist.push(e);
+        }
+      } else if (es >= field_es) {
+        // fields_escape_state is also set to 'es' if it is less than 'es'.
+        if (e->escape_state() < es) {
+          set_escape_state(e, es);
+          escape_worklist.push(e);
+        }
+      } else {
+        // Propagate field escape state.
+        bool es_changed = false;
+        if (e->fields_escape_state() < field_es) {
+          set_fields_escape_state(e, field_es);
+          es_changed = true;
+        }
+        if ((e->escape_state() < field_es) &&
+            e->is_Field() && ptn->is_JavaObject() &&
+            e->as_Field()->is_oop()) {
+          // Change escape state of referenced fileds.
+          set_escape_state(e, field_es);
+          es_changed = true;;
+        } else if (e->escape_state() < es) {
+          set_escape_state(e, es);
+          es_changed = true;;
+        }
+        if (es_changed) {
+          escape_worklist.push(e);
+        }
+      }
+    }
+  }
+  // Remove escaped objects from non_escaped list.
+  for (int next = non_escaped_worklist.length()-1; next >= 0 ; --next) {
+    JavaObjectNode* ptn = non_escaped_worklist.at(next);
+    if (ptn->escape_state() >= PointsToNode::GlobalEscape) {
+      non_escaped_worklist.delete_at(next);
+    }
+    if (ptn->escape_state() == PointsToNode::NoEscape) {
+      // Find fields in non-escaped allocations which have unknown value.
+      find_init_values(ptn, phantom_obj, NULL);
+    }
+  }
+  return (non_escaped_worklist.length() > 0);
+}
+
+// Add all references to JavaObject node by walking over all uses.
+int ConnectionGraph::add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist) {
+  int new_edges = 0;
+  if (populate_worklist) {
+    // Populate _worklist by uses of jobj's uses.
+    for (UseIterator i(jobj); i.has_next(); i.next()) {
+      PointsToNode* use = i.get();
+      if (use->is_Arraycopy())
+        continue;
+      add_uses_to_worklist(use);
+      if (use->is_Field() && use->as_Field()->is_oop()) {
+        // Put on worklist all field's uses (loads) and
+        // related field nodes (same base and offset).
+        add_field_uses_to_worklist(use->as_Field());
+      }
+    }
+  }
+  while(_worklist.length() > 0) {
+    PointsToNode* use = _worklist.pop();
+    if (PointsToNode::is_base_use(use)) {
+      // Add reference from jobj to field and from field to jobj (field's base).
+      use = PointsToNode::get_use_node(use)->as_Field();
+      if (add_base(use->as_Field(), jobj)) {
+        new_edges++;
+      }
+      continue;
+    }
+    assert(!use->is_JavaObject(), "sanity");
+    if (use->is_Arraycopy()) {
+      if (jobj == null_obj) // NULL object does not have field edges
+        continue;
+      // Added edge from Arraycopy node to arraycopy's source java object
+      if (add_edge(use, jobj)) {
+        jobj->set_arraycopy_src();
+        new_edges++;
+      }
+      // and stop here.
+      continue;
+    }
+    if (!add_edge(use, jobj))
+      continue; // No new edge added, there was such edge already.
+    new_edges++;
+    if (use->is_LocalVar()) {
+      add_uses_to_worklist(use);
+      if (use->arraycopy_dst()) {
+        for (EdgeIterator i(use); i.has_next(); i.next()) {
+          PointsToNode* e = i.get();
+          if (e->is_Arraycopy()) {
+            if (jobj == null_obj) // NULL object does not have field edges
+              continue;
+            // Add edge from arraycopy's destination java object to Arraycopy node.
+            if (add_edge(jobj, e)) {
+              new_edges++;
+              jobj->set_arraycopy_dst();
+            }
+          }
+        }
+      }
+    } else {
+      // Added new edge to stored in field values.
+      // Put on worklist all field's uses (loads) and
+      // related field nodes (same base and offset).
+      add_field_uses_to_worklist(use->as_Field());
+    }
+  }
+  return new_edges;
+}
+
+// Put on worklist all related field nodes.
+void ConnectionGraph::add_field_uses_to_worklist(FieldNode* field) {
+  assert(field->is_oop(), "sanity");
+  int offset = field->offset();
+  add_uses_to_worklist(field);
+  // Loop over all bases of this field and push on worklist Field nodes
+  // with the same offset and base (since they may reference the same field).
+  for (BaseIterator i(field); i.has_next(); i.next()) {
+    PointsToNode* base = i.get();
+    add_fields_to_worklist(field, base);
+    // Check if the base was source object of arraycopy and go over arraycopy's
+    // destination objects since values stored to a field of source object are
+    // accessable by uses (loads) of fields of destination objects.
+    if (base->arraycopy_src()) {
+      for (UseIterator j(base); j.has_next(); j.next()) {
+        PointsToNode* arycp = j.get();
+        if (arycp->is_Arraycopy()) {
+          for (UseIterator k(arycp); k.has_next(); k.next()) {
+            PointsToNode* abase = k.get();
+            if (abase->arraycopy_dst() && abase != base) {
+              // Look for the same arracopy reference.
+              add_fields_to_worklist(field, abase);
+            }
+          }
+        }
+      }
+    }
+  }
+}
+
+// Put on worklist all related field nodes.
+void ConnectionGraph::add_fields_to_worklist(FieldNode* field, PointsToNode* base) {
+  int offset = field->offset();
+  if (base->is_LocalVar()) {
+    for (UseIterator j(base); j.has_next(); j.next()) {
+      PointsToNode* f = j.get();
+      if (PointsToNode::is_base_use(f)) { // Field
+        f = PointsToNode::get_use_node(f);
+        if (f == field || !f->as_Field()->is_oop())
+          continue;
+        int offs = f->as_Field()->offset();
+        if (offs == offset || offset == Type::OffsetBot || offs == Type::OffsetBot) {
+          add_to_worklist(f);
+        }
+      }
+    }
+  } else {
+    assert(base->is_JavaObject(), "sanity");
+    if (// Skip phantom_object since it is only used to indicate that
+        // this field's content globally escapes.
+        (base != phantom_obj) &&
+        // NULL object node does not have fields.
+        (base != null_obj)) {
+      for (EdgeIterator i(base); i.has_next(); i.next()) {
+        PointsToNode* f = i.get();
+        // Skip arraycopy edge since store to destination object field
+        // does not update value in source object field.
+        if (f->is_Arraycopy()) {
+          assert(base->arraycopy_dst(), "sanity");
+          continue;
+        }
+        if (f == field || !f->as_Field()->is_oop())
+          continue;
+        int offs = f->as_Field()->offset();
+        if (offs == offset || offset == Type::OffsetBot || offs == Type::OffsetBot) {
+          add_to_worklist(f);
+        }
+      }
+    }
+  }
+}
+
+// Find fields which have unknown value.
+int ConnectionGraph::find_field_value(FieldNode* field) {
+  // Escaped fields should have init value already.
+  assert(field->escape_state() == PointsToNode::NoEscape, "sanity");
+  int new_edges = 0;
+  for (BaseIterator i(field); i.has_next(); i.next()) {
+    PointsToNode* base = i.get();
+    if (base->is_JavaObject()) {
+      // Skip Allocate's fields which will be processed later.
+      if (base->ideal_node()->is_Allocate())
+        return 0;
+      assert(base == null_obj, "only NULL ptr base expected here");
+    }
+  }
+  if (add_edge(field, phantom_obj)) {
+    // New edge was added
+    new_edges++;
+    add_field_uses_to_worklist(field);
+  }
+  return new_edges;
+}
+
+// Find fields initializing values for allocations.
+int ConnectionGraph::find_init_values(JavaObjectNode* pta, PointsToNode* init_val, PhaseTransform* phase) {
+  assert(pta->escape_state() == PointsToNode::NoEscape, "Not escaped Allocate nodes only");
+  int new_edges = 0;
+  Node* alloc = pta->ideal_node();
+  if (init_val == phantom_obj) {
+    // Do nothing for Allocate nodes since its fields values are "known".
+    if (alloc->is_Allocate())
+      return 0;
+    assert(alloc->as_CallStaticJava(), "sanity");
+#ifdef ASSERT
+    if (alloc->as_CallStaticJava()->method() == NULL) {
+      const char* name = alloc->as_CallStaticJava()->_name;
+      assert(strncmp(name, "_multianewarray", 15) == 0, "sanity");
+    }
+#endif
+    // Non-escaped allocation returned from Java or runtime call have
+    // unknown values in fields.
+    for (EdgeIterator i(pta); i.has_next(); i.next()) {
+      PointsToNode* field = i.get();
+      if (field->is_Field() && field->as_Field()->is_oop()) {
+        if (add_edge(field, phantom_obj)) {
+          // New edge was added
+          new_edges++;
+          add_field_uses_to_worklist(field->as_Field());
+        }
+      }
+    }
+    return new_edges;
+  }
+  assert(init_val == null_obj, "sanity");
+  // Do nothing for Call nodes since its fields values are unknown.
+  if (!alloc->is_Allocate())
+    return 0;
+
+  InitializeNode* ini = alloc->as_Allocate()->initialization();
+  Compile* C = _compile;
+  bool visited_bottom_offset = false;
+  GrowableArray<int> offsets_worklist;
+
+  // Check if an oop field's initializing value is recorded and add
+  // a corresponding NULL if field's value if it is not recorded.
+  // Connection Graph does not record a default initialization by NULL
+  // captured by Initialize node.
+  //
+  for (EdgeIterator i(pta); i.has_next(); i.next()) {
+    PointsToNode* field = i.get(); // Field (AddP)
+    if (!field->is_Field() || !field->as_Field()->is_oop())
+      continue; // Not oop field
+    int offset = field->as_Field()->offset();
+    if (offset == Type::OffsetBot) {
+      if (!visited_bottom_offset) {
+        // OffsetBot is used to reference array's element,
+        // always add reference to NULL to all Field nodes since we don't
+        // known which element is referenced.
+        if (add_edge(field, null_obj)) {
+          // New edge was added
+          new_edges++;
+          add_field_uses_to_worklist(field->as_Field());
+          visited_bottom_offset = true;
+        }
+      }
+    } else {
+      // Check only oop fields.
+      const Type* adr_type = field->ideal_node()->as_AddP()->bottom_type();
+      if (adr_type->isa_rawptr()) {
+#ifdef ASSERT
+        // Raw pointers are used for initializing stores so skip it
+        // since it should be recorded already
+        Node* base = get_addp_base(field->ideal_node());
+        assert(adr_type->isa_rawptr() && base->is_Proj() &&
+               (base->in(0) == alloc),"unexpected pointer type");
+#endif
+        continue;
+      }
+      if (!offsets_worklist.contains(offset)) {
+        offsets_worklist.append(offset);
+        Node* value = NULL;
+        if (ini != NULL) {
+          // StoreP::memory_type() == T_ADDRESS
+          BasicType ft = UseCompressedOops ? T_NARROWOOP : T_ADDRESS;
+          Node* store = ini->find_captured_store(offset, type2aelembytes(ft, true), phase);
+          // Make sure initializing store has the same type as this AddP.
+          // This AddP may reference non existing field because it is on a
+          // dead branch of bimorphic call which is not eliminated yet.
+          if (store != NULL && store->is_Store() &&
+              store->as_Store()->memory_type() == ft) {
+            value = store->in(MemNode::ValueIn);
+#ifdef ASSERT
+            if (VerifyConnectionGraph) {
+              // Verify that AddP already points to all objects the value points to.
+              PointsToNode* val = ptnode_adr(value->_idx);
+              assert((val != NULL), "should be processed already");
+              PointsToNode* missed_obj = NULL;
+              if (val->is_JavaObject()) {
+                if (!field->points_to(val->as_JavaObject())) {
+                  missed_obj = val;
+                }
+              } else {
+                if (!val->is_LocalVar() || (val->edge_count() == 0)) {
+                  tty->print_cr("----------init store has invalid value -----");
+                  store->dump();
+                  val->dump();
+                  assert(val->is_LocalVar() && (val->edge_count() > 0), "should be processed already");
+                }
+                for (EdgeIterator j(val); j.has_next(); j.next()) {
+                  PointsToNode* obj = j.get();
+                  if (obj->is_JavaObject()) {
+                    if (!field->points_to(obj->as_JavaObject())) {
+                      missed_obj = obj;
+                      break;
+                    }
+                  }
+                }
+              }
+              if (missed_obj != NULL) {
+                tty->print_cr("----------field---------------------------------");
+                field->dump();
+                tty->print_cr("----------missed referernce to object-----------");
+                missed_obj->dump();
+                tty->print_cr("----------object referernced by init store -----");
+                store->dump();
+                val->dump();
+                assert(!field->points_to(missed_obj->as_JavaObject()), "missed JavaObject reference");
+              }
+            }
+#endif
+          } else {
+            // There could be initializing stores which follow allocation.
+            // For example, a volatile field store is not collected
+            // by Initialize node.
+            //
+            // Need to check for dependent loads to separate such stores from
+            // stores which follow loads. For now, add initial value NULL so
+            // that compare pointers optimization works correctly.
+          }
+        }
+        if (value == NULL) {
+          // A field's initializing value was not recorded. Add NULL.
+          if (add_edge(field, null_obj)) {
+            // New edge was added
+            new_edges++;
+            add_field_uses_to_worklist(field->as_Field());
+          }
+        }
+      }
+    }
+  }
+  return new_edges;
+}
+
+// Adjust scalar_replaceable state after Connection Graph is built.
+void ConnectionGraph::adjust_scalar_replaceable_state(JavaObjectNode* jobj) {
+  // Search for non-escaping objects which are not scalar replaceable
+  // and mark them to propagate the state to referenced objects.
+
+  // 1. An object is not scalar replaceable if the field into which it is
+  // stored has unknown offset (stored into unknown element of an array).
+  //
+  for (UseIterator i(jobj); i.has_next(); i.next()) {
+    PointsToNode* use = i.get();
+    assert(!use->is_Arraycopy(), "sanity");
+    if (use->is_Field()) {
+      FieldNode* field = use->as_Field();
+      assert(field->is_oop() && field->scalar_replaceable() &&
+             field->fields_escape_state() == PointsToNode::NoEscape, "sanity");
+      if (field->offset() == Type::OffsetBot) {
+        jobj->set_scalar_replaceable(false);
+        return;
+      }
+    }
+    assert(use->is_Field() || use->is_LocalVar(), "sanity");
+    // 2. An object is not scalar replaceable if it is merged with other objects.
+    for (EdgeIterator j(use); j.has_next(); j.next()) {
+      PointsToNode* ptn = j.get();
+      if (ptn->is_JavaObject() && ptn != jobj) {
+        // Mark all objects.
+        jobj->set_scalar_replaceable(false);
+         ptn->set_scalar_replaceable(false);
+      }
+    }
+    if (!jobj->scalar_replaceable()) {
+      return;
+    }
+  }
+
+  for (EdgeIterator j(jobj); j.has_next(); j.next()) {
+    // Non-escaping object node should point only to field nodes.
+    FieldNode* field = j.get()->as_Field();
+    int offset = field->as_Field()->offset();
+
+    // 3. An object is not scalar replaceable if it has a field with unknown
+    // offset (array's element is accessed in loop).
+    if (offset == Type::OffsetBot) {
+      jobj->set_scalar_replaceable(false);
+      return;
+    }
+    // 4. Currently an object is not scalar replaceable if a LoadStore node
+    // access its field since the field value is unknown after it.
+    //
+    Node* n = field->ideal_node();
+    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+      if (n->fast_out(i)->is_LoadStore()) {
+        jobj->set_scalar_replaceable(false);
+        return;
+      }
+    }
+
+    // 5. Or the address may point to more then one object. This may produce
+    // the false positive result (set not scalar replaceable)
+    // since the flow-insensitive escape analysis can't separate
+    // the case when stores overwrite the field's value from the case
+    // when stores happened on different control branches.
+    //
+    // Note: it will disable scalar replacement in some cases:
+    //
+    //    Point p[] = new Point[1];
+    //    p[0] = new Point(); // Will be not scalar replaced
+    //
+    // but it will save us from incorrect optimizations in next cases:
+    //
+    //    Point p[] = new Point[1];
+    //    if ( x ) p[0] = new Point(); // Will be not scalar replaced
+    //
+    if (field->base_count() > 1) {
+      for (BaseIterator i(field); i.has_next(); i.next()) {
+        PointsToNode* base = i.get();
+        // Don't take into account LocalVar nodes which
+        // may point to only one object which should be also
+        // this field's base by now.
+        if (base->is_JavaObject() && base != jobj) {
+          // Mark all bases.
+          jobj->set_scalar_replaceable(false);
+          base->set_scalar_replaceable(false);
+        }
+      }
+    }
+  }
+}
+
+#ifdef ASSERT
+void ConnectionGraph::verify_connection_graph(
+                         GrowableArray<PointsToNode*>&   ptnodes_worklist,
+                         GrowableArray<JavaObjectNode*>& non_escaped_worklist,
+                         GrowableArray<JavaObjectNode*>& java_objects_worklist,
+                         GrowableArray<Node*>& addp_worklist) {
+  // Verify that graph is complete - no new edges could be added.
+  int java_objects_length = java_objects_worklist.length();
+  int non_escaped_length  = non_escaped_worklist.length();
+  int new_edges = 0;
+  for (int next = 0; next < java_objects_length; ++next) {
+    JavaObjectNode* ptn = java_objects_worklist.at(next);
+    new_edges += add_java_object_edges(ptn, true);
+  }
+  assert(new_edges == 0, "graph was not complete");
+  // Verify that escape state is final.
+  int length = non_escaped_worklist.length();
+  find_non_escaped_objects(ptnodes_worklist, non_escaped_worklist);
+  assert((non_escaped_length == non_escaped_worklist.length()) &&
+         (non_escaped_length == length) &&
+         (_worklist.length() == 0), "escape state was not final");
+
+  // Verify fields information.
+  int addp_length = addp_worklist.length();
+  for (int next = 0; next < addp_length; ++next ) {
+    Node* n = addp_worklist.at(next);
+    FieldNode* field = ptnode_adr(n->_idx)->as_Field();
+    if (field->is_oop()) {
+      // Verify that field has all bases
+      Node* base = get_addp_base(n);
+      PointsToNode* ptn = ptnode_adr(base->_idx);
+      if (ptn->is_JavaObject()) {
+        assert(field->has_base(ptn->as_JavaObject()), "sanity");
+      } else {
+        assert(ptn->is_LocalVar(), "sanity");
+        for (EdgeIterator i(ptn); i.has_next(); i.next()) {
+          PointsToNode* e = i.get();
+          if (e->is_JavaObject()) {
+            assert(field->has_base(e->as_JavaObject()), "sanity");
+          }
+        }
+      }
+      // Verify that all fields have initializing values.
+      if (field->edge_count() == 0) {
+        tty->print_cr("----------field does not have references----------");
+        field->dump();
+        for (BaseIterator i(field); i.has_next(); i.next()) {
+          PointsToNode* base = i.get();
+          tty->print_cr("----------field has next base---------------------");
+          base->dump();
+          if (base->is_JavaObject() && (base != phantom_obj) && (base != null_obj)) {
+            tty->print_cr("----------base has fields-------------------------");
+            for (EdgeIterator j(base); j.has_next(); j.next()) {
+              j.get()->dump();
+            }
+            tty->print_cr("----------base has references---------------------");
+            for (UseIterator j(base); j.has_next(); j.next()) {
+              j.get()->dump();
+            }
+          }
+        }
+        for (UseIterator i(field); i.has_next(); i.next()) {
+          i.get()->dump();
+        }
+        assert(field->edge_count() > 0, "sanity");
+      }
+    }
+  }
+}
+#endif
+
+// Optimize ideal graph.
+void ConnectionGraph::optimize_ideal_graph(GrowableArray<Node*>& ptr_cmp_worklist,
+                                           GrowableArray<Node*>& storestore_worklist) {
+  Compile* C = _compile;
+  PhaseIterGVN* igvn = _igvn;
+  if (EliminateLocks) {
+    // Mark locks before changing ideal graph.
+    int cnt = C->macro_count();
+    for( int i=0; i < cnt; i++ ) {
+      Node *n = C->macro_node(i);
+      if (n->is_AbstractLock()) { // Lock and Unlock nodes
+        AbstractLockNode* alock = n->as_AbstractLock();
+        if (!alock->is_non_esc_obj()) {
+          if (not_global_escape(alock->obj_node())) {
+            assert(!alock->is_eliminated() || alock->is_coarsened(), "sanity");
+            // The lock could be marked eliminated by lock coarsening
+            // code during first IGVN before EA. Replace coarsened flag
+            // to eliminate all associated locks/unlocks.
+            alock->set_non_esc_obj();
+          }
+        }
+      }
+    }
+  }
+
+  if (OptimizePtrCompare) {
+    // Add ConI(#CC_GT) and ConI(#CC_EQ).
+    _pcmp_neq = igvn->makecon(TypeInt::CC_GT);
+    _pcmp_eq = igvn->makecon(TypeInt::CC_EQ);
+    // Optimize objects compare.
+    while (ptr_cmp_worklist.length() != 0) {
+      Node *n = ptr_cmp_worklist.pop();
+      Node *res = optimize_ptr_compare(n);
+      if (res != NULL) {
+#ifndef PRODUCT
+        if (PrintOptimizePtrCompare) {
+          tty->print_cr("++++ Replaced: %d %s(%d,%d) --> %s", n->_idx, (n->Opcode() == Op_CmpP ? "CmpP" : "CmpN"), n->in(1)->_idx, n->in(2)->_idx, (res == _pcmp_eq ? "EQ" : "NotEQ"));
+          if (Verbose) {
+            n->dump(1);
+          }
+        }
+#endif
+        igvn->replace_node(n, res);
+      }
+    }
+    // cleanup
+    if (_pcmp_neq->outcnt() == 0)
+      igvn->hash_delete(_pcmp_neq);
+    if (_pcmp_eq->outcnt()  == 0)
+      igvn->hash_delete(_pcmp_eq);
+  }
+
+  // For MemBarStoreStore nodes added in library_call.cpp, check
+  // escape status of associated AllocateNode and optimize out
+  // MemBarStoreStore node if the allocated object never escapes.
+  while (storestore_worklist.length() != 0) {
+    Node *n = storestore_worklist.pop();
+    MemBarStoreStoreNode *storestore = n ->as_MemBarStoreStore();
+    Node *alloc = storestore->in(MemBarNode::Precedent)->in(0);
+    assert (alloc->is_Allocate(), "storestore should point to AllocateNode");
+    if (not_global_escape(alloc)) {
+      MemBarNode* mb = MemBarNode::make(C, Op_MemBarCPUOrder, Compile::AliasIdxBot);
+      mb->init_req(TypeFunc::Memory, storestore->in(TypeFunc::Memory));
+      mb->init_req(TypeFunc::Control, storestore->in(TypeFunc::Control));
+      igvn->register_new_node_with_optimizer(mb);
+      igvn->replace_node(storestore, mb);
+    }
+  }
+}
+
+// Optimize objects compare.
+Node* ConnectionGraph::optimize_ptr_compare(Node* n) {
+  assert(OptimizePtrCompare, "sanity");
+  PointsToNode* ptn1 = ptnode_adr(n->in(1)->_idx);
+  PointsToNode* ptn2 = ptnode_adr(n->in(2)->_idx);
+  JavaObjectNode* jobj1 = unique_java_object(n->in(1));
+  JavaObjectNode* jobj2 = unique_java_object(n->in(2));
+  assert(ptn1->is_JavaObject() || ptn1->is_LocalVar(), "sanity");
+  assert(ptn2->is_JavaObject() || ptn2->is_LocalVar(), "sanity");
+
+  // Check simple cases first.
+  if (jobj1 != NULL) {
+    if (jobj1->escape_state() == PointsToNode::NoEscape) {
+      if (jobj1 == jobj2) {
+        // Comparing the same not escaping object.
+        return _pcmp_eq;
+      }
+      Node* obj = jobj1->ideal_node();
+      // Comparing not escaping allocation.
+      if ((obj->is_Allocate() || obj->is_CallStaticJava()) &&
+          !ptn2->points_to(jobj1)) {
+        return _pcmp_neq; // This includes nullness check.
+      }
+    }
+  }
+  if (jobj2 != NULL) {
+    if (jobj2->escape_state() == PointsToNode::NoEscape) {
+      Node* obj = jobj2->ideal_node();
+      // Comparing not escaping allocation.
+      if ((obj->is_Allocate() || obj->is_CallStaticJava()) &&
+          !ptn1->points_to(jobj2)) {
+        return _pcmp_neq; // This includes nullness check.
+      }
+    }
+  }
+  if (jobj1 != NULL && jobj1 != phantom_obj &&
+      jobj2 != NULL && jobj2 != phantom_obj &&
+      jobj1->ideal_node()->is_Con() &&
+      jobj2->ideal_node()->is_Con()) {
+    // Klass or String constants compare. Need to be careful with
+    // compressed pointers - compare types of ConN and ConP instead of nodes.
+    const Type* t1 = jobj1->ideal_node()->bottom_type()->make_ptr();
+    const Type* t2 = jobj2->ideal_node()->bottom_type()->make_ptr();
+    assert(t1 != NULL && t2 != NULL, "sanity");
+    if (t1->make_ptr() == t2->make_ptr()) {
+      return _pcmp_eq;
+    } else {
+      return _pcmp_neq;
+    }
+  }
+  if (ptn1->meet(ptn2)) {
+    return NULL; // Sets are not disjoint
+  }
+
+  // Sets are disjoint.
+  bool set1_has_unknown_ptr = ptn1->points_to(phantom_obj);
+  bool set2_has_unknown_ptr = ptn2->points_to(phantom_obj);
+  bool set1_has_null_ptr    = ptn1->points_to(null_obj);
+  bool set2_has_null_ptr    = ptn2->points_to(null_obj);
+  if (set1_has_unknown_ptr && set2_has_null_ptr ||
+      set2_has_unknown_ptr && set1_has_null_ptr) {
+    // Check nullness of unknown object.
+    return NULL;
+  }
+
+  // Disjointness by itself is not sufficient since
+  // alias analysis is not complete for escaped objects.
+  // Disjoint sets are definitely unrelated only when
+  // at least one set has only not escaping allocations.
+  if (!set1_has_unknown_ptr && !set1_has_null_ptr) {
+    if (ptn1->non_escaping_allocation()) {
+      return _pcmp_neq;
+    }
+  }
+  if (!set2_has_unknown_ptr && !set2_has_null_ptr) {
+    if (ptn2->non_escaping_allocation()) {
+      return _pcmp_neq;
+    }
+  }
+  return NULL;
+}
+
+// Connection Graph constuction functions.
+
+void ConnectionGraph::add_local_var(Node *n, PointsToNode::EscapeState es) {
+  PointsToNode* ptadr = _nodes.at(n->_idx);
+  if (ptadr != NULL) {
+    assert(ptadr->is_LocalVar() && ptadr->ideal_node() == n, "sanity");
+    return;
+  }
+  Compile* C = _compile;
+  ptadr = new (C->comp_arena()) LocalVarNode(C, n, es);
+  _nodes.at_put(n->_idx, ptadr);
+}
+
+void ConnectionGraph::add_java_object(Node *n, PointsToNode::EscapeState es) {
+  PointsToNode* ptadr = _nodes.at(n->_idx);
+  if (ptadr != NULL) {
+    assert(ptadr->is_JavaObject() && ptadr->ideal_node() == n, "sanity");
+    return;
+  }
+  Compile* C = _compile;
+  ptadr = new (C->comp_arena()) JavaObjectNode(C, n, es);
+  _nodes.at_put(n->_idx, ptadr);
+}
+
+void ConnectionGraph::add_field(Node *n, PointsToNode::EscapeState es, int offset) {
+  PointsToNode* ptadr = _nodes.at(n->_idx);
+  if (ptadr != NULL) {
+    assert(ptadr->is_Field() && ptadr->ideal_node() == n, "sanity");
+    return;
+  }
+  bool unsafe = false;
+  bool is_oop = is_oop_field(n, offset, &unsafe);
+  if (unsafe) {
+    es = PointsToNode::GlobalEscape;
+  }
+  Compile* C = _compile;
+  FieldNode* field = new (C->comp_arena()) FieldNode(C, n, es, offset, is_oop);
+  _nodes.at_put(n->_idx, field);
+}
+
+void ConnectionGraph::add_arraycopy(Node *n, PointsToNode::EscapeState es,
+                                    PointsToNode* src, PointsToNode* dst) {
+  assert(!src->is_Field() && !dst->is_Field(), "only for JavaObject and LocalVar");
+  assert((src != null_obj) && (dst != null_obj), "not for ConP NULL");
+  PointsToNode* ptadr = _nodes.at(n->_idx);
+  if (ptadr != NULL) {
+    assert(ptadr->is_Arraycopy() && ptadr->ideal_node() == n, "sanity");
+    return;
+  }
+  Compile* C = _compile;
+  ptadr = new (C->comp_arena()) ArraycopyNode(C, n, es);
+  _nodes.at_put(n->_idx, ptadr);
+  // Add edge from arraycopy node to source object.
+  (void)add_edge(ptadr, src);
+  src->set_arraycopy_src();
+  // Add edge from destination object to arraycopy node.
+  (void)add_edge(dst, ptadr);
+  dst->set_arraycopy_dst();
+}
+
+bool ConnectionGraph::is_oop_field(Node* n, int offset, bool* unsafe) {
+  const Type* adr_type = n->as_AddP()->bottom_type();
+  BasicType bt = T_INT;
+  if (offset == Type::OffsetBot) {
+    // Check only oop fields.
+    if (!adr_type->isa_aryptr() ||
+        (adr_type->isa_aryptr()->klass() == NULL) ||
+         adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
+      // OffsetBot is used to reference array's element. Ignore first AddP.
+      if (find_second_addp(n, n->in(AddPNode::Base)) == NULL) {
+        bt = T_OBJECT;
+      }
+    }
+  } else if (offset != oopDesc::klass_offset_in_bytes()) {
+    if (adr_type->isa_instptr()) {
+      ciField* field = _compile->alias_type(adr_type->isa_instptr())->field();
+      if (field != NULL) {
+        bt = field->layout_type();
+      } else {
+        // Check for unsafe oop field access
+        for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+          int opcode = n->fast_out(i)->Opcode();
+          if (opcode == Op_StoreP || opcode == Op_LoadP ||
+              opcode == Op_StoreN || opcode == Op_LoadN) {
+            bt = T_OBJECT;
+            (*unsafe) = true;
+            break;
+          }
+        }
+      }
+    } else if (adr_type->isa_aryptr()) {
+      if (offset == arrayOopDesc::length_offset_in_bytes()) {
+        // Ignore array length load.
+      } else if (find_second_addp(n, n->in(AddPNode::Base)) != NULL) {
+        // Ignore first AddP.
+      } else {
+        const Type* elemtype = adr_type->isa_aryptr()->elem();
+        bt = elemtype->array_element_basic_type();
+      }
+    } else if (adr_type->isa_rawptr() || adr_type->isa_klassptr()) {
+      // Allocation initialization, ThreadLocal field access, unsafe access
+      for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
+        int opcode = n->fast_out(i)->Opcode();
+        if (opcode == Op_StoreP || opcode == Op_LoadP ||
+            opcode == Op_StoreN || opcode == Op_LoadN) {
+          bt = T_OBJECT;
+          break;
+        }
+      }
+    }
+  }
+  return (bt == T_OBJECT || bt == T_NARROWOOP || bt == T_ARRAY);
+}
+
+// Returns unique pointed java object or NULL.
+JavaObjectNode* ConnectionGraph::unique_java_object(Node *n) {
+  assert(!_collecting, "should not call when contructed graph");
+  // If the node was created after the escape computation we can't answer.
+  uint idx = n->_idx;
+  if (idx >= nodes_size()) {
+    return NULL;
+  }
+  PointsToNode* ptn = ptnode_adr(idx);
+  if (ptn->is_JavaObject()) {
+    return ptn->as_JavaObject();
+  }
+  assert(ptn->is_LocalVar(), "sanity");
+  // Check all java objects it points to.
+  JavaObjectNode* jobj = NULL;
+  for (EdgeIterator i(ptn); i.has_next(); i.next()) {
+    PointsToNode* e = i.get();
+    if (e->is_JavaObject()) {
+      if (jobj == NULL) {
+        jobj = e->as_JavaObject();
+      } else if (jobj != e) {
+        return NULL;
+      }
+    }
+  }
+  return jobj;
+}
+
+// Return true if this node points only to non-escaping allocations.
+bool PointsToNode::non_escaping_allocation() {
+  if (is_JavaObject()) {
+    Node* n = ideal_node();
+    if (n->is_Allocate() || n->is_CallStaticJava()) {
+      return (escape_state() == PointsToNode::NoEscape);
+    } else {
+      return false;
+    }
+  }
+  assert(is_LocalVar(), "sanity");
+  // Check all java objects it points to.
+  for (EdgeIterator i(this); i.has_next(); i.next()) {
+    PointsToNode* e = i.get();
+    if (e->is_JavaObject()) {
+      Node* n = e->ideal_node();
+      if ((e->escape_state() != PointsToNode::NoEscape) ||
+          !(n->is_Allocate() || n->is_CallStaticJava())) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+// Return true if we know the node does not escape globally.
+bool ConnectionGraph::not_global_escape(Node *n) {
+  assert(!_collecting, "should not call during graph construction");
+  // If the node was created after the escape computation we can't answer.
+  uint idx = n->_idx;
+  if (idx >= nodes_size()) {
+    return false;
+  }
+  PointsToNode* ptn = ptnode_adr(idx);
+  PointsToNode::EscapeState es = ptn->escape_state();
+  // If we have already computed a value, return it.
+  if (es >= PointsToNode::GlobalEscape)
+    return false;
+  if (ptn->is_JavaObject()) {
+    return true; // (es < PointsToNode::GlobalEscape);
+  }
+  assert(ptn->is_LocalVar(), "sanity");
+  // Check all java objects it points to.
+  for (EdgeIterator i(ptn); i.has_next(); i.next()) {
+    if (i.get()->escape_state() >= PointsToNode::GlobalEscape)
+      return false;
+  }
+  return true;
+}
+
+
+// Helper functions
+
+// Return true if this node points to specified node or nodes it points to.
+bool PointsToNode::points_to(JavaObjectNode* ptn) const {
+  if (is_JavaObject()) {
+    return (this == ptn);
+  }
+  assert(is_LocalVar() || is_Field(), "sanity");
+  for (EdgeIterator i(this); i.has_next(); i.next()) {
+    if (i.get() == ptn)
+      return true;
+  }
+  return false;
+}
+
+// Return true if one node points to an other.
+bool PointsToNode::meet(PointsToNode* ptn) {
+  if (this == ptn) {
+    return true;
+  } else if (ptn->is_JavaObject()) {
+    return this->points_to(ptn->as_JavaObject());
+  } else if (this->is_JavaObject()) {
+    return ptn->points_to(this->as_JavaObject());
+  }
+  assert(this->is_LocalVar() && ptn->is_LocalVar(), "sanity");
+  int ptn_count =  ptn->edge_count();
+  for (EdgeIterator i(this); i.has_next(); i.next()) {
+    PointsToNode* this_e = i.get();
+    for (int j = 0; j < ptn_count; j++) {
+      if (this_e == ptn->edge(j))
+        return true;
+    }
+  }
+  return false;
+}
+
+#ifdef ASSERT
+// Return true if bases point to this java object.
+bool FieldNode::has_base(JavaObjectNode* jobj) const {
+  for (BaseIterator i(this); i.has_next(); i.next()) {
+    if (i.get() == jobj)
+      return true;
+  }
+  return false;
+}
+#endif
+
 int ConnectionGraph::address_offset(Node* adr, PhaseTransform *phase) {
   const Type *adr_type = phase->type(adr);
   if (adr->is_AddP() && adr_type->isa_oopptr() == NULL &&
@@ -171,286 +2081,7 @@
   return t_ptr->offset();
 }
 
-void ConnectionGraph::add_field_edge(uint from_i, uint to_i, int offset) {
-  // Don't add fields to NULL pointer.
-  if (is_null_ptr(from_i))
-    return;
-  PointsToNode *f = ptnode_adr(from_i);
-  PointsToNode *t = ptnode_adr(to_i);
-
-  assert(f->node_type() != PointsToNode::UnknownType && t->node_type() != PointsToNode::UnknownType, "node types must be set");
-  assert(f->node_type() == PointsToNode::JavaObject, "invalid destination of Field edge");
-  assert(t->node_type() == PointsToNode::Field, "invalid destination of Field edge");
-  assert (t->offset() == -1 || t->offset() == offset, "conflicting field offsets");
-  t->set_offset(offset);
-
-  add_edge(f, to_i, PointsToNode::FieldEdge);
-}
-
-void ConnectionGraph::set_escape_state(uint ni, PointsToNode::EscapeState es) {
-  // Don't change non-escaping state of NULL pointer.
-  if (is_null_ptr(ni))
-    return;
-  PointsToNode *npt = ptnode_adr(ni);
-  PointsToNode::EscapeState old_es = npt->escape_state();
-  if (es > old_es)
-    npt->set_escape_state(es);
-}
-
-void ConnectionGraph::add_node(Node *n, PointsToNode::NodeType nt,
-                               PointsToNode::EscapeState es, bool done) {
-  PointsToNode* ptadr = ptnode_adr(n->_idx);
-  ptadr->_node = n;
-  ptadr->set_node_type(nt);
-
-  // inline set_escape_state(idx, es);
-  PointsToNode::EscapeState old_es = ptadr->escape_state();
-  if (es > old_es)
-    ptadr->set_escape_state(es);
-
-  if (done)
-    _processed.set(n->_idx);
-}
-
-PointsToNode::EscapeState ConnectionGraph::escape_state(Node *n) {
-  uint idx = n->_idx;
-  PointsToNode::EscapeState es;
-
-  // If we are still collecting or there were no non-escaping allocations
-  // we don't know the answer yet
-  if (_collecting)
-    return PointsToNode::UnknownEscape;
-
-  // if the node was created after the escape computation, return
-  // UnknownEscape
-  if (idx >= nodes_size())
-    return PointsToNode::UnknownEscape;
-
-  es = ptnode_adr(idx)->escape_state();
-
-  // if we have already computed a value, return it
-  if (es != PointsToNode::UnknownEscape &&
-      ptnode_adr(idx)->node_type() == PointsToNode::JavaObject)
-    return es;
-
-  // PointsTo() calls n->uncast() which can return a new ideal node.
-  if (n->uncast()->_idx >= nodes_size())
-    return PointsToNode::UnknownEscape;
-
-  PointsToNode::EscapeState orig_es = es;
-
-  // compute max escape state of anything this node could point to
-  for(VectorSetI i(PointsTo(n)); i.test() && es != PointsToNode::GlobalEscape; ++i) {
-    uint pt = i.elem;
-    PointsToNode::EscapeState pes = ptnode_adr(pt)->escape_state();
-    if (pes > es)
-      es = pes;
-  }
-  if (orig_es != es) {
-    // cache the computed escape state
-    assert(es > orig_es, "should have computed an escape state");
-    set_escape_state(idx, es);
-  } // orig_es could be PointsToNode::UnknownEscape
-  return es;
-}
-
-VectorSet* ConnectionGraph::PointsTo(Node * n) {
-  pt_ptset.Reset();
-  pt_visited.Reset();
-  pt_worklist.clear();
-
-#ifdef ASSERT
-  Node *orig_n = n;
-#endif
-
-  n = n->uncast();
-  PointsToNode* npt = ptnode_adr(n->_idx);
-
-  // If we have a JavaObject, return just that object
-  if (npt->node_type() == PointsToNode::JavaObject) {
-    pt_ptset.set(n->_idx);
-    return &pt_ptset;
-  }
-#ifdef ASSERT
-  if (npt->_node == NULL) {
-    if (orig_n != n)
-      orig_n->dump();
-    n->dump();
-    assert(npt->_node != NULL, "unregistered node");
-  }
-#endif
-  pt_worklist.push(n->_idx);
-  while(pt_worklist.length() > 0) {
-    int ni = pt_worklist.pop();
-    if (pt_visited.test_set(ni))
-      continue;
-
-    PointsToNode* pn = ptnode_adr(ni);
-    // ensure that all inputs of a Phi have been processed
-    assert(!_collecting || !pn->_node->is_Phi() || _processed.test(ni),"");
-
-    int edges_processed = 0;
-    uint e_cnt = pn->edge_count();
-    for (uint e = 0; e < e_cnt; e++) {
-      uint etgt = pn->edge_target(e);
-      PointsToNode::EdgeType et = pn->edge_type(e);
-      if (et == PointsToNode::PointsToEdge) {
-        pt_ptset.set(etgt);
-        edges_processed++;
-      } else if (et == PointsToNode::DeferredEdge) {
-        pt_worklist.push(etgt);
-        edges_processed++;
-      } else {
-        assert(false,"neither PointsToEdge or DeferredEdge");
-      }
-    }
-    if (edges_processed == 0) {
-      // no deferred or pointsto edges found.  Assume the value was set
-      // outside this method.  Add the phantom object to the pointsto set.
-      pt_ptset.set(_phantom_object);
-    }
-  }
-  return &pt_ptset;
-}
-
-void ConnectionGraph::remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited) {
-  // This method is most expensive during ConnectionGraph construction.
-  // Reuse vectorSet and an additional growable array for deferred edges.
-  deferred_edges->clear();
-  visited->Reset();
-
-  visited->set(ni);
-  PointsToNode *ptn = ptnode_adr(ni);
-  assert(ptn->node_type() == PointsToNode::LocalVar ||
-         ptn->node_type() == PointsToNode::Field, "sanity");
-  assert(ptn->edge_count() != 0, "should have at least phantom_object");
-
-  // Mark current edges as visited and move deferred edges to separate array.
-  for (uint i = 0; i < ptn->edge_count(); ) {
-    uint t = ptn->edge_target(i);
-#ifdef ASSERT
-    assert(!visited->test_set(t), "expecting no duplications");
-#else
-    visited->set(t);
-#endif
-    if (ptn->edge_type(i) == PointsToNode::DeferredEdge) {
-      ptn->remove_edge(t, PointsToNode::DeferredEdge);
-      deferred_edges->append(t);
-    } else {
-      i++;
-    }
-  }
-  for (int next = 0; next < deferred_edges->length(); ++next) {
-    uint t = deferred_edges->at(next);
-    PointsToNode *ptt = ptnode_adr(t);
-    uint e_cnt = ptt->edge_count();
-    assert(e_cnt != 0, "should have at least phantom_object");
-    for (uint e = 0; e < e_cnt; e++) {
-      uint etgt = ptt->edge_target(e);
-      if (visited->test_set(etgt))
-        continue;
-
-      PointsToNode::EdgeType et = ptt->edge_type(e);
-      if (et == PointsToNode::PointsToEdge) {
-        add_pointsto_edge(ni, etgt);
-      } else if (et == PointsToNode::DeferredEdge) {
-        deferred_edges->append(etgt);
-      } else {
-        assert(false,"invalid connection graph");
-      }
-    }
-  }
-  if (ptn->edge_count() == 0) {
-    // No pointsto edges found after deferred edges are removed.
-    // For example, in the next case where call is replaced
-    // with uncommon trap and as result array's load references
-    // itself through deferred edges:
-    //
-    // A a = b[i];
-    // if (c!=null) a = c.foo();
-    // b[i] = a;
-    //
-    // Assume the value was set outside this method and
-    // add edge to phantom object.
-    add_pointsto_edge(ni, _phantom_object);
-  }
-}
-
-
-//  Add an edge to node given by "to_i" from any field of adr_i whose offset
-//  matches "offset"  A deferred edge is added if to_i is a LocalVar, and
-//  a pointsto edge is added if it is a JavaObject
-
-void ConnectionGraph::add_edge_from_fields(uint adr_i, uint to_i, int offs) {
-  // No fields for NULL pointer.
-  if (is_null_ptr(adr_i)) {
-    return;
-  }
-  PointsToNode* an = ptnode_adr(adr_i);
-  PointsToNode* to = ptnode_adr(to_i);
-  bool deferred = (to->node_type() == PointsToNode::LocalVar);
-  bool escaped  = (to_i == _phantom_object) && (offs == Type::OffsetTop);
-  if (escaped) {
-    // Values in fields escaped during call.
-    assert(an->escape_state() >= PointsToNode::ArgEscape, "sanity");
-    offs = Type::OffsetBot;
-  }
-  for (uint fe = 0; fe < an->edge_count(); fe++) {
-    assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
-    int fi = an->edge_target(fe);
-    if (escaped) {
-      set_escape_state(fi, PointsToNode::GlobalEscape);
-    }
-    PointsToNode* pf = ptnode_adr(fi);
-    int po = pf->offset();
-    if (po == offs || po == Type::OffsetBot || offs == Type::OffsetBot) {
-      if (deferred)
-        add_deferred_edge(fi, to_i);
-      else
-        add_pointsto_edge(fi, to_i);
-    }
-  }
-}
-
-// Add a deferred  edge from node given by "from_i" to any field of adr_i
-// whose offset matches "offset".
-void ConnectionGraph::add_deferred_edge_to_fields(uint from_i, uint adr_i, int offs) {
-  // No fields for NULL pointer.
-  if (is_null_ptr(adr_i)) {
-    return;
-  }
-  if (adr_i == _phantom_object) {
-    // Add only one edge for unknown object.
-    add_pointsto_edge(from_i, _phantom_object);
-    return;
-  }
-  PointsToNode* an = ptnode_adr(adr_i);
-  bool is_alloc = an->_node->is_Allocate();
-  for (uint fe = 0; fe < an->edge_count(); fe++) {
-    assert(an->edge_type(fe) == PointsToNode::FieldEdge, "expecting a field edge");
-    int fi = an->edge_target(fe);
-    PointsToNode* pf = ptnode_adr(fi);
-    int offset = pf->offset();
-    if (!is_alloc) {
-      // Assume the field was set outside this method if it is not Allocation
-      add_pointsto_edge(fi, _phantom_object);
-    }
-    if (offset == offs || offset == Type::OffsetBot || offs == Type::OffsetBot) {
-      add_deferred_edge(from_i, fi);
-    }
-  }
-  // Some fields references (AddP) may still be missing
-  // until Connection Graph construction is complete.
-  // For example, loads from RAW pointers with offset 0
-  // which don't have AddP.
-  // A reference to phantom_object will be added if
-  // a field reference is still missing after completing
-  // Connection Graph (see remove_deferred()).
-}
-
-// Helper functions
-
-static Node* get_addp_base(Node *addp) {
+Node* ConnectionGraph::get_addp_base(Node *addp) {
   assert(addp->is_AddP(), "must be AddP");
   //
   // AddP cases for Base and Address inputs:
@@ -513,30 +2144,30 @@
   //       | |
   //       AddP  ( base == address )
   //
-  Node *base = addp->in(AddPNode::Base)->uncast();
-  if (base->is_top()) { // The AddP case #3 and #6.
-    base = addp->in(AddPNode::Address)->uncast();
+  Node *base = addp->in(AddPNode::Base);
+  if (base->uncast()->is_top()) { // The AddP case #3 and #6.
+    base = addp->in(AddPNode::Address);
     while (base->is_AddP()) {
       // Case #6 (unsafe access) may have several chained AddP nodes.
-      assert(base->in(AddPNode::Base)->is_top(), "expected unsafe access address only");
-      base = base->in(AddPNode::Address)->uncast();
+      assert(base->in(AddPNode::Base)->uncast()->is_top(), "expected unsafe access address only");
+      base = base->in(AddPNode::Address);
     }
-    assert(base->Opcode() == Op_ConP || base->Opcode() == Op_ThreadLocal ||
-           base->Opcode() == Op_CastX2P || base->is_DecodeN() ||
-           (base->is_Mem() && base->bottom_type() == TypeRawPtr::NOTNULL) ||
-           (base->is_Proj() && base->in(0)->is_Allocate()), "sanity");
+    Node* uncast_base = base->uncast();
+    int opcode = uncast_base->Opcode();
+    assert(opcode == Op_ConP || opcode == Op_ThreadLocal ||
+           opcode == Op_CastX2P || uncast_base->is_DecodeN() ||
+           (uncast_base->is_Mem() && uncast_base->bottom_type() == TypeRawPtr::NOTNULL) ||
+           (uncast_base->is_Proj() && uncast_base->in(0)->is_Allocate()), "sanity");
   }
   return base;
 }
 
-static Node* find_second_addp(Node* addp, Node* n) {
+Node* ConnectionGraph::find_second_addp(Node* addp, Node* n) {
   assert(addp->is_AddP() && addp->outcnt() > 0, "Don't process dead nodes");
-
   Node* addp2 = addp->raw_out(0);
   if (addp->outcnt() == 1 && addp2->is_AddP() &&
       addp2->in(AddPNode::Base) == n &&
       addp2->in(AddPNode::Address) == addp) {
-
     assert(addp->in(AddPNode::Base) == n, "expecting the same base");
     //
     // Find array's offset to push it on worklist first and
@@ -575,7 +2206,8 @@
 // Adjust the type and inputs of an AddP which computes the
 // address of a field of an instance
 //
-bool ConnectionGraph::split_AddP(Node *addp, Node *base,  PhaseGVN  *igvn) {
+bool ConnectionGraph::split_AddP(Node *addp, Node *base) {
+  PhaseGVN* igvn = _igvn;
   const TypeOopPtr *base_t = igvn->type(base)->isa_oopptr();
   assert(base_t != NULL && base_t->is_known_instance(), "expecting instance oopptr");
   const TypeOopPtr *t = igvn->type(addp)->isa_oopptr();
@@ -612,7 +2244,6 @@
       !base_t->klass()->is_subtype_of(t->klass())) {
      return false; // bail out
   }
-
   const TypeOopPtr *tinst = base_t->add_offset(t->offset())->is_oopptr();
   // Do NOT remove the next line: ensure a new alias index is allocated
   // for the instance type. Note: C++ will not remove it since the call
@@ -620,9 +2251,7 @@
   int alias_idx = _compile->get_alias_index(tinst);
   igvn->set_type(addp, tinst);
   // record the allocation in the node map
-  assert(ptnode_adr(addp->_idx)->_node != NULL, "should be registered");
-  set_map(addp->_idx, get_map(base->_idx));
-
+  set_map(addp, get_map(base->_idx));
   // Set addp's Base and Address to 'base'.
   Node *abase = addp->in(AddPNode::Base);
   Node *adr   = addp->in(AddPNode::Address);
@@ -657,8 +2286,9 @@
 // created phi or an existing phi.  Sets create_new to indicate whether a new
 // phi was created.  Cache the last newly created phi in the node map.
 //
-PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn, bool &new_created) {
+PhiNode *ConnectionGraph::create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, bool &new_created) {
   Compile *C = _compile;
+  PhaseGVN* igvn = _igvn;
   new_created = false;
   int phi_alias_idx = C->get_alias_index(orig_phi->adr_type());
   // nothing to do if orig_phi is bottom memory or matches alias_idx
@@ -698,12 +2328,7 @@
   C->copy_node_notes_to(result, orig_phi);
   igvn->set_type(result, result->bottom_type());
   record_for_optimizer(result);
-
-  debug_only(Node* pn = ptnode_adr(orig_phi->_idx)->_node;)
-  assert(pn == NULL || pn == orig_phi, "wrong node");
-  set_map(orig_phi->_idx, result);
-  ptnode_adr(orig_phi->_idx)->_node = orig_phi;
-
+  set_map(orig_phi, result);
   new_created = true;
   return result;
 }
@@ -712,27 +2337,25 @@
 // Return a new version of Memory Phi "orig_phi" with the inputs having the
 // specified alias index.
 //
-PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn) {
-
+PhiNode *ConnectionGraph::split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist) {
   assert(alias_idx != Compile::AliasIdxBot, "can't split out bottom memory");
   Compile *C = _compile;
+  PhaseGVN* igvn = _igvn;
   bool new_phi_created;
-  PhiNode *result = create_split_phi(orig_phi, alias_idx, orig_phi_worklist, igvn, new_phi_created);
+  PhiNode *result = create_split_phi(orig_phi, alias_idx, orig_phi_worklist, new_phi_created);
   if (!new_phi_created) {
     return result;
   }
-
   GrowableArray<PhiNode *>  phi_list;
   GrowableArray<uint>  cur_input;
-
   PhiNode *phi = orig_phi;
   uint idx = 1;
   bool finished = false;
   while(!finished) {
     while (idx < phi->req()) {
-      Node *mem = find_inst_mem(phi->in(idx), alias_idx, orig_phi_worklist, igvn);
+      Node *mem = find_inst_mem(phi->in(idx), alias_idx, orig_phi_worklist);
       if (mem != NULL && mem->is_Phi()) {
-        PhiNode *newphi = create_split_phi(mem->as_Phi(), alias_idx, orig_phi_worklist, igvn, new_phi_created);
+        PhiNode *newphi = create_split_phi(mem->as_Phi(), alias_idx, orig_phi_worklist, new_phi_created);
         if (new_phi_created) {
           // found an phi for which we created a new split, push current one on worklist and begin
           // processing new one
@@ -775,19 +2398,18 @@
   return result;
 }
 
-
 //
 // The next methods are derived from methods in MemNode.
 //
-static Node *step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop) {
+Node* ConnectionGraph::step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop) {
   Node *mem = mmem;
   // TypeOopPtr::NOTNULL+any is an OOP with unknown offset - generally
   // means an array I have not precisely typed yet.  Do not do any
   // alias stuff with it any time soon.
-  if( toop->base() != Type::AnyPtr &&
+  if (toop->base() != Type::AnyPtr &&
       !(toop->klass() != NULL &&
         toop->klass()->is_java_lang_Object() &&
-        toop->offset() == Type::OffsetBot) ) {
+        toop->offset() == Type::OffsetBot)) {
     mem = mmem->memory_at(alias_idx);
     // Update input if it is progress over what we have now
   }
@@ -797,9 +2419,9 @@
 //
 // Move memory users to their memory slices.
 //
-void ConnectionGraph::move_inst_mem(Node* n, GrowableArray<PhiNode *>  &orig_phis, PhaseGVN *igvn) {
+void ConnectionGraph::move_inst_mem(Node* n, GrowableArray<PhiNode *>  &orig_phis) {
   Compile* C = _compile;
-
+  PhaseGVN* igvn = _igvn;
   const TypePtr* tp = igvn->type(n->in(MemNode::Address))->isa_ptr();
   assert(tp != NULL, "ptr type");
   int alias_idx = C->get_alias_index(tp);
@@ -816,7 +2438,7 @@
       }
       // Replace previous general reference to mem node.
       uint orig_uniq = C->unique();
-      Node* m = find_inst_mem(n, general_idx, orig_phis, igvn);
+      Node* m = find_inst_mem(n, general_idx, orig_phis);
       assert(orig_uniq == C->unique(), "no new nodes");
       mmem->set_memory_at(general_idx, m);
       --imax;
@@ -836,7 +2458,7 @@
       }
       // Move to general memory slice.
       uint orig_uniq = C->unique();
-      Node* m = find_inst_mem(n, general_idx, orig_phis, igvn);
+      Node* m = find_inst_mem(n, general_idx, orig_phis);
       assert(orig_uniq == C->unique(), "no new nodes");
       igvn->hash_delete(use);
       imax -= use->replace_edge(n, m);
@@ -873,10 +2495,11 @@
 // Search memory chain of "mem" to find a MemNode whose address
 // is the specified alias index.
 //
-Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray<PhiNode *>  &orig_phis, PhaseGVN *phase) {
+Node* ConnectionGraph::find_inst_mem(Node *orig_mem, int alias_idx, GrowableArray<PhiNode *>  &orig_phis) {
   if (orig_mem == NULL)
     return orig_mem;
-  Compile* C = phase->C;
+  Compile* C = _compile;
+  PhaseGVN* igvn = _igvn;
   const TypeOopPtr *toop = C->get_adr_type(alias_idx)->isa_oopptr();
   bool is_instance = (toop != NULL) && toop->is_known_instance();
   Node *start_mem = C->start()->proj_out(TypeFunc::Memory);
@@ -887,7 +2510,7 @@
     if (result == start_mem)
       break;  // hit one of our sentinels
     if (result->is_Mem()) {
-      const Type *at = phase->type(result->in(MemNode::Address));
+      const Type *at = igvn->type(result->in(MemNode::Address));
       if (at == Type::TOP)
         break; // Dead
       assert (at->isa_ptr() != NULL, "pointer type required.");
@@ -909,7 +2532,7 @@
         break;  // hit one of our sentinels
       } else if (proj_in->is_Call()) {
         CallNode *call = proj_in->as_Call();
-        if (!call->may_modify(toop, phase)) {
+        if (!call->may_modify(toop, igvn)) {
           result = call->in(TypeFunc::Memory);
         }
       } else if (proj_in->is_Initialize()) {
@@ -928,7 +2551,7 @@
       if (result == mmem->base_memory()) {
         // Didn't find instance memory, search through general slice recursively.
         result = mmem->memory_at(C->get_general_index(alias_idx));
-        result = find_inst_mem(result, alias_idx, orig_phis, phase);
+        result = find_inst_mem(result, alias_idx, orig_phis);
         if (C->failing()) {
           return NULL;
         }
@@ -936,7 +2559,7 @@
       }
     } else if (result->is_Phi() &&
                C->get_alias_index(result->as_Phi()->adr_type()) != alias_idx) {
-      Node *un = result->as_Phi()->unique_input(phase);
+      Node *un = result->as_Phi()->unique_input(igvn);
       if (un != NULL) {
         orig_phis.append_if_missing(result->as_Phi());
         result = un;
@@ -944,7 +2567,7 @@
         break;
       }
     } else if (result->is_ClearArray()) {
-      if (!ClearArrayNode::step_through(&result, (uint)toop->instance_id(), phase)) {
+      if (!ClearArrayNode::step_through(&result, (uint)toop->instance_id(), igvn)) {
         // Can not bypass initialization of the instance
         // we are looking for.
         break;
@@ -952,7 +2575,7 @@
       // Otherwise skip it (the call updated 'result' value).
     } else if (result->Opcode() == Op_SCMemProj) {
       assert(result->in(0)->is_LoadStore(), "sanity");
-      const Type *at = phase->type(result->in(0)->in(MemNode::Address));
+      const Type *at = igvn->type(result->in(0)->in(MemNode::Address));
       if (at != Type::TOP) {
         assert (at->isa_ptr() != NULL, "pointer type required.");
         int idx = C->get_alias_index(at->is_ptr());
@@ -972,7 +2595,7 @@
       orig_phis.append_if_missing(mphi);
     } else if (C->get_alias_index(t) != alias_idx) {
       // Create a new Phi with the specified alias index type.
-      result = split_memory_phi(mphi, alias_idx, orig_phis, phase);
+      result = split_memory_phi(mphi, alias_idx, orig_phis);
     }
   }
   // the result is either MemNode, PhiNode, InitializeNode.
@@ -1071,12 +2694,12 @@
 void ConnectionGraph::split_unique_types(GrowableArray<Node *>  &alloc_worklist) {
   GrowableArray<Node *>  memnode_worklist;
   GrowableArray<PhiNode *>  orig_phis;
-
   PhaseIterGVN  *igvn = _igvn;
   uint new_index_start = (uint) _compile->num_alias_types();
   Arena* arena = Thread::current()->resource_area();
   VectorSet visited(arena);
-
+  ideal_nodes.clear(); // Reset for use with set_map/get_map.
+  uint unique_old = _compile->unique();
 
   //  Phase 1:  Process possible allocations from alloc_worklist.
   //  Create instance types for the CheckCastPP for allocations where possible.
@@ -1088,17 +2711,15 @@
   while (alloc_worklist.length() != 0) {
     Node *n = alloc_worklist.pop();
     uint ni = n->_idx;
-    const TypeOopPtr* tinst = NULL;
     if (n->is_Call()) {
       CallNode *alloc = n->as_Call();
       // copy escape information to call node
       PointsToNode* ptn = ptnode_adr(alloc->_idx);
-      PointsToNode::EscapeState es = escape_state(alloc);
+      PointsToNode::EscapeState es = ptn->escape_state();
       // We have an allocation or call which returns a Java object,
       // see if it is unescaped.
       if (es != PointsToNode::NoEscape || !ptn->scalar_replaceable())
         continue;
-
       // Find CheckCastPP for the allocate or for the return value of a call
       n = alloc->result_cast();
       if (n == NULL) {            // No uses except Initialize node
@@ -1145,20 +2766,18 @@
         // so it could be eliminated.
         alloc->as_Allocate()->_is_scalar_replaceable = true;
       }
-      set_escape_state(n->_idx, es); // CheckCastPP escape state
+      set_escape_state(ptnode_adr(n->_idx), es); // CheckCastPP escape state
       // in order for an object to be scalar-replaceable, it must be:
       //   - a direct allocation (not a call returning an object)
       //   - non-escaping
       //   - eligible to be a unique type
       //   - not determined to be ineligible by escape analysis
-      assert(ptnode_adr(alloc->_idx)->_node != NULL &&
-             ptnode_adr(n->_idx)->_node != NULL, "should be registered");
-      set_map(alloc->_idx, n);
-      set_map(n->_idx, alloc);
+      set_map(alloc, n);
+      set_map(n, alloc);
       const TypeOopPtr *t = igvn->type(n)->isa_oopptr();
       if (t == NULL)
         continue;  // not a TypeOopPtr
-      tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni);
+      const TypeOopPtr* tinst = t->cast_to_exactness(true)->is_oopptr()->cast_to_instance_id(ni);
       igvn->hash_delete(n);
       igvn->set_type(n,  tinst);
       n->raise_bottom_type(tinst);
@@ -1168,9 +2787,10 @@
 
         // First, put on the worklist all Field edges from Connection Graph
         // which is more accurate then putting immediate users from Ideal Graph.
-        for (uint e = 0; e < ptn->edge_count(); e++) {
-          Node *use = ptnode_adr(ptn->edge_target(e))->_node;
-          assert(ptn->edge_type(e) == PointsToNode::FieldEdge && use->is_AddP(),
+        for (EdgeIterator e(ptn); e.has_next(); e.next()) {
+          PointsToNode* tgt = e.get();
+          Node* use = tgt->ideal_node();
+          assert(tgt->is_Field() && use->is_AddP(),
                  "only AddP nodes are Field edges in CG");
           if (use->outcnt() > 0) { // Don't process dead nodes
             Node* addp2 = find_second_addp(use, use->in(AddPNode::Base));
@@ -1202,16 +2822,18 @@
         }
       }
     } else if (n->is_AddP()) {
-      VectorSet* ptset = PointsTo(get_addp_base(n));
-      assert(ptset->Size() == 1, "AddP address is unique");
-      uint elem = ptset->getelem(); // Allocation node's index
-      if (elem == _phantom_object) {
-        assert(false, "escaped allocation");
-        continue; // Assume the value was set outside this method.
+      JavaObjectNode* jobj = unique_java_object(get_addp_base(n));
+      if (jobj == NULL || jobj == phantom_obj) {
+#ifdef ASSERT
+        ptnode_adr(get_addp_base(n)->_idx)->dump();
+        ptnode_adr(n->_idx)->dump();
+        assert(jobj != NULL && jobj != phantom_obj, "escaped allocation");
+#endif
+        _compile->record_failure(C2Compiler::retry_no_escape_analysis());
+        return;
       }
-      Node *base = get_map(elem);  // CheckCastPP node
-      if (!split_AddP(n, base, igvn)) continue; // wrong type from dead path
-      tinst = igvn->type(base)->isa_oopptr();
+      Node *base = get_map(jobj->idx());  // CheckCastPP node
+      if (!split_AddP(n, base)) continue; // wrong type from dead path
     } else if (n->is_Phi() ||
                n->is_CheckCastPP() ||
                n->is_EncodeP() ||
@@ -1221,18 +2843,20 @@
         assert(n->is_Phi(), "loops only through Phi's");
         continue;  // already processed
       }
-      VectorSet* ptset = PointsTo(n);
-      if (ptset->Size() == 1) {
-        uint elem = ptset->getelem(); // Allocation node's index
-        if (elem == _phantom_object) {
-          assert(false, "escaped allocation");
-          continue; // Assume the value was set outside this method.
-        }
-        Node *val = get_map(elem);   // CheckCastPP node
+      JavaObjectNode* jobj = unique_java_object(n);
+      if (jobj == NULL || jobj == phantom_obj) {
+#ifdef ASSERT
+        ptnode_adr(n->_idx)->dump();
+        assert(jobj != NULL && jobj != phantom_obj, "escaped allocation");
+#endif
+        _compile->record_failure(C2Compiler::retry_no_escape_analysis());
+        return;
+      } else {
+        Node *val = get_map(jobj->idx());   // CheckCastPP node
         TypeNode *tn = n->as_Type();
-        tinst = igvn->type(val)->isa_oopptr();
+        const TypeOopPtr* tinst = igvn->type(val)->isa_oopptr();
         assert(tinst != NULL && tinst->is_known_instance() &&
-               (uint)tinst->instance_id() == elem , "instance type expected.");
+               tinst->instance_id() == jobj->idx() , "instance type expected.");
 
         const Type *tn_type = igvn->type(tn);
         const TypeOopPtr *tn_t;
@@ -1241,7 +2865,6 @@
         } else {
           tn_t = tn_type->isa_oopptr();
         }
-
         if (tn_t != NULL && tinst->klass()->is_subtype_of(tn_t->klass())) {
           if (tn_type->isa_narrowoop()) {
             tn_type = tinst->make_narrowoop();
@@ -1314,13 +2937,13 @@
   }
   // New alias types were created in split_AddP().
   uint new_index_end = (uint) _compile->num_alias_types();
+  assert(unique_old == _compile->unique(), "there should be no new ideal nodes after Phase 1");
 
   //  Phase 2:  Process MemNode's from memnode_worklist. compute new address type and
   //            compute new values for Memory inputs  (the Memory inputs are not
   //            actually updated until phase 4.)
   if (memnode_worklist.length() == 0)
     return;  // nothing to do
-
   while (memnode_worklist.length() != 0) {
     Node *n = memnode_worklist.pop();
     if (visited.test_set(n->_idx))
@@ -1341,17 +2964,14 @@
       assert (addr_t->isa_ptr() != NULL, "pointer type required.");
       int alias_idx = _compile->get_alias_index(addr_t->is_ptr());
       assert ((uint)alias_idx < new_index_end, "wrong alias index");
-      Node *mem = find_inst_mem(n->in(MemNode::Memory), alias_idx, orig_phis, igvn);
+      Node *mem = find_inst_mem(n->in(MemNode::Memory), alias_idx, orig_phis);
       if (_compile->failing()) {
         return;
       }
       if (mem != n->in(MemNode::Memory)) {
         // We delay the memory edge update since we need old one in
         // MergeMem code below when instances memory slices are separated.
-        debug_only(Node* pn = ptnode_adr(n->_idx)->_node;)
-        assert(pn == NULL || pn == n, "wrong node");
-        set_map(n->_idx, mem);
-        ptnode_adr(n->_idx)->_node = n;
+        set_map(n, mem);
       }
       if (n->is_Load()) {
         continue;  // don't push users
@@ -1442,7 +3062,7 @@
         if((uint)_compile->get_general_index(ni) == i) {
           Node *m = (ni >= nmm->req()) ? nmm->empty_memory() : nmm->in(ni);
           if (nmm->is_empty_memory(m)) {
-            Node* result = find_inst_mem(mem, ni, orig_phis, igvn);
+            Node* result = find_inst_mem(mem, ni, orig_phis);
             if (_compile->failing()) {
               return;
             }
@@ -1458,7 +3078,7 @@
       if (result == nmm->base_memory()) {
         // Didn't find instance memory, search through general slice recursively.
         result = nmm->memory_at(_compile->get_general_index(ni));
-        result = find_inst_mem(result, ni, orig_phis, igvn);
+        result = find_inst_mem(result, ni, orig_phis);
         if (_compile->failing()) {
           return;
         }
@@ -1482,7 +3102,7 @@
     igvn->hash_delete(phi);
     for (uint i = 1; i < phi->req(); i++) {
       Node *mem = phi->in(i);
-      Node *new_mem = find_inst_mem(mem, alias_idx, orig_phis, igvn);
+      Node *new_mem = find_inst_mem(mem, alias_idx, orig_phis);
       if (_compile->failing()) {
         return;
       }
@@ -1496,39 +3116,36 @@
 
   // Update the memory inputs of MemNodes with the value we computed
   // in Phase 2 and move stores memory users to corresponding memory slices.
-
   // Disable memory split verification code until the fix for 6984348.
   // Currently it produces false negative results since it does not cover all cases.
 #if 0 // ifdef ASSERT
   visited.Reset();
   Node_Stack old_mems(arena, _compile->unique() >> 2);
 #endif
-  for (uint i = 0; i < nodes_size(); i++) {
-    Node *nmem = get_map(i);
-    if (nmem != NULL) {
-      Node *n = ptnode_adr(i)->_node;
-      assert(n != NULL, "sanity");
-      if (n->is_Mem()) {
+  for (uint i = 0; i < ideal_nodes.size(); i++) {
+    Node*    n = ideal_nodes.at(i);
+    Node* nmem = get_map(n->_idx);
+    assert(nmem != NULL, "sanity");
+    if (n->is_Mem()) {
 #if 0 // ifdef ASSERT
-        Node* old_mem = n->in(MemNode::Memory);
-        if (!visited.test_set(old_mem->_idx)) {
-          old_mems.push(old_mem, old_mem->outcnt());
-        }
-#endif
-        assert(n->in(MemNode::Memory) != nmem, "sanity");
-        if (!n->is_Load()) {
-          // Move memory users of a store first.
-          move_inst_mem(n, orig_phis, igvn);
-        }
-        // Now update memory input
-        igvn->hash_delete(n);
-        n->set_req(MemNode::Memory, nmem);
-        igvn->hash_insert(n);
-        record_for_optimizer(n);
-      } else {
-        assert(n->is_Allocate() || n->is_CheckCastPP() ||
-               n->is_AddP() || n->is_Phi(), "unknown node used for set_map()");
+      Node* old_mem = n->in(MemNode::Memory);
+      if (!visited.test_set(old_mem->_idx)) {
+        old_mems.push(old_mem, old_mem->outcnt());
       }
+#endif
+      assert(n->in(MemNode::Memory) != nmem, "sanity");
+      if (!n->is_Load()) {
+        // Move memory users of a store first.
+        move_inst_mem(n, orig_phis);
+      }
+      // Now update memory input
+      igvn->hash_delete(n);
+      n->set_req(MemNode::Memory, nmem);
+      igvn->hash_insert(n);
+      record_for_optimizer(n);
+    } else {
+      assert(n->is_Allocate() || n->is_CheckCastPP() ||
+             n->is_AddP() || n->is_Phi(), "unknown node used for set_map()");
     }
   }
 #if 0 // ifdef ASSERT
@@ -1542,1571 +3159,76 @@
 #endif
 }
 
-bool ConnectionGraph::has_candidates(Compile *C) {
-  // EA brings benefits only when the code has allocations and/or locks which
-  // are represented by ideal Macro nodes.
-  int cnt = C->macro_count();
-  for( int i=0; i < cnt; i++ ) {
-    Node *n = C->macro_node(i);
-    if ( n->is_Allocate() )
-      return true;
-    if( n->is_Lock() ) {
-      Node* obj = n->as_Lock()->obj_node()->uncast();
-      if( !(obj->is_Parm() || obj->is_Con()) )
-        return true;
-    }
-  }
-  return false;
-}
-
-void ConnectionGraph::do_analysis(Compile *C, PhaseIterGVN *igvn) {
-  // Add ConP#NULL and ConN#NULL nodes before ConnectionGraph construction
-  // to create space for them in ConnectionGraph::_nodes[].
-  Node* oop_null = igvn->zerocon(T_OBJECT);
-  Node* noop_null = igvn->zerocon(T_NARROWOOP);
-
-  ConnectionGraph* congraph = new(C->comp_arena()) ConnectionGraph(C, igvn);
-  // Perform escape analysis
-  if (congraph->compute_escape()) {
-    // There are non escaping objects.
-    C->set_congraph(congraph);
-  }
-
-  // Cleanup.
-  if (oop_null->outcnt() == 0)
-    igvn->hash_delete(oop_null);
-  if (noop_null->outcnt() == 0)
-    igvn->hash_delete(noop_null);
-}
-
-bool ConnectionGraph::compute_escape() {
-  Compile* C = _compile;
-
-  // 1. Populate Connection Graph (CG) with Ideal nodes.
-
-  Unique_Node_List worklist_init;
-  worklist_init.map(C->unique(), NULL);  // preallocate space
-
-  // Initialize worklist
-  if (C->root() != NULL) {
-    worklist_init.push(C->root());
-  }
-
-  GrowableArray<Node*> alloc_worklist;
-  GrowableArray<Node*> addp_worklist;
-  GrowableArray<Node*> ptr_cmp_worklist;
-  GrowableArray<Node*> storestore_worklist;
-  PhaseGVN* igvn = _igvn;
-
-  // Push all useful nodes onto CG list and set their type.
-  for( uint next = 0; next < worklist_init.size(); ++next ) {
-    Node* n = worklist_init.at(next);
-    record_for_escape_analysis(n, igvn);
-    // Only allocations and java static calls results are checked
-    // for an escape status. See process_call_result() below.
-    if (n->is_Allocate() || n->is_CallStaticJava() &&
-        ptnode_adr(n->_idx)->node_type() == PointsToNode::JavaObject) {
-      alloc_worklist.append(n);
-    } else if(n->is_AddP()) {
-      // Collect address nodes. Use them during stage 3 below
-      // to build initial connection graph field edges.
-      addp_worklist.append(n);
-    } else if (n->is_MergeMem()) {
-      // Collect all MergeMem nodes to add memory slices for
-      // scalar replaceable objects in split_unique_types().
-      _mergemem_worklist.append(n->as_MergeMem());
-    } else if (OptimizePtrCompare && n->is_Cmp() &&
-               (n->Opcode() == Op_CmpP || n->Opcode() == Op_CmpN)) {
-      // Compare pointers nodes
-      ptr_cmp_worklist.append(n);
-    } else if (n->is_MemBarStoreStore()) {
-      // Collect all MemBarStoreStore nodes so that depending on the
-      // escape status of the associated Allocate node some of them
-      // may be eliminated.
-      storestore_worklist.append(n);
-    }
-    for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-      Node* m = n->fast_out(i);   // Get user
-      worklist_init.push(m);
-    }
-  }
-
-  if (alloc_worklist.length() == 0) {
-    _collecting = false;
-    return false; // Nothing to do.
-  }
-
-  // 2. First pass to create simple CG edges (doesn't require to walk CG).
-  uint delayed_size = _delayed_worklist.size();
-  for( uint next = 0; next < delayed_size; ++next ) {
-    Node* n = _delayed_worklist.at(next);
-    build_connection_graph(n, igvn);
-  }
-
-  // 3. Pass to create initial fields edges (JavaObject -F-> AddP)
-  //    to reduce number of iterations during stage 4 below.
-  uint addp_length = addp_worklist.length();
-  for( uint next = 0; next < addp_length; ++next ) {
-    Node* n = addp_worklist.at(next);
-    Node* base = get_addp_base(n);
-    if (base->is_Proj() && base->in(0)->is_Call())
-      base = base->in(0);
-    PointsToNode::NodeType nt = ptnode_adr(base->_idx)->node_type();
-    if (nt == PointsToNode::JavaObject) {
-      build_connection_graph(n, igvn);
-    }
-  }
-
-  GrowableArray<int> cg_worklist;
-  cg_worklist.append(_phantom_object);
-  GrowableArray<uint>  worklist;
-
-  // 4. Build Connection Graph which need
-  //    to walk the connection graph.
-  _progress = false;
-  for (uint ni = 0; ni < nodes_size(); ni++) {
-    PointsToNode* ptn = ptnode_adr(ni);
-    Node *n = ptn->_node;
-    if (n != NULL) { // Call, AddP, LoadP, StoreP
-      build_connection_graph(n, igvn);
-      if (ptn->node_type() != PointsToNode::UnknownType)
-        cg_worklist.append(n->_idx); // Collect CG nodes
-      if (!_processed.test(n->_idx))
-        worklist.append(n->_idx); // Collect C/A/L/S nodes
-    }
-  }
-
-  // After IGVN user nodes may have smaller _idx than
-  // their inputs so they will be processed first in
-  // previous loop. Because of that not all Graph
-  // edges will be created. Walk over interesting
-  // nodes again until no new edges are created.
-  //
-  // Normally only 1-3 passes needed to build
-  // Connection Graph depending on graph complexity.
-  // 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.
-  // Also limit build time to 30 sec (60 in debug VM).
-
-#define CG_BUILD_ITER_LIMIT 20
-
-#ifdef ASSERT
-#define CG_BUILD_TIME_LIMIT 60.0
-#else
-#define CG_BUILD_TIME_LIMIT 30.0
-#endif
-
-  uint length = worklist.length();
-  int iterations = 0;
-  elapsedTimer time;
-  while(_progress &&
-        (iterations++   < CG_BUILD_ITER_LIMIT) &&
-        (time.seconds() < CG_BUILD_TIME_LIMIT)) {
-    time.start();
-    _progress = false;
-    for( uint next = 0; next < length; ++next ) {
-      int ni = worklist.at(next);
-      PointsToNode* ptn = ptnode_adr(ni);
-      Node* n = ptn->_node;
-      assert(n != NULL, "should be known node");
-      build_connection_graph(n, igvn);
-    }
-    time.stop();
-  }
-  if ((iterations     >= CG_BUILD_ITER_LIMIT) ||
-      (time.seconds() >= CG_BUILD_TIME_LIMIT)) {
-    assert(false, err_msg("infinite EA connection graph build (%f sec, %d iterations) with %d nodes and worklist size %d",
-           time.seconds(), iterations, nodes_size(), length));
-    // Possible infinite build_connection_graph loop,
-    // bailout (no changes to ideal graph were made).
-    _collecting = false;
-    return false;
-  }
-#undef CG_BUILD_ITER_LIMIT
-#undef CG_BUILD_TIME_LIMIT
-
-  // 5. Propagate escaped states.
-  worklist.clear();
-
-  // mark all nodes reachable from GlobalEscape nodes
-  (void)propagate_escape_state(&cg_worklist, &worklist, PointsToNode::GlobalEscape);
-
-  // mark all nodes reachable from ArgEscape nodes
-  bool has_non_escaping_obj = propagate_escape_state(&cg_worklist, &worklist, PointsToNode::ArgEscape);
-
-  Arena* arena = Thread::current()->resource_area();
-  VectorSet visited(arena);
-
-  // 6. Find fields initializing values for not escaped allocations
-  uint alloc_length = alloc_worklist.length();
-  for (uint next = 0; next < alloc_length; ++next) {
-    Node* n = alloc_worklist.at(next);
-    PointsToNode::EscapeState es = ptnode_adr(n->_idx)->escape_state();
-    if (es == PointsToNode::NoEscape) {
-      has_non_escaping_obj = true;
-      if (n->is_Allocate()) {
-        find_init_values(n, &visited, igvn);
-        // The object allocated by this Allocate node will never be
-        // seen by an other thread. Mark it so that when it is
-        // expanded no MemBarStoreStore is added.
-        n->as_Allocate()->initialization()->set_does_not_escape();
-      }
-    } else if ((es == PointsToNode::ArgEscape) && n->is_Allocate()) {
-      // Same as above. Mark this Allocate node so that when it is
-      // expanded no MemBarStoreStore is added.
-      n->as_Allocate()->initialization()->set_does_not_escape();
-    }
-  }
-
-  uint cg_length = cg_worklist.length();
-
-  // Skip the rest of code if all objects escaped.
-  if (!has_non_escaping_obj) {
-    cg_length = 0;
-    addp_length = 0;
-  }
-
-  for (uint next = 0; next < cg_length; ++next) {
-    int ni = cg_worklist.at(next);
-    PointsToNode* ptn = ptnode_adr(ni);
-    PointsToNode::NodeType nt = ptn->node_type();
-    if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
-      if (ptn->edge_count() == 0) {
-        // No values were found. Assume the value was set
-        // outside this method - add edge to phantom object.
-        add_pointsto_edge(ni, _phantom_object);
-      }
-    }
-  }
-
-  // 7. Remove deferred edges from the graph.
-  for (uint next = 0; next < cg_length; ++next) {
-    int ni = cg_worklist.at(next);
-    PointsToNode* ptn = ptnode_adr(ni);
-    PointsToNode::NodeType nt = ptn->node_type();
-    if (nt == PointsToNode::LocalVar || nt == PointsToNode::Field) {
-      remove_deferred(ni, &worklist, &visited);
-    }
-  }
-
-  // 8. Adjust escape state of nonescaping objects.
-  for (uint next = 0; next < addp_length; ++next) {
-    Node* n = addp_worklist.at(next);
-    adjust_escape_state(n);
-  }
-
-  // push all NoEscape nodes on the worklist
-  worklist.clear();
-  for( uint next = 0; next < cg_length; ++next ) {
-    int nk = cg_worklist.at(next);
-    if (ptnode_adr(nk)->escape_state() == PointsToNode::NoEscape &&
-        !is_null_ptr(nk))
-      worklist.push(nk);
-  }
-
-  alloc_worklist.clear();
-  // Propagate scalar_replaceable value.
-  while(worklist.length() > 0) {
-    uint nk = worklist.pop();
-    PointsToNode* ptn = ptnode_adr(nk);
-    Node* n = ptn->_node;
-    bool scalar_replaceable = ptn->scalar_replaceable();
-    if (n->is_Allocate() && scalar_replaceable) {
-      // Push scalar replaceable allocations on alloc_worklist
-      // for processing in split_unique_types(). Note,
-      // following code may change scalar_replaceable value.
-      alloc_worklist.append(n);
-    }
-    uint e_cnt = ptn->edge_count();
-    for (uint ei = 0; ei < e_cnt; ei++) {
-      uint npi = ptn->edge_target(ei);
-      if (is_null_ptr(npi))
-        continue;
-      PointsToNode *np = ptnode_adr(npi);
-      if (np->escape_state() < PointsToNode::NoEscape) {
-        set_escape_state(npi, PointsToNode::NoEscape);
-        if (!scalar_replaceable) {
-          np->set_scalar_replaceable(false);
-        }
-        worklist.push(npi);
-      } else if (np->scalar_replaceable() && !scalar_replaceable) {
-        np->set_scalar_replaceable(false);
-        worklist.push(npi);
-      }
-    }
-  }
-
-  _collecting = false;
-  assert(C->unique() == nodes_size(), "there should be no new ideal nodes during ConnectionGraph build");
-
-  assert(ptnode_adr(_oop_null)->escape_state() == PointsToNode::NoEscape &&
-         ptnode_adr(_oop_null)->edge_count() == 0, "sanity");
-  if (UseCompressedOops) {
-    assert(ptnode_adr(_noop_null)->escape_state() == PointsToNode::NoEscape &&
-           ptnode_adr(_noop_null)->edge_count() == 0, "sanity");
-  }
-
-  if (EliminateLocks && has_non_escaping_obj) {
-    // Mark locks before changing ideal graph.
-    int cnt = C->macro_count();
-    for( int i=0; i < cnt; i++ ) {
-      Node *n = C->macro_node(i);
-      if (n->is_AbstractLock()) { // Lock and Unlock nodes
-        AbstractLockNode* alock = n->as_AbstractLock();
-        if (!alock->is_non_esc_obj()) {
-          PointsToNode::EscapeState es = escape_state(alock->obj_node());
-          assert(es != PointsToNode::UnknownEscape, "should know");
-          if (es != PointsToNode::UnknownEscape && es != PointsToNode::GlobalEscape) {
-            assert(!alock->is_eliminated() || alock->is_coarsened(), "sanity");
-            // The lock could be marked eliminated by lock coarsening
-            // code during first IGVN before EA. Replace coarsened flag
-            // to eliminate all associated locks/unlocks.
-            alock->set_non_esc_obj();
-          }
-        }
-      }
-    }
-  }
-
-  if (OptimizePtrCompare && has_non_escaping_obj) {
-    // Add ConI(#CC_GT) and ConI(#CC_EQ).
-    _pcmp_neq = igvn->makecon(TypeInt::CC_GT);
-    _pcmp_eq = igvn->makecon(TypeInt::CC_EQ);
-    // Optimize objects compare.
-    while (ptr_cmp_worklist.length() != 0) {
-      Node *n = ptr_cmp_worklist.pop();
-      Node *res = optimize_ptr_compare(n);
-      if (res != NULL) {
 #ifndef PRODUCT
-        if (PrintOptimizePtrCompare) {
-          tty->print_cr("++++ Replaced: %d %s(%d,%d) --> %s", n->_idx, (n->Opcode() == Op_CmpP ? "CmpP" : "CmpN"), n->in(1)->_idx, n->in(2)->_idx, (res == _pcmp_eq ? "EQ" : "NotEQ"));
-          if (Verbose) {
-            n->dump(1);
-          }
-        }
-#endif
-        _igvn->replace_node(n, res);
-      }
+static const char *node_type_names[] = {
+  "UnknownType",
+  "JavaObject",
+  "LocalVar",
+  "Field",
+  "Arraycopy"
+};
+
+static const char *esc_names[] = {
+  "UnknownEscape",
+  "NoEscape",
+  "ArgEscape",
+  "GlobalEscape"
+};
+
+void PointsToNode::dump(bool print_state) const {
+  NodeType nt = node_type();
+  tty->print("%s ", node_type_names[(int) nt]);
+  if (print_state) {
+    EscapeState es = escape_state();
+    EscapeState fields_es = fields_escape_state();
+    tty->print("%s(%s) ", esc_names[(int)es], esc_names[(int)fields_es]);
+    if (nt == PointsToNode::JavaObject && !this->scalar_replaceable())
+      tty->print("NSR ");
+  }
+  if (is_Field()) {
+    FieldNode* f = (FieldNode*)this;
+    if (f->is_oop())
+      tty->print("oop ");
+    if (f->offset() > 0)
+      tty->print("+%d ", f->offset());
+    tty->print("(");
+    for (BaseIterator i(f); i.has_next(); i.next()) {
+      PointsToNode* b = i.get();
+      tty->print(" %d%s", b->idx(),(b->is_JavaObject() ? "P" : ""));
     }
-    // cleanup
-    if (_pcmp_neq->outcnt() == 0)
-      igvn->hash_delete(_pcmp_neq);
-    if (_pcmp_eq->outcnt()  == 0)
-      igvn->hash_delete(_pcmp_eq);
+    tty->print(" )");
   }
-
-  // For MemBarStoreStore nodes added in library_call.cpp, check
-  // escape status of associated AllocateNode and optimize out
-  // MemBarStoreStore node if the allocated object never escapes.
-  while (storestore_worklist.length() != 0) {
-    Node *n = storestore_worklist.pop();
-    MemBarStoreStoreNode *storestore = n ->as_MemBarStoreStore();
-    Node *alloc = storestore->in(MemBarNode::Precedent)->in(0);
-    assert (alloc->is_Allocate(), "storestore should point to AllocateNode");
-    PointsToNode::EscapeState es = ptnode_adr(alloc->_idx)->escape_state();
-    if (es == PointsToNode::NoEscape || es == PointsToNode::ArgEscape) {
-      MemBarNode* mb = MemBarNode::make(C, Op_MemBarCPUOrder, Compile::AliasIdxBot);
-      mb->init_req(TypeFunc::Memory, storestore->in(TypeFunc::Memory));
-      mb->init_req(TypeFunc::Control, storestore->in(TypeFunc::Control));
-
-      _igvn->register_new_node_with_optimizer(mb);
-      _igvn->replace_node(storestore, mb);
+  tty->print("[");
+  for (EdgeIterator i(this); i.has_next(); i.next()) {
+    PointsToNode* e = i.get();
+    tty->print(" %d%s%s", e->idx(),(e->is_JavaObject() ? "P" : (e->is_Field() ? "F" : "")), e->is_Arraycopy() ? "cp" : "");
+  }
+  tty->print(" [");
+  for (UseIterator i(this); i.has_next(); i.next()) {
+    PointsToNode* u = i.get();
+    bool is_base = false;
+    if (PointsToNode::is_base_use(u)) {
+      is_base = true;
+      u = PointsToNode::get_use_node(u)->as_Field();
     }
+    tty->print(" %d%s%s", u->idx(), is_base ? "b" : "", u->is_Arraycopy() ? "cp" : "");
   }
-
-#ifndef PRODUCT
-  if (PrintEscapeAnalysis) {
-    dump(); // Dump ConnectionGraph
-  }
-#endif
-
-  bool has_scalar_replaceable_candidates = false;
-  alloc_length = alloc_worklist.length();
-  for (uint next = 0; next < alloc_length; ++next) {
-    Node* n = alloc_worklist.at(next);
-    PointsToNode* ptn = ptnode_adr(n->_idx);
-    assert(ptn->escape_state() == PointsToNode::NoEscape, "sanity");
-    if (ptn->scalar_replaceable()) {
-      has_scalar_replaceable_candidates = true;
-      break;
-    }
-  }
-
-  if ( has_scalar_replaceable_candidates &&
-       C->AliasLevel() >= 3 && EliminateAllocations ) {
-
-    // Now use the escape information to create unique types for
-    // scalar replaceable objects.
-    split_unique_types(alloc_worklist);
-
-    if (C->failing())  return false;
-
-    C->print_method("After Escape Analysis", 2);
-
-#ifdef ASSERT
-  } else if (Verbose && (PrintEscapeAnalysis || PrintEliminateAllocations)) {
-    tty->print("=== No allocations eliminated for ");
-    C->method()->print_short_name();
-    if(!EliminateAllocations) {
-      tty->print(" since EliminateAllocations is off ===");
-    } else if(!has_scalar_replaceable_candidates) {
-      tty->print(" since there are no scalar replaceable candidates ===");
-    } else if(C->AliasLevel() < 3) {
-      tty->print(" since AliasLevel < 3 ===");
-    }
-    tty->cr();
-#endif
-  }
-  return has_non_escaping_obj;
+  tty->print(" ]]  ");
+  if (_node == NULL)
+    tty->print_cr("<null>");
+  else
+    _node->dump();
 }
 
-// Find fields initializing values for allocations.
-void ConnectionGraph::find_init_values(Node* alloc, VectorSet* visited, PhaseTransform* phase) {
-  assert(alloc->is_Allocate(), "Should be called for Allocate nodes only");
-  PointsToNode* pta = ptnode_adr(alloc->_idx);
-  assert(pta->escape_state() == PointsToNode::NoEscape, "Not escaped Allocate nodes only");
-  InitializeNode* ini = alloc->as_Allocate()->initialization();
-
-  Compile* C = _compile;
-  visited->Reset();
-  // Check if a oop field's initializing value is recorded and add
-  // a corresponding NULL field's value if it is not recorded.
-  // Connection Graph does not record a default initialization by NULL
-  // captured by Initialize node.
-  //
-  uint null_idx = UseCompressedOops ? _noop_null : _oop_null;
-  uint ae_cnt = pta->edge_count();
-  bool visited_bottom_offset = false;
-  for (uint ei = 0; ei < ae_cnt; ei++) {
-    uint nidx = pta->edge_target(ei); // Field (AddP)
-    PointsToNode* ptn = ptnode_adr(nidx);
-    assert(ptn->_node->is_AddP(), "Should be AddP nodes only");
-    int offset = ptn->offset();
-    if (offset == Type::OffsetBot) {
-      if (!visited_bottom_offset) {
-        visited_bottom_offset = true;
-        // Check only oop fields.
-        const Type* adr_type = ptn->_node->as_AddP()->bottom_type();
-        if (!adr_type->isa_aryptr() ||
-            (adr_type->isa_aryptr()->klass() == NULL) ||
-             adr_type->isa_aryptr()->klass()->is_obj_array_klass()) {
-          // OffsetBot is used to reference array's element,
-          // always add reference to NULL since we don't
-          // known which element is referenced.
-          add_edge_from_fields(alloc->_idx, null_idx, offset);
-        }
-      }
-    } else if (offset != oopDesc::klass_offset_in_bytes() &&
-               !visited->test_set(offset)) {
-
-      // Check only oop fields.
-      const Type* adr_type = ptn->_node->as_AddP()->bottom_type();
-      BasicType basic_field_type = T_INT;
-      if (adr_type->isa_instptr()) {
-        ciField* field = C->alias_type(adr_type->isa_instptr())->field();
-        if (field != NULL) {
-          basic_field_type = field->layout_type();
-        } else {
-          // Ignore non field load (for example, klass load)
-        }
-      } else if (adr_type->isa_aryptr()) {
-        if (offset != arrayOopDesc::length_offset_in_bytes()) {
-          const Type* elemtype = adr_type->isa_aryptr()->elem();
-          basic_field_type = elemtype->array_element_basic_type();
-        } else {
-          // Ignore array length load
-        }
-#ifdef ASSERT
-      } else {
-        // Raw pointers are used for initializing stores so skip it
-        // since it should be recorded already
-        Node* base = get_addp_base(ptn->_node);
-        assert(adr_type->isa_rawptr() && base->is_Proj() &&
-               (base->in(0) == alloc),"unexpected pointer type");
-#endif
-      }
-      if (basic_field_type == T_OBJECT ||
-          basic_field_type == T_NARROWOOP ||
-          basic_field_type == T_ARRAY) {
-        Node* value = NULL;
-        if (ini != NULL) {
-          BasicType ft = UseCompressedOops ? T_NARROWOOP : T_OBJECT;
-          Node* store = ini->find_captured_store(offset, type2aelembytes(ft), phase);
-          if (store != NULL && store->is_Store()) {
-            value = store->in(MemNode::ValueIn);
-          } else {
-            // There could be initializing stores which follow allocation.
-            // For example, a volatile field store is not collected
-            // by Initialize node.
-            //
-            // Need to check for dependent loads to separate such stores from
-            // stores which follow loads. For now, add initial value NULL so
-            // that compare pointers optimization works correctly.
-          }
-        }
-        if (value == NULL || value != ptnode_adr(value->_idx)->_node) {
-          // A field's initializing value was not recorded. Add NULL.
-          add_edge_from_fields(alloc->_idx, null_idx, offset);
-        }
-      }
-    }
-  }
-}
-
-// Adjust escape state after Connection Graph is built.
-void ConnectionGraph::adjust_escape_state(Node* n) {
-  PointsToNode* ptn = ptnode_adr(n->_idx);
-  assert(n->is_AddP(), "Should be called for AddP nodes only");
-  // Search for objects which are not scalar replaceable
-  // and mark them to propagate the state to referenced objects.
-  //
-
-  int offset = ptn->offset();
-  Node* base = get_addp_base(n);
-  VectorSet* ptset = PointsTo(base);
-  int ptset_size = ptset->Size();
-
-  // An object is not scalar replaceable if the field which may point
-  // to it has unknown offset (unknown element of an array of objects).
-  //
-
-  if (offset == Type::OffsetBot) {
-    uint e_cnt = ptn->edge_count();
-    for (uint ei = 0; ei < e_cnt; ei++) {
-      uint npi = ptn->edge_target(ei);
-      ptnode_adr(npi)->set_scalar_replaceable(false);
-    }
-  }
-
-  // Currently an object is not scalar replaceable if a LoadStore node
-  // access its field since the field value is unknown after it.
-  //
-  bool has_LoadStore = false;
-  for (DUIterator_Fast imax, i = n->fast_outs(imax); i < imax; i++) {
-    Node *use = n->fast_out(i);
-    if (use->is_LoadStore()) {
-      has_LoadStore = true;
-      break;
-    }
-  }
-  // An object is not scalar replaceable if the address points
-  // to unknown field (unknown element for arrays, offset is OffsetBot).
-  //
-  // Or the address may point to more then one object. This may produce
-  // the false positive result (set not scalar replaceable)
-  // since the flow-insensitive escape analysis can't separate
-  // the case when stores overwrite the field's value from the case
-  // when stores happened on different control branches.
-  //
-  // Note: it will disable scalar replacement in some cases:
-  //
-  //    Point p[] = new Point[1];
-  //    p[0] = new Point(); // Will be not scalar replaced
-  //
-  // but it will save us from incorrect optimizations in next cases:
-  //
-  //    Point p[] = new Point[1];
-  //    if ( x ) p[0] = new Point(); // Will be not scalar replaced
-  //
-  if (ptset_size > 1 || ptset_size != 0 &&
-      (has_LoadStore || offset == Type::OffsetBot)) {
-    for( VectorSetI j(ptset); j.test(); ++j ) {
-      ptnode_adr(j.elem)->set_scalar_replaceable(false);
-    }
-  }
-}
-
-// Propagate escape states to referenced nodes.
-bool ConnectionGraph::propagate_escape_state(GrowableArray<int>* cg_worklist,
-                                             GrowableArray<uint>* worklist,
-                                             PointsToNode::EscapeState esc_state) {
-  bool has_java_obj = false;
-
-  // push all nodes with the same escape state on the worklist
-  uint cg_length = cg_worklist->length();
-  for (uint next = 0; next < cg_length; ++next) {
-    int nk = cg_worklist->at(next);
-    if (ptnode_adr(nk)->escape_state() == esc_state)
-      worklist->push(nk);
-  }
-  // mark all reachable nodes
-  while (worklist->length() > 0) {
-    int pt = worklist->pop();
-    PointsToNode* ptn = ptnode_adr(pt);
-    if (ptn->node_type() == PointsToNode::JavaObject &&
-        !is_null_ptr(pt)) {
-      has_java_obj = true;
-      if (esc_state > PointsToNode::NoEscape) {
-        // fields values are unknown if object escapes
-        add_edge_from_fields(pt, _phantom_object, Type::OffsetBot);
-      }
-    }
-    uint e_cnt = ptn->edge_count();
-    for (uint ei = 0; ei < e_cnt; ei++) {
-      uint npi = ptn->edge_target(ei);
-      if (is_null_ptr(npi))
-        continue;
-      PointsToNode *np = ptnode_adr(npi);
-      if (np->escape_state() < esc_state) {
-        set_escape_state(npi, esc_state);
-        worklist->push(npi);
-      }
-    }
-  }
-  // Has not escaping java objects
-  return has_java_obj && (esc_state < PointsToNode::GlobalEscape);
-}
-
-// Optimize objects compare.
-Node* ConnectionGraph::optimize_ptr_compare(Node* n) {
-  assert(OptimizePtrCompare, "sanity");
-  // Clone returned Set since PointsTo() returns pointer
-  // to the same structure ConnectionGraph.pt_ptset.
-  VectorSet ptset1 = *PointsTo(n->in(1));
-  VectorSet ptset2 = *PointsTo(n->in(2));
-
-  // Check simple cases first.
-  if (ptset1.Size() == 1) {
-    uint pt1 = ptset1.getelem();
-    PointsToNode* ptn1 = ptnode_adr(pt1);
-    if (ptn1->escape_state() == PointsToNode::NoEscape) {
-      if (ptset2.Size() == 1 && ptset2.getelem() == pt1) {
-        // Comparing the same not escaping object.
-        return _pcmp_eq;
-      }
-      Node* obj = ptn1->_node;
-      // Comparing not escaping allocation.
-      if ((obj->is_Allocate() || obj->is_CallStaticJava()) &&
-          !ptset2.test(pt1)) {
-        return _pcmp_neq; // This includes nullness check.
-      }
-    }
-  } else if (ptset2.Size() == 1) {
-    uint pt2 = ptset2.getelem();
-    PointsToNode* ptn2 = ptnode_adr(pt2);
-    if (ptn2->escape_state() == PointsToNode::NoEscape) {
-      Node* obj = ptn2->_node;
-      // Comparing not escaping allocation.
-      if ((obj->is_Allocate() || obj->is_CallStaticJava()) &&
-          !ptset1.test(pt2)) {
-        return _pcmp_neq; // This includes nullness check.
-      }
-    }
-  }
-
-  if (!ptset1.disjoint(ptset2)) {
-    return NULL; // Sets are not disjoint
-  }
-
-  // Sets are disjoint.
-  bool set1_has_unknown_ptr = ptset1.test(_phantom_object) != 0;
-  bool set2_has_unknown_ptr = ptset2.test(_phantom_object) != 0;
-  bool set1_has_null_ptr   = (ptset1.test(_oop_null) | ptset1.test(_noop_null)) != 0;
-  bool set2_has_null_ptr   = (ptset2.test(_oop_null) | ptset2.test(_noop_null)) != 0;
-
-  if (set1_has_unknown_ptr && set2_has_null_ptr ||
-      set2_has_unknown_ptr && set1_has_null_ptr) {
-    // Check nullness of unknown object.
-    return NULL;
-  }
-
-  // Disjointness by itself is not sufficient since
-  // alias analysis is not complete for escaped objects.
-  // Disjoint sets are definitely unrelated only when
-  // at least one set has only not escaping objects.
-  if (!set1_has_unknown_ptr && !set1_has_null_ptr) {
-    bool has_only_non_escaping_alloc = true;
-    for (VectorSetI i(&ptset1); i.test(); ++i) {
-      uint pt = i.elem;
-      PointsToNode* ptn = ptnode_adr(pt);
-      Node* obj = ptn->_node;
-      if (ptn->escape_state() != PointsToNode::NoEscape ||
-          !(obj->is_Allocate() || obj->is_CallStaticJava())) {
-        has_only_non_escaping_alloc = false;
-        break;
-      }
-    }
-    if (has_only_non_escaping_alloc) {
-      return _pcmp_neq;
-    }
-  }
-  if (!set2_has_unknown_ptr && !set2_has_null_ptr) {
-    bool has_only_non_escaping_alloc = true;
-    for (VectorSetI i(&ptset2); i.test(); ++i) {
-      uint pt = i.elem;
-      PointsToNode* ptn = ptnode_adr(pt);
-      Node* obj = ptn->_node;
-      if (ptn->escape_state() != PointsToNode::NoEscape ||
-          !(obj->is_Allocate() || obj->is_CallStaticJava())) {
-        has_only_non_escaping_alloc = false;
-        break;
-      }
-    }
-    if (has_only_non_escaping_alloc) {
-      return _pcmp_neq;
-    }
-  }
-  return NULL;
-}
-
-void ConnectionGraph::process_call_arguments(CallNode *call, PhaseTransform *phase) {
-    bool is_arraycopy = false;
-    switch (call->Opcode()) {
-#ifdef ASSERT
-    case Op_Allocate:
-    case Op_AllocateArray:
-    case Op_Lock:
-    case Op_Unlock:
-      assert(false, "should be done already");
-      break;
-#endif
-    case Op_CallLeafNoFP:
-      is_arraycopy = (call->as_CallLeaf()->_name != NULL &&
-                      strstr(call->as_CallLeaf()->_name, "arraycopy") != 0);
-      // fall through
-    case Op_CallLeaf:
-    {
-      // Stub calls, objects do not escape but they are not scale replaceable.
-      // Adjust escape state for outgoing arguments.
-      const TypeTuple * d = call->tf()->domain();
-      bool src_has_oops = false;
-      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
-        const Type* at = d->field_at(i);
-        Node *arg = call->in(i)->uncast();
-        const Type *aat = phase->type(arg);
-        PointsToNode::EscapeState arg_esc = ptnode_adr(arg->_idx)->escape_state();
-        if (!arg->is_top() && at->isa_ptr() && aat->isa_ptr() &&
-            (is_arraycopy || arg_esc < PointsToNode::ArgEscape)) {
-#ifdef ASSERT
-          assert(aat == Type::TOP || aat == TypePtr::NULL_PTR ||
-                 aat->isa_ptr() != NULL, "expecting an Ptr");
-          if (!(is_arraycopy ||
-                call->as_CallLeaf()->_name != NULL &&
-                (strcmp(call->as_CallLeaf()->_name, "g1_wb_pre")  == 0 ||
-                 strcmp(call->as_CallLeaf()->_name, "g1_wb_post") == 0 ))
-          ) {
-            call->dump();
-            assert(false, "EA: unexpected CallLeaf");
-          }
-#endif
-          if (arg_esc < PointsToNode::ArgEscape) {
-            set_escape_state(arg->_idx, PointsToNode::ArgEscape);
-            Node* arg_base = arg;
-            if (arg->is_AddP()) {
-              //
-              // The inline_native_clone() case when the arraycopy stub is called
-              // after the allocation before Initialize and CheckCastPP nodes.
-              // Or normal arraycopy for object arrays case.
-              //
-              // Set AddP's base (Allocate) as not scalar replaceable since
-              // pointer to the base (with offset) is passed as argument.
-              //
-              arg_base = get_addp_base(arg);
-              set_escape_state(arg_base->_idx, PointsToNode::ArgEscape);
-            }
-          }
-
-          bool arg_has_oops = aat->isa_oopptr() &&
-                              (aat->isa_oopptr()->klass() == NULL || aat->isa_instptr() ||
-                               (aat->isa_aryptr() && aat->isa_aryptr()->klass()->is_obj_array_klass()));
-          if (i == TypeFunc::Parms) {
-            src_has_oops = arg_has_oops;
-          }
-          //
-          // src or dst could be j.l.Object when other is basic type array:
-          //
-          //   arraycopy(char[],0,Object*,0,size);
-          //   arraycopy(Object*,0,char[],0,size);
-          //
-          // Do nothing special in such cases.
-          //
-          if (is_arraycopy && (i > TypeFunc::Parms) &&
-              src_has_oops && arg_has_oops) {
-            // Destination object's fields reference an unknown object.
-            Node* arg_base = arg;
-            if (arg->is_AddP()) {
-              arg_base = get_addp_base(arg);
-            }
-            for (VectorSetI s(PointsTo(arg_base)); s.test(); ++s) {
-              uint ps = s.elem;
-              set_escape_state(ps, PointsToNode::ArgEscape);
-              add_edge_from_fields(ps, _phantom_object, Type::OffsetBot);
-            }
-            // Conservatively all values in source object fields globally escape
-            // since we don't know if values in destination object fields
-            // escape (it could be traced but it is too expensive).
-            Node* src = call->in(TypeFunc::Parms)->uncast();
-            Node* src_base = src;
-            if (src->is_AddP()) {
-              src_base  = get_addp_base(src);
-            }
-            for (VectorSetI s(PointsTo(src_base)); s.test(); ++s) {
-              uint ps = s.elem;
-              set_escape_state(ps, PointsToNode::ArgEscape);
-              // Use OffsetTop to indicate fields global escape.
-              add_edge_from_fields(ps, _phantom_object, Type::OffsetTop);
-            }
-          }
-        }
-      }
-      break;
-    }
-
-    case Op_CallStaticJava:
-    // For a static call, we know exactly what method is being called.
-    // Use bytecode estimator to record the call's escape affects
-    {
-      ciMethod *meth = call->as_CallJava()->method();
-      BCEscapeAnalyzer *call_analyzer = (meth !=NULL) ? meth->get_bcea() : NULL;
-      // fall-through if not a Java method or no analyzer information
-      if (call_analyzer != NULL) {
-        const TypeTuple * d = call->tf()->domain();
-        bool copy_dependencies = false;
-        for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
-          const Type* at = d->field_at(i);
-          int k = i - TypeFunc::Parms;
-          Node *arg = call->in(i)->uncast();
-
-          if (at->isa_oopptr() != NULL &&
-              ptnode_adr(arg->_idx)->escape_state() < PointsToNode::GlobalEscape) {
-
-            bool global_escapes = false;
-            bool fields_escapes = false;
-            if (!call_analyzer->is_arg_stack(k)) {
-              // The argument global escapes, mark everything it could point to
-              set_escape_state(arg->_idx, PointsToNode::GlobalEscape);
-              global_escapes = true;
-            } else {
-              if (!call_analyzer->is_arg_local(k)) {
-                // The argument itself doesn't escape, but any fields might
-                fields_escapes = true;
-              }
-              set_escape_state(arg->_idx, PointsToNode::ArgEscape);
-              copy_dependencies = true;
-            }
-
-            for( VectorSetI j(PointsTo(arg)); j.test(); ++j ) {
-              uint pt = j.elem;
-              if (global_escapes) {
-                // The argument global escapes, mark everything it could point to
-                set_escape_state(pt, PointsToNode::GlobalEscape);
-                add_edge_from_fields(pt, _phantom_object, Type::OffsetBot);
-              } else {
-                set_escape_state(pt, PointsToNode::ArgEscape);
-                if (fields_escapes) {
-                  // The argument itself doesn't escape, but any fields might.
-                  // Use OffsetTop to indicate such case.
-                  add_edge_from_fields(pt, _phantom_object, Type::OffsetTop);
-                }
-              }
-            }
-          }
-        }
-        if (copy_dependencies)
-          call_analyzer->copy_dependencies(_compile->dependencies());
-        break;
-      }
-    }
-
-    default:
-    // Fall-through here if not a Java method or no analyzer information
-    // or some other type of call, assume the worst case: all arguments
-    // globally escape.
-    {
-      // adjust escape state for  outgoing arguments
-      const TypeTuple * d = call->tf()->domain();
-      for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
-        const Type* at = d->field_at(i);
-        if (at->isa_oopptr() != NULL) {
-          Node *arg = call->in(i)->uncast();
-          set_escape_state(arg->_idx, PointsToNode::GlobalEscape);
-          for( VectorSetI j(PointsTo(arg)); j.test(); ++j ) {
-            uint pt = j.elem;
-            set_escape_state(pt, PointsToNode::GlobalEscape);
-            add_edge_from_fields(pt, _phantom_object, Type::OffsetBot);
-          }
-        }
-      }
-    }
-  }
-}
-void ConnectionGraph::process_call_result(ProjNode *resproj, PhaseTransform *phase) {
-  CallNode   *call = resproj->in(0)->as_Call();
-  uint    call_idx = call->_idx;
-  uint resproj_idx = resproj->_idx;
-
-  switch (call->Opcode()) {
-    case Op_Allocate:
-    {
-      Node *k = call->in(AllocateNode::KlassNode);
-      const TypeKlassPtr *kt = k->bottom_type()->isa_klassptr();
-      assert(kt != NULL, "TypeKlassPtr  required.");
-      ciKlass* cik = kt->klass();
-
-      PointsToNode::EscapeState es;
-      uint edge_to;
-      if (cik->is_subclass_of(_compile->env()->Thread_klass()) ||
-         !cik->is_instance_klass() || // StressReflectiveCode
-          cik->as_instance_klass()->has_finalizer()) {
-        es = PointsToNode::GlobalEscape;
-        edge_to = _phantom_object; // Could not be worse
-      } else {
-        es = PointsToNode::NoEscape;
-        edge_to = call_idx;
-        assert(ptnode_adr(call_idx)->scalar_replaceable(), "sanity");
-      }
-      set_escape_state(call_idx, es);
-      add_pointsto_edge(resproj_idx, edge_to);
-      _processed.set(resproj_idx);
-      break;
-    }
-
-    case Op_AllocateArray:
-    {
-
-      Node *k = call->in(AllocateNode::KlassNode);
-      const TypeKlassPtr *kt = k->bottom_type()->isa_klassptr();
-      assert(kt != NULL, "TypeKlassPtr  required.");
-      ciKlass* cik = kt->klass();
-
-      PointsToNode::EscapeState es;
-      uint edge_to;
-      if (!cik->is_array_klass()) { // StressReflectiveCode
-        es = PointsToNode::GlobalEscape;
-        edge_to = _phantom_object;
-      } else {
-        es = PointsToNode::NoEscape;
-        edge_to = call_idx;
-        assert(ptnode_adr(call_idx)->scalar_replaceable(), "sanity");
-        int length = call->in(AllocateNode::ALength)->find_int_con(-1);
-        if (length < 0 || length > EliminateAllocationArraySizeLimit) {
-          // Not scalar replaceable if the length is not constant or too big.
-          ptnode_adr(call_idx)->set_scalar_replaceable(false);
-        }
-      }
-      set_escape_state(call_idx, es);
-      add_pointsto_edge(resproj_idx, edge_to);
-      _processed.set(resproj_idx);
-      break;
-    }
-
-    case Op_CallStaticJava:
-    // For a static call, we know exactly what method is being called.
-    // Use bytecode estimator to record whether the call's return value escapes
-    {
-      bool done = true;
-      const TypeTuple *r = call->tf()->range();
-      const Type* ret_type = NULL;
-
-      if (r->cnt() > TypeFunc::Parms)
-        ret_type = r->field_at(TypeFunc::Parms);
-
-      // Note:  we use isa_ptr() instead of isa_oopptr()  here because the
-      //        _multianewarray functions return a TypeRawPtr.
-      if (ret_type == NULL || ret_type->isa_ptr() == NULL) {
-        _processed.set(resproj_idx);
-        break;  // doesn't return a pointer type
-      }
-      ciMethod *meth = call->as_CallJava()->method();
-      const TypeTuple * d = call->tf()->domain();
-      if (meth == NULL) {
-        // not a Java method, assume global escape
-        set_escape_state(call_idx, PointsToNode::GlobalEscape);
-        add_pointsto_edge(resproj_idx, _phantom_object);
-      } else {
-        BCEscapeAnalyzer *call_analyzer = meth->get_bcea();
-        bool copy_dependencies = false;
-
-        if (call_analyzer->is_return_allocated()) {
-          // Returns a newly allocated unescaped object, simply
-          // update dependency information.
-          // Mark it as NoEscape so that objects referenced by
-          // it's fields will be marked as NoEscape at least.
-          set_escape_state(call_idx, PointsToNode::NoEscape);
-          ptnode_adr(call_idx)->set_scalar_replaceable(false);
-          // Fields values are unknown
-          add_edge_from_fields(call_idx, _phantom_object, Type::OffsetBot);
-          add_pointsto_edge(resproj_idx, call_idx);
-          copy_dependencies = true;
-        } else {
-          // determine whether any arguments are returned
-          set_escape_state(call_idx, PointsToNode::ArgEscape);
-          bool ret_arg = false;
-          for (uint i = TypeFunc::Parms; i < d->cnt(); i++) {
-            const Type* at = d->field_at(i);
-            if (at->isa_oopptr() != NULL) {
-              Node *arg = call->in(i)->uncast();
-
-              if (call_analyzer->is_arg_returned(i - TypeFunc::Parms)) {
-                ret_arg = true;
-                PointsToNode *arg_esp = ptnode_adr(arg->_idx);
-                if (arg_esp->node_type() == PointsToNode::UnknownType)
-                  done = false;
-                else if (arg_esp->node_type() == PointsToNode::JavaObject)
-                  add_pointsto_edge(resproj_idx, arg->_idx);
-                else
-                  add_deferred_edge(resproj_idx, arg->_idx);
-              }
-            }
-          }
-          if (done) {
-            copy_dependencies = true;
-            // is_return_local() is true when only arguments are returned.
-            if (!ret_arg || !call_analyzer->is_return_local()) {
-              // Returns unknown object.
-              add_pointsto_edge(resproj_idx, _phantom_object);
-            }
-          }
-        }
-        if (copy_dependencies)
-          call_analyzer->copy_dependencies(_compile->dependencies());
-      }
-      if (done)
-        _processed.set(resproj_idx);
-      break;
-    }
-
-    default:
-    // Some other type of call, assume the worst case that the
-    // returned value, if any, globally escapes.
-    {
-      const TypeTuple *r = call->tf()->range();
-      if (r->cnt() > TypeFunc::Parms) {
-        const Type* ret_type = r->field_at(TypeFunc::Parms);
-
-        // Note:  we use isa_ptr() instead of isa_oopptr()  here because the
-        //        _multianewarray functions return a TypeRawPtr.
-        if (ret_type->isa_ptr() != NULL) {
-          set_escape_state(call_idx, PointsToNode::GlobalEscape);
-          add_pointsto_edge(resproj_idx, _phantom_object);
-        }
-      }
-      _processed.set(resproj_idx);
-    }
-  }
-}
-
-// Populate Connection Graph with Ideal nodes and create simple
-// connection graph edges (do not need to check the node_type of inputs
-// or to call PointsTo() to walk the connection graph).
-void ConnectionGraph::record_for_escape_analysis(Node *n, PhaseTransform *phase) {
-  if (_processed.test(n->_idx))
-    return; // No need to redefine node's state.
-
-  if (n->is_Call()) {
-    // Arguments to allocation and locking don't escape.
-    if (n->is_Allocate()) {
-      add_node(n, PointsToNode::JavaObject, PointsToNode::UnknownEscape, true);
-      record_for_optimizer(n);
-    } else if (n->is_Lock() || n->is_Unlock()) {
-      // Put Lock and Unlock nodes on IGVN worklist to process them during
-      // the first IGVN optimization when escape information is still available.
-      record_for_optimizer(n);
-      _processed.set(n->_idx);
-    } else {
-      // Don't mark as processed since call's arguments have to be processed.
-      PointsToNode::NodeType nt = PointsToNode::UnknownType;
-      PointsToNode::EscapeState es = PointsToNode::UnknownEscape;
-
-      // Check if a call returns an object.
-      const TypeTuple *r = n->as_Call()->tf()->range();
-      if (r->cnt() > TypeFunc::Parms &&
-          r->field_at(TypeFunc::Parms)->isa_ptr() &&
-          n->as_Call()->proj_out(TypeFunc::Parms) != NULL) {
-        nt = PointsToNode::JavaObject;
-        if (!n->is_CallStaticJava()) {
-          // Since the called mathod is statically unknown assume
-          // the worst case that the returned value globally escapes.
-          es = PointsToNode::GlobalEscape;
-        }
-      }
-      add_node(n, nt, es, false);
-    }
-    return;
-  }
-
-  // Using isa_ptr() instead of isa_oopptr() for LoadP and Phi because
-  // ThreadLocal has RawPrt type.
-  switch (n->Opcode()) {
-    case Op_AddP:
-    {
-      add_node(n, PointsToNode::Field, PointsToNode::UnknownEscape, false);
-      break;
-    }
-    case Op_CastX2P:
-    { // "Unsafe" memory access.
-      add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true);
-      break;
-    }
-    case Op_CastPP:
-    case Op_CheckCastPP:
-    case Op_EncodeP:
-    case Op_DecodeN:
-    {
-      add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
-      int ti = n->in(1)->_idx;
-      PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
-      if (nt == PointsToNode::UnknownType) {
-        _delayed_worklist.push(n); // Process it later.
-        break;
-      } else if (nt == PointsToNode::JavaObject) {
-        add_pointsto_edge(n->_idx, ti);
-      } else {
-        add_deferred_edge(n->_idx, ti);
-      }
-      _processed.set(n->_idx);
-      break;
-    }
-    case Op_ConP:
-    {
-      // assume all pointer constants globally escape except for null
-      PointsToNode::EscapeState es;
-      if (phase->type(n) == TypePtr::NULL_PTR)
-        es = PointsToNode::NoEscape;
-      else
-        es = PointsToNode::GlobalEscape;
-
-      add_node(n, PointsToNode::JavaObject, es, true);
-      break;
-    }
-    case Op_ConN:
-    {
-      // assume all narrow oop constants globally escape except for null
-      PointsToNode::EscapeState es;
-      if (phase->type(n) == TypeNarrowOop::NULL_PTR)
-        es = PointsToNode::NoEscape;
-      else
-        es = PointsToNode::GlobalEscape;
-
-      add_node(n, PointsToNode::JavaObject, es, true);
-      break;
-    }
-    case Op_CreateEx:
-    {
-      // assume that all exception objects globally escape
-      add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true);
-      break;
-    }
-    case Op_LoadKlass:
-    case Op_LoadNKlass:
-    {
-      add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, true);
-      break;
-    }
-    case Op_LoadP:
-    case Op_LoadN:
-    {
-      const Type *t = phase->type(n);
-      if (t->make_ptr() == NULL) {
-        _processed.set(n->_idx);
-        return;
-      }
-      add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
-      break;
-    }
-    case Op_Parm:
-    {
-      _processed.set(n->_idx); // No need to redefine it state.
-      uint con = n->as_Proj()->_con;
-      if (con < TypeFunc::Parms)
-        return;
-      const Type *t = n->in(0)->as_Start()->_domain->field_at(con);
-      if (t->isa_ptr() == NULL)
-        return;
-      // We have to assume all input parameters globally escape
-      // (Note: passing 'false' since _processed is already set).
-      add_node(n, PointsToNode::JavaObject, PointsToNode::GlobalEscape, false);
-      break;
-    }
-    case Op_PartialSubtypeCheck:
-    { // Produces Null or notNull and is used in CmpP.
-      add_node(n, PointsToNode::JavaObject, PointsToNode::ArgEscape, true);
-      break;
-    }
-    case Op_Phi:
-    {
-      const Type *t = n->as_Phi()->type();
-      if (t->make_ptr() == NULL) {
-        // nothing to do if not an oop or narrow oop
-        _processed.set(n->_idx);
-        return;
-      }
-      add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
-      uint i;
-      for (i = 1; i < n->req() ; i++) {
-        Node* in = n->in(i);
-        if (in == NULL)
-          continue;  // ignore NULL
-        in = in->uncast();
-        if (in->is_top() || in == n)
-          continue;  // ignore top or inputs which go back this node
-        int ti = in->_idx;
-        PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
-        if (nt == PointsToNode::UnknownType) {
-          break;
-        } else if (nt == PointsToNode::JavaObject) {
-          add_pointsto_edge(n->_idx, ti);
-        } else {
-          add_deferred_edge(n->_idx, ti);
-        }
-      }
-      if (i >= n->req())
-        _processed.set(n->_idx);
-      else
-        _delayed_worklist.push(n);
-      break;
-    }
-    case Op_Proj:
-    {
-      // we are only interested in the oop result projection from a call
-      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) {
-        const TypeTuple *r = n->in(0)->as_Call()->tf()->range();
-        assert(r->cnt() > TypeFunc::Parms, "sanity");
-        if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) {
-          add_node(n, PointsToNode::LocalVar, PointsToNode::UnknownEscape, false);
-          int ti = n->in(0)->_idx;
-          // The call may not be registered yet (since not all its inputs are registered)
-          // if this is the projection from backbranch edge of Phi.
-          if (ptnode_adr(ti)->node_type() != PointsToNode::UnknownType) {
-            process_call_result(n->as_Proj(), phase);
-          }
-          if (!_processed.test(n->_idx)) {
-            // The call's result may need to be processed later if the call
-            // returns it's argument and the argument is not processed yet.
-            _delayed_worklist.push(n);
-          }
-          break;
-        }
-      }
-      _processed.set(n->_idx);
-      break;
-    }
-    case Op_Return:
-    {
-      if( n->req() > TypeFunc::Parms &&
-          phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) {
-        // Treat Return value as LocalVar with GlobalEscape escape state.
-        add_node(n, PointsToNode::LocalVar, PointsToNode::GlobalEscape, false);
-        int ti = n->in(TypeFunc::Parms)->_idx;
-        PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
-        if (nt == PointsToNode::UnknownType) {
-          _delayed_worklist.push(n); // Process it later.
-          break;
-        } else if (nt == PointsToNode::JavaObject) {
-          add_pointsto_edge(n->_idx, ti);
-        } else {
-          add_deferred_edge(n->_idx, ti);
-        }
-      }
-      _processed.set(n->_idx);
-      break;
-    }
-    case Op_StoreP:
-    case Op_StoreN:
-    {
-      const Type *adr_type = phase->type(n->in(MemNode::Address));
-      adr_type = adr_type->make_ptr();
-      if (adr_type->isa_oopptr()) {
-        add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
-      } else {
-        Node* adr = n->in(MemNode::Address);
-        if (adr->is_AddP() && phase->type(adr) == TypeRawPtr::NOTNULL &&
-            adr->in(AddPNode::Address)->is_Proj() &&
-            adr->in(AddPNode::Address)->in(0)->is_Allocate()) {
-          add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
-          // We are computing a raw address for a store captured
-          // by an Initialize compute an appropriate address type.
-          int offs = (int)phase->find_intptr_t_con(adr->in(AddPNode::Offset), Type::OffsetBot);
-          assert(offs != Type::OffsetBot, "offset must be a constant");
-        } else {
-          _processed.set(n->_idx);
-          return;
-        }
-      }
-      break;
-    }
-    case Op_StorePConditional:
-    case Op_CompareAndSwapP:
-    case Op_CompareAndSwapN:
-    {
-      const Type *adr_type = phase->type(n->in(MemNode::Address));
-      adr_type = adr_type->make_ptr();
-      if (adr_type->isa_oopptr()) {
-        add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
-      } else {
-        _processed.set(n->_idx);
-        return;
-      }
-      break;
-    }
-    case Op_AryEq:
-    case Op_StrComp:
-    case Op_StrEquals:
-    case Op_StrIndexOf:
-    {
-      // char[] arrays passed to string intrinsics are not scalar replaceable.
-      add_node(n, PointsToNode::UnknownType, PointsToNode::UnknownEscape, false);
-      break;
-    }
-    case Op_ThreadLocal:
-    {
-      add_node(n, PointsToNode::JavaObject, PointsToNode::ArgEscape, true);
-      break;
-    }
-    default:
-      ;
-      // nothing to do
-  }
-  return;
-}
-
-void ConnectionGraph::build_connection_graph(Node *n, PhaseTransform *phase) {
-  uint n_idx = n->_idx;
-  assert(ptnode_adr(n_idx)->_node != NULL, "node should be registered");
-
-  // Don't set processed bit for AddP, LoadP, StoreP since
-  // they may need more then one pass to process.
-  // Also don't mark as processed Call nodes since their
-  // arguments may need more then one pass to process.
-  if (_processed.test(n_idx))
-    return; // No need to redefine node's state.
-
-  if (n->is_Call()) {
-    CallNode *call = n->as_Call();
-    process_call_arguments(call, phase);
-    return;
-  }
-
-  switch (n->Opcode()) {
-    case Op_AddP:
-    {
-      Node *base = get_addp_base(n);
-      int offset = address_offset(n, phase);
-      // Create a field edge to this node from everything base could point to.
-      for( VectorSetI i(PointsTo(base)); i.test(); ++i ) {
-        uint pt = i.elem;
-        add_field_edge(pt, n_idx, offset);
-      }
-      break;
-    }
-    case Op_CastX2P:
-    {
-      assert(false, "Op_CastX2P");
-      break;
-    }
-    case Op_CastPP:
-    case Op_CheckCastPP:
-    case Op_EncodeP:
-    case Op_DecodeN:
-    {
-      int ti = n->in(1)->_idx;
-      assert(ptnode_adr(ti)->node_type() != PointsToNode::UnknownType, "all nodes should be registered");
-      if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
-        add_pointsto_edge(n_idx, ti);
-      } else {
-        add_deferred_edge(n_idx, ti);
-      }
-      _processed.set(n_idx);
-      break;
-    }
-    case Op_ConP:
-    {
-      assert(false, "Op_ConP");
-      break;
-    }
-    case Op_ConN:
-    {
-      assert(false, "Op_ConN");
-      break;
-    }
-    case Op_CreateEx:
-    {
-      assert(false, "Op_CreateEx");
-      break;
-    }
-    case Op_LoadKlass:
-    case Op_LoadNKlass:
-    {
-      assert(false, "Op_LoadKlass");
-      break;
-    }
-    case Op_LoadP:
-    case Op_LoadN:
-    {
-      const Type *t = phase->type(n);
-#ifdef ASSERT
-      if (t->make_ptr() == NULL)
-        assert(false, "Op_LoadP");
-#endif
-
-      Node* adr = n->in(MemNode::Address)->uncast();
-      Node* adr_base;
-      if (adr->is_AddP()) {
-        adr_base = get_addp_base(adr);
-      } else {
-        adr_base = adr;
-      }
-
-      // For everything "adr_base" could point to, create a deferred edge from
-      // this node to each field with the same offset.
-      int offset = address_offset(adr, phase);
-      for( VectorSetI i(PointsTo(adr_base)); i.test(); ++i ) {
-        uint pt = i.elem;
-        if (adr->is_AddP()) {
-          // Add field edge if it is missing.
-          add_field_edge(pt, adr->_idx, offset);
-        }
-        add_deferred_edge_to_fields(n_idx, pt, offset);
-      }
-      break;
-    }
-    case Op_Parm:
-    {
-      assert(false, "Op_Parm");
-      break;
-    }
-    case Op_PartialSubtypeCheck:
-    {
-      assert(false, "Op_PartialSubtypeCheck");
-      break;
-    }
-    case Op_Phi:
-    {
-#ifdef ASSERT
-      const Type *t = n->as_Phi()->type();
-      if (t->make_ptr() == NULL)
-        assert(false, "Op_Phi");
-#endif
-      for (uint i = 1; i < n->req() ; i++) {
-        Node* in = n->in(i);
-        if (in == NULL)
-          continue;  // ignore NULL
-        in = in->uncast();
-        if (in->is_top() || in == n)
-          continue;  // ignore top or inputs which go back this node
-        int ti = in->_idx;
-        PointsToNode::NodeType nt = ptnode_adr(ti)->node_type();
-        assert(nt != PointsToNode::UnknownType, "all nodes should be known");
-        if (nt == PointsToNode::JavaObject) {
-          add_pointsto_edge(n_idx, ti);
-        } else {
-          add_deferred_edge(n_idx, ti);
-        }
-      }
-      _processed.set(n_idx);
-      break;
-    }
-    case Op_Proj:
-    {
-      // we are only interested in the oop result projection from a call
-      if (n->as_Proj()->_con == TypeFunc::Parms && n->in(0)->is_Call() ) {
-        assert(ptnode_adr(n->in(0)->_idx)->node_type() != PointsToNode::UnknownType,
-               "all nodes should be registered");
-        const TypeTuple *r = n->in(0)->as_Call()->tf()->range();
-        assert(r->cnt() > TypeFunc::Parms, "sanity");
-        if (r->field_at(TypeFunc::Parms)->isa_ptr() != NULL) {
-          process_call_result(n->as_Proj(), phase);
-          assert(_processed.test(n_idx), "all call results should be processed");
-          break;
-        }
-      }
-      assert(false, "Op_Proj");
-      break;
-    }
-    case Op_Return:
-    {
-#ifdef ASSERT
-      if( n->req() <= TypeFunc::Parms ||
-          !phase->type(n->in(TypeFunc::Parms))->isa_oopptr() ) {
-        assert(false, "Op_Return");
-      }
-#endif
-      int ti = n->in(TypeFunc::Parms)->_idx;
-      assert(ptnode_adr(ti)->node_type() != PointsToNode::UnknownType, "node should be registered");
-      if (ptnode_adr(ti)->node_type() == PointsToNode::JavaObject) {
-        add_pointsto_edge(n_idx, ti);
-      } else {
-        add_deferred_edge(n_idx, ti);
-      }
-      _processed.set(n_idx);
-      break;
-    }
-    case Op_StoreP:
-    case Op_StoreN:
-    case Op_StorePConditional:
-    case Op_CompareAndSwapP:
-    case Op_CompareAndSwapN:
-    {
-      Node *adr = n->in(MemNode::Address);
-      const Type *adr_type = phase->type(adr)->make_ptr();
-#ifdef ASSERT
-      if (!adr_type->isa_oopptr())
-        assert(phase->type(adr) == TypeRawPtr::NOTNULL, "Op_StoreP");
-#endif
-
-      assert(adr->is_AddP(), "expecting an AddP");
-      Node *adr_base = get_addp_base(adr);
-      Node *val = n->in(MemNode::ValueIn)->uncast();
-      int offset = address_offset(adr, phase);
-      // For everything "adr_base" could point to, create a deferred edge
-      // to "val" from each field with the same offset.
-      for( VectorSetI i(PointsTo(adr_base)); i.test(); ++i ) {
-        uint pt = i.elem;
-        // Add field edge if it is missing.
-        add_field_edge(pt, adr->_idx, offset);
-        add_edge_from_fields(pt, val->_idx, offset);
-      }
-      break;
-    }
-    case Op_AryEq:
-    case Op_StrComp:
-    case Op_StrEquals:
-    case Op_StrIndexOf:
-    {
-      // char[] arrays passed to string intrinsic do not escape but
-      // they are not scalar replaceable. Adjust escape state for them.
-      // Start from in(2) edge since in(1) is memory edge.
-      for (uint i = 2; i < n->req(); i++) {
-        Node* adr = n->in(i)->uncast();
-        const Type *at = phase->type(adr);
-        if (!adr->is_top() && at->isa_ptr()) {
-          assert(at == Type::TOP || at == TypePtr::NULL_PTR ||
-                 at->isa_ptr() != NULL, "expecting an Ptr");
-          if (adr->is_AddP()) {
-            adr = get_addp_base(adr);
-          }
-          // Mark as ArgEscape everything "adr" could point to.
-          set_escape_state(adr->_idx, PointsToNode::ArgEscape);
-        }
-      }
-      _processed.set(n_idx);
-      break;
-    }
-    case Op_ThreadLocal:
-    {
-      assert(false, "Op_ThreadLocal");
-      break;
-    }
-    default:
-      // This method should be called only for EA specific nodes.
-      ShouldNotReachHere();
-  }
-}
-
-#ifndef PRODUCT
-void ConnectionGraph::dump() {
+void ConnectionGraph::dump(GrowableArray<PointsToNode*>& ptnodes_worklist) {
   bool first = true;
-
-  uint size = nodes_size();
-  for (uint ni = 0; ni < size; ni++) {
-    PointsToNode *ptn = ptnode_adr(ni);
-    PointsToNode::NodeType ptn_type = ptn->node_type();
-
-    if (ptn_type != PointsToNode::JavaObject || ptn->_node == NULL)
+  int ptnodes_length = ptnodes_worklist.length();
+  for (int i = 0; i < ptnodes_length; i++) {
+    PointsToNode *ptn = ptnodes_worklist.at(i);
+    if (ptn == NULL || !ptn->is_JavaObject())
       continue;
-    PointsToNode::EscapeState es = escape_state(ptn->_node);
-    if (ptn->_node->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) {
+    PointsToNode::EscapeState es = ptn->escape_state();
+    if (ptn->ideal_node()->is_Allocate() && (es == PointsToNode::NoEscape || Verbose)) {
       if (first) {
         tty->cr();
         tty->print("======== Connection graph for ");
@@ -3114,22 +3236,14 @@
         tty->cr();
         first = false;
       }
-      tty->print("%6d ", ni);
       ptn->dump();
-      // Print all locals which reference this allocation
-      for (uint li = ni; li < size; li++) {
-        PointsToNode *ptn_loc = ptnode_adr(li);
-        PointsToNode::NodeType ptn_loc_type = ptn_loc->node_type();
-        if ( ptn_loc_type == PointsToNode::LocalVar && ptn_loc->_node != NULL &&
-             ptn_loc->edge_count() == 1 && ptn_loc->edge_target(0) == ni ) {
-          ptnode_adr(li)->dump(false);
-        }
-      }
-      if (Verbose) {
-        // Print all fields which reference this allocation
-        for (uint i = 0; i < ptn->edge_count(); i++) {
-          uint ei = ptn->edge_target(i);
-          ptnode_adr(ei)->dump(false);
+      // Print all locals and fields which reference this allocation
+      for (UseIterator j(ptn); j.has_next(); j.next()) {
+        PointsToNode* use = j.get();
+        if (use->is_LocalVar()) {
+          use->dump(Verbose);
+        } else if (Verbose) {
+          use->dump();
         }
       }
       tty->cr();
diff --git a/hotspot/src/share/vm/opto/escape.hpp b/hotspot/src/share/vm/opto/escape.hpp
index 2d66529..78447f0 100644
--- a/hotspot/src/share/vm/opto/escape.hpp
+++ b/hotspot/src/share/vm/opto/escape.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -115,18 +115,36 @@
 class  CallNode;
 class  PhiNode;
 class  PhaseTransform;
+class  PointsToNode;
 class  Type;
 class  TypePtr;
 class  VectorSet;
 
-class PointsToNode {
-friend class ConnectionGraph;
+class JavaObjectNode;
+class LocalVarNode;
+class FieldNode;
+class ArraycopyNode;
+
+// ConnectionGraph nodes
+class PointsToNode : public ResourceObj {
+  GrowableArray<PointsToNode*> _edges; // List of nodes this node points to
+  GrowableArray<PointsToNode*> _uses;  // List of nodes which point to this node
+
+  const u1           _type;  // NodeType
+  u1                _flags;  // NodeFlags
+  u1               _escape;  // EscapeState of object
+  u1        _fields_escape;  // EscapeState of object's fields
+
+  Node* const        _node;  // Ideal node corresponding to this PointsTo node.
+  const int           _idx;  // Cached ideal node's _idx
+
 public:
   typedef enum {
     UnknownType = 0,
     JavaObject  = 1,
     LocalVar    = 2,
-    Field       = 3
+    Field       = 3,
+    Arraycopy   = 4
   } NodeType;
 
   typedef enum {
@@ -140,178 +158,387 @@
   } EscapeState;
 
   typedef enum {
-    UnknownEdge   = 0,
-    PointsToEdge  = 1,
-    DeferredEdge  = 2,
-    FieldEdge     = 3
-  } EdgeType;
-
-private:
-  enum {
-    EdgeMask = 3,
-    EdgeShift = 2,
-
-    INITIAL_EDGE_COUNT = 4
-  };
-
-  NodeType             _type;
-  EscapeState          _escape;
-  GrowableArray<uint>* _edges; // outgoing edges
-  Node* _node;                 // Ideal node corresponding to this PointsTo node.
-  int   _offset;               // Object fields offsets.
-  bool  _scalar_replaceable;   // Not escaped object could be replaced with scalar
-  bool  _has_unknown_ptr;      // Has edge to phantom_object
-
-public:
-  PointsToNode():
-    _type(UnknownType),
-    _escape(UnknownEscape),
-    _edges(NULL),
-    _node(NULL),
-    _offset(-1),
-    _has_unknown_ptr(false),
-    _scalar_replaceable(true) {}
+    ScalarReplaceable = 1,  // Not escaped object could be replaced with scalar
+    PointsToUnknown   = 2,  // Has edge to phantom_object
+    ArraycopySrc      = 4,  // Has edge from Arraycopy node
+    ArraycopyDst      = 8   // Has edge to Arraycopy node
+  } NodeFlags;
 
 
-  EscapeState escape_state() const { return _escape; }
-  NodeType node_type() const { return _type;}
-  int offset() { return _offset;}
-  bool scalar_replaceable() { return _scalar_replaceable;}
-  bool has_unknown_ptr()    { return _has_unknown_ptr;}
-
-  void set_offset(int offs) { _offset = offs;}
-  void set_escape_state(EscapeState state) { _escape = state; }
-  void set_node_type(NodeType ntype) {
-    assert(_type == UnknownType || _type == ntype, "Can't change node type");
-    _type = ntype;
-  }
-  void set_scalar_replaceable(bool v) { _scalar_replaceable = v; }
-  void set_has_unknown_ptr()          { _has_unknown_ptr = true; }
-
-  // count of outgoing edges
-  uint edge_count() const { return (_edges == NULL) ? 0 : _edges->length(); }
-
-  // node index of target of outgoing edge "e"
-  uint edge_target(uint e) const {
-    assert(_edges != NULL, "valid edge index");
-    return (_edges->at(e) >> EdgeShift);
-  }
-  // type of outgoing edge "e"
-  EdgeType edge_type(uint e) const {
-    assert(_edges != NULL, "valid edge index");
-    return (EdgeType) (_edges->at(e) & EdgeMask);
+  PointsToNode(Compile *C, Node* n, EscapeState es, NodeType type):
+    _edges(C->comp_arena(), 2, 0, NULL),
+    _uses (C->comp_arena(), 2, 0, NULL),
+    _node(n),
+    _idx(n->_idx),
+    _type((u1)type),
+    _escape((u1)es),
+    _fields_escape((u1)es),
+    _flags(ScalarReplaceable) {
+    assert(n != NULL && es != UnknownEscape, "sanity");
   }
 
-  // add a edge of the specified type pointing to the specified target
-  void add_edge(uint targIdx, EdgeType et);
+  Node* ideal_node()   const { return _node; }
+  int          idx()   const { return _idx; }
 
-  // remove an edge of the specified type pointing to the specified target
-  void remove_edge(uint targIdx, EdgeType et);
+  bool is_JavaObject() const { return _type == (u1)JavaObject; }
+  bool is_LocalVar()   const { return _type == (u1)LocalVar; }
+  bool is_Field()      const { return _type == (u1)Field; }
+  bool is_Arraycopy()  const { return _type == (u1)Arraycopy; }
+
+  JavaObjectNode* as_JavaObject() { assert(is_JavaObject(),""); return (JavaObjectNode*)this; }
+  LocalVarNode*   as_LocalVar()   { assert(is_LocalVar(),"");   return (LocalVarNode*)this; }
+  FieldNode*      as_Field()      { assert(is_Field(),"");      return (FieldNode*)this; }
+  ArraycopyNode*  as_Arraycopy()  { assert(is_Arraycopy(),"");  return (ArraycopyNode*)this; }
+
+  EscapeState escape_state() const { return (EscapeState)_escape; }
+  void    set_escape_state(EscapeState state) { _escape = (u1)state; }
+
+  EscapeState fields_escape_state() const { return (EscapeState)_fields_escape; }
+  void    set_fields_escape_state(EscapeState state) { _fields_escape = (u1)state; }
+
+  bool     has_unknown_ptr() const { return (_flags & PointsToUnknown) != 0; }
+  void set_has_unknown_ptr()       { _flags |= PointsToUnknown; }
+
+  bool     arraycopy_src() const { return (_flags & ArraycopySrc) != 0; }
+  void set_arraycopy_src()       { _flags |= ArraycopySrc; }
+  bool     arraycopy_dst() const { return (_flags & ArraycopyDst) != 0; }
+  void set_arraycopy_dst()       { _flags |= ArraycopyDst; }
+
+  bool     scalar_replaceable() const { return (_flags & ScalarReplaceable) != 0;}
+  void set_scalar_replaceable(bool v) {
+    if (v)
+      _flags |= ScalarReplaceable;
+    else
+      _flags &= ~ScalarReplaceable;
+  }
+
+  int edge_count()              const { return _edges.length(); }
+  PointsToNode* edge(int e)     const { return _edges.at(e); }
+  bool add_edge(PointsToNode* edge)    { return _edges.append_if_missing(edge); }
+
+  int use_count()             const { return _uses.length(); }
+  PointsToNode* use(int e)    const { return _uses.at(e); }
+  bool add_use(PointsToNode* use)    { return _uses.append_if_missing(use); }
+
+  // Mark base edge use to distinguish from stored value edge.
+  bool add_base_use(FieldNode* use) { return _uses.append_if_missing((PointsToNode*)((intptr_t)use + 1)); }
+  static bool is_base_use(PointsToNode* use) { return (((intptr_t)use) & 1); }
+  static PointsToNode* get_use_node(PointsToNode* use) { return (PointsToNode*)(((intptr_t)use) & ~1); }
+
+  // Return true if this node points to specified node or nodes it points to.
+  bool points_to(JavaObjectNode* ptn) const;
+
+  // Return true if this node points only to non-escaping allocations.
+  bool non_escaping_allocation();
+
+  // Return true if one node points to an other.
+  bool meet(PointsToNode* ptn);
 
 #ifndef PRODUCT
+  NodeType node_type() const { return (NodeType)_type;}
   void dump(bool print_state=true) const;
 #endif
 
 };
 
+class LocalVarNode: public PointsToNode {
+public:
+  LocalVarNode(Compile *C, Node* n, EscapeState es):
+    PointsToNode(C, n, es, LocalVar) {}
+};
+
+class JavaObjectNode: public PointsToNode {
+public:
+  JavaObjectNode(Compile *C, Node* n, EscapeState es):
+    PointsToNode(C, n, es, JavaObject) {
+      if (es > NoEscape)
+        set_scalar_replaceable(false);
+    }
+};
+
+class FieldNode: public PointsToNode {
+  GrowableArray<PointsToNode*> _bases; // List of JavaObject nodes which point to this node
+  const int   _offset; // Field's offset.
+  const bool  _is_oop; // Field points to object
+        bool  _has_unknown_base; // Has phantom_object base
+public:
+  FieldNode(Compile *C, Node* n, EscapeState es, int offs, bool is_oop):
+    PointsToNode(C, n, es, Field),
+    _offset(offs), _is_oop(is_oop),
+    _has_unknown_base(false) {}
+
+  int      offset()              const { return _offset;}
+  bool     is_oop()              const { return _is_oop;}
+  bool     has_unknown_base()    const { return _has_unknown_base; }
+  void set_has_unknown_base()          { _has_unknown_base = true; }
+
+  int base_count()              const { return _bases.length(); }
+  PointsToNode* base(int e)     const { return _bases.at(e); }
+  bool add_base(PointsToNode* base)    { return _bases.append_if_missing(base); }
+#ifdef ASSERT
+  // Return true if bases points to this java object.
+  bool has_base(JavaObjectNode* ptn) const;
+#endif
+
+};
+
+class ArraycopyNode: public PointsToNode {
+public:
+  ArraycopyNode(Compile *C, Node* n, EscapeState es):
+    PointsToNode(C, n, es, Arraycopy) {}
+};
+
+// Iterators for PointsTo node's edges:
+//   for (EdgeIterator i(n); i.has_next(); i.next()) {
+//     PointsToNode* u = i.get();
+class PointsToIterator: public StackObj {
+protected:
+  const PointsToNode* node;
+  const int cnt;
+  int i;
+public:
+  inline PointsToIterator(const PointsToNode* n, int cnt) : node(n), cnt(cnt), i(0) { }
+  inline bool has_next() const { return i < cnt; }
+  inline void next() { i++; }
+  PointsToNode* get() const { ShouldNotCallThis(); return NULL; }
+};
+
+class EdgeIterator: public PointsToIterator {
+public:
+  inline EdgeIterator(const PointsToNode* n) : PointsToIterator(n, n->edge_count()) { }
+  inline PointsToNode* get() const { return node->edge(i); }
+};
+
+class UseIterator: public PointsToIterator {
+public:
+  inline UseIterator(const PointsToNode* n) : PointsToIterator(n, n->use_count()) { }
+  inline PointsToNode* get() const { return node->use(i); }
+};
+
+class BaseIterator: public PointsToIterator {
+public:
+  inline BaseIterator(const FieldNode* n) : PointsToIterator(n, n->base_count()) { }
+  inline PointsToNode* get() const { return ((PointsToNode*)node)->as_Field()->base(i); }
+};
+
+
 class ConnectionGraph: public ResourceObj {
 private:
-  GrowableArray<PointsToNode>  _nodes; // Connection graph nodes indexed
-                                       // by ideal node index.
+  GrowableArray<PointsToNode*>  _nodes; // Map from ideal nodes to
+                                        // ConnectionGraph nodes.
 
-  Unique_Node_List  _delayed_worklist; // Nodes to be processed before
-                                       // the call build_connection_graph().
+  GrowableArray<PointsToNode*>  _worklist; // Nodes to be processed
 
-  GrowableArray<MergeMemNode *>  _mergemem_worklist; // List of all MergeMem nodes
+  bool            _collecting; // Indicates whether escape information
+                               // is still being collected. If false,
+                               // no new nodes will be processed.
 
-  VectorSet                _processed; // Records which nodes have been
-                                       // processed.
+  bool               _verify;  // verify graph
 
-  bool                    _collecting; // Indicates whether escape information
-                                       // is still being collected. If false,
-                                       // no new nodes will be processed.
+  JavaObjectNode* phantom_obj; // Unknown object
+  JavaObjectNode*    null_obj;
+  Node*             _pcmp_neq; // ConI(#CC_GT)
+  Node*              _pcmp_eq; // ConI(#CC_EQ)
 
-  bool                    _progress;   // Indicates whether new Graph's edges
-                                       // were created.
+  Compile*           _compile; // Compile object for current compilation
+  PhaseIterGVN*         _igvn; // Value numbering
 
-  uint                _phantom_object; // Index of globally escaping object
-                                       // that pointer values loaded from
-                                       // a field which has not been set
-                                       // are assumed to point to.
-  uint                      _oop_null; // ConP(#NULL)->_idx
-  uint                     _noop_null; // ConN(#NULL)->_idx
-  Node*                     _pcmp_neq; // ConI(#CC_GT)
-  Node*                      _pcmp_eq; // ConI(#CC_EQ)
-
-  Compile *                  _compile; // Compile object for current compilation
-  PhaseIterGVN *                _igvn; // Value numbering
+  Unique_Node_List ideal_nodes; // Used by CG construction and types splitting.
 
   // Address of an element in _nodes.  Used when the element is to be modified
-  PointsToNode *ptnode_adr(uint idx) const {
+  PointsToNode* ptnode_adr(int idx) const {
     // There should be no new ideal nodes during ConnectionGraph build,
-    // growableArray::adr_at() will throw assert otherwise.
-    return _nodes.adr_at(idx);
+    // growableArray::at() will throw assert otherwise.
+    return _nodes.at(idx);
   }
   uint nodes_size() const { return _nodes.length(); }
 
-  bool is_null_ptr(uint idx) const { return (idx == _noop_null || idx == _oop_null); }
+  // Add nodes to ConnectionGraph.
+  void add_local_var(Node* n, PointsToNode::EscapeState es);
+  void add_java_object(Node* n, PointsToNode::EscapeState es);
+  void add_field(Node* n, PointsToNode::EscapeState es, int offset);
+  void add_arraycopy(Node* n, PointsToNode::EscapeState es, PointsToNode* src, PointsToNode* dst);
 
-  // Add node to ConnectionGraph.
-  void add_node(Node *n, PointsToNode::NodeType nt, PointsToNode::EscapeState es, bool done);
+  // Compute the escape state for arguments to a call.
+  void process_call_arguments(CallNode *call);
 
+  // Add PointsToNode node corresponding to a call
+  void add_call_node(CallNode* call);
+
+  // Map ideal node to existing PointsTo node (usually phantom_object).
+  void map_ideal_node(Node *n, PointsToNode* ptn) {
+    assert(ptn != NULL, "only existing PointsTo node");
+    _nodes.at_put(n->_idx, ptn);
+  }
+
+  // Utility function for nodes that load an object
+  void add_objload_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist);
+  // Create PointsToNode node and add it to Connection Graph.
+  void add_node_to_connection_graph(Node *n, Unique_Node_List *delayed_worklist);
+
+  // Add final simple edges to graph.
+  void add_final_edges(Node *n);
+
+  // Finish Graph construction.
+  bool complete_connection_graph(GrowableArray<PointsToNode*>&   ptnodes_worklist,
+                                 GrowableArray<JavaObjectNode*>& non_escaped_worklist,
+                                 GrowableArray<JavaObjectNode*>& java_objects_worklist,
+                                 GrowableArray<FieldNode*>&      oop_fields_worklist);
+
+#ifdef ASSERT
+  void verify_connection_graph(GrowableArray<PointsToNode*>&   ptnodes_worklist,
+                               GrowableArray<JavaObjectNode*>& non_escaped_worklist,
+                               GrowableArray<JavaObjectNode*>& java_objects_worklist,
+                               GrowableArray<Node*>& addp_worklist);
+#endif
+
+  // Add all references to this JavaObject node.
+  int add_java_object_edges(JavaObjectNode* jobj, bool populate_worklist);
+
+  // Put node on worklist if it is (or was) not there.
+  void add_to_worklist(PointsToNode* pt) {
+    _worklist.push(pt);
+    return;
+  }
+
+  // Put on worklist all uses of this node.
+  void add_uses_to_worklist(PointsToNode* pt) {
+    for (UseIterator i(pt); i.has_next(); i.next())
+      _worklist.push(i.get());
+  }
+
+  // Put on worklist all field's uses and related field nodes.
+  void add_field_uses_to_worklist(FieldNode* field);
+
+  // Put on worklist all related field nodes.
+  void add_fields_to_worklist(FieldNode* field, PointsToNode* base);
+
+  // Find fields which have unknown value.
+  int find_field_value(FieldNode* field);
+
+  // Find fields initializing values for allocations.
+  int find_init_values(JavaObjectNode* ptn, PointsToNode* init_val, PhaseTransform* phase);
+
+  // Set the escape state of an object and its fields.
+  void set_escape_state(PointsToNode* ptn, PointsToNode::EscapeState esc) {
+    // Don't change non-escaping state of NULL pointer.
+    if (ptn != null_obj) {
+      if (ptn->escape_state() < esc)
+        ptn->set_escape_state(esc);
+      if (ptn->fields_escape_state() < esc)
+        ptn->set_fields_escape_state(esc);
+    }
+  }
+  void set_fields_escape_state(PointsToNode* ptn, PointsToNode::EscapeState esc) {
+    // Don't change non-escaping state of NULL pointer.
+    if (ptn != null_obj) {
+      if (ptn->fields_escape_state() < esc)
+        ptn->set_fields_escape_state(esc);
+    }
+  }
+
+  // Propagate GlobalEscape and ArgEscape escape states to all nodes
+  // and check that we still have non-escaping java objects.
+  bool find_non_escaped_objects(GrowableArray<PointsToNode*>& ptnodes_worklist,
+                                GrowableArray<JavaObjectNode*>& non_escaped_worklist);
+
+  // Adjust scalar_replaceable state after Connection Graph is built.
+  void adjust_scalar_replaceable_state(JavaObjectNode* jobj);
+
+  // Optimize ideal graph.
+  void optimize_ideal_graph(GrowableArray<Node*>& ptr_cmp_worklist,
+                            GrowableArray<Node*>& storestore_worklist);
+  // Optimize objects compare.
+  Node* optimize_ptr_compare(Node* n);
+
+  // Returns unique corresponding java object or NULL.
+  JavaObjectNode* unique_java_object(Node *n);
+
+  // Add an edge of the specified type pointing to the specified target.
+  bool add_edge(PointsToNode* from, PointsToNode* to) {
+    assert(!from->is_Field() || from->as_Field()->is_oop(), "sanity");
+
+    if (to == phantom_obj) {
+      if (from->has_unknown_ptr()) {
+        return false; // already points to phantom_obj
+      }
+      from->set_has_unknown_ptr();
+    }
+
+    bool is_new = from->add_edge(to);
+    assert(to != phantom_obj || is_new, "sanity");
+    if (is_new) { // New edge?
+      assert(!_verify, "graph is incomplete");
+      is_new = to->add_use(from);
+      assert(is_new, "use should be also new");
+    }
+    return is_new;
+  }
+
+  // Add an edge from Field node to its base and back.
+  bool add_base(FieldNode* from, PointsToNode* to) {
+    assert(!to->is_Arraycopy(), "sanity");
+    if (to == phantom_obj) {
+      if (from->has_unknown_base()) {
+        return false; // already has phantom_obj base
+      }
+      from->set_has_unknown_base();
+    }
+    bool is_new = from->add_base(to);
+    assert(to != phantom_obj || is_new, "sanity");
+    if (is_new) {      // New edge?
+      assert(!_verify, "graph is incomplete");
+      if (to == null_obj)
+        return is_new; // Don't add fields to NULL pointer.
+      if (to->is_JavaObject()) {
+        is_new = to->add_edge(from);
+      } else {
+        is_new = to->add_base_use(from);
+      }
+      assert(is_new, "use should be also new");
+    }
+    return is_new;
+  }
+
+  // Add LocalVar node and edge if possible
+  void add_local_var_and_edge(Node* n, PointsToNode::EscapeState es, Node* to,
+                              Unique_Node_List *delayed_worklist) {
+    PointsToNode* ptn = ptnode_adr(to->_idx);
+    if (delayed_worklist != NULL) { // First iteration of CG construction
+      add_local_var(n, es);
+      if (ptn == NULL) {
+        delayed_worklist->push(n);
+        return; // Process it later.
+      }
+    } else {
+      assert(ptn != NULL, "node should be registered");
+    }
+    add_edge(ptnode_adr(n->_idx), ptn);
+ }
+  // Helper functions
+  bool   is_oop_field(Node* n, int offset, bool* unsafe);
+ static Node* get_addp_base(Node *addp);
+ static Node* find_second_addp(Node* addp, Node* n);
   // offset of a field reference
   int address_offset(Node* adr, PhaseTransform *phase);
 
-  // compute the escape state for arguments to a call
-  void process_call_arguments(CallNode *call, PhaseTransform *phase);
 
-  // compute the escape state for the return value of a call
-  void process_call_result(ProjNode *resproj, PhaseTransform *phase);
+  // Propagate unique types created for unescaped allocated objects
+  // through the graph
+  void split_unique_types(GrowableArray<Node *>  &alloc_worklist);
 
-  // Populate Connection Graph with Ideal nodes.
-  void record_for_escape_analysis(Node *n, PhaseTransform *phase);
+  // Helper methods for unique types split.
+  bool split_AddP(Node *addp, Node *base);
 
-  // Build Connection Graph and set nodes escape state.
-  void build_connection_graph(Node *n, PhaseTransform *phase);
+  PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, bool &new_created);
+  PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist);
 
-  // walk the connection graph starting at the node corresponding to "n" and
-  // add the index of everything it could point to, to "ptset".  This may cause
-  // Phi's encountered to get (re)processed  (which requires "phase".)
-  VectorSet* PointsTo(Node * n);
-
-  // Reused structures for PointsTo().
-  VectorSet            pt_ptset;
-  VectorSet            pt_visited;
-  GrowableArray<uint>  pt_worklist;
-
-  //  Edge manipulation.  The "from_i" and "to_i" arguments are the
-  //  node indices of the source and destination of the edge
-  void add_pointsto_edge(uint from_i, uint to_i);
-  void add_deferred_edge(uint from_i, uint to_i);
-  void add_field_edge(uint from_i, uint to_i, int offs);
-
-  // Add an edge of the specified type pointing to the specified target.
-  // Set _progress if new edge is added.
-  void add_edge(PointsToNode *f, uint to_i, PointsToNode::EdgeType et) {
-    uint e_cnt = f->edge_count();
-    f->add_edge(to_i, et);
-    _progress |= (f->edge_count() != e_cnt);
-  }
-
-  // Add an edge to node given by "to_i" from any field of adr_i whose offset
-  // matches "offset"  A deferred edge is added if to_i is a LocalVar, and
-  // a pointsto edge is added if it is a JavaObject
-  void add_edge_from_fields(uint adr, uint to_i, int offs);
-
-  // Add a deferred  edge from node given by "from_i" to any field
-  // of adr_i whose offset matches "offset"
-  void add_deferred_edge_to_fields(uint from_i, uint adr, int offs);
+  void  move_inst_mem(Node* n, GrowableArray<PhiNode *>  &orig_phis);
+  Node* find_inst_mem(Node* mem, int alias_idx,GrowableArray<PhiNode *>  &orig_phi_worklist);
+  Node* step_through_mergemem(MergeMemNode *mmem, int alias_idx, const TypeOopPtr *toop);
 
 
-  // Remove outgoing deferred edges from the node referenced by "ni".
-  // Any outgoing edges from the target of the deferred edge are copied
-  // to "ni".
-  void remove_deferred(uint ni, GrowableArray<uint>* deferred_edges, VectorSet* visited);
+  GrowableArray<MergeMemNode*>  _mergemem_worklist; // List of all MergeMem nodes
 
   Node_Array _node_map; // used for bookeeping during type splitting
                         // Used for the following purposes:
@@ -320,21 +547,18 @@
                         // MemNode       - new memory input for this node
                         // ChecCastPP    - allocation that this is a cast of
                         // allocation    - CheckCastPP of the allocation
-  bool split_AddP(Node *addp, Node *base,  PhaseGVN  *igvn);
-  PhiNode *create_split_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn, bool &new_created);
-  PhiNode *split_memory_phi(PhiNode *orig_phi, int alias_idx, GrowableArray<PhiNode *>  &orig_phi_worklist, PhaseGVN  *igvn);
-  void  move_inst_mem(Node* n, GrowableArray<PhiNode *>  &orig_phis, PhaseGVN *igvn);
-  Node *find_inst_mem(Node *mem, int alias_idx,GrowableArray<PhiNode *>  &orig_phi_worklist,  PhaseGVN  *igvn);
-
-  // Propagate unique types created for unescaped allocated objects
-  // through the graph
-  void split_unique_types(GrowableArray<Node *>  &alloc_worklist);
 
   // manage entries in _node_map
-  void  set_map(int idx, Node *n)        { _node_map.map(idx, n); }
-  Node *get_map(int idx)                 { return _node_map[idx]; }
-  PhiNode *get_map_phi(int idx) {
-    Node *phi = _node_map[idx];
+
+  void  set_map(Node* from, Node* to)  {
+    ideal_nodes.push(from);
+    _node_map.map(from->_idx, to);
+  }
+
+  Node* get_map(int idx) { return _node_map[idx]; }
+
+  PhiNode* get_map_phi(int idx) {
+    Node* phi = _node_map[idx];
     return (phi == NULL) ? NULL : phi->as_Phi();
   }
 
@@ -344,23 +568,6 @@
     _igvn->add_users_to_worklist(n);
   }
 
-  // Set the escape state of a node
-  void set_escape_state(uint ni, PointsToNode::EscapeState es);
-
-  // Find fields initializing values for allocations.
-  void find_init_values(Node* n, VectorSet* visited, PhaseTransform* phase);
-
-  // Adjust escape state after Connection Graph is built.
-  void adjust_escape_state(Node* n);
-
-  // Propagate escape states to referenced nodes.
-  bool propagate_escape_state(GrowableArray<int>* cg_worklist,
-                              GrowableArray<uint>* worklist,
-                              PointsToNode::EscapeState esc_state);
-
-  // Optimize objects compare.
-  Node* optimize_ptr_compare(Node* n);
-
   // Compute the escape information
   bool compute_escape();
 
@@ -373,11 +580,10 @@
   // Perform escape analysis
   static void do_analysis(Compile *C, PhaseIterGVN *igvn);
 
-  // escape state of a node
-  PointsToNode::EscapeState escape_state(Node *n);
+  bool not_global_escape(Node *n);
 
 #ifndef PRODUCT
-  void dump();
+  void dump(GrowableArray<PointsToNode*>& ptnodes_worklist);
 #endif
 };
 
diff --git a/hotspot/src/share/vm/opto/generateOptoStub.cpp b/hotspot/src/share/vm/opto/generateOptoStub.cpp
index 31600a7..032f008 100644
--- a/hotspot/src/share/vm/opto/generateOptoStub.cpp
+++ b/hotspot/src/share/vm/opto/generateOptoStub.cpp
@@ -50,7 +50,7 @@
   const TypeTuple *jrange  = C->tf()->range();
 
   // The procedure start
-  StartNode* start = new (C, 2) StartNode(root(), jdomain);
+  StartNode* start = new (C) StartNode(root(), jdomain);
   _gvn.set_type_bottom(start);
 
   // Make a map, with JVM state
@@ -63,7 +63,7 @@
   jvms->set_monoff(max_map);
   jvms->set_endoff(max_map);
   {
-    SafePointNode *map = new (C, max_map) SafePointNode( max_map, jvms );
+    SafePointNode *map = new (C) SafePointNode( max_map, jvms );
     jvms->set_map(map);
     set_jvms(jvms);
     assert(map == this->map(), "kit.map is set");
@@ -72,7 +72,7 @@
   // Make up the parameters
   uint i;
   for( i = 0; i < parm_cnt; i++ )
-    map()->init_req(i, _gvn.transform(new (C, 1) ParmNode(start, i)));
+    map()->init_req(i, _gvn.transform(new (C) ParmNode(start, i)));
   for( ; i<map()->req(); i++ )
     map()->init_req(i, top());      // For nicer debugging
 
@@ -80,7 +80,7 @@
   set_all_memory(map()->memory());
 
   // Get base of thread-local storage area
-  Node* thread = _gvn.transform( new (C, 1) ThreadLocalNode() );
+  Node* thread = _gvn.transform( new (C) ThreadLocalNode() );
 
   const int NoAlias = Compile::AliasIdxBot;
 
@@ -160,7 +160,7 @@
 
   //-----------------------------
   // Make the call node
-  CallRuntimeNode *call = new (C, c_sig->domain()->cnt())
+  CallRuntimeNode *call = new (C)
     CallRuntimeNode(c_sig, C_function, name, TypePtr::BOTTOM);
   //-----------------------------
 
@@ -186,23 +186,23 @@
 
   //-----------------------------
   // Now set up the return results
-  set_control( _gvn.transform( new (C, 1) ProjNode(call,TypeFunc::Control)) );
-  set_i_o(     _gvn.transform( new (C, 1) ProjNode(call,TypeFunc::I_O    )) );
+  set_control( _gvn.transform( new (C) ProjNode(call,TypeFunc::Control)) );
+  set_i_o(     _gvn.transform( new (C) ProjNode(call,TypeFunc::I_O    )) );
   set_all_memory_call(call);
   if (range->cnt() > TypeFunc::Parms) {
-    Node* retnode = _gvn.transform( new (C, 1) ProjNode(call,TypeFunc::Parms) );
+    Node* retnode = _gvn.transform( new (C) ProjNode(call,TypeFunc::Parms) );
     // C-land is allowed to return sub-word values.  Convert to integer type.
     assert( retval != Type::TOP, "" );
     if (retval == TypeInt::BOOL) {
-      retnode = _gvn.transform( new (C, 3) AndINode(retnode, intcon(0xFF)) );
+      retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFF)) );
     } else if (retval == TypeInt::CHAR) {
-      retnode = _gvn.transform( new (C, 3) AndINode(retnode, intcon(0xFFFF)) );
+      retnode = _gvn.transform( new (C) AndINode(retnode, intcon(0xFFFF)) );
     } else if (retval == TypeInt::BYTE) {
-      retnode = _gvn.transform( new (C, 3) LShiftINode(retnode, intcon(24)) );
-      retnode = _gvn.transform( new (C, 3) RShiftINode(retnode, intcon(24)) );
+      retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(24)) );
+      retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(24)) );
     } else if (retval == TypeInt::SHORT) {
-      retnode = _gvn.transform( new (C, 3) LShiftINode(retnode, intcon(16)) );
-      retnode = _gvn.transform( new (C, 3) RShiftINode(retnode, intcon(16)) );
+      retnode = _gvn.transform( new (C) LShiftINode(retnode, intcon(16)) );
+      retnode = _gvn.transform( new (C) RShiftINode(retnode, intcon(16)) );
     }
     map()->set_req( TypeFunc::Parms, retnode );
   }
@@ -247,21 +247,21 @@
 
   Node* exit_memory = reset_memory();
 
-  Node* cmp = _gvn.transform( new (C, 3) CmpPNode(pending, null()) );
-  Node* bo  = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) );
+  Node* cmp = _gvn.transform( new (C) CmpPNode(pending, null()) );
+  Node* bo  = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) );
   IfNode   *iff = create_and_map_if(control(), bo, PROB_MIN, COUNT_UNKNOWN);
 
-  Node* if_null     = _gvn.transform( new (C, 1) IfFalseNode(iff) );
-  Node* if_not_null = _gvn.transform( new (C, 1) IfTrueNode(iff)  );
+  Node* if_null     = _gvn.transform( new (C) IfFalseNode(iff) );
+  Node* if_not_null = _gvn.transform( new (C) IfTrueNode(iff)  );
 
   assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
   Node *exc_target = makecon(TypeRawPtr::make( StubRoutines::forward_exception_entry() ));
-  Node *to_exc = new (C, TypeFunc::Parms+2) TailCallNode(if_not_null,
-                                  i_o(),
-                                  exit_memory,
-                                  frameptr(),
-                                  returnadr(),
-                                  exc_target, null());
+  Node *to_exc = new (C) TailCallNode(if_not_null,
+                                      i_o(),
+                                      exit_memory,
+                                      frameptr(),
+                                      returnadr(),
+                                      exc_target, null());
   root()->add_req(_gvn.transform(to_exc));  // bind to root to keep live
   C->init_start(start);
 
@@ -271,31 +271,31 @@
   switch( is_fancy_jump ) {
   case 0:                       // Make a return instruction
     // Return to caller, free any space for return address
-    ret = new (C, TypeFunc::Parms) ReturnNode(TypeFunc::Parms, if_null,
-                         i_o(),
-                         exit_memory,
-                         frameptr(),
-                         returnadr());
+    ret = new (C) ReturnNode(TypeFunc::Parms, if_null,
+                             i_o(),
+                             exit_memory,
+                             frameptr(),
+                             returnadr());
     if (C->tf()->range()->cnt() > TypeFunc::Parms)
       ret->add_req( map()->in(TypeFunc::Parms) );
     break;
   case 1:    // This is a fancy tail-call jump.  Jump to computed address.
     // Jump to new callee; leave old return address alone.
-    ret = new (C, TypeFunc::Parms+2) TailCallNode(if_null,
-                           i_o(),
-                           exit_memory,
-                           frameptr(),
-                           returnadr(),
-                           target, map()->in(TypeFunc::Parms));
+    ret = new (C) TailCallNode(if_null,
+                               i_o(),
+                               exit_memory,
+                               frameptr(),
+                               returnadr(),
+                               target, map()->in(TypeFunc::Parms));
     break;
   case 2:                       // Pop return address & jump
     // Throw away old return address; jump to new computed address
     //assert(C_function == CAST_FROM_FN_PTR(address, OptoRuntime::rethrow_C), "fancy_jump==2 only for rethrow");
-    ret = new (C, TypeFunc::Parms+2) TailJumpNode(if_null,
-                           i_o(),
-                           exit_memory,
-                           frameptr(),
-                           target, map()->in(TypeFunc::Parms));
+    ret = new (C) TailJumpNode(if_null,
+                               i_o(),
+                               exit_memory,
+                               frameptr(),
+                               target, map()->in(TypeFunc::Parms));
     break;
   default:
     ShouldNotReachHere();
diff --git a/hotspot/src/share/vm/opto/graphKit.cpp b/hotspot/src/share/vm/opto/graphKit.cpp
index b3dca95..3cceb51 100644
--- a/hotspot/src/share/vm/opto/graphKit.cpp
+++ b/hotspot/src/share/vm/opto/graphKit.cpp
@@ -280,7 +280,7 @@
       JVMState* jvms = new (C) JVMState(_method, NULL);
       jvms->set_bci(_bci);
       jvms->set_sp(_sp);
-      jvms->set_map(new (C, TypeFunc::Parms) SafePointNode(TypeFunc::Parms, jvms));
+      jvms->set_map(new (C) SafePointNode(TypeFunc::Parms, jvms));
       set_jvms(jvms);
       for (uint i = 0; i < map()->req(); i++)  map()->init_req(i, top());
       set_all_memory(top());
@@ -332,7 +332,7 @@
   if (region->in(0) != hidden_merge_mark) {
     // The control input is not (yet) a specially-marked region in phi_map.
     // Make it so, and build some phis.
-    region = new (C, 2) RegionNode(2);
+    region = new (C) RegionNode(2);
     _gvn.set_type(region, Type::CONTROL);
     region->set_req(0, hidden_merge_mark);  // marks an internal ex-state
     region->init_req(1, phi_map->control());
@@ -481,13 +481,13 @@
     // take the uncommon_trap in the BuildCutout below.
 
     // first must access the should_post_on_exceptions_flag in this thread's JavaThread
-    Node* jthread = _gvn.transform(new (C, 1) ThreadLocalNode());
+    Node* jthread = _gvn.transform(new (C) ThreadLocalNode());
     Node* adr = basic_plus_adr(top(), jthread, in_bytes(JavaThread::should_post_on_exceptions_flag_offset()));
     Node* should_post_flag = make_load(control(), adr, TypeInt::INT, T_INT, Compile::AliasIdxRaw, false);
 
     // Test the should_post_on_exceptions_flag vs. 0
-    Node* chk = _gvn.transform( new (C, 3) CmpINode(should_post_flag, intcon(0)) );
-    Node* tst = _gvn.transform( new (C, 2) BoolNode(chk, BoolTest::eq) );
+    Node* chk = _gvn.transform( new (C) CmpINode(should_post_flag, intcon(0)) );
+    Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) );
 
     // Branch to slow_path if should_post_on_exceptions_flag was true
     { BuildCutout unless(this, tst, PROB_MAX);
@@ -656,8 +656,8 @@
   SafePointNode* outer_map = _map;   // preserved map is caller's
   SafePointNode* inner_map = kit->map();
   IfNode* iff = kit->create_and_map_if(outer_map->control(), p, prob, cnt);
-  outer_map->set_control(kit->gvn().transform( new (kit->C, 1) IfTrueNode(iff) ));
-  inner_map->set_control(kit->gvn().transform( new (kit->C, 1) IfFalseNode(iff) ));
+  outer_map->set_control(kit->gvn().transform( new (kit->C) IfTrueNode(iff) ));
+  inner_map->set_control(kit->gvn().transform( new (kit->C) IfFalseNode(iff) ));
 }
 BuildCutout::~BuildCutout() {
   GraphKit* kit = _kit;
@@ -965,7 +965,7 @@
   assert(call->jvms()->debug_depth() == call->req() - non_debug_edges, "");
 }
 
-bool GraphKit::compute_stack_effects(int& inputs, int& depth) {
+bool GraphKit::compute_stack_effects(int& inputs, int& depth, bool for_parse) {
   Bytecodes::Code code = java_bc();
   if (code == Bytecodes::_wide) {
     code = method()->java_code_at_bci(bci() + 1);
@@ -1006,11 +1006,11 @@
   case Bytecodes::_putfield:
     {
       bool is_get = (depth >= 0), is_static = (depth & 1);
-      bool ignore;
       ciBytecodeStream iter(method());
       iter.reset_to_bci(bci());
       iter.next();
-      ciField* field = iter.get_field(ignore);
+      bool ignored_will_link;
+      ciField* field = iter.get_field(ignored_will_link);
       int      size  = field->type()->size();
       inputs  = (is_static ? 0 : 1);
       if (is_get) {
@@ -1028,16 +1028,27 @@
   case Bytecodes::_invokedynamic:
   case Bytecodes::_invokeinterface:
     {
-      bool ignore;
       ciBytecodeStream iter(method());
       iter.reset_to_bci(bci());
       iter.next();
-      ciMethod* method = iter.get_method(ignore);
+      bool ignored_will_link;
+      ciSignature* declared_signature = NULL;
+      ciMethod* callee = iter.get_method(ignored_will_link, &declared_signature);
+      assert(declared_signature != NULL, "cannot be null");
       // (Do not use ciMethod::arg_size(), because
       // it might be an unloaded method, which doesn't
       // know whether it is static or not.)
-      inputs = method->invoke_arg_size(code);
-      int size = method->return_type()->size();
+      if (for_parse) {
+        // Case 1: When called from parse we are *before* the invoke (in the
+        //         caller) and need to to adjust the inputs by an appendix
+        //         argument that will be pushed implicitly.
+        inputs = callee->invoke_arg_size(code) - (iter.has_appendix() ? 1 : 0);
+      } else {
+        // Case 2: Here we are *after* the invoke (in the callee) and need to
+        //         remove any appendix arguments that were popped.
+        inputs = callee->invoke_arg_size(code) - (callee->has_member_arg() ? 1 : 0);
+      }
+      int size = declared_signature->return_type()->size();
       depth = size - inputs;
     }
     break;
@@ -1097,16 +1108,16 @@
 Node* GraphKit::basic_plus_adr(Node* base, Node* ptr, Node* offset) {
   // short-circuit a common case
   if (offset == intcon(0))  return ptr;
-  return _gvn.transform( new (C, 4) AddPNode(base, ptr, offset) );
+  return _gvn.transform( new (C) AddPNode(base, ptr, offset) );
 }
 
 Node* GraphKit::ConvI2L(Node* offset) {
   // short-circuit a common case
   jint offset_con = find_int_con(offset, Type::OffsetBot);
   if (offset_con != Type::OffsetBot) {
-    return longcon((long) offset_con);
+    return longcon((jlong) offset_con);
   }
-  return _gvn.transform( new (C, 2) ConvI2LNode(offset));
+  return _gvn.transform( new (C) ConvI2LNode(offset));
 }
 Node* GraphKit::ConvL2I(Node* offset) {
   // short-circuit a common case
@@ -1114,7 +1125,7 @@
   if (offset_con != (jlong)Type::OffsetBot) {
     return intcon((int) offset_con);
   }
-  return _gvn.transform( new (C, 2) ConvL2INode(offset));
+  return _gvn.transform( new (C) ConvL2INode(offset));
 }
 
 //-------------------------load_object_klass-----------------------------------
@@ -1133,7 +1144,7 @@
   Node *alen;
   if (alloc == NULL) {
     Node *r_adr = basic_plus_adr(array, arrayOopDesc::length_offset_in_bytes());
-    alen = _gvn.transform( new (C, 3) LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS));
+    alen = _gvn.transform( new (C) LoadRangeNode(0, immutable_memory(), r_adr, TypeInt::POS));
   } else {
     alen = alloc->Ideal_length();
     Node* ccast = alloc->make_ideal_length(_gvn.type(array)->is_oopptr(), &_gvn);
@@ -1166,8 +1177,8 @@
   // Construct NULL check
   Node *chk = NULL;
   switch(type) {
-    case T_LONG   : chk = new (C, 3) CmpLNode(value, _gvn.zerocon(T_LONG)); break;
-    case T_INT    : chk = new (C, 3) CmpINode( value, _gvn.intcon(0)); break;
+    case T_LONG   : chk = new (C) CmpLNode(value, _gvn.zerocon(T_LONG)); break;
+    case T_INT    : chk = new (C) CmpINode( value, _gvn.intcon(0)); break;
     case T_ARRAY  : // fall through
       type = T_OBJECT;  // simplify further tests
     case T_OBJECT : {
@@ -1214,7 +1225,7 @@
           return value;           // Elided null check quickly!
         }
       }
-      chk = new (C, 3) CmpPNode( value, null() );
+      chk = new (C) CmpPNode( value, null() );
       break;
     }
 
@@ -1224,7 +1235,7 @@
   chk = _gvn.transform(chk);
 
   BoolTest::mask btest = assert_null ? BoolTest::eq : BoolTest::ne;
-  BoolNode *btst = new (C, 2) BoolNode( chk, btest);
+  BoolNode *btst = new (C) BoolNode( chk, btest);
   Node   *tst = _gvn.transform( btst );
 
   //-----------
@@ -1291,8 +1302,8 @@
 
   if (null_control != NULL) {
     IfNode* iff = create_and_map_if(control(), tst, ok_prob, COUNT_UNKNOWN);
-    Node* null_true = _gvn.transform( new (C, 1) IfFalseNode(iff));
-    set_control(      _gvn.transform( new (C, 1) IfTrueNode(iff)));
+    Node* null_true = _gvn.transform( new (C) IfFalseNode(iff));
+    set_control(      _gvn.transform( new (C) IfTrueNode(iff)));
     if (null_true == top())
       explicit_null_checks_elided++;
     (*null_control) = null_true;
@@ -1344,7 +1355,7 @@
   // Object is already not-null?
   if( t == t_not_null ) return obj;
 
-  Node *cast = new (C, 2) CastPPNode(obj,t_not_null);
+  Node *cast = new (C) CastPPNode(obj,t_not_null);
   cast->init_req(0, control());
   cast = _gvn.transform( cast );
 
@@ -1373,7 +1384,6 @@
 }
 
 
-
 //=============================================================================
 //--------------------------------memory---------------------------------------
 Node* GraphKit::memory(uint alias_idx) {
@@ -1400,7 +1410,7 @@
 
 //------------------------------set_all_memory_call----------------------------
 void GraphKit::set_all_memory_call(Node* call, bool separate_io_proj) {
-  Node* newmem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory, separate_io_proj) );
+  Node* newmem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory, separate_io_proj) );
   set_all_memory(newmem);
 }
 
@@ -1604,9 +1614,9 @@
   int index_max = max_jint - 1;  // array size is max_jint, index is one less
   if (sizetype != NULL)  index_max = sizetype->_hi - 1;
   const TypeLong* lidxtype = TypeLong::make(CONST64(0), index_max, Type::WidenMax);
-  idx = _gvn.transform( new (C, 2) ConvI2LNode(idx, lidxtype) );
+  idx = _gvn.transform( new (C) ConvI2LNode(idx, lidxtype) );
 #endif
-  Node* scale = _gvn.transform( new (C, 3) LShiftXNode(idx, intcon(shift)) );
+  Node* scale = _gvn.transform( new (C) LShiftXNode(idx, intcon(shift)) );
   return basic_plus_adr(ary, base, scale);
 }
 
@@ -1654,8 +1664,8 @@
 
   // Re-use the current map to produce the result.
 
-  set_control(_gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Control)));
-  set_i_o(    _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::I_O    , separate_io_proj)));
+  set_control(_gvn.transform(new (C) ProjNode(call, TypeFunc::Control)));
+  set_i_o(    _gvn.transform(new (C) ProjNode(call, TypeFunc::I_O    , separate_io_proj)));
   set_all_memory_call(xcall, separate_io_proj);
 
   //return xcall;   // no need, caller already has it
@@ -1669,7 +1679,7 @@
   if (call->method() == NULL ||
       call->method()->return_type()->basic_type() == T_VOID)
         ret = top();
-  else  ret = _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms));
+  else  ret = _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
 
   // Note:  Since any out-of-line call can produce an exception,
   // we always insert an I_O projection from the call into the result.
@@ -1680,8 +1690,8 @@
     // The caller requested separate projections be used by the fall
     // through and exceptional paths, so replace the projections for
     // the fall through path.
-    set_i_o(_gvn.transform( new (C, 1) ProjNode(call, TypeFunc::I_O) ));
-    set_all_memory(_gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) ));
+    set_i_o(_gvn.transform( new (C) ProjNode(call, TypeFunc::I_O) ));
+    set_all_memory(_gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) ));
   }
   return ret;
 }
@@ -1721,13 +1731,13 @@
                                                       Node* keep_mem,
                                                       const TypePtr* hook_mem) {
   // no i/o
-  set_control(_gvn.transform( new (C, 1) ProjNode(call,TypeFunc::Control) ));
+  set_control(_gvn.transform( new (C) ProjNode(call,TypeFunc::Control) ));
   if (keep_mem) {
     // First clone the existing memory state
     set_all_memory(keep_mem);
     if (hook_mem != NULL) {
       // Make memory for the call
-      Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+      Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) );
       // Set the RawPtr memory state only.  This covers all the heap top/GC stuff
       // We also use hook_mem to extract specific effects from arraycopy stubs.
       set_memory(mem, hook_mem);
@@ -1831,7 +1841,7 @@
   int adr_type = Compile::AliasIdxRaw;
   Node* ctrl = control();
   Node* cnt  = make_load(ctrl, counter_addr, TypeInt::INT, T_INT, adr_type);
-  Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1)));
+  Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1)));
   store_to_memory( ctrl, counter_addr, incr, T_INT, adr_type );
 }
 
@@ -1947,7 +1957,7 @@
   // The debug info is the only real input to this call.
 
   // Halt-and-catch fire here.  The above call should never return!
-  HaltNode* halt = new(C, TypeFunc::Parms) HaltNode(control(), frameptr());
+  HaltNode* halt = new(C) HaltNode(control(), frameptr());
   _gvn.set_type_bottom(halt);
   root()->add_req(halt);
 
@@ -2003,7 +2013,7 @@
 Node* GraphKit::precision_rounding(Node* n) {
   return UseStrictFP && _method->flags().is_strict()
     && UseSSE == 0 && Matcher::strict_fp_requires_explicit_rounding
-    ? _gvn.transform( new (C, 2) RoundFloatNode(0, n) )
+    ? _gvn.transform( new (C) RoundFloatNode(0, n) )
     : n;
 }
 
@@ -2011,7 +2021,7 @@
 Node* GraphKit::dprecision_rounding(Node *n) {
   return UseStrictFP && _method->flags().is_strict()
     && UseSSE <= 1 && Matcher::strict_fp_requires_explicit_rounding
-    ? _gvn.transform( new (C, 2) RoundDoubleNode(0, n) )
+    ? _gvn.transform( new (C) RoundDoubleNode(0, n) )
     : n;
 }
 
@@ -2019,7 +2029,7 @@
 Node* GraphKit::dstore_rounding(Node* n) {
   return Matcher::strict_fp_requires_explicit_rounding
     && UseSSE <= 1
-    ? _gvn.transform( new (C, 2) RoundDoubleNode(0, n) )
+    ? _gvn.transform( new (C) RoundDoubleNode(0, n) )
     : n;
 }
 
@@ -2092,11 +2102,11 @@
   IfNode *opt_iff = _gvn.transform(iff)->as_If();
 
   // Fast path taken; set region slot 2
-  Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(opt_iff) );
+  Node *fast_taken = _gvn.transform( new (C) IfFalseNode(opt_iff) );
   region->init_req(2,fast_taken); // Capture fast-control
 
   // Fast path not-taken, i.e. slow path
-  Node *slow_taken = _gvn.transform( new (C, 1) IfTrueNode(opt_iff) );
+  Node *slow_taken = _gvn.transform( new (C) IfTrueNode(opt_iff) );
   return slow_taken;
 }
 
@@ -2112,7 +2122,6 @@
                                   Node* parm4, Node* parm5,
                                   Node* parm6, Node* parm7) {
   // Slow-path call
-  int size = call_type->domain()->cnt();
   bool is_leaf = !(flags & RC_NO_LEAF);
   bool has_io  = (!is_leaf && !(flags & RC_NO_IO));
   if (call_name == NULL) {
@@ -2121,12 +2130,12 @@
   }
   CallNode* call;
   if (!is_leaf) {
-    call = new(C, size) CallStaticJavaNode(call_type, call_addr, call_name,
+    call = new(C) CallStaticJavaNode(call_type, call_addr, call_name,
                                            bci(), adr_type);
   } else if (flags & RC_NO_FP) {
-    call = new(C, size) CallLeafNoFPNode(call_type, call_addr, call_name, adr_type);
+    call = new(C) CallLeafNoFPNode(call_type, call_addr, call_name, adr_type);
   } else {
-    call = new(C, size) CallLeafNode(call_type, call_addr, call_name, adr_type);
+    call = new(C) CallLeafNode(call_type, call_addr, call_name, adr_type);
   }
 
   // The following is similar to set_edges_for_java_call,
@@ -2187,7 +2196,7 @@
   }
 
   if (has_io) {
-    set_i_o(_gvn.transform(new (C, 1) ProjNode(call, TypeFunc::I_O)));
+    set_i_o(_gvn.transform(new (C) ProjNode(call, TypeFunc::I_O)));
   }
   return call;
 
@@ -2228,10 +2237,10 @@
   if (stopped())  return;
 
   // Make a catch node with just two handlers:  fall-through and catch-all
-  Node* i_o  = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::I_O, separate_io_proj) );
-  Node* catc = _gvn.transform( new (C, 2) CatchNode(control(), i_o, 2) );
-  Node* norm = _gvn.transform( new (C, 1) CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) );
-  Node* excp = _gvn.transform( new (C, 1) CatchProjNode(catc, CatchProjNode::catch_all_index,    CatchProjNode::no_handler_bci) );
+  Node* i_o  = _gvn.transform( new (C) ProjNode(call, TypeFunc::I_O, separate_io_proj) );
+  Node* catc = _gvn.transform( new (C) CatchNode(control(), i_o, 2) );
+  Node* norm = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::fall_through_index, CatchProjNode::no_handler_bci) );
+  Node* excp = _gvn.transform( new (C) CatchProjNode(catc, CatchProjNode::catch_all_index,    CatchProjNode::no_handler_bci) );
 
   { PreserveJVMState pjvms(this);
     set_control(excp);
@@ -2241,7 +2250,7 @@
       // Create an exception state also.
       // Use an exact type if the caller has specified a specific exception.
       const Type* ex_type = TypeOopPtr::make_from_klass_unique(ex_klass)->cast_to_ptr_type(TypePtr::NotNull);
-      Node*       ex_oop  = new (C, 2) CreateExNode(ex_type, control(), i_o);
+      Node*       ex_oop  = new (C) CreateExNode(ex_type, control(), i_o);
       add_exception_state(make_exception_state(_gvn.transform(ex_oop)));
     }
   }
@@ -2291,11 +2300,11 @@
     case SSC_easy_test:
       {
         // Just do a direct pointer compare and be done.
-        Node* cmp = _gvn.transform( new(C, 3) CmpPNode(subklass, superklass) );
-        Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) );
+        Node* cmp = _gvn.transform( new(C) CmpPNode(subklass, superklass) );
+        Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) );
         IfNode* iff = create_and_xform_if(control(), bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
-        set_control( _gvn.transform( new(C, 1) IfTrueNode (iff) ) );
-        return       _gvn.transform( new(C, 1) IfFalseNode(iff) );
+        set_control( _gvn.transform( new(C) IfTrueNode (iff) ) );
+        return       _gvn.transform( new(C) IfFalseNode(iff) );
       }
     case SSC_full_test:
       break;
@@ -2310,7 +2319,7 @@
 
   // First load the super-klass's check-offset
   Node *p1 = basic_plus_adr( superklass, superklass, in_bytes(Klass::super_check_offset_offset()) );
-  Node *chk_off = _gvn.transform( new (C, 3) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) );
+  Node *chk_off = _gvn.transform( new (C) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) );
   int cacheoff_con = in_bytes(Klass::secondary_super_cache_offset());
   bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con);
 
@@ -2321,7 +2330,7 @@
   // Worst-case type is a little odd: NULL is allowed as a result (usually
   // klass loads can never produce a NULL).
   Node *chk_off_X = ConvI2X(chk_off);
-  Node *p2 = _gvn.transform( new (C, 4) AddPNode(subklass,subklass,chk_off_X) );
+  Node *p2 = _gvn.transform( new (C) AddPNode(subklass,subklass,chk_off_X) );
   // For some types like interfaces the following loadKlass is from a 1-word
   // cache which is mutable so can't use immutable memory.  Other
   // types load from the super-class display table which is immutable.
@@ -2335,11 +2344,11 @@
   // See if we get an immediate positive hit.  Happens roughly 83% of the
   // time.  Test to see if the value loaded just previously from the subklass
   // is exactly the superklass.
-  Node *cmp1 = _gvn.transform( new (C, 3) CmpPNode( superklass, nkls ) );
-  Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp1, BoolTest::eq ) );
+  Node *cmp1 = _gvn.transform( new (C) CmpPNode( superklass, nkls ) );
+  Node *bol1 = _gvn.transform( new (C) BoolNode( cmp1, BoolTest::eq ) );
   IfNode *iff1 = create_and_xform_if( control(), bol1, PROB_LIKELY(0.83f), COUNT_UNKNOWN );
-  Node *iftrue1 = _gvn.transform( new (C, 1) IfTrueNode ( iff1 ) );
-  set_control(    _gvn.transform( new (C, 1) IfFalseNode( iff1 ) ) );
+  Node *iftrue1 = _gvn.transform( new (C) IfTrueNode ( iff1 ) );
+  set_control(    _gvn.transform( new (C) IfFalseNode( iff1 ) ) );
 
   // Compile speed common case: Check for being deterministic right now.  If
   // chk_off is a constant and not equal to cacheoff then we are NOT a
@@ -2352,9 +2361,9 @@
   }
 
   // Gather the various success & failures here
-  RegionNode *r_ok_subtype = new (C, 4) RegionNode(4);
+  RegionNode *r_ok_subtype = new (C) RegionNode(4);
   record_for_igvn(r_ok_subtype);
-  RegionNode *r_not_subtype = new (C, 3) RegionNode(3);
+  RegionNode *r_not_subtype = new (C) RegionNode(3);
   record_for_igvn(r_not_subtype);
 
   r_ok_subtype->init_req(1, iftrue1);
@@ -2365,20 +2374,20 @@
   // cache.  If it points to the display (and NOT the cache) and the display
   // missed then it's not a subtype.
   Node *cacheoff = _gvn.intcon(cacheoff_con);
-  Node *cmp2 = _gvn.transform( new (C, 3) CmpINode( chk_off, cacheoff ) );
-  Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmp2, BoolTest::ne ) );
+  Node *cmp2 = _gvn.transform( new (C) CmpINode( chk_off, cacheoff ) );
+  Node *bol2 = _gvn.transform( new (C) BoolNode( cmp2, BoolTest::ne ) );
   IfNode *iff2 = create_and_xform_if( control(), bol2, PROB_LIKELY(0.63f), COUNT_UNKNOWN );
-  r_not_subtype->init_req(1, _gvn.transform( new (C, 1) IfTrueNode (iff2) ) );
-  set_control(                _gvn.transform( new (C, 1) IfFalseNode(iff2) ) );
+  r_not_subtype->init_req(1, _gvn.transform( new (C) IfTrueNode (iff2) ) );
+  set_control(                _gvn.transform( new (C) IfFalseNode(iff2) ) );
 
   // Check for self.  Very rare to get here, but it is taken 1/3 the time.
   // No performance impact (too rare) but allows sharing of secondary arrays
   // which has some footprint reduction.
-  Node *cmp3 = _gvn.transform( new (C, 3) CmpPNode( subklass, superklass ) );
-  Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmp3, BoolTest::eq ) );
+  Node *cmp3 = _gvn.transform( new (C) CmpPNode( subklass, superklass ) );
+  Node *bol3 = _gvn.transform( new (C) BoolNode( cmp3, BoolTest::eq ) );
   IfNode *iff3 = create_and_xform_if( control(), bol3, PROB_LIKELY(0.36f), COUNT_UNKNOWN );
-  r_ok_subtype->init_req(2, _gvn.transform( new (C, 1) IfTrueNode ( iff3 ) ) );
-  set_control(               _gvn.transform( new (C, 1) IfFalseNode( iff3 ) ) );
+  r_ok_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode ( iff3 ) ) );
+  set_control(               _gvn.transform( new (C) IfFalseNode( iff3 ) ) );
 
   // -- Roads not taken here: --
   // We could also have chosen to perform the self-check at the beginning
@@ -2402,13 +2411,13 @@
   // The decision to inline or out-of-line this final check is platform
   // dependent, and is found in the AD file definition of PartialSubtypeCheck.
   Node* psc = _gvn.transform(
-    new (C, 3) PartialSubtypeCheckNode(control(), subklass, superklass) );
+    new (C) PartialSubtypeCheckNode(control(), subklass, superklass) );
 
-  Node *cmp4 = _gvn.transform( new (C, 3) CmpPNode( psc, null() ) );
-  Node *bol4 = _gvn.transform( new (C, 2) BoolNode( cmp4, BoolTest::ne ) );
+  Node *cmp4 = _gvn.transform( new (C) CmpPNode( psc, null() ) );
+  Node *bol4 = _gvn.transform( new (C) BoolNode( cmp4, BoolTest::ne ) );
   IfNode *iff4 = create_and_xform_if( control(), bol4, PROB_FAIR, COUNT_UNKNOWN );
-  r_not_subtype->init_req(2, _gvn.transform( new (C, 1) IfTrueNode (iff4) ) );
-  r_ok_subtype ->init_req(3, _gvn.transform( new (C, 1) IfFalseNode(iff4) ) );
+  r_not_subtype->init_req(2, _gvn.transform( new (C) IfTrueNode (iff4) ) );
+  r_ok_subtype ->init_req(3, _gvn.transform( new (C) IfFalseNode(iff4) ) );
 
   // Return false path; set default control to true path.
   set_control( _gvn.transform(r_ok_subtype) );
@@ -2472,18 +2481,18 @@
   const TypeKlassPtr* tklass = TypeKlassPtr::make(klass);
   Node* recv_klass = load_object_klass(receiver);
   Node* want_klass = makecon(tklass);
-  Node* cmp = _gvn.transform( new(C, 3) CmpPNode(recv_klass, want_klass) );
-  Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) );
+  Node* cmp = _gvn.transform( new(C) CmpPNode(recv_klass, want_klass) );
+  Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) );
   IfNode* iff = create_and_xform_if(control(), bol, prob, COUNT_UNKNOWN);
-  set_control( _gvn.transform( new(C, 1) IfTrueNode (iff) ));
-  Node* fail = _gvn.transform( new(C, 1) IfFalseNode(iff) );
+  set_control( _gvn.transform( new(C) IfTrueNode (iff) ));
+  Node* fail = _gvn.transform( new(C) IfFalseNode(iff) );
 
   const TypeOopPtr* recv_xtype = tklass->as_instance_type();
   assert(recv_xtype->klass_is_exact(), "");
 
   // Subsume downstream occurrences of receiver with a cast to
   // recv_xtype, since now we know what the type will be.
-  Node* cast = new(C, 2) CheckCastPPNode(control(), receiver, recv_xtype);
+  Node* cast = new(C) CheckCastPPNode(control(), receiver, recv_xtype);
   (*casted_receiver) = _gvn.transform(cast);
   // (User must make the replace_in_map call.)
 
@@ -2570,8 +2579,8 @@
 
   // Make the merge point
   enum { _obj_path = 1, _fail_path, _null_path, PATH_LIMIT };
-  RegionNode* region = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
-  Node*       phi    = new(C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL);
+  RegionNode* region = new(C) RegionNode(PATH_LIMIT);
+  Node*       phi    = new(C) PhiNode(region, TypeInt::BOOL);
   C->set_has_split_ifs(true); // Has chance for split-if optimization
 
   ciProfileData* data = NULL;
@@ -2673,8 +2682,8 @@
 
   // Make the merge point
   enum { _obj_path = 1, _null_path, PATH_LIMIT };
-  RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT);
-  Node*       phi    = new (C, PATH_LIMIT) PhiNode(region, toop);
+  RegionNode* region = new (C) RegionNode(PATH_LIMIT);
+  Node*       phi    = new (C) PhiNode(region, toop);
   C->set_has_split_ifs(true); // Has chance for split-if optimization
 
   // Use null-cast information if it is available
@@ -2723,7 +2732,7 @@
     Node* not_subtype_ctrl = gen_subtype_check( obj_klass, superklass );
 
     // Plug in success path into the merge
-    cast_obj = _gvn.transform(new (C, 2) CheckCastPPNode(control(),
+    cast_obj = _gvn.transform(new (C) CheckCastPPNode(control(),
                                                          not_null_obj, toop));
     // Failure path ends in uncommon trap (or may be dead - failure impossible)
     if (failure_control == NULL) {
@@ -2777,7 +2786,7 @@
   mb->init_req(TypeFunc::Control, control());
   mb->init_req(TypeFunc::Memory,  reset_memory());
   Node* membar = _gvn.transform(mb);
-  set_control(_gvn.transform(new (C, 1) ProjNode(membar,TypeFunc::Control) ));
+  set_control(_gvn.transform(new (C) ProjNode(membar,TypeFunc::Control) ));
   set_all_memory_call(membar);
   return membar;
 }
@@ -2806,11 +2815,11 @@
     mb->set_req(TypeFunc::Memory, memory(alias_idx));
   }
   Node* membar = _gvn.transform(mb);
-  set_control(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Control)));
+  set_control(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Control)));
   if (alias_idx == Compile::AliasIdxBot) {
-    merged_memory()->set_base_memory(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Memory)));
+    merged_memory()->set_base_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory)));
   } else {
-    set_memory(_gvn.transform(new (C, 1) ProjNode(membar, TypeFunc::Memory)),alias_idx);
+    set_memory(_gvn.transform(new (C) ProjNode(membar, TypeFunc::Memory)),alias_idx);
   }
   return membar;
 }
@@ -2830,10 +2839,10 @@
   assert(dead_locals_are_killed(), "should kill locals before sync. point");
 
   // Box the stack location
-  Node* box = _gvn.transform(new (C, 1) BoxLockNode(next_monitor()));
+  Node* box = _gvn.transform(new (C) BoxLockNode(next_monitor()));
   Node* mem = reset_memory();
 
-  FastLockNode * flock = _gvn.transform(new (C, 3) FastLockNode(0, obj, box) )->as_FastLock();
+  FastLockNode * flock = _gvn.transform(new (C) FastLockNode(0, obj, box) )->as_FastLock();
   if (PrintPreciseBiasedLockingStatistics) {
     // Create the counters for this fast lock.
     flock->create_lock_counter(sync_jvms()); // sync_jvms used to get current bci
@@ -2843,7 +2852,7 @@
   map()->push_monitor( flock );
 
   const TypeFunc *tf = LockNode::lock_type();
-  LockNode *lock = new (C, tf->domain()->cnt()) LockNode(C, tf);
+  LockNode *lock = new (C) LockNode(C, tf);
 
   lock->init_req( TypeFunc::Control, control() );
   lock->init_req( TypeFunc::Memory , mem );
@@ -2897,7 +2906,7 @@
   insert_mem_bar(Op_MemBarReleaseLock);
 
   const TypeFunc *tf = OptoRuntime::complete_monitor_exit_Type();
-  UnlockNode *unlock = new (C, tf->domain()->cnt()) UnlockNode(C, tf);
+  UnlockNode *unlock = new (C) UnlockNode(C, tf);
   uint raw_idx = Compile::AliasIdxRaw;
   unlock->init_req( TypeFunc::Control, control() );
   unlock->init_req( TypeFunc::Memory , memory(raw_idx) );
@@ -2963,19 +2972,19 @@
   alloc->set_req( TypeFunc::FramePtr, frameptr() );
   add_safepoint_edges(alloc);
   Node* allocx = _gvn.transform(alloc);
-  set_control( _gvn.transform(new (C, 1) ProjNode(allocx, TypeFunc::Control) ) );
+  set_control( _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Control) ) );
   // create memory projection for i_o
-  set_memory ( _gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx );
+  set_memory ( _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Memory, true) ), rawidx );
   make_slow_call_ex(allocx, env()->OutOfMemoryError_klass(), true);
 
   // create a memory projection as for the normal control path
-  Node* malloc = _gvn.transform(new (C, 1) ProjNode(allocx, TypeFunc::Memory));
+  Node* malloc = _gvn.transform(new (C) ProjNode(allocx, TypeFunc::Memory));
   set_memory(malloc, rawidx);
 
   // a normal slow-call doesn't change i_o, but an allocation does
   // we create a separate i_o projection for the normal control path
-  set_i_o(_gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::I_O, false) ) );
-  Node* rawoop = _gvn.transform( new (C, 1) ProjNode(allocx, TypeFunc::Parms) );
+  set_i_o(_gvn.transform( new (C) ProjNode(allocx, TypeFunc::I_O, false) ) );
+  Node* rawoop = _gvn.transform( new (C) ProjNode(allocx, TypeFunc::Parms) );
 
   // put in an initialization barrier
   InitializeNode* init = insert_mem_bar_volatile(Op_Initialize, rawidx,
@@ -3011,7 +3020,7 @@
   }
 
   // Cast raw oop to the real thing...
-  Node* javaoop = new (C, 2) CheckCastPPNode(control(), rawoop, oop_type);
+  Node* javaoop = new (C) CheckCastPPNode(control(), rawoop, oop_type);
   javaoop = _gvn.transform(javaoop);
   C->set_recent_alloc(control(), javaoop);
   assert(just_allocated_object(control()) == javaoop, "just allocated");
@@ -3070,9 +3079,9 @@
     // (It may be stress-tested by specifying StressReflectiveCode.)
     // Basically, we want to get into the VM is there's an illegal argument.
     Node* bit = intcon(Klass::_lh_instance_slow_path_bit);
-    initial_slow_test = _gvn.transform( new (C, 3) AndINode(layout_val, bit) );
+    initial_slow_test = _gvn.transform( new (C) AndINode(layout_val, bit) );
     if (extra_slow_test != intcon(0)) {
-      initial_slow_test = _gvn.transform( new (C, 3) OrINode(initial_slow_test, extra_slow_test) );
+      initial_slow_test = _gvn.transform( new (C) OrINode(initial_slow_test, extra_slow_test) );
     }
     // (Macro-expander will further convert this to a Bool, if necessary.)
   }
@@ -3089,7 +3098,7 @@
     // Clear the low bits to extract layout_helper_size_in_bytes:
     assert((int)Klass::_lh_instance_slow_path_bit < BytesPerLong, "clear bit");
     Node* mask = MakeConX(~ (intptr_t)right_n_bits(LogBytesPerLong));
-    size = _gvn.transform( new (C, 3) AndXNode(size, mask) );
+    size = _gvn.transform( new (C) AndXNode(size, mask) );
   }
   if (return_size_val != NULL) {
     (*return_size_val) = size;
@@ -3110,11 +3119,10 @@
   set_all_memory(mem); // Create new memory state
 
   AllocateNode* alloc
-    = new (C, AllocateNode::ParmLimit)
-        AllocateNode(C, AllocateNode::alloc_type(),
-                     control(), mem, i_o(),
-                     size, klass_node,
-                     initial_slow_test);
+    = new (C) AllocateNode(C, AllocateNode::alloc_type(),
+                           control(), mem, i_o(),
+                           size, klass_node,
+                           initial_slow_test);
 
   return set_output_for_allocation(alloc, oop_type);
 }
@@ -3137,8 +3145,8 @@
     // Optimistically assume that it is a subtype of Object[],
     // so that we can fold up all the address arithmetic.
     layout_con = Klass::array_layout_helper(T_OBJECT);
-    Node* cmp_lh = _gvn.transform( new(C, 3) CmpINode(layout_val, intcon(layout_con)) );
-    Node* bol_lh = _gvn.transform( new(C, 2) BoolNode(cmp_lh, BoolTest::eq) );
+    Node* cmp_lh = _gvn.transform( new(C) CmpINode(layout_val, intcon(layout_con)) );
+    Node* bol_lh = _gvn.transform( new(C) BoolNode(cmp_lh, BoolTest::eq) );
     { BuildCutout unless(this, bol_lh, PROB_MAX);
       _sp += nargs;
       uncommon_trap(Deoptimization::Reason_class_check,
@@ -3162,8 +3170,8 @@
     fast_size_limit <<= (LogBytesPerLong - log2_esize);
   }
 
-  Node* initial_slow_cmp  = _gvn.transform( new (C, 3) CmpUNode( length, intcon( fast_size_limit ) ) );
-  Node* initial_slow_test = _gvn.transform( new (C, 2) BoolNode( initial_slow_cmp, BoolTest::gt ) );
+  Node* initial_slow_cmp  = _gvn.transform( new (C) CmpUNode( length, intcon( fast_size_limit ) ) );
+  Node* initial_slow_test = _gvn.transform( new (C) BoolNode( initial_slow_cmp, BoolTest::gt ) );
   if (initial_slow_test->is_Bool()) {
     // Hide it behind a CMoveI, or else PhaseIdealLoop::split_up will get sick.
     initial_slow_test = initial_slow_test->as_Bool()->as_int_value(&_gvn);
@@ -3191,10 +3199,10 @@
   } else {
     Node* hss   = intcon(Klass::_lh_header_size_shift);
     Node* hsm   = intcon(Klass::_lh_header_size_mask);
-    Node* hsize = _gvn.transform( new(C, 3) URShiftINode(layout_val, hss) );
-    hsize       = _gvn.transform( new(C, 3) AndINode(hsize, hsm) );
+    Node* hsize = _gvn.transform( new(C) URShiftINode(layout_val, hss) );
+    hsize       = _gvn.transform( new(C) AndINode(hsize, hsm) );
     Node* mask  = intcon(round_mask);
-    header_size = _gvn.transform( new(C, 3) AddINode(hsize, mask) );
+    header_size = _gvn.transform( new(C) AddINode(hsize, mask) );
   }
 
   Node* elem_shift = NULL;
@@ -3219,7 +3227,7 @@
       jlong size_max = arrayOopDesc::max_array_length(T_BYTE);
       if (size_max > tllen->_hi)  size_max = tllen->_hi;
       const TypeLong* tlcon = TypeLong::make(CONST64(0), size_max, Type::WidenMin);
-      lengthx = _gvn.transform( new (C, 2) ConvI2LNode(length, tlcon));
+      lengthx = _gvn.transform( new (C) ConvI2LNode(length, tlcon));
     }
   }
 #endif
@@ -3230,11 +3238,11 @@
   // after a successful allocation.
   Node* abody = lengthx;
   if (elem_shift != NULL)
-    abody     = _gvn.transform( new(C, 3) LShiftXNode(lengthx, elem_shift) );
-  Node* size  = _gvn.transform( new(C, 3) AddXNode(headerx, abody) );
+    abody     = _gvn.transform( new(C) LShiftXNode(lengthx, elem_shift) );
+  Node* size  = _gvn.transform( new(C) AddXNode(headerx, abody) );
   if (round_mask != 0) {
     Node* mask = MakeConX(~round_mask);
-    size       = _gvn.transform( new(C, 3) AndXNode(size, mask) );
+    size       = _gvn.transform( new(C) AndXNode(size, mask) );
   }
   // else if round_mask == 0, the size computation is self-rounding
 
@@ -3252,12 +3260,11 @@
 
   // Create the AllocateArrayNode and its result projections
   AllocateArrayNode* alloc
-    = new (C, AllocateArrayNode::ParmLimit)
-        AllocateArrayNode(C, AllocateArrayNode::alloc_type(),
-                          control(), mem, i_o(),
-                          size, klass_node,
-                          initial_slow_test,
-                          length);
+    = new (C) AllocateArrayNode(C, AllocateArrayNode::alloc_type(),
+                                control(), mem, i_o(),
+                                size, klass_node,
+                                initial_slow_test,
+                                length);
 
   // Cast to correct type.  Note that the klass_node may be constant or not,
   // and in the latter case the actual array type will be inexact also.
@@ -3376,10 +3383,10 @@
   }
 
   Node *cont    = _gvn.intcon(1);
-  Node* opq     = _gvn.transform(new (C, 2) Opaque1Node(C, cont));
-  Node *bol     = _gvn.transform(new (C, 2) Conv2BNode(opq));
+  Node* opq     = _gvn.transform(new (C) Opaque1Node(C, cont));
+  Node *bol     = _gvn.transform(new (C) Conv2BNode(opq));
   IfNode* iff   = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
-  Node* iffalse = _gvn.transform(new (C, 1) IfFalseNode(iff));
+  Node* iffalse = _gvn.transform(new (C) IfFalseNode(iff));
   C->add_predicate_opaq(opq);
   {
     PreserveJVMState pjvms(this);
@@ -3387,7 +3394,7 @@
     _sp += nargs;
     uncommon_trap(reason, Deoptimization::Action_maybe_recompile);
   }
-  Node* iftrue = _gvn.transform(new (C, 1) IfTrueNode(iff));
+  Node* iftrue = _gvn.transform(new (C) IfTrueNode(iff));
   set_control(iftrue);
 }
 
@@ -3586,7 +3593,7 @@
 #ifdef _LP64
         // We could refine the type for what it's worth
         // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
-        next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
+        next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
 #endif
 
         // Now get the buffer location we will log the previous value into and store it
@@ -3634,7 +3641,7 @@
 #ifdef _LP64
     // We could refine the type for what it's worth
     // const TypeLong* lidxtype = TypeLong::make(CONST64(0), get_size_from_queue);
-    next_indexX = _gvn.transform( new (C, 2) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
+    next_indexX = _gvn.transform( new (C) ConvI2LNode(next_index, TypeLong::make(0, max_jlong, Type::WidenMax)) );
 #endif // _LP64
     Node* log_addr = __ AddP(no_base, buffer, next_indexX);
 
diff --git a/hotspot/src/share/vm/opto/graphKit.hpp b/hotspot/src/share/vm/opto/graphKit.hpp
index 723e65e..7d37a6d 100644
--- a/hotspot/src/share/vm/opto/graphKit.hpp
+++ b/hotspot/src/share/vm/opto/graphKit.hpp
@@ -145,6 +145,7 @@
   void clean_stack(int from_sp); // clear garbage beyond from_sp to top
 
   void inc_sp(int i)                  { set_sp(sp() + i); }
+  void dec_sp(int i)                  { set_sp(sp() - i); }
   void set_bci(int bci)               { _bci = bci; }
 
   // Make sure jvms has current bci & sp.
@@ -285,7 +286,7 @@
   // How many stack inputs does the current BC consume?
   // And, how does the stack change after the bytecode?
   // Returns false if unknown.
-  bool compute_stack_effects(int& inputs, int& depth);
+  bool compute_stack_effects(int& inputs, int& depth, bool for_parse = false);
 
   // Add a fixed offset to a pointer
   Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset) {
@@ -302,31 +303,31 @@
 
 
   // Some convenient shortcuts for common nodes
-  Node* IfTrue(IfNode* iff)                   { return _gvn.transform(new (C,1) IfTrueNode(iff));      }
-  Node* IfFalse(IfNode* iff)                  { return _gvn.transform(new (C,1) IfFalseNode(iff));     }
+  Node* IfTrue(IfNode* iff)                   { return _gvn.transform(new (C) IfTrueNode(iff));      }
+  Node* IfFalse(IfNode* iff)                  { return _gvn.transform(new (C) IfFalseNode(iff));     }
 
-  Node* AddI(Node* l, Node* r)                { return _gvn.transform(new (C,3) AddINode(l, r));       }
-  Node* SubI(Node* l, Node* r)                { return _gvn.transform(new (C,3) SubINode(l, r));       }
-  Node* MulI(Node* l, Node* r)                { return _gvn.transform(new (C,3) MulINode(l, r));       }
-  Node* DivI(Node* ctl, Node* l, Node* r)     { return _gvn.transform(new (C,3) DivINode(ctl, l, r));  }
+  Node* AddI(Node* l, Node* r)                { return _gvn.transform(new (C) AddINode(l, r));       }
+  Node* SubI(Node* l, Node* r)                { return _gvn.transform(new (C) SubINode(l, r));       }
+  Node* MulI(Node* l, Node* r)                { return _gvn.transform(new (C) MulINode(l, r));       }
+  Node* DivI(Node* ctl, Node* l, Node* r)     { return _gvn.transform(new (C) DivINode(ctl, l, r));  }
 
-  Node* AndI(Node* l, Node* r)                { return _gvn.transform(new (C,3) AndINode(l, r));       }
-  Node* OrI(Node* l, Node* r)                 { return _gvn.transform(new (C,3) OrINode(l, r));        }
-  Node* XorI(Node* l, Node* r)                { return _gvn.transform(new (C,3) XorINode(l, r));       }
+  Node* AndI(Node* l, Node* r)                { return _gvn.transform(new (C) AndINode(l, r));       }
+  Node* OrI(Node* l, Node* r)                 { return _gvn.transform(new (C) OrINode(l, r));        }
+  Node* XorI(Node* l, Node* r)                { return _gvn.transform(new (C) XorINode(l, r));       }
 
-  Node* MaxI(Node* l, Node* r)                { return _gvn.transform(new (C,3) MaxINode(l, r));       }
-  Node* MinI(Node* l, Node* r)                { return _gvn.transform(new (C,3) MinINode(l, r));       }
+  Node* MaxI(Node* l, Node* r)                { return _gvn.transform(new (C) MaxINode(l, r));       }
+  Node* MinI(Node* l, Node* r)                { return _gvn.transform(new (C) MinINode(l, r));       }
 
-  Node* LShiftI(Node* l, Node* r)             { return _gvn.transform(new (C,3) LShiftINode(l, r));    }
-  Node* RShiftI(Node* l, Node* r)             { return _gvn.transform(new (C,3) RShiftINode(l, r));    }
-  Node* URShiftI(Node* l, Node* r)            { return _gvn.transform(new (C,3) URShiftINode(l, r));   }
+  Node* LShiftI(Node* l, Node* r)             { return _gvn.transform(new (C) LShiftINode(l, r));    }
+  Node* RShiftI(Node* l, Node* r)             { return _gvn.transform(new (C) RShiftINode(l, r));    }
+  Node* URShiftI(Node* l, Node* r)            { return _gvn.transform(new (C) URShiftINode(l, r));   }
 
-  Node* CmpI(Node* l, Node* r)                { return _gvn.transform(new (C,3) CmpINode(l, r));       }
-  Node* CmpL(Node* l, Node* r)                { return _gvn.transform(new (C,3) CmpLNode(l, r));       }
-  Node* CmpP(Node* l, Node* r)                { return _gvn.transform(new (C,3) CmpPNode(l, r));       }
-  Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C,2) BoolNode(cmp, relop)); }
+  Node* CmpI(Node* l, Node* r)                { return _gvn.transform(new (C) CmpINode(l, r));       }
+  Node* CmpL(Node* l, Node* r)                { return _gvn.transform(new (C) CmpLNode(l, r));       }
+  Node* CmpP(Node* l, Node* r)                { return _gvn.transform(new (C) CmpPNode(l, r));       }
+  Node* Bool(Node* cmp, BoolTest::mask relop) { return _gvn.transform(new (C) BoolNode(cmp, relop)); }
 
-  Node* AddP(Node* b, Node* a, Node* o)       { return _gvn.transform(new (C,4) AddPNode(b, a, o));    }
+  Node* AddP(Node* b, Node* a, Node* o)       { return _gvn.transform(new (C) AddPNode(b, a, o));    }
 
   // Convert between int and long, and size_t.
   // (See macros ConvI2X, etc., in type.hpp for ConvI2X, etc.)
@@ -370,9 +371,9 @@
   // Replace all occurrences of one node by another.
   void replace_in_map(Node* old, Node* neww);
 
-  void push(Node* n)    { map_not_null(); _map->set_stack(_map->_jvms,_sp++,n); }
-  Node* pop()           { map_not_null(); return _map->stack(_map->_jvms,--_sp); }
-  Node* peek(int off=0) { map_not_null(); return _map->stack(_map->_jvms, _sp - off - 1); }
+  void  push(Node* n)     { map_not_null();        _map->set_stack(_map->_jvms,   _sp++, n); }
+  Node* pop()             { map_not_null(); return _map->stack(    _map->_jvms, --_sp); }
+  Node* peek(int off = 0) { map_not_null(); return _map->stack(    _map->_jvms,   _sp - off - 1); }
 
   void push_pair(Node* ldval) {
     push(ldval);
@@ -791,7 +792,7 @@
 
   // Handy for making control flow
   IfNode* create_and_map_if(Node* ctrl, Node* tst, float prob, float cnt) {
-    IfNode* iff = new (C, 2) IfNode(ctrl, tst, prob, cnt);// New IfNode's
+    IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's
     _gvn.set_type(iff, iff->Value(&_gvn)); // Value may be known at parse-time
     // Place 'if' on worklist if it will be in graph
     if (!tst->is_Con())  record_for_igvn(iff);     // Range-check and Null-check removal is later
@@ -799,7 +800,7 @@
   }
 
   IfNode* create_and_xform_if(Node* ctrl, Node* tst, float prob, float cnt) {
-    IfNode* iff = new (C, 2) IfNode(ctrl, tst, prob, cnt);// New IfNode's
+    IfNode* iff = new (C) IfNode(ctrl, tst, prob, cnt);// New IfNode's
     _gvn.transform(iff);                           // Value may be known at parse-time
     // Place 'if' on worklist if it will be in graph
     if (!tst->is_Con())  record_for_igvn(iff);     // Range-check and Null-check removal is later
diff --git a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp
index f9f40a3..b3919a6 100644
--- a/hotspot/src/share/vm/opto/idealGraphPrinter.cpp
+++ b/hotspot/src/share/vm/opto/idealGraphPrinter.cpp
@@ -130,15 +130,15 @@
       } else {
         st.print("%s%d", PrintIdealGraphFile, _file_count);
       }
-      fileStream *stream = new (ResourceObj::C_HEAP) fileStream(st.as_string());
+      fileStream *stream = new (ResourceObj::C_HEAP, mtCompiler) fileStream(st.as_string());
       _output = stream;
     } else {
-      fileStream *stream = new (ResourceObj::C_HEAP) fileStream(PrintIdealGraphFile);
+      fileStream *stream = new (ResourceObj::C_HEAP, mtCompiler) fileStream(PrintIdealGraphFile);
       _output = stream;
     }
     _file_count++;
   } else {
-    _stream = new (ResourceObj::C_HEAP) networkStream();
+    _stream = new (ResourceObj::C_HEAP, mtCompiler) networkStream();
 
     // Try to connect to visualizer
     if (_stream->connect(PrintIdealGraphAddress, PrintIdealGraphPort)) {
@@ -155,12 +155,12 @@
     } else {
       // It would be nice if we could shut down cleanly but it should
       // be an error if we can't connect to the visualizer.
-      fatal(err_msg("Couldn't connect to visualizer at %s:%d",
-                    PrintIdealGraphAddress, PrintIdealGraphPort));
+      fatal(err_msg_res("Couldn't connect to visualizer at %s:%d",
+                        PrintIdealGraphAddress, PrintIdealGraphPort));
     }
   }
 
-  _xml = new (ResourceObj::C_HEAP) xmlStream(_output);
+  _xml = new (ResourceObj::C_HEAP, mtCompiler) xmlStream(_output);
 
   head(TOP_ELEMENT);
 }
diff --git a/hotspot/src/share/vm/opto/idealKit.cpp b/hotspot/src/share/vm/opto/idealKit.cpp
index c9cb0f8..9083c62 100644
--- a/hotspot/src/share/vm/opto/idealKit.cpp
+++ b/hotspot/src/share/vm/opto/idealKit.cpp
@@ -86,7 +86,7 @@
   }
   // Delay gvn.tranform on if-nodes until construction is finished
   // to prevent a constant bool input from discarding a control output.
-  IfNode* iff = delay_transform(new (C, 2) IfNode(ctrl(), bol, prob, cnt))->as_If();
+  IfNode* iff = delay_transform(new (C) IfNode(ctrl(), bol, prob, cnt))->as_If();
   Node* then  = IfTrue(iff);
   Node* elsen = IfFalse(iff);
   Node* else_cvstate = copy_cvstate();
@@ -205,7 +205,7 @@
   assert(_cvstate != NULL, "must declare variables before labels");
   Node* lab = new_cvstate();
   int sz = 1 + goto_ct + 1 /* fall thru */;
-  Node* reg = delay_transform(new (C, sz) RegionNode(sz));
+  Node* reg = delay_transform(new (C) RegionNode(sz));
   lab->init_req(TypeFunc::Control, reg);
   return lab;
 }
@@ -295,7 +295,11 @@
   if (_delay_all_transforms) {
     return delay_transform(n);
   } else {
-    return gvn().transform(n);
+    n = gvn().transform(n);
+    if (!gvn().is_IterGVN()) {
+      C->record_for_igvn(n);
+    }
+    return n;
   }
 }
 
@@ -311,7 +315,7 @@
 //-----------------------------new_cvstate-----------------------------------
 Node* IdealKit::new_cvstate() {
   uint sz = _var_ct + first_var;
-  return new (C, sz) Node(sz);
+  return new (C) Node(sz);
 }
 
 //-----------------------------copy_cvstate-----------------------------------
@@ -409,7 +413,7 @@
 
   // Add required edge to oop_store, optimizer does not support precedence edges.
   // Convert required edge to precedence edge before allocation.
-  Node* st = new (C, 5) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx);
+  Node* st = new (C) StoreCMNode(ctl, mem, adr, adr_type, val, oop_store, oop_adr_idx);
 
   st = transform(st);
   set_memory(st, adr_idx);
@@ -509,8 +513,7 @@
   uint adr_idx = C->get_alias_index(adr_type);
 
   // Slow-path leaf call
-  int size = slow_call_type->domain()->cnt();
-  CallNode *call =  (CallNode*)new (C, size) CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type);
+  CallNode *call =  (CallNode*)new (C) CallLeafNode( slow_call_type, slow_call, leaf_name, adr_type);
 
   // Set fixed predefined input arguments
   call->init_req( TypeFunc::Control, ctrl() );
@@ -531,10 +534,10 @@
 
   // Slow leaf call has no side-effects, sets few values
 
-  set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) ));
+  set_ctrl(transform( new (C) ProjNode(call,TypeFunc::Control) ));
 
   // Make memory for the call
-  Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+  Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) );
 
   // Set the RawPtr memory state only.
   set_memory(mem, adr_idx);
@@ -557,8 +560,7 @@
   uint adr_idx = C->get_alias_index(adr_type);
 
   // Slow-path leaf call
-  int size = slow_call_type->domain()->cnt();
-  CallNode *call =  (CallNode*)new (C, size) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type);
+  CallNode *call =  (CallNode*)new (C) CallLeafNoFPNode( slow_call_type, slow_call, leaf_name, adr_type);
 
   // Set fixed predefined input arguments
   call->init_req( TypeFunc::Control, ctrl() );
@@ -579,10 +581,10 @@
 
   // Slow leaf call has no side-effects, sets few values
 
-  set_ctrl(transform( new (C, 1) ProjNode(call,TypeFunc::Control) ));
+  set_ctrl(transform( new (C) ProjNode(call,TypeFunc::Control) ));
 
   // Make memory for the call
-  Node* mem = _gvn.transform( new (C, 1) ProjNode(call, TypeFunc::Memory) );
+  Node* mem = _gvn.transform( new (C) ProjNode(call, TypeFunc::Memory) );
 
   // Set the RawPtr memory state only.
   set_memory(mem, adr_idx);
diff --git a/hotspot/src/share/vm/opto/idealKit.hpp b/hotspot/src/share/vm/opto/idealKit.hpp
index 6787e53..c6cc3c2 100644
--- a/hotspot/src/share/vm/opto/idealKit.hpp
+++ b/hotspot/src/share/vm/opto/idealKit.hpp
@@ -175,39 +175,39 @@
   void declarations_done();
   void drain_delay_transform();
 
-  Node* IfTrue(IfNode* iff)  { return transform(new (C,1) IfTrueNode(iff)); }
-  Node* IfFalse(IfNode* iff) { return transform(new (C,1) IfFalseNode(iff)); }
+  Node* IfTrue(IfNode* iff)  { return transform(new (C) IfTrueNode(iff)); }
+  Node* IfFalse(IfNode* iff) { return transform(new (C) IfFalseNode(iff)); }
 
   // Data
   Node* ConI(jint k) { return (Node*)gvn().intcon(k); }
   Node* makecon(const Type *t)  const { return _gvn.makecon(t); }
 
-  Node* AddI(Node* l, Node* r) { return transform(new (C,3) AddINode(l, r)); }
-  Node* SubI(Node* l, Node* r) { return transform(new (C,3) SubINode(l, r)); }
-  Node* AndI(Node* l, Node* r) { return transform(new (C,3) AndINode(l, r)); }
-  Node* MaxI(Node* l, Node* r) { return transform(new (C,3) MaxINode(l, r)); }
-  Node* LShiftI(Node* l, Node* r) { return transform(new (C,3) LShiftINode(l, r)); }
-  Node* CmpI(Node* l, Node* r) { return transform(new (C,3) CmpINode(l, r)); }
-  Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C,2) BoolNode(cmp, relop)); }
+  Node* AddI(Node* l, Node* r) { return transform(new (C) AddINode(l, r)); }
+  Node* SubI(Node* l, Node* r) { return transform(new (C) SubINode(l, r)); }
+  Node* AndI(Node* l, Node* r) { return transform(new (C) AndINode(l, r)); }
+  Node* MaxI(Node* l, Node* r) { return transform(new (C) MaxINode(l, r)); }
+  Node* LShiftI(Node* l, Node* r) { return transform(new (C) LShiftINode(l, r)); }
+  Node* CmpI(Node* l, Node* r) { return transform(new (C) CmpINode(l, r)); }
+  Node* Bool(Node* cmp, BoolTest::mask relop) { return transform(new (C) BoolNode(cmp, relop)); }
   void  increment(IdealVariable& v, Node* j)  { set(v, AddI(value(v), j)); }
   void  decrement(IdealVariable& v, Node* j)  { set(v, SubI(value(v), j)); }
 
-  Node* CmpL(Node* l, Node* r) { return transform(new (C,3) CmpLNode(l, r)); }
+  Node* CmpL(Node* l, Node* r) { return transform(new (C) CmpLNode(l, r)); }
 
   // TLS
-  Node* thread()  {  return gvn().transform(new (C, 1) ThreadLocalNode()); }
+  Node* thread()  {  return gvn().transform(new (C) ThreadLocalNode()); }
 
   // Pointers
-  Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C,4) AddPNode(base, ptr, off)); }
-  Node* CmpP(Node* l, Node* r) { return transform(new (C,3) CmpPNode(l, r)); }
+  Node* AddP(Node *base, Node *ptr, Node *off) { return transform(new (C) AddPNode(base, ptr, off)); }
+  Node* CmpP(Node* l, Node* r) { return transform(new (C) CmpPNode(l, r)); }
 #ifdef _LP64
-  Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorLNode(l, r)); }
+  Node* XorX(Node* l, Node* r) { return transform(new (C) XorLNode(l, r)); }
 #else // _LP64
-  Node* XorX(Node* l, Node* r) { return transform(new (C,3) XorINode(l, r)); }
+  Node* XorX(Node* l, Node* r) { return transform(new (C) XorINode(l, r)); }
 #endif // _LP64
-  Node* URShiftX(Node* l, Node* r) { return transform(new (C,3) URShiftXNode(l, r)); }
+  Node* URShiftX(Node* l, Node* r) { return transform(new (C) URShiftXNode(l, r)); }
   Node* ConX(jint k) { return (Node*)gvn().MakeConX(k); }
-  Node* CastPX(Node* ctl, Node* p) { return transform(new (C,2) CastP2XNode(ctl, p)); }
+  Node* CastPX(Node* ctl, Node* p) { return transform(new (C) CastP2XNode(ctl, p)); }
   // Add a fixed offset to a pointer
   Node* basic_plus_adr(Node* base, Node* ptr, intptr_t offset);
 
diff --git a/hotspot/src/share/vm/opto/ifg.cpp b/hotspot/src/share/vm/opto/ifg.cpp
index 3a22545..4827a17 100644
--- a/hotspot/src/share/vm/opto/ifg.cpp
+++ b/hotspot/src/share/vm/opto/ifg.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -416,6 +416,7 @@
     if( lrgs(lidx).mask().is_UP() &&
         lrgs(lidx).mask_size() &&
         !lrgs(lidx)._is_float &&
+        !lrgs(lidx)._is_vector &&
         lrgs(lidx).mask().overlap(*Matcher::idealreg2regmask[Op_RegI]) )
       cnt += lrgs(lidx).reg_pressure();
   }
@@ -430,7 +431,7 @@
   while ((lidx = elements.next()) != 0) {
     if( lrgs(lidx).mask().is_UP() &&
         lrgs(lidx).mask_size() &&
-        lrgs(lidx)._is_float )
+        (lrgs(lidx)._is_float || lrgs(lidx)._is_vector))
       cnt += lrgs(lidx).reg_pressure();
   }
   return cnt;
@@ -439,8 +440,8 @@
 //------------------------------lower_pressure---------------------------------
 // Adjust register pressure down by 1.  Capture last hi-to-low transition,
 static void lower_pressure( LRG *lrg, uint where, Block *b, uint *pressure, uint *hrp_index ) {
-  if( lrg->mask().is_UP() && lrg->mask_size() ) {
-    if( lrg->_is_float ) {
+  if (lrg->mask().is_UP() && lrg->mask_size()) {
+    if (lrg->_is_float || lrg->_is_vector) {
       pressure[1] -= lrg->reg_pressure();
       if( pressure[1] == (uint)FLOATPRESSURE ) {
         hrp_index[1] = where;
@@ -522,8 +523,8 @@
       LRG &lrg = lrgs(lidx);
       lrg._area += cost;
       // Compute initial register pressure
-      if( lrg.mask().is_UP() && lrg.mask_size() ) {
-        if( lrg._is_float ) {   // Count float pressure
+      if (lrg.mask().is_UP() && lrg.mask_size()) {
+        if (lrg._is_float || lrg._is_vector) {   // Count float pressure
           pressure[1] += lrg.reg_pressure();
 #ifdef EXACT_PRESSURE
           if( pressure[1] > b->_freg_pressure )
@@ -681,13 +682,10 @@
         // according to its bindings.
         const RegMask &rmask = lrgs(r).mask();
         if( lrgs(r).is_bound() && !(n->rematerialize()) && rmask.is_NotEmpty() ) {
-          // Smear odd bits; leave only aligned pairs of bits.
-          RegMask r2mask = rmask;
-          r2mask.SmearToPairs();
           // Check for common case
           int r_size = lrgs(r).num_regs();
           OptoReg::Name r_reg = (r_size == 1) ? rmask.find_first_elem() : OptoReg::Physical;
-
+          // Smear odd bits
           IndexSetIterator elements(&liveout);
           uint l;
           while ((l = elements.next()) != 0) {
@@ -701,10 +699,15 @@
             // Remove the bits from LRG 'r' from LRG 'l' so 'l' no
             // longer interferes with 'r'.  If 'l' requires aligned
             // adjacent pairs, subtract out bit pairs.
-            if( lrg.num_regs() == 2 && !lrg._fat_proj ) {
+            assert(!lrg._is_vector || !lrg._fat_proj, "sanity");
+            if (lrg.num_regs() > 1 && !lrg._fat_proj) {
+              RegMask r2mask = rmask;
+              // Leave only aligned set of bits.
+              r2mask.smear_to_sets(lrg.num_regs());
+              // It includes vector case.
               lrg.SUBTRACT( r2mask );
               lrg.compute_set_mask_size();
-            } else if( r_size != 1 ) {
+            } else if( r_size != 1 ) { // fat proj
               lrg.SUBTRACT( rmask );
               lrg.compute_set_mask_size();
             } else {            // Common case: size 1 bound removal
@@ -763,8 +766,8 @@
             // Newly live things assumed live from here to top of block
             lrg._area += cost;
             // Adjust register pressure
-            if( lrg.mask().is_UP() && lrg.mask_size() ) {
-              if( lrg._is_float ) {
+            if (lrg.mask().is_UP() && lrg.mask_size()) {
+              if (lrg._is_float || lrg._is_vector) {
                 pressure[1] += lrg.reg_pressure();
 #ifdef EXACT_PRESSURE
                 if( pressure[1] > b->_freg_pressure )
diff --git a/hotspot/src/share/vm/opto/ifnode.cpp b/hotspot/src/share/vm/opto/ifnode.cpp
index ce84f64..bc9106b 100644
--- a/hotspot/src/share/vm/opto/ifnode.cpp
+++ b/hotspot/src/share/vm/opto/ifnode.cpp
@@ -238,10 +238,10 @@
   Node* predicate_x = NULL;
   bool counted_loop = r->is_CountedLoop();
 
-  Node *region_c = new (igvn->C, req_c + 1) RegionNode(req_c + 1);
+  Node *region_c = new (igvn->C) RegionNode(req_c + 1);
   Node *phi_c    = con1;
   uint  len      = r->req();
-  Node *region_x = new (igvn->C, len - req_c) RegionNode(len - req_c);
+  Node *region_x = new (igvn->C) RegionNode(len - req_c);
   Node *phi_x    = PhiNode::make_blank(region_x, phi);
   for (uint i = 1, i_c = 1, i_x = 1; i < len; i++) {
     if (phi->in(i) == con1) {
@@ -272,7 +272,7 @@
   // Prevent the untimely death of phi_x.  Currently he has no uses.  He is
   // about to get one.  If this only use goes away, then phi_x will look dead.
   // However, he will be picking up some more uses down below.
-  Node *hook = new (igvn->C, 4) Node(4);
+  Node *hook = new (igvn->C) Node(4);
   hook->init_req(0, phi_x);
   hook->init_req(1, phi_c);
   phi_x = phase->transform( phi_x );
@@ -284,30 +284,30 @@
   cmp_x->set_req(2,con2);
   cmp_x = phase->transform(cmp_x);
   // Make the bool
-  Node *b_c = phase->transform(new (igvn->C, 2) BoolNode(cmp_c,b->_test._test));
-  Node *b_x = phase->transform(new (igvn->C, 2) BoolNode(cmp_x,b->_test._test));
+  Node *b_c = phase->transform(new (igvn->C) BoolNode(cmp_c,b->_test._test));
+  Node *b_x = phase->transform(new (igvn->C) BoolNode(cmp_x,b->_test._test));
   // Make the IfNode
-  IfNode *iff_c = new (igvn->C, 2) IfNode(region_c,b_c,iff->_prob,iff->_fcnt);
+  IfNode *iff_c = new (igvn->C) IfNode(region_c,b_c,iff->_prob,iff->_fcnt);
   igvn->set_type_bottom(iff_c);
   igvn->_worklist.push(iff_c);
   hook->init_req(2, iff_c);
 
-  IfNode *iff_x = new (igvn->C, 2) IfNode(region_x,b_x,iff->_prob, iff->_fcnt);
+  IfNode *iff_x = new (igvn->C) IfNode(region_x,b_x,iff->_prob, iff->_fcnt);
   igvn->set_type_bottom(iff_x);
   igvn->_worklist.push(iff_x);
   hook->init_req(3, iff_x);
 
   // Make the true/false arms
-  Node *iff_c_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_c));
-  Node *iff_c_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_c));
+  Node *iff_c_t = phase->transform(new (igvn->C) IfTrueNode (iff_c));
+  Node *iff_c_f = phase->transform(new (igvn->C) IfFalseNode(iff_c));
   if (predicate_c != NULL) {
     assert(predicate_x == NULL, "only one predicate entry expected");
     // Clone loop predicates to each path
     iff_c_t = igvn->clone_loop_predicates(predicate_c, iff_c_t, !counted_loop);
     iff_c_f = igvn->clone_loop_predicates(predicate_c, iff_c_f, !counted_loop);
   }
-  Node *iff_x_t = phase->transform(new (igvn->C, 1) IfTrueNode (iff_x));
-  Node *iff_x_f = phase->transform(new (igvn->C, 1) IfFalseNode(iff_x));
+  Node *iff_x_t = phase->transform(new (igvn->C) IfTrueNode (iff_x));
+  Node *iff_x_f = phase->transform(new (igvn->C) IfFalseNode(iff_x));
   if (predicate_x != NULL) {
     assert(predicate_c == NULL, "only one predicate entry expected");
     // Clone loop predicates to each path
@@ -316,14 +316,14 @@
   }
 
   // Merge the TRUE paths
-  Node *region_s = new (igvn->C, 3) RegionNode(3);
+  Node *region_s = new (igvn->C) RegionNode(3);
   igvn->_worklist.push(region_s);
   region_s->init_req(1, iff_c_t);
   region_s->init_req(2, iff_x_t);
   igvn->register_new_node_with_optimizer( region_s );
 
   // Merge the FALSE paths
-  Node *region_f = new (igvn->C, 3) RegionNode(3);
+  Node *region_f = new (igvn->C) RegionNode(3);
   igvn->_worklist.push(region_f);
   region_f->init_req(1, iff_c_f);
   region_f->init_req(2, iff_x_f);
@@ -338,8 +338,7 @@
   Node *phi_f = NULL;     // do not construct unless needed
   for (DUIterator_Last i2min, i2 = phi->last_outs(i2min); i2 >= i2min; --i2) {
     Node* v = phi->last_out(i2);// User of the phi
-    igvn->hash_delete(v);       // Have to fixup other Phi users
-    igvn->_worklist.push(v);
+    igvn->rehash_node_delayed(v); // Have to fixup other Phi users
     uint vop = v->Opcode();
     Node *proj = NULL;
     if( vop == Op_Phi ) {       // Remote merge point
@@ -439,7 +438,7 @@
 
   // Must return either the original node (now dead) or a new node
   // (Do not return a top here, since that would break the uniqueness of top.)
-  return new (igvn->C, 1) ConINode(TypeInt::ZERO);
+  return new (igvn->C) ConINode(TypeInt::ZERO);
 }
 
 //------------------------------is_range_check---------------------------------
@@ -542,19 +541,18 @@
   // Compute a new check
   Node *new_add = gvn->intcon(off_lo);
   if( index ) {
-    new_add = off_lo ? gvn->transform(new (gvn->C, 3) AddINode( index, new_add )) : index;
+    new_add = off_lo ? gvn->transform(new (gvn->C) AddINode( index, new_add )) : index;
   }
   Node *new_cmp = (flip == 1)
-    ? new (gvn->C, 3) CmpUNode( new_add, range )
-    : new (gvn->C, 3) CmpUNode( range, new_add );
+    ? new (gvn->C) CmpUNode( new_add, range )
+    : new (gvn->C) CmpUNode( range, new_add );
   new_cmp = gvn->transform(new_cmp);
   // See if no need to adjust the existing check
   if( new_cmp == cmp ) return;
   // Else, adjust existing check
-  Node *new_bol = gvn->transform( new (gvn->C, 2) BoolNode( new_cmp, bol->as_Bool()->_test._test ) );
-  igvn->hash_delete( iff );
+  Node *new_bol = gvn->transform( new (gvn->C) BoolNode( new_cmp, bol->as_Bool()->_test._test ) );
+  igvn->rehash_node_delayed( iff );
   iff->set_req_X( 1, new_bol, igvn );
-  igvn->_worklist.push( iff );
 }
 
 //------------------------------up_one_dom-------------------------------------
@@ -729,12 +727,10 @@
             if (failtype->_hi != max_jint && failtype->_lo != min_jint && bound > 1) {
               // Merge the two compares into a single unsigned compare by building  (CmpU (n - lo) hi)
               BoolTest::mask cond = fail->as_Proj()->_con ? BoolTest::lt : BoolTest::ge;
-              Node* adjusted = phase->transform(new (phase->C, 3) SubINode(n, phase->intcon(failtype->_lo)));
-              Node* newcmp = phase->transform(new (phase->C, 3) CmpUNode(adjusted, phase->intcon(bound)));
-              Node* newbool = phase->transform(new (phase->C, 2) BoolNode(newcmp, cond));
-              phase->hash_delete(dom_iff);
-              dom_iff->set_req(1, phase->intcon(ctrl->as_Proj()->_con));
-              phase->is_IterGVN()->_worklist.push(dom_iff);
+              Node* adjusted = phase->transform(new (phase->C) SubINode(n, phase->intcon(failtype->_lo)));
+              Node* newcmp = phase->transform(new (phase->C) CmpUNode(adjusted, phase->intcon(bound)));
+              Node* newbool = phase->transform(new (phase->C) BoolNode(newcmp, cond));
+              phase->is_IterGVN()->replace_input_of(dom_iff, 1, phase->intcon(ctrl->as_Proj()->_con));
               phase->hash_delete(this);
               set_req(1, newbool);
               return this;
@@ -1006,7 +1002,7 @@
 
   // Must return either the original node (now dead) or a new node
   // (Do not return a top here, since that would break the uniqueness of top.)
-  return new (phase->C, 1) ConINode(TypeInt::ZERO);
+  return new (phase->C) ConINode(TypeInt::ZERO);
 }
 
 //------------------------------dominated_by-----------------------------------
@@ -1042,17 +1038,15 @@
     // Loop ends when projection has no more uses.
     for (DUIterator_Last jmin, j = ifp->last_outs(jmin); j >= jmin; --j) {
       Node* s = ifp->last_out(j);   // Get child of IfTrue/IfFalse
-      igvn->hash_delete(s);         // Yank from hash table before edge hacking
       if( !s->depends_only_on_test() ) {
         // Find the control input matching this def-use edge.
         // For Regions it may not be in slot 0.
         uint l;
         for( l = 0; s->in(l) != ifp; l++ ) { }
-        s->set_req(l, ctrl_target);
+        igvn->replace_input_of(s, l, ctrl_target);
       } else {                      // Else, for control producers,
-        s->set_req(0, data_target); // Move child to data-target
+        igvn->replace_input_of(s, 0, data_target); // Move child to data-target
       }
-      igvn->_worklist.push(s);  // Revisit collapsed Phis
     } // End for each child of a projection
 
     igvn->remove_dead_node(ifp);
@@ -1104,7 +1098,7 @@
 
   // Flip test to be canonical.  Requires flipping the IfFalse/IfTrue and
   // cloning the IfNode.
-  Node* new_b = phase->transform( new (phase->C, 2) BoolNode(b->in(1), bt.negate()) );
+  Node* new_b = phase->transform( new (phase->C) BoolNode(b->in(1), bt.negate()) );
   if( !new_b->is_Bool() ) return NULL;
   b = new_b->as_Bool();
 
@@ -1112,7 +1106,7 @@
   assert( igvn, "Test is not canonical in parser?" );
 
   // The IF node never really changes, but it needs to be cloned
-  iff = new (phase->C, 2) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt);
+  iff = new (phase->C) IfNode( iff->in(0), b, 1.0-iff->_prob, iff->_fcnt);
 
   Node *prior = igvn->hash_find_insert(iff);
   if( prior ) {
@@ -1125,8 +1119,8 @@
   igvn->_worklist.push(iff);
 
   // Now handle projections.  Cloning not required.
-  Node* new_if_f = (Node*)(new (phase->C, 1) IfFalseNode( iff ));
-  Node* new_if_t = (Node*)(new (phase->C, 1) IfTrueNode ( iff ));
+  Node* new_if_f = (Node*)(new (phase->C) IfFalseNode( iff ));
+  Node* new_if_t = (Node*)(new (phase->C) IfTrueNode ( iff ));
 
   igvn->register_new_node_with_optimizer(new_if_f);
   igvn->register_new_node_with_optimizer(new_if_t);
diff --git a/hotspot/src/share/vm/opto/lcm.cpp b/hotspot/src/share/vm/opto/lcm.cpp
index 1ad9f0b..4cca9c5 100644
--- a/hotspot/src/share/vm/opto/lcm.cpp
+++ b/hotspot/src/share/vm/opto/lcm.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -139,6 +139,7 @@
     int iop = mach->ideal_Opcode();
     switch( iop ) {
     case Op_LoadB:
+    case Op_LoadUB:
     case Op_LoadUS:
     case Op_LoadD:
     case Op_LoadF:
@@ -368,7 +369,7 @@
     Node *tmp2 = _nodes[end_idx()+2];
     _nodes.map(end_idx()+1, tmp2);
     _nodes.map(end_idx()+2, tmp1);
-    Node *tmp = new (C, 1) Node(C->top()); // Use not NULL input
+    Node *tmp = new (C) Node(C->top()); // Use not NULL input
     tmp1->replace_by(tmp);
     tmp2->replace_by(tmp1);
     tmp->replace_by(tmp2);
@@ -445,6 +446,11 @@
     if( e->is_MachNullCheck() && e->in(1) == n )
       continue;
 
+    // Schedule IV increment last.
+    if (e->is_Mach() && e->as_Mach()->ideal_Opcode() == Op_CountedLoopEnd &&
+        e->in(1)->in(1) == n && n->is_iteratively_computed())
+      continue;
+
     uint n_choice  = 2;
 
     // See if this instruction is consumed by a branch. If so, then (as the
@@ -606,7 +612,7 @@
   // Set all registers killed and not already defined by the call.
   uint r_cnt = mcall->tf()->range()->cnt();
   int op = mcall->ideal_Opcode();
-  MachProjNode *proj = new (matcher.C, 1) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
+  MachProjNode *proj = new (matcher.C) MachProjNode( mcall, r_cnt+1, RegMask::Empty, MachProjNode::fat_proj );
   bbs.map(proj->_idx,this);
   _nodes.insert(node_cnt++, proj);
 
@@ -833,7 +839,7 @@
       regs.Insert(matcher.c_frame_pointer());
       regs.OR(n->out_RegMask());
 
-      MachProjNode *proj = new (matcher.C, 1) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj );
+      MachProjNode *proj = new (matcher.C) MachProjNode( n, 1, RegMask::Empty, MachProjNode::fat_proj );
       cfg->_bbs.map(proj->_idx,this);
       _nodes.insert(phi_cnt++, proj);
 
diff --git a/hotspot/src/share/vm/opto/library_call.cpp b/hotspot/src/share/vm/opto/library_call.cpp
index 29af531..40742d2 100644
--- a/hotspot/src/share/vm/opto/library_call.cpp
+++ b/hotspot/src/share/vm/opto/library_call.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,18 +44,22 @@
  public:
  private:
   bool             _is_virtual;
+  bool             _is_predicted;
   vmIntrinsics::ID _intrinsic_id;
 
  public:
-  LibraryIntrinsic(ciMethod* m, bool is_virtual, vmIntrinsics::ID id)
+  LibraryIntrinsic(ciMethod* m, bool is_virtual, bool is_predicted, vmIntrinsics::ID id)
     : InlineCallGenerator(m),
       _is_virtual(is_virtual),
+      _is_predicted(is_predicted),
       _intrinsic_id(id)
   {
   }
   virtual bool is_intrinsic() const { return true; }
   virtual bool is_virtual()   const { return _is_virtual; }
+  virtual bool is_predicted()   const { return _is_predicted; }
   virtual JVMState* generate(JVMState* jvms);
+  virtual Node* generate_predicate(JVMState* jvms);
   vmIntrinsics::ID intrinsic_id() const { return _intrinsic_id; }
 };
 
@@ -65,6 +69,8 @@
  private:
   LibraryIntrinsic* _intrinsic;   // the library intrinsic being called
 
+  const TypeOopPtr* sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr = false);
+
  public:
   LibraryCallKit(JVMState* caller, LibraryIntrinsic* intrinsic)
     : GraphKit(caller),
@@ -81,6 +87,7 @@
   int               arg_size()  const    { return callee()->arg_size(); }
 
   bool try_to_inline();
+  Node* try_to_predicate();
 
   // Helper functions to inline natives
   void push_result(RegionNode* region, PhiNode* value);
@@ -146,6 +153,7 @@
   CallJavaNode* generate_method_call_virtual(vmIntrinsics::ID method_id) {
     return generate_method_call(method_id, true, false);
   }
+  Node * load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString, bool is_exact, bool is_static);
 
   Node* make_string_method_node(int opcode, Node* str1_start, Node* cnt1, Node* str2_start, Node* cnt2);
   Node* make_string_method_node(int opcode, Node* str1, Node* str2);
@@ -160,6 +168,7 @@
   bool inline_trans(vmIntrinsics::ID id);
   bool inline_abs(vmIntrinsics::ID id);
   bool inline_sqrt(vmIntrinsics::ID id);
+  void finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName);
   bool inline_pow(vmIntrinsics::ID id);
   bool inline_exp(vmIntrinsics::ID id);
   bool inline_min_max(vmIntrinsics::ID id);
@@ -170,13 +179,17 @@
   // Helper for inline_unsafe_access.
   // Generates the guards that check whether the result of
   // Unsafe.getObject should be recorded in an SATB log buffer.
-  void insert_g1_pre_barrier(Node* base_oop, Node* offset, Node* pre_val);
+  void insert_pre_barrier(Node* base_oop, Node* offset, Node* pre_val, int nargs, bool need_mem_bar);
   bool inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile);
   bool inline_unsafe_prefetch(bool is_native_ptr, bool is_store, bool is_static);
   bool inline_unsafe_allocate();
   bool inline_unsafe_copyMemory();
   bool inline_native_currentThread();
-  bool inline_native_time_funcs(bool isNano);
+#ifdef TRACE_HAVE_INTRINSICS
+  bool inline_native_classID();
+  bool inline_native_threadID();
+#endif
+  bool inline_native_time_funcs(address method, const char* funcName);
   bool inline_native_isInterrupted();
   bool inline_native_Class_query(vmIntrinsics::ID id);
   bool inline_native_subtype_check();
@@ -188,8 +201,6 @@
   void copy_to_clone(Node* obj, Node* alloc_obj, Node* obj_size, bool is_array, bool card_mark);
   bool inline_native_clone(bool is_virtual);
   bool inline_native_Reflection_getCallerClass();
-  bool inline_native_AtomicLong_get();
-  bool inline_native_AtomicLong_attemptUpdate();
   bool is_method_invoke_or_aux_frame(JVMState* jvms);
   // Helper function for inlining native object hash method
   bool inline_native_hashcode(bool is_virtual, bool is_static);
@@ -238,7 +249,8 @@
                                     Node* src,  Node* src_offset,
                                     Node* dest, Node* dest_offset,
                                     Node* copy_length, bool dest_uninitialized);
-  bool inline_unsafe_CAS(BasicType type);
+  typedef enum { LS_xadd, LS_xchg, LS_cmpxchg } LoadStoreKind;
+  bool inline_unsafe_load_store(BasicType type,  LoadStoreKind kind);
   bool inline_unsafe_ordered_store(BasicType type);
   bool inline_fp_conversions(vmIntrinsics::ID id);
   bool inline_numberOfLeadingZeros(vmIntrinsics::ID id);
@@ -247,6 +259,10 @@
   bool inline_reverseBytes(vmIntrinsics::ID id);
 
   bool inline_reference_get();
+  bool inline_aescrypt_Block(vmIntrinsics::ID id);
+  bool inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id);
+  Node* inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting);
+  Node* get_key_start_from_aescrypt_object(Node* aescrypt_object);
 };
 
 
@@ -287,12 +303,21 @@
     case vmIntrinsics::_compareTo:
     case vmIntrinsics::_equals:
     case vmIntrinsics::_equalsC:
+    case vmIntrinsics::_getAndAddInt:
+    case vmIntrinsics::_getAndAddLong:
+    case vmIntrinsics::_getAndSetInt:
+    case vmIntrinsics::_getAndSetLong:
+    case vmIntrinsics::_getAndSetObject:
       break;  // InlineNatives does not control String.compareTo
+    case vmIntrinsics::_Reference_get:
+      break;  // InlineNatives does not control Reference.get
     default:
       return NULL;
     }
   }
 
+  bool is_predicted = false;
+
   switch (id) {
   case vmIntrinsics::_compareTo:
     if (!SpecialStringCompareTo)  return NULL;
@@ -327,11 +352,6 @@
     // We do not intrinsify this.  The optimizer does fine with it.
     return NULL;
 
-  case vmIntrinsics::_get_AtomicLong:
-  case vmIntrinsics::_attemptUpdate:
-    if (!InlineAtomicLong)  return NULL;
-    break;
-
   case vmIntrinsics::_getCallerClass:
     if (!UseNewReflection)  return NULL;
     if (!InlineReflectionGetCallerClass)  return NULL;
@@ -339,16 +359,82 @@
     break;
 
   case vmIntrinsics::_bitCount_i:
+    if (!Matcher::match_rule_supported(Op_PopCountI)) return NULL;
+    break;
+
   case vmIntrinsics::_bitCount_l:
-    if (!UsePopCountInstruction)  return NULL;
+    if (!Matcher::match_rule_supported(Op_PopCountL)) return NULL;
+    break;
+
+  case vmIntrinsics::_numberOfLeadingZeros_i:
+    if (!Matcher::match_rule_supported(Op_CountLeadingZerosI)) return NULL;
+    break;
+
+  case vmIntrinsics::_numberOfLeadingZeros_l:
+    if (!Matcher::match_rule_supported(Op_CountLeadingZerosL)) return NULL;
+    break;
+
+  case vmIntrinsics::_numberOfTrailingZeros_i:
+    if (!Matcher::match_rule_supported(Op_CountTrailingZerosI)) return NULL;
+    break;
+
+  case vmIntrinsics::_numberOfTrailingZeros_l:
+    if (!Matcher::match_rule_supported(Op_CountTrailingZerosL)) return NULL;
     break;
 
   case vmIntrinsics::_Reference_get:
-    // It is only when G1 is enabled that we absolutely
-    // need to use the intrinsic version of Reference.get()
-    // so that the value in the referent field, if necessary,
-    // can be registered by the pre-barrier code.
-    if (!UseG1GC) return NULL;
+    // Use the intrinsic version of Reference.get() so that the value in
+    // the referent field can be registered by the G1 pre-barrier code.
+    // Also add memory barrier to prevent commoning reads from this field
+    // across safepoint since GC can change it value.
+    break;
+
+  case vmIntrinsics::_compareAndSwapObject:
+#ifdef _LP64
+    if (!UseCompressedOops && !Matcher::match_rule_supported(Op_CompareAndSwapP)) return NULL;
+#endif
+    break;
+
+  case vmIntrinsics::_compareAndSwapLong:
+    if (!Matcher::match_rule_supported(Op_CompareAndSwapL)) return NULL;
+    break;
+
+  case vmIntrinsics::_getAndAddInt:
+    if (!Matcher::match_rule_supported(Op_GetAndAddI)) return NULL;
+    break;
+
+  case vmIntrinsics::_getAndAddLong:
+    if (!Matcher::match_rule_supported(Op_GetAndAddL)) return NULL;
+    break;
+
+  case vmIntrinsics::_getAndSetInt:
+    if (!Matcher::match_rule_supported(Op_GetAndSetI)) return NULL;
+    break;
+
+  case vmIntrinsics::_getAndSetLong:
+    if (!Matcher::match_rule_supported(Op_GetAndSetL)) return NULL;
+    break;
+
+  case vmIntrinsics::_getAndSetObject:
+#ifdef _LP64
+    if (!UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
+    if (UseCompressedOops && !Matcher::match_rule_supported(Op_GetAndSetN)) return NULL;
+    break;
+#else
+    if (!Matcher::match_rule_supported(Op_GetAndSetP)) return NULL;
+    break;
+#endif
+
+  case vmIntrinsics::_aescrypt_encryptBlock:
+  case vmIntrinsics::_aescrypt_decryptBlock:
+    if (!UseAESIntrinsics) return NULL;
+    break;
+
+  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
+  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+    if (!UseAESIntrinsics) return NULL;
+    // these two require the predicated logic
+    is_predicted = true;
     break;
 
  default:
@@ -382,7 +468,7 @@
     if (!InlineUnsafeOps)  return NULL;
   }
 
-  return new LibraryIntrinsic(m, is_virtual, (vmIntrinsics::ID) id);
+  return new LibraryIntrinsic(m, is_virtual, is_predicted, (vmIntrinsics::ID) id);
 }
 
 //----------------------register_library_intrinsics-----------------------
@@ -417,14 +503,12 @@
     return kit.transfer_exceptions_into_jvms();
   }
 
-  if (PrintIntrinsics) {
+  // The intrinsic bailed out
+  if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
     if (jvms->has_method()) {
       // Not a root compile.
-      tty->print("Did not inline intrinsic %s%s at bci:%d in",
-                 vmIntrinsics::name_at(intrinsic_id()),
-                 (is_virtual() ? " (virtual)" : ""), kit.bci());
-      kit.caller()->print_short_name(tty);
-      tty->print_cr(" (%d bytes)", kit.caller()->code_size());
+      const char* msg = is_virtual() ? "failed to inline (intrinsic, virtual)" : "failed to inline (intrinsic)";
+      CompileTask::print_inlining(kit.callee(), jvms->depth() - 1, kit.bci(), msg);
     } else {
       // Root compile
       tty->print("Did not generate intrinsic %s%s at bci:%d in",
@@ -436,6 +520,47 @@
   return NULL;
 }
 
+Node* LibraryIntrinsic::generate_predicate(JVMState* jvms) {
+  LibraryCallKit kit(jvms, this);
+  Compile* C = kit.C;
+  int nodes = C->unique();
+#ifndef PRODUCT
+  assert(is_predicted(), "sanity");
+  if ((PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) && Verbose) {
+    char buf[1000];
+    const char* str = vmIntrinsics::short_name_as_C_string(intrinsic_id(), buf, sizeof(buf));
+    tty->print_cr("Predicate for intrinsic %s", str);
+  }
+#endif
+
+  Node* slow_ctl = kit.try_to_predicate();
+  if (!kit.failing()) {
+    if (C->log()) {
+      C->log()->elem("predicate_intrinsic id='%s'%s nodes='%d'",
+                     vmIntrinsics::name_at(intrinsic_id()),
+                     (is_virtual() ? " virtual='1'" : ""),
+                     C->unique() - nodes);
+    }
+    return slow_ctl; // Could be NULL if the check folds.
+  }
+
+  // The intrinsic bailed out
+  if (PrintIntrinsics || PrintInlining NOT_PRODUCT( || PrintOptoInlining) ) {
+    if (jvms->has_method()) {
+      // Not a root compile.
+      const char* msg = "failed to generate predicate for intrinsic";
+      CompileTask::print_inlining(kit.callee(), jvms->depth() - 1, kit.bci(), msg);
+    } else {
+      // Root compile
+      tty->print("Did not generate predicate for intrinsic %s%s at bci:%d in",
+               vmIntrinsics::name_at(intrinsic_id()),
+               (is_virtual() ? " (virtual)" : ""), kit.bci());
+    }
+  }
+  C->gather_intrinsic_statistics(intrinsic_id(), is_virtual(), Compile::_intrinsic_failed);
+  return NULL;
+}
+
 bool LibraryCallKit::try_to_inline() {
   // Handle symbolic names for otherwise undistinguished boolean switches:
   const bool is_store       = true;
@@ -604,11 +729,11 @@
     return inline_unsafe_prefetch(!is_native_ptr, is_store, is_static);
 
   case vmIntrinsics::_compareAndSwapObject:
-    return inline_unsafe_CAS(T_OBJECT);
+    return inline_unsafe_load_store(T_OBJECT, LS_cmpxchg);
   case vmIntrinsics::_compareAndSwapInt:
-    return inline_unsafe_CAS(T_INT);
+    return inline_unsafe_load_store(T_INT, LS_cmpxchg);
   case vmIntrinsics::_compareAndSwapLong:
-    return inline_unsafe_CAS(T_LONG);
+    return inline_unsafe_load_store(T_LONG, LS_cmpxchg);
 
   case vmIntrinsics::_putOrderedObject:
     return inline_unsafe_ordered_store(T_OBJECT);
@@ -617,15 +742,34 @@
   case vmIntrinsics::_putOrderedLong:
     return inline_unsafe_ordered_store(T_LONG);
 
+  case vmIntrinsics::_getAndAddInt:
+    return inline_unsafe_load_store(T_INT, LS_xadd);
+  case vmIntrinsics::_getAndAddLong:
+    return inline_unsafe_load_store(T_LONG, LS_xadd);
+  case vmIntrinsics::_getAndSetInt:
+    return inline_unsafe_load_store(T_INT, LS_xchg);
+  case vmIntrinsics::_getAndSetLong:
+    return inline_unsafe_load_store(T_LONG, LS_xchg);
+  case vmIntrinsics::_getAndSetObject:
+    return inline_unsafe_load_store(T_OBJECT, LS_xchg);
+
   case vmIntrinsics::_currentThread:
     return inline_native_currentThread();
   case vmIntrinsics::_isInterrupted:
     return inline_native_isInterrupted();
 
+#ifdef TRACE_HAVE_INTRINSICS
+  case vmIntrinsics::_classID:
+    return inline_native_classID();
+  case vmIntrinsics::_threadID:
+    return inline_native_threadID();
+  case vmIntrinsics::_counterTime:
+    return inline_native_time_funcs(CAST_FROM_FN_PTR(address, TRACE_TIME_METHOD), "counterTime");
+#endif
   case vmIntrinsics::_currentTimeMillis:
-    return inline_native_time_funcs(false);
+    return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeMillis), "currentTimeMillis");
   case vmIntrinsics::_nanoTime:
-    return inline_native_time_funcs(true);
+    return inline_native_time_funcs(CAST_FROM_FN_PTR(address, os::javaTimeNanos), "nanoTime");
   case vmIntrinsics::_allocateInstance:
     return inline_unsafe_allocate();
   case vmIntrinsics::_copyMemory:
@@ -682,17 +826,20 @@
   case vmIntrinsics::_reverseBytes_c:
     return inline_reverseBytes((vmIntrinsics::ID) intrinsic_id());
 
-  case vmIntrinsics::_get_AtomicLong:
-    return inline_native_AtomicLong_get();
-  case vmIntrinsics::_attemptUpdate:
-    return inline_native_AtomicLong_attemptUpdate();
-
   case vmIntrinsics::_getCallerClass:
     return inline_native_Reflection_getCallerClass();
 
   case vmIntrinsics::_Reference_get:
     return inline_reference_get();
 
+  case vmIntrinsics::_aescrypt_encryptBlock:
+  case vmIntrinsics::_aescrypt_decryptBlock:
+    return inline_aescrypt_Block(intrinsic_id());
+
+  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
+  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+    return inline_cipherBlockChaining_AESCrypt(intrinsic_id());
+
   default:
     // If you get here, it may be that someone has added a new intrinsic
     // to the list in vmSymbols.hpp without implementing it here.
@@ -706,6 +853,36 @@
   }
 }
 
+Node* LibraryCallKit::try_to_predicate() {
+  if (!jvms()->has_method()) {
+    // Root JVMState has a null method.
+    assert(map()->memory()->Opcode() == Op_Parm, "");
+    // Insert the memory aliasing node
+    set_all_memory(reset_memory());
+  }
+  assert(merged_memory(), "");
+
+  switch (intrinsic_id()) {
+  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
+    return inline_cipherBlockChaining_AESCrypt_predicate(false);
+  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+    return inline_cipherBlockChaining_AESCrypt_predicate(true);
+
+  default:
+    // If you get here, it may be that someone has added a new intrinsic
+    // to the list in vmSymbols.hpp without implementing it here.
+#ifndef PRODUCT
+    if ((PrintMiscellaneous && (Verbose || WizardMode)) || PrintOpto) {
+      tty->print_cr("*** Warning: Unimplemented predicate for intrinsic %s(%d)",
+                    vmIntrinsics::name_at(intrinsic_id()), intrinsic_id());
+    }
+#endif
+    Node* slow_ctl = control();
+    set_control(top()); // No fast path instrinsic
+    return slow_ctl;
+  }
+}
+
 //------------------------------push_result------------------------------
 // Helper function for finishing intrinsics.
 void LibraryCallKit::push_result(RegionNode* region, PhiNode* value) {
@@ -740,7 +917,7 @@
 
   IfNode* iff = create_and_map_if(control(), test, true_prob, COUNT_UNKNOWN);
 
-  Node* if_slow = _gvn.transform( new (C, 1) IfTrueNode(iff) );
+  Node* if_slow = _gvn.transform( new (C) IfTrueNode(iff) );
   if (if_slow == top()) {
     // The slow branch is never taken.  No need to build this guard.
     return NULL;
@@ -749,7 +926,7 @@
   if (region != NULL)
     region->add_req(if_slow);
 
-  Node* if_fast = _gvn.transform( new (C, 1) IfFalseNode(iff) );
+  Node* if_fast = _gvn.transform( new (C) IfFalseNode(iff) );
   set_control(if_fast);
 
   return if_slow;
@@ -768,12 +945,12 @@
     return NULL;                // already stopped
   if (_gvn.type(index)->higher_equal(TypeInt::POS)) // [0,maxint]
     return NULL;                // index is already adequately typed
-  Node* cmp_lt = _gvn.transform( new (C, 3) CmpINode(index, intcon(0)) );
-  Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) );
+  Node* cmp_lt = _gvn.transform( new (C) CmpINode(index, intcon(0)) );
+  Node* bol_lt = _gvn.transform( new (C) BoolNode(cmp_lt, BoolTest::lt) );
   Node* is_neg = generate_guard(bol_lt, region, PROB_MIN);
   if (is_neg != NULL && pos_index != NULL) {
     // Emulate effect of Parse::adjust_map_after_if.
-    Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS);
+    Node* ccast = new (C) CastIINode(index, TypeInt::POS);
     ccast->set_req(0, control());
     (*pos_index) = _gvn.transform(ccast);
   }
@@ -786,13 +963,13 @@
     return NULL;                // already stopped
   if (_gvn.type(index)->higher_equal(TypeInt::POS1)) // [1,maxint]
     return NULL;                // index is already adequately typed
-  Node* cmp_le = _gvn.transform( new (C, 3) CmpINode(index, intcon(0)) );
+  Node* cmp_le = _gvn.transform( new (C) CmpINode(index, intcon(0)) );
   BoolTest::mask le_or_eq = (never_negative ? BoolTest::eq : BoolTest::le);
-  Node* bol_le = _gvn.transform( new (C, 2) BoolNode(cmp_le, le_or_eq) );
+  Node* bol_le = _gvn.transform( new (C) BoolNode(cmp_le, le_or_eq) );
   Node* is_notp = generate_guard(bol_le, NULL, PROB_MIN);
   if (is_notp != NULL && pos_index != NULL) {
     // Emulate effect of Parse::adjust_map_after_if.
-    Node* ccast = new (C, 2) CastIINode(index, TypeInt::POS1);
+    Node* ccast = new (C) CastIINode(index, TypeInt::POS1);
     ccast->set_req(0, control());
     (*pos_index) = _gvn.transform(ccast);
   }
@@ -824,9 +1001,9 @@
     return NULL;                // common case of whole-array copy
   Node* last = subseq_length;
   if (!zero_offset)             // last += offset
-    last = _gvn.transform( new (C, 3) AddINode(last, offset));
-  Node* cmp_lt = _gvn.transform( new (C, 3) CmpUNode(array_length, last) );
-  Node* bol_lt = _gvn.transform( new (C, 2) BoolNode(cmp_lt, BoolTest::lt) );
+    last = _gvn.transform( new (C) AddINode(last, offset));
+  Node* cmp_lt = _gvn.transform( new (C) CmpUNode(array_length, last) );
+  Node* bol_lt = _gvn.transform( new (C) BoolNode(cmp_lt, BoolTest::lt) );
   Node* is_over = generate_guard(bol_lt, region, PROB_MIN);
   return is_over;
 }
@@ -836,7 +1013,7 @@
 Node* LibraryCallKit::generate_current_thread(Node* &tls_output) {
   ciKlass*    thread_klass = env()->Thread_klass();
   const Type* thread_type  = TypeOopPtr::make_from_klass(thread_klass)->cast_to_ptr_type(TypePtr::NotNull);
-  Node* thread = _gvn.transform(new (C, 1) ThreadLocalNode());
+  Node* thread = _gvn.transform(new (C) ThreadLocalNode());
   Node* p = basic_plus_adr(top()/*!oop*/, thread, in_bytes(JavaThread::threadObj_offset()));
   Node* threadObj = make_load(NULL, p, thread_type, T_OBJECT);
   tls_output = thread;
@@ -871,18 +1048,18 @@
     // Get length of string 2
     str2_len = load_String_length(no_ctrl, str2);
 
-    result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
+    result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
                                  str1_start, str1_len, str2_start, str2_len);
     break;
   case Op_StrComp:
     // Get length of string 2
     str2_len = load_String_length(no_ctrl, str2);
 
-    result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
+    result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS),
                                  str1_start, str1_len, str2_start, str2_len);
     break;
   case Op_StrEquals:
-    result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
+    result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
                                str1_start, str2_start, str1_len);
     break;
   default:
@@ -905,15 +1082,15 @@
   Node* result = NULL;
   switch (opcode) {
   case Op_StrIndexOf:
-    result = new (C, 6) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
+    result = new (C) StrIndexOfNode(control(), memory(TypeAryPtr::CHARS),
                                  str1_start, cnt1, str2_start, cnt2);
     break;
   case Op_StrComp:
-    result = new (C, 6) StrCompNode(control(), memory(TypeAryPtr::CHARS),
+    result = new (C) StrCompNode(control(), memory(TypeAryPtr::CHARS),
                                  str1_start, cnt1, str2_start, cnt2);
     break;
   case Op_StrEquals:
-    result = new (C, 5) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
+    result = new (C) StrEqualsNode(control(), memory(TypeAryPtr::CHARS),
                                  str1_start, str2_start, cnt1);
     break;
   default:
@@ -978,12 +1155,12 @@
   }
 
   // paths (plus control) merge
-  RegionNode* region = new (C, 5) RegionNode(5);
-  Node* phi = new (C, 5) PhiNode(region, TypeInt::BOOL);
+  RegionNode* region = new (C) RegionNode(5);
+  Node* phi = new (C) PhiNode(region, TypeInt::BOOL);
 
   // does source == target string?
-  Node* cmp = _gvn.transform(new (C, 3) CmpPNode(receiver, argument));
-  Node* bol = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::eq));
+  Node* cmp = _gvn.transform(new (C) CmpPNode(receiver, argument));
+  Node* bol = _gvn.transform(new (C) BoolNode(cmp, BoolTest::eq));
 
   Node* if_eq = generate_slow_guard(bol, NULL);
   if (if_eq != NULL) {
@@ -999,8 +1176,8 @@
     _sp += nargs;          // gen_instanceof might do an uncommon trap
     Node* inst = gen_instanceof(argument, makecon(TypeKlassPtr::make(klass)));
     _sp -= nargs;
-    Node* cmp  = _gvn.transform(new (C, 3) CmpINode(inst, intcon(1)));
-    Node* bol  = _gvn.transform(new (C, 2) BoolNode(cmp, BoolTest::ne));
+    Node* cmp  = _gvn.transform(new (C) CmpINode(inst, intcon(1)));
+    Node* bol  = _gvn.transform(new (C) BoolNode(cmp, BoolTest::ne));
 
     Node* inst_false = generate_guard(bol, NULL, PROB_MIN);
     //instanceOf == true, fallthrough
@@ -1015,7 +1192,7 @@
     const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(klass);
 
     // Properly cast the argument to String
-    argument = _gvn.transform(new (C, 2) CheckCastPPNode(control(), argument, string_type));
+    argument = _gvn.transform(new (C) CheckCastPPNode(control(), argument, string_type));
     // This path is taken only when argument's type is String:NotNull.
     argument = cast_not_null(argument, false);
 
@@ -1038,8 +1215,8 @@
     Node* argument_cnt  = load_String_length(no_ctrl, argument);
 
     // Check for receiver count != argument count
-    Node* cmp = _gvn.transform( new(C, 3) CmpINode(receiver_cnt, argument_cnt) );
-    Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::ne) );
+    Node* cmp = _gvn.transform( new(C) CmpINode(receiver_cnt, argument_cnt) );
+    Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::ne) );
     Node* if_ne = generate_slow_guard(bol, NULL);
     if (if_ne != NULL) {
       phi->init_req(4, intcon(0));
@@ -1074,7 +1251,7 @@
   Node *argument1 = pop();
 
   Node* equals =
-    _gvn.transform(new (C, 4) AryEqNode(control(), memory(TypeAryPtr::CHARS),
+    _gvn.transform(new (C) AryEqNode(control(), memory(TypeAryPtr::CHARS),
                                         argument1, argument2) );
   push(equals);
   return true;
@@ -1249,8 +1426,8 @@
     const TypeOopPtr* string_type = TypeOopPtr::make_from_klass(str_klass);
 
     // Make the merge point
-    RegionNode* result_rgn = new (C, 4) RegionNode(4);
-    Node*       result_phi = new (C, 4) PhiNode(result_rgn, TypeInt::INT);
+    RegionNode* result_rgn = new (C) RegionNode(4);
+    Node*       result_phi = new (C) PhiNode(result_rgn, TypeInt::INT);
     Node* no_ctrl  = NULL;
 
     // Get start addr of source string
@@ -1270,8 +1447,8 @@
     Node* substr_cnt  = load_String_length(no_ctrl, argument);
 
     // Check for substr count > string count
-    Node* cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, source_cnt) );
-    Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::gt) );
+    Node* cmp = _gvn.transform( new(C) CmpINode(substr_cnt, source_cnt) );
+    Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::gt) );
     Node* if_gt = generate_slow_guard(bol, NULL);
     if (if_gt != NULL) {
       result_phi->init_req(2, intcon(-1));
@@ -1280,8 +1457,8 @@
 
     if (!stopped()) {
       // Check for substr count == 0
-      cmp = _gvn.transform( new(C, 3) CmpINode(substr_cnt, intcon(0)) );
-      bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) );
+      cmp = _gvn.transform( new(C) CmpINode(substr_cnt, intcon(0)) );
+      bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) );
       Node* if_zero = generate_slow_guard(bol, NULL);
       if (if_zero != NULL) {
         result_phi->init_req(3, intcon(0));
@@ -1382,7 +1559,7 @@
 Node * LibraryCallKit::pop_math_arg() {
   Node *arg = pop_pair();
   if( Matcher::strict_fp_requires_explicit_rounding && UseSSE<=1 )
-    arg = _gvn.transform( new (C, 2) RoundDoubleNode(0, arg) );
+    arg = _gvn.transform( new (C) RoundDoubleNode(0, arg) );
   return arg;
 }
 
@@ -1396,13 +1573,13 @@
 
   switch (id) {
   case vmIntrinsics::_dsin:
-    trig = _gvn.transform((Node*)new (C, 2) SinDNode(arg));
+    trig = _gvn.transform((Node*)new (C) SinDNode(arg));
     break;
   case vmIntrinsics::_dcos:
-    trig = _gvn.transform((Node*)new (C, 2) CosDNode(arg));
+    trig = _gvn.transform((Node*)new (C) CosDNode(arg));
     break;
   case vmIntrinsics::_dtan:
-    trig = _gvn.transform((Node*)new (C, 2) TanDNode(arg));
+    trig = _gvn.transform((Node*)new (C) TanDNode(arg));
     break;
   default:
     assert(false, "bad intrinsic was passed in");
@@ -1446,17 +1623,17 @@
     // probably do the math inside the SIN encoding.
 
     // Make the merge point
-    RegionNode *r = new (C, 3) RegionNode(3);
-    Node *phi = new (C, 3) PhiNode(r,Type::DOUBLE);
+    RegionNode *r = new (C) RegionNode(3);
+    Node *phi = new (C) PhiNode(r,Type::DOUBLE);
 
     // Flatten arg so we need only 1 test
-    Node *abs = _gvn.transform(new (C, 2) AbsDNode(arg));
+    Node *abs = _gvn.transform(new (C) AbsDNode(arg));
     // Node for PI/4 constant
     Node *pi4 = makecon(TypeD::make(pi_4));
     // Check PI/4 : abs(arg)
-    Node *cmp = _gvn.transform(new (C, 3) CmpDNode(pi4,abs));
+    Node *cmp = _gvn.transform(new (C) CmpDNode(pi4,abs));
     // Check: If PI/4 < abs(arg) then go slow
-    Node *bol = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::lt ) );
+    Node *bol = _gvn.transform( new (C) BoolNode( cmp, BoolTest::lt ) );
     // Branch either way
     IfNode *iff = create_and_xform_if(control(),bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
     set_control(opt_iff(r,iff));
@@ -1484,7 +1661,7 @@
       break;
     }
     assert(control()->in(0) == call, "");
-    Node* slow_result = _gvn.transform(new (C, 1) ProjNode(call,TypeFunc::Parms));
+    Node* slow_result = _gvn.transform(new (C) ProjNode(call,TypeFunc::Parms));
     r->init_req(1,control());
     phi->init_req(1,slow_result);
 
@@ -1505,7 +1682,7 @@
 bool LibraryCallKit::inline_sqrt(vmIntrinsics::ID id) {
   assert(id == vmIntrinsics::_dsqrt, "Not square root");
   _sp += arg_size();        // restore stack pointer
-  push_pair(_gvn.transform(new (C, 2) SqrtDNode(0, pop_math_arg())));
+  push_pair(_gvn.transform(new (C) SqrtDNode(0, pop_math_arg())));
   return true;
 }
 
@@ -1514,47 +1691,83 @@
 bool LibraryCallKit::inline_abs(vmIntrinsics::ID id) {
   assert(id == vmIntrinsics::_dabs, "Not absolute value");
   _sp += arg_size();        // restore stack pointer
-  push_pair(_gvn.transform(new (C, 2) AbsDNode(pop_math_arg())));
+  push_pair(_gvn.transform(new (C) AbsDNode(pop_math_arg())));
   return true;
 }
 
+void LibraryCallKit::finish_pow_exp(Node* result, Node* x, Node* y, const TypeFunc* call_type, address funcAddr, const char* funcName) {
+  //-------------------
+  //result=(result.isNaN())? funcAddr():result;
+  // Check: If isNaN() by checking result!=result? then either trap
+  // or go to runtime
+  Node* cmpisnan = _gvn.transform(new (C) CmpDNode(result,result));
+  // Build the boolean node
+  Node* bolisnum = _gvn.transform( new (C) BoolNode(cmpisnan, BoolTest::eq) );
+
+  if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
+    {
+      BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
+      // End the current control-flow path
+      push_pair(x);
+      if (y != NULL) {
+        push_pair(y);
+      }
+      // The pow or exp intrinsic returned a NaN, which requires a call
+      // to the runtime.  Recompile with the runtime call.
+      uncommon_trap(Deoptimization::Reason_intrinsic,
+                    Deoptimization::Action_make_not_entrant);
+    }
+    push_pair(result);
+  } else {
+    // If this inlining ever returned NaN in the past, we compile a call
+    // to the runtime to properly handle corner cases
+
+    IfNode* iff = create_and_xform_if(control(), bolisnum, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
+    Node* if_slow = _gvn.transform( new (C) IfFalseNode(iff) );
+    Node* if_fast = _gvn.transform( new (C) IfTrueNode(iff) );
+
+    if (!if_slow->is_top()) {
+      RegionNode* result_region = new(C) RegionNode(3);
+      PhiNode*    result_val = new (C) PhiNode(result_region, Type::DOUBLE);
+
+      result_region->init_req(1, if_fast);
+      result_val->init_req(1, result);
+
+      set_control(if_slow);
+
+      const TypePtr* no_memory_effects = NULL;
+      Node* rt = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
+                                   no_memory_effects,
+                                   x, top(), y, y ? top() : NULL);
+      Node* value = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+0));
+#ifdef ASSERT
+      Node* value_top = _gvn.transform(new (C) ProjNode(rt, TypeFunc::Parms+1));
+      assert(value_top == top(), "second value must be top");
+#endif
+
+      result_region->init_req(2, control());
+      result_val->init_req(2, value);
+      push_result(result_region, result_val);
+    } else {
+      push_pair(result);
+    }
+  }
+}
+
 //------------------------------inline_exp-------------------------------------
 // Inline exp instructions, if possible.  The Intel hardware only misses
 // really odd corner cases (+/- Infinity).  Just uncommon-trap them.
 bool LibraryCallKit::inline_exp(vmIntrinsics::ID id) {
   assert(id == vmIntrinsics::_dexp, "Not exp");
 
-  // If this inlining ever returned NaN in the past, we do not intrinsify it
-  // every again.  NaN results requires StrictMath.exp handling.
-  if (too_many_traps(Deoptimization::Reason_intrinsic))  return false;
-
-  // Do not intrinsify on older platforms which lack cmove.
-  if (ConditionalMoveLimit == 0)  return false;
-
   _sp += arg_size();        // restore stack pointer
   Node *x = pop_math_arg();
-  Node *result = _gvn.transform(new (C, 2) ExpDNode(0,x));
+  Node *result = _gvn.transform(new (C) ExpDNode(0,x));
 
-  //-------------------
-  //result=(result.isNaN())? StrictMath::exp():result;
-  // Check: If isNaN() by checking result!=result? then go to Strict Math
-  Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result));
-  // Build the boolean node
-  Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) );
-
-  { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
-    // End the current control-flow path
-    push_pair(x);
-    // Math.exp intrinsic returned a NaN, which requires StrictMath.exp
-    // to handle.  Recompile without intrinsifying Math.exp
-    uncommon_trap(Deoptimization::Reason_intrinsic,
-                  Deoptimization::Action_make_not_entrant);
-  }
+  finish_pow_exp(result, x, NULL, OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
 
   C->set_has_split_ifs(true); // Has chance for split-if optimization
 
-  push_pair(result);
-
   return true;
 }
 
@@ -1563,17 +1776,12 @@
 bool LibraryCallKit::inline_pow(vmIntrinsics::ID id) {
   assert(id == vmIntrinsics::_dpow, "Not pow");
 
-  // If this inlining ever returned NaN in the past, we do not intrinsify it
-  // every again.  NaN results requires StrictMath.pow handling.
-  if (too_many_traps(Deoptimization::Reason_intrinsic))  return false;
-
-  // Do not intrinsify on older platforms which lack cmove.
-  if (ConditionalMoveLimit == 0)  return false;
-
   // Pseudocode for pow
   // if (x <= 0.0) {
-  //   if ((double)((int)y)==y) { // if y is int
-  //     result = ((1&(int)y)==0)?-DPow(abs(x), y):DPow(abs(x), y)
+  //   long longy = (long)y;
+  //   if ((double)longy == y) { // if y is long
+  //     if (y + 1 == y) longy = 0; // huge number: even
+  //     result = ((1&longy) == 0)?-DPow(abs(x), y):DPow(abs(x), y);
   //   } else {
   //     result = NaN;
   //   }
@@ -1581,7 +1789,7 @@
   //   result = DPow(x,y);
   // }
   // if (result != result)?  {
-  //   uncommon_trap();
+  //   result = uncommon_trap() or runtime_call();
   // }
   // return result;
 
@@ -1589,79 +1797,118 @@
   Node* y = pop_math_arg();
   Node* x = pop_math_arg();
 
-  Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, x, y) );
+  Node* result = NULL;
 
-  // Short form: if not top-level (i.e., Math.pow but inlining Math.pow
-  // inside of something) then skip the fancy tests and just check for
-  // NaN result.
-  Node *result = NULL;
-  if( jvms()->depth() >= 1 ) {
-    result = fast_result;
+  if (!too_many_traps(Deoptimization::Reason_intrinsic)) {
+    // Short form: skip the fancy tests and just check for NaN result.
+    result = _gvn.transform( new (C) PowDNode(0, x, y) );
   } else {
+    // If this inlining ever returned NaN in the past, include all
+    // checks + call to the runtime.
 
     // Set the merge point for If node with condition of (x <= 0.0)
     // There are four possible paths to region node and phi node
-    RegionNode *r = new (C, 4) RegionNode(4);
-    Node *phi = new (C, 4) PhiNode(r, Type::DOUBLE);
+    RegionNode *r = new (C) RegionNode(4);
+    Node *phi = new (C) PhiNode(r, Type::DOUBLE);
 
     // Build the first if node: if (x <= 0.0)
     // Node for 0 constant
     Node *zeronode = makecon(TypeD::ZERO);
     // Check x:0
-    Node *cmp = _gvn.transform(new (C, 3) CmpDNode(x, zeronode));
+    Node *cmp = _gvn.transform(new (C) CmpDNode(x, zeronode));
     // Check: If (x<=0) then go complex path
-    Node *bol1 = _gvn.transform( new (C, 2) BoolNode( cmp, BoolTest::le ) );
+    Node *bol1 = _gvn.transform( new (C) BoolNode( cmp, BoolTest::le ) );
     // Branch either way
     IfNode *if1 = create_and_xform_if(control(),bol1, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
-    Node *opt_test = _gvn.transform(if1);
-    //assert( opt_test->is_If(), "Expect an IfNode");
-    IfNode *opt_if1 = (IfNode*)opt_test;
     // Fast path taken; set region slot 3
-    Node *fast_taken = _gvn.transform( new (C, 1) IfFalseNode(opt_if1) );
+    Node *fast_taken = _gvn.transform( new (C) IfFalseNode(if1) );
     r->init_req(3,fast_taken); // Capture fast-control
 
     // Fast path not-taken, i.e. slow path
-    Node *complex_path = _gvn.transform( new (C, 1) IfTrueNode(opt_if1) );
+    Node *complex_path = _gvn.transform( new (C) IfTrueNode(if1) );
 
     // Set fast path result
-    Node *fast_result = _gvn.transform( new (C, 3) PowDNode(0, y, x) );
+    Node *fast_result = _gvn.transform( new (C) PowDNode(0, x, y) );
     phi->init_req(3, fast_result);
 
     // Complex path
-    // Build the second if node (if y is int)
-    // Node for (int)y
-    Node *inty = _gvn.transform( new (C, 2) ConvD2INode(y));
-    // Node for (double)((int) y)
-    Node *doubleinty= _gvn.transform( new (C, 2) ConvI2DNode(inty));
-    // Check (double)((int) y) : y
-    Node *cmpinty= _gvn.transform(new (C, 3) CmpDNode(doubleinty, y));
-    // Check if (y isn't int) then go to slow path
+    // Build the second if node (if y is long)
+    // Node for (long)y
+    Node *longy = _gvn.transform( new (C) ConvD2LNode(y));
+    // Node for (double)((long) y)
+    Node *doublelongy= _gvn.transform( new (C) ConvL2DNode(longy));
+    // Check (double)((long) y) : y
+    Node *cmplongy= _gvn.transform(new (C) CmpDNode(doublelongy, y));
+    // Check if (y isn't long) then go to slow path
 
-    Node *bol2 = _gvn.transform( new (C, 2) BoolNode( cmpinty, BoolTest::ne ) );
+    Node *bol2 = _gvn.transform( new (C) BoolNode( cmplongy, BoolTest::ne ) );
     // Branch either way
     IfNode *if2 = create_and_xform_if(complex_path,bol2, PROB_STATIC_INFREQUENT, COUNT_UNKNOWN);
-    Node *slow_path = opt_iff(r,if2); // Set region path 2
+    Node* ylong_path = _gvn.transform( new (C) IfFalseNode(if2));
 
-    // Calculate DPow(abs(x), y)*(1 & (int)y)
+    Node *slow_path = _gvn.transform( new (C) IfTrueNode(if2) );
+
+    // Calculate DPow(abs(x), y)*(1 & (long)y)
     // Node for constant 1
-    Node *conone = intcon(1);
-    // 1& (int)y
-    Node *signnode= _gvn.transform( new (C, 3) AndINode(conone, inty) );
+    Node *conone = longcon(1);
+    // 1& (long)y
+    Node *signnode= _gvn.transform( new (C) AndLNode(conone, longy) );
+
+    // A huge number is always even. Detect a huge number by checking
+    // if y + 1 == y and set integer to be tested for parity to 0.
+    // Required for corner case:
+    // (long)9.223372036854776E18 = max_jlong
+    // (double)(long)9.223372036854776E18 = 9.223372036854776E18
+    // max_jlong is odd but 9.223372036854776E18 is even
+    Node* yplus1 = _gvn.transform( new (C) AddDNode(y, makecon(TypeD::make(1))));
+    Node *cmpyplus1= _gvn.transform(new (C) CmpDNode(yplus1, y));
+    Node *bolyplus1 = _gvn.transform( new (C) BoolNode( cmpyplus1, BoolTest::eq ) );
+    Node* correctedsign = NULL;
+    if (ConditionalMoveLimit != 0) {
+      correctedsign = _gvn.transform( CMoveNode::make(C, NULL, bolyplus1, signnode, longcon(0), TypeLong::LONG));
+    } else {
+      IfNode *ifyplus1 = create_and_xform_if(ylong_path,bolyplus1, PROB_FAIR, COUNT_UNKNOWN);
+      RegionNode *r = new (C) RegionNode(3);
+      Node *phi = new (C) PhiNode(r, TypeLong::LONG);
+      r->init_req(1, _gvn.transform( new (C) IfFalseNode(ifyplus1)));
+      r->init_req(2, _gvn.transform( new (C) IfTrueNode(ifyplus1)));
+      phi->init_req(1, signnode);
+      phi->init_req(2, longcon(0));
+      correctedsign = _gvn.transform(phi);
+      ylong_path = _gvn.transform(r);
+      record_for_igvn(r);
+    }
+
     // zero node
-    Node *conzero = intcon(0);
-    // Check (1&(int)y)==0?
-    Node *cmpeq1 = _gvn.transform(new (C, 3) CmpINode(signnode, conzero));
-    // Check if (1&(int)y)!=0?, if so the result is negative
-    Node *bol3 = _gvn.transform( new (C, 2) BoolNode( cmpeq1, BoolTest::ne ) );
+    Node *conzero = longcon(0);
+    // Check (1&(long)y)==0?
+    Node *cmpeq1 = _gvn.transform(new (C) CmpLNode(correctedsign, conzero));
+    // Check if (1&(long)y)!=0?, if so the result is negative
+    Node *bol3 = _gvn.transform( new (C) BoolNode( cmpeq1, BoolTest::ne ) );
     // abs(x)
-    Node *absx=_gvn.transform( new (C, 2) AbsDNode(x));
+    Node *absx=_gvn.transform( new (C) AbsDNode(x));
     // abs(x)^y
-    Node *absxpowy = _gvn.transform( new (C, 3) PowDNode(0, y, absx) );
+    Node *absxpowy = _gvn.transform( new (C) PowDNode(0, absx, y) );
     // -abs(x)^y
-    Node *negabsxpowy = _gvn.transform(new (C, 2) NegDNode (absxpowy));
-    // (1&(int)y)==1?-DPow(abs(x), y):DPow(abs(x), y)
-    Node *signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE));
+    Node *negabsxpowy = _gvn.transform(new (C) NegDNode (absxpowy));
+    // (1&(long)y)==1?-DPow(abs(x), y):DPow(abs(x), y)
+    Node *signresult = NULL;
+    if (ConditionalMoveLimit != 0) {
+      signresult = _gvn.transform( CMoveNode::make(C, NULL, bol3, absxpowy, negabsxpowy, Type::DOUBLE));
+    } else {
+      IfNode *ifyeven = create_and_xform_if(ylong_path,bol3, PROB_FAIR, COUNT_UNKNOWN);
+      RegionNode *r = new (C) RegionNode(3);
+      Node *phi = new (C) PhiNode(r, Type::DOUBLE);
+      r->init_req(1, _gvn.transform( new (C) IfFalseNode(ifyeven)));
+      r->init_req(2, _gvn.transform( new (C) IfTrueNode(ifyeven)));
+      phi->init_req(1, absxpowy);
+      phi->init_req(2, negabsxpowy);
+      signresult = _gvn.transform(phi);
+      ylong_path = _gvn.transform(r);
+      record_for_igvn(r);
+    }
     // Set complex path fast result
+    r->init_req(2, ylong_path);
     phi->init_req(2, signresult);
 
     static const jlong nan_bits = CONST64(0x7ff8000000000000);
@@ -1675,27 +1922,10 @@
     result=_gvn.transform(phi);
   }
 
-  //-------------------
-  //result=(result.isNaN())? uncommon_trap():result;
-  // Check: If isNaN() by checking result!=result? then go to Strict Math
-  Node* cmpisnan = _gvn.transform(new (C, 3) CmpDNode(result,result));
-  // Build the boolean node
-  Node* bolisnum = _gvn.transform( new (C, 2) BoolNode(cmpisnan, BoolTest::eq) );
-
-  { BuildCutout unless(this, bolisnum, PROB_STATIC_FREQUENT);
-    // End the current control-flow path
-    push_pair(x);
-    push_pair(y);
-    // Math.pow intrinsic returned a NaN, which requires StrictMath.pow
-    // to handle.  Recompile without intrinsifying Math.pow.
-    uncommon_trap(Deoptimization::Reason_intrinsic,
-                  Deoptimization::Action_make_not_entrant);
-  }
+  finish_pow_exp(result, x, y, OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
 
   C->set_has_split_ifs(true); // Has chance for split-if optimization
 
-  push_pair(result);
-
   return true;
 }
 
@@ -1709,10 +1939,10 @@
 
   switch (id) {
   case vmIntrinsics::_dlog:
-    trans = _gvn.transform((Node*)new (C, 2) LogDNode(arg));
+    trans = _gvn.transform((Node*)new (C) LogDNode(arg));
     break;
   case vmIntrinsics::_dlog10:
-    trans = _gvn.transform((Node*)new (C, 2) Log10DNode(arg));
+    trans = _gvn.transform((Node*)new (C) Log10DNode(arg));
     break;
   default:
     assert(false, "bad intrinsic was passed in");
@@ -1743,9 +1973,9 @@
   Node* trig = make_runtime_call(RC_LEAF, call_type, funcAddr, funcName,
                                  no_memory_effects,
                                  a, top(), b, b ? top() : NULL);
-  Node* value = _gvn.transform(new (C, 1) ProjNode(trig, TypeFunc::Parms+0));
+  Node* value = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+0));
 #ifdef ASSERT
-  Node* value_top = _gvn.transform(new (C, 1) ProjNode(trig, TypeFunc::Parms+1));
+  Node* value_top = _gvn.transform(new (C) ProjNode(trig, TypeFunc::Parms+1));
   assert(value_top == top(), "second value must be top");
 #endif
 
@@ -1773,15 +2003,11 @@
   case vmIntrinsics::_dsqrt: return Matcher::has_match_rule(Op_SqrtD) ? inline_sqrt(id) : false;
   case vmIntrinsics::_dabs:  return Matcher::has_match_rule(Op_AbsD)  ? inline_abs(id)  : false;
 
-    // These intrinsics don't work on X86.  The ad implementation doesn't
-    // handle NaN's properly.  Instead of returning infinity, the ad
-    // implementation returns a NaN on overflow. See bug: 6304089
-    // Once the ad implementations are fixed, change the code below
-    // to match the intrinsics above
-
   case vmIntrinsics::_dexp:  return
+    Matcher::has_match_rule(Op_ExpD) ? inline_exp(id) :
     runtime_math(OptoRuntime::Math_D_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dexp), "EXP");
   case vmIntrinsics::_dpow:  return
+    Matcher::has_match_rule(Op_PowD) ? inline_pow(id) :
     runtime_math(OptoRuntime::Math_DD_D_Type(), CAST_FROM_FN_PTR(address, SharedRuntime::dpow), "POW");
 
    // These intrinsics are not yet correctly implemented
@@ -1840,7 +2066,7 @@
   int   cmp_op = Op_CmpI;
   Node* xkey = xvalue;
   Node* ykey = yvalue;
-  Node* ideal_cmpxy = _gvn.transform( new(C, 3) CmpINode(xkey, ykey) );
+  Node* ideal_cmpxy = _gvn.transform( new(C) CmpINode(xkey, ykey) );
   if (ideal_cmpxy->is_Cmp()) {
     // E.g., if we have CmpI(length - offset, count),
     // it might idealize to CmpI(length, count + offset)
@@ -1933,7 +2159,7 @@
   default:
     if (cmpxy == NULL)
       cmpxy = ideal_cmpxy;
-    best_bol = _gvn.transform( new(C, 2) BoolNode(cmpxy, BoolTest::lt) );
+    best_bol = _gvn.transform( new(C) BoolNode(cmpxy, BoolTest::lt) );
     // and fall through:
   case BoolTest::lt:          // x < y
   case BoolTest::le:          // x <= y
@@ -1993,7 +2219,7 @@
     return Type::AnyPtr;
   } else if (base_type == TypePtr::NULL_PTR) {
     // Since this is a NULL+long form, we have to switch to a rawptr.
-    base   = _gvn.transform( new (C, 2) CastX2PNode(offset) );
+    base   = _gvn.transform( new (C) CastX2PNode(offset) );
     offset = MakeConX(0);
     return Type::RawPtr;
   } else if (base_type->base() == Type::RawPtr) {
@@ -2038,10 +2264,10 @@
   _sp += arg_size();  // restore stack pointer
   switch (id) {
   case vmIntrinsics::_numberOfLeadingZeros_i:
-    push(_gvn.transform(new (C, 2) CountLeadingZerosINode(pop())));
+    push(_gvn.transform(new (C) CountLeadingZerosINode(pop())));
     break;
   case vmIntrinsics::_numberOfLeadingZeros_l:
-    push(_gvn.transform(new (C, 2) CountLeadingZerosLNode(pop_pair())));
+    push(_gvn.transform(new (C) CountLeadingZerosLNode(pop_pair())));
     break;
   default:
     ShouldNotReachHere();
@@ -2059,10 +2285,10 @@
   _sp += arg_size();  // restore stack pointer
   switch (id) {
   case vmIntrinsics::_numberOfTrailingZeros_i:
-    push(_gvn.transform(new (C, 2) CountTrailingZerosINode(pop())));
+    push(_gvn.transform(new (C) CountTrailingZerosINode(pop())));
     break;
   case vmIntrinsics::_numberOfTrailingZeros_l:
-    push(_gvn.transform(new (C, 2) CountTrailingZerosLNode(pop_pair())));
+    push(_gvn.transform(new (C) CountTrailingZerosLNode(pop_pair())));
     break;
   default:
     ShouldNotReachHere();
@@ -2080,10 +2306,10 @@
   _sp += arg_size();  // restore stack pointer
   switch (id) {
   case vmIntrinsics::_bitCount_i:
-    push(_gvn.transform(new (C, 2) PopCountINode(pop())));
+    push(_gvn.transform(new (C) PopCountINode(pop())));
     break;
   case vmIntrinsics::_bitCount_l:
-    push(_gvn.transform(new (C, 2) PopCountLNode(pop_pair())));
+    push(_gvn.transform(new (C) PopCountLNode(pop_pair())));
     break;
   default:
     ShouldNotReachHere();
@@ -2104,19 +2330,19 @@
   if (id == vmIntrinsics::_reverseBytes_l && !Matcher::has_match_rule(Op_ReverseBytesL))  return false;
   if (id == vmIntrinsics::_reverseBytes_c && !Matcher::has_match_rule(Op_ReverseBytesUS)) return false;
   if (id == vmIntrinsics::_reverseBytes_s && !Matcher::has_match_rule(Op_ReverseBytesS))  return false;
-  _sp += arg_size();        // restore stack pointer
+  _sp += arg_size();  // restore stack pointer
   switch (id) {
   case vmIntrinsics::_reverseBytes_i:
-    push(_gvn.transform(new (C, 2) ReverseBytesINode(0, pop())));
+    push(_gvn.transform(new (C) ReverseBytesINode(0, pop())));
     break;
   case vmIntrinsics::_reverseBytes_l:
-    push_pair(_gvn.transform(new (C, 2) ReverseBytesLNode(0, pop_pair())));
+    push_pair(_gvn.transform(new (C) ReverseBytesLNode(0, pop_pair())));
     break;
   case vmIntrinsics::_reverseBytes_c:
-    push(_gvn.transform(new (C, 2) ReverseBytesUSNode(0, pop())));
+    push(_gvn.transform(new (C) ReverseBytesUSNode(0, pop())));
     break;
   case vmIntrinsics::_reverseBytes_s:
-    push(_gvn.transform(new (C, 2) ReverseBytesSNode(0, pop())));
+    push(_gvn.transform(new (C) ReverseBytesSNode(0, pop())));
     break;
   default:
     ;
@@ -2128,14 +2354,17 @@
 
 const static BasicType T_ADDRESS_HOLDER = T_LONG;
 
-// Helper that guards and inserts a G1 pre-barrier.
-void LibraryCallKit::insert_g1_pre_barrier(Node* base_oop, Node* offset, Node* pre_val) {
-  assert(UseG1GC, "should not call this otherwise");
-
+// Helper that guards and inserts a pre-barrier.
+void LibraryCallKit::insert_pre_barrier(Node* base_oop, Node* offset,
+                                        Node* pre_val, int nargs, bool need_mem_bar) {
   // We could be accessing the referent field of a reference object. If so, when G1
   // is enabled, we need to log the value in the referent field in an SATB buffer.
   // This routine performs some compile time filters and generates suitable
   // runtime filters that guard the pre-barrier code.
+  // Also add memory barrier for non volatile load from the referent field
+  // to prevent commoning of loads across safepoint.
+  if (!UseG1GC && !need_mem_bar)
+    return;
 
   // Some compile time checks.
 
@@ -2157,11 +2386,12 @@
 
     const TypeInstPtr* itype = btype->isa_instptr();
     if (itype != NULL) {
-      // Can the klass of base_oop be statically determined
-      // to be _not_ a sub-class of Reference?
+      // Can the klass of base_oop be statically determined to be
+      // _not_ a sub-class of Reference and _not_ Object?
       ciKlass* klass = itype->klass();
-      if (klass->is_subtype_of(env()->Reference_klass()) &&
-          !env()->Reference_klass()->is_subtype_of(klass)) {
+      if ( klass->is_loaded() &&
+          !klass->is_subtype_of(env()->Reference_klass()) &&
+          !env()->Object_klass()->is_subtype_of(klass)) {
         return;
       }
     }
@@ -2171,10 +2401,8 @@
   // we need to generate the following runtime filters
   //
   // if (offset == java_lang_ref_Reference::_reference_offset) {
-  //   if (base != null) {
-  //     if (instance_of(base, java.lang.ref.Reference)) {
-  //       pre_barrier(_, pre_val, ...);
-  //     }
+  //   if (instance_of(base, java.lang.ref.Reference)) {
+  //     pre_barrier(_, pre_val, ...);
   //   }
   // }
 
@@ -2187,19 +2415,19 @@
   Node* referent_off = __ ConX(java_lang_ref_Reference::referent_offset);
 
   __ if_then(offset, BoolTest::eq, referent_off, unlikely); {
-    __ if_then(base_oop, BoolTest::ne, null(), likely); {
-
       // Update graphKit memory and control from IdealKit.
       sync_kit(ideal);
 
       Node* ref_klass_con = makecon(TypeKlassPtr::make(env()->Reference_klass()));
+      _sp += nargs;  // gen_instanceof might do an uncommon trap
       Node* is_instof = gen_instanceof(base_oop, ref_klass_con);
+      _sp -= nargs;
 
       // Update IdealKit memory and control from graphKit.
       __ sync_kit(this);
 
       Node* one = __ ConI(1);
-
+      // is_instof == 0 if base_oop == NULL
       __ if_then(is_instof, BoolTest::eq, one, unlikely); {
 
         // Update graphKit from IdeakKit.
@@ -2211,12 +2439,15 @@
                     NULL /* obj */, NULL /* adr */, max_juint /* alias_idx */, NULL /* val */, NULL /* val_type */,
                     pre_val /* pre_val */,
                     T_OBJECT);
-
+        if (need_mem_bar) {
+          // Add memory barrier to prevent commoning reads from this field
+          // across safepoint since GC can change its value.
+          insert_mem_bar(Op_MemBarCPUOrder);
+        }
         // Update IdealKit from graphKit.
         __ sync_kit(this);
 
       } __ end_if(); // _ref_type != ref_none
-    } __ end_if(); // base  != NULL
   } __ end_if(); // offset == referent_offset
 
   // Final sync IdealKit and GraphKit.
@@ -2228,6 +2459,45 @@
 // Interpret Unsafe.fieldOffset cookies correctly:
 extern jlong Unsafe_field_offset_to_byte_offset(jlong field_offset);
 
+const TypeOopPtr* LibraryCallKit::sharpen_unsafe_type(Compile::AliasType* alias_type, const TypePtr *adr_type, bool is_native_ptr) {
+  // Attempt to infer a sharper value type from the offset and base type.
+  ciKlass* sharpened_klass = NULL;
+
+  // See if it is an instance field, with an object type.
+  if (alias_type->field() != NULL) {
+    assert(!is_native_ptr, "native pointer op cannot use a java address");
+    if (alias_type->field()->type()->is_klass()) {
+      sharpened_klass = alias_type->field()->type()->as_klass();
+    }
+  }
+
+  // See if it is a narrow oop array.
+  if (adr_type->isa_aryptr()) {
+    if (adr_type->offset() >= objArrayOopDesc::base_offset_in_bytes()) {
+      const TypeOopPtr *elem_type = adr_type->is_aryptr()->elem()->isa_oopptr();
+      if (elem_type != NULL) {
+        sharpened_klass = elem_type->klass();
+      }
+    }
+  }
+
+  // The sharpened class might be unloaded if there is no class loader
+  // contraint in place.
+  if (sharpened_klass != NULL && sharpened_klass->is_loaded()) {
+    const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass);
+
+#ifndef PRODUCT
+    if (PrintIntrinsics || PrintInlining || PrintOptoInlining) {
+      tty->print("  from base type: ");  adr_type->dump();
+      tty->print("  sharpened value: ");  tjp->dump();
+    }
+#endif
+    // Sharpen the value type.
+    return tjp;
+  }
+  return NULL;
+}
+
 bool LibraryCallKit::inline_unsafe_access(bool is_native_ptr, bool is_store, BasicType type, bool is_volatile) {
   if (callee()->is_static())  return false;  // caller must have the capability!
 
@@ -2277,6 +2547,7 @@
 
   // Argument words:  "this" plus (oop/offset) or (lo/hi) args plus maybe 1 or 2 value words
   int nargs = 1 + (is_native_ptr ? 2 : 3) + (is_store ? type_words : 0);
+  assert(callee()->arg_size() == nargs, "must be");
 
   debug_only(int saved_sp = _sp);
   _sp += nargs;
@@ -2350,43 +2621,15 @@
   // object (either by using Unsafe directly or through reflection)
   // then, if G1 is enabled, we need to record the referent in an
   // SATB log buffer using the pre-barrier mechanism.
-  bool need_read_barrier = UseG1GC && !is_native_ptr && !is_store &&
+  // Also we need to add memory barrier to prevent commoning reads
+  // from this field across safepoint since GC can change its value.
+  bool need_read_barrier = !is_native_ptr && !is_store &&
                            offset != top() && heap_base_oop != top();
 
   if (!is_store && type == T_OBJECT) {
-    // Attempt to infer a sharper value type from the offset and base type.
-    ciKlass* sharpened_klass = NULL;
-
-    // See if it is an instance field, with an object type.
-    if (alias_type->field() != NULL) {
-      assert(!is_native_ptr, "native pointer op cannot use a java address");
-      if (alias_type->field()->type()->is_klass()) {
-        sharpened_klass = alias_type->field()->type()->as_klass();
-      }
-    }
-
-    // See if it is a narrow oop array.
-    if (adr_type->isa_aryptr()) {
-      if (adr_type->offset() >= objArrayOopDesc::base_offset_in_bytes()) {
-        const TypeOopPtr *elem_type = adr_type->is_aryptr()->elem()->isa_oopptr();
-        if (elem_type != NULL) {
-          sharpened_klass = elem_type->klass();
-        }
-      }
-    }
-
-    if (sharpened_klass != NULL) {
-      const TypeOopPtr* tjp = TypeOopPtr::make_from_klass(sharpened_klass);
-
-      // Sharpen the value type.
+    const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type, is_native_ptr);
+    if (tjp != NULL) {
       value_type = tjp;
-
-#ifndef PRODUCT
-      if (PrintIntrinsics || PrintInlining || PrintOptoInlining) {
-        tty->print("  from base type:  ");   adr_type->dump();
-        tty->print("  sharpened value: "); value_type->dump();
-      }
-#endif
     }
   }
 
@@ -2440,13 +2683,13 @@
       break;
     case T_OBJECT:
       if (need_read_barrier) {
-        insert_g1_pre_barrier(heap_base_oop, offset, p);
+        insert_pre_barrier(heap_base_oop, offset, p, nargs, !(is_volatile || need_mem_bar));
       }
       push(p);
       break;
     case T_ADDRESS:
       // Cast to an int type.
-      p = _gvn.transform( new (C, 2) CastP2XNode(NULL,p) );
+      p = _gvn.transform( new (C) CastP2XNode(NULL,p) );
       p = ConvX2L(p);
       push_pair(p);
       break;
@@ -2465,7 +2708,7 @@
     case T_ADDRESS:
       // Repackage the long as a pointer.
       val = ConvL2X(val);
-      val = _gvn.transform( new (C, 2) CastX2PNode(val) );
+      val = _gvn.transform( new (C) CastX2PNode(val) );
       break;
     }
 
@@ -2587,9 +2830,9 @@
   // Generate the read or write prefetch
   Node *prefetch;
   if (is_store) {
-    prefetch = new (C, 3) PrefetchWriteNode(i_o(), adr);
+    prefetch = new (C) PrefetchWriteNode(i_o(), adr);
   } else {
-    prefetch = new (C, 3) PrefetchReadNode(i_o(), adr);
+    prefetch = new (C) PrefetchReadNode(i_o(), adr);
   }
   prefetch->init_req(0, control());
   set_i_o(_gvn.transform(prefetch));
@@ -2597,9 +2840,9 @@
   return true;
 }
 
-//----------------------------inline_unsafe_CAS----------------------------
+//----------------------------inline_unsafe_load_store----------------------------
 
-bool LibraryCallKit::inline_unsafe_CAS(BasicType type) {
+bool LibraryCallKit::inline_unsafe_load_store(BasicType type, LoadStoreKind kind) {
   // This basic scheme here is the same as inline_unsafe_access, but
   // differs in enough details that combining them would make the code
   // overly confusing.  (This is a true fact! I originally combined
@@ -2610,37 +2853,47 @@
   if (callee()->is_static())  return false;  // caller must have the capability!
 
 #ifndef PRODUCT
+  BasicType rtype;
   {
     ResourceMark rm;
-    // Check the signatures.
     ciSignature* sig = signature();
+    rtype = sig->return_type()->basic_type();
+    if (kind == LS_xadd || kind == LS_xchg) {
+      // Check the signatures.
 #ifdef ASSERT
-    BasicType rtype = sig->return_type()->basic_type();
-    assert(rtype == T_BOOLEAN, "CAS must return boolean");
-    assert(sig->count() == 4, "CAS has 4 arguments");
-    assert(sig->type_at(0)->basic_type() == T_OBJECT, "CAS base is object");
-    assert(sig->type_at(1)->basic_type() == T_LONG, "CAS offset is long");
+      assert(rtype == type, "get and set must return the expected type");
+      assert(sig->count() == 3, "get and set has 3 arguments");
+      assert(sig->type_at(0)->basic_type() == T_OBJECT, "get and set base is object");
+      assert(sig->type_at(1)->basic_type() == T_LONG, "get and set offset is long");
+      assert(sig->type_at(2)->basic_type() == type, "get and set must take expected type as new value/delta");
 #endif // ASSERT
+    } else if (kind == LS_cmpxchg) {
+      // Check the signatures.
+#ifdef ASSERT
+      assert(rtype == T_BOOLEAN, "CAS must return boolean");
+      assert(sig->count() == 4, "CAS has 4 arguments");
+      assert(sig->type_at(0)->basic_type() == T_OBJECT, "CAS base is object");
+      assert(sig->type_at(1)->basic_type() == T_LONG, "CAS offset is long");
+#endif // ASSERT
+    } else {
+      ShouldNotReachHere();
+    }
   }
 #endif //PRODUCT
 
   // number of stack slots per value argument (1 or 2)
   int type_words = type2size[type];
 
-  // Cannot inline wide CAS on machines that don't support it natively
-  if (type2aelembytes(type) > BytesPerInt && !VM_Version::supports_cx8())
-    return false;
-
   C->set_has_unsafe_access(true);  // Mark eventual nmethod as "unsafe".
 
-  // Argument words:  "this" plus oop plus offset plus oldvalue plus newvalue;
-  int nargs = 1 + 1 + 2  + type_words + type_words;
+  // Argument words:  "this" plus oop plus offset (plus oldvalue) plus newvalue/delta;
+  int nargs = 1 + 1 + 2  + ((kind == LS_cmpxchg) ? type_words : 0) + type_words;
 
-  // pop arguments: newval, oldval, offset, base, and receiver
+  // pop arguments: newval, offset, base, and receiver
   debug_only(int saved_sp = _sp);
   _sp += nargs;
   Node* newval   = (type_words == 1) ? pop() : pop_pair();
-  Node* oldval   = (type_words == 1) ? pop() : pop_pair();
+  Node* oldval   = (kind == LS_cmpxchg) ? ((type_words == 1) ? pop() : pop_pair()) : NULL;
   Node *offset   = pop_pair();
   Node *base     = pop();
   Node *receiver = pop();
@@ -2664,16 +2917,24 @@
   Node* adr = make_unsafe_address(base, offset);
   const TypePtr *adr_type = _gvn.type(adr)->isa_ptr();
 
-  // (Unlike inline_unsafe_access, there seems no point in trying
-  // to refine types. Just use the coarse types here.
+  // For CAS, unlike inline_unsafe_access, there seems no point in
+  // trying to refine types. Just use the coarse types here.
   const Type *value_type = Type::get_const_basic_type(type);
   Compile::AliasType* alias_type = C->alias_type(adr_type);
   assert(alias_type->index() != Compile::AliasIdxBot, "no bare pointers here");
+
+  if (kind == LS_xchg && type == T_OBJECT) {
+    const TypeOopPtr* tjp = sharpen_unsafe_type(alias_type, adr_type);
+    if (tjp != NULL) {
+      value_type = tjp;
+    }
+  }
+
   int alias_idx = C->get_alias_index(adr_type);
 
-  // Memory-model-wise, a CAS acts like a little synchronized block,
-  // so needs barriers on each side.  These don't translate into
-  // actual barriers on most machines, but we still need rest of
+  // Memory-model-wise, a LoadStore acts like a little synchronized
+  // block, so needs barriers on each side.  These don't translate
+  // into actual barriers on most machines, but we still need rest of
   // compiler to respect ordering.
 
   insert_mem_bar(Op_MemBarRelease);
@@ -2686,13 +2947,29 @@
 
   // For now, we handle only those cases that actually exist: ints,
   // longs, and Object. Adding others should be straightforward.
-  Node* cas;
+  Node* load_store;
   switch(type) {
   case T_INT:
-    cas = _gvn.transform(new (C, 5) CompareAndSwapINode(control(), mem, adr, newval, oldval));
+    if (kind == LS_xadd) {
+      load_store = _gvn.transform(new (C) GetAndAddINode(control(), mem, adr, newval, adr_type));
+    } else if (kind == LS_xchg) {
+      load_store = _gvn.transform(new (C) GetAndSetINode(control(), mem, adr, newval, adr_type));
+    } else if (kind == LS_cmpxchg) {
+      load_store = _gvn.transform(new (C) CompareAndSwapINode(control(), mem, adr, newval, oldval));
+    } else {
+      ShouldNotReachHere();
+    }
     break;
   case T_LONG:
-    cas = _gvn.transform(new (C, 5) CompareAndSwapLNode(control(), mem, adr, newval, oldval));
+    if (kind == LS_xadd) {
+      load_store = _gvn.transform(new (C) GetAndAddLNode(control(), mem, adr, newval, adr_type));
+    } else if (kind == LS_xchg) {
+      load_store = _gvn.transform(new (C) GetAndSetLNode(control(), mem, adr, newval, adr_type));
+    } else if (kind == LS_cmpxchg) {
+      load_store = _gvn.transform(new (C) CompareAndSwapLNode(control(), mem, adr, newval, oldval));
+    } else {
+      ShouldNotReachHere();
+    }
     break;
   case T_OBJECT:
     // Transformation of a value which could be NULL pointer (CastPP #NULL)
@@ -2702,40 +2979,57 @@
       newval = _gvn.makecon(TypePtr::NULL_PTR);
 
     // Reference stores need a store barrier.
-    // (They don't if CAS fails, but it isn't worth checking.)
     pre_barrier(true /* do_load*/,
                 control(), base, adr, alias_idx, newval, value_type->make_oopptr(),
                 NULL /* pre_val*/,
                 T_OBJECT);
 #ifdef _LP64
     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
-      Node *newval_enc = _gvn.transform(new (C, 2) EncodePNode(newval, newval->bottom_type()->make_narrowoop()));
-      Node *oldval_enc = _gvn.transform(new (C, 2) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop()));
-      cas = _gvn.transform(new (C, 5) CompareAndSwapNNode(control(), mem, adr,
-                                                          newval_enc, oldval_enc));
+      Node *newval_enc = _gvn.transform(new (C) EncodePNode(newval, newval->bottom_type()->make_narrowoop()));
+      if (kind == LS_xchg) {
+        load_store = _gvn.transform(new (C) GetAndSetNNode(control(), mem, adr,
+                                                              newval_enc, adr_type, value_type->make_narrowoop()));
+      } else {
+        assert(kind == LS_cmpxchg, "wrong LoadStore operation");
+        Node *oldval_enc = _gvn.transform(new (C) EncodePNode(oldval, oldval->bottom_type()->make_narrowoop()));
+        load_store = _gvn.transform(new (C) CompareAndSwapNNode(control(), mem, adr,
+                                                                   newval_enc, oldval_enc));
+      }
     } else
 #endif
     {
-      cas = _gvn.transform(new (C, 5) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
+      if (kind == LS_xchg) {
+        load_store = _gvn.transform(new (C) GetAndSetPNode(control(), mem, adr, newval, adr_type, value_type->is_oopptr()));
+      } else {
+        assert(kind == LS_cmpxchg, "wrong LoadStore operation");
+        load_store = _gvn.transform(new (C) CompareAndSwapPNode(control(), mem, adr, newval, oldval));
+      }
     }
-    post_barrier(control(), cas, base, adr, alias_idx, newval, T_OBJECT, true);
+    post_barrier(control(), load_store, base, adr, alias_idx, newval, T_OBJECT, true);
     break;
   default:
     ShouldNotReachHere();
     break;
   }
 
-  // SCMemProjNodes represent the memory state of CAS. Their main
-  // role is to prevent CAS nodes from being optimized away when their
-  // results aren't used.
-  Node* proj = _gvn.transform( new (C, 1) SCMemProjNode(cas));
+  // SCMemProjNodes represent the memory state of a LoadStore. Their
+  // main role is to prevent LoadStore nodes from being optimized away
+  // when their results aren't used.
+  Node* proj = _gvn.transform( new (C) SCMemProjNode(load_store));
   set_memory(proj, alias_idx);
 
   // Add the trailing membar surrounding the access
   insert_mem_bar(Op_MemBarCPUOrder);
   insert_mem_bar(Op_MemBarAcquire);
 
-  push(cas);
+#ifdef _LP64
+  if (type == T_OBJECT && adr->bottom_type()->is_ptr_to_narrowoop() && kind == LS_xchg) {
+    load_store = _gvn.transform(new (C) DecodeNNode(load_store, load_store->bottom_type()->make_ptr()));
+  }
+#endif
+
+  assert(type2size[load_store->bottom_type()->basic_type()] == type2size[rtype], "result type should match");
+  push_node(load_store->bottom_type()->basic_type(), load_store);
   return true;
 }
 
@@ -2833,7 +3127,7 @@
   // can generate code to load it as unsigned byte.
   Node* inst = make_load(NULL, insp, TypeInt::UBYTE, T_BOOLEAN);
   Node* bits = intcon(instanceKlass::fully_initialized);
-  Node* test = _gvn.transform( new (C, 3) SubINode(inst, bits) );
+  Node* test = _gvn.transform( new (C) SubINode(inst, bits) );
   // The 'test' is non-zero if we need to take a slow path.
 
   Node* obj = new_instance(kls, test);
@@ -2842,19 +3136,68 @@
   return true;
 }
 
+#ifdef TRACE_HAVE_INTRINSICS
+/*
+ * oop -> myklass
+ * myklass->trace_id |= USED
+ * return myklass->trace_id & ~0x3
+ */
+bool LibraryCallKit::inline_native_classID() {
+  int nargs = 1 + 1;
+  null_check_receiver(callee());  // check then ignore argument(0)
+  _sp += nargs;
+  Node* cls = do_null_check(argument(1), T_OBJECT);
+  _sp -= nargs;
+  Node* kls = load_klass_from_mirror(cls, false, nargs, NULL, 0);
+  _sp += nargs;
+  kls = do_null_check(kls, T_OBJECT);
+  _sp -= nargs;
+  ByteSize offset = TRACE_ID_OFFSET;
+  Node* insp = basic_plus_adr(kls, in_bytes(offset));
+  Node* tvalue = make_load(NULL, insp, TypeLong::LONG, T_LONG);
+  Node* bits = longcon(~0x03l); // ignore bit 0 & 1
+  Node* andl = _gvn.transform(new (C) AndLNode(tvalue, bits));
+  Node* clsused = longcon(0x01l); // set the class bit
+  Node* orl = _gvn.transform(new (C) OrLNode(tvalue, clsused));
+
+  const TypePtr *adr_type = _gvn.type(insp)->isa_ptr();
+  store_to_memory(control(), insp, orl, T_LONG, adr_type);
+  push_pair(andl);
+  return true;
+}
+
+bool LibraryCallKit::inline_native_threadID() {
+  Node* tls_ptr = NULL;
+  Node* cur_thr = generate_current_thread(tls_ptr);
+  Node* p = basic_plus_adr(top()/*!oop*/, tls_ptr, in_bytes(JavaThread::osthread_offset()));
+  Node* osthread = make_load(NULL, p, TypeRawPtr::NOTNULL, T_ADDRESS);
+  p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::thread_id_offset()));
+
+  Node* threadid = NULL;
+  size_t thread_id_size = OSThread::thread_id_size();
+  if (thread_id_size == (size_t) BytesPerLong) {
+    threadid = ConvL2I(make_load(control(), p, TypeLong::LONG, T_LONG));
+    push(threadid);
+  } else if (thread_id_size == (size_t) BytesPerInt) {
+    threadid = make_load(control(), p, TypeInt::INT, T_INT);
+    push(threadid);
+  } else {
+    ShouldNotReachHere();
+  }
+  return true;
+}
+#endif
+
 //------------------------inline_native_time_funcs--------------
 // inline code for System.currentTimeMillis() and System.nanoTime()
 // these have the same type and signature
-bool LibraryCallKit::inline_native_time_funcs(bool isNano) {
-  address funcAddr = isNano ? CAST_FROM_FN_PTR(address, os::javaTimeNanos) :
-                              CAST_FROM_FN_PTR(address, os::javaTimeMillis);
-  const char * funcName = isNano ? "nanoTime" : "currentTimeMillis";
-  const TypeFunc *tf = OptoRuntime::current_time_millis_Type();
+bool LibraryCallKit::inline_native_time_funcs(address funcAddr, const char* funcName) {
+  const TypeFunc *tf = OptoRuntime::void_long_Type();
   const TypePtr* no_memory_effects = NULL;
   Node* time = make_runtime_call(RC_LEAF, tf, funcAddr, funcName, no_memory_effects);
-  Node* value = _gvn.transform(new (C, 1) ProjNode(time, TypeFunc::Parms+0));
+  Node* value = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms+0));
 #ifdef ASSERT
-  Node* value_top = _gvn.transform(new (C, 1) ProjNode(time, TypeFunc::Parms + 1));
+  Node* value_top = _gvn.transform(new (C) ProjNode(time, TypeFunc::Parms + 1));
   assert(value_top == top(), "second value must be top");
 #endif
   push_pair(value);
@@ -2883,10 +3226,10 @@
 
   // We only go to the fast case code if we pass two guards.
   // Paths which do not pass are accumulated in the slow_region.
-  RegionNode* slow_region = new (C, 1) RegionNode(1);
+  RegionNode* slow_region = new (C) RegionNode(1);
   record_for_igvn(slow_region);
-  RegionNode* result_rgn = new (C, 4) RegionNode(1+3); // fast1, fast2, slow
-  PhiNode*    result_val = new (C, 4) PhiNode(result_rgn, TypeInt::BOOL);
+  RegionNode* result_rgn = new (C) RegionNode(1+3); // fast1, fast2, slow
+  PhiNode*    result_val = new (C) PhiNode(result_rgn, TypeInt::BOOL);
   enum { no_int_result_path   = 1,
          no_clear_result_path = 2,
          slow_result_path     = 3
@@ -2896,8 +3239,8 @@
   Node* rec_thr = argument(0);
   Node* tls_ptr = NULL;
   Node* cur_thr = generate_current_thread(tls_ptr);
-  Node* cmp_thr = _gvn.transform( new (C, 3) CmpPNode(cur_thr, rec_thr) );
-  Node* bol_thr = _gvn.transform( new (C, 2) BoolNode(cmp_thr, BoolTest::ne) );
+  Node* cmp_thr = _gvn.transform( new (C) CmpPNode(cur_thr, rec_thr) );
+  Node* bol_thr = _gvn.transform( new (C) BoolNode(cmp_thr, BoolTest::ne) );
 
   bool known_current_thread = (_gvn.type(bol_thr) == TypeInt::ZERO);
   if (!known_current_thread)
@@ -2909,32 +3252,32 @@
   p = basic_plus_adr(top()/*!oop*/, osthread, in_bytes(OSThread::interrupted_offset()));
   // Set the control input on the field _interrupted read to prevent it floating up.
   Node* int_bit = make_load(control(), p, TypeInt::BOOL, T_INT);
-  Node* cmp_bit = _gvn.transform( new (C, 3) CmpINode(int_bit, intcon(0)) );
-  Node* bol_bit = _gvn.transform( new (C, 2) BoolNode(cmp_bit, BoolTest::ne) );
+  Node* cmp_bit = _gvn.transform( new (C) CmpINode(int_bit, intcon(0)) );
+  Node* bol_bit = _gvn.transform( new (C) BoolNode(cmp_bit, BoolTest::ne) );
 
   IfNode* iff_bit = create_and_map_if(control(), bol_bit, PROB_UNLIKELY_MAG(3), COUNT_UNKNOWN);
 
   // First fast path:  if (!TLS._interrupted) return false;
-  Node* false_bit = _gvn.transform( new (C, 1) IfFalseNode(iff_bit) );
+  Node* false_bit = _gvn.transform( new (C) IfFalseNode(iff_bit) );
   result_rgn->init_req(no_int_result_path, false_bit);
   result_val->init_req(no_int_result_path, intcon(0));
 
   // drop through to next case
-  set_control( _gvn.transform(new (C, 1) IfTrueNode(iff_bit)) );
+  set_control( _gvn.transform(new (C) IfTrueNode(iff_bit)) );
 
   // (c) Or, if interrupt bit is set and clear_int is false, use 2nd fast path.
   Node* clr_arg = argument(1);
-  Node* cmp_arg = _gvn.transform( new (C, 3) CmpINode(clr_arg, intcon(0)) );
-  Node* bol_arg = _gvn.transform( new (C, 2) BoolNode(cmp_arg, BoolTest::ne) );
+  Node* cmp_arg = _gvn.transform( new (C) CmpINode(clr_arg, intcon(0)) );
+  Node* bol_arg = _gvn.transform( new (C) BoolNode(cmp_arg, BoolTest::ne) );
   IfNode* iff_arg = create_and_map_if(control(), bol_arg, PROB_FAIR, COUNT_UNKNOWN);
 
   // Second fast path:  ... else if (!clear_int) return true;
-  Node* false_arg = _gvn.transform( new (C, 1) IfFalseNode(iff_arg) );
+  Node* false_arg = _gvn.transform( new (C) IfFalseNode(iff_arg) );
   result_rgn->init_req(no_clear_result_path, false_arg);
   result_val->init_req(no_clear_result_path, intcon(1));
 
   // drop through to next case
-  set_control( _gvn.transform(new (C, 1) IfTrueNode(iff_arg)) );
+  set_control( _gvn.transform(new (C) IfTrueNode(iff_arg)) );
 
   // (d) Otherwise, go to the slow path.
   slow_region->add_req(control());
@@ -3022,9 +3365,9 @@
   Node* mods = make_load(NULL, modp, TypeInt::INT, T_INT);
   Node* mask = intcon(modifier_mask);
   Node* bits = intcon(modifier_bits);
-  Node* mbit = _gvn.transform( new (C, 3) AndINode(mods, mask) );
-  Node* cmp  = _gvn.transform( new (C, 3) CmpINode(mbit, bits) );
-  Node* bol  = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ne) );
+  Node* mbit = _gvn.transform( new (C) AndINode(mods, mask) );
+  Node* cmp  = _gvn.transform( new (C) CmpINode(mbit, bits) );
+  Node* bol  = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ne) );
   return generate_fair_guard(bol, region);
 }
 Node* LibraryCallKit::generate_interface_guard(Node* kls, RegionNode* region) {
@@ -3097,9 +3440,9 @@
 #endif
 
   // Null-check the mirror, and the mirror's klass ptr (in case it is a primitive).
-  RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT);
+  RegionNode* region = new (C) RegionNode(PATH_LIMIT);
   record_for_igvn(region);
-  PhiNode* phi = new (C, PATH_LIMIT) PhiNode(region, return_type);
+  PhiNode* phi = new (C) PhiNode(region, return_type);
 
   // The mirror will never be null of Reflection.getClassAccessFlags, however
   // it may be null for Class.isInstance or Class.getModifiers. Throw a NPE
@@ -3247,8 +3590,8 @@
     PATH_LIMIT
   };
 
-  RegionNode* region = new (C, PATH_LIMIT) RegionNode(PATH_LIMIT);
-  Node*       phi    = new (C, PATH_LIMIT) PhiNode(region, TypeInt::BOOL);
+  RegionNode* region = new (C) RegionNode(PATH_LIMIT);
+  Node*       phi    = new (C) PhiNode(region, TypeInt::BOOL);
   record_for_igvn(region);
 
   const TypePtr* adr_type = TypeRawPtr::BOTTOM;   // memory type of loads
@@ -3299,8 +3642,8 @@
   set_control(region->in(_prim_0_path)); // go back to first null check
   if (!stopped()) {
     // Since superc is primitive, make a guard for the superc==subc case.
-    Node* cmp_eq = _gvn.transform( new (C, 3) CmpPNode(args[0], args[1]) );
-    Node* bol_eq = _gvn.transform( new (C, 2) BoolNode(cmp_eq, BoolTest::eq) );
+    Node* cmp_eq = _gvn.transform( new (C) CmpPNode(args[0], args[1]) );
+    Node* bol_eq = _gvn.transform( new (C) BoolNode(cmp_eq, BoolTest::eq) );
     generate_guard(bol_eq, region, PROB_FAIR);
     if (region->req() == PATH_LIMIT+1) {
       // A guard was added.  If the added guard is taken, superc==subc.
@@ -3366,11 +3709,11 @@
                 ? ((jint)Klass::_lh_array_tag_type_value
                    <<    Klass::_lh_array_tag_shift)
                 : Klass::_lh_neutral_value);
-  Node* cmp = _gvn.transform( new(C, 3) CmpINode(layout_val, intcon(nval)) );
+  Node* cmp = _gvn.transform( new(C) CmpINode(layout_val, intcon(nval)) );
   BoolTest::mask btest = BoolTest::lt;  // correct for testing is_[obj]array
   // invert the test if we are looking for a non-array
   if (not_array)  btest = BoolTest(btest).negate();
-  Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, btest) );
+  Node* bol = _gvn.transform( new(C) BoolNode(cmp, btest) );
   return generate_fair_guard(bol, region);
 }
 
@@ -3388,12 +3731,12 @@
   if (stopped())  return true;
 
   enum { _normal_path = 1, _slow_path = 2, PATH_LIMIT };
-  RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
-  PhiNode*    result_val = new(C, PATH_LIMIT) PhiNode(result_reg,
-                                                      TypeInstPtr::NOTNULL);
-  PhiNode*    result_io  = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO);
-  PhiNode*    result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY,
-                                                      TypePtr::BOTTOM);
+  RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT);
+  PhiNode*    result_val = new(C) PhiNode(result_reg,
+                                          TypeInstPtr::NOTNULL);
+  PhiNode*    result_io  = new(C) PhiNode(result_reg, Type::ABIO);
+  PhiNode*    result_mem = new(C) PhiNode(result_reg, Type::MEMORY,
+                                          TypePtr::BOTTOM);
 
   bool never_see_null = !too_many_traps(Deoptimization::Reason_null_check);
   Node* klass_node = load_array_klass_from_mirror(mirror, never_see_null,
@@ -3508,7 +3851,7 @@
                                               NULL, 0);
     klass_node = do_null_check(klass_node, T_OBJECT);
 
-    RegionNode* bailout = new (C, 1) RegionNode(1);
+    RegionNode* bailout = new (C) RegionNode(1);
     record_for_igvn(bailout);
 
     // Despite the generic type of Arrays.copyOf, the mirror might be int, int[], etc.
@@ -3518,7 +3861,7 @@
       // Improve the klass node's type from the new optimistic assumption:
       ciKlass* ak = ciArrayKlass::make(env()->Object_klass());
       const Type* akls = TypeKlassPtr::make(TypePtr::NotNull, ak, 0/*offset*/);
-      Node* cast = new (C, 2) CastPPNode(klass_node, akls);
+      Node* cast = new (C) CastPPNode(klass_node, akls);
       cast->init_req(0, control());
       klass_node = _gvn.transform(cast);
     }
@@ -3529,7 +3872,7 @@
 
     Node* length = end;
     if (_gvn.type(start) != TypeInt::ZERO) {
-      length = _gvn.transform( new (C, 3) SubINode(end, start) );
+      length = _gvn.transform( new (C) SubINode(end, start) );
     }
 
     // Bail out if length is negative.
@@ -3549,7 +3892,7 @@
 
       // How many elements will we copy from the original?
       // The answer is MinI(orig_length - start, length).
-      Node* orig_tail = _gvn.transform( new(C, 3) SubINode(orig_length, start) );
+      Node* orig_tail = _gvn.transform( new(C) SubINode(orig_length, start) );
       Node* moved = generate_min_max(vmIntrinsics::_min, orig_tail, length);
 
       newcopy = new_array(klass_node, length, 0);
@@ -3596,8 +3939,8 @@
   const TypeInstPtr* native_call_addr = TypeInstPtr::make(method);
 
   Node* native_call = makecon(native_call_addr);
-  Node* chk_native  = _gvn.transform( new(C, 3) CmpPNode(target_call, native_call) );
-  Node* test_native = _gvn.transform( new(C, 2) BoolNode(chk_native, BoolTest::ne) );
+  Node* chk_native  = _gvn.transform( new(C) CmpPNode(target_call, native_call) );
+  Node* test_native = _gvn.transform( new(C) BoolNode(chk_native, BoolTest::ne) );
 
   return generate_slow_guard(test_native, slow_region);
 }
@@ -3619,13 +3962,12 @@
   guarantee(method_id == method->intrinsic_id(), "must match");
 
   const TypeFunc* tf = TypeFunc::make(method);
-  int tfdc = tf->domain()->cnt();
   CallJavaNode* slow_call;
   if (is_static) {
     assert(!is_virtual, "");
-    slow_call = new(C, tfdc) CallStaticJavaNode(tf,
-                                SharedRuntime::get_resolve_static_call_stub(),
-                                method, bci());
+    slow_call = new(C) CallStaticJavaNode(tf,
+                           SharedRuntime::get_resolve_static_call_stub(),
+                           method, bci());
   } else if (is_virtual) {
     null_check_receiver(method);
     int vtable_index = methodOopDesc::invalid_vtable_index;
@@ -3637,12 +3979,12 @@
       // No need to use the linkResolver to get it.
        vtable_index = method->vtable_index();
     }
-    slow_call = new(C, tfdc) CallDynamicJavaNode(tf,
-                                SharedRuntime::get_resolve_virtual_call_stub(),
-                                method, vtable_index, bci());
+    slow_call = new(C) CallDynamicJavaNode(tf,
+                          SharedRuntime::get_resolve_virtual_call_stub(),
+                          method, vtable_index, bci());
   } else {  // neither virtual nor static:  opt_virtual
     null_check_receiver(method);
-    slow_call = new(C, tfdc) CallStaticJavaNode(tf,
+    slow_call = new(C) CallStaticJavaNode(tf,
                                 SharedRuntime::get_resolve_opt_virtual_call_stub(),
                                 method, bci());
     slow_call->set_optimized_virtual(true);
@@ -3661,12 +4003,12 @@
 
   enum { _slow_path = 1, _fast_path, _null_path, PATH_LIMIT };
 
-  RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
-  PhiNode*    result_val = new(C, PATH_LIMIT) PhiNode(result_reg,
-                                                      TypeInt::INT);
-  PhiNode*    result_io  = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO);
-  PhiNode*    result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY,
-                                                      TypePtr::BOTTOM);
+  RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT);
+  PhiNode*    result_val = new(C) PhiNode(result_reg,
+                                          TypeInt::INT);
+  PhiNode*    result_io  = new(C) PhiNode(result_reg, Type::ABIO);
+  PhiNode*    result_mem = new(C) PhiNode(result_reg, Type::MEMORY,
+                                          TypePtr::BOTTOM);
   Node* obj = NULL;
   if (!is_static) {
     // Check for hashing null object
@@ -3700,7 +4042,7 @@
 
   // We only go to the fast case code if we pass a number of guards.  The
   // paths which do not pass are accumulated in the slow_region.
-  RegionNode* slow_region = new (C, 1) RegionNode(1);
+  RegionNode* slow_region = new (C) RegionNode(1);
   record_for_igvn(slow_region);
 
   // If this is a virtual call, we generate a funny guard.  We pull out
@@ -3719,10 +4061,10 @@
 
   // Test the header to see if it is unlocked.
   Node *lock_mask      = _gvn.MakeConX(markOopDesc::biased_lock_mask_in_place);
-  Node *lmasked_header = _gvn.transform( new (C, 3) AndXNode(header, lock_mask) );
+  Node *lmasked_header = _gvn.transform( new (C) AndXNode(header, lock_mask) );
   Node *unlocked_val   = _gvn.MakeConX(markOopDesc::unlocked_value);
-  Node *chk_unlocked   = _gvn.transform( new (C, 3) CmpXNode( lmasked_header, unlocked_val));
-  Node *test_unlocked  = _gvn.transform( new (C, 2) BoolNode( chk_unlocked, BoolTest::ne) );
+  Node *chk_unlocked   = _gvn.transform( new (C) CmpXNode( lmasked_header, unlocked_val));
+  Node *test_unlocked  = _gvn.transform( new (C) BoolNode( chk_unlocked, BoolTest::ne) );
 
   generate_slow_guard(test_unlocked, slow_region);
 
@@ -3732,17 +4074,17 @@
   // vm: see markOop.hpp.
   Node *hash_mask      = _gvn.intcon(markOopDesc::hash_mask);
   Node *hash_shift     = _gvn.intcon(markOopDesc::hash_shift);
-  Node *hshifted_header= _gvn.transform( new (C, 3) URShiftXNode(header, hash_shift) );
+  Node *hshifted_header= _gvn.transform( new (C) URShiftXNode(header, hash_shift) );
   // This hack lets the hash bits live anywhere in the mark object now, as long
   // as the shift drops the relevant bits into the low 32 bits.  Note that
   // Java spec says that HashCode is an int so there's no point in capturing
   // an 'X'-sized hashcode (32 in 32-bit build or 64 in 64-bit build).
   hshifted_header      = ConvX2I(hshifted_header);
-  Node *hash_val       = _gvn.transform( new (C, 3) AndINode(hshifted_header, hash_mask) );
+  Node *hash_val       = _gvn.transform( new (C) AndINode(hshifted_header, hash_mask) );
 
   Node *no_hash_val    = _gvn.intcon(markOopDesc::no_hash);
-  Node *chk_assigned   = _gvn.transform( new (C, 3) CmpINode( hash_val, no_hash_val));
-  Node *test_assigned  = _gvn.transform( new (C, 2) BoolNode( chk_assigned, BoolTest::eq) );
+  Node *chk_assigned   = _gvn.transform( new (C) CmpINode( hash_val, no_hash_val));
+  Node *test_assigned  = _gvn.transform( new (C) BoolNode( chk_assigned, BoolTest::eq) );
 
   generate_slow_guard(test_assigned, slow_region);
 
@@ -3931,7 +4273,8 @@
       }
     }
   }
-  else if (method->is_method_handle_adapter()) {
+  else if (method->is_method_handle_intrinsic() ||
+           method->is_compiled_lambda_form()) {
     // This is an internal adapter frame from the MethodHandleCompiler -- skip it
     return true;
   }
@@ -3939,144 +4282,37 @@
   return false;
 }
 
-static int value_field_offset = -1;  // offset of the "value" field of AtomicLongCSImpl.  This is needed by
-                                     // inline_native_AtomicLong_attemptUpdate() but it has no way of
-                                     // computing it since there is no lookup field by name function in the
-                                     // CI interface.  This is computed and set by inline_native_AtomicLong_get().
-                                     // Using a static variable here is safe even if we have multiple compilation
-                                     // threads because the offset is constant.  At worst the same offset will be
-                                     // computed and  stored multiple
-
-bool LibraryCallKit::inline_native_AtomicLong_get() {
-  // Restore the stack and pop off the argument
-  _sp+=1;
-  Node *obj = pop();
-
-  // get the offset of the "value" field. Since the CI interfaces
-  // does not provide a way to look up a field by name, we scan the bytecodes
-  // to get the field index.  We expect the first 2 instructions of the method
-  // to be:
-  //    0 aload_0
-  //    1 getfield "value"
-  ciMethod* method = callee();
-  if (value_field_offset == -1)
-  {
-    ciField* value_field;
-    ciBytecodeStream iter(method);
-    Bytecodes::Code bc = iter.next();
-
-    if ((bc != Bytecodes::_aload_0) &&
-              ((bc != Bytecodes::_aload) || (iter.get_index() != 0)))
-      return false;
-    bc = iter.next();
-    if (bc != Bytecodes::_getfield)
-      return false;
-    bool ignore;
-    value_field = iter.get_field(ignore);
-    value_field_offset = value_field->offset_in_bytes();
-  }
-
-  // Null check without removing any arguments.
-  _sp++;
-  obj = do_null_check(obj, T_OBJECT);
-  _sp--;
-  // Check for locking null object
-  if (stopped()) return true;
-
-  Node *adr = basic_plus_adr(obj, obj, value_field_offset);
-  const TypePtr *adr_type = _gvn.type(adr)->is_ptr();
-  int alias_idx = C->get_alias_index(adr_type);
-
-  Node *result = _gvn.transform(new (C, 3) LoadLLockedNode(control(), memory(alias_idx), adr));
-
-  push_pair(result);
-
-  return true;
-}
-
-bool LibraryCallKit::inline_native_AtomicLong_attemptUpdate() {
-  // Restore the stack and pop off the arguments
-  _sp+=5;
-  Node *newVal = pop_pair();
-  Node *oldVal = pop_pair();
-  Node *obj = pop();
-
-  // we need the offset of the "value" field which was computed when
-  // inlining the get() method.  Give up if we don't have it.
-  if (value_field_offset == -1)
-    return false;
-
-  // Null check without removing any arguments.
-  _sp+=5;
-  obj = do_null_check(obj, T_OBJECT);
-  _sp-=5;
-  // Check for locking null object
-  if (stopped()) return true;
-
-  Node *adr = basic_plus_adr(obj, obj, value_field_offset);
-  const TypePtr *adr_type = _gvn.type(adr)->is_ptr();
-  int alias_idx = C->get_alias_index(adr_type);
-
-  Node *cas = _gvn.transform(new (C, 5) StoreLConditionalNode(control(), memory(alias_idx), adr, newVal, oldVal));
-  Node *store_proj = _gvn.transform( new (C, 1) SCMemProjNode(cas));
-  set_memory(store_proj, alias_idx);
-  Node *bol = _gvn.transform( new (C, 2) BoolNode( cas, BoolTest::eq ) );
-
-  Node *result;
-  // CMove node is not used to be able fold a possible check code
-  // after attemptUpdate() call. This code could be transformed
-  // into CMove node by loop optimizations.
-  {
-    RegionNode *r = new (C, 3) RegionNode(3);
-    result = new (C, 3) PhiNode(r, TypeInt::BOOL);
-
-    Node *iff = create_and_xform_if(control(), bol, PROB_FAIR, COUNT_UNKNOWN);
-    Node *iftrue = opt_iff(r, iff);
-    r->init_req(1, iftrue);
-    result->init_req(1, intcon(1));
-    result->init_req(2, intcon(0));
-
-    set_control(_gvn.transform(r));
-    record_for_igvn(r);
-
-    C->set_has_split_ifs(true); // Has chance for split-if optimization
-  }
-
-  push(_gvn.transform(result));
-  return true;
-}
-
 bool LibraryCallKit::inline_fp_conversions(vmIntrinsics::ID id) {
   // restore the arguments
   _sp += arg_size();
 
   switch (id) {
   case vmIntrinsics::_floatToRawIntBits:
-    push(_gvn.transform( new (C, 2) MoveF2INode(pop())));
+    push(_gvn.transform( new (C) MoveF2INode(pop())));
     break;
 
   case vmIntrinsics::_intBitsToFloat:
-    push(_gvn.transform( new (C, 2) MoveI2FNode(pop())));
+    push(_gvn.transform( new (C) MoveI2FNode(pop())));
     break;
 
   case vmIntrinsics::_doubleToRawLongBits:
-    push_pair(_gvn.transform( new (C, 2) MoveD2LNode(pop_pair())));
+    push_pair(_gvn.transform( new (C) MoveD2LNode(pop_pair())));
     break;
 
   case vmIntrinsics::_longBitsToDouble:
-    push_pair(_gvn.transform( new (C, 2) MoveL2DNode(pop_pair())));
+    push_pair(_gvn.transform( new (C) MoveL2DNode(pop_pair())));
     break;
 
   case vmIntrinsics::_doubleToLongBits: {
     Node* value = pop_pair();
 
     // two paths (plus control) merge in a wood
-    RegionNode *r = new (C, 3) RegionNode(3);
-    Node *phi = new (C, 3) PhiNode(r, TypeLong::LONG);
+    RegionNode *r = new (C) RegionNode(3);
+    Node *phi = new (C) PhiNode(r, TypeLong::LONG);
 
-    Node *cmpisnan = _gvn.transform( new (C, 3) CmpDNode(value, value));
+    Node *cmpisnan = _gvn.transform( new (C) CmpDNode(value, value));
     // Build the boolean node
-    Node *bolisnan = _gvn.transform( new (C, 2) BoolNode( cmpisnan, BoolTest::ne ) );
+    Node *bolisnan = _gvn.transform( new (C) BoolNode( cmpisnan, BoolTest::ne ) );
 
     // Branch either way.
     // NaN case is less traveled, which makes all the difference.
@@ -4084,7 +4320,7 @@
     Node *opt_isnan = _gvn.transform(ifisnan);
     assert( opt_isnan->is_If(), "Expect an IfNode");
     IfNode *opt_ifisnan = (IfNode*)opt_isnan;
-    Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(opt_ifisnan) );
+    Node *iftrue = _gvn.transform( new (C) IfTrueNode(opt_ifisnan) );
 
     set_control(iftrue);
 
@@ -4094,10 +4330,10 @@
     r->init_req(1, iftrue);
 
     // Else fall through
-    Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(opt_ifisnan) );
+    Node *iffalse = _gvn.transform( new (C) IfFalseNode(opt_ifisnan) );
     set_control(iffalse);
 
-    phi->init_req(2, _gvn.transform( new (C, 2) MoveD2LNode(value)));
+    phi->init_req(2, _gvn.transform( new (C) MoveD2LNode(value)));
     r->init_req(2, iffalse);
 
     // Post merge
@@ -4117,12 +4353,12 @@
     Node* value = pop();
 
     // two paths (plus control) merge in a wood
-    RegionNode *r = new (C, 3) RegionNode(3);
-    Node *phi = new (C, 3) PhiNode(r, TypeInt::INT);
+    RegionNode *r = new (C) RegionNode(3);
+    Node *phi = new (C) PhiNode(r, TypeInt::INT);
 
-    Node *cmpisnan = _gvn.transform( new (C, 3) CmpFNode(value, value));
+    Node *cmpisnan = _gvn.transform( new (C) CmpFNode(value, value));
     // Build the boolean node
-    Node *bolisnan = _gvn.transform( new (C, 2) BoolNode( cmpisnan, BoolTest::ne ) );
+    Node *bolisnan = _gvn.transform( new (C) BoolNode( cmpisnan, BoolTest::ne ) );
 
     // Branch either way.
     // NaN case is less traveled, which makes all the difference.
@@ -4130,7 +4366,7 @@
     Node *opt_isnan = _gvn.transform(ifisnan);
     assert( opt_isnan->is_If(), "Expect an IfNode");
     IfNode *opt_ifisnan = (IfNode*)opt_isnan;
-    Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(opt_ifisnan) );
+    Node *iftrue = _gvn.transform( new (C) IfTrueNode(opt_ifisnan) );
 
     set_control(iftrue);
 
@@ -4140,10 +4376,10 @@
     r->init_req(1, iftrue);
 
     // Else fall through
-    Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(opt_ifisnan) );
+    Node *iffalse = _gvn.transform( new (C) IfFalseNode(opt_ifisnan) );
     set_control(iffalse);
 
-    phi->init_req(2, _gvn.transform( new (C, 2) MoveF2INode(value)));
+    phi->init_req(2, _gvn.transform( new (C) MoveF2INode(value)));
     r->init_req(2, iffalse);
 
     // Post merge
@@ -4265,8 +4501,8 @@
 
   // Compute the length also, if needed:
   Node* countx = size;
-  countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(base_off)) );
-  countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong) ));
+  countx = _gvn.transform( new (C) SubXNode(countx, MakeConX(base_off)) );
+  countx = _gvn.transform( new (C) URShiftXNode(countx, intcon(LogBytesPerLong) ));
 
   const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
   bool disjoint_bases = true;
@@ -4357,12 +4593,12 @@
       _instance_path,     // plain instance allocation, plus arrayof_long_arraycopy
       PATH_LIMIT
     };
-    RegionNode* result_reg = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
-    result_val             = new(C, PATH_LIMIT) PhiNode(result_reg,
-                                                        TypeInstPtr::NOTNULL);
-    PhiNode*    result_i_o = new(C, PATH_LIMIT) PhiNode(result_reg, Type::ABIO);
-    PhiNode*    result_mem = new(C, PATH_LIMIT) PhiNode(result_reg, Type::MEMORY,
-                                                        TypePtr::BOTTOM);
+    RegionNode* result_reg = new(C) RegionNode(PATH_LIMIT);
+    result_val             = new(C) PhiNode(result_reg,
+                                            TypeInstPtr::NOTNULL);
+    PhiNode*    result_i_o = new(C) PhiNode(result_reg, Type::ABIO);
+    PhiNode*    result_mem = new(C) PhiNode(result_reg, Type::MEMORY,
+                                            TypePtr::BOTTOM);
     record_for_igvn(result_reg);
 
     const TypePtr* raw_adr_type = TypeRawPtr::BOTTOM;
@@ -4418,7 +4654,7 @@
 
     // We only go to the instance fast case code if we pass a number of guards.
     // The paths which do not pass are accumulated in the slow_region.
-    RegionNode* slow_region = new (C, 1) RegionNode(1);
+    RegionNode* slow_region = new (C) RegionNode(1);
     record_for_igvn(slow_region);
     if (!stopped()) {
       // It's an instance (we did array above).  Make the slow-path tests.
@@ -4588,7 +4824,7 @@
   // (8) dest_offset + length must not exceed length of dest.
   // (9) each element of an oop array must be assignable
 
-  RegionNode* slow_region = new (C, 1) RegionNode(1);
+  RegionNode* slow_region = new (C) RegionNode(1);
   record_for_igvn(slow_region);
 
   // (3) operands must not be null
@@ -4678,7 +4914,7 @@
                                    RegionNode* slow_region) {
 
   if (slow_region == NULL) {
-    slow_region = new(C,1) RegionNode(1);
+    slow_region = new(C) RegionNode(1);
     record_for_igvn(slow_region);
   }
 
@@ -4726,9 +4962,9 @@
          bcopy_path       = 5,  // copy primitive array by 64-bit blocks
          PATH_LIMIT       = 6
   };
-  RegionNode* result_region = new(C, PATH_LIMIT) RegionNode(PATH_LIMIT);
-  PhiNode*    result_i_o    = new(C, PATH_LIMIT) PhiNode(result_region, Type::ABIO);
-  PhiNode*    result_memory = new(C, PATH_LIMIT) PhiNode(result_region, Type::MEMORY, adr_type);
+  RegionNode* result_region = new(C) RegionNode(PATH_LIMIT);
+  PhiNode*    result_i_o    = new(C) PhiNode(result_region, Type::ABIO);
+  PhiNode*    result_memory = new(C) PhiNode(result_region, Type::MEMORY, adr_type);
   record_for_igvn(result_region);
   _gvn.set_type_bottom(result_i_o);
   _gvn.set_type_bottom(result_memory);
@@ -4802,7 +5038,7 @@
     // are dest_head = dest[0..off] and dest_tail = dest[off+len..dest.length].
     Node* dest_size   = alloc->in(AllocateNode::AllocSize);
     Node* dest_length = alloc->in(AllocateNode::ALength);
-    Node* dest_tail   = _gvn.transform( new(C,3) AddINode(dest_offset,
+    Node* dest_tail   = _gvn.transform( new(C) AddINode(dest_offset,
                                                           copy_length) );
 
     // If there is a head section that needs zeroing, do it now.
@@ -4819,8 +5055,8 @@
     // the copy to a more hardware-friendly word size of 64 bits.
     Node* tail_ctl = NULL;
     if (!stopped() && !dest_tail->eqv_uncast(dest_length)) {
-      Node* cmp_lt   = _gvn.transform( new(C,3) CmpINode(dest_tail, dest_length) );
-      Node* bol_lt   = _gvn.transform( new(C,2) BoolNode(cmp_lt, BoolTest::lt) );
+      Node* cmp_lt   = _gvn.transform( new(C) CmpINode(dest_tail, dest_length) );
+      Node* bol_lt   = _gvn.transform( new(C) BoolNode(cmp_lt, BoolTest::lt) );
       tail_ctl = generate_slow_guard(bol_lt, NULL);
       assert(tail_ctl != NULL || !stopped(), "must be an outcome");
     }
@@ -4854,8 +5090,8 @@
                              dest_size);
       } else {
         // Make a local merge.
-        Node* done_ctl = new(C,3) RegionNode(3);
-        Node* done_mem = new(C,3) PhiNode(done_ctl, Type::MEMORY, adr_type);
+        Node* done_ctl = new(C) RegionNode(3);
+        Node* done_mem = new(C) PhiNode(done_ctl, Type::MEMORY, adr_type);
         done_ctl->init_req(1, notail_ctl);
         done_mem->init_req(1, memory(adr_type));
         generate_clear_array(adr_type, dest, basic_elem_type,
@@ -4950,21 +5186,21 @@
     // Clean up after the checked call.
     // The returned value is either 0 or -1^K,
     // where K = number of partially transferred array elements.
-    Node* cmp = _gvn.transform( new(C, 3) CmpINode(checked_value, intcon(0)) );
-    Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) );
+    Node* cmp = _gvn.transform( new(C) CmpINode(checked_value, intcon(0)) );
+    Node* bol = _gvn.transform( new(C) BoolNode(cmp, BoolTest::eq) );
     IfNode* iff = create_and_map_if(control(), bol, PROB_MAX, COUNT_UNKNOWN);
 
     // If it is 0, we are done, so transfer to the end.
-    Node* checks_done = _gvn.transform( new(C, 1) IfTrueNode(iff) );
+    Node* checks_done = _gvn.transform( new(C) IfTrueNode(iff) );
     result_region->init_req(checked_path, checks_done);
     result_i_o   ->init_req(checked_path, checked_i_o);
     result_memory->init_req(checked_path, checked_mem);
 
     // If it is not zero, merge into the slow call.
-    set_control( _gvn.transform( new(C, 1) IfFalseNode(iff) ));
-    RegionNode* slow_reg2 = new(C, 3) RegionNode(3);
-    PhiNode*    slow_i_o2 = new(C, 3) PhiNode(slow_reg2, Type::ABIO);
-    PhiNode*    slow_mem2 = new(C, 3) PhiNode(slow_reg2, Type::MEMORY, adr_type);
+    set_control( _gvn.transform( new(C) IfFalseNode(iff) ));
+    RegionNode* slow_reg2 = new(C) RegionNode(3);
+    PhiNode*    slow_i_o2 = new(C) PhiNode(slow_reg2, Type::ABIO);
+    PhiNode*    slow_mem2 = new(C) PhiNode(slow_reg2, Type::MEMORY, adr_type);
     record_for_igvn(slow_reg2);
     slow_reg2  ->init_req(1, slow_control);
     slow_i_o2  ->init_req(1, slow_i_o);
@@ -4984,16 +5220,16 @@
     } else {
       // We must continue the copy exactly where it failed, or else
       // another thread might see the wrong number of writes to dest.
-      Node* checked_offset = _gvn.transform( new(C, 3) XorINode(checked_value, intcon(-1)) );
-      Node* slow_offset    = new(C, 3) PhiNode(slow_reg2, TypeInt::INT);
+      Node* checked_offset = _gvn.transform( new(C) XorINode(checked_value, intcon(-1)) );
+      Node* slow_offset    = new(C) PhiNode(slow_reg2, TypeInt::INT);
       slow_offset->init_req(1, intcon(0));
       slow_offset->init_req(2, checked_offset);
       slow_offset  = _gvn.transform(slow_offset);
 
       // Adjust the arguments by the conditionally incoming offset.
-      Node* src_off_plus  = _gvn.transform( new(C, 3) AddINode(src_offset,  slow_offset) );
-      Node* dest_off_plus = _gvn.transform( new(C, 3) AddINode(dest_offset, slow_offset) );
-      Node* length_minus  = _gvn.transform( new(C, 3) SubINode(copy_length, slow_offset) );
+      Node* src_off_plus  = _gvn.transform( new(C) AddINode(src_offset,  slow_offset) );
+      Node* dest_off_plus = _gvn.transform( new(C) AddINode(dest_offset, slow_offset) );
+      Node* length_minus  = _gvn.transform( new(C) SubINode(copy_length, slow_offset) );
 
       // Tweak the node variables to adjust the code produced below:
       src_offset  = src_off_plus;
@@ -5214,10 +5450,10 @@
     int      end_round = (-1 << scale) & (BytesPerLong  - 1);
     Node*    end       = ConvI2X(slice_len);
     if (scale != 0)
-      end = _gvn.transform( new(C,3) LShiftXNode(end, intcon(scale) ));
+      end = _gvn.transform( new(C) LShiftXNode(end, intcon(scale) ));
     end_base += end_round;
-    end = _gvn.transform( new(C,3) AddXNode(end, MakeConX(end_base)) );
-    end = _gvn.transform( new(C,3) AndXNode(end, MakeConX(~end_round)) );
+    end = _gvn.transform( new(C) AddXNode(end, MakeConX(end_base)) );
+    end = _gvn.transform( new(C) AndXNode(end, MakeConX(~end_round)) );
     mem = ClearArrayNode::clear_memory(control(), mem, dest,
                                        start_con, end, &_gvn);
   } else if (start_con < 0 && dest_size != top()) {
@@ -5226,8 +5462,8 @@
     Node* start = slice_idx;
     start = ConvI2X(start);
     if (scale != 0)
-      start = _gvn.transform( new(C,3) LShiftXNode( start, intcon(scale) ));
-    start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(abase)) );
+      start = _gvn.transform( new(C) LShiftXNode( start, intcon(scale) ));
+    start = _gvn.transform( new(C) AddXNode(start, MakeConX(abase)) );
     if ((bump_bit | clear_low) != 0) {
       int to_clear = (bump_bit | clear_low);
       // Align up mod 8, then store a jint zero unconditionally
@@ -5238,14 +5474,14 @@
         assert((abase & to_clear) == 0, "array base must be long-aligned");
       } else {
         // Bump 'start' up to (or past) the next jint boundary:
-        start = _gvn.transform( new(C,3) AddXNode(start, MakeConX(bump_bit)) );
+        start = _gvn.transform( new(C) AddXNode(start, MakeConX(bump_bit)) );
         assert((abase & clear_low) == 0, "array base must be int-aligned");
       }
       // Round bumped 'start' down to jlong boundary in body of array.
-      start = _gvn.transform( new(C,3) AndXNode(start, MakeConX(~to_clear)) );
+      start = _gvn.transform( new(C) AndXNode(start, MakeConX(~to_clear)) );
       if (bump_bit != 0) {
         // Store a zero to the immediately preceding jint:
-        Node* x1 = _gvn.transform( new(C,3) AddXNode(start, MakeConX(-bump_bit)) );
+        Node* x1 = _gvn.transform( new(C) AddXNode(start, MakeConX(-bump_bit)) );
         Node* p1 = basic_plus_adr(dest, x1);
         mem = StoreNode::make(_gvn, control(), mem, p1, adr_type, intcon(0), T_INT);
         mem = _gvn.transform(mem);
@@ -5312,8 +5548,8 @@
   Node* sptr  = basic_plus_adr(src,  src_off);
   Node* dptr  = basic_plus_adr(dest, dest_off);
   Node* countx = dest_size;
-  countx = _gvn.transform( new (C, 3) SubXNode(countx, MakeConX(dest_off)) );
-  countx = _gvn.transform( new (C, 3) URShiftXNode(countx, intcon(LogBytesPerLong)) );
+  countx = _gvn.transform( new (C) SubXNode(countx, MakeConX(dest_off)) );
+  countx = _gvn.transform( new (C) URShiftXNode(countx, intcon(LogBytesPerLong)) );
 
   bool disjoint_bases = true;   // since alloc != NULL
   generate_unchecked_arraycopy(adr_type, T_LONG, disjoint_bases,
@@ -5363,7 +5599,7 @@
   // super_check_offset, for the desired klass.
   int sco_offset = in_bytes(Klass::super_check_offset_offset());
   Node* p3 = basic_plus_adr(dest_elem_klass, sco_offset);
-  Node* n3 = new(C, 3) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr());
+  Node* n3 = new(C) LoadINode(NULL, memory(p3), p3, _gvn.type(p3)->is_ptr());
   Node* check_offset = ConvI2X(_gvn.transform(n3));
   Node* check_value  = dest_elem_klass;
 
@@ -5381,7 +5617,7 @@
                                  check_offset XTOP,
                                  check_value);
 
-  return _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms));
+  return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
 }
 
 
@@ -5403,7 +5639,7 @@
                     copyfunc_addr, "generic_arraycopy", adr_type,
                     src, src_offset, dest, dest_offset, copy_length);
 
-  return _gvn.transform(new (C, 1) ProjNode(call, TypeFunc::Parms));
+  return _gvn.transform(new (C) ProjNode(call, TypeFunc::Parms));
 }
 
 // Helper function; generates the fast out-of-line call to an arraycopy stub.
@@ -5473,7 +5709,272 @@
               result /* pre_val */,
               T_OBJECT);
 
+  // Add memory barrier to prevent commoning reads from this field
+  // across safepoint since GC can change its value.
+  insert_mem_bar(Op_MemBarCPUOrder);
+
   push(result);
   return true;
 }
 
+
+Node * LibraryCallKit::load_field_from_object(Node * fromObj, const char * fieldName, const char * fieldTypeString,
+                                              bool is_exact=true, bool is_static=false) {
+
+  const TypeInstPtr* tinst = _gvn.type(fromObj)->isa_instptr();
+  assert(tinst != NULL, "obj is null");
+  assert(tinst->klass()->is_loaded(), "obj is not loaded");
+  assert(!is_exact || tinst->klass_is_exact(), "klass not exact");
+
+  ciField* field = tinst->klass()->as_instance_klass()->get_field_by_name(ciSymbol::make(fieldName),
+                                                                          ciSymbol::make(fieldTypeString),
+                                                                          is_static);
+  if (field == NULL) return (Node *) NULL;
+  assert (field != NULL, "undefined field");
+
+  // Next code  copied from Parse::do_get_xxx():
+
+  // Compute address and memory type.
+  int offset  = field->offset_in_bytes();
+  bool is_vol = field->is_volatile();
+  ciType* field_klass = field->type();
+  assert(field_klass->is_loaded(), "should be loaded");
+  const TypePtr* adr_type = C->alias_type(field)->adr_type();
+  Node *adr = basic_plus_adr(fromObj, fromObj, offset);
+  BasicType bt = field->layout_type();
+
+  // Build the resultant type of the load
+  const Type *type = TypeOopPtr::make_from_klass(field_klass->as_klass());
+
+  // Build the load.
+  Node* loadedField = make_load(NULL, adr, type, bt, adr_type, is_vol);
+  return loadedField;
+}
+
+
+//------------------------------inline_aescrypt_Block-----------------------
+bool LibraryCallKit::inline_aescrypt_Block(vmIntrinsics::ID id) {
+  address stubAddr;
+  const char *stubName;
+  assert(UseAES, "need AES instruction support");
+
+  switch(id) {
+  case vmIntrinsics::_aescrypt_encryptBlock:
+    stubAddr = StubRoutines::aescrypt_encryptBlock();
+    stubName = "aescrypt_encryptBlock";
+    break;
+  case vmIntrinsics::_aescrypt_decryptBlock:
+    stubAddr = StubRoutines::aescrypt_decryptBlock();
+    stubName = "aescrypt_decryptBlock";
+    break;
+  }
+  if (stubAddr == NULL) return false;
+
+  // Restore the stack and pop off the arguments.
+  int nargs = 5;  // this + 2 oop/offset combos
+  assert(callee()->signature()->size() == nargs-1, "encryptBlock has 4 arguments");
+
+  Node *aescrypt_object  = argument(0);
+  Node *src         = argument(1);
+  Node *src_offset  = argument(2);
+  Node *dest        = argument(3);
+  Node *dest_offset = argument(4);
+
+  // (1) src and dest are arrays.
+  const Type* src_type = src->Value(&_gvn);
+  const Type* dest_type = dest->Value(&_gvn);
+  const TypeAryPtr* top_src = src_type->isa_aryptr();
+  const TypeAryPtr* top_dest = dest_type->isa_aryptr();
+  assert (top_src  != NULL && top_src->klass()  != NULL &&  top_dest != NULL && top_dest->klass() != NULL, "args are strange");
+
+  // for the quick and dirty code we will skip all the checks.
+  // we are just trying to get the call to be generated.
+  Node* src_start  = src;
+  Node* dest_start = dest;
+  if (src_offset != NULL || dest_offset != NULL) {
+    assert(src_offset != NULL && dest_offset != NULL, "");
+    src_start  = array_element_address(src,  src_offset,  T_BYTE);
+    dest_start = array_element_address(dest, dest_offset, T_BYTE);
+  }
+
+  // now need to get the start of its expanded key array
+  // this requires a newer class file that has this array as littleEndian ints, otherwise we revert to java
+  Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
+  if (k_start == NULL) return false;
+
+  // Call the stub.
+  make_runtime_call(RC_LEAF|RC_NO_FP, OptoRuntime::aescrypt_block_Type(),
+                    stubAddr, stubName, TypePtr::BOTTOM,
+                    src_start, dest_start, k_start);
+
+  return true;
+}
+
+//------------------------------inline_cipherBlockChaining_AESCrypt-----------------------
+bool LibraryCallKit::inline_cipherBlockChaining_AESCrypt(vmIntrinsics::ID id) {
+  address stubAddr;
+  const char *stubName;
+
+  assert(UseAES, "need AES instruction support");
+
+  switch(id) {
+  case vmIntrinsics::_cipherBlockChaining_encryptAESCrypt:
+    stubAddr = StubRoutines::cipherBlockChaining_encryptAESCrypt();
+    stubName = "cipherBlockChaining_encryptAESCrypt";
+    break;
+  case vmIntrinsics::_cipherBlockChaining_decryptAESCrypt:
+    stubAddr = StubRoutines::cipherBlockChaining_decryptAESCrypt();
+    stubName = "cipherBlockChaining_decryptAESCrypt";
+    break;
+  }
+  if (stubAddr == NULL) return false;
+
+
+  // Restore the stack and pop off the arguments.
+  int nargs = 6;  // this + oop/offset + len + oop/offset
+  assert(callee()->signature()->size() == nargs-1, "wrong number of arguments");
+  Node *cipherBlockChaining_object  = argument(0);
+  Node *src         = argument(1);
+  Node *src_offset  = argument(2);
+  Node *len         = argument(3);
+  Node *dest        = argument(4);
+  Node *dest_offset = argument(5);
+
+  // (1) src and dest are arrays.
+  const Type* src_type = src->Value(&_gvn);
+  const Type* dest_type = dest->Value(&_gvn);
+  const TypeAryPtr* top_src = src_type->isa_aryptr();
+  const TypeAryPtr* top_dest = dest_type->isa_aryptr();
+  assert (top_src  != NULL && top_src->klass()  != NULL
+          &&  top_dest != NULL && top_dest->klass() != NULL, "args are strange");
+
+  // checks are the responsibility of the caller
+  Node* src_start  = src;
+  Node* dest_start = dest;
+  if (src_offset != NULL || dest_offset != NULL) {
+    assert(src_offset != NULL && dest_offset != NULL, "");
+    src_start  = array_element_address(src,  src_offset,  T_BYTE);
+    dest_start = array_element_address(dest, dest_offset, T_BYTE);
+  }
+
+  // if we are in this set of code, we "know" the embeddedCipher is an AESCrypt object
+  // (because of the predicated logic executed earlier).
+  // so we cast it here safely.
+  // this requires a newer class file that has this array as littleEndian ints, otherwise we revert to java
+
+  Node* embeddedCipherObj = load_field_from_object(cipherBlockChaining_object, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false);
+  if (embeddedCipherObj == NULL) return false;
+
+  // cast it to what we know it will be at runtime
+  const TypeInstPtr* tinst = _gvn.type(cipherBlockChaining_object)->isa_instptr();
+  assert(tinst != NULL, "CBC obj is null");
+  assert(tinst->klass()->is_loaded(), "CBC obj is not loaded");
+  ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt"));
+  if (!klass_AESCrypt->is_loaded()) return false;
+
+  ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
+  const TypeKlassPtr* aklass = TypeKlassPtr::make(instklass_AESCrypt);
+  const TypeOopPtr* xtype = aklass->as_instance_type();
+  Node* aescrypt_object = new(C) CheckCastPPNode(control(), embeddedCipherObj, xtype);
+  aescrypt_object = _gvn.transform(aescrypt_object);
+
+  // we need to get the start of the aescrypt_object's expanded key array
+  Node* k_start = get_key_start_from_aescrypt_object(aescrypt_object);
+  if (k_start == NULL) return false;
+
+  // similarly, get the start address of the r vector
+  Node* objRvec = load_field_from_object(cipherBlockChaining_object, "r", "[B", /*is_exact*/ false);
+  if (objRvec == NULL) return false;
+  Node* r_start = array_element_address(objRvec, intcon(0), T_BYTE);
+
+  // Call the stub, passing src_start, dest_start, k_start, r_start and src_len
+  make_runtime_call(RC_LEAF|RC_NO_FP,
+                    OptoRuntime::cipherBlockChaining_aescrypt_Type(),
+                    stubAddr, stubName, TypePtr::BOTTOM,
+                    src_start, dest_start, k_start, r_start, len);
+
+  // return is void so no result needs to be pushed
+
+  return true;
+}
+
+//------------------------------get_key_start_from_aescrypt_object-----------------------
+Node * LibraryCallKit::get_key_start_from_aescrypt_object(Node *aescrypt_object) {
+  Node* objAESCryptKey = load_field_from_object(aescrypt_object, "K", "[I", /*is_exact*/ false);
+  assert (objAESCryptKey != NULL, "wrong version of com.sun.crypto.provider.AESCrypt");
+  if (objAESCryptKey == NULL) return (Node *) NULL;
+
+  // now have the array, need to get the start address of the K array
+  Node* k_start = array_element_address(objAESCryptKey, intcon(0), T_INT);
+  return k_start;
+}
+
+//----------------------------inline_cipherBlockChaining_AESCrypt_predicate----------------------------
+// Return node representing slow path of predicate check.
+// the pseudo code we want to emulate with this predicate is:
+// for encryption:
+//    if (embeddedCipherObj instanceof AESCrypt) do_intrinsic, else do_javapath
+// for decryption:
+//    if ((embeddedCipherObj instanceof AESCrypt) && (cipher!=plain)) do_intrinsic, else do_javapath
+//    note cipher==plain is more conservative than the original java code but that's OK
+//
+Node* LibraryCallKit::inline_cipherBlockChaining_AESCrypt_predicate(bool decrypting) {
+  // First, check receiver for NULL since it is virtual method.
+  int nargs = arg_size();
+  Node* objCBC = argument(0);
+  _sp += nargs;
+  objCBC = do_null_check(objCBC, T_OBJECT);
+  _sp -= nargs;
+
+  if (stopped()) return NULL; // Always NULL
+
+  // Load embeddedCipher field of CipherBlockChaining object.
+  Node* embeddedCipherObj = load_field_from_object(objCBC, "embeddedCipher", "Lcom/sun/crypto/provider/SymmetricCipher;", /*is_exact*/ false);
+
+  // get AESCrypt klass for instanceOf check
+  // AESCrypt might not be loaded yet if some other SymmetricCipher got us to this compile point
+  // will have same classloader as CipherBlockChaining object
+  const TypeInstPtr* tinst = _gvn.type(objCBC)->isa_instptr();
+  assert(tinst != NULL, "CBCobj is null");
+  assert(tinst->klass()->is_loaded(), "CBCobj is not loaded");
+
+  // we want to do an instanceof comparison against the AESCrypt class
+  ciKlass* klass_AESCrypt = tinst->klass()->as_instance_klass()->find_klass(ciSymbol::make("com/sun/crypto/provider/AESCrypt"));
+  if (!klass_AESCrypt->is_loaded()) {
+    // if AESCrypt is not even loaded, we never take the intrinsic fast path
+    Node* ctrl = control();
+    set_control(top()); // no regular fast path
+    return ctrl;
+  }
+  ciInstanceKlass* instklass_AESCrypt = klass_AESCrypt->as_instance_klass();
+
+  _sp += nargs;          // gen_instanceof might do an uncommon trap
+  Node* instof = gen_instanceof(embeddedCipherObj, makecon(TypeKlassPtr::make(instklass_AESCrypt)));
+  _sp -= nargs;
+  Node* cmp_instof  = _gvn.transform(new (C) CmpINode(instof, intcon(1)));
+  Node* bool_instof  = _gvn.transform(new (C) BoolNode(cmp_instof, BoolTest::ne));
+
+  Node* instof_false = generate_guard(bool_instof, NULL, PROB_MIN);
+
+  // for encryption, we are done
+  if (!decrypting)
+    return instof_false;  // even if it is NULL
+
+  // for decryption, we need to add a further check to avoid
+  // taking the intrinsic path when cipher and plain are the same
+  // see the original java code for why.
+  RegionNode* region = new(C) RegionNode(3);
+  region->init_req(1, instof_false);
+  Node* src = argument(1);
+  Node *dest = argument(4);
+  Node* cmp_src_dest = _gvn.transform(new (C) CmpPNode(src, dest));
+  Node* bool_src_dest = _gvn.transform(new (C) BoolNode(cmp_src_dest, BoolTest::eq));
+  Node* src_dest_conjoint = generate_guard(bool_src_dest, NULL, PROB_MIN);
+  region->init_req(2, src_dest_conjoint);
+
+  record_for_igvn(region);
+  return _gvn.transform(region);
+
+}
+
+
diff --git a/hotspot/src/share/vm/opto/loopPredicate.cpp b/hotspot/src/share/vm/opto/loopPredicate.cpp
index d4a575d..6dd45e0 100644
--- a/hotspot/src/share/vm/opto/loopPredicate.cpp
+++ b/hotspot/src/share/vm/opto/loopPredicate.cpp
@@ -159,7 +159,7 @@
     assert(rgn->is_Call(), "must be call uct");
     CallNode* call = rgn->as_Call();
     IdealLoopTree* loop = get_loop(call);
-    rgn = new (C, 1) RegionNode(1);
+    rgn = new (C) RegionNode(1);
     rgn->add_req(uncommon_proj);
     register_control(rgn, loop, uncommon_proj);
     _igvn.hash_delete(call);
@@ -185,8 +185,8 @@
   IfNode *new_iff = iff->clone()->as_If();
   new_iff->set_req(0, entry);
   register_control(new_iff, lp, entry);
-  Node *if_cont = new (C, 1) IfTrueNode(new_iff);
-  Node *if_uct  = new (C, 1) IfFalseNode(new_iff);
+  Node *if_cont = new (C) IfTrueNode(new_iff);
+  Node *if_uct  = new (C) IfFalseNode(new_iff);
   if (cont_proj->is_IfFalse()) {
     // Swap
     Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
@@ -212,9 +212,8 @@
     Node* use = rgn->fast_out(i);
     if (use->is_Phi() && use->outcnt() > 0) {
       assert(use->in(0) == rgn, "");
-      _igvn.hash_delete(use);
+      _igvn.rehash_node_delayed(use);
       use->add_req(use->in(proj_index));
-      _igvn._worklist.push(use);
       has_phi = true;
     }
   }
@@ -247,7 +246,7 @@
   if (!rgn->is_Region()) { // create a region to guard the call
     assert(rgn->is_Call(), "must be call uct");
     CallNode* call = rgn->as_Call();
-    rgn = new (C, 1) RegionNode(1);
+    rgn = new (C) RegionNode(1);
     register_new_node_with_optimizer(rgn);
     rgn->add_req(uncommon_proj);
     hash_delete(call);
@@ -264,8 +263,8 @@
   new_iff->set_req(0, new_entry);
 
   register_new_node_with_optimizer(new_iff);
-  Node *if_cont = new (C, 1) IfTrueNode(new_iff);
-  Node *if_uct  = new (C, 1) IfFalseNode(new_iff);
+  Node *if_cont = new (C) IfTrueNode(new_iff);
+  Node *if_uct  = new (C) IfFalseNode(new_iff);
   if (cont_proj->is_IfFalse()) {
     // Swap
     Node* tmp = if_uct; if_uct = if_cont; if_cont = tmp;
@@ -284,9 +283,8 @@
   for (DUIterator_Fast imax, i = rgn->fast_outs(imax); i < imax; i++) {
     Node* use = rgn->fast_out(i);
     if (use->is_Phi() && use->outcnt() > 0) {
-      hash_delete(use);
+      rehash_node_delayed(use);
       use->add_req(use->in(proj_index));
-      _worklist.push(use);
       has_phi = true;
     }
   }
@@ -311,10 +309,10 @@
 
   // Match original condition since predicate's projections could be swapped.
   assert(predicate_proj->in(0)->in(1)->in(1)->Opcode()==Op_Opaque1, "must be");
-  Node* opq = new (igvn->C, 2) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1));
+  Node* opq = new (igvn->C) Opaque1Node(igvn->C, predicate_proj->in(0)->in(1)->in(1)->in(1));
   igvn->C->add_predicate_opaq(opq);
 
-  Node* bol = new (igvn->C, 2) Conv2BNode(opq);
+  Node* bol = new (igvn->C) Conv2BNode(opq);
   if (loop_phase != NULL) {
     loop_phase->register_new_node(opq, ctrl);
     loop_phase->register_new_node(bol, ctrl);
@@ -662,11 +660,11 @@
       // Calculate exact limit here.
       // Note, counted loop's test is '<' or '>'.
       limit = exact_limit(loop);
-      max_idx_expr = new (C, 3) SubINode(limit, stride);
+      max_idx_expr = new (C) SubINode(limit, stride);
       register_new_node(max_idx_expr, ctrl);
       if (TraceLoopPredicate) predString->print("(limit - stride) ");
     } else {
-      max_idx_expr = new (C, 3) SubINode(limit, stride);
+      max_idx_expr = new (C) SubINode(limit, stride);
       register_new_node(max_idx_expr, ctrl);
       if (TraceLoopPredicate) predString->print("(limit - stride) ");
     }
@@ -676,22 +674,22 @@
 
   if (scale != 1) {
     ConNode* con_scale = _igvn.intcon(scale);
-    max_idx_expr = new (C, 3) MulINode(max_idx_expr, con_scale);
+    max_idx_expr = new (C) MulINode(max_idx_expr, con_scale);
     register_new_node(max_idx_expr, ctrl);
     if (TraceLoopPredicate) predString->print("* %d ", scale);
   }
 
   if (offset && (!offset->is_Con() || offset->get_int() != 0)){
-    max_idx_expr = new (C, 3) AddINode(max_idx_expr, offset);
+    max_idx_expr = new (C) AddINode(max_idx_expr, offset);
     register_new_node(max_idx_expr, ctrl);
     if (TraceLoopPredicate)
       if (offset->is_Con()) predString->print("+ %d ", offset->get_int());
       else predString->print("+ offset ");
   }
 
-  CmpUNode* cmp = new (C, 3) CmpUNode(max_idx_expr, range);
+  CmpUNode* cmp = new (C) CmpUNode(max_idx_expr, range);
   register_new_node(cmp, ctrl);
-  BoolNode* bol = new (C, 2) BoolNode(cmp, BoolTest::lt);
+  BoolNode* bol = new (C) BoolNode(cmp, BoolTest::lt);
   register_new_node(bol, ctrl);
 
   if (TraceLoopPredicate) {
@@ -807,7 +805,7 @@
       // Negate test if necessary
       bool negated = false;
       if (proj->_con != predicate_proj->_con) {
-        new_predicate_bol = new (C, 2) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
+        new_predicate_bol = new (C) BoolNode(new_predicate_bol->in(1), new_predicate_bol->_test.negate());
         register_new_node(new_predicate_bol, ctrl);
         negated = true;
       }
diff --git a/hotspot/src/share/vm/opto/loopTransform.cpp b/hotspot/src/share/vm/opto/loopTransform.cpp
index d0b790a..71f694a 100644
--- a/hotspot/src/share/vm/opto/loopTransform.cpp
+++ b/hotspot/src/share/vm/opto/loopTransform.cpp
@@ -92,10 +92,10 @@
       limit_n != NULL && limit_n->is_Con()) {
     // Use longs to avoid integer overflow.
     int stride_con  = cl->stride_con();
-    long init_con   = cl->init_trip()->get_int();
-    long limit_con  = cl->limit()->get_int();
+    jlong init_con   = cl->init_trip()->get_int();
+    jlong limit_con  = cl->limit()->get_int();
     int stride_m    = stride_con - (stride_con > 0 ? 1 : -1);
-    long trip_count = (limit_con - init_con + stride_m)/stride_con;
+    jlong trip_count = (limit_con - init_con + stride_m)/stride_con;
     if (trip_count > 0 && (julong)trip_count < (julong)max_juint) {
       // Set exact trip count.
       cl->set_exact_trip_count((uint)trip_count);
@@ -224,24 +224,24 @@
   if (neg_inv1) {
     Node *zero = phase->_igvn.intcon(0);
     phase->set_ctrl(zero, phase->C->root());
-    n_inv1 = new (phase->C, 3) SubINode(zero, inv1);
+    n_inv1 = new (phase->C) SubINode(zero, inv1);
     phase->register_new_node(n_inv1, inv1_c);
   } else {
     n_inv1 = inv1;
   }
   Node* inv;
   if (neg_inv2) {
-    inv = new (phase->C, 3) SubINode(n_inv1, inv2);
+    inv = new (phase->C) SubINode(n_inv1, inv2);
   } else {
-    inv = new (phase->C, 3) AddINode(n_inv1, inv2);
+    inv = new (phase->C) AddINode(n_inv1, inv2);
   }
   phase->register_new_node(inv, phase->get_early_ctrl(inv));
 
   Node* addx;
   if (neg_x) {
-    addx = new (phase->C, 3) SubINode(inv, x);
+    addx = new (phase->C) SubINode(inv, x);
   } else {
-    addx = new (phase->C, 3) AddINode(x, inv);
+    addx = new (phase->C) AddINode(x, inv);
   }
   phase->register_new_node(addx, phase->get_ctrl(x));
   phase->_igvn.replace_node(n1, addx);
@@ -547,11 +547,6 @@
     Node *nnn = old_new[old->_idx];
     if (!has_ctrl(nnn))
       set_idom(nnn, idom(nnn), dd-1);
-    // While we're at it, remove any SafePoints from the peeled code
-    if (old->Opcode() == Op_SafePoint) {
-      Node *nnn = old_new[old->_idx];
-      lazy_replace(nnn,nnn->in(TypeFunc::Control));
-    }
   }
 
   // Now force out all loop-invariant dominating tests.  The optimizer
@@ -937,7 +932,7 @@
   post_end->_prob = PROB_FAIR;
 
   // Build the main-loop normal exit.
-  IfFalseNode *new_main_exit = new (C, 1) IfFalseNode(main_end);
+  IfFalseNode *new_main_exit = new (C) IfFalseNode(main_end);
   _igvn.register_new_node_with_optimizer( new_main_exit );
   set_idom(new_main_exit, main_end, dd_main_exit );
   set_loop(new_main_exit, loop->_parent);
@@ -947,27 +942,25 @@
   // (the main-loop trip-counter exit value) because we will be changing
   // the exit value (via unrolling) so we cannot constant-fold away the zero
   // trip guard until all unrolling is done.
-  Node *zer_opaq = new (C, 2) Opaque1Node(C, incr);
-  Node *zer_cmp  = new (C, 3) CmpINode( zer_opaq, limit );
-  Node *zer_bol  = new (C, 2) BoolNode( zer_cmp, b_test );
+  Node *zer_opaq = new (C) Opaque1Node(C, incr);
+  Node *zer_cmp  = new (C) CmpINode( zer_opaq, limit );
+  Node *zer_bol  = new (C) BoolNode( zer_cmp, b_test );
   register_new_node( zer_opaq, new_main_exit );
   register_new_node( zer_cmp , new_main_exit );
   register_new_node( zer_bol , new_main_exit );
 
   // Build the IfNode
-  IfNode *zer_iff = new (C, 2) IfNode( new_main_exit, zer_bol, PROB_FAIR, COUNT_UNKNOWN );
+  IfNode *zer_iff = new (C) IfNode( new_main_exit, zer_bol, PROB_FAIR, COUNT_UNKNOWN );
   _igvn.register_new_node_with_optimizer( zer_iff );
   set_idom(zer_iff, new_main_exit, dd_main_exit);
   set_loop(zer_iff, loop->_parent);
 
   // Plug in the false-path, taken if we need to skip post-loop
-  _igvn.hash_delete( main_exit );
-  main_exit->set_req(0, zer_iff);
-  _igvn._worklist.push(main_exit);
+  _igvn.replace_input_of(main_exit, 0, zer_iff);
   set_idom(main_exit, zer_iff, dd_main_exit);
   set_idom(main_exit->unique_out(), zer_iff, dd_main_exit);
   // Make the true-path, must enter the post loop
-  Node *zer_taken = new (C, 1) IfTrueNode( zer_iff );
+  Node *zer_taken = new (C) IfTrueNode( zer_iff );
   _igvn.register_new_node_with_optimizer( zer_taken );
   set_idom(zer_taken, zer_iff, dd_main_exit);
   set_loop(zer_taken, loop->_parent);
@@ -1015,7 +1008,7 @@
   // Find the pre-loop normal exit.
   Node* pre_exit = pre_end->proj_out(false);
   assert( pre_exit->Opcode() == Op_IfFalse, "" );
-  IfFalseNode *new_pre_exit = new (C, 1) IfFalseNode(pre_end);
+  IfFalseNode *new_pre_exit = new (C) IfFalseNode(pre_end);
   _igvn.register_new_node_with_optimizer( new_pre_exit );
   set_idom(new_pre_exit, pre_end, dd_main_head);
   set_loop(new_pre_exit, loop->_parent);
@@ -1024,15 +1017,15 @@
   // pre-loop, the main-loop may not execute at all.  Later in life this
   // zero-trip guard will become the minimum-trip guard when we unroll
   // the main-loop.
-  Node *min_opaq = new (C, 2) Opaque1Node(C, limit);
-  Node *min_cmp  = new (C, 3) CmpINode( pre_incr, min_opaq );
-  Node *min_bol  = new (C, 2) BoolNode( min_cmp, b_test );
+  Node *min_opaq = new (C) Opaque1Node(C, limit);
+  Node *min_cmp  = new (C) CmpINode( pre_incr, min_opaq );
+  Node *min_bol  = new (C) BoolNode( min_cmp, b_test );
   register_new_node( min_opaq, new_pre_exit );
   register_new_node( min_cmp , new_pre_exit );
   register_new_node( min_bol , new_pre_exit );
 
   // Build the IfNode (assume the main-loop is executed always).
-  IfNode *min_iff = new (C, 2) IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN );
+  IfNode *min_iff = new (C) IfNode( new_pre_exit, min_bol, PROB_ALWAYS, COUNT_UNKNOWN );
   _igvn.register_new_node_with_optimizer( min_iff );
   set_idom(min_iff, new_pre_exit, dd_main_head);
   set_loop(min_iff, loop->_parent);
@@ -1043,7 +1036,7 @@
   set_idom(pre_exit, min_iff, dd_main_head);
   set_idom(pre_exit->unique_out(), min_iff, dd_main_head);
   // Make the true-path, must enter the main loop
-  Node *min_taken = new (C, 1) IfTrueNode( min_iff );
+  Node *min_taken = new (C) IfTrueNode( min_iff );
   _igvn.register_new_node_with_optimizer( min_taken );
   set_idom(min_taken, min_iff, dd_main_head);
   set_loop(min_taken, loop->_parent);
@@ -1073,11 +1066,11 @@
   // RCE and alignment may change this later.
   Node *cmp_end = pre_end->cmp_node();
   assert( cmp_end->in(2) == limit, "" );
-  Node *pre_limit = new (C, 3) AddINode( init, stride );
+  Node *pre_limit = new (C) AddINode( init, stride );
 
   // Save the original loop limit in this Opaque1 node for
   // use by range check elimination.
-  Node *pre_opaq  = new (C, 3) Opaque1Node(C, pre_limit, limit);
+  Node *pre_opaq  = new (C) Opaque1Node(C, pre_limit, limit);
 
   register_new_node( pre_limit, pre_head->in(0) );
   register_new_node( pre_opaq , pre_head->in(0) );
@@ -1102,19 +1095,19 @@
     BoolTest::mask new_test = (main_end->stride_con() > 0) ? BoolTest::lt : BoolTest::gt;
     // Modify pre loop end condition
     Node* pre_bol = pre_end->in(CountedLoopEndNode::TestValue)->as_Bool();
-    BoolNode* new_bol0 = new (C, 2) BoolNode(pre_bol->in(1), new_test);
+    BoolNode* new_bol0 = new (C) BoolNode(pre_bol->in(1), new_test);
     register_new_node( new_bol0, pre_head->in(0) );
     _igvn.hash_delete(pre_end);
     pre_end->set_req(CountedLoopEndNode::TestValue, new_bol0);
     // Modify main loop guard condition
     assert(min_iff->in(CountedLoopEndNode::TestValue) == min_bol, "guard okay");
-    BoolNode* new_bol1 = new (C, 2) BoolNode(min_bol->in(1), new_test);
+    BoolNode* new_bol1 = new (C) BoolNode(min_bol->in(1), new_test);
     register_new_node( new_bol1, new_pre_exit );
     _igvn.hash_delete(min_iff);
     min_iff->set_req(CountedLoopEndNode::TestValue, new_bol1);
     // Modify main loop end condition
     BoolNode* main_bol = main_end->in(CountedLoopEndNode::TestValue)->as_Bool();
-    BoolNode* new_bol2 = new (C, 2) BoolNode(main_bol->in(1), new_test);
+    BoolNode* new_bol2 = new (C) BoolNode(main_bol->in(1), new_test);
     register_new_node( new_bol2, main_end->in(CountedLoopEndNode::TestControl) );
     _igvn.hash_delete(main_end);
     main_end->set_req(CountedLoopEndNode::TestValue, new_bol2);
@@ -1219,16 +1212,16 @@
     } else if (loop_head->has_exact_trip_count() && init->is_Con()) {
       // Loop's limit is constant. Loop's init could be constant when pre-loop
       // become peeled iteration.
-      long init_con = init->get_int();
+      jlong init_con = init->get_int();
       // We can keep old loop limit if iterations count stays the same:
       //   old_trip_count == new_trip_count * 2
       // Note: since old_trip_count >= 2 then new_trip_count >= 1
       // so we also don't need to adjust zero trip test.
-      long limit_con  = limit->get_int();
+      jlong limit_con  = limit->get_int();
       // (stride_con*2) not overflow since stride_con <= 8.
       int new_stride_con = stride_con * 2;
       int stride_m    = new_stride_con - (stride_con > 0 ? 1 : -1);
-      long trip_count = (limit_con - init_con + stride_m)/new_stride_con;
+      jlong trip_count = (limit_con - init_con + stride_m)/new_stride_con;
       // New trip count should satisfy next conditions.
       assert(trip_count > 0 && (julong)trip_count < (julong)max_juint/2, "sanity");
       uint new_trip_count = (uint)trip_count;
@@ -1264,13 +1257,13 @@
           // zero trip guard limit will be different from loop limit.
           assert(has_ctrl(opaq), "should have it");
           Node* opaq_ctrl = get_ctrl(opaq);
-          limit = new (C, 2) Opaque2Node( C, limit );
+          limit = new (C) Opaque2Node( C, limit );
           register_new_node( limit, opaq_ctrl );
         }
         if (stride_con > 0 && ((limit_type->_lo - stride_con) < limit_type->_lo) ||
                    stride_con < 0 && ((limit_type->_hi - stride_con) > limit_type->_hi)) {
           // No underflow.
-          new_limit = new (C, 3) SubINode(limit, stride);
+          new_limit = new (C) SubINode(limit, stride);
         } else {
           // (limit - stride) may underflow.
           // Clamp the adjustment value with MININT or MAXINT:
@@ -1300,18 +1293,18 @@
             old_limit = bol->in(1)->in(1);
             // Adjust previous adjusted limit.
             adj_limit = limit->in(CMoveNode::IfFalse);
-            adj_limit = new (C, 3) SubINode(adj_limit, stride);
+            adj_limit = new (C) SubINode(adj_limit, stride);
           } else {
             old_limit = limit;
-            adj_limit = new (C, 3) SubINode(limit, stride);
+            adj_limit = new (C) SubINode(limit, stride);
           }
           assert(old_limit != NULL && adj_limit != NULL, "");
           register_new_node( adj_limit, ctrl ); // adjust amount
-          Node* adj_cmp = new (C, 3) CmpINode(old_limit, adj_limit);
+          Node* adj_cmp = new (C) CmpINode(old_limit, adj_limit);
           register_new_node( adj_cmp, ctrl );
-          Node* adj_bool = new (C, 2) BoolNode(adj_cmp, bt);
+          Node* adj_bool = new (C) BoolNode(adj_cmp, bt);
           register_new_node( adj_bool, ctrl );
-          new_limit = new (C, 4) CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT);
+          new_limit = new (C) CMoveINode(adj_bool, adj_limit, adj_max, TypeInt::INT);
         }
         register_new_node(new_limit, ctrl);
       }
@@ -1373,24 +1366,24 @@
     // CountedLoop this is exact (stride divides limit-init exactly).
     // We are going to double the loop body, so we want to knock off any
     // odd iteration: (trip_cnt & ~1).  Then back compute a new limit.
-    Node *span = new (C, 3) SubINode( limit, init );
+    Node *span = new (C) SubINode( limit, init );
     register_new_node( span, ctrl );
-    Node *trip = new (C, 3) DivINode( 0, span, stride );
+    Node *trip = new (C) DivINode( 0, span, stride );
     register_new_node( trip, ctrl );
     Node *mtwo = _igvn.intcon(-2);
     set_ctrl(mtwo, C->root());
-    Node *rond = new (C, 3) AndINode( trip, mtwo );
+    Node *rond = new (C) AndINode( trip, mtwo );
     register_new_node( rond, ctrl );
-    Node *spn2 = new (C, 3) MulINode( rond, stride );
+    Node *spn2 = new (C) MulINode( rond, stride );
     register_new_node( spn2, ctrl );
-    new_limit = new (C, 3) AddINode( spn2, init );
+    new_limit = new (C) AddINode( spn2, init );
     register_new_node( new_limit, ctrl );
 
     // Hammer in the new limit
     Node *ctrl2 = loop_end->in(0);
-    Node *cmp2 = new (C, 3) CmpINode( loop_head->incr(), new_limit );
+    Node *cmp2 = new (C) CmpINode( loop_head->incr(), new_limit );
     register_new_node( cmp2, ctrl2 );
-    Node *bol2 = new (C, 2) BoolNode( cmp2, loop_end->test_trip() );
+    Node *bol2 = new (C) BoolNode( cmp2, loop_end->test_trip() );
     register_new_node( bol2, ctrl2 );
     _igvn.hash_delete(loop_end);
     loop_end->set_req(CountedLoopEndNode::TestValue, bol2);
@@ -1496,15 +1489,15 @@
 // Helper function for add_constraint().
 Node* PhaseIdealLoop::adjust_limit(int stride_con, Node * scale, Node *offset, Node *rc_limit, Node *loop_limit, Node *pre_ctrl) {
   // Compute "I :: (limit-offset)/scale"
-  Node *con = new (C, 3) SubINode(rc_limit, offset);
+  Node *con = new (C) SubINode(rc_limit, offset);
   register_new_node(con, pre_ctrl);
-  Node *X = new (C, 3) DivINode(0, con, scale);
+  Node *X = new (C) DivINode(0, con, scale);
   register_new_node(X, pre_ctrl);
 
   // Adjust loop limit
   loop_limit = (stride_con > 0)
-               ? (Node*)(new (C, 3) MinINode(loop_limit, X))
-               : (Node*)(new (C, 3) MaxINode(loop_limit, X));
+               ? (Node*)(new (C) MinINode(loop_limit, X))
+               : (Node*)(new (C) MaxINode(loop_limit, X));
   register_new_node(loop_limit, pre_ctrl);
   return loop_limit;
 }
@@ -1565,9 +1558,9 @@
       // to avoid problem with scale == -1 (min_int/(-1) == min_int).
       Node* shift = _igvn.intcon(31);
       set_ctrl(shift, C->root());
-      Node* sign = new (C, 3) RShiftINode(offset, shift);
+      Node* sign = new (C) RShiftINode(offset, shift);
       register_new_node(sign, pre_ctrl);
-      offset = new (C, 3) AndINode(offset, sign);
+      offset = new (C) AndINode(offset, sign);
       register_new_node(offset, pre_ctrl);
     } else {
       assert(low_limit->get_int() == 0, "wrong low limit for range check");
@@ -1600,7 +1593,7 @@
     Node *one  = _igvn.intcon(1);
     set_ctrl(one, C->root());
 
-    Node *plus_one = new (C, 3) AddINode(offset, one);
+    Node *plus_one = new (C) AddINode(offset, one);
     register_new_node( plus_one, pre_ctrl );
     // Pass (-stride) to indicate pre_loop_cond = NOT(main_loop_cond);
     *pre_limit = adjust_limit((-stride_con), scale, plus_one, upper_limit, *pre_limit, pre_ctrl);
@@ -1618,9 +1611,9 @@
       // to avoid problem with scale == -1 (min_int/(-1) == min_int).
       Node* shift = _igvn.intcon(31);
       set_ctrl(shift, C->root());
-      Node* sign = new (C, 3) RShiftINode(plus_one, shift);
+      Node* sign = new (C) RShiftINode(plus_one, shift);
       register_new_node(sign, pre_ctrl);
-      plus_one = new (C, 3) AndINode(plus_one, sign);
+      plus_one = new (C) AndINode(plus_one, sign);
       register_new_node(plus_one, pre_ctrl);
     } else {
       assert(low_limit->get_int() == 0, "wrong low limit for range check");
@@ -1703,7 +1696,7 @@
                                    p_offset != NULL ? &offset2 : NULL, depth+1)) {
         if (p_offset != NULL) {
           Node *ctrl_off2 = get_ctrl(offset2);
-          Node* offset = new (C, 3) AddINode(offset2, exp->in(2));
+          Node* offset = new (C) AddINode(offset2, exp->in(2));
           register_new_node(offset, ctrl_off2);
           *p_offset = offset;
         }
@@ -1716,7 +1709,7 @@
         Node *zero = _igvn.intcon(0);
         set_ctrl(zero, C->root());
         Node *ctrl_off = get_ctrl(exp->in(2));
-        Node* offset = new (C, 3) SubINode(zero, exp->in(2));
+        Node* offset = new (C) SubINode(zero, exp->in(2));
         register_new_node(offset, ctrl_off);
         *p_offset = offset;
       }
@@ -1919,15 +1912,15 @@
         case BoolTest::ge:
           // Convert (I*scale+offset) >= Limit to (I*(-scale)+(-offset)) <= -Limit
           scale_con = -scale_con;
-          offset = new (C, 3) SubINode( zero, offset );
+          offset = new (C) SubINode( zero, offset );
           register_new_node( offset, pre_ctrl );
-          limit  = new (C, 3) SubINode( zero, limit  );
+          limit  = new (C) SubINode( zero, limit  );
           register_new_node( limit, pre_ctrl );
           // Fall into LE case
         case BoolTest::le:
           if (b_test._test != BoolTest::gt) {
             // Convert X <= Y to X < Y+1
-            limit = new (C, 3) AddINode( limit, one );
+            limit = new (C) AddINode( limit, one );
             register_new_node( limit, pre_ctrl );
           }
           // Fall into LT case
@@ -1956,9 +1949,7 @@
       C->set_major_progress();
       Node *kill_con = _igvn.intcon( 1-flip );
       set_ctrl(kill_con, C->root());
-      _igvn.hash_delete(iff);
-      iff->set_req(1, kill_con);
-      _igvn._worklist.push(iff);
+      _igvn.replace_input_of(iff, 1, kill_con);
       // Find surviving projection
       assert(iff->is_If(), "");
       ProjNode* dp = ((IfNode*)iff)->proj_out(1-flip);
@@ -1966,11 +1957,9 @@
       for (DUIterator_Fast imax, i = dp->fast_outs(imax); i < imax; i++) {
         Node* cd = dp->fast_out(i); // Control-dependent node
         if( cd->is_Load() ) {   // Loads can now float around in the loop
-          _igvn.hash_delete(cd);
           // Allow the load to float around in the loop, or before it
           // but NOT before the pre-loop.
-          cd->set_req(0, ctrl);   // ctrl, not NULL
-          _igvn._worklist.push(cd);
+          _igvn.replace_input_of(cd, 0, ctrl); // ctrl, not NULL
           --i;
           --imax;
         }
@@ -1982,8 +1971,8 @@
 
   // Update loop limits
   if (conditional_rc) {
-    pre_limit = (stride_con > 0) ? (Node*)new (C,3) MinINode(pre_limit, orig_limit)
-                                 : (Node*)new (C,3) MaxINode(pre_limit, orig_limit);
+    pre_limit = (stride_con > 0) ? (Node*)new (C) MinINode(pre_limit, orig_limit)
+                                 : (Node*)new (C) MaxINode(pre_limit, orig_limit);
     register_new_node(pre_limit, pre_ctrl);
   }
   _igvn.hash_delete(pre_opaq);
@@ -1998,16 +1987,16 @@
     Node *ctrl = get_ctrl(main_limit);
     Node *stride = cl->stride();
     Node *init = cl->init_trip();
-    Node *span = new (C, 3) SubINode(main_limit,init);
+    Node *span = new (C) SubINode(main_limit,init);
     register_new_node(span,ctrl);
     Node *rndup = _igvn.intcon(stride_con + ((stride_con>0)?-1:1));
-    Node *add = new (C, 3) AddINode(span,rndup);
+    Node *add = new (C) AddINode(span,rndup);
     register_new_node(add,ctrl);
-    Node *div = new (C, 3) DivINode(0,add,stride);
+    Node *div = new (C) DivINode(0,add,stride);
     register_new_node(div,ctrl);
-    Node *mul = new (C, 3) MulINode(div,stride);
+    Node *mul = new (C) MulINode(div,stride);
     register_new_node(mul,ctrl);
-    Node *newlim = new (C, 3) AddINode(mul,init);
+    Node *newlim = new (C) AddINode(mul,init);
     register_new_node(newlim,ctrl);
     main_limit = newlim;
   }
@@ -2029,14 +2018,10 @@
     main_bol->set_req(1,main_cmp);
   }
   // Hack the now-private loop bounds
-  _igvn.hash_delete(main_cmp);
-  main_cmp->set_req(2, main_limit);
-  _igvn._worklist.push(main_cmp);
+  _igvn.replace_input_of(main_cmp, 2, main_limit);
   // The OpaqueNode is unshared by design
-  _igvn.hash_delete(opqzm);
   assert( opqzm->outcnt() == 1, "cannot hack shared node" );
-  opqzm->set_req(1,main_limit);
-  _igvn._worklist.push(opqzm);
+  _igvn.replace_input_of(opqzm, 1, main_limit);
 }
 
 //------------------------------DCE_loop_body----------------------------------
@@ -2178,13 +2163,11 @@
     Node* cmp = cl->loopexit()->cmp_node();
     assert(cl->limit() == cmp->in(2), "sanity");
     phase->_igvn._worklist.push(cmp->in(2)); // put limit on worklist
-    phase->_igvn.hash_delete(cmp);
-    cmp->set_req(2, exact_limit);
-    phase->_igvn._worklist.push(cmp);        // put cmp on worklist
+    phase->_igvn.replace_input_of(cmp, 2, exact_limit); // put cmp on worklist
   }
   // Note: the final value after increment should not overflow since
   // counted loop has limit check predicate.
-  Node *final = new (phase->C, 3) SubINode( exact_limit, cl->stride() );
+  Node *final = new (phase->C) SubINode( exact_limit, cl->stride() );
   phase->register_new_node(final,cl->in(LoopNode::EntryControl));
   phase->_igvn.replace_node(phi,final);
   phase->C->set_major_progress();
@@ -2668,20 +2651,20 @@
   // Build an expression for the beginning of the copy region
   Node* index = head->init_trip();
 #ifdef _LP64
-  index = new (C, 2) ConvI2LNode(index);
+  index = new (C) ConvI2LNode(index);
   _igvn.register_new_node_with_optimizer(index);
 #endif
   if (shift != NULL) {
     // byte arrays don't require a shift but others do.
-    index = new (C, 3) LShiftXNode(index, shift->in(2));
+    index = new (C) LShiftXNode(index, shift->in(2));
     _igvn.register_new_node_with_optimizer(index);
   }
-  index = new (C, 4) AddPNode(base, base, index);
+  index = new (C) AddPNode(base, base, index);
   _igvn.register_new_node_with_optimizer(index);
-  Node* from = new (C, 4) AddPNode(base, index, offset);
+  Node* from = new (C) AddPNode(base, index, offset);
   _igvn.register_new_node_with_optimizer(from);
   // Compute the number of elements to copy
-  Node* len = new (C, 3) SubINode(head->limit(), head->init_trip());
+  Node* len = new (C) SubINode(head->limit(), head->init_trip());
   _igvn.register_new_node_with_optimizer(len);
 
   BasicType t = store->as_Mem()->memory_type();
@@ -2698,10 +2681,10 @@
 
   // Convert float/double to int/long for fill routines
   if (t == T_FLOAT) {
-    store_value = new (C, 2) MoveF2INode(store_value);
+    store_value = new (C) MoveF2INode(store_value);
     _igvn.register_new_node_with_optimizer(store_value);
   } else if (t == T_DOUBLE) {
-    store_value = new (C, 2) MoveD2LNode(store_value);
+    store_value = new (C) MoveD2LNode(store_value);
     _igvn.register_new_node_with_optimizer(store_value);
   }
 
@@ -2709,13 +2692,12 @@
   Node* result_ctrl;
   Node* result_mem;
   const TypeFunc* call_type = OptoRuntime::array_fill_Type();
-  int size = call_type->domain()->cnt();
-  CallLeafNode *call = new (C, size) CallLeafNoFPNode(call_type, fill,
-                                                      fill_name, TypeAryPtr::get_array_body_type(t));
+  CallLeafNode *call = new (C) CallLeafNoFPNode(call_type, fill,
+                                                fill_name, TypeAryPtr::get_array_body_type(t));
   call->init_req(TypeFunc::Parms+0, from);
   call->init_req(TypeFunc::Parms+1, store_value);
 #ifdef _LP64
-  len = new (C, 2) ConvI2LNode(len);
+  len = new (C) ConvI2LNode(len);
   _igvn.register_new_node_with_optimizer(len);
 #endif
   call->init_req(TypeFunc::Parms+2, len);
@@ -2728,9 +2710,9 @@
   call->init_req( TypeFunc::ReturnAdr, C->start()->proj_out(TypeFunc::ReturnAdr) );
   call->init_req( TypeFunc::FramePtr, C->start()->proj_out(TypeFunc::FramePtr) );
   _igvn.register_new_node_with_optimizer(call);
-  result_ctrl = new (C, 1) ProjNode(call,TypeFunc::Control);
+  result_ctrl = new (C) ProjNode(call,TypeFunc::Control);
   _igvn.register_new_node_with_optimizer(result_ctrl);
-  result_mem = new (C, 1) ProjNode(call,TypeFunc::Memory);
+  result_mem = new (C) ProjNode(call,TypeFunc::Memory);
   _igvn.register_new_node_with_optimizer(result_mem);
 
 /* Disable following optimization until proper fix (add missing checks).
diff --git a/hotspot/src/share/vm/opto/loopUnswitch.cpp b/hotspot/src/share/vm/opto/loopUnswitch.cpp
index 20ddf78..1470598 100644
--- a/hotspot/src/share/vm/opto/loopUnswitch.cpp
+++ b/hotspot/src/share/vm/opto/loopUnswitch.cpp
@@ -174,27 +174,21 @@
       Node* use = worklist.pop();
       Node* nuse = use->clone();
       nuse->set_req(0, invar_proj);
-      _igvn.hash_delete(use);
-      use->set_req(1, nuse);
-      _igvn._worklist.push(use);
+      _igvn.replace_input_of(use, 1, nuse);
       register_new_node(nuse, invar_proj);
       // Same for the clone
       Node* use_clone = old_new[use->_idx];
-      _igvn.hash_delete(use_clone);
-      use_clone->set_req(1, nuse);
-      _igvn._worklist.push(use_clone);
+      _igvn.replace_input_of(use_clone, 1, nuse);
     }
   }
 
   // Hardwire the control paths in the loops into if(true) and if(false)
-  _igvn.hash_delete(unswitch_iff);
+  _igvn.rehash_node_delayed(unswitch_iff);
   short_circuit_if(unswitch_iff, proj_true);
-  _igvn._worklist.push(unswitch_iff);
 
   IfNode* unswitch_iff_clone = old_new[unswitch_iff->_idx]->as_If();
-  _igvn.hash_delete(unswitch_iff_clone);
+  _igvn.rehash_node_delayed(unswitch_iff_clone);
   short_circuit_if(unswitch_iff_clone, proj_false);
-  _igvn._worklist.push(unswitch_iff_clone);
 
   // Reoptimize loops
   loop->record_for_igvn();
@@ -224,21 +218,20 @@
   LoopNode* head  = loop->_head->as_Loop();
   bool counted_loop = head->is_CountedLoop();
   Node*     entry = head->in(LoopNode::EntryControl);
-  _igvn.hash_delete(entry);
-  _igvn._worklist.push(entry);
+  _igvn.rehash_node_delayed(entry);
   IdealLoopTree* outer_loop = loop->_parent;
 
   Node *cont      = _igvn.intcon(1);
   set_ctrl(cont, C->root());
-  Node* opq       = new (C, 2) Opaque1Node(C, cont);
+  Node* opq       = new (C) Opaque1Node(C, cont);
   register_node(opq, outer_loop, entry, dom_depth(entry));
-  Node *bol       = new (C, 2) Conv2BNode(opq);
+  Node *bol       = new (C) Conv2BNode(opq);
   register_node(bol, outer_loop, entry, dom_depth(entry));
-  IfNode* iff = new (C, 2) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
+  IfNode* iff = new (C) IfNode(entry, bol, PROB_MAX, COUNT_UNKNOWN);
   register_node(iff, outer_loop, entry, dom_depth(entry));
-  ProjNode* iffast = new (C, 1) IfTrueNode(iff);
+  ProjNode* iffast = new (C) IfTrueNode(iff);
   register_node(iffast, outer_loop, iff, dom_depth(iff));
-  ProjNode* ifslow = new (C, 1) IfFalseNode(iff);
+  ProjNode* ifslow = new (C) IfFalseNode(iff);
   register_node(ifslow, outer_loop, iff, dom_depth(iff));
 
   // Clone the loop body.  The clone becomes the fast loop.  The
@@ -249,18 +242,14 @@
 
   // Fast (true) control
   Node* iffast_pred = clone_loop_predicates(entry, iffast, !counted_loop);
-  _igvn.hash_delete(head);
-  head->set_req(LoopNode::EntryControl, iffast_pred);
+  _igvn.replace_input_of(head, LoopNode::EntryControl, iffast_pred);
   set_idom(head, iffast_pred, dom_depth(head));
-  _igvn._worklist.push(head);
 
   // Slow (false) control
   Node* ifslow_pred = clone_loop_predicates(entry, ifslow, !counted_loop);
   LoopNode* slow_head = old_new[head->_idx]->as_Loop();
-  _igvn.hash_delete(slow_head);
-  slow_head->set_req(LoopNode::EntryControl, ifslow_pred);
+  _igvn.replace_input_of(slow_head, LoopNode::EntryControl, ifslow_pred);
   set_idom(slow_head, ifslow_pred, dom_depth(slow_head));
-  _igvn._worklist.push(slow_head);
 
   recompute_dom_depth();
 
diff --git a/hotspot/src/share/vm/opto/loopnode.cpp b/hotspot/src/share/vm/opto/loopnode.cpp
index 2d045e4..a483f01 100644
--- a/hotspot/src/share/vm/opto/loopnode.cpp
+++ b/hotspot/src/share/vm/opto/loopnode.cpp
@@ -328,12 +328,12 @@
   const TypeInt* limit_t = gvn->type(limit)->is_int();
 
   if (stride_con > 0) {
-    long init_p = (long)init_t->_lo + stride_con;
-    if (init_p > (long)max_jint || init_p > (long)limit_t->_hi)
+    jlong init_p = (jlong)init_t->_lo + stride_con;
+    if (init_p > (jlong)max_jint || init_p > (jlong)limit_t->_hi)
       return false; // cyclic loop or this loop trips only once
   } else {
-    long init_p = (long)init_t->_hi + stride_con;
-    if (init_p < (long)min_jint || init_p < (long)limit_t->_lo)
+    jlong init_p = (jlong)init_t->_hi + stride_con;
+    if (init_p < (jlong)min_jint || init_p < (jlong)limit_t->_lo)
       return false; // cyclic loop or this loop trips only once
   }
 
@@ -343,7 +343,7 @@
   assert(x->Opcode() == Op_Loop, "regular loops only");
   C->print_method("Before CountedLoop", 3);
 
-  Node *hook = new (C, 6) Node(6);
+  Node *hook = new (C) Node(6);
 
   if (LoopLimitCheck) {
 
@@ -406,11 +406,11 @@
     Node* bol;
 
     if (stride_con > 0) {
-      cmp_limit = new (C, 3) CmpINode(limit, _igvn.intcon(max_jint - stride_m));
-      bol = new (C, 2) BoolNode(cmp_limit, BoolTest::le);
+      cmp_limit = new (C) CmpINode(limit, _igvn.intcon(max_jint - stride_m));
+      bol = new (C) BoolNode(cmp_limit, BoolTest::le);
     } else {
-      cmp_limit = new (C, 3) CmpINode(limit, _igvn.intcon(min_jint - stride_m));
-      bol = new (C, 2) BoolNode(cmp_limit, BoolTest::ge);
+      cmp_limit = new (C) CmpINode(limit, _igvn.intcon(min_jint - stride_m));
+      bol = new (C) BoolNode(cmp_limit, BoolTest::ge);
     }
     cmp_limit = _igvn.register_new_node_with_optimizer(cmp_limit);
     bol = _igvn.register_new_node_with_optimizer(bol);
@@ -447,7 +447,7 @@
     // is converted to
     //   i = init; do {} while(++i < limit+1);
     //
-    limit = gvn->transform(new (C, 3) AddINode(limit, stride));
+    limit = gvn->transform(new (C) AddINode(limit, stride));
   }
 
   // Now we need to canonicalize loop condition.
@@ -466,7 +466,7 @@
     // we can convert 'i <= limit' to 'i < limit+1' since stride != 0.
     //
     Node* one = (stride_con > 0) ? gvn->intcon( 1) : gvn->intcon(-1);
-    limit = gvn->transform(new (C, 3) AddINode(limit, one));
+    limit = gvn->transform(new (C) AddINode(limit, one));
     if (bt == BoolTest::le)
       bt = BoolTest::lt;
     else if (bt == BoolTest::ge)
@@ -482,7 +482,7 @@
   // can directly point to the phi; in this case adjust the compare so that
   // it points to the incr by adjusting the limit.
   if (cmp->in(1) == phi || cmp->in(2) == phi)
-    limit = gvn->transform(new (C, 3) AddINode(limit,stride));
+    limit = gvn->transform(new (C) AddINode(limit,stride));
 
   // trip-count for +-tive stride should be: (limit - init_trip + stride - 1)/stride.
   // Final value for iterator should be: trip_count * stride + init_trip.
@@ -495,16 +495,16 @@
     ShouldNotReachHere();
   case BoolTest::ne:            // Ahh, the case we desire
     if (stride_con == 1)
-      trip_count = gvn->transform(new (C, 3) SubINode(limit,init_trip));
+      trip_count = gvn->transform(new (C) SubINode(limit,init_trip));
     else if (stride_con == -1)
-      trip_count = gvn->transform(new (C, 3) SubINode(init_trip,limit));
+      trip_count = gvn->transform(new (C) SubINode(init_trip,limit));
     else
       ShouldNotReachHere();
     set_subtree_ctrl(trip_count);
     //_loop.map(trip_count->_idx,loop(limit));
     break;
   case BoolTest::le:            // Maybe convert to '<' case
-    limit = gvn->transform(new (C, 3) AddINode(limit,one_p));
+    limit = gvn->transform(new (C) AddINode(limit,one_p));
     set_subtree_ctrl( limit );
     hook->init_req(4, limit);
 
@@ -515,26 +515,26 @@
   case BoolTest::lt: {          // Maybe convert to '!=' case
     if (stride_con < 0) // Count down loop rolls through MAXINT
       ShouldNotReachHere();
-    Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip));
+    Node *range = gvn->transform(new (C) SubINode(limit,init_trip));
     set_subtree_ctrl( range );
     hook->init_req(0, range);
 
-    Node *bias  = gvn->transform(new (C, 3) AddINode(range,stride));
+    Node *bias  = gvn->transform(new (C) AddINode(range,stride));
     set_subtree_ctrl( bias );
     hook->init_req(1, bias);
 
-    Node *bias1 = gvn->transform(new (C, 3) AddINode(bias,one_m));
+    Node *bias1 = gvn->transform(new (C) AddINode(bias,one_m));
     set_subtree_ctrl( bias1 );
     hook->init_req(2, bias1);
 
-    trip_count  = gvn->transform(new (C, 3) DivINode(0,bias1,stride));
+    trip_count  = gvn->transform(new (C) DivINode(0,bias1,stride));
     set_subtree_ctrl( trip_count );
     hook->init_req(3, trip_count);
     break;
   }
 
   case BoolTest::ge:            // Maybe convert to '>' case
-    limit = gvn->transform(new (C, 3) AddINode(limit,one_m));
+    limit = gvn->transform(new (C) AddINode(limit,one_m));
     set_subtree_ctrl( limit );
     hook->init_req(4 ,limit);
 
@@ -545,30 +545,30 @@
   case BoolTest::gt: {          // Maybe convert to '!=' case
     if (stride_con > 0) // count up loop rolls through MININT
       ShouldNotReachHere();
-    Node *range = gvn->transform(new (C, 3) SubINode(limit,init_trip));
+    Node *range = gvn->transform(new (C) SubINode(limit,init_trip));
     set_subtree_ctrl( range );
     hook->init_req(0, range);
 
-    Node *bias  = gvn->transform(new (C, 3) AddINode(range,stride));
+    Node *bias  = gvn->transform(new (C) AddINode(range,stride));
     set_subtree_ctrl( bias );
     hook->init_req(1, bias);
 
-    Node *bias1 = gvn->transform(new (C, 3) AddINode(bias,one_p));
+    Node *bias1 = gvn->transform(new (C) AddINode(bias,one_p));
     set_subtree_ctrl( bias1 );
     hook->init_req(2, bias1);
 
-    trip_count  = gvn->transform(new (C, 3) DivINode(0,bias1,stride));
+    trip_count  = gvn->transform(new (C) DivINode(0,bias1,stride));
     set_subtree_ctrl( trip_count );
     hook->init_req(3, trip_count);
     break;
   }
   } // switch( bt )
 
-  Node *span = gvn->transform(new (C, 3) MulINode(trip_count,stride));
+  Node *span = gvn->transform(new (C) MulINode(trip_count,stride));
   set_subtree_ctrl( span );
   hook->init_req(5, span);
 
-  limit = gvn->transform(new (C, 3) AddINode(span,init_trip));
+  limit = gvn->transform(new (C) AddINode(span,init_trip));
   set_subtree_ctrl( limit );
 
   } // LoopLimitCheck
@@ -577,6 +577,9 @@
   Node *sfpt = x->in(LoopNode::LoopBackControl);
   if (sfpt->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt)) {
     lazy_replace( sfpt, iftrue );
+    if (loop->_safepts != NULL) {
+      loop->_safepts->yank(sfpt);
+    }
     loop->_tail = iftrue;
   }
 
@@ -614,7 +617,7 @@
   set_ctrl(test, iff->in(0));
 
   // Replace the old IfNode with a new LoopEndNode
-  Node *lex = _igvn.register_new_node_with_optimizer(new (C, 2) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt ));
+  Node *lex = _igvn.register_new_node_with_optimizer(new (C) CountedLoopEndNode( iff->in(0), test, cl_prob, iff->as_If()->_fcnt ));
   IfNode *le = lex->as_If();
   uint dd = dom_depth(iff);
   set_idom(le, le->in(0), dd); // Update dominance for loop exit
@@ -625,8 +628,8 @@
 
   // Need to swap loop-exit and loop-back control?
   if (iftrue_op == Op_IfFalse) {
-    Node *ift2=_igvn.register_new_node_with_optimizer(new (C, 1) IfTrueNode (le));
-    Node *iff2=_igvn.register_new_node_with_optimizer(new (C, 1) IfFalseNode(le));
+    Node *ift2=_igvn.register_new_node_with_optimizer(new (C) IfTrueNode (le));
+    Node *iff2=_igvn.register_new_node_with_optimizer(new (C) IfFalseNode(le));
 
     loop->_tail = back_control = ift2;
     set_loop(ift2, loop);
@@ -652,7 +655,7 @@
   lazy_replace( iff, le ); // fix 'get_ctrl'
 
   // Now setup a new CountedLoopNode to replace the existing LoopNode
-  CountedLoopNode *l = new (C, 3) CountedLoopNode(init_control, back_control);
+  CountedLoopNode *l = new (C) CountedLoopNode(init_control, back_control);
   l->set_unswitch_count(x->as_Loop()->unswitch_count()); // Preserve
   // The following assert is approximately true, and defines the intention
   // of can_be_counted_loop.  It fails, however, because phase->type
@@ -668,8 +671,12 @@
 
   // Check for immediately preceding SafePoint and remove
   Node *sfpt2 = le->in(0);
-  if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2))
+  if (sfpt2->Opcode() == Op_SafePoint && is_deleteable_safept(sfpt2)) {
     lazy_replace( sfpt2, sfpt2->in(TypeFunc::Control));
+    if (loop->_safepts != NULL) {
+      loop->_safepts->yank(sfpt2);
+    }
+  }
 
   // Free up intermediate goo
   _igvn.remove_dead_node(hook);
@@ -709,20 +716,20 @@
 #endif
   if (cl->has_exact_trip_count()) {
     // Simple case: loop has constant boundaries.
-    // Use longs to avoid integer overflow.
+    // Use jlongs to avoid integer overflow.
     int stride_con = cl->stride_con();
-    long  init_con = cl->init_trip()->get_int();
-    long limit_con = cl->limit()->get_int();
+    jlong  init_con = cl->init_trip()->get_int();
+    jlong limit_con = cl->limit()->get_int();
     julong trip_cnt = cl->trip_count();
-    long final_con = init_con + trip_cnt*stride_con;
+    jlong final_con = init_con + trip_cnt*stride_con;
     int final_int = (int)final_con;
     // The final value should be in integer range since the loop
     // is counted and the limit was checked for overflow.
-    assert(final_con == (long)final_int, "final value should be integer");
+    assert(final_con == (jlong)final_int, "final value should be integer");
     limit = _igvn.intcon(final_int);
   } else {
     // Create new LoopLimit node to get exact limit (final iv value).
-    limit = new (C, 4) LoopLimitNode(C, cl->init_trip(), cl->limit(), cl->stride());
+    limit = new (C) LoopLimitNode(C, cl->init_trip(), cl->limit(), cl->stride());
     register_new_node(limit, cl->in(LoopNode::EntryControl));
   }
   assert(limit != NULL, "sanity");
@@ -783,16 +790,16 @@
     return NULL;  // Identity
 
   if (init_t->is_int()->is_con() && limit_t->is_int()->is_con()) {
-    // Use longs to avoid integer overflow.
-    long init_con   =  init_t->is_int()->get_con();
-    long limit_con  = limit_t->is_int()->get_con();
+    // Use jlongs to avoid integer overflow.
+    jlong init_con   =  init_t->is_int()->get_con();
+    jlong limit_con  = limit_t->is_int()->get_con();
     int  stride_m   = stride_con - (stride_con > 0 ? 1 : -1);
-    long trip_count = (limit_con - init_con + stride_m)/stride_con;
-    long final_con  = init_con + stride_con*trip_count;
+    jlong trip_count = (limit_con - init_con + stride_m)/stride_con;
+    jlong final_con  = init_con + stride_con*trip_count;
     int final_int = (int)final_con;
     // The final value should be in integer range since the loop
     // is counted and the limit was checked for overflow.
-    assert(final_con == (long)final_int, "final value should be integer");
+    assert(final_con == (jlong)final_int, "final value should be integer");
     return TypeInt::make(final_int);
   }
 
@@ -822,7 +829,7 @@
   const TypeInt* init_t  = phase->type(in(Init) )->is_int();
   const TypeInt* limit_t = phase->type(in(Limit))->is_int();
   int stride_p;
-  long lim, ini;
+  jlong lim, ini;
   julong max;
   if (stride_con > 0) {
     stride_p = stride_con;
@@ -839,11 +846,11 @@
   if (range <= max) {
     // Convert to integer expression if it is not overflow.
     Node* stride_m = phase->intcon(stride_con - (stride_con > 0 ? 1 : -1));
-    Node *range = phase->transform(new (phase->C, 3) SubINode(in(Limit), in(Init)));
-    Node *bias  = phase->transform(new (phase->C, 3) AddINode(range, stride_m));
-    Node *trip  = phase->transform(new (phase->C, 3) DivINode(0, bias, in(Stride)));
-    Node *span  = phase->transform(new (phase->C, 3) MulINode(trip, in(Stride)));
-    return new (phase->C, 3) AddINode(span, in(Init)); // exact limit
+    Node *range = phase->transform(new (phase->C) SubINode(in(Limit), in(Init)));
+    Node *bias  = phase->transform(new (phase->C) AddINode(range, stride_m));
+    Node *trip  = phase->transform(new (phase->C) DivINode(0, bias, in(Stride)));
+    Node *span  = phase->transform(new (phase->C) MulINode(trip, in(Stride)));
+    return new (phase->C) AddINode(span, in(Init)); // exact limit
   }
 
   if (is_power_of_2(stride_p) ||                // divisor is 2^n
@@ -851,13 +858,13 @@
     // Convert to long expression to avoid integer overflow
     // and let igvn optimizer convert this division.
     //
-    Node*   init   = phase->transform( new (phase->C, 2) ConvI2LNode(in(Init)));
-    Node*  limit   = phase->transform( new (phase->C, 2) ConvI2LNode(in(Limit)));
+    Node*   init   = phase->transform( new (phase->C) ConvI2LNode(in(Init)));
+    Node*  limit   = phase->transform( new (phase->C) ConvI2LNode(in(Limit)));
     Node* stride   = phase->longcon(stride_con);
     Node* stride_m = phase->longcon(stride_con - (stride_con > 0 ? 1 : -1));
 
-    Node *range = phase->transform(new (phase->C, 3) SubLNode(limit, init));
-    Node *bias  = phase->transform(new (phase->C, 3) AddLNode(range, stride_m));
+    Node *range = phase->transform(new (phase->C) SubLNode(limit, init));
+    Node *bias  = phase->transform(new (phase->C) AddLNode(range, stride_m));
     Node *span;
     if (stride_con > 0 && is_power_of_2(stride_p)) {
       // bias >= 0 if stride >0, so if stride is 2^n we can use &(-stride)
@@ -868,14 +875,14 @@
       // only RCE predicate where exact limit is used and the predicate
       // will simply fail forcing recompilation.
       Node* neg_stride   = phase->longcon(-stride_con);
-      span = phase->transform(new (phase->C, 3) AndLNode(bias, neg_stride));
+      span = phase->transform(new (phase->C) AndLNode(bias, neg_stride));
     } else {
-      Node *trip  = phase->transform(new (phase->C, 3) DivLNode(0, bias, stride));
-      span = phase->transform(new (phase->C, 3) MulLNode(trip, stride));
+      Node *trip  = phase->transform(new (phase->C) DivLNode(0, bias, stride));
+      span = phase->transform(new (phase->C) MulLNode(trip, stride));
     }
     // Convert back to int
-    Node *span_int = phase->transform(new (phase->C, 2) ConvL2INode(span));
-    return new (phase->C, 3) AddINode(span_int, in(Init)); // exact limit
+    Node *span_int = phase->transform(new (phase->C) ConvL2INode(span));
+    return new (phase->C) AddINode(span_int, in(Init)); // exact limit
   }
 
   return NULL;    // No progress
@@ -1081,7 +1088,7 @@
   uint i;
 
   // Make a new RegionNode to be the landing pad.
-  Node *landing_pad = new (phase->C, fall_in_cnt+1) RegionNode( fall_in_cnt+1 );
+  Node *landing_pad = new (phase->C) RegionNode( fall_in_cnt+1 );
   phase->set_loop(landing_pad,_parent);
   // Gather all the fall-in control paths into the landing pad
   uint icnt = fall_in_cnt;
@@ -1129,8 +1136,7 @@
         // I'm mid-iteration over the Region's uses.
         for (DUIterator_Last imin, i = old_phi->last_outs(imin); i >= imin; ) {
           Node* use = old_phi->last_out(i);
-          igvn.hash_delete(use);
-          igvn._worklist.push(use);
+          igvn.rehash_node_delayed(use);
           uint uses_found = 0;
           for (uint j = 0; j < use->len(); j++) {
             if (use->in(j) == old_phi) {
@@ -1168,7 +1174,7 @@
 
   // Make a LoopNode for the outermost loop.
   Node *ctl = _head->in(LoopNode::EntryControl);
-  Node *outer = new (phase->C, 3) LoopNode( ctl, _head->in(outer_idx) );
+  Node *outer = new (phase->C) LoopNode( ctl, _head->in(outer_idx) );
   outer = igvn.register_new_node_with_optimizer(outer, _head);
   phase->set_created_loop_node();
 
@@ -1186,10 +1192,8 @@
       phi->init_req(LoopNode::LoopBackControl, old_phi->in(outer_idx));
       phi = igvn.register_new_node_with_optimizer(phi, old_phi);
       // Make old Phi point to new Phi on the fall-in path
-      igvn.hash_delete(old_phi);
-      old_phi->set_req(LoopNode::EntryControl, phi);
+      igvn.replace_input_of(old_phi, LoopNode::EntryControl, phi);
       old_phi->del_req(outer_idx);
-      igvn._worklist.push(old_phi);
     }
   }
 
@@ -1284,7 +1288,7 @@
 
   Node *hot_tail = NULL;
   // Make a Region for the merge point
-  Node *r = new (phase->C, 1) RegionNode(1);
+  Node *r = new (phase->C) RegionNode(1);
   for( i = 2; i < _head->req(); i++ ) {
     if( i != hot_idx )
       r->add_req( _head->in(i) );
@@ -1303,7 +1307,7 @@
       PhiNode* n = out->as_Phi();
       igvn.hash_delete(n);      // Delete from hash before hacking edges
       Node *hot_phi = NULL;
-      Node *phi = new (phase->C, r->req()) PhiNode(r, n->type(), n->adr_type());
+      Node *phi = new (phase->C) PhiNode(r, n->type(), n->adr_type());
       // Check all inputs for the ones to peel out
       uint j = 1;
       for( uint i = 2; i < n->req(); i++ ) {
@@ -1425,7 +1429,7 @@
 
   } else if( !_head->is_Loop() && !_irreducible ) {
     // Make a new LoopNode to replace the old loop head
-    Node *l = new (phase->C, 3) LoopNode( _head->in(1), _head->in(2) );
+    Node *l = new (phase->C) LoopNode( _head->in(1), _head->in(2) );
     l = igvn.register_new_node_with_optimizer(l, _head);
     phase->set_created_loop_node();
     // Go ahead and replace _head
@@ -1529,10 +1533,8 @@
 void IdealLoopTree::check_safepts(VectorSet &visited, Node_List &stack) {
   // Bottom up traversal
   IdealLoopTree* ch = _child;
-  while (ch != NULL) {
-    ch->check_safepts(visited, stack);
-    ch = ch->_next;
-  }
+  if (_child) _child->check_safepts(visited, stack);
+  if (_next)  _next ->check_safepts(visited, stack);
 
   if (!_head->is_CountedLoop() && !_has_sfpt && _parent != NULL && !_irreducible) {
     bool  has_call         = false; // call on dom-path
@@ -1669,16 +1671,16 @@
       // It is scaled by the 'ratio_con'.
       Node* ratio = _igvn.intcon(ratio_con);
       set_ctrl(ratio, C->root());
-      Node* ratio_init = new (C, 3) MulINode(init, ratio);
+      Node* ratio_init = new (C) MulINode(init, ratio);
       _igvn.register_new_node_with_optimizer(ratio_init, init);
       set_early_ctrl(ratio_init);
-      Node* diff = new (C, 3) SubINode(init2, ratio_init);
+      Node* diff = new (C) SubINode(init2, ratio_init);
       _igvn.register_new_node_with_optimizer(diff, init2);
       set_early_ctrl(diff);
-      Node* ratio_idx = new (C, 3) MulINode(phi, ratio);
+      Node* ratio_idx = new (C) MulINode(phi, ratio);
       _igvn.register_new_node_with_optimizer(ratio_idx, phi);
       set_ctrl(ratio_idx, cl);
-      Node* add = new (C, 3) AddINode(ratio_idx, diff);
+      Node* add = new (C) AddINode(ratio_idx, diff);
       _igvn.register_new_node_with_optimizer(add);
       set_ctrl(add, cl);
       _igvn.replace_node( phi2, add );
@@ -1705,29 +1707,39 @@
       phase->is_counted_loop(_head, this)) {
     _has_sfpt = 1;              // Indicate we do not need a safepoint here
 
-    // Look for a safepoint to remove
-    for (Node* n = tail(); n != _head; n = phase->idom(n))
-      if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this &&
-          phase->is_deleteable_safept(n))
-        phase->lazy_replace(n,n->in(TypeFunc::Control));
+    // Look for safepoints to remove.
+    Node_List* sfpts = _safepts;
+    if (sfpts != NULL) {
+      for (uint i = 0; i < sfpts->size(); i++) {
+        Node* n = sfpts->at(i);
+        assert(phase->get_loop(n) == this, "");
+        if (phase->is_deleteable_safept(n)) {
+          phase->lazy_replace(n, n->in(TypeFunc::Control));
+        }
+      }
+    }
 
     // Look for induction variables
     phase->replace_parallel_iv(this);
 
   } else if (_parent != NULL && !_irreducible) {
     // Not a counted loop.
-    // Look for a safepoint on the idom-path to remove, preserving the first one
-    bool found = false;
-    Node* n = tail();
-    for (; n != _head && !found; n = phase->idom(n)) {
-      if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this)
-        found = true; // Found one
+    // Look for a safepoint on the idom-path.
+    Node* sfpt = tail();
+    for (; sfpt != _head; sfpt = phase->idom(sfpt)) {
+      if (sfpt->Opcode() == Op_SafePoint && phase->get_loop(sfpt) == this)
+        break; // Found one
     }
-    // Skip past it and delete the others
-    for (; n != _head; n = phase->idom(n)) {
-      if (n->Opcode() == Op_SafePoint && phase->get_loop(n) == this &&
-          phase->is_deleteable_safept(n))
-        phase->lazy_replace(n,n->in(TypeFunc::Control));
+    // Delete other safepoints in this loop.
+    Node_List* sfpts = _safepts;
+    if (sfpts != NULL && sfpt != _head && sfpt->Opcode() == Op_SafePoint) {
+      for (uint i = 0; i < sfpts->size(); i++) {
+        Node* n = sfpts->at(i);
+        assert(phase->get_loop(n) == this, "");
+        if (n != sfpt && phase->is_deleteable_safept(n)) {
+          phase->lazy_replace(n, n->in(TypeFunc::Control));
+        }
+      }
     }
   }
 
@@ -1776,6 +1788,8 @@
     if (stride_con > 0) tty->print("+");
     tty->print("%d", stride_con);
 
+    tty->print(" (%d iters) ", (int)cl->profile_trip_cnt());
+
     if (cl->is_pre_loop ()) tty->print(" pre" );
     if (cl->is_main_loop()) tty->print(" main");
     if (cl->is_post_loop()) tty->print(" post");
@@ -1992,9 +2006,7 @@
     // we do it here.
     for( uint i = 1; i < C->root()->req(); i++ ) {
       if( !_nodes[C->root()->in(i)->_idx] ) {    // Dead path into Root?
-        _igvn.hash_delete(C->root());
-        C->root()->del_req(i);
-        _igvn._worklist.push(C->root());
+        _igvn.delete_input_of(C->root(), i);
         i--;                      // Rerun same iteration on compressed edges
       }
     }
@@ -2665,10 +2677,10 @@
 
         if (!_verify_only) {
           // Insert the NeverBranch between 'm' and it's control user.
-          NeverBranchNode *iff = new (C, 1) NeverBranchNode( m );
+          NeverBranchNode *iff = new (C) NeverBranchNode( m );
           _igvn.register_new_node_with_optimizer(iff);
           set_loop(iff, l);
-          Node *if_t = new (C, 1) CProjNode( iff, 0 );
+          Node *if_t = new (C) CProjNode( iff, 0 );
           _igvn.register_new_node_with_optimizer(if_t);
           set_loop(if_t, l);
 
@@ -2684,16 +2696,16 @@
           cfg->set_req( k, if_t ); // Now point to NeverBranch
 
           // Now create the never-taken loop exit
-          Node *if_f = new (C, 1) CProjNode( iff, 1 );
+          Node *if_f = new (C) CProjNode( iff, 1 );
           _igvn.register_new_node_with_optimizer(if_f);
           set_loop(if_f, l);
           // Find frame ptr for Halt.  Relies on the optimizer
           // V-N'ing.  Easier and quicker than searching through
           // the program structure.
-          Node *frame = new (C, 1) ParmNode( C->start(), TypeFunc::FramePtr );
+          Node *frame = new (C) ParmNode( C->start(), TypeFunc::FramePtr );
           _igvn.register_new_node_with_optimizer(frame);
           // Halt & Catch Fire
-          Node *halt = new (C, TypeFunc::Parms) HaltNode( if_f, frame );
+          Node *halt = new (C) HaltNode( if_f, frame );
           _igvn.register_new_node_with_optimizer(halt);
           set_loop(halt, l);
           C->root()->add_req(halt);
@@ -2756,7 +2768,8 @@
         // Do not count uncommon calls
         if( !n->is_CallStaticJava() || !n->as_CallStaticJava()->_name ) {
           Node *iff = n->in(0)->in(0);
-          if( !iff->is_If() ||
+          // No any calls for vectorized loops.
+          if( UseSuperWord || !iff->is_If() ||
               (n->in(0)->Opcode() == Op_IfFalse &&
                (1.0 - iff->as_If()->_prob) >= 0.01) ||
               (iff->as_If()->_prob >= 0.01) )
@@ -2768,6 +2781,10 @@
         // if the allocation is not eliminated for some reason.
         innermost->_allow_optimizations = false;
         innermost->_has_call = 1; // = true
+      } else if (n->Opcode() == Op_SafePoint) {
+        // Record all safepoints in this loop.
+        if (innermost->_safepts == NULL) innermost->_safepts = new Node_List();
+        innermost->_safepts->push(n);
       }
     }
   }
@@ -2818,6 +2835,9 @@
               is_deleteable_safept(n)) {
             Node *in = n->in(TypeFunc::Control);
             lazy_replace(n,in);       // Pull safepoint now
+            if (ilt->_safepts != NULL) {
+              ilt->_safepts->yank(n);
+            }
             // Carry on with the recursion "as if" we are walking
             // only the control input
             if( !visited.test_set( in->_idx ) ) {
@@ -3221,7 +3241,8 @@
     case Op_ModF:
     case Op_ModD:
     case Op_LoadB:              // Same with Loads; they can sink
-    case Op_LoadUS:             // during loop optimizations.
+    case Op_LoadUB:             // during loop optimizations.
+    case Op_LoadUS:
     case Op_LoadD:
     case Op_LoadF:
     case Op_LoadI:
diff --git a/hotspot/src/share/vm/opto/loopnode.hpp b/hotspot/src/share/vm/opto/loopnode.hpp
index d2ea556..92f6912 100644
--- a/hotspot/src/share/vm/opto/loopnode.hpp
+++ b/hotspot/src/share/vm/opto/loopnode.hpp
@@ -336,6 +336,7 @@
         _has_sfpt:1,            // True if has non-call safepoint
         _rce_candidate:1;       // True if candidate for range check elimination
 
+  Node_List* _safepts;          // List of safepoints in this loop
   Node_List* _required_safept;  // A inner loop cannot delete these safepts;
   bool  _allow_optimizations;   // Allow loop optimizations
 
@@ -343,6 +344,7 @@
     : _parent(0), _next(0), _child(0),
       _head(head), _tail(tail),
       _phase(phase),
+      _safepts(NULL),
       _required_safept(NULL),
       _allow_optimizations(true),
       _nest(0), _irreducible(0), _has_call(0), _has_sfpt(0), _rce_candidate(0)
diff --git a/hotspot/src/share/vm/opto/loopopts.cpp b/hotspot/src/share/vm/opto/loopopts.cpp
index e93fb4d..5c49a04 100644
--- a/hotspot/src/share/vm/opto/loopopts.cpp
+++ b/hotspot/src/share/vm/opto/loopopts.cpp
@@ -53,7 +53,7 @@
     int iid    = t_oop->instance_id();
     int index  = C->get_alias_index(t_oop);
     int offset = t_oop->offset();
-    phi = new (C,region->req()) PhiNode(region, type, NULL, iid, index, offset);
+    phi = new (C) PhiNode(region, type, NULL, iid, index, offset);
   } else {
     phi = PhiNode::make_blank(region, n);
   }
@@ -216,9 +216,7 @@
   Node *con = _igvn.makecon(pop == Op_IfTrue ? TypeInt::ONE : TypeInt::ZERO);
   set_ctrl(con, C->root()); // Constant gets a new use
   // Hack the dominated test
-  _igvn.hash_delete(iff);
-  iff->set_req(1, con);
-  _igvn._worklist.push(iff);
+  _igvn.replace_input_of(iff, 1, con);
 
   // If I dont have a reachable TRUE and FALSE path following the IfNode then
   // I can assume this path reaches an infinite loop.  In this case it's not
@@ -245,10 +243,8 @@
     Node* cd = dp->fast_out(i); // Control-dependent node
     if (cd->depends_only_on_test()) {
       assert(cd->in(0) == dp, "");
-      _igvn.hash_delete(cd);
-      cd->set_req(0, prevdom);
+      _igvn.replace_input_of(cd, 0, prevdom);
       set_early_ctrl(cd);
-      _igvn._worklist.push(cd);
       IdealLoopTree *new_loop = get_loop(get_ctrl(cd));
       if (old_loop != new_loop) {
         if (!old_loop->_child) old_loop->_body.yank(cd);
@@ -360,9 +356,9 @@
         _igvn.type( add->in(1) ) != TypeInt::ZERO ) {
       Node *zero = _igvn.intcon(0);
       set_ctrl(zero, C->root());
-      Node *neg = new (C, 3) SubINode( _igvn.intcon(0), add->in(2) );
+      Node *neg = new (C) SubINode( _igvn.intcon(0), add->in(2) );
       register_new_node( neg, get_ctrl(add->in(2) ) );
-      add = new (C, 3) AddINode( add->in(1), neg );
+      add = new (C) AddINode( add->in(1), neg );
       register_new_node( add, add_ctrl );
     }
     if( add->Opcode() != Op_AddI ) return NULL;
@@ -388,14 +384,14 @@
       return NULL;              // No invariant part of the add?
 
     // Yes!  Reshape address expression!
-    Node *inv_scale = new (C, 3) LShiftINode( add_invar, scale );
+    Node *inv_scale = new (C) LShiftINode( add_invar, scale );
     Node *inv_scale_ctrl =
       dom_depth(add_invar_ctrl) > dom_depth(scale_ctrl) ?
       add_invar_ctrl : scale_ctrl;
     register_new_node( inv_scale, inv_scale_ctrl );
-    Node *var_scale = new (C, 3) LShiftINode( add_var, scale );
+    Node *var_scale = new (C) LShiftINode( add_var, scale );
     register_new_node( var_scale, n_ctrl );
-    Node *var_add = new (C, 3) AddINode( var_scale, inv_scale );
+    Node *var_add = new (C) AddINode( var_scale, inv_scale );
     register_new_node( var_add, n_ctrl );
     _igvn.replace_node( n, var_add );
     return var_add;
@@ -427,10 +423,10 @@
         IdealLoopTree *n23_loop = get_loop( n23_ctrl );
         if( n22loop != n_loop && n22loop->is_member(n_loop) &&
             n23_loop == n_loop ) {
-          Node *add1 = new (C, 4) AddPNode( n->in(1), n->in(2)->in(2), n->in(3) );
+          Node *add1 = new (C) AddPNode( n->in(1), n->in(2)->in(2), n->in(3) );
           // Stuff new AddP in the loop preheader
           register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) );
-          Node *add2 = new (C, 4) AddPNode( n->in(1), add1, n->in(2)->in(3) );
+          Node *add2 = new (C) AddPNode( n->in(1), add1, n->in(2)->in(3) );
           register_new_node( add2, n_ctrl );
           _igvn.replace_node( n, add2 );
           return add2;
@@ -448,10 +444,10 @@
           Node *tmp = V; V = I; I = tmp;
         }
         if( !is_member(n_loop,get_ctrl(I)) ) {
-          Node *add1 = new (C, 4) AddPNode( n->in(1), n->in(2), I );
+          Node *add1 = new (C) AddPNode( n->in(1), n->in(2), I );
           // Stuff new AddP in the loop preheader
           register_new_node( add1, n_loop->_head->in(LoopNode::EntryControl) );
-          Node *add2 = new (C, 4) AddPNode( n->in(1), add1, V );
+          Node *add2 = new (C) AddPNode( n->in(1), add1, V );
           register_new_node( add2, n_ctrl );
           _igvn.replace_node( n, add2 );
           return add2;
@@ -952,8 +948,7 @@
         if (!n->is_Load() || late_load_ctrl != n_ctrl) {
           for (DUIterator_Last jmin, j = n->last_outs(jmin); j >= jmin; ) {
             Node *u = n->last_out(j); // Clone private computation per use
-            _igvn.hash_delete(u);
-            _igvn._worklist.push(u);
+            _igvn.rehash_node_delayed(u);
             Node *x = n->clone(); // Clone computation
             Node *x_ctrl = NULL;
             if( u->is_Phi() ) {
@@ -1089,9 +1084,7 @@
   for( i = 1; i < phi->req(); i++ ) {
     Node *b = phi->in(i);
     if( b->is_Phi() ) {
-      _igvn.hash_delete(phi);
-      _igvn._worklist.push(phi);
-      phi->set_req(i, clone_iff( b->as_Phi(), loop ));
+      _igvn.replace_input_of(phi, i, clone_iff( b->as_Phi(), loop ));
     } else {
       assert( b->is_Bool(), "" );
     }
@@ -1101,9 +1094,8 @@
   Node *sample_cmp  = sample_bool->in(1);
 
   // Make Phis to merge the Cmp's inputs.
-  int size = phi->in(0)->req();
-  PhiNode *phi1 = new (C, size) PhiNode( phi->in(0), Type::TOP );
-  PhiNode *phi2 = new (C, size) PhiNode( phi->in(0), Type::TOP );
+  PhiNode *phi1 = new (C) PhiNode( phi->in(0), Type::TOP );
+  PhiNode *phi2 = new (C) PhiNode( phi->in(0), Type::TOP );
   for( i = 1; i < phi->req(); i++ ) {
     Node *n1 = phi->in(i)->in(1)->in(1);
     Node *n2 = phi->in(i)->in(1)->in(2);
@@ -1161,9 +1153,7 @@
   for( i = 1; i < phi->req(); i++ ) {
     Node *b = phi->in(i);
     if( b->is_Phi() ) {
-      _igvn.hash_delete(phi);
-      _igvn._worklist.push(phi);
-      phi->set_req(i, clone_bool( b->as_Phi(), loop ));
+      _igvn.replace_input_of(phi, i, clone_bool( b->as_Phi(), loop ));
     } else {
       assert( b->is_Cmp() || b->is_top(), "inputs are all Cmp or TOP" );
     }
@@ -1172,9 +1162,8 @@
   Node *sample_cmp = phi->in(1);
 
   // Make Phis to merge the Cmp's inputs.
-  int size = phi->in(0)->req();
-  PhiNode *phi1 = new (C, size) PhiNode( phi->in(0), Type::TOP );
-  PhiNode *phi2 = new (C, size) PhiNode( phi->in(0), Type::TOP );
+  PhiNode *phi1 = new (C) PhiNode( phi->in(0), Type::TOP );
+  PhiNode *phi2 = new (C) PhiNode( phi->in(0), Type::TOP );
   for( uint j = 1; j < phi->req(); j++ ) {
     Node *cmp_top = phi->in(j); // Inputs are all Cmp or TOP
     Node *n1, *n2;
@@ -1338,7 +1327,7 @@
 
         // We need a Region to merge the exit from the peeled body and the
         // exit from the old loop body.
-        RegionNode *r = new (C, 3) RegionNode(3);
+        RegionNode *r = new (C) RegionNode(3);
         // Map the old use to the new merge point
         old_new.map( use->_idx, r );
         uint dd_r = MIN2(dom_depth(newuse),dom_depth(use));
@@ -1347,8 +1336,7 @@
         // The original user of 'use' uses 'r' instead.
         for (DUIterator_Last lmin, l = use->last_outs(lmin); l >= lmin;) {
           Node* useuse = use->last_out(l);
-          _igvn.hash_delete(useuse);
-          _igvn._worklist.push(useuse);
+          _igvn.rehash_node_delayed(useuse);
           uint uses_found = 0;
           if( useuse->in(0) == use ) {
             useuse->set_req(0, r);
@@ -1435,9 +1423,7 @@
         if( use->is_Phi() )     // Phi use is in prior block
           cfg = prev->in(idx);  // NOT in block of Phi itself
         if (cfg->is_top()) {    // Use is dead?
-          _igvn.hash_delete(use);
-          _igvn._worklist.push(use);
-          use->set_req(idx, C->top());
+          _igvn.replace_input_of(use, idx, C->top());
           continue;
         }
 
@@ -1487,9 +1473,7 @@
           set_ctrl(phi, prev);
         }
         // Make 'use' use the Phi instead of the old loop body exit value
-        _igvn.hash_delete(use);
-        _igvn._worklist.push(use);
-        use->set_req(idx, phi);
+        _igvn.replace_input_of(use, idx, phi);
         if( use->_idx >= new_counter ) { // If updating new phis
           // Not needed for correctness, but prevents a weak assert
           // in AddPNode from tripping (when we end up with different
@@ -1517,9 +1501,7 @@
       Node *iff = split_if_set->pop();
       if( iff->in(1)->is_Phi() ) {
         BoolNode *b = clone_iff( iff->in(1)->as_Phi(), loop );
-        _igvn.hash_delete(iff);
-        _igvn._worklist.push(iff);
-        iff->set_req(1, b);
+        _igvn.replace_input_of(iff, 1, b);
       }
     }
   }
@@ -1529,9 +1511,7 @@
       Node *phi = b->in(1);
       assert( phi->is_Phi(), "" );
       CmpNode *cmp = clone_bool( (PhiNode*)phi, loop );
-      _igvn.hash_delete(b);
-      _igvn._worklist.push(b);
-      b->set_req(1, cmp);
+      _igvn.replace_input_of(b, 1, cmp);
     }
   }
   if( split_cex_set ) {
@@ -1686,22 +1666,20 @@
   ProjNode *other_proj = iff->proj_out(!proj->is_IfTrue())->as_Proj();
   int ddepth = dom_depth(proj);
 
-  _igvn.hash_delete(iff);
-  _igvn._worklist.push(iff);
-  _igvn.hash_delete(proj);
-  _igvn._worklist.push(proj);
+  _igvn.rehash_node_delayed(iff);
+  _igvn.rehash_node_delayed(proj);
 
   proj->set_req(0, NULL);  // temporary disconnect
   ProjNode* proj2 = proj_clone(proj, iff);
   register_node(proj2, loop, iff, ddepth);
 
-  Node* cmp = Signed ? (Node*) new (C,3)CmpINode(left, right) : (Node*) new (C,3)CmpUNode(left, right);
+  Node* cmp = Signed ? (Node*) new (C)CmpINode(left, right) : (Node*) new (C)CmpUNode(left, right);
   register_node(cmp, loop, proj2, ddepth);
 
-  BoolNode* bol = new (C,2)BoolNode(cmp, relop);
+  BoolNode* bol = new (C)BoolNode(cmp, relop);
   register_node(bol, loop, proj2, ddepth);
 
-  IfNode* new_if = new (C,2)IfNode(proj2, bol, iff->_prob, iff->_fcnt);
+  IfNode* new_if = new (C)IfNode(proj2, bol, iff->_prob, iff->_fcnt);
   register_node(new_if, loop, proj2, ddepth);
 
   proj->set_req(0, new_if); // reattach
@@ -1745,20 +1723,18 @@
   ProjNode *other_proj = iff->proj_out(!proj->is_IfTrue())->as_Proj();
   int ddepth = dom_depth(proj);
 
-  _igvn.hash_delete(iff);
-  _igvn._worklist.push(iff);
-  _igvn.hash_delete(proj);
-  _igvn._worklist.push(proj);
+  _igvn.rehash_node_delayed(iff);
+  _igvn.rehash_node_delayed(proj);
 
   proj->set_req(0, NULL);  // temporary disconnect
   ProjNode* proj2 = proj_clone(proj, iff);
   register_node(proj2, loop, iff, ddepth);
 
-  RegionNode* reg = new (C,2)RegionNode(2);
+  RegionNode* reg = new (C)RegionNode(2);
   reg->set_req(1, proj2);
   register_node(reg, loop, iff, ddepth);
 
-  IfNode* dum_if = new (C,2)IfNode(reg, short_circuit_if(NULL, proj), iff->_prob, iff->_fcnt);
+  IfNode* dum_if = new (C)IfNode(reg, short_circuit_if(NULL, proj), iff->_prob, iff->_fcnt);
   register_node(dum_if, loop, reg, ddepth);
 
   proj->set_req(0, dum_if); // reattach
@@ -1970,9 +1946,7 @@
 
     // clone "n" and insert it between the inputs of "n" and the use outside the loop
     Node* n_clone = n->clone();
-    _igvn.hash_delete(use);
-    use->set_req(j, n_clone);
-    _igvn._worklist.push(use);
+    _igvn.replace_input_of(use, j, n_clone);
     Node* use_c;
     if (!use->is_Phi()) {
       use_c = has_ctrl(use) ? get_ctrl(use) : use->in(0);
@@ -2028,8 +2002,7 @@
 #endif
     while( worklist.size() ) {
       Node *use = worklist.pop();
-      _igvn.hash_delete(use);
-      _igvn._worklist.push(use);
+      _igvn.rehash_node_delayed(use);
       for (uint j = 1; j < use->req(); j++) {
         if (use->in(j) == n) {
           use->set_req(j, n_clone);
@@ -2055,9 +2028,7 @@
     _igvn.remove_dead_node(phi);
     phi = hit;
   }
-  _igvn.hash_delete(use);
-  _igvn._worklist.push(use);
-  use->set_req(idx, phi);
+  _igvn.replace_input_of(use, idx, phi);
 }
 
 #ifdef ASSERT
@@ -2574,7 +2545,7 @@
 
   // Create new loop head for new phis and to hang
   // the nodes being moved (sinked) from the peel region.
-  LoopNode* new_head = new (C, 3) LoopNode(last_peel, last_peel);
+  LoopNode* new_head = new (C) LoopNode(last_peel, last_peel);
   new_head->set_unswitch_count(head->unswitch_count()); // Preserve
   _igvn.register_new_node_with_optimizer(new_head);
   assert(first_not_peeled->in(0) == last_peel, "last_peel <- first_not_peeled");
@@ -2630,9 +2601,7 @@
               // use is in loop
               if (old_new[use->_idx] != NULL) { // null for dead code
                 Node* use_clone = old_new[use->_idx];
-                _igvn.hash_delete(use);
-                use->set_req(j, C->top());
-                _igvn._worklist.push(use);
+                _igvn.replace_input_of(use, j, C->top());
                 insert_phi_for_loop( use_clone, j, old_new[def->_idx], def, new_head_clone );
               }
             } else {
@@ -2667,46 +2636,35 @@
     if (!n->is_CFG()           && n->in(0) != NULL        &&
         not_peel.test(n->_idx) && peel.test(n->in(0)->_idx)) {
       Node* n_clone = old_new[n->_idx];
-      _igvn.hash_delete(n_clone);
-      n_clone->set_req(0, new_head_clone);
-      _igvn._worklist.push(n_clone);
+      _igvn.replace_input_of(n_clone, 0, new_head_clone);
     }
   }
 
   // Backedge of the surviving new_head (the clone) is original last_peel
-  _igvn.hash_delete(new_head_clone);
-  new_head_clone->set_req(LoopNode::LoopBackControl, last_peel);
-  _igvn._worklist.push(new_head_clone);
+  _igvn.replace_input_of(new_head_clone, LoopNode::LoopBackControl, last_peel);
 
   // Cut first node in original not_peel set
-  _igvn.hash_delete(new_head);
-  new_head->set_req(LoopNode::EntryControl, C->top());
-  new_head->set_req(LoopNode::LoopBackControl, C->top());
-  _igvn._worklist.push(new_head);
+  _igvn.rehash_node_delayed(new_head);                     // Multiple edge updates:
+  new_head->set_req(LoopNode::EntryControl,    C->top());  //   use rehash_node_delayed / set_req instead of
+  new_head->set_req(LoopNode::LoopBackControl, C->top());  //   multiple replace_input_of calls
 
   // Copy head_clone back-branch info to original head
   // and remove original head's loop entry and
   // clone head's back-branch
-  _igvn.hash_delete(head);
-  _igvn.hash_delete(head_clone);
-  head->set_req(LoopNode::EntryControl, head_clone->in(LoopNode::LoopBackControl));
+  _igvn.rehash_node_delayed(head); // Multiple edge updates
+  head->set_req(LoopNode::EntryControl,    head_clone->in(LoopNode::LoopBackControl));
   head->set_req(LoopNode::LoopBackControl, C->top());
-  head_clone->set_req(LoopNode::LoopBackControl, C->top());
-  _igvn._worklist.push(head);
-  _igvn._worklist.push(head_clone);
+  _igvn.replace_input_of(head_clone, LoopNode::LoopBackControl, C->top());
 
   // Similarly modify the phis
   for (DUIterator_Fast kmax, k = head->fast_outs(kmax); k < kmax; k++) {
     Node* use = head->fast_out(k);
     if (use->is_Phi() && use->outcnt() > 0) {
       Node* use_clone = old_new[use->_idx];
-      _igvn.hash_delete(use);
-      _igvn.hash_delete(use_clone);
-      use->set_req(LoopNode::EntryControl, use_clone->in(LoopNode::LoopBackControl));
+      _igvn.rehash_node_delayed(use); // Multiple edge updates
+      use->set_req(LoopNode::EntryControl,    use_clone->in(LoopNode::LoopBackControl));
       use->set_req(LoopNode::LoopBackControl, C->top());
-      use_clone->set_req(LoopNode::LoopBackControl, C->top());
-      _igvn._worklist.push(use);
-      _igvn._worklist.push(use_clone);
+      _igvn.replace_input_of(use_clone, LoopNode::LoopBackControl, C->top());
     }
   }
 
@@ -2786,14 +2744,13 @@
       if (dom_lca(exit, u_ctrl) != exit) continue;
       // Hit!  Refactor use to use the post-incremented tripcounter.
       // Compute a post-increment tripcounter.
-      Node *opaq = new (C, 2) Opaque2Node( C, cle->incr() );
+      Node *opaq = new (C) Opaque2Node( C, cle->incr() );
       register_new_node( opaq, u_ctrl );
       Node *neg_stride = _igvn.intcon(-cle->stride_con());
       set_ctrl(neg_stride, C->root());
-      Node *post = new (C, 3) AddINode( opaq, neg_stride);
+      Node *post = new (C) AddINode( opaq, neg_stride);
       register_new_node( post, u_ctrl );
-      _igvn.hash_delete(use);
-      _igvn._worklist.push(use);
+      _igvn.rehash_node_delayed(use);
       for (uint j = 1; j < use->req(); j++) {
         if (use->in(j) == phi)
           use->set_req(j, post);
diff --git a/hotspot/src/share/vm/opto/machnode.cpp b/hotspot/src/share/vm/opto/machnode.cpp
index 7bc5877..88bb23b 100644
--- a/hotspot/src/share/vm/opto/machnode.cpp
+++ b/hotspot/src/share/vm/opto/machnode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -439,9 +439,9 @@
   // Don't remateralize somebody with bound inputs - it stretches a
   // fixed register lifetime.
   uint idx = oper_input_base();
-  if( req() > idx ) {
+  if (req() > idx) {
     const RegMask &rm = in_RegMask(idx);
-    if( rm.is_bound1() || rm.is_bound2() )
+    if (rm.is_bound(ideal_reg()))
       return false;
   }
 
diff --git a/hotspot/src/share/vm/opto/machnode.hpp b/hotspot/src/share/vm/opto/machnode.hpp
index 566e031..4db1154 100644
--- a/hotspot/src/share/vm/opto/machnode.hpp
+++ b/hotspot/src/share/vm/opto/machnode.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -319,6 +319,7 @@
 class MachTypeNode : public MachNode {
   virtual uint size_of() const { return sizeof(*this); } // Size is bigger
 public:
+  MachTypeNode( ) {}
   const Type *_bottom_type;
 
   virtual const class Type *bottom_type() const { return _bottom_type; }
@@ -370,12 +371,12 @@
 
 //------------------------------MachConstantNode-------------------------------
 // Machine node that holds a constant which is stored in the constant table.
-class MachConstantNode : public MachNode {
+class MachConstantNode : public MachTypeNode {
 protected:
   Compile::Constant _constant;  // This node's constant.
 
 public:
-  MachConstantNode() : MachNode() {
+  MachConstantNode() : MachTypeNode() {
     init_class_id(Class_MachConstant);
   }
 
diff --git a/hotspot/src/share/vm/opto/macro.cpp b/hotspot/src/share/vm/opto/macro.cpp
index 11416ac..9bfb37a 100644
--- a/hotspot/src/share/vm/opto/macro.cpp
+++ b/hotspot/src/share/vm/opto/macro.cpp
@@ -103,20 +103,20 @@
 Node* PhaseMacroExpand::opt_bits_test(Node* ctrl, Node* region, int edge, Node* word, int mask, int bits, bool return_fast_path) {
   Node* cmp;
   if (mask != 0) {
-    Node* and_node = transform_later(new (C, 3) AndXNode(word, MakeConX(mask)));
-    cmp = transform_later(new (C, 3) CmpXNode(and_node, MakeConX(bits)));
+    Node* and_node = transform_later(new (C) AndXNode(word, MakeConX(mask)));
+    cmp = transform_later(new (C) CmpXNode(and_node, MakeConX(bits)));
   } else {
     cmp = word;
   }
-  Node* bol = transform_later(new (C, 2) BoolNode(cmp, BoolTest::ne));
-  IfNode* iff = new (C, 2) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
+  Node* bol = transform_later(new (C) BoolNode(cmp, BoolTest::ne));
+  IfNode* iff = new (C) IfNode( ctrl, bol, PROB_MIN, COUNT_UNKNOWN );
   transform_later(iff);
 
   // Fast path taken.
-  Node *fast_taken = transform_later( new (C, 1) IfFalseNode(iff) );
+  Node *fast_taken = transform_later( new (C) IfFalseNode(iff) );
 
   // Fast path not-taken, i.e. slow path
-  Node *slow_taken = transform_later( new (C, 1) IfTrueNode(iff) );
+  Node *slow_taken = transform_later( new (C) IfTrueNode(iff) );
 
   if (return_fast_path) {
     region->init_req(edge, slow_taken); // Capture slow-control
@@ -141,10 +141,9 @@
 CallNode* PhaseMacroExpand::make_slow_call(CallNode *oldcall, const TypeFunc* slow_call_type, address slow_call, const char* leaf_name, Node* slow_path, Node* parm0, Node* parm1) {
 
   // Slow-path call
-  int size = slow_call_type->domain()->cnt();
  CallNode *call = leaf_name
-   ? (CallNode*)new (C, size) CallLeafNode      ( slow_call_type, slow_call, leaf_name, TypeRawPtr::BOTTOM )
-   : (CallNode*)new (C, size) CallStaticJavaNode( slow_call_type, slow_call, OptoRuntime::stub_name(slow_call), oldcall->jvms()->bci(), TypeRawPtr::BOTTOM );
+   ? (CallNode*)new (C) CallLeafNode      ( slow_call_type, slow_call, leaf_name, TypeRawPtr::BOTTOM )
+   : (CallNode*)new (C) CallStaticJavaNode( slow_call_type, slow_call, OptoRuntime::stub_name(slow_call), oldcall->jvms()->bci(), TypeRawPtr::BOTTOM );
 
   // Slow path call has no side-effects, uses few values
   copy_predefined_input_for_runtime_call(slow_path, oldcall, call );
@@ -409,10 +408,10 @@
   Node *alloc_mem = alloc->in(TypeFunc::Memory);
 
   uint length = mem->req();
-  GrowableArray <Node *> values(length, length, NULL);
+  GrowableArray <Node *> values(length, length, NULL, false);
 
   // create a new Phi for the value
-  PhiNode *phi = new (C, length) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
+  PhiNode *phi = new (C) PhiNode(mem->in(0), phi_type, NULL, instance_id, alias_idx, offset);
   transform_later(phi);
   value_phis->push(phi, mem->_idx);
 
@@ -720,7 +719,7 @@
     SafePointNode* sfpt = safepoints.pop();
     Node* mem = sfpt->memory();
     uint first_ind = sfpt->req();
-    SafePointScalarObjectNode* sobj = new (C, 1) SafePointScalarObjectNode(res_type,
+    SafePointScalarObjectNode* sobj = new (C) SafePointScalarObjectNode(res_type,
 #ifdef ASSERT
                                                  alloc,
 #endif
@@ -828,7 +827,7 @@
         if (field_val->is_EncodeP()) {
           field_val = field_val->in(1);
         } else {
-          field_val = transform_later(new (C, 2) DecodeNNode(field_val, field_val->bottom_type()->make_ptr()));
+          field_val = transform_later(new (C) DecodeNNode(field_val, field_val->bottom_type()->make_ptr()));
         }
       }
       sfpt->add_req(field_val);
@@ -995,7 +994,7 @@
 //---------------------------set_eden_pointers-------------------------
 void PhaseMacroExpand::set_eden_pointers(Node* &eden_top_adr, Node* &eden_end_adr) {
   if (UseTLAB) {                // Private allocation: load from TLS
-    Node* thread = transform_later(new (C, 1) ThreadLocalNode());
+    Node* thread = transform_later(new (C) ThreadLocalNode());
     int tlab_top_offset = in_bytes(JavaThread::tlab_top_offset());
     int tlab_end_offset = in_bytes(JavaThread::tlab_end_offset());
     eden_top_adr = basic_plus_adr(top()/*not oop*/, thread, tlab_top_offset);
@@ -1137,18 +1136,18 @@
   assert (initial_slow_test == NULL || !always_slow, "arguments must be consistent");
   // generate the initial test if necessary
   if (initial_slow_test != NULL ) {
-    slow_region = new (C, 3) RegionNode(3);
+    slow_region = new (C) RegionNode(3);
 
     // Now make the initial failure test.  Usually a too-big test but
     // might be a TRUE for finalizers or a fancy class check for
     // newInstance0.
-    IfNode *toobig_iff = new (C, 2) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN);
+    IfNode *toobig_iff = new (C) IfNode(ctrl, initial_slow_test, PROB_MIN, COUNT_UNKNOWN);
     transform_later(toobig_iff);
     // Plug the failing-too-big test into the slow-path region
-    Node *toobig_true = new (C, 1) IfTrueNode( toobig_iff );
+    Node *toobig_true = new (C) IfTrueNode( toobig_iff );
     transform_later(toobig_true);
     slow_region    ->init_req( too_big_or_final_path, toobig_true );
-    toobig_false = new (C, 1) IfFalseNode( toobig_iff );
+    toobig_false = new (C) IfFalseNode( toobig_iff );
     transform_later(toobig_false);
   } else {         // No initial test, just fall into next case
     toobig_false = ctrl;
@@ -1181,10 +1180,10 @@
     Node *eden_end = make_load(ctrl, mem, eden_end_adr, 0, TypeRawPtr::BOTTOM, T_ADDRESS);
 
     // 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_region = new (C) RegionNode(3);
+    result_phi_rawmem = new (C) PhiNode(result_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    result_phi_rawoop = new (C) PhiNode(result_region, TypeRawPtr::BOTTOM);
+    result_phi_i_o    = new (C) 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 };
@@ -1194,8 +1193,8 @@
       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_region = new (C) RegionNode(3);
+      contended_phi_rawmem = new (C) 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);
@@ -1207,23 +1206,23 @@
     // 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) LoadPNode      (ctrl, contended_phi_rawmem, eden_top_adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM)
+      : new (C) 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) 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) 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) 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) 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) IfTrueNode(needgc_iff);
     transform_later(needgc_true);
     if (initial_slow_test) {
       slow_region->init_req(need_gc_path, needgc_true);
@@ -1234,7 +1233,7 @@
       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) IfFalseNode(needgc_iff);
     transform_later(needgc_false);
 
     // Grab regular I/O before optional prefetch may change it.
@@ -1254,37 +1253,37 @@
     // memory state.
     if (UseTLAB) {
       Node* store_eden_top =
-        new (C, 4) StorePNode(needgc_false, contended_phi_rawmem, eden_top_adr,
+        new (C) 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 {
       Node* store_eden_top =
-        new (C, 5) StorePConditionalNode(needgc_false, contended_phi_rawmem, eden_top_adr,
+        new (C) 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) BoolNode(store_eden_top, BoolTest::ne);
       transform_later(contention_check);
-      store_eden_top = new (C, 1) SCMemProjNode(store_eden_top);
+      store_eden_top = new (C) 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) 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) 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);
 
       // Fast-path succeeded with no contention!
-      Node *contention_false = new (C, 1) IfFalseNode(contention_iff);
+      Node *contention_false = new (C) 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();
+      Node* thread = new (C) ThreadLocalNode();
       transform_later(thread);
       Node* alloc_bytes_adr = basic_plus_adr(top()/*not oop*/, thread,
                                              in_bytes(JavaThread::allocated_bytes_offset()));
@@ -1293,10 +1292,10 @@
 #ifdef _LP64
       Node* alloc_size = size_in_bytes;
 #else
-      Node* alloc_size = new (C, 2) ConvI2LNode(size_in_bytes);
+      Node* alloc_size = new (C) ConvI2LNode(size_in_bytes);
       transform_later(alloc_size);
 #endif
-      Node* new_alloc_bytes = new (C, 3) AddLNode(alloc_bytes, alloc_size);
+      Node* new_alloc_bytes = new (C) 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);
@@ -1323,9 +1322,9 @@
 
         mb->init_req(TypeFunc::Memory, fast_oop_rawmem);
         mb->init_req(TypeFunc::Control, fast_oop_ctrl);
-        fast_oop_ctrl = new (C, 1) ProjNode(mb,TypeFunc::Control);
+        fast_oop_ctrl = new (C) ProjNode(mb,TypeFunc::Control);
         transform_later(fast_oop_ctrl);
-        fast_oop_rawmem = new (C, 1) ProjNode(mb,TypeFunc::Memory);
+        fast_oop_rawmem = new (C) ProjNode(mb,TypeFunc::Memory);
         transform_later(fast_oop_rawmem);
       } else {
         // Add the MemBarStoreStore after the InitializeNode so that
@@ -1339,9 +1338,9 @@
         MemBarNode* mb = MemBarNode::make(C, Op_MemBarStoreStore, Compile::AliasIdxBot);
         transform_later(mb);
 
-        Node* ctrl = new (C, 1) ProjNode(init,TypeFunc::Control);
+        Node* ctrl = new (C) ProjNode(init,TypeFunc::Control);
         transform_later(ctrl);
-        Node* mem = new (C, 1) ProjNode(init,TypeFunc::Memory);
+        Node* mem = new (C) ProjNode(init,TypeFunc::Memory);
         transform_later(mem);
 
         // The MemBarStoreStore depends on control and memory coming
@@ -1349,9 +1348,9 @@
         mb->init_req(TypeFunc::Memory, mem);
         mb->init_req(TypeFunc::Control, ctrl);
 
-        ctrl = new (C, 1) ProjNode(mb,TypeFunc::Control);
+        ctrl = new (C) ProjNode(mb,TypeFunc::Control);
         transform_later(ctrl);
-        mem = new (C, 1) ProjNode(mb,TypeFunc::Memory);
+        mem = new (C) ProjNode(mb,TypeFunc::Memory);
         transform_later(mem);
 
         // All nodes that depended on the InitializeNode for control
@@ -1365,13 +1364,13 @@
     if (C->env()->dtrace_extended_probes()) {
       // Slow-path call
       int size = TypeFunc::Parms + 2;
-      CallLeafNode *call = new (C, size) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(),
-                                                      CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base),
-                                                      "dtrace_object_alloc",
-                                                      TypeRawPtr::BOTTOM);
+      CallLeafNode *call = new (C) CallLeafNode(OptoRuntime::dtrace_object_alloc_Type(),
+                                                CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc_base),
+                                                "dtrace_object_alloc",
+                                                TypeRawPtr::BOTTOM);
 
       // Get base of thread-local storage area
-      Node* thread = new (C, 1) ThreadLocalNode();
+      Node* thread = new (C) ThreadLocalNode();
       transform_later(thread);
 
       call->init_req(TypeFunc::Parms+0, thread);
@@ -1382,9 +1381,9 @@
       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);
+      fast_oop_ctrl = new (C) ProjNode(call,TypeFunc::Control);
       transform_later(fast_oop_ctrl);
-      fast_oop_rawmem = new (C, 1) ProjNode(call,TypeFunc::Memory);
+      fast_oop_rawmem = new (C) ProjNode(call,TypeFunc::Memory);
       transform_later(fast_oop_rawmem);
     }
 
@@ -1399,11 +1398,10 @@
   }
 
   // Generate slow-path call
-  CallNode *call = new (C, slow_call_type->domain()->cnt())
-    CallStaticJavaNode(slow_call_type, slow_call_address,
-                       OptoRuntime::stub_name(slow_call_address),
-                       alloc->jvms()->bci(),
-                       TypePtr::BOTTOM);
+  CallNode *call = new (C) CallStaticJavaNode(slow_call_type, slow_call_address,
+                               OptoRuntime::stub_name(slow_call_address),
+                               alloc->jvms()->bci(),
+                               TypePtr::BOTTOM);
   call->init_req( TypeFunc::Control, slow_region );
   call->init_req( TypeFunc::I_O    , top() )     ;   // does no i/o
   call->init_req( TypeFunc::Memory , slow_mem ); // may gc ptrs
@@ -1447,9 +1445,8 @@
   if (!always_slow && _memproj_fallthrough != NULL) {
     for (DUIterator_Fast imax, i = _memproj_fallthrough->fast_outs(imax); i < imax; i++) {
       Node *use = _memproj_fallthrough->fast_out(i);
-      _igvn.hash_delete(use);
+      _igvn.rehash_node_delayed(use);
       imax -= replace_input(use, _memproj_fallthrough, result_phi_rawmem);
-      _igvn._worklist.push(use);
       // back up iterator
       --i;
     }
@@ -1458,14 +1455,13 @@
   // _memproj_catchall so we end up with a call that has only 1 memory projection.
   if (_memproj_catchall != NULL ) {
     if (_memproj_fallthrough == NULL) {
-      _memproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::Memory);
+      _memproj_fallthrough = new (C) ProjNode(call, TypeFunc::Memory);
       transform_later(_memproj_fallthrough);
     }
     for (DUIterator_Fast imax, i = _memproj_catchall->fast_outs(imax); i < imax; i++) {
       Node *use = _memproj_catchall->fast_out(i);
-      _igvn.hash_delete(use);
+      _igvn.rehash_node_delayed(use);
       imax -= replace_input(use, _memproj_catchall, _memproj_fallthrough);
-      _igvn._worklist.push(use);
       // back up iterator
       --i;
     }
@@ -1481,9 +1477,8 @@
   if (_ioproj_fallthrough != NULL) {
     for (DUIterator_Fast imax, i = _ioproj_fallthrough->fast_outs(imax); i < imax; i++) {
       Node *use = _ioproj_fallthrough->fast_out(i);
-      _igvn.hash_delete(use);
+      _igvn.rehash_node_delayed(use);
       imax -= replace_input(use, _ioproj_fallthrough, result_phi_i_o);
-      _igvn._worklist.push(use);
       // back up iterator
       --i;
     }
@@ -1492,14 +1487,13 @@
   // _ioproj_catchall so we end up with a call that has only 1 i_o projection.
   if (_ioproj_catchall != NULL ) {
     if (_ioproj_fallthrough == NULL) {
-      _ioproj_fallthrough = new (C, 1) ProjNode(call, TypeFunc::I_O);
+      _ioproj_fallthrough = new (C) ProjNode(call, TypeFunc::I_O);
       transform_later(_ioproj_fallthrough);
     }
     for (DUIterator_Fast imax, i = _ioproj_catchall->fast_outs(imax); i < imax; i++) {
       Node *use = _ioproj_catchall->fast_out(i);
-      _igvn.hash_delete(use);
+      _igvn.rehash_node_delayed(use);
       imax -= replace_input(use, _ioproj_catchall, _ioproj_fallthrough);
-      _igvn._worklist.push(use);
       // back up iterator
       --i;
     }
@@ -1627,46 +1621,46 @@
       // As an allocation hits the watermark, we will prefetch starting
       // at a "distance" away from watermark.
 
-      Node *pf_region = new (C, 3) RegionNode(3);
-      Node *pf_phi_rawmem = new (C, 3) PhiNode( pf_region, Type::MEMORY,
+      Node *pf_region = new (C) RegionNode(3);
+      Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY,
                                                 TypeRawPtr::BOTTOM );
       // I/O is used for Prefetch
-      Node *pf_phi_abio = new (C, 3) PhiNode( pf_region, Type::ABIO );
+      Node *pf_phi_abio = new (C) PhiNode( pf_region, Type::ABIO );
 
-      Node *thread = new (C, 1) ThreadLocalNode();
+      Node *thread = new (C) ThreadLocalNode();
       transform_later(thread);
 
-      Node *eden_pf_adr = new (C, 4) AddPNode( top()/*not oop*/, thread,
+      Node *eden_pf_adr = new (C) AddPNode( top()/*not oop*/, thread,
                    _igvn.MakeConX(in_bytes(JavaThread::tlab_pf_top_offset())) );
       transform_later(eden_pf_adr);
 
-      Node *old_pf_wm = new (C, 3) LoadPNode( needgc_false,
+      Node *old_pf_wm = new (C) LoadPNode( needgc_false,
                                    contended_phi_rawmem, eden_pf_adr,
                                    TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM );
       transform_later(old_pf_wm);
 
       // check against new_eden_top
-      Node *need_pf_cmp = new (C, 3) CmpPNode( new_eden_top, old_pf_wm );
+      Node *need_pf_cmp = new (C) CmpPNode( new_eden_top, old_pf_wm );
       transform_later(need_pf_cmp);
-      Node *need_pf_bol = new (C, 2) BoolNode( need_pf_cmp, BoolTest::ge );
+      Node *need_pf_bol = new (C) BoolNode( need_pf_cmp, BoolTest::ge );
       transform_later(need_pf_bol);
-      IfNode *need_pf_iff = new (C, 2) IfNode( needgc_false, need_pf_bol,
+      IfNode *need_pf_iff = new (C) IfNode( needgc_false, need_pf_bol,
                                        PROB_UNLIKELY_MAG(4), COUNT_UNKNOWN );
       transform_later(need_pf_iff);
 
       // true node, add prefetchdistance
-      Node *need_pf_true = new (C, 1) IfTrueNode( need_pf_iff );
+      Node *need_pf_true = new (C) IfTrueNode( need_pf_iff );
       transform_later(need_pf_true);
 
-      Node *need_pf_false = new (C, 1) IfFalseNode( need_pf_iff );
+      Node *need_pf_false = new (C) IfFalseNode( need_pf_iff );
       transform_later(need_pf_false);
 
-      Node *new_pf_wmt = new (C, 4) AddPNode( top(), old_pf_wm,
+      Node *new_pf_wmt = new (C) AddPNode( top(), old_pf_wm,
                                     _igvn.MakeConX(AllocatePrefetchDistance) );
       transform_later(new_pf_wmt );
       new_pf_wmt->set_req(0, need_pf_true);
 
-      Node *store_new_wmt = new (C, 4) StorePNode( need_pf_true,
+      Node *store_new_wmt = new (C) StorePNode( need_pf_true,
                                        contended_phi_rawmem, eden_pf_adr,
                                        TypeRawPtr::BOTTOM, new_pf_wmt );
       transform_later(store_new_wmt);
@@ -1681,10 +1675,10 @@
       uint distance = 0;
 
       for ( uint i = 0; i < lines; i++ ) {
-        prefetch_adr = new (C, 4) AddPNode( old_pf_wm, new_pf_wmt,
+        prefetch_adr = new (C) AddPNode( old_pf_wm, new_pf_wmt,
                                             _igvn.MakeConX(distance) );
         transform_later(prefetch_adr);
-        prefetch = new (C, 3) PrefetchAllocationNode( i_o, prefetch_adr );
+        prefetch = new (C) PrefetchAllocationNode( i_o, prefetch_adr );
         transform_later(prefetch);
         distance += step_size;
         i_o = prefetch;
@@ -1707,9 +1701,9 @@
    } else if( UseTLAB && AllocatePrefetchStyle == 3 ) {
       // Insert a prefetch for each allocation.
       // This code is used for Sparc with BIS.
-      Node *pf_region = new (C, 3) RegionNode(3);
-      Node *pf_phi_rawmem = new (C, 3) PhiNode( pf_region, Type::MEMORY,
-                                                TypeRawPtr::BOTTOM );
+      Node *pf_region = new (C) RegionNode(3);
+      Node *pf_phi_rawmem = new (C) PhiNode( pf_region, Type::MEMORY,
+                                             TypeRawPtr::BOTTOM );
 
       // Generate several prefetch instructions.
       uint lines = (length != NULL) ? AllocatePrefetchLines : AllocateInstancePrefetchLines;
@@ -1717,29 +1711,29 @@
       uint distance = AllocatePrefetchDistance;
 
       // Next cache address.
-      Node *cache_adr = new (C, 4) AddPNode(old_eden_top, old_eden_top,
+      Node *cache_adr = new (C) AddPNode(old_eden_top, old_eden_top,
                                             _igvn.MakeConX(distance));
       transform_later(cache_adr);
-      cache_adr = new (C, 2) CastP2XNode(needgc_false, cache_adr);
+      cache_adr = new (C) CastP2XNode(needgc_false, cache_adr);
       transform_later(cache_adr);
       Node* mask = _igvn.MakeConX(~(intptr_t)(step_size-1));
-      cache_adr = new (C, 3) AndXNode(cache_adr, mask);
+      cache_adr = new (C) AndXNode(cache_adr, mask);
       transform_later(cache_adr);
-      cache_adr = new (C, 2) CastX2PNode(cache_adr);
+      cache_adr = new (C) CastX2PNode(cache_adr);
       transform_later(cache_adr);
 
       // Prefetch
-      Node *prefetch = new (C, 3) PrefetchAllocationNode( contended_phi_rawmem, cache_adr );
+      Node *prefetch = new (C) PrefetchAllocationNode( contended_phi_rawmem, cache_adr );
       prefetch->set_req(0, needgc_false);
       transform_later(prefetch);
       contended_phi_rawmem = prefetch;
       Node *prefetch_adr;
       distance = step_size;
       for ( uint i = 1; i < lines; i++ ) {
-        prefetch_adr = new (C, 4) AddPNode( cache_adr, cache_adr,
+        prefetch_adr = new (C) AddPNode( cache_adr, cache_adr,
                                             _igvn.MakeConX(distance) );
         transform_later(prefetch_adr);
-        prefetch = new (C, 3) PrefetchAllocationNode( contended_phi_rawmem, prefetch_adr );
+        prefetch = new (C) PrefetchAllocationNode( contended_phi_rawmem, prefetch_adr );
         transform_later(prefetch);
         distance += step_size;
         contended_phi_rawmem = prefetch;
@@ -1753,10 +1747,10 @@
       uint step_size = AllocatePrefetchStepSize;
       uint distance = AllocatePrefetchDistance;
       for ( uint i = 0; i < lines; i++ ) {
-        prefetch_adr = new (C, 4) AddPNode( old_eden_top, new_eden_top,
+        prefetch_adr = new (C) AddPNode( old_eden_top, new_eden_top,
                                             _igvn.MakeConX(distance) );
         transform_later(prefetch_adr);
-        prefetch = new (C, 3) PrefetchAllocationNode( i_o, prefetch_adr );
+        prefetch = new (C) PrefetchAllocationNode( i_o, prefetch_adr );
         // Do not let it float too high, since if eden_top == eden_end,
         // both might be null.
         if( i == 0 ) { // Set control for first prefetch, next follows it
@@ -1857,18 +1851,16 @@
       if (alock->box_node() == oldbox && alock->obj_node()->eqv_uncast(obj)) {
         // Replace Box and mark eliminated all related locks and unlocks.
         alock->set_non_esc_obj();
-        _igvn.hash_delete(alock);
+        _igvn.rehash_node_delayed(alock);
         alock->set_box_node(newbox);
-        _igvn._worklist.push(alock);
         next_edge = false;
       }
     }
     if (u->is_FastLock() && u->as_FastLock()->obj_node()->eqv_uncast(obj)) {
       FastLockNode* flock = u->as_FastLock();
       assert(flock->box_node() == oldbox, "sanity");
-      _igvn.hash_delete(flock);
+      _igvn.rehash_node_delayed(flock);
       flock->set_box_node(newbox);
-      _igvn._worklist.push(flock);
       next_edge = false;
     }
 
@@ -1886,9 +1878,7 @@
           Node* box_node = sfn->monitor_box(jvms, idx);
           if (box_node == oldbox && obj_node->eqv_uncast(obj)) {
             int j = jvms->monitor_box_offset(idx);
-            _igvn.hash_delete(u);
-            u->set_req(j, newbox);
-            _igvn._worklist.push(u);
+            _igvn.replace_input_of(u, j, newbox);
             next_edge = false;
           }
         }
@@ -2109,12 +2099,12 @@
      *  }
      */
 
-    region  = new (C, 5) RegionNode(5);
+    region  = new (C) RegionNode(5);
     // create a Phi for the memory state
-    mem_phi = new (C, 5) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
 
-    Node* fast_lock_region  = new (C, 3) RegionNode(3);
-    Node* fast_lock_mem_phi = new (C, 3) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    Node* fast_lock_region  = new (C) RegionNode(3);
+    Node* fast_lock_mem_phi = new (C) PhiNode( fast_lock_region, Type::MEMORY, TypeRawPtr::BOTTOM);
 
     // First, check mark word for the biased lock pattern.
     Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
@@ -2144,10 +2134,10 @@
     }
     Node *proto_node = make_load(ctrl, mem, klass_node, in_bytes(Klass::prototype_header_offset()), TypeX_X, TypeX_X->basic_type());
 
-    Node* thread = transform_later(new (C, 1) ThreadLocalNode());
-    Node* cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
-    Node* o_node = transform_later(new (C, 3) OrXNode(cast_thread, proto_node));
-    Node* x_node = transform_later(new (C, 3) XorXNode(o_node, mark_node));
+    Node* thread = transform_later(new (C) ThreadLocalNode());
+    Node* cast_thread = transform_later(new (C) CastP2XNode(ctrl, thread));
+    Node* o_node = transform_later(new (C) OrXNode(cast_thread, proto_node));
+    Node* x_node = transform_later(new (C) XorXNode(o_node, mark_node));
 
     // Get slow path - mark word does NOT match the value.
     Node* not_biased_ctrl =  opt_bits_test(ctrl, region, 3, x_node,
@@ -2170,17 +2160,17 @@
     // We are going to try to reset the mark of this object to the prototype
     // value and fall through to the CAS-based locking scheme.
     Node* adr = basic_plus_adr(obj, oopDesc::mark_offset_in_bytes());
-    Node* cas = new (C, 5) StoreXConditionalNode(not_biased_ctrl, mem, adr,
-                                                 proto_node, mark_node);
+    Node* cas = new (C) StoreXConditionalNode(not_biased_ctrl, mem, adr,
+                                              proto_node, mark_node);
     transform_later(cas);
-    Node* proj = transform_later( new (C, 1) SCMemProjNode(cas));
+    Node* proj = transform_later( new (C) SCMemProjNode(cas));
     fast_lock_mem_phi->init_req(2, proj);
 
 
     // Second, check epoch bits.
-    Node* rebiased_region  = new (C, 3) RegionNode(3);
-    Node* old_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
-    Node* new_phi = new (C, 3) PhiNode( rebiased_region, TypeX_X);
+    Node* rebiased_region  = new (C) RegionNode(3);
+    Node* old_phi = new (C) PhiNode( rebiased_region, TypeX_X);
+    Node* new_phi = new (C) PhiNode( rebiased_region, TypeX_X);
 
     // Get slow path - mark word does NOT match epoch bits.
     Node* epoch_ctrl =  opt_bits_test(ctrl, rebiased_region, 1, x_node,
@@ -2197,9 +2187,9 @@
     Node* cmask   = MakeConX(markOopDesc::biased_lock_mask_in_place |
                              markOopDesc::age_mask_in_place |
                              markOopDesc::epoch_mask_in_place);
-    Node* old = transform_later(new (C, 3) AndXNode(mark_node, cmask));
-    cast_thread = transform_later(new (C, 2) CastP2XNode(ctrl, thread));
-    Node* new_mark = transform_later(new (C, 3) OrXNode(cast_thread, old));
+    Node* old = transform_later(new (C) AndXNode(mark_node, cmask));
+    cast_thread = transform_later(new (C) CastP2XNode(ctrl, thread));
+    Node* new_mark = transform_later(new (C) OrXNode(cast_thread, old));
     old_phi->init_req(1, old);
     new_phi->init_req(1, new_mark);
 
@@ -2209,10 +2199,10 @@
 
     // Try to acquire the bias of the object using an atomic operation.
     // If this fails we will go in to the runtime to revoke the object's bias.
-    cas = new (C, 5) StoreXConditionalNode(rebiased_region, mem, adr,
+    cas = new (C) StoreXConditionalNode(rebiased_region, mem, adr,
                                            new_phi, old_phi);
     transform_later(cas);
-    proj = transform_later( new (C, 1) SCMemProjNode(cas));
+    proj = transform_later( new (C) SCMemProjNode(cas));
 
     // Get slow path - Failed to CAS.
     not_biased_ctrl = opt_bits_test(rebiased_region, region, 4, cas, 0, 0);
@@ -2220,8 +2210,8 @@
     // region->in(4) is set to fast path - the object is rebiased to the current thread.
 
     // Failed to CAS.
-    slow_path  = new (C, 3) RegionNode(3);
-    Node *slow_mem = new (C, 3) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM);
+    slow_path  = new (C) RegionNode(3);
+    Node *slow_mem = new (C) PhiNode( slow_path, Type::MEMORY, TypeRawPtr::BOTTOM);
 
     slow_path->init_req(1, not_biased_ctrl); // Capture slow-control
     slow_mem->init_req(1, proj);
@@ -2245,9 +2235,9 @@
     lock->set_req(TypeFunc::Memory, slow_mem);
 
   } else {
-    region  = new (C, 3) RegionNode(3);
+    region  = new (C) RegionNode(3);
     // create a Phi for the memory state
-    mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
 
     // Optimize test; set region slot 2
     slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0);
@@ -2278,7 +2268,7 @@
   transform_later(region);
   _igvn.replace_node(_fallthroughproj, region);
 
-  Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
+  Node *memproj = transform_later( new(C) ProjNode(call, TypeFunc::Memory) );
   mem_phi->init_req(1, memproj );
   transform_later(mem_phi);
   _igvn.replace_node(_memproj_fallthrough, mem_phi);
@@ -2303,9 +2293,9 @@
   if (UseOptoBiasInlining) {
     // Check for biased locking unlock case, which is a no-op.
     // See the full description in MacroAssembler::biased_locking_exit().
-    region  = new (C, 4) RegionNode(4);
+    region  = new (C) RegionNode(4);
     // create a Phi for the memory state
-    mem_phi = new (C, 4) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
     mem_phi->init_req(3, mem);
 
     Node* mark_node = make_load(ctrl, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
@@ -2313,12 +2303,12 @@
                          markOopDesc::biased_lock_mask_in_place,
                          markOopDesc::biased_lock_pattern);
   } else {
-    region  = new (C, 3) RegionNode(3);
+    region  = new (C) RegionNode(3);
     // create a Phi for the memory state
-    mem_phi = new (C, 3) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
+    mem_phi = new (C) PhiNode( region, Type::MEMORY, TypeRawPtr::BOTTOM);
   }
 
-  FastUnlockNode *funlock = new (C, 3) FastUnlockNode( ctrl, obj, box );
+  FastUnlockNode *funlock = new (C) FastUnlockNode( ctrl, obj, box );
   funlock = transform_later( funlock )->as_FastUnlock();
   // Optimize test; set region slot 2
   Node *slow_path = opt_bits_test(ctrl, region, 2, funlock, 0, 0);
@@ -2343,7 +2333,7 @@
   transform_later(region);
   _igvn.replace_node(_fallthroughproj, region);
 
-  Node *memproj = transform_later( new(C, 1) ProjNode(call, TypeFunc::Memory) );
+  Node *memproj = transform_later( new(C) ProjNode(call, TypeFunc::Memory) );
   mem_phi->init_req(1, memproj );
   mem_phi->init_req(2, mem);
   transform_later(mem_phi);
diff --git a/hotspot/src/share/vm/opto/macro.hpp b/hotspot/src/share/vm/opto/macro.hpp
index f521e3d..b84d8d7 100644
--- a/hotspot/src/share/vm/opto/macro.hpp
+++ b/hotspot/src/share/vm/opto/macro.hpp
@@ -52,7 +52,7 @@
     return basic_plus_adr(base, base, offset);
   }
   Node* basic_plus_adr(Node* base, Node* ptr, Node* offset) {
-    Node* adr = new (C, 4) AddPNode(base, ptr, offset);
+    Node* adr = new (C) AddPNode(base, ptr, offset);
     return transform_later(adr);
   }
   Node* transform_later(Node* n) {
diff --git a/hotspot/src/share/vm/opto/matcher.cpp b/hotspot/src/share/vm/opto/matcher.cpp
index 3973856..562f145 100644
--- a/hotspot/src/share/vm/opto/matcher.cpp
+++ b/hotspot/src/share/vm/opto/matcher.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -35,6 +35,7 @@
 #include "opto/rootnode.hpp"
 #include "opto/runtime.hpp"
 #include "opto/type.hpp"
+#include "opto/vectornode.hpp"
 #include "runtime/atomic.hpp"
 #include "runtime/os.hpp"
 #ifdef TARGET_ARCH_MODEL_x86_32
@@ -58,18 +59,6 @@
 
 OptoReg::Name OptoReg::c_frame_pointer;
 
-
-
-const int Matcher::base2reg[Type::lastype] = {
-  Node::NotAMachineReg,0,0, Op_RegI, Op_RegL, 0, Op_RegN,
-  Node::NotAMachineReg, Node::NotAMachineReg, /* tuple, array */
-  Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, Op_RegP, /* the pointers */
-  0, 0/*abio*/,
-  Op_RegP /* Return address */, 0, /* the memories */
-  Op_RegF, Op_RegF, Op_RegF, Op_RegD, Op_RegD, Op_RegD,
-  0  /*bottom*/
-};
-
 const RegMask *Matcher::idealreg2regmask[_last_machine_leaf];
 RegMask Matcher::mreg2regmask[_last_Mach_Reg];
 RegMask Matcher::STACK_ONLY_mask;
@@ -107,6 +96,10 @@
   idealreg2spillmask  [Op_RegF] = NULL;
   idealreg2spillmask  [Op_RegD] = NULL;
   idealreg2spillmask  [Op_RegP] = NULL;
+  idealreg2spillmask  [Op_VecS] = NULL;
+  idealreg2spillmask  [Op_VecD] = NULL;
+  idealreg2spillmask  [Op_VecX] = NULL;
+  idealreg2spillmask  [Op_VecY] = NULL;
 
   idealreg2debugmask  [Op_RegI] = NULL;
   idealreg2debugmask  [Op_RegN] = NULL;
@@ -114,6 +107,10 @@
   idealreg2debugmask  [Op_RegF] = NULL;
   idealreg2debugmask  [Op_RegD] = NULL;
   idealreg2debugmask  [Op_RegP] = NULL;
+  idealreg2debugmask  [Op_VecS] = NULL;
+  idealreg2debugmask  [Op_VecD] = NULL;
+  idealreg2debugmask  [Op_VecX] = NULL;
+  idealreg2debugmask  [Op_VecY] = NULL;
 
   idealreg2mhdebugmask[Op_RegI] = NULL;
   idealreg2mhdebugmask[Op_RegN] = NULL;
@@ -121,6 +118,10 @@
   idealreg2mhdebugmask[Op_RegF] = NULL;
   idealreg2mhdebugmask[Op_RegD] = NULL;
   idealreg2mhdebugmask[Op_RegP] = NULL;
+  idealreg2mhdebugmask[Op_VecS] = NULL;
+  idealreg2mhdebugmask[Op_VecD] = NULL;
+  idealreg2mhdebugmask[Op_VecX] = NULL;
+  idealreg2mhdebugmask[Op_VecY] = NULL;
 
   debug_only(_mem_node = NULL;)   // Ideal memory node consumed by mach node
 }
@@ -134,7 +135,7 @@
     warped = OptoReg::add(warped, C->out_preserve_stack_slots());
     if( warped >= _in_arg_limit )
       _in_arg_limit = OptoReg::add(warped, 1); // Bump max stack slot seen
-    if (!RegMask::can_represent(warped)) {
+    if (!RegMask::can_represent_arg(warped)) {
       // the compiler cannot represent this method's calling sequence
       C->record_method_not_compilable_all_tiers("unsupported incoming calling sequence");
       return OptoReg::Bad;
@@ -302,7 +303,7 @@
   _out_arg_limit = OptoReg::add(_new_SP, C->out_preserve_stack_slots());
   assert( is_even(_out_arg_limit), "out_preserve must be even" );
 
-  if (!RegMask::can_represent(OptoReg::add(_out_arg_limit,-1))) {
+  if (!RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1))) {
     // the compiler cannot represent this method's calling sequence
     C->record_method_not_compilable("must be able to represent all call arguments in reg mask");
   }
@@ -428,7 +429,7 @@
 void Matcher::init_first_stack_mask() {
 
   // Allocate storage for spill masks as masks for the appropriate load type.
-  RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask) * 3*6);
+  RegMask *rms = (RegMask*)C->comp_arena()->Amalloc_D(sizeof(RegMask) * (3*6+4));
 
   idealreg2spillmask  [Op_RegN] = &rms[0];
   idealreg2spillmask  [Op_RegI] = &rms[1];
@@ -451,6 +452,11 @@
   idealreg2mhdebugmask[Op_RegD] = &rms[16];
   idealreg2mhdebugmask[Op_RegP] = &rms[17];
 
+  idealreg2spillmask  [Op_VecS] = &rms[18];
+  idealreg2spillmask  [Op_VecD] = &rms[19];
+  idealreg2spillmask  [Op_VecX] = &rms[20];
+  idealreg2spillmask  [Op_VecY] = &rms[21];
+
   OptoReg::Name i;
 
   // At first, start with the empty mask
@@ -462,7 +468,7 @@
     C->FIRST_STACK_mask().Insert(i);
 
   // Add in all bits past the outgoing argument area
-  guarantee(RegMask::can_represent(OptoReg::add(_out_arg_limit,-1)),
+  guarantee(RegMask::can_represent_arg(OptoReg::add(_out_arg_limit,-1)),
             "must be able to represent all call arguments in reg mask");
   init = _out_arg_limit;
   for (i = init; RegMask::can_represent(i); i = OptoReg::add(i,1))
@@ -472,21 +478,48 @@
   C->FIRST_STACK_mask().set_AllStack();
 
   // Make spill masks.  Registers for their class, plus FIRST_STACK_mask.
+  RegMask aligned_stack_mask = C->FIRST_STACK_mask();
+  // Keep spill masks aligned.
+  aligned_stack_mask.clear_to_pairs();
+  assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
+
+  *idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP];
 #ifdef _LP64
   *idealreg2spillmask[Op_RegN] = *idealreg2regmask[Op_RegN];
    idealreg2spillmask[Op_RegN]->OR(C->FIRST_STACK_mask());
+   idealreg2spillmask[Op_RegP]->OR(aligned_stack_mask);
+#else
+   idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask());
 #endif
   *idealreg2spillmask[Op_RegI] = *idealreg2regmask[Op_RegI];
    idealreg2spillmask[Op_RegI]->OR(C->FIRST_STACK_mask());
   *idealreg2spillmask[Op_RegL] = *idealreg2regmask[Op_RegL];
-   idealreg2spillmask[Op_RegL]->OR(C->FIRST_STACK_mask());
+   idealreg2spillmask[Op_RegL]->OR(aligned_stack_mask);
   *idealreg2spillmask[Op_RegF] = *idealreg2regmask[Op_RegF];
    idealreg2spillmask[Op_RegF]->OR(C->FIRST_STACK_mask());
   *idealreg2spillmask[Op_RegD] = *idealreg2regmask[Op_RegD];
-   idealreg2spillmask[Op_RegD]->OR(C->FIRST_STACK_mask());
-  *idealreg2spillmask[Op_RegP] = *idealreg2regmask[Op_RegP];
-   idealreg2spillmask[Op_RegP]->OR(C->FIRST_STACK_mask());
+   idealreg2spillmask[Op_RegD]->OR(aligned_stack_mask);
 
+  if (Matcher::vector_size_supported(T_BYTE,4)) {
+    *idealreg2spillmask[Op_VecS] = *idealreg2regmask[Op_VecS];
+     idealreg2spillmask[Op_VecS]->OR(C->FIRST_STACK_mask());
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,2)) {
+    *idealreg2spillmask[Op_VecD] = *idealreg2regmask[Op_VecD];
+     idealreg2spillmask[Op_VecD]->OR(aligned_stack_mask);
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,4)) {
+     aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecX);
+     assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
+    *idealreg2spillmask[Op_VecX] = *idealreg2regmask[Op_VecX];
+     idealreg2spillmask[Op_VecX]->OR(aligned_stack_mask);
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,8)) {
+     aligned_stack_mask.clear_to_sets(RegMask::SlotsPerVecY);
+     assert(aligned_stack_mask.is_AllStack(), "should be infinite stack");
+    *idealreg2spillmask[Op_VecY] = *idealreg2regmask[Op_VecY];
+     idealreg2spillmask[Op_VecY]->OR(aligned_stack_mask);
+  }
    if (UseFPUForSpilling) {
      // This mask logic assumes that the spill operations are
      // symmetric and that the registers involved are the same size.
@@ -694,7 +727,7 @@
         tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1));
         tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1));
         halt_rms     [     halt_edge_cnt].Insert(OptoReg::Name(i+1));
-        mproj = new (C, 1) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD );
+        mproj = new (C) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegD );
         proj_cnt += 2;          // Skip 2 for doubles
       }
       else if( (i&1) == 1 &&    // Else check for high half of double
@@ -720,7 +753,7 @@
         tail_call_rms[tail_call_edge_cnt].Insert(OptoReg::Name(i+1));
         tail_jump_rms[tail_jump_edge_cnt].Insert(OptoReg::Name(i+1));
         halt_rms     [     halt_edge_cnt].Insert(OptoReg::Name(i+1));
-        mproj = new (C, 1) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL );
+        mproj = new (C) MachProjNode( start, proj_cnt, ret_rms[ret_edge_cnt], Op_RegL );
         proj_cnt += 2;          // Skip 2 for longs
       }
       else if( (i&1) == 1 &&    // Else check for high half of long
@@ -735,7 +768,7 @@
         mproj = C->top();
       } else {
         // Make a projection for it off the Start
-        mproj = new (C, 1) MachProjNode( start, proj_cnt++, ret_rms[ret_edge_cnt], _register_save_type[i] );
+        mproj = new (C) MachProjNode( start, proj_cnt++, ret_rms[ret_edge_cnt], _register_save_type[i] );
       }
 
       ret_edge_cnt ++;
@@ -788,13 +821,13 @@
 
   // Compute generic short-offset Loads
 #ifdef _LP64
-  MachNode *spillCP = match_tree(new (C, 3) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM));
+  MachNode *spillCP = match_tree(new (C) LoadNNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM));
 #endif
-  MachNode *spillI  = match_tree(new (C, 3) LoadINode(NULL,mem,fp,atp));
-  MachNode *spillL  = match_tree(new (C, 3) LoadLNode(NULL,mem,fp,atp));
-  MachNode *spillF  = match_tree(new (C, 3) LoadFNode(NULL,mem,fp,atp));
-  MachNode *spillD  = match_tree(new (C, 3) LoadDNode(NULL,mem,fp,atp));
-  MachNode *spillP  = match_tree(new (C, 3) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM));
+  MachNode *spillI  = match_tree(new (C) LoadINode(NULL,mem,fp,atp));
+  MachNode *spillL  = match_tree(new (C) LoadLNode(NULL,mem,fp,atp));
+  MachNode *spillF  = match_tree(new (C) LoadFNode(NULL,mem,fp,atp));
+  MachNode *spillD  = match_tree(new (C) LoadDNode(NULL,mem,fp,atp));
+  MachNode *spillP  = match_tree(new (C) LoadPNode(NULL,mem,fp,atp,TypeInstPtr::BOTTOM));
   assert(spillI != NULL && spillL != NULL && spillF != NULL &&
          spillD != NULL && spillP != NULL, "");
 
@@ -807,6 +840,25 @@
   idealreg2regmask[Op_RegF] = &spillF->out_RegMask();
   idealreg2regmask[Op_RegD] = &spillD->out_RegMask();
   idealreg2regmask[Op_RegP] = &spillP->out_RegMask();
+
+  // Vector regmasks.
+  if (Matcher::vector_size_supported(T_BYTE,4)) {
+    TypeVect::VECTS = TypeVect::make(T_BYTE, 4);
+    MachNode *spillVectS = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTS));
+    idealreg2regmask[Op_VecS] = &spillVectS->out_RegMask();
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,2)) {
+    MachNode *spillVectD = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTD));
+    idealreg2regmask[Op_VecD] = &spillVectD->out_RegMask();
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,4)) {
+    MachNode *spillVectX = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTX));
+    idealreg2regmask[Op_VecX] = &spillVectX->out_RegMask();
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,8)) {
+    MachNode *spillVectY = match_tree(new (C) LoadVectorNode(NULL,mem,fp,atp,TypeVect::VECTY));
+    idealreg2regmask[Op_VecY] = &spillVectY->out_RegMask();
+  }
 }
 
 #ifdef ASSERT
@@ -1063,7 +1115,7 @@
     // that is killed by the call.
     if( warped >= out_arg_limit_per_call )
       out_arg_limit_per_call = OptoReg::add(warped,1);
-    if (!RegMask::can_represent(warped)) {
+    if (!RegMask::can_represent_arg(warped)) {
       C->record_method_not_compilable_all_tiers("unsupported calling sequence");
       return OptoReg::Bad;
     }
@@ -1231,8 +1283,9 @@
   if (is_method_handle_invoke) {
     // Kill some extra stack space in case method handles want to do
     // a little in-place argument insertion.
+    // FIXME: Is this still necessary?
     int regs_per_word  = NOT_LP64(1) LP64_ONLY(2); // %%% make a global const!
-    out_arg_limit_per_call += MethodHandlePushLimit * regs_per_word;
+    out_arg_limit_per_call += methodOopDesc::extra_stack_entries() * regs_per_word;
     // Do not update mcall->_argsize because (a) the extra space is not
     // pushed as arguments and (b) _argsize is dead (not used anywhere).
   }
@@ -1250,8 +1303,8 @@
     // is excluded on the max-per-method basis, debug info cannot land in
     // this killed area.
     uint r_cnt = mcall->tf()->range()->cnt();
-    MachProjNode *proj = new (C, 1) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj );
-    if (!RegMask::can_represent(OptoReg::Name(out_arg_limit_per_call-1))) {
+    MachProjNode *proj = new (C) MachProjNode( mcall, r_cnt+10000, RegMask::Empty, MachProjNode::fat_proj );
+    if (!RegMask::can_represent_arg(OptoReg::Name(out_arg_limit_per_call-1))) {
       C->record_method_not_compilable_all_tiers("unsupported outgoing calling sequence");
     } else {
       for (int i = begin_out_arg_area; i < out_arg_limit_per_call; i++)
@@ -2081,10 +2134,10 @@
       case Op_CompareAndSwapP:
       case Op_CompareAndSwapN: {   // Convert trinary to binary-tree
         Node *newval = n->in(MemNode::ValueIn );
-        Node *oldval  = n->in(LoadStoreNode::ExpectedIn);
-        Node *pair = new (C, 3) BinaryNode( oldval, newval );
+        Node *oldval  = n->in(LoadStoreConditionalNode::ExpectedIn);
+        Node *pair = new (C) BinaryNode( oldval, newval );
         n->set_req(MemNode::ValueIn,pair);
-        n->del_req(LoadStoreNode::ExpectedIn);
+        n->del_req(LoadStoreConditionalNode::ExpectedIn);
         break;
       }
       case Op_CMoveD:              // Convert trinary to binary-tree
@@ -2097,22 +2150,22 @@
         // we could move this code up next to the graph reshaping for IfNodes
         // or vice-versa, but I do not want to debug this for Ladybird.
         // 10/2/2000 CNC.
-        Node *pair1 = new (C, 3) BinaryNode(n->in(1),n->in(1)->in(1));
+        Node *pair1 = new (C) BinaryNode(n->in(1),n->in(1)->in(1));
         n->set_req(1,pair1);
-        Node *pair2 = new (C, 3) BinaryNode(n->in(2),n->in(3));
+        Node *pair2 = new (C) BinaryNode(n->in(2),n->in(3));
         n->set_req(2,pair2);
         n->del_req(3);
         break;
       }
       case Op_LoopLimit: {
-        Node *pair1 = new (C, 3) BinaryNode(n->in(1),n->in(2));
+        Node *pair1 = new (C) BinaryNode(n->in(1),n->in(2));
         n->set_req(1,pair1);
         n->set_req(2,n->in(3));
         n->del_req(3);
         break;
       }
       case Op_StrEquals: {
-        Node *pair1 = new (C, 3) BinaryNode(n->in(2),n->in(3));
+        Node *pair1 = new (C) BinaryNode(n->in(2),n->in(3));
         n->set_req(2,pair1);
         n->set_req(3,n->in(4));
         n->del_req(4);
@@ -2120,9 +2173,9 @@
       }
       case Op_StrComp:
       case Op_StrIndexOf: {
-        Node *pair1 = new (C, 3) BinaryNode(n->in(2),n->in(3));
+        Node *pair1 = new (C) BinaryNode(n->in(2),n->in(3));
         n->set_req(2,pair1);
-        Node *pair2 = new (C, 3) BinaryNode(n->in(4),n->in(5));
+        Node *pair2 = new (C) BinaryNode(n->in(4),n->in(5));
         n->set_req(3,pair2);
         n->del_req(5);
         n->del_req(4);
diff --git a/hotspot/src/share/vm/opto/matcher.hpp b/hotspot/src/share/vm/opto/matcher.hpp
index e6aae28..844015c 100644
--- a/hotspot/src/share/vm/opto/matcher.hpp
+++ b/hotspot/src/share/vm/opto/matcher.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -250,10 +250,22 @@
   static const bool convL2FSupported(void);
 
   // Vector width in bytes
-  static const uint vector_width_in_bytes(void);
+  static const int vector_width_in_bytes(BasicType bt);
+
+  // Limits on vector size (number of elements).
+  static const int max_vector_size(const BasicType bt);
+  static const int min_vector_size(const BasicType bt);
+  static const bool vector_size_supported(const BasicType bt, int size) {
+    return (Matcher::max_vector_size(bt) >= size &&
+            Matcher::min_vector_size(bt) <= size);
+  }
 
   // Vector ideal reg
-  static const uint vector_ideal_reg(void);
+  static const int vector_ideal_reg(int len);
+  static const int vector_shift_count_ideal_reg(int len);
+
+  // CPU supports misaligned vectors store/load.
+  static const bool misaligned_vectors_ok();
 
   // Used to determine a "low complexity" 64-bit constant.  (Zero is simple.)
   // The standard of comparison is one (StoreL ConL) vs. two (StoreI ConI).
diff --git a/hotspot/src/share/vm/opto/memnode.cpp b/hotspot/src/share/vm/opto/memnode.cpp
index e28e092..6e29210 100644
--- a/hotspot/src/share/vm/opto/memnode.cpp
+++ b/hotspot/src/share/vm/opto/memnode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -883,25 +883,25 @@
           rt->isa_oopptr() || is_immutable_value(adr),
           "raw memory operations should have control edge");
   switch (bt) {
-  case T_BOOLEAN: return new (C, 3) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_BYTE:    return new (C, 3) LoadBNode (ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_INT:     return new (C, 3) LoadINode (ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_CHAR:    return new (C, 3) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_SHORT:   return new (C, 3) LoadSNode (ctl, mem, adr, adr_type, rt->is_int()    );
-  case T_LONG:    return new (C, 3) LoadLNode (ctl, mem, adr, adr_type, rt->is_long()   );
-  case T_FLOAT:   return new (C, 3) LoadFNode (ctl, mem, adr, adr_type, rt              );
-  case T_DOUBLE:  return new (C, 3) LoadDNode (ctl, mem, adr, adr_type, rt              );
-  case T_ADDRESS: return new (C, 3) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr()    );
+  case T_BOOLEAN: return new (C) LoadUBNode(ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_BYTE:    return new (C) LoadBNode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_INT:     return new (C) LoadINode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_CHAR:    return new (C) LoadUSNode(ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_SHORT:   return new (C) LoadSNode (ctl, mem, adr, adr_type, rt->is_int()    );
+  case T_LONG:    return new (C) LoadLNode (ctl, mem, adr, adr_type, rt->is_long()   );
+  case T_FLOAT:   return new (C) LoadFNode (ctl, mem, adr, adr_type, rt              );
+  case T_DOUBLE:  return new (C) LoadDNode (ctl, mem, adr, adr_type, rt              );
+  case T_ADDRESS: return new (C) LoadPNode (ctl, mem, adr, adr_type, rt->is_ptr()    );
   case T_OBJECT:
 #ifdef _LP64
     if (adr->bottom_type()->is_ptr_to_narrowoop()) {
-      Node* load  = gvn.transform(new (C, 3) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop()));
-      return new (C, 2) DecodeNNode(load, load->bottom_type()->make_ptr());
+      Node* load  = gvn.transform(new (C) LoadNNode(ctl, mem, adr, adr_type, rt->make_narrowoop()));
+      return new (C) DecodeNNode(load, load->bottom_type()->make_ptr());
     } else
 #endif
     {
       assert(!adr->bottom_type()->is_ptr_to_narrowoop(), "should have got back a narrow oop");
-      return new (C, 3) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr());
+      return new (C) LoadPNode(ctl, mem, adr, adr_type, rt->is_oopptr());
     }
   }
   ShouldNotReachHere();
@@ -910,7 +910,7 @@
 
 LoadLNode* LoadLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, const Type* rt) {
   bool require_atomic = true;
-  return new (C, 3) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), require_atomic);
+  return new (C) LoadLNode(ctl, mem, adr, adr_type, rt->is_long(), require_atomic);
 }
 
 
@@ -1244,20 +1244,20 @@
           // Add up all the offsets making of the address of the load
           Node* result = elements[0];
           for (int i = 1; i < count; i++) {
-            result = phase->transform(new (phase->C, 3) AddXNode(result, elements[i]));
+            result = phase->transform(new (phase->C) AddXNode(result, elements[i]));
           }
           // Remove the constant offset from the address and then
           // remove the scaling of the offset to recover the original index.
-          result = phase->transform(new (phase->C, 3) AddXNode(result, phase->MakeConX(-offset)));
+          result = phase->transform(new (phase->C) AddXNode(result, phase->MakeConX(-offset)));
           if (result->Opcode() == Op_LShiftX && result->in(2) == phase->intcon(shift)) {
             // Peel the shift off directly but wrap it in a dummy node
             // since Ideal can't return existing nodes
-            result = new (phase->C, 3) RShiftXNode(result->in(1), phase->intcon(0));
+            result = new (phase->C) RShiftXNode(result->in(1), phase->intcon(0));
           } else {
-            result = new (phase->C, 3) RShiftXNode(result, phase->intcon(shift));
+            result = new (phase->C) RShiftXNode(result, phase->intcon(shift));
           }
 #ifdef _LP64
-          result = new (phase->C, 2) ConvL2INode(phase->transform(result));
+          result = new (phase->C) ConvL2INode(phase->transform(result));
 #endif
           return result;
         }
@@ -1320,7 +1320,7 @@
   int this_offset = addr_t->offset();
   int this_iid    = addr_t->is_oopptr()->instance_id();
   PhaseIterGVN *igvn = phase->is_IterGVN();
-  Node *phi = new (igvn->C, region->req()) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
+  Node *phi = new (igvn->C) PhiNode(region, this_type, NULL, this_iid, this_index, this_offset);
   for (uint i = 1; i < region->req(); i++) {
     Node *x;
     Node* the_clone = NULL;
@@ -1543,6 +1543,7 @@
     // had an original form like p1:(AddP x x (LShiftL quux 3)), where the
     // expression (LShiftL quux 3) independently optimized to the constant 8.
     if ((t->isa_int() == NULL) && (t->isa_long() == NULL)
+        && (_type->isa_vect() == NULL)
         && Opcode() != Op_LoadKlass && Opcode() != Op_LoadNKlass) {
       // t might actually be lower than _type, if _type is a unique
       // concrete subclass of abstract class t.
@@ -1770,8 +1771,8 @@
   Node* mem = in(MemNode::Memory);
   Node* value = can_see_stored_value(mem,phase);
   if( value && !phase->type(value)->higher_equal( _type ) ) {
-    Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(24)) );
-    return new (phase->C, 3) RShiftINode(result, phase->intcon(24));
+    Node *result = phase->transform( new (phase->C) LShiftINode(value, phase->intcon(24)) );
+    return new (phase->C) RShiftINode(result, phase->intcon(24));
   }
   // Identity call will handle the case where truncation is not needed.
   return LoadNode::Ideal(phase, can_reshape);
@@ -1802,7 +1803,7 @@
   Node* mem = in(MemNode::Memory);
   Node* value = can_see_stored_value(mem, phase);
   if (value && !phase->type(value)->higher_equal(_type))
-    return new (phase->C, 3) AndINode(value, phase->intcon(0xFF));
+    return new (phase->C) AndINode(value, phase->intcon(0xFF));
   // Identity call will handle the case where truncation is not needed.
   return LoadNode::Ideal(phase, can_reshape);
 }
@@ -1832,7 +1833,7 @@
   Node* mem = in(MemNode::Memory);
   Node* value = can_see_stored_value(mem,phase);
   if( value && !phase->type(value)->higher_equal( _type ) )
-    return new (phase->C, 3) AndINode(value,phase->intcon(0xFFFF));
+    return new (phase->C) AndINode(value,phase->intcon(0xFFFF));
   // Identity call will handle the case where truncation is not needed.
   return LoadNode::Ideal(phase, can_reshape);
 }
@@ -1862,8 +1863,8 @@
   Node* mem = in(MemNode::Memory);
   Node* value = can_see_stored_value(mem,phase);
   if( value && !phase->type(value)->higher_equal( _type ) ) {
-    Node *result = phase->transform( new (phase->C, 3) LShiftINode(value, phase->intcon(16)) );
-    return new (phase->C, 3) RShiftINode(result, phase->intcon(16));
+    Node *result = phase->transform( new (phase->C) LShiftINode(value, phase->intcon(16)) );
+    return new (phase->C) RShiftINode(result, phase->intcon(16));
   }
   // Identity call will handle the case where truncation is not needed.
   return LoadNode::Ideal(phase, can_reshape);
@@ -1894,12 +1895,12 @@
   assert(adr_type != NULL, "expecting TypeOopPtr");
 #ifdef _LP64
   if (adr_type->is_ptr_to_narrowoop()) {
-    Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop()));
-    return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr());
+    Node* load_klass = gvn.transform(new (C) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop()));
+    return new (C) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr());
   }
 #endif
   assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
-  return new (C, 3) LoadKlassNode(ctl, mem, adr, at, tk);
+  return new (C) LoadKlassNode(ctl, mem, adr, at, tk);
 }
 
 //------------------------------Value------------------------------------------
@@ -2121,7 +2122,7 @@
   if( t == Type::TOP ) return x;
   if( t->isa_narrowoop()) return x;
 
-  return phase->transform(new (phase->C, 2) EncodePNode(x, t->make_narrowoop()));
+  return phase->transform(new (phase->C) EncodePNode(x, t->make_narrowoop()));
 }
 
 //------------------------------Value-----------------------------------------
@@ -2215,25 +2216,25 @@
 
   switch (bt) {
   case T_BOOLEAN:
-  case T_BYTE:    return new (C, 4) StoreBNode(ctl, mem, adr, adr_type, val);
-  case T_INT:     return new (C, 4) StoreINode(ctl, mem, adr, adr_type, val);
+  case T_BYTE:    return new (C) StoreBNode(ctl, mem, adr, adr_type, val);
+  case T_INT:     return new (C) StoreINode(ctl, mem, adr, adr_type, val);
   case T_CHAR:
-  case T_SHORT:   return new (C, 4) StoreCNode(ctl, mem, adr, adr_type, val);
-  case T_LONG:    return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val);
-  case T_FLOAT:   return new (C, 4) StoreFNode(ctl, mem, adr, adr_type, val);
-  case T_DOUBLE:  return new (C, 4) StoreDNode(ctl, mem, adr, adr_type, val);
+  case T_SHORT:   return new (C) StoreCNode(ctl, mem, adr, adr_type, val);
+  case T_LONG:    return new (C) StoreLNode(ctl, mem, adr, adr_type, val);
+  case T_FLOAT:   return new (C) StoreFNode(ctl, mem, adr, adr_type, val);
+  case T_DOUBLE:  return new (C) StoreDNode(ctl, mem, adr, adr_type, val);
   case T_ADDRESS:
   case T_OBJECT:
 #ifdef _LP64
     if (adr->bottom_type()->is_ptr_to_narrowoop() ||
         (UseCompressedOops && val->bottom_type()->isa_klassptr() &&
          adr->bottom_type()->isa_rawptr())) {
-      val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop()));
-      return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val);
+      val = gvn.transform(new (C) EncodePNode(val, val->bottom_type()->make_narrowoop()));
+      return new (C) StoreNNode(ctl, mem, adr, adr_type, val);
     } else
 #endif
     {
-      return new (C, 4) StorePNode(ctl, mem, adr, adr_type, val);
+      return new (C) StorePNode(ctl, mem, adr, adr_type, val);
     }
   }
   ShouldNotReachHere();
@@ -2242,7 +2243,7 @@
 
 StoreLNode* StoreLNode::make_atomic(Compile *C, Node* ctl, Node* mem, Node* adr, const TypePtr* adr_type, Node* val) {
   bool require_atomic = true;
-  return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val, require_atomic);
+  return new (C) StoreLNode(ctl, mem, adr, adr_type, val, require_atomic);
 }
 
 
@@ -2549,14 +2550,38 @@
 }
 
 //=============================================================================
-LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex ) : Node(5) {
+//----------------------------------LoadStoreNode------------------------------
+LoadStoreNode::LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* rt, uint required )
+  : Node(required),
+    _type(rt),
+    _adr_type(at)
+{
   init_req(MemNode::Control, c  );
   init_req(MemNode::Memory , mem);
   init_req(MemNode::Address, adr);
   init_req(MemNode::ValueIn, val);
-  init_req(         ExpectedIn, ex );
   init_class_id(Class_LoadStore);
+}
 
+uint LoadStoreNode::ideal_reg() const {
+  return Matcher::base2reg[_type->base()];
+}
+
+bool LoadStoreNode::result_not_used() const {
+  for( DUIterator_Fast imax, i = fast_outs(imax); i < imax; i++ ) {
+    Node *x = fast_out(i);
+    if (x->Opcode() == Op_SCMemProj) continue;
+    return false;
+  }
+  return true;
+}
+
+uint LoadStoreNode::size_of() const { return sizeof(*this); }
+
+//=============================================================================
+//----------------------------------LoadStoreConditionalNode--------------------
+LoadStoreConditionalNode::LoadStoreConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex ) : LoadStoreNode(c, mem, adr, val, NULL, TypeInt::BOOL, 5) {
+  init_req(ExpectedIn, ex );
 }
 
 //=============================================================================
@@ -2611,12 +2636,12 @@
 
   Node *zero = phase->makecon(TypeLong::ZERO);
   Node *off  = phase->MakeConX(BytesPerLong);
-  mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero);
+  mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero);
   count--;
   while( count-- ) {
     mem = phase->transform(mem);
-    adr = phase->transform(new (phase->C, 4) AddPNode(base,adr,off));
-    mem = new (phase->C, 4) StoreLNode(in(0),mem,adr,atp,zero);
+    adr = phase->transform(new (phase->C) AddPNode(base,adr,off));
+    mem = new (phase->C) StoreLNode(in(0),mem,adr,atp,zero);
   }
   return mem;
 }
@@ -2657,7 +2682,7 @@
 
   int unit = BytesPerLong;
   if ((offset % unit) != 0) {
-    Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(offset));
+    Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(offset));
     adr = phase->transform(adr);
     const TypePtr* atp = TypeRawPtr::BOTTOM;
     mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT);
@@ -2687,16 +2712,16 @@
   // Scale to the unit required by the CPU:
   if (!Matcher::init_array_count_is_in_bytes) {
     Node* shift = phase->intcon(exact_log2(unit));
-    zbase = phase->transform( new(C,3) URShiftXNode(zbase, shift) );
-    zend  = phase->transform( new(C,3) URShiftXNode(zend,  shift) );
+    zbase = phase->transform( new(C) URShiftXNode(zbase, shift) );
+    zend  = phase->transform( new(C) URShiftXNode(zend,  shift) );
   }
 
-  Node* zsize = phase->transform( new(C,3) SubXNode(zend, zbase) );
+  Node* zsize = phase->transform( new(C) SubXNode(zend, zbase) );
   Node* zinit = phase->zerocon((unit == BytesPerLong) ? T_LONG : T_INT);
 
   // Bulk clear double-words
-  Node* adr = phase->transform( new(C,4) AddPNode(dest, dest, start_offset) );
-  mem = new (C, 4) ClearArrayNode(ctl, mem, zsize, adr);
+  Node* adr = phase->transform( new(C) AddPNode(dest, dest, start_offset) );
+  mem = new (C) ClearArrayNode(ctl, mem, zsize, adr);
   return phase->transform(mem);
 }
 
@@ -2720,7 +2745,7 @@
                        start_offset, phase->MakeConX(done_offset), phase);
   }
   if (done_offset < end_offset) { // emit the final 32-bit store
-    Node* adr = new (C, 4) AddPNode(dest, dest, phase->MakeConX(done_offset));
+    Node* adr = new (C) AddPNode(dest, dest, phase->MakeConX(done_offset));
     adr = phase->transform(adr);
     const TypePtr* atp = TypeRawPtr::BOTTOM;
     mem = StoreNode::make(*phase, ctl, mem, adr, atp, phase->zerocon(T_INT), T_INT);
@@ -2786,16 +2811,15 @@
 
 //------------------------------make-------------------------------------------
 MemBarNode* MemBarNode::make(Compile* C, int opcode, int atp, Node* pn) {
-  int len = Precedent + (pn == NULL? 0: 1);
   switch (opcode) {
-  case Op_MemBarAcquire:   return new(C, len) MemBarAcquireNode(C,  atp, pn);
-  case Op_MemBarRelease:   return new(C, len) MemBarReleaseNode(C,  atp, pn);
-  case Op_MemBarAcquireLock: return new(C, len) MemBarAcquireLockNode(C,  atp, pn);
-  case Op_MemBarReleaseLock: return new(C, len) MemBarReleaseLockNode(C,  atp, pn);
-  case Op_MemBarVolatile:  return new(C, len) MemBarVolatileNode(C, atp, pn);
-  case Op_MemBarCPUOrder:  return new(C, len) MemBarCPUOrderNode(C, atp, pn);
-  case Op_Initialize:      return new(C, len) InitializeNode(C,     atp, pn);
-  case Op_MemBarStoreStore: return new(C, len) MemBarStoreStoreNode(C,  atp, pn);
+  case Op_MemBarAcquire:   return new(C) MemBarAcquireNode(C,  atp, pn);
+  case Op_MemBarRelease:   return new(C) MemBarReleaseNode(C,  atp, pn);
+  case Op_MemBarAcquireLock: return new(C) MemBarAcquireLockNode(C,  atp, pn);
+  case Op_MemBarReleaseLock: return new(C) MemBarReleaseLockNode(C,  atp, pn);
+  case Op_MemBarVolatile:  return new(C) MemBarVolatileNode(C, atp, pn);
+  case Op_MemBarCPUOrder:  return new(C) MemBarCPUOrderNode(C, atp, pn);
+  case Op_Initialize:      return new(C) InitializeNode(C,     atp, pn);
+  case Op_MemBarStoreStore: return new(C) MemBarStoreStoreNode(C,  atp, pn);
   default:                 ShouldNotReachHere(); return NULL;
   }
 }
@@ -2825,7 +2849,7 @@
         igvn->replace_node(proj_out(TypeFunc::Control), in(TypeFunc::Control));
         // Must return either the original node (now dead) or a new node
         // (Do not return a top here, since that would break the uniqueness of top.)
-        return new (phase->C, 1) ConINode(TypeInt::ZERO);
+        return new (phase->C) ConINode(TypeInt::ZERO);
       }
     }
   }
@@ -2846,7 +2870,7 @@
   switch (proj->_con) {
   case TypeFunc::Control:
   case TypeFunc::Memory:
-    return new (m->C, 1) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
+    return new (m->C) MachProjNode(this,proj->_con,RegMask::Empty,MachProjNode::unmatched_proj);
   }
   ShouldNotReachHere();
   return NULL;
@@ -3190,7 +3214,7 @@
   Node* addr = in(RawAddress);
   if (offset != 0) {
     Compile* C = phase->C;
-    addr = phase->transform( new (C, 4) AddPNode(C->top(), addr,
+    addr = phase->transform( new (C) AddPNode(C->top(), addr,
                                                  phase->MakeConX(offset)) );
   }
   return addr;
@@ -3879,7 +3903,7 @@
 // Make a new, untransformed MergeMem with the same base as 'mem'.
 // If mem is itself a MergeMem, populate the result with the same edges.
 MergeMemNode* MergeMemNode::make(Compile* C, Node* mem) {
-  return new(C, 1+Compile::AliasIdxRaw) MergeMemNode(mem);
+  return new(C) MergeMemNode(mem);
 }
 
 //------------------------------cmp--------------------------------------------
diff --git a/hotspot/src/share/vm/opto/memnode.hpp b/hotspot/src/share/vm/opto/memnode.hpp
index 36623a8..c4e73b1 100644
--- a/hotspot/src/share/vm/opto/memnode.hpp
+++ b/hotspot/src/share/vm/opto/memnode.hpp
@@ -274,18 +274,6 @@
   virtual BasicType memory_type() const { return T_INT; }
 };
 
-//------------------------------LoadUI2LNode-----------------------------------
-// Load an unsigned integer into long from memory
-class LoadUI2LNode : public LoadNode {
-public:
-  LoadUI2LNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeLong* t = TypeLong::UINT)
-    : LoadNode(c, mem, adr, at, t) {}
-  virtual int Opcode() const;
-  virtual uint ideal_reg() const { return Op_RegL; }
-  virtual int store_Opcode() const { return Op_StoreL; }
-  virtual BasicType memory_type() const { return T_LONG; }
-};
-
 //------------------------------LoadRangeNode----------------------------------
 // Load an array length from the array
 class LoadRangeNode : public LoadINode {
@@ -636,17 +624,6 @@
   virtual bool depends_only_on_test() const { return true; }
 };
 
-//------------------------------LoadLLockedNode---------------------------------
-// Load-locked a pointer from memory (either object or array).
-// On Sparc & Intel this is implemented as a normal long load.
-class LoadLLockedNode : public LoadLNode {
-public:
-  LoadLLockedNode( Node *c, Node *mem, Node *adr )
-    : LoadLNode(c,mem,adr,TypeRawPtr::BOTTOM, TypeLong::LONG) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_StoreLConditional; }
-};
-
 //------------------------------SCMemProjNode---------------------------------------
 // This class defines a projection of the memory  state of a store conditional node.
 // These nodes return a value, but also update memory.
@@ -668,23 +645,36 @@
 //------------------------------LoadStoreNode---------------------------
 // Note: is_Mem() method returns 'true' for this class.
 class LoadStoreNode : public Node {
+private:
+  const Type* const _type;      // What kind of value is loaded?
+  const TypePtr* _adr_type;     // What kind of memory is being addressed?
+  virtual uint size_of() const; // Size is bigger
+public:
+  LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* rt, uint required );
+  virtual bool depends_only_on_test() const { return false; }
+  virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; }
+
+  virtual const Type *bottom_type() const { return _type; }
+  virtual uint ideal_reg() const;
+  virtual const class TypePtr *adr_type() const { return _adr_type; }  // returns bottom_type of address
+
+  bool result_not_used() const;
+};
+
+class LoadStoreConditionalNode : public LoadStoreNode {
 public:
   enum {
     ExpectedIn = MemNode::ValueIn+1 // One more input than MemNode
   };
-  LoadStoreNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex);
-  virtual bool depends_only_on_test() const { return false; }
-  virtual const Type *bottom_type() const { return TypeInt::BOOL; }
-  virtual uint ideal_reg() const { return Op_RegI; }
-  virtual uint match_edge(uint idx) const { return idx == MemNode::Address || idx == MemNode::ValueIn; }
+  LoadStoreConditionalNode(Node *c, Node *mem, Node *adr, Node *val, Node *ex);
 };
 
 //------------------------------StorePConditionalNode---------------------------
 // Conditionally store pointer to memory, if no change since prior
 // load-locked.  Sets flags for success or failure of the store.
-class StorePConditionalNode : public LoadStoreNode {
+class StorePConditionalNode : public LoadStoreConditionalNode {
 public:
-  StorePConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { }
+  StorePConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreConditionalNode(c, mem, adr, val, ll) { }
   virtual int Opcode() const;
   // Produces flags
   virtual uint ideal_reg() const { return Op_RegFlags; }
@@ -693,9 +683,9 @@
 //------------------------------StoreIConditionalNode---------------------------
 // Conditionally store int to memory, if no change since prior
 // load-locked.  Sets flags for success or failure of the store.
-class StoreIConditionalNode : public LoadStoreNode {
+class StoreIConditionalNode : public LoadStoreConditionalNode {
 public:
-  StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreNode(c, mem, adr, val, ii) { }
+  StoreIConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ii ) : LoadStoreConditionalNode(c, mem, adr, val, ii) { }
   virtual int Opcode() const;
   // Produces flags
   virtual uint ideal_reg() const { return Op_RegFlags; }
@@ -704,9 +694,9 @@
 //------------------------------StoreLConditionalNode---------------------------
 // Conditionally store long to memory, if no change since prior
 // load-locked.  Sets flags for success or failure of the store.
-class StoreLConditionalNode : public LoadStoreNode {
+class StoreLConditionalNode : public LoadStoreConditionalNode {
 public:
-  StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreNode(c, mem, adr, val, ll) { }
+  StoreLConditionalNode( Node *c, Node *mem, Node *adr, Node *val, Node *ll ) : LoadStoreConditionalNode(c, mem, adr, val, ll) { }
   virtual int Opcode() const;
   // Produces flags
   virtual uint ideal_reg() const { return Op_RegFlags; }
@@ -714,32 +704,75 @@
 
 
 //------------------------------CompareAndSwapLNode---------------------------
-class CompareAndSwapLNode : public LoadStoreNode {
+class CompareAndSwapLNode : public LoadStoreConditionalNode {
 public:
-  CompareAndSwapLNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { }
+  CompareAndSwapLNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreConditionalNode(c, mem, adr, val, ex) { }
   virtual int Opcode() const;
 };
 
 
 //------------------------------CompareAndSwapINode---------------------------
-class CompareAndSwapINode : public LoadStoreNode {
+class CompareAndSwapINode : public LoadStoreConditionalNode {
 public:
-  CompareAndSwapINode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { }
+  CompareAndSwapINode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreConditionalNode(c, mem, adr, val, ex) { }
   virtual int Opcode() const;
 };
 
 
 //------------------------------CompareAndSwapPNode---------------------------
-class CompareAndSwapPNode : public LoadStoreNode {
+class CompareAndSwapPNode : public LoadStoreConditionalNode {
 public:
-  CompareAndSwapPNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { }
+  CompareAndSwapPNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreConditionalNode(c, mem, adr, val, ex) { }
   virtual int Opcode() const;
 };
 
 //------------------------------CompareAndSwapNNode---------------------------
-class CompareAndSwapNNode : public LoadStoreNode {
+class CompareAndSwapNNode : public LoadStoreConditionalNode {
 public:
-  CompareAndSwapNNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreNode(c, mem, adr, val, ex) { }
+  CompareAndSwapNNode( Node *c, Node *mem, Node *adr, Node *val, Node *ex) : LoadStoreConditionalNode(c, mem, adr, val, ex) { }
+  virtual int Opcode() const;
+};
+
+//------------------------------GetAndAddINode---------------------------
+class GetAndAddINode : public LoadStoreNode {
+public:
+  GetAndAddINode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::INT, 4) { }
+  virtual int Opcode() const;
+};
+
+//------------------------------GetAndAddLNode---------------------------
+class GetAndAddLNode : public LoadStoreNode {
+public:
+  GetAndAddLNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeLong::LONG, 4) { }
+  virtual int Opcode() const;
+};
+
+
+//------------------------------GetAndSetINode---------------------------
+class GetAndSetINode : public LoadStoreNode {
+public:
+  GetAndSetINode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeInt::INT, 4) { }
+  virtual int Opcode() const;
+};
+
+//------------------------------GetAndSetINode---------------------------
+class GetAndSetLNode : public LoadStoreNode {
+public:
+  GetAndSetLNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at ) : LoadStoreNode(c, mem, adr, val, at, TypeLong::LONG, 4) { }
+  virtual int Opcode() const;
+};
+
+//------------------------------GetAndSetPNode---------------------------
+class GetAndSetPNode : public LoadStoreNode {
+public:
+  GetAndSetPNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* t ) : LoadStoreNode(c, mem, adr, val, at, t, 4) { }
+  virtual int Opcode() const;
+};
+
+//------------------------------GetAndSetNNode---------------------------
+class GetAndSetNNode : public LoadStoreNode {
+public:
+  GetAndSetNNode( Node *c, Node *mem, Node *adr, Node *val, const TypePtr* at, const Type* t ) : LoadStoreNode(c, mem, adr, val, at, t, 4) { }
   virtual int Opcode() const;
 };
 
diff --git a/hotspot/src/share/vm/opto/mulnode.cpp b/hotspot/src/share/vm/opto/mulnode.cpp
index f086319..58a40ff 100644
--- a/hotspot/src/share/vm/opto/mulnode.cpp
+++ b/hotspot/src/share/vm/opto/mulnode.cpp
@@ -198,22 +198,22 @@
   Node *res = NULL;
   jint bit1 = con & -con;       // Extract low bit
   if( bit1 == con ) {           // Found a power of 2?
-    res = new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) );
+    res = new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) );
   } else {
 
     // Check for constant with 2 bits set
     jint bit2 = con-bit1;
     bit2 = bit2 & -bit2;          // Extract 2nd bit
     if( bit2 + bit1 == con ) {    // Found all bits in con?
-      Node *n1 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) );
-      Node *n2 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) );
-      res = new (phase->C, 3) AddINode( n2, n1 );
+      Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit1)) ) );
+      Node *n2 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(bit2)) ) );
+      res = new (phase->C) AddINode( n2, n1 );
 
     } else if (is_power_of_2(con+1)) {
       // Sleezy: power-of-2 -1.  Next time be generic.
       jint temp = (jint) (con + 1);
-      Node *n1 = phase->transform( new (phase->C, 3) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) );
-      res = new (phase->C, 3) SubINode( n1, in(1) );
+      Node *n1 = phase->transform( new (phase->C) LShiftINode( in(1), phase->intcon(log2_intptr(temp)) ) );
+      res = new (phase->C) SubINode( n1, in(1) );
     } else {
       return MulNode::Ideal(phase, can_reshape);
     }
@@ -221,7 +221,7 @@
 
   if( sign_flip ) {             // Need to negate result?
     res = phase->transform(res);// Transform, before making the zero con
-    res = new (phase->C, 3) SubINode(phase->intcon(0),res);
+    res = new (phase->C) SubINode(phase->intcon(0),res);
   }
 
   return res;                   // Return final result
@@ -294,22 +294,22 @@
   Node *res = NULL;
   jlong bit1 = con & -con;      // Extract low bit
   if( bit1 == con ) {           // Found a power of 2?
-    res = new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) );
+    res = new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) );
   } else {
 
     // Check for constant with 2 bits set
     jlong bit2 = con-bit1;
     bit2 = bit2 & -bit2;          // Extract 2nd bit
     if( bit2 + bit1 == con ) {    // Found all bits in con?
-      Node *n1 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) );
-      Node *n2 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) );
-      res = new (phase->C, 3) AddLNode( n2, n1 );
+      Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit1)) ) );
+      Node *n2 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(bit2)) ) );
+      res = new (phase->C) AddLNode( n2, n1 );
 
     } else if (is_power_of_2_long(con+1)) {
       // Sleezy: power-of-2 -1.  Next time be generic.
       jlong temp = (jlong) (con + 1);
-      Node *n1 = phase->transform( new (phase->C, 3) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) );
-      res = new (phase->C, 3) SubLNode( n1, in(1) );
+      Node *n1 = phase->transform( new (phase->C) LShiftLNode( in(1), phase->intcon(log2_long(temp)) ) );
+      res = new (phase->C) SubLNode( n1, in(1) );
     } else {
       return MulNode::Ideal(phase, can_reshape);
     }
@@ -317,7 +317,7 @@
 
   if( sign_flip ) {             // Need to negate result?
     res = phase->transform(res);// Transform, before making the zero con
-    res = new (phase->C, 3) SubLNode(phase->longcon(0),res);
+    res = new (phase->C) SubLNode(phase->longcon(0),res);
   }
 
   return res;                   // Return final result
@@ -476,27 +476,30 @@
   // Masking bits off of a Character?  Hi bits are already zero.
   if( lop == Op_LoadUS &&
       (mask & 0xFFFF0000) )     // Can we make a smaller mask?
-    return new (phase->C, 3) AndINode(load,phase->intcon(mask&0xFFFF));
+    return new (phase->C) AndINode(load,phase->intcon(mask&0xFFFF));
 
   // Masking bits off of a Short?  Loading a Character does some masking
-  if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
-    Node *ldus = new (phase->C, 3) LoadUSNode(load->in(MemNode::Control),
-                                              load->in(MemNode::Memory),
-                                              load->in(MemNode::Address),
-                                              load->adr_type());
-    ldus = phase->transform(ldus);
-    return new (phase->C, 3) AndINode(ldus, phase->intcon(mask & 0xFFFF));
-  }
+  if (can_reshape &&
+      load->outcnt() == 1 && load->unique_out() == this) {
+    if (lop == Op_LoadS && (mask & 0xFFFF0000) == 0 ) {
+      Node *ldus = new (phase->C) LoadUSNode(load->in(MemNode::Control),
+                                             load->in(MemNode::Memory),
+                                             load->in(MemNode::Address),
+                                             load->adr_type());
+      ldus = phase->transform(ldus);
+      return new (phase->C) AndINode(ldus, phase->intcon(mask & 0xFFFF));
+    }
 
-  // Masking sign bits off of a Byte?  Do an unsigned byte load plus
-  // an and.
-  if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
-    Node* ldub = new (phase->C, 3) LoadUBNode(load->in(MemNode::Control),
-                                              load->in(MemNode::Memory),
-                                              load->in(MemNode::Address),
-                                              load->adr_type());
-    ldub = phase->transform(ldub);
-    return new (phase->C, 3) AndINode(ldub, phase->intcon(mask));
+    // Masking sign bits off of a Byte?  Do an unsigned byte load plus
+    // an and.
+    if (lop == Op_LoadB && (mask & 0xFFFFFF00) == 0) {
+      Node* ldub = new (phase->C) LoadUBNode(load->in(MemNode::Control),
+                                             load->in(MemNode::Memory),
+                                             load->in(MemNode::Address),
+                                             load->adr_type());
+      ldub = phase->transform(ldub);
+      return new (phase->C) AndINode(ldub, phase->intcon(mask));
+    }
   }
 
   // Masking off sign bits?  Dont make them!
@@ -510,8 +513,8 @@
       // bits survive.  NO sign-extension bits survive the maskings.
       if( (sign_bits_mask & mask) == 0 ) {
         // Use zero-fill shift instead
-        Node *zshift = phase->transform(new (phase->C, 3) URShiftINode(load->in(1),load->in(2)));
-        return new (phase->C, 3) AndINode( zshift, in(2) );
+        Node *zshift = phase->transform(new (phase->C) URShiftINode(load->in(1),load->in(2)));
+        return new (phase->C) AndINode( zshift, in(2) );
       }
     }
   }
@@ -521,7 +524,7 @@
   // plus 1) and the mask is of the low order bit.  Skip the negate.
   if( lop == Op_SubI && mask == 1 && load->in(1) &&
       phase->type(load->in(1)) == TypeInt::ZERO )
-    return new (phase->C, 3) AndINode( load->in(2), in(2) );
+    return new (phase->C) AndINode( load->in(2), in(2) );
 
   return MulNode::Ideal(phase, can_reshape);
 }
@@ -599,29 +602,15 @@
   Node* in1 = in(1);
   uint op = in1->Opcode();
 
-  // Masking sign bits off of an integer?  Do an unsigned integer to
-  // long load.
-  // NOTE: This check must be *before* we try to convert the AndLNode
-  // to an AndINode and commute it with ConvI2LNode because
-  // 0xFFFFFFFFL masks the whole integer and we get a sign extension,
-  // which is wrong.
-  if (op == Op_ConvI2L && in1->in(1)->Opcode() == Op_LoadI && mask == CONST64(0x00000000FFFFFFFF)) {
-    Node* load = in1->in(1);
-    return new (phase->C, 3) LoadUI2LNode(load->in(MemNode::Control),
-                                          load->in(MemNode::Memory),
-                                          load->in(MemNode::Address),
-                                          load->adr_type());
-  }
-
   // Are we masking a long that was converted from an int with a mask
   // that fits in 32-bits?  Commute them and use an AndINode.  Don't
   // convert masks which would cause a sign extension of the integer
   // value.  This check includes UI2L masks (0x00000000FFFFFFFF) which
   // would be optimized away later in Identity.
   if (op == Op_ConvI2L && (mask & CONST64(0xFFFFFFFF80000000)) == 0) {
-    Node* andi = new (phase->C, 3) AndINode(in1->in(1), phase->intcon(mask));
+    Node* andi = new (phase->C) AndINode(in1->in(1), phase->intcon(mask));
     andi = phase->transform(andi);
-    return new (phase->C, 2) ConvI2LNode(andi);
+    return new (phase->C) ConvI2LNode(andi);
   }
 
   // Masking off sign bits?  Dont make them!
@@ -635,8 +624,8 @@
       // bits survive.  NO sign-extension bits survive the maskings.
       if( (sign_bits_mask & mask) == 0 ) {
         // Use zero-fill shift instead
-        Node *zshift = phase->transform(new (phase->C, 3) URShiftLNode(in1->in(1), in1->in(2)));
-        return new (phase->C, 3) AndLNode(zshift, in(2));
+        Node *zshift = phase->transform(new (phase->C) URShiftLNode(in1->in(1), in1->in(2)));
+        return new (phase->C) AndLNode(zshift, in(2));
       }
     }
   }
@@ -674,9 +663,9 @@
       // and 'i2b' patterns which typically fold into 'StoreC/StoreB'.
       if( con < 16 ) {
         // Compute X << con0
-        Node *lsh = phase->transform( new (phase->C, 3) LShiftINode( add1->in(1), in(2) ) );
+        Node *lsh = phase->transform( new (phase->C) LShiftINode( add1->in(1), in(2) ) );
         // Compute X<<con0 + (con1<<con0)
-        return new (phase->C, 3) AddINode( lsh, phase->intcon(t12->get_con() << con));
+        return new (phase->C) AddINode( lsh, phase->intcon(t12->get_con() << con));
       }
     }
   }
@@ -685,7 +674,7 @@
   if( (add1_op == Op_RShiftI || add1_op == Op_URShiftI ) &&
       add1->in(2) == in(2) )
     // Convert to "(x & -(1<<c0))"
-    return new (phase->C, 3) AndINode(add1->in(1),phase->intcon( -(1<<con)));
+    return new (phase->C) AndINode(add1->in(1),phase->intcon( -(1<<con)));
 
   // Check for "((x>>c0) & Y)<<c0" which just masks off more low bits
   if( add1_op == Op_AndI ) {
@@ -694,8 +683,8 @@
     if( (add2_op == Op_RShiftI || add2_op == Op_URShiftI ) &&
         add2->in(2) == in(2) ) {
       // Convert to "(x & (Y<<c0))"
-      Node *y_sh = phase->transform( new (phase->C, 3) LShiftINode( add1->in(2), in(2) ) );
-      return new (phase->C, 3) AndINode( add2->in(1), y_sh );
+      Node *y_sh = phase->transform( new (phase->C) LShiftINode( add1->in(2), in(2) ) );
+      return new (phase->C) AndINode( add2->in(1), y_sh );
     }
   }
 
@@ -704,7 +693,7 @@
   const jint bits_mask = right_n_bits(BitsPerJavaInteger-con);
   if( add1_op == Op_AndI &&
       phase->type(add1->in(2)) == TypeInt::make( bits_mask ) )
-    return new (phase->C, 3) LShiftINode( add1->in(1), in(2) );
+    return new (phase->C) LShiftINode( add1->in(1), in(2) );
 
   return NULL;
 }
@@ -784,9 +773,9 @@
     const TypeLong *t12 = phase->type(add1->in(2))->isa_long();
     if( t12 && t12->is_con() ){ // Left input is an add of a con?
       // Compute X << con0
-      Node *lsh = phase->transform( new (phase->C, 3) LShiftLNode( add1->in(1), in(2) ) );
+      Node *lsh = phase->transform( new (phase->C) LShiftLNode( add1->in(1), in(2) ) );
       // Compute X<<con0 + (con1<<con0)
-      return new (phase->C, 3) AddLNode( lsh, phase->longcon(t12->get_con() << con));
+      return new (phase->C) AddLNode( lsh, phase->longcon(t12->get_con() << con));
     }
   }
 
@@ -794,7 +783,7 @@
   if( (add1_op == Op_RShiftL || add1_op == Op_URShiftL ) &&
       add1->in(2) == in(2) )
     // Convert to "(x & -(1<<c0))"
-    return new (phase->C, 3) AndLNode(add1->in(1),phase->longcon( -(CONST64(1)<<con)));
+    return new (phase->C) AndLNode(add1->in(1),phase->longcon( -(CONST64(1)<<con)));
 
   // Check for "((x>>c0) & Y)<<c0" which just masks off more low bits
   if( add1_op == Op_AndL ) {
@@ -803,8 +792,8 @@
     if( (add2_op == Op_RShiftL || add2_op == Op_URShiftL ) &&
         add2->in(2) == in(2) ) {
       // Convert to "(x & (Y<<c0))"
-      Node *y_sh = phase->transform( new (phase->C, 3) LShiftLNode( add1->in(2), in(2) ) );
-      return new (phase->C, 3) AndLNode( add2->in(1), y_sh );
+      Node *y_sh = phase->transform( new (phase->C) LShiftLNode( add1->in(2), in(2) ) );
+      return new (phase->C) AndLNode( add2->in(1), y_sh );
     }
   }
 
@@ -813,7 +802,7 @@
   const jlong bits_mask = ((jlong)CONST64(1) << (jlong)(BitsPerJavaLong - con)) - CONST64(1);
   if( add1_op == Op_AndL &&
       phase->type(add1->in(2)) == TypeLong::make( bits_mask ) )
-    return new (phase->C, 3) LShiftLNode( add1->in(1), in(2) );
+    return new (phase->C) LShiftLNode( add1->in(1), in(2) );
 
   return NULL;
 }
@@ -915,8 +904,8 @@
     Node *x = mask->in(1);
     jint maskbits = t3->get_con();
     // Convert to "(x >> shift) & (mask >> shift)"
-    Node *shr_nomask = phase->transform( new (phase->C, 3) RShiftINode(mask->in(1), in(2)) );
-    return new (phase->C, 3) AndINode(shr_nomask, phase->intcon( maskbits >> shift));
+    Node *shr_nomask = phase->transform( new (phase->C) RShiftINode(mask->in(1), in(2)) );
+    return new (phase->C) AndINode(shr_nomask, phase->intcon( maskbits >> shift));
   }
 
   // Check for "(short[i] <<16)>>16" which simply sign-extends
@@ -937,9 +926,11 @@
       set_req(2, phase->intcon(0));
       return this;
     }
-    else if( ld->Opcode() == Op_LoadUS )
+    else if( can_reshape &&
+             ld->Opcode() == Op_LoadUS &&
+             ld->outcnt() == 1 && ld->unique_out() == shl)
       // Replace zero-extension-load with sign-extension-load
-      return new (phase->C, 3) LoadSNode( ld->in(MemNode::Control),
+      return new (phase->C) LoadSNode( ld->in(MemNode::Control),
                                 ld->in(MemNode::Memory),
                                 ld->in(MemNode::Address),
                                 ld->adr_type());
@@ -1124,7 +1115,7 @@
       const int con2 = t12->get_con() & 31; // Shift count is always masked
       const int con3 = con+con2;
       if( con3 < 32 )           // Only merge shifts if total is < 32
-        return new (phase->C, 3) URShiftINode( in(1)->in(1), phase->intcon(con3) );
+        return new (phase->C) URShiftINode( in(1)->in(1), phase->intcon(con3) );
     }
   }
 
@@ -1137,9 +1128,9 @@
     Node *lshl = add->in(1);
     if( lshl->Opcode() == Op_LShiftI &&
         phase->type(lshl->in(2)) == t2 ) {
-      Node *y_z = phase->transform( new (phase->C, 3) URShiftINode(add->in(2),in(2)) );
-      Node *sum = phase->transform( new (phase->C, 3) AddINode( lshl->in(1), y_z ) );
-      return new (phase->C, 3) AndINode( sum, phase->intcon(mask) );
+      Node *y_z = phase->transform( new (phase->C) URShiftINode(add->in(2),in(2)) );
+      Node *sum = phase->transform( new (phase->C) AddINode( lshl->in(1), y_z ) );
+      return new (phase->C) AndINode( sum, phase->intcon(mask) );
     }
   }
 
@@ -1152,8 +1143,8 @@
     if( t3 && t3->is_con() ) { // Right input is a constant
       jint mask2 = t3->get_con();
       mask2 >>= con;  // *signed* shift downward (high-order zeroes do not help)
-      Node *newshr = phase->transform( new (phase->C, 3) URShiftINode(andi->in(1), in(2)) );
-      return new (phase->C, 3) AndINode(newshr, phase->intcon(mask2));
+      Node *newshr = phase->transform( new (phase->C) URShiftINode(andi->in(1), in(2)) );
+      return new (phase->C) AndINode(newshr, phase->intcon(mask2));
       // The negative values are easier to materialize than positive ones.
       // A typical case from address arithmetic is ((x & ~15) >> 4).
       // It's better to change that to ((x >> 4) & ~0) versus
@@ -1165,7 +1156,7 @@
   Node *shl = in(1);
   if( in1_op == Op_LShiftI &&
       phase->type(shl->in(2)) == t2 )
-    return new (phase->C, 3) AndINode( shl->in(1), phase->intcon(mask) );
+    return new (phase->C) AndINode( shl->in(1), phase->intcon(mask) );
 
   return NULL;
 }
@@ -1270,9 +1261,9 @@
     Node *lshl = add->in(1);
     if( lshl->Opcode() == Op_LShiftL &&
         phase->type(lshl->in(2)) == t2 ) {
-      Node *y_z = phase->transform( new (phase->C, 3) URShiftLNode(add->in(2),in(2)) );
-      Node *sum = phase->transform( new (phase->C, 3) AddLNode( lshl->in(1), y_z ) );
-      return new (phase->C, 3) AndLNode( sum, phase->longcon(mask) );
+      Node *y_z = phase->transform( new (phase->C) URShiftLNode(add->in(2),in(2)) );
+      Node *sum = phase->transform( new (phase->C) AddLNode( lshl->in(1), y_z ) );
+      return new (phase->C) AndLNode( sum, phase->longcon(mask) );
     }
   }
 
@@ -1285,8 +1276,8 @@
     if( t3 && t3->is_con() ) { // Right input is a constant
       jlong mask2 = t3->get_con();
       mask2 >>= con;  // *signed* shift downward (high-order zeroes do not help)
-      Node *newshr = phase->transform( new (phase->C, 3) URShiftLNode(andi->in(1), in(2)) );
-      return new (phase->C, 3) AndLNode(newshr, phase->longcon(mask2));
+      Node *newshr = phase->transform( new (phase->C) URShiftLNode(andi->in(1), in(2)) );
+      return new (phase->C) AndLNode(newshr, phase->longcon(mask2));
     }
   }
 
@@ -1294,7 +1285,7 @@
   Node *shl = in(1);
   if( shl->Opcode() == Op_LShiftL &&
       phase->type(shl->in(2)) == t2 )
-    return new (phase->C, 3) AndLNode( shl->in(1), phase->longcon(mask) );
+    return new (phase->C) AndLNode( shl->in(1), phase->longcon(mask) );
 
   return NULL;
 }
diff --git a/hotspot/src/share/vm/opto/mulnode.hpp b/hotspot/src/share/vm/opto/mulnode.hpp
index 11cc771..c3adc43 100644
--- a/hotspot/src/share/vm/opto/mulnode.hpp
+++ b/hotspot/src/share/vm/opto/mulnode.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -41,7 +41,9 @@
 class MulNode : public Node {
   virtual uint hash() const;
 public:
-  MulNode( Node *in1, Node *in2 ): Node(0,in1,in2) {}
+  MulNode( Node *in1, Node *in2 ): Node(0,in1,in2) {
+    init_class_id(Class_Mul);
+  }
 
   // Handle algebraic identities here.  If we have an identity, return the Node
   // we are equivalent to.  We look for "add of zero" as an identity.
diff --git a/hotspot/src/share/vm/opto/node.cpp b/hotspot/src/share/vm/opto/node.cpp
index 4bd752f..55c2df5 100644
--- a/hotspot/src/share/vm/opto/node.cpp
+++ b/hotspot/src/share/vm/opto/node.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -296,6 +296,14 @@
   assert(Compile::current() == C, "must use operator new(Compile*)");
   int idx = C->next_unique();
 
+  // Allocate memory for the necessary number of edges.
+  if (req > 0) {
+    // Allocate space for _in array to have double alignment.
+    _in = (Node **) ((char *) (C->node_arena()->Amalloc_D(req * sizeof(void*))));
+#ifdef ASSERT
+    _in[req-1] = this; // magic cookie for assertion check
+#endif
+  }
   // If there are default notes floating around, capture them:
   Node_Notes* nn = C->default_node_notes();
   if (nn != NULL)  init_node_notes(C, idx, nn);
@@ -1004,15 +1012,15 @@
 //    set_req(2, phase->intcon(7));
 //    return this;
 // Example: reshape "X*4" into "X<<2"
-//    return new (C,3) LShiftINode(in(1), phase->intcon(2));
+//    return new (C) LShiftINode(in(1), phase->intcon(2));
 //
 // You must call 'phase->transform(X)' on any new Nodes X you make, except
 // for the returned root node.  Example: reshape "X*31" with "(X<<5)-X".
-//    Node *shift=phase->transform(new(C,3)LShiftINode(in(1),phase->intcon(5)));
-//    return new (C,3) AddINode(shift, in(1));
+//    Node *shift=phase->transform(new(C)LShiftINode(in(1),phase->intcon(5)));
+//    return new (C) AddINode(shift, in(1));
 //
 // When making a Node for a constant use 'phase->makecon' or 'phase->intcon'.
-// These forms are faster than 'phase->transform(new (C,1) ConNode())' and Do
+// These forms are faster than 'phase->transform(new (C) ConNode())' and Do
 // The Right Thing with def-use info.
 //
 // You cannot bury the 'this' Node inside of a graph reshape.  If the reshaped
@@ -1576,6 +1584,9 @@
     } else {
       tty->print("no type");
     }
+  } else if (t->isa_vect() && this->is_MachSpillCopy()) {
+    // Dump MachSpillcopy vector type.
+    t->dump();
   }
   if (is_new) {
     debug_only(dump_orig(debug_orig()));
diff --git a/hotspot/src/share/vm/opto/node.hpp b/hotspot/src/share/vm/opto/node.hpp
index 5ddae2f..a6033c6 100644
--- a/hotspot/src/share/vm/opto/node.hpp
+++ b/hotspot/src/share/vm/opto/node.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -100,6 +100,7 @@
 class MemBarStoreStoreNode;
 class MemNode;
 class MergeMemNode;
+class MulNode;
 class MultiNode;
 class MultiBranchNode;
 class NeverBranchNode;
@@ -133,8 +134,8 @@
 class TypeNode;
 class UnlockNode;
 class VectorNode;
-class VectorLoadNode;
-class VectorStoreNode;
+class LoadVectorNode;
+class StoreVectorNode;
 class VectorSet;
 typedef void (*NFunc)(Node&,void*);
 extern "C" {
@@ -216,18 +217,6 @@
     return (void*)n;
   }
 
-  // New Operator that takes a Compile pointer, this will eventually
-  // be the "new" New operator.
-  inline void* operator new( size_t x, Compile* C, int y) {
-    Node* n = (Node*)C->node_arena()->Amalloc_D(x + y*sizeof(void*));
-    n->_in = (Node**)(((char*)n) + x);
-#ifdef ASSERT
-    n->_in[y-1] = n; // magic cookie for assertion check
-#endif
-    n->_out = (Node**)C;
-    return (void*)n;
-  }
-
   // Delete is a NOP
   void operator delete( void *ptr ) {}
   // Fancy destructor; eagerly attempt to reclaim Node numberings and storage
@@ -362,7 +351,7 @@
 #endif
 
   // Reference to the i'th input Node.  Error if out of bounds.
-  Node* in(uint i) const { assert(i < _max,"oob"); return _in[i]; }
+  Node* in(uint i) const { assert(i < _max, err_msg_res("oob: i=%d, _max=%d", i, _max)); return _in[i]; }
   // Reference to the i'th output Node.  Error if out of bounds.
   // Use this accessor sparingly.  We are going trying to use iterators instead.
   Node* raw_out(uint i) const { assert(i < _outcnt,"oob"); return _out[i]; }
@@ -393,7 +382,7 @@
   void ins_req( uint i, Node *n ); // Insert a NEW required input
   void set_req( uint i, Node *n ) {
     assert( is_not_dead(n), "can not use dead node");
-    assert( i < _cnt, "oob");
+    assert( i < _cnt, err_msg_res("oob: i=%d, _cnt=%d", i, _cnt));
     assert( !VerifyHashTableKeys || _hash_lock == 0,
             "remove node from hash table before modifying it");
     Node** p = &_in[i];    // cache this._in, across the del_out call
@@ -609,9 +598,9 @@
 
     DEFINE_CLASS_ID(Mem,   Node, 4)
       DEFINE_CLASS_ID(Load,  Mem, 0)
-        DEFINE_CLASS_ID(VectorLoad,  Load, 0)
+        DEFINE_CLASS_ID(LoadVector,  Load, 0)
       DEFINE_CLASS_ID(Store, Mem, 1)
-        DEFINE_CLASS_ID(VectorStore, Store, 0)
+        DEFINE_CLASS_ID(StoreVector, Store, 0)
       DEFINE_CLASS_ID(LoadStore, Mem, 2)
 
     DEFINE_CLASS_ID(Region, Node, 5)
@@ -629,8 +618,9 @@
     DEFINE_CLASS_ID(AddP,     Node, 9)
     DEFINE_CLASS_ID(BoxLock,  Node, 10)
     DEFINE_CLASS_ID(Add,      Node, 11)
-    DEFINE_CLASS_ID(Vector,   Node, 12)
-    DEFINE_CLASS_ID(ClearArray, Node, 13)
+    DEFINE_CLASS_ID(Mul,      Node, 12)
+    DEFINE_CLASS_ID(Vector,   Node, 13)
+    DEFINE_CLASS_ID(ClearArray, Node, 14)
 
     _max_classes  = ClassMask_ClearArray
   };
@@ -752,6 +742,7 @@
   DEFINE_CLASS_QUERY(MemBar)
   DEFINE_CLASS_QUERY(MemBarStoreStore)
   DEFINE_CLASS_QUERY(MergeMem)
+  DEFINE_CLASS_QUERY(Mul)
   DEFINE_CLASS_QUERY(Multi)
   DEFINE_CLASS_QUERY(MultiBranch)
   DEFINE_CLASS_QUERY(Parm)
@@ -767,8 +758,8 @@
   DEFINE_CLASS_QUERY(Sub)
   DEFINE_CLASS_QUERY(Type)
   DEFINE_CLASS_QUERY(Vector)
-  DEFINE_CLASS_QUERY(VectorLoad)
-  DEFINE_CLASS_QUERY(VectorStore)
+  DEFINE_CLASS_QUERY(LoadVector)
+  DEFINE_CLASS_QUERY(StoreVector)
   DEFINE_CLASS_QUERY(Unlock)
 
   #undef DEFINE_CLASS_QUERY
diff --git a/hotspot/src/share/vm/opto/opcodes.cpp b/hotspot/src/share/vm/opto/opcodes.cpp
index 58489db..8331056 100644
--- a/hotspot/src/share/vm/opto/opcodes.cpp
+++ b/hotspot/src/share/vm/opto/opcodes.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -38,6 +38,10 @@
   "RegD",
   "RegL",
   "RegFlags",
+  "VecS",
+  "VecD",
+  "VecX",
+  "VecY",
   "_last_machine_leaf",
 #include "classes.hpp"
   "_last_class_name",
diff --git a/hotspot/src/share/vm/opto/opcodes.hpp b/hotspot/src/share/vm/opto/opcodes.hpp
index 9eb5b8a..4baec83 100644
--- a/hotspot/src/share/vm/opto/opcodes.hpp
+++ b/hotspot/src/share/vm/opto/opcodes.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -36,6 +36,10 @@
   macro(RegF)                   // Machine float   register
   macro(RegD)                   // Machine double  register
   macro(RegL)                   // Machine long    register
+  macro(VecS)                   // Machine vectors register
+  macro(VecD)                   // Machine vectord register
+  macro(VecX)                   // Machine vectorx register
+  macro(VecY)                   // Machine vectory register
   macro(RegFlags)               // Machine flags   register
   _last_machine_leaf,           // Split between regular opcodes and machine
 #include "classes.hpp"
diff --git a/hotspot/src/share/vm/opto/output.cpp b/hotspot/src/share/vm/opto/output.cpp
index e32a185..06dcfc2 100644
--- a/hotspot/src/share/vm/opto/output.cpp
+++ b/hotspot/src/share/vm/opto/output.cpp
@@ -265,9 +265,9 @@
 Node* Compile::call_zap_node(MachSafePointNode* node_to_check, int block_no) {
   const TypeFunc *tf = OptoRuntime::zap_dead_locals_Type();
   CallStaticJavaNode* ideal_node =
-    new (this, tf->domain()->cnt()) CallStaticJavaNode( tf,
+    new (this) CallStaticJavaNode( tf,
          OptoRuntime::zap_dead_locals_stub(_method->flags().is_native()),
-                            "call zap dead locals stub", 0, TypePtr::BOTTOM);
+                       "call zap dead locals stub", 0, TypePtr::BOTTOM);
   // We need to copy the OopMap from the site we're zapping at.
   // We have to make a copy, because the zap site might not be
   // a call site, and zap_dead is a call site.
@@ -1871,6 +1871,10 @@
   if (!do_scheduling())
     return;
 
+  // Scheduling code works only with pairs (8 bytes) maximum.
+  if (max_vector_size() > 8)
+    return;
+
   NOT_PRODUCT( TracePhase t2("isched", &_t_instrSched, TimeCompiler); )
 
   // Create a data structure for all the scheduling information
@@ -2682,7 +2686,7 @@
     if ( _pinch_free_list.size() > 0) {
       pinch = _pinch_free_list.pop();
     } else {
-      pinch = new (_cfg->C, 1) Node(1); // Pinch point to-be
+      pinch = new (_cfg->C) Node(1); // Pinch point to-be
     }
     if (pinch->_idx >= _regalloc->node_regs_max_index()) {
       _cfg->C->record_method_not_compilable("too many D-U pinch points");
diff --git a/hotspot/src/share/vm/opto/parse.hpp b/hotspot/src/share/vm/opto/parse.hpp
index ec9a083..620c837 100644
--- a/hotspot/src/share/vm/opto/parse.hpp
+++ b/hotspot/src/share/vm/opto/parse.hpp
@@ -84,7 +84,7 @@
   static const char* check_can_parse(ciMethod* callee);
 
   static InlineTree* build_inline_tree_root();
-  static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee, bool create_if_not_found = false);
+  static InlineTree* find_subtree_from_root(InlineTree* root, JVMState* jvms, ciMethod* callee);
 
   // For temporary (stack-allocated, stateless) ilts:
   InlineTree(Compile* c, ciMethod* callee_method, JVMState* caller_jvms, float site_invoke_ratio, int max_inline_level);
@@ -527,6 +527,9 @@
   int     repush_if_args();
   void    adjust_map_after_if(BoolTest::mask btest, Node* c, float prob,
                               Block* path, Block* other_path);
+  void    sharpen_type_after_if(BoolTest::mask btest,
+                                Node* con, const Type* tcon,
+                                Node* val, const Type* tval);
   IfNode* jump_if_fork_int(Node* a, Node* b, BoolTest::mask mask);
   Node*   jump_if_join(Node* iffalse, Node* iftrue);
   void    jump_if_true_fork(IfNode *ifNode, int dest_bci_if_true, int prof_table_index);
diff --git a/hotspot/src/share/vm/opto/parse1.cpp b/hotspot/src/share/vm/opto/parse1.cpp
index 99bdf93..abe3e7b 100644
--- a/hotspot/src/share/vm/opto/parse1.cpp
+++ b/hotspot/src/share/vm/opto/parse1.cpp
@@ -107,10 +107,10 @@
   // doubles on Sparc.  Intel can handle them just fine directly.
   Node *l;
   switch( bt ) {                // Signature is flattened
-  case T_INT:     l = new (C, 3) LoadINode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
-  case T_FLOAT:   l = new (C, 3) LoadFNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
-  case T_ADDRESS: l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM  ); break;
-  case T_OBJECT:  l = new (C, 3) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break;
+  case T_INT:     l = new (C) LoadINode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
+  case T_FLOAT:   l = new (C) LoadFNode( ctl, mem, adr, TypeRawPtr::BOTTOM ); break;
+  case T_ADDRESS: l = new (C) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeRawPtr::BOTTOM  ); break;
+  case T_OBJECT:  l = new (C) LoadPNode( ctl, mem, adr, TypeRawPtr::BOTTOM, TypeInstPtr::BOTTOM ); break;
   case T_LONG:
   case T_DOUBLE: {
     // Since arguments are in reverse order, the argument address 'adr'
@@ -118,12 +118,12 @@
     adr = basic_plus_adr( local_addrs_base, local_addrs, -(index+1)*wordSize );
     if( Matcher::misaligned_doubles_ok ) {
       l = (bt == T_DOUBLE)
-        ? (Node*)new (C, 3) LoadDNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
-        : (Node*)new (C, 3) LoadLNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
+        ? (Node*)new (C) LoadDNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
+        : (Node*)new (C) LoadLNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
     } else {
       l = (bt == T_DOUBLE)
-        ? (Node*)new (C, 3) LoadD_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
-        : (Node*)new (C, 3) LoadL_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
+        ? (Node*)new (C) LoadD_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM )
+        : (Node*)new (C) LoadL_unalignedNode( ctl, mem, adr, TypeRawPtr::BOTTOM );
     }
     break;
   }
@@ -147,11 +147,11 @@
   if (type == TypePtr::NULL_PTR ||
       (tp != NULL && !tp->klass()->is_loaded())) {
     // Value must be null, not a real oop.
-    Node* chk = _gvn.transform( new (C, 3) CmpPNode(l, null()) );
-    Node* tst = _gvn.transform( new (C, 2) BoolNode(chk, BoolTest::eq) );
+    Node* chk = _gvn.transform( new (C) CmpPNode(l, null()) );
+    Node* tst = _gvn.transform( new (C) BoolNode(chk, BoolTest::eq) );
     IfNode* iff = create_and_map_if(control(), tst, PROB_MAX, COUNT_UNKNOWN);
-    set_control(_gvn.transform( new (C, 1) IfTrueNode(iff) ));
-    Node* bad_type = _gvn.transform( new (C, 1) IfFalseNode(iff) );
+    set_control(_gvn.transform( new (C) IfTrueNode(iff) ));
+    Node* bad_type = _gvn.transform( new (C) IfFalseNode(iff) );
     bad_type_exit->control()->add_req(bad_type);
     l = null();
   }
@@ -218,7 +218,7 @@
   Node *monitors_addr = basic_plus_adr(osr_buf, osr_buf, (max_locals+mcnt*2-1)*wordSize);
   for (index = 0; index < mcnt; index++) {
     // Make a BoxLockNode for the monitor.
-    Node *box = _gvn.transform(new (C, 1) BoxLockNode(next_monitor()));
+    Node *box = _gvn.transform(new (C) BoxLockNode(next_monitor()));
 
 
     // Displaced headers and locked objects are interleaved in the
@@ -233,7 +233,7 @@
 
     // Build a bogus FastLockNode (no code will be generated) and push the
     // monitor into our debug info.
-    const FastLockNode *flock = _gvn.transform(new (C, 3) FastLockNode( 0, lock_object, box ))->as_FastLock();
+    const FastLockNode *flock = _gvn.transform(new (C) FastLockNode( 0, lock_object, box ))->as_FastLock();
     map()->push_monitor(flock);
 
     // If the lock is our method synchronization lock, tuck it away in
@@ -323,7 +323,7 @@
   // Now that the interpreter state is loaded, make sure it will match
   // at execution time what the compiler is expecting now:
   SafePointNode* bad_type_exit = clone_map();
-  bad_type_exit->set_control(new (C, 1) RegionNode(1));
+  bad_type_exit->set_control(new (C) RegionNode(1));
 
   assert(osr_block->flow()->jsrs()->size() == 0, "should be no jsrs live at osr point");
   for (index = 0; index < max_locals; index++) {
@@ -372,7 +372,8 @@
     // in the CFG, which typeflow had previously ignored.
     // E.g., Object x = coldAtFirst() && notReached()? "str": new Integer(123).
     // This x will be typed as Integer if notReached is not yet linked.
-    uncommon_trap(Deoptimization::Reason_unreached,
+    // It could also happen due to a problem in ciTypeFlow analysis.
+    uncommon_trap(Deoptimization::Reason_constraint,
                   Deoptimization::Action_reinterpret);
     set_map(types_are_good);
   }
@@ -398,7 +399,7 @@
   if (PrintCompilation || PrintOpto) {
     // Make sure I have an inline tree, so I can print messages about it.
     JVMState* ilt_caller = is_osr_parse() ? caller->caller() : caller;
-    InlineTree::find_subtree_from_root(C->ilt(), ilt_caller, parse_method, true);
+    InlineTree::find_subtree_from_root(C->ilt(), ilt_caller, parse_method);
   }
   _max_switch_depth = 0;
   _est_switch_depth = 0;
@@ -647,7 +648,7 @@
           add_predicate();
           // Add new region for back branches.
           int edges = block->pred_count() - block->preds_parsed() + 1; // +1 for original region
-          RegionNode *r = new (C, edges+1) RegionNode(edges+1);
+          RegionNode *r = new (C) RegionNode(edges+1);
           _gvn.set_type(r, Type::CONTROL);
           record_for_igvn(r);
           r->init_req(edges, control());
@@ -714,14 +715,14 @@
   _exits.clean_stack(_exits.sp());
   _exits.sync_jvms();
 
-  RegionNode* region = new (C, 1) RegionNode(1);
+  RegionNode* region = new (C) RegionNode(1);
   record_for_igvn(region);
   gvn().set_type_bottom(region);
   _exits.set_control(region);
 
   // Note:  iophi and memphi are not transformed until do_exits.
-  Node* iophi  = new (C, region->req()) PhiNode(region, Type::ABIO);
-  Node* memphi = new (C, region->req()) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
+  Node* iophi  = new (C) PhiNode(region, Type::ABIO);
+  Node* memphi = new (C) PhiNode(region, Type::MEMORY, TypePtr::BOTTOM);
   _exits.set_i_o(iophi);
   _exits.set_all_memory(memphi);
 
@@ -736,7 +737,7 @@
       ret_type = TypeOopPtr::BOTTOM;
     }
     int         ret_size = type2size[ret_type->basic_type()];
-    Node*       ret_phi  = new (C, region->req()) PhiNode(region, ret_type);
+    Node*       ret_phi  = new (C) PhiNode(region, ret_type);
     _exits.ensure_stack(ret_size);
     assert((int)(tf()->range()->cnt() - TypeFunc::Parms) == ret_size, "good tf range");
     assert(method()->return_type()->size() == ret_size, "tf agrees w/ method");
@@ -753,7 +754,7 @@
   int        arg_size = tf->domain()->cnt();
   int        max_size = MAX2(arg_size, (int)tf->range()->cnt());
   JVMState*  jvms     = new (this) JVMState(max_size - TypeFunc::Parms);
-  SafePointNode* map  = new (this, max_size) SafePointNode(max_size, NULL);
+  SafePointNode* map  = new (this) SafePointNode(max_size, NULL);
   record_for_igvn(map);
   assert(arg_size == TypeFunc::Parms + (is_osr_compilation() ? 1 : method()->arg_size()), "correct arg_size");
   Node_Notes* old_nn = default_node_notes();
@@ -767,7 +768,7 @@
   }
   uint i;
   for (i = 0; i < (uint)arg_size; i++) {
-    Node* parm = initial_gvn()->transform(new (this, 1) ParmNode(start, i));
+    Node* parm = initial_gvn()->transform(new (this) ParmNode(start, i));
     map->init_req(i, parm);
     // Record all these guys for later GVN.
     record_for_igvn(parm);
@@ -798,7 +799,7 @@
 //--------------------------return_values--------------------------------------
 void Compile::return_values(JVMState* jvms) {
   GraphKit kit(jvms);
-  Node* ret = new (this, TypeFunc::Parms) ReturnNode(TypeFunc::Parms,
+  Node* ret = new (this) ReturnNode(TypeFunc::Parms,
                              kit.control(),
                              kit.i_o(),
                              kit.reset_memory(),
@@ -826,7 +827,7 @@
   // Load my combined exception state into the kit, with all phis transformed:
   SafePointNode* ex_map = kit.combine_and_pop_all_exception_states();
   Node* ex_oop = kit.use_exception_state(ex_map);
-  RethrowNode* exit = new (this, TypeFunc::Parms + 1) RethrowNode(kit.control(),
+  RethrowNode* exit = new (this) RethrowNode(kit.control(),
                                       kit.i_o(), kit.reset_memory(),
                                       kit.frameptr(), kit.returnadr(),
                                       // like a return but with exception input
@@ -1020,7 +1021,7 @@
 
   // Create an initial safepoint to hold JVM state during parsing
   JVMState* jvms = new (C) JVMState(method(), _caller->has_method() ? _caller : NULL);
-  set_map(new (C, len) SafePointNode(len, jvms));
+  set_map(new (C) SafePointNode(len, jvms));
   jvms->set_map(map());
   record_for_igvn(map());
   assert(jvms->endoff() == len, "correct jvms sizing");
@@ -1380,8 +1381,7 @@
       // that occur during parsing of this BC.  If there is no log
       // output until the next context string, this context string
       // will be silently ignored.
-      log->context()->reset();
-      log->context()->print_cr("<bc code='%d' bci='%d'/>", (int)bc(), bci());
+      log->set_context("bc code='%d' bci='%d'", (int)bc(), bci());
     }
 
     if (block()->has_trap_at(bci())) {
@@ -1398,8 +1398,8 @@
 #ifdef ASSERT
     int pre_bc_sp = sp();
     int inputs, depth;
-    bool have_se = !stopped() && compute_stack_effects(inputs, depth);
-    assert(!have_se || pre_bc_sp >= inputs, "have enough stack to execute this BC");
+    bool have_se = !stopped() && compute_stack_effects(inputs, depth, /*for_parse*/ true);
+    assert(!have_se || pre_bc_sp >= inputs, err_msg_res("have enough stack to execute this BC: pre_bc_sp=%d, inputs=%d", pre_bc_sp, inputs));
 #endif //ASSERT
 
     do_one_bytecode();
@@ -1410,7 +1410,8 @@
 
     NOT_PRODUCT( parse_histogram()->record_change(); );
 
-    if (log != NULL)  log->context()->reset();  // done w/ this one
+    if (log != NULL)
+      log->clear_context();  // skip marker if nothing was printed
 
     // Fall into next bytecode.  Each bytecode normally has 1 sequential
     // successor which is typically made ready by visiting this bytecode.
@@ -1528,7 +1529,7 @@
       // later lazily.
       int edges = target->pred_count();
       if (edges < pnum)  edges = pnum;  // might be a new path!
-      RegionNode *r = new (C, edges+1) RegionNode(edges+1);
+      RegionNode *r = new (C) RegionNode(edges+1);
       gvn().set_type(r, Type::CONTROL);
       record_for_igvn(r);
       // zap all inputs to NULL for debugging (done in Node(uint) constructor)
@@ -1923,19 +1924,19 @@
   Node* access_flags_addr = basic_plus_adr(klass, klass, in_bytes(Klass::access_flags_offset()));
   Node* access_flags = make_load(NULL, access_flags_addr, TypeInt::INT, T_INT);
 
-  Node* mask  = _gvn.transform(new (C, 3) AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER)));
-  Node* check = _gvn.transform(new (C, 3) CmpINode(mask, intcon(0)));
-  Node* test  = _gvn.transform(new (C, 2) BoolNode(check, BoolTest::ne));
+  Node* mask  = _gvn.transform(new (C) AndINode(access_flags, intcon(JVM_ACC_HAS_FINALIZER)));
+  Node* check = _gvn.transform(new (C) CmpINode(mask, intcon(0)));
+  Node* test  = _gvn.transform(new (C) BoolNode(check, BoolTest::ne));
 
   IfNode* iff = create_and_map_if(control(), test, PROB_MAX, COUNT_UNKNOWN);
 
-  RegionNode* result_rgn = new (C, 3) RegionNode(3);
+  RegionNode* result_rgn = new (C) RegionNode(3);
   record_for_igvn(result_rgn);
 
-  Node *skip_register = _gvn.transform(new (C, 1) IfFalseNode(iff));
+  Node *skip_register = _gvn.transform(new (C) IfFalseNode(iff));
   result_rgn->init_req(1, skip_register);
 
-  Node *needs_register = _gvn.transform(new (C, 1) IfTrueNode(iff));
+  Node *needs_register = _gvn.transform(new (C) IfTrueNode(iff));
   set_control(needs_register);
   if (stopped()) {
     // There is no slow path.
@@ -2013,7 +2014,7 @@
         // sharpen the type eagerly; this eases certain assert checking
         if (tp->higher_equal(TypeInstPtr::NOTNULL))
           tr = tr->join(TypeInstPtr::NOTNULL)->is_instptr();
-        value = _gvn.transform(new (C, 2) CheckCastPPNode(0,value,tr));
+        value = _gvn.transform(new (C) CheckCastPPNode(0,value,tr));
       }
     }
     phi->add_req(value);
@@ -2048,7 +2049,7 @@
   kill_dead_locals();
 
   // Clone the JVM State
-  SafePointNode *sfpnt = new (C, parms) SafePointNode(parms, NULL);
+  SafePointNode *sfpnt = new (C) SafePointNode(parms, NULL);
 
   // Capture memory state BEFORE a SafePoint.  Since we can block at a
   // SafePoint we need our GC state to be safe; i.e. we need all our current
diff --git a/hotspot/src/share/vm/opto/parse2.cpp b/hotspot/src/share/vm/opto/parse2.cpp
index 5e8007d..9ce6008 100644
--- a/hotspot/src/share/vm/opto/parse2.cpp
+++ b/hotspot/src/share/vm/opto/parse2.cpp
@@ -127,9 +127,9 @@
       Node* len = load_array_length(ary);
 
       // Test length vs index (standard trick using unsigned compare)
-      Node* chk = _gvn.transform( new (C, 3) CmpUNode(idx, len) );
+      Node* chk = _gvn.transform( new (C) CmpUNode(idx, len) );
       BoolTest::mask btest = BoolTest::lt;
-      tst = _gvn.transform( new (C, 2) BoolNode(chk, btest) );
+      tst = _gvn.transform( new (C) BoolNode(chk, btest) );
     }
     // Branch to failure if out of bounds
     { BuildCutout unless(this, tst, PROB_MAX);
@@ -165,15 +165,15 @@
 
 // returns IfNode
 IfNode* Parse::jump_if_fork_int(Node* a, Node* b, BoolTest::mask mask) {
-  Node   *cmp = _gvn.transform( new (C, 3) CmpINode( a, b)); // two cases: shiftcount > 32 and shiftcount <= 32
-  Node   *tst = _gvn.transform( new (C, 2) BoolNode( cmp, mask));
+  Node   *cmp = _gvn.transform( new (C) CmpINode( a, b)); // two cases: shiftcount > 32 and shiftcount <= 32
+  Node   *tst = _gvn.transform( new (C) BoolNode( cmp, mask));
   IfNode *iff = create_and_map_if( control(), tst, ((mask == BoolTest::eq) ? PROB_STATIC_INFREQUENT : PROB_FAIR), COUNT_UNKNOWN );
   return iff;
 }
 
 // return Region node
 Node* Parse::jump_if_join(Node* iffalse, Node* iftrue) {
-  Node *region  = new (C, 3) RegionNode(3); // 2 results
+  Node *region  = new (C) RegionNode(3); // 2 results
   record_for_igvn(region);
   region->init_req(1, iffalse);
   region->init_req(2, iftrue );
@@ -188,28 +188,28 @@
 void Parse::jump_if_true_fork(IfNode *iff, int dest_bci_if_true, int prof_table_index) {
   // True branch, use existing map info
   { PreserveJVMState pjvms(this);
-    Node *iftrue  = _gvn.transform( new (C, 1) IfTrueNode (iff) );
+    Node *iftrue  = _gvn.transform( new (C) IfTrueNode (iff) );
     set_control( iftrue );
     profile_switch_case(prof_table_index);
     merge_new_path(dest_bci_if_true);
   }
 
   // False branch
-  Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff) );
+  Node *iffalse = _gvn.transform( new (C) IfFalseNode(iff) );
   set_control( iffalse );
 }
 
 void Parse::jump_if_false_fork(IfNode *iff, int dest_bci_if_true, int prof_table_index) {
   // True branch, use existing map info
   { PreserveJVMState pjvms(this);
-    Node *iffalse  = _gvn.transform( new (C, 1) IfFalseNode (iff) );
+    Node *iffalse  = _gvn.transform( new (C) IfFalseNode (iff) );
     set_control( iffalse );
     profile_switch_case(prof_table_index);
     merge_new_path(dest_bci_if_true);
   }
 
   // False branch
-  Node *iftrue = _gvn.transform( new (C, 1) IfTrueNode(iff) );
+  Node *iftrue = _gvn.transform( new (C) IfTrueNode(iff) );
   set_control( iftrue );
 }
 
@@ -437,14 +437,14 @@
 
   // Normalize table lookups to zero
   int lowval = lo->lo();
-  key_val = _gvn.transform( new (C, 3) SubINode(key_val, _gvn.intcon(lowval)) );
+  key_val = _gvn.transform( new (C) SubINode(key_val, _gvn.intcon(lowval)) );
 
   // Generate a guard to protect against input keyvals that aren't
   // in the switch domain.
   if (needs_guard) {
     Node*   size = _gvn.intcon(num_cases);
-    Node*   cmp = _gvn.transform( new (C, 3) CmpUNode(key_val, size) );
-    Node*   tst = _gvn.transform( new (C, 2) BoolNode(cmp, BoolTest::ge) );
+    Node*   cmp = _gvn.transform( new (C) CmpUNode(key_val, size) );
+    Node*   tst = _gvn.transform( new (C) BoolNode(cmp, BoolTest::ge) );
     IfNode* iff = create_and_map_if( control(), tst, PROB_FAIR, COUNT_UNKNOWN);
     jump_if_true_fork(iff, default_dest, NullTableIndex);
   }
@@ -457,21 +457,21 @@
   // Clean the 32-bit int into a real 64-bit offset.
   // Otherwise, the jint value 0 might turn into an offset of 0x0800000000.
   const TypeLong* lkeytype = TypeLong::make(CONST64(0), num_cases-1, Type::WidenMin);
-  key_val       = _gvn.transform( new (C, 2) ConvI2LNode(key_val, lkeytype) );
+  key_val       = _gvn.transform( new (C) ConvI2LNode(key_val, lkeytype) );
 #endif
   // Shift the value by wordsize so we have an index into the table, rather
   // than a switch value
   Node *shiftWord = _gvn.MakeConX(wordSize);
-  key_val = _gvn.transform( new (C, 3) MulXNode( key_val, shiftWord));
+  key_val = _gvn.transform( new (C) MulXNode( key_val, shiftWord));
 
   // Create the JumpNode
-  Node* jtn = _gvn.transform( new (C, 2) JumpNode(control(), key_val, num_cases) );
+  Node* jtn = _gvn.transform( new (C) JumpNode(control(), key_val, num_cases) );
 
   // These are the switch destinations hanging off the jumpnode
   int i = 0;
   for (SwitchRange* r = lo; r <= hi; r++) {
     for (int j = r->lo(); j <= r->hi(); j++, i++) {
-      Node* input = _gvn.transform(new (C, 1) JumpProjNode(jtn, i, r->dest(), j - lowval));
+      Node* input = _gvn.transform(new (C) JumpProjNode(jtn, i, r->dest(), j - lowval));
       {
         PreserveJVMState pjvms(this);
         set_control(input);
@@ -572,8 +572,8 @@
         // two comparisons of same values--should enable 1 test for 2 branches
         // Use BoolTest::le instead of BoolTest::gt
         IfNode *iff_le  = jump_if_fork_int(key_val, test_val, BoolTest::le);
-        Node   *iftrue  = _gvn.transform( new (C, 1) IfTrueNode(iff_le) );
-        Node   *iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff_le) );
+        Node   *iftrue  = _gvn.transform( new (C) IfTrueNode(iff_le) );
+        Node   *iffalse = _gvn.transform( new (C) IfFalseNode(iff_le) );
         { PreserveJVMState pjvms(this);
           set_control(iffalse);
           jump_switch_ranges(key_val, mid+1, hi, switch_depth+1);
@@ -589,8 +589,8 @@
       if (mid == hi) {
         jump_if_true_fork(iff_ge, mid->dest(), mid->table_index());
       } else {
-        Node *iftrue  = _gvn.transform( new (C, 1) IfTrueNode(iff_ge) );
-        Node *iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff_ge) );
+        Node *iftrue  = _gvn.transform( new (C) IfTrueNode(iff_ge) );
+        Node *iffalse = _gvn.transform( new (C) IfFalseNode(iff_ge) );
         { PreserveJVMState pjvms(this);
           set_control(iftrue);
           jump_switch_ranges(key_val, mid, hi, switch_depth+1);
@@ -645,7 +645,7 @@
                               CAST_FROM_FN_PTR(address, SharedRuntime::frem),
                               "frem", NULL, //no memory effects
                               f1, f2);
-  Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms + 0));
+  Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0));
 
   push(res);
 }
@@ -657,10 +657,10 @@
                               CAST_FROM_FN_PTR(address, SharedRuntime::drem),
                               "drem", NULL, //no memory effects
                               d1, top(), d2, top());
-  Node* res_d   = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms + 0));
+  Node* res_d   = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0));
 
 #ifdef ASSERT
-  Node* res_top = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms + 1));
+  Node* res_top = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 1));
   assert(res_top == top(), "second value must be top");
 #endif
 
@@ -674,7 +674,7 @@
                               CAST_FROM_FN_PTR(address, SharedRuntime::l2f),
                               "l2f", NULL, //no memory effects
                               f1, f2);
-  Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms + 0));
+  Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms + 0));
 
   push(res);
 }
@@ -701,17 +701,17 @@
         // Sigh, must handle negative dividends
         Node *zero = _gvn.intcon(0);
         IfNode *ifff = jump_if_fork_int(a, zero, BoolTest::lt);
-        Node *iff = _gvn.transform( new (C, 1) IfFalseNode(ifff) );
-        Node *ift = _gvn.transform( new (C, 1) IfTrueNode (ifff) );
+        Node *iff = _gvn.transform( new (C) IfFalseNode(ifff) );
+        Node *ift = _gvn.transform( new (C) IfTrueNode (ifff) );
         Node *reg = jump_if_join(ift, iff);
         Node *phi = PhiNode::make(reg, NULL, TypeInt::INT);
         // Negative path; negate/and/negate
-        Node *neg = _gvn.transform( new (C, 3) SubINode(zero, a) );
-        Node *andn= _gvn.transform( new (C, 3) AndINode(neg, mask) );
-        Node *negn= _gvn.transform( new (C, 3) SubINode(zero, andn) );
+        Node *neg = _gvn.transform( new (C) SubINode(zero, a) );
+        Node *andn= _gvn.transform( new (C) AndINode(neg, mask) );
+        Node *negn= _gvn.transform( new (C) SubINode(zero, andn) );
         phi->init_req(1, negn);
         // Fast positive case
-        Node *andx = _gvn.transform( new (C, 3) AndINode(a, mask) );
+        Node *andx = _gvn.transform( new (C) AndINode(a, mask) );
         phi->init_req(2, andx);
         // Push the merge
         push( _gvn.transform(phi) );
@@ -720,7 +720,7 @@
     }
   }
   // Default case
-  push( _gvn.transform( new (C, 3) ModINode(control(),a,b) ) );
+  push( _gvn.transform( new (C) ModINode(control(),a,b) ) );
 }
 
 // Handle jsr and jsr_w bytecode
@@ -997,7 +997,7 @@
   explicit_null_checks_inserted++;
 
   // Generate real control flow
-  Node   *tst = _gvn.transform( new (C, 2) BoolNode( c, btest ) );
+  Node   *tst = _gvn.transform( new (C) BoolNode( c, btest ) );
 
   // Sanity check the probability value
   assert(prob > 0.0f,"Bad probability in Parser");
@@ -1006,7 +1006,7 @@
   assert(iff->_prob > 0.0f,"Optimizer made bad probability in parser");
   // True branch
   { PreserveJVMState pjvms(this);
-    Node* iftrue  = _gvn.transform( new (C, 1) IfTrueNode (iff) );
+    Node* iftrue  = _gvn.transform( new (C) IfTrueNode (iff) );
     set_control(iftrue);
 
     if (stopped()) {            // Path is dead?
@@ -1026,7 +1026,7 @@
   }
 
   // False branch
-  Node* iffalse = _gvn.transform( new (C, 1) IfFalseNode(iff) );
+  Node* iffalse = _gvn.transform( new (C) IfFalseNode(iff) );
   set_control(iffalse);
 
   if (stopped()) {              // Path is dead?
@@ -1089,7 +1089,7 @@
   }
   assert(btest != BoolTest::eq, "!= is the only canonical exact test");
 
-  Node* tst0 = new (C, 2) BoolNode(c, btest);
+  Node* tst0 = new (C) BoolNode(c, btest);
   Node* tst = _gvn.transform(tst0);
   BoolTest::mask taken_btest   = BoolTest::illegal;
   BoolTest::mask untaken_btest = BoolTest::illegal;
@@ -1120,8 +1120,8 @@
   float true_prob = (taken_if_true ? prob : untaken_prob);
   IfNode* iff = create_and_map_if(control(), tst, true_prob, cnt);
   assert(iff->_prob > 0.0f,"Optimizer made bad probability in parser");
-  Node* taken_branch   = new (C, 1) IfTrueNode(iff);
-  Node* untaken_branch = new (C, 1) IfFalseNode(iff);
+  Node* taken_branch   = new (C) IfTrueNode(iff);
+  Node* untaken_branch = new (C) IfFalseNode(iff);
   if (!taken_if_true) {  // Finish conversion to canonical form
     Node* tmp      = taken_branch;
     taken_branch   = untaken_branch;
@@ -1233,6 +1233,71 @@
   if (!have_con)                        // remaining adjustments need a con
     return;
 
+  sharpen_type_after_if(btest, con, tcon, val, tval);
+}
+
+
+static Node* extract_obj_from_klass_load(PhaseGVN* gvn, Node* n) {
+  Node* ldk;
+  if (n->is_DecodeN()) {
+    if (n->in(1)->Opcode() != Op_LoadNKlass) {
+      return NULL;
+    } else {
+      ldk = n->in(1);
+    }
+  } else if (n->Opcode() != Op_LoadKlass) {
+    return NULL;
+  } else {
+    ldk = n;
+  }
+  assert(ldk != NULL && ldk->is_Load(), "should have found a LoadKlass or LoadNKlass node");
+
+  Node* adr = ldk->in(MemNode::Address);
+  intptr_t off = 0;
+  Node* obj = AddPNode::Ideal_base_and_offset(adr, gvn, off);
+  if (obj == NULL || off != oopDesc::klass_offset_in_bytes()) // loading oopDesc::_klass?
+    return NULL;
+  const TypePtr* tp = gvn->type(obj)->is_ptr();
+  if (tp == NULL || !(tp->isa_instptr() || tp->isa_aryptr())) // is obj a Java object ptr?
+    return NULL;
+
+  return obj;
+}
+
+void Parse::sharpen_type_after_if(BoolTest::mask btest,
+                                  Node* con, const Type* tcon,
+                                  Node* val, const Type* tval) {
+  // Look for opportunities to sharpen the type of a node
+  // whose klass is compared with a constant klass.
+  if (btest == BoolTest::eq && tcon->isa_klassptr()) {
+    Node* obj = extract_obj_from_klass_load(&_gvn, val);
+    const TypeOopPtr* con_type = tcon->isa_klassptr()->as_instance_type();
+    if (obj != NULL && (con_type->isa_instptr() || con_type->isa_aryptr())) {
+       // Found:
+       //   Bool(CmpP(LoadKlass(obj._klass), ConP(Foo.klass)), [eq])
+       // or the narrowOop equivalent.
+       const Type* obj_type = _gvn.type(obj);
+       const TypeOopPtr* tboth = obj_type->join(con_type)->isa_oopptr();
+       if (tboth != NULL && tboth->klass_is_exact() && tboth != obj_type &&
+           tboth->higher_equal(obj_type)) {
+          // obj has to be of the exact type Foo if the CmpP succeeds.
+          int obj_in_map = map()->find_edge(obj);
+          JVMState* jvms = this->jvms();
+          if (obj_in_map >= 0 &&
+              (jvms->is_loc(obj_in_map) || jvms->is_stk(obj_in_map))) {
+            TypeNode* ccast = new (C) CheckCastPPNode(control(), obj, tboth);
+            const Type* tcc = ccast->as_Type()->type();
+            assert(tcc != obj_type && tcc->higher_equal(obj_type), "must improve");
+            // Delay transform() call to allow recovery of pre-cast value
+            // at the control merge.
+            _gvn.set_type_bottom(ccast);
+            record_for_igvn(ccast);
+            // Here's the payoff.
+            replace_in_map(obj, ccast);
+          }
+       }
+    }
+  }
 
   int val_in_map = map()->find_edge(val);
   if (val_in_map < 0)  return;          // replace_in_map would be useless
@@ -1255,16 +1320,17 @@
       const Type* tboth = tcon->join(tval);
       if (tboth == tval)  break;        // Nothing to gain.
       if (tcon->isa_int()) {
-        ccast = new (C, 2) CastIINode(val, tboth);
+        ccast = new (C) CastIINode(val, tboth);
       } else if (tcon == TypePtr::NULL_PTR) {
         // Cast to null, but keep the pointer identity temporarily live.
-        ccast = new (C, 2) CastPPNode(val, tboth);
+        ccast = new (C) CastPPNode(val, tboth);
       } else {
         const TypeF* tf = tcon->isa_float_constant();
         const TypeD* td = tcon->isa_double_constant();
         // Exclude tests vs float/double 0 as these could be
         // either +0 or -0.  Just because you are equal to +0
         // doesn't mean you ARE +0!
+        // Note, following code also replaces Long and Oop values.
         if ((!tf || tf->_f != 0.0) &&
             (!td || td->_d != 0.0))
           cast = con;                   // Replace non-constant val by con.
@@ -1672,59 +1738,59 @@
     if (stopped())  return;
     b = pop();
     a = pop();
-    push( _gvn.transform( new (C, 3) DivINode(control(),a,b) ) );
+    push( _gvn.transform( new (C) DivINode(control(),a,b) ) );
     break;
   case Bytecodes::_imul:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) MulINode(a,b) ) );
+    push( _gvn.transform( new (C) MulINode(a,b) ) );
     break;
   case Bytecodes::_iadd:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) AddINode(a,b) ) );
+    push( _gvn.transform( new (C) AddINode(a,b) ) );
     break;
   case Bytecodes::_ineg:
     a = pop();
-    push( _gvn.transform( new (C, 3) SubINode(_gvn.intcon(0),a)) );
+    push( _gvn.transform( new (C) SubINode(_gvn.intcon(0),a)) );
     break;
   case Bytecodes::_isub:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) SubINode(a,b) ) );
+    push( _gvn.transform( new (C) SubINode(a,b) ) );
     break;
   case Bytecodes::_iand:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) AndINode(a,b) ) );
+    push( _gvn.transform( new (C) AndINode(a,b) ) );
     break;
   case Bytecodes::_ior:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) OrINode(a,b) ) );
+    push( _gvn.transform( new (C) OrINode(a,b) ) );
     break;
   case Bytecodes::_ixor:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) XorINode(a,b) ) );
+    push( _gvn.transform( new (C) XorINode(a,b) ) );
     break;
   case Bytecodes::_ishl:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) LShiftINode(a,b) ) );
+    push( _gvn.transform( new (C) LShiftINode(a,b) ) );
     break;
   case Bytecodes::_ishr:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) RShiftINode(a,b) ) );
+    push( _gvn.transform( new (C) RShiftINode(a,b) ) );
     break;
   case Bytecodes::_iushr:
     b = pop(); a = pop();
-    push( _gvn.transform( new (C, 3) URShiftINode(a,b) ) );
+    push( _gvn.transform( new (C) URShiftINode(a,b) ) );
     break;
 
   case Bytecodes::_fneg:
     a = pop();
-    b = _gvn.transform(new (C, 2) NegFNode (a));
+    b = _gvn.transform(new (C) NegFNode (a));
     push(b);
     break;
 
   case Bytecodes::_fsub:
     b = pop();
     a = pop();
-    c = _gvn.transform( new (C, 3) SubFNode(a,b) );
+    c = _gvn.transform( new (C) SubFNode(a,b) );
     d = precision_rounding(c);
     push( d );
     break;
@@ -1732,7 +1798,7 @@
   case Bytecodes::_fadd:
     b = pop();
     a = pop();
-    c = _gvn.transform( new (C, 3) AddFNode(a,b) );
+    c = _gvn.transform( new (C) AddFNode(a,b) );
     d = precision_rounding(c);
     push( d );
     break;
@@ -1740,7 +1806,7 @@
   case Bytecodes::_fmul:
     b = pop();
     a = pop();
-    c = _gvn.transform( new (C, 3) MulFNode(a,b) );
+    c = _gvn.transform( new (C) MulFNode(a,b) );
     d = precision_rounding(c);
     push( d );
     break;
@@ -1748,7 +1814,7 @@
   case Bytecodes::_fdiv:
     b = pop();
     a = pop();
-    c = _gvn.transform( new (C, 3) DivFNode(0,a,b) );
+    c = _gvn.transform( new (C) DivFNode(0,a,b) );
     d = precision_rounding(c);
     push( d );
     break;
@@ -1758,7 +1824,7 @@
       // Generate a ModF node.
       b = pop();
       a = pop();
-      c = _gvn.transform( new (C, 3) ModFNode(0,a,b) );
+      c = _gvn.transform( new (C) ModFNode(0,a,b) );
       d = precision_rounding(c);
       push( d );
     }
@@ -1771,7 +1837,7 @@
   case Bytecodes::_fcmpl:
     b = pop();
     a = pop();
-    c = _gvn.transform( new (C, 3) CmpF3Node( a, b));
+    c = _gvn.transform( new (C) CmpF3Node( a, b));
     push(c);
     break;
   case Bytecodes::_fcmpg:
@@ -1783,40 +1849,40 @@
     // as well by using CmpF3 which implements unordered-lesser instead of
     // unordered-greater semantics.  Finally, commute the result bits.  Result
     // is same as using a CmpF3Greater except we did it with CmpF3 alone.
-    c = _gvn.transform( new (C, 3) CmpF3Node( b, a));
-    c = _gvn.transform( new (C, 3) SubINode(_gvn.intcon(0),c) );
+    c = _gvn.transform( new (C) CmpF3Node( b, a));
+    c = _gvn.transform( new (C) SubINode(_gvn.intcon(0),c) );
     push(c);
     break;
 
   case Bytecodes::_f2i:
     a = pop();
-    push(_gvn.transform(new (C, 2) ConvF2INode(a)));
+    push(_gvn.transform(new (C) ConvF2INode(a)));
     break;
 
   case Bytecodes::_d2i:
     a = pop_pair();
-    b = _gvn.transform(new (C, 2) ConvD2INode(a));
+    b = _gvn.transform(new (C) ConvD2INode(a));
     push( b );
     break;
 
   case Bytecodes::_f2d:
     a = pop();
-    b = _gvn.transform( new (C, 2) ConvF2DNode(a));
+    b = _gvn.transform( new (C) ConvF2DNode(a));
     push_pair( b );
     break;
 
   case Bytecodes::_d2f:
     a = pop_pair();
-    b = _gvn.transform( new (C, 2) ConvD2FNode(a));
+    b = _gvn.transform( new (C) ConvD2FNode(a));
     // This breaks _227_mtrt (speed & correctness) and _222_mpegaudio (speed)
-    //b = _gvn.transform(new (C, 2) RoundFloatNode(0, b) );
+    //b = _gvn.transform(new (C) RoundFloatNode(0, b) );
     push( b );
     break;
 
   case Bytecodes::_l2f:
     if (Matcher::convL2FSupported()) {
       a = pop_pair();
-      b = _gvn.transform( new (C, 2) ConvL2FNode(a));
+      b = _gvn.transform( new (C) ConvL2FNode(a));
       // For i486.ad, FILD doesn't restrict precision to 24 or 53 bits.
       // Rather than storing the result into an FP register then pushing
       // out to memory to round, the machine instruction that implements
@@ -1831,7 +1897,7 @@
 
   case Bytecodes::_l2d:
     a = pop_pair();
-    b = _gvn.transform( new (C, 2) ConvL2DNode(a));
+    b = _gvn.transform( new (C) ConvL2DNode(a));
     // For i486.ad, rounding is always necessary (see _l2f above).
     // c = dprecision_rounding(b);
     c = _gvn.transform(b);
@@ -1840,20 +1906,20 @@
 
   case Bytecodes::_f2l:
     a = pop();
-    b = _gvn.transform( new (C, 2) ConvF2LNode(a));
+    b = _gvn.transform( new (C) ConvF2LNode(a));
     push_pair(b);
     break;
 
   case Bytecodes::_d2l:
     a = pop_pair();
-    b = _gvn.transform( new (C, 2) ConvD2LNode(a));
+    b = _gvn.transform( new (C) ConvD2LNode(a));
     push_pair(b);
     break;
 
   case Bytecodes::_dsub:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) SubDNode(a,b) );
+    c = _gvn.transform( new (C) SubDNode(a,b) );
     d = dprecision_rounding(c);
     push_pair( d );
     break;
@@ -1861,7 +1927,7 @@
   case Bytecodes::_dadd:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) AddDNode(a,b) );
+    c = _gvn.transform( new (C) AddDNode(a,b) );
     d = dprecision_rounding(c);
     push_pair( d );
     break;
@@ -1869,7 +1935,7 @@
   case Bytecodes::_dmul:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) MulDNode(a,b) );
+    c = _gvn.transform( new (C) MulDNode(a,b) );
     d = dprecision_rounding(c);
     push_pair( d );
     break;
@@ -1877,14 +1943,14 @@
   case Bytecodes::_ddiv:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) DivDNode(0,a,b) );
+    c = _gvn.transform( new (C) DivDNode(0,a,b) );
     d = dprecision_rounding(c);
     push_pair( d );
     break;
 
   case Bytecodes::_dneg:
     a = pop_pair();
-    b = _gvn.transform(new (C, 2) NegDNode (a));
+    b = _gvn.transform(new (C) NegDNode (a));
     push_pair(b);
     break;
 
@@ -1895,7 +1961,7 @@
       a = pop_pair();
       // a % b
 
-      c = _gvn.transform( new (C, 3) ModDNode(0,a,b) );
+      c = _gvn.transform( new (C) ModDNode(0,a,b) );
       d = dprecision_rounding(c);
       push_pair( d );
     }
@@ -1908,7 +1974,7 @@
   case Bytecodes::_dcmpl:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) CmpD3Node( a, b));
+    c = _gvn.transform( new (C) CmpD3Node( a, b));
     push(c);
     break;
 
@@ -1921,8 +1987,8 @@
     // unordered-lesser instead of unordered-greater semantics.
     // Finally, negate the result bits.  Result is same as using a
     // CmpD3Greater except we did it with CmpD3 alone.
-    c = _gvn.transform( new (C, 3) CmpD3Node( b, a));
-    c = _gvn.transform( new (C, 3) SubINode(_gvn.intcon(0),c) );
+    c = _gvn.transform( new (C) CmpD3Node( b, a));
+    c = _gvn.transform( new (C) SubINode(_gvn.intcon(0),c) );
     push(c);
     break;
 
@@ -1931,44 +1997,44 @@
   case Bytecodes::_land:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) AndLNode(a,b) );
+    c = _gvn.transform( new (C) AndLNode(a,b) );
     push_pair(c);
     break;
   case Bytecodes::_lor:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) OrLNode(a,b) );
+    c = _gvn.transform( new (C) OrLNode(a,b) );
     push_pair(c);
     break;
   case Bytecodes::_lxor:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) XorLNode(a,b) );
+    c = _gvn.transform( new (C) XorLNode(a,b) );
     push_pair(c);
     break;
 
   case Bytecodes::_lshl:
     b = pop();                  // the shift count
     a = pop_pair();             // value to be shifted
-    c = _gvn.transform( new (C, 3) LShiftLNode(a,b) );
+    c = _gvn.transform( new (C) LShiftLNode(a,b) );
     push_pair(c);
     break;
   case Bytecodes::_lshr:
     b = pop();                  // the shift count
     a = pop_pair();             // value to be shifted
-    c = _gvn.transform( new (C, 3) RShiftLNode(a,b) );
+    c = _gvn.transform( new (C) RShiftLNode(a,b) );
     push_pair(c);
     break;
   case Bytecodes::_lushr:
     b = pop();                  // the shift count
     a = pop_pair();             // value to be shifted
-    c = _gvn.transform( new (C, 3) URShiftLNode(a,b) );
+    c = _gvn.transform( new (C) URShiftLNode(a,b) );
     push_pair(c);
     break;
   case Bytecodes::_lmul:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) MulLNode(a,b) );
+    c = _gvn.transform( new (C) MulLNode(a,b) );
     push_pair(c);
     break;
 
@@ -1980,7 +2046,7 @@
     if (stopped())  return;
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) ModLNode(control(),a,b) );
+    c = _gvn.transform( new (C) ModLNode(control(),a,b) );
     push_pair(c);
     break;
 
@@ -1992,20 +2058,20 @@
     if (stopped())  return;
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) DivLNode(control(),a,b) );
+    c = _gvn.transform( new (C) DivLNode(control(),a,b) );
     push_pair(c);
     break;
 
   case Bytecodes::_ladd:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) AddLNode(a,b) );
+    c = _gvn.transform( new (C) AddLNode(a,b) );
     push_pair(c);
     break;
   case Bytecodes::_lsub:
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) SubLNode(a,b) );
+    c = _gvn.transform( new (C) SubLNode(a,b) );
     push_pair(c);
     break;
   case Bytecodes::_lcmp:
@@ -2036,58 +2102,58 @@
     }
     b = pop_pair();
     a = pop_pair();
-    c = _gvn.transform( new (C, 3) CmpL3Node( a, b ));
+    c = _gvn.transform( new (C) CmpL3Node( a, b ));
     push(c);
     break;
 
   case Bytecodes::_lneg:
     a = pop_pair();
-    b = _gvn.transform( new (C, 3) SubLNode(longcon(0),a));
+    b = _gvn.transform( new (C) SubLNode(longcon(0),a));
     push_pair(b);
     break;
   case Bytecodes::_l2i:
     a = pop_pair();
-    push( _gvn.transform( new (C, 2) ConvL2INode(a)));
+    push( _gvn.transform( new (C) ConvL2INode(a)));
     break;
   case Bytecodes::_i2l:
     a = pop();
-    b = _gvn.transform( new (C, 2) ConvI2LNode(a));
+    b = _gvn.transform( new (C) ConvI2LNode(a));
     push_pair(b);
     break;
   case Bytecodes::_i2b:
     // Sign extend
     a = pop();
-    a = _gvn.transform( new (C, 3) LShiftINode(a,_gvn.intcon(24)) );
-    a = _gvn.transform( new (C, 3) RShiftINode(a,_gvn.intcon(24)) );
+    a = _gvn.transform( new (C) LShiftINode(a,_gvn.intcon(24)) );
+    a = _gvn.transform( new (C) RShiftINode(a,_gvn.intcon(24)) );
     push( a );
     break;
   case Bytecodes::_i2s:
     a = pop();
-    a = _gvn.transform( new (C, 3) LShiftINode(a,_gvn.intcon(16)) );
-    a = _gvn.transform( new (C, 3) RShiftINode(a,_gvn.intcon(16)) );
+    a = _gvn.transform( new (C) LShiftINode(a,_gvn.intcon(16)) );
+    a = _gvn.transform( new (C) RShiftINode(a,_gvn.intcon(16)) );
     push( a );
     break;
   case Bytecodes::_i2c:
     a = pop();
-    push( _gvn.transform( new (C, 3) AndINode(a,_gvn.intcon(0xFFFF)) ) );
+    push( _gvn.transform( new (C) AndINode(a,_gvn.intcon(0xFFFF)) ) );
     break;
 
   case Bytecodes::_i2f:
     a = pop();
-    b = _gvn.transform( new (C, 2) ConvI2FNode(a) ) ;
+    b = _gvn.transform( new (C) ConvI2FNode(a) ) ;
     c = precision_rounding(b);
     push (b);
     break;
 
   case Bytecodes::_i2d:
     a = pop();
-    b = _gvn.transform( new (C, 2) ConvI2DNode(a));
+    b = _gvn.transform( new (C) ConvI2DNode(a));
     push_pair(b);
     break;
 
   case Bytecodes::_iinc:        // Increment local
     i = iter().get_index();     // Get local index
-    set_local( i, _gvn.transform( new (C, 3) AddINode( _gvn.intcon(iter().get_iinc_con()), local(i) ) ) );
+    set_local( i, _gvn.transform( new (C) AddINode( _gvn.intcon(iter().get_iinc_con()), local(i) ) ) );
     break;
 
   // Exit points of synchronized methods must have an unlock node
@@ -2159,7 +2225,7 @@
     maybe_add_safepoint(iter().get_dest());
     a = null();
     b = pop();
-    c = _gvn.transform( new (C, 3) CmpPNode(b, a) );
+    c = _gvn.transform( new (C) CmpPNode(b, a) );
     do_ifnull(btest, c);
     break;
 
@@ -2170,7 +2236,7 @@
     maybe_add_safepoint(iter().get_dest());
     a = pop();
     b = pop();
-    c = _gvn.transform( new (C, 3) CmpPNode(b, a) );
+    c = _gvn.transform( new (C) CmpPNode(b, a) );
     do_if(btest, c);
     break;
 
@@ -2185,7 +2251,7 @@
     maybe_add_safepoint(iter().get_dest());
     a = _gvn.intcon(0);
     b = pop();
-    c = _gvn.transform( new (C, 3) CmpINode(b, a) );
+    c = _gvn.transform( new (C) CmpINode(b, a) );
     do_if(btest, c);
     break;
 
@@ -2200,7 +2266,7 @@
     maybe_add_safepoint(iter().get_dest());
     a = pop();
     b = pop();
-    c = _gvn.transform( new (C, 3) CmpINode( b, a ) );
+    c = _gvn.transform( new (C) CmpINode( b, a ) );
     do_if(btest, c);
     break;
 
diff --git a/hotspot/src/share/vm/opto/parse3.cpp b/hotspot/src/share/vm/opto/parse3.cpp
index 6d6fd07..1a2f052 100644
--- a/hotspot/src/share/vm/opto/parse3.cpp
+++ b/hotspot/src/share/vm/opto/parse3.cpp
@@ -510,7 +510,7 @@
                           dims);
   }
 
-  Node* res = _gvn.transform(new (C, 1) ProjNode(c, TypeFunc::Parms));
+  Node* res = _gvn.transform(new (C) ProjNode(c, TypeFunc::Parms));
 
   const Type* type = TypeOopPtr::make_from_klass_raw(array_klass);
 
@@ -524,7 +524,7 @@
 
     // We cannot sharpen the nested sub-arrays, since the top level is mutable.
 
-  Node* cast = _gvn.transform( new (C, 2) CheckCastPPNode(control(), res, type) );
+  Node* cast = _gvn.transform( new (C) CheckCastPPNode(control(), res, type) );
   push(cast);
 
   // Possible improvements:
diff --git a/hotspot/src/share/vm/opto/parseHelper.cpp b/hotspot/src/share/vm/opto/parseHelper.cpp
index 26a146f5..e83c29f 100644
--- a/hotspot/src/share/vm/opto/parseHelper.cpp
+++ b/hotspot/src/share/vm/opto/parseHelper.cpp
@@ -43,7 +43,7 @@
   const char     *call_name    = is_entry ? "dtrace_method_entry" : "dtrace_method_exit";
 
   // Get base of thread-local storage area
-  Node* thread = _gvn.transform( new (C, 1) ThreadLocalNode() );
+  Node* thread = _gvn.transform( new (C) ThreadLocalNode() );
 
   // Get method
   const TypeInstPtr* method_type = TypeInstPtr::make(TypePtr::Constant, method->klass(), true, method, 0);
@@ -175,8 +175,8 @@
     // Make a constant out of the inexact array klass
     const TypeKlassPtr *extak = tak->cast_to_exactness(true)->is_klassptr();
     Node* con = makecon(extak);
-    Node* cmp = _gvn.transform(new (C, 3) CmpPNode( array_klass, con ));
-    Node* bol = _gvn.transform(new (C, 2) BoolNode( cmp, BoolTest::eq ));
+    Node* cmp = _gvn.transform(new (C) CmpPNode( array_klass, con ));
+    Node* bol = _gvn.transform(new (C) BoolNode( cmp, BoolTest::eq ));
     Node* ctrl= control();
     { BuildCutout unless(this, bol, PROB_MAX);
       uncommon_trap(Deoptimization::Reason_array_check,
@@ -215,8 +215,8 @@
   //   if (klass->_init_thread != current_thread ||
   //       klass->_init_state != being_initialized)
   //      uncommon_trap
-  Node* cur_thread = _gvn.transform( new (C, 1) ThreadLocalNode() );
-  Node* merge = new (C, 3) RegionNode(3);
+  Node* cur_thread = _gvn.transform( new (C) ThreadLocalNode() );
+  Node* merge = new (C) RegionNode(3);
   _gvn.set_type(merge, Type::CONTROL);
   Node* kls = makecon(TypeKlassPtr::make(klass));
 
@@ -322,9 +322,9 @@
 
   // Test invocation count vs threshold
   Node *threshold = makecon(TypeInt::make(limit));
-  Node *chk   = _gvn.transform( new (C, 3) CmpUNode( cnt, threshold) );
+  Node *chk   = _gvn.transform( new (C) CmpUNode( cnt, threshold) );
   BoolTest::mask btest = BoolTest::lt;
-  Node *tst   = _gvn.transform( new (C, 2) BoolNode( chk, btest) );
+  Node *tst   = _gvn.transform( new (C) BoolNode( chk, btest) );
   // Branch to failure if threshold exceeded
   { BuildCutout unless(this, tst, PROB_ALWAYS);
     uncommon_trap(Deoptimization::Reason_age,
@@ -348,7 +348,7 @@
   test_counter_against_threshold(cnt, limit);
 
   // Add one to the counter and store
-  Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(1)));
+  Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(1)));
   store_to_memory( NULL, adr_node, incr, T_INT, adr_type );
 }
 
@@ -369,8 +369,8 @@
 
   if (stride != 0) {
     Node* str = _gvn.MakeConX(stride);
-    Node* scale = _gvn.transform( new (C, 3) MulXNode( idx, str ) );
-    ptr   = _gvn.transform( new (C, 4) AddPNode( mdo, ptr, scale ) );
+    Node* scale = _gvn.transform( new (C) MulXNode( idx, str ) );
+    ptr   = _gvn.transform( new (C) AddPNode( mdo, ptr, scale ) );
   }
 
   return ptr;
@@ -382,7 +382,7 @@
 
   const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr();
   Node* cnt  = make_load(NULL, adr_node, TypeInt::INT, T_INT, adr_type);
-  Node* incr = _gvn.transform(new (C, 3) AddINode(cnt, _gvn.intcon(DataLayout::counter_increment)));
+  Node* incr = _gvn.transform(new (C) AddINode(cnt, _gvn.intcon(DataLayout::counter_increment)));
   store_to_memory(NULL, adr_node, incr, T_INT, adr_type );
 }
 
@@ -402,7 +402,7 @@
 
   const TypePtr* adr_type = _gvn.type(adr_node)->is_ptr();
   Node* flags = make_load(NULL, adr_node, TypeInt::BYTE, T_BYTE, adr_type);
-  Node* incr = _gvn.transform(new (C, 3) OrINode(flags, _gvn.intcon(flag_constant)));
+  Node* incr = _gvn.transform(new (C) OrINode(flags, _gvn.intcon(flag_constant)));
   store_to_memory(NULL, adr_node, incr, T_BYTE, adr_type);
 }
 
diff --git a/hotspot/src/share/vm/opto/phase.cpp b/hotspot/src/share/vm/opto/phase.cpp
index ae79a55..0b88996 100644
--- a/hotspot/src/share/vm/opto/phase.cpp
+++ b/hotspot/src/share/vm/opto/phase.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -39,8 +39,9 @@
 
 // The next timers used for LogCompilation
 elapsedTimer Phase::_t_parser;
-elapsedTimer Phase::_t_escapeAnalysis;
 elapsedTimer Phase::_t_optimizer;
+elapsedTimer   Phase::_t_escapeAnalysis;
+elapsedTimer     Phase::_t_connectionGraph;
 elapsedTimer   Phase::_t_idealLoop;
 elapsedTimer   Phase::_t_ccp;
 elapsedTimer Phase::_t_matcher;
@@ -51,6 +52,7 @@
 elapsedTimer Phase::_t_graphReshaping;
 elapsedTimer Phase::_t_scheduler;
 elapsedTimer Phase::_t_blockOrdering;
+elapsedTimer Phase::_t_macroEliminate;
 elapsedTimer Phase::_t_macroExpand;
 elapsedTimer Phase::_t_peephole;
 elapsedTimer Phase::_t_codeGeneration;
@@ -104,6 +106,8 @@
     if (DoEscapeAnalysis) {
       // EA is part of Optimizer.
       tty->print_cr ("      escape analysis: %3.3f sec", Phase::_t_escapeAnalysis.seconds());
+      tty->print_cr ("        connection graph: %3.3f sec", Phase::_t_connectionGraph.seconds());
+      tty->print_cr ("      macroEliminate : %3.3f sec", Phase::_t_macroEliminate.seconds());
     }
     tty->print_cr ("      iterGVN        : %3.3f sec", Phase::_t_iterGVN.seconds());
     tty->print_cr ("      idealLoop      : %3.3f sec", Phase::_t_idealLoop.seconds());
@@ -112,9 +116,10 @@
     tty->print_cr ("      iterGVN2       : %3.3f sec", Phase::_t_iterGVN2.seconds());
     tty->print_cr ("      macroExpand    : %3.3f sec", Phase::_t_macroExpand.seconds());
     tty->print_cr ("      graphReshape   : %3.3f sec", Phase::_t_graphReshaping.seconds());
-    double optimizer_subtotal = Phase::_t_iterGVN.seconds() +
+    double optimizer_subtotal = Phase::_t_iterGVN.seconds() + Phase::_t_iterGVN2.seconds() +
+      Phase::_t_escapeAnalysis.seconds() + Phase::_t_macroEliminate.seconds() +
       Phase::_t_idealLoop.seconds() + Phase::_t_ccp.seconds() +
-      Phase::_t_graphReshaping.seconds();
+      Phase::_t_macroExpand.seconds() + Phase::_t_graphReshaping.seconds();
     double percent_of_optimizer = ((optimizer_subtotal == 0.0) ? 0.0 : (optimizer_subtotal / Phase::_t_optimizer.seconds() * 100.0));
     tty->print_cr ("      subtotal       : %3.3f sec,  %3.2f %%", optimizer_subtotal, percent_of_optimizer);
   }
diff --git a/hotspot/src/share/vm/opto/phase.hpp b/hotspot/src/share/vm/opto/phase.hpp
index c52fda3..9faabf5 100644
--- a/hotspot/src/share/vm/opto/phase.hpp
+++ b/hotspot/src/share/vm/opto/phase.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -72,8 +72,12 @@
 
 // The next timers used for LogCompilation
   static elapsedTimer _t_parser;
-  static elapsedTimer _t_escapeAnalysis;
   static elapsedTimer _t_optimizer;
+public:
+  // ConnectionGraph can't be Phase since it is used after EA done.
+  static elapsedTimer   _t_escapeAnalysis;
+  static elapsedTimer     _t_connectionGraph;
+protected:
   static elapsedTimer   _t_idealLoop;
   static elapsedTimer   _t_ccp;
   static elapsedTimer _t_matcher;
@@ -84,6 +88,7 @@
   static elapsedTimer _t_graphReshaping;
   static elapsedTimer _t_scheduler;
   static elapsedTimer _t_blockOrdering;
+  static elapsedTimer _t_macroEliminate;
   static elapsedTimer _t_macroExpand;
   static elapsedTimer _t_peephole;
   static elapsedTimer _t_codeGeneration;
diff --git a/hotspot/src/share/vm/opto/phaseX.cpp b/hotspot/src/share/vm/opto/phaseX.cpp
index 99b7393..0373596 100644
--- a/hotspot/src/share/vm/opto/phaseX.cpp
+++ b/hotspot/src/share/vm/opto/phaseX.cpp
@@ -48,7 +48,7 @@
   _total_insert_probes(0), _total_inserts(0),
   _insert_probes(0), _grows(0) {
   // _sentinel must be in the current node space
-  _sentinel = new (Compile::current(), 1) ProjNode(NULL, TypeFunc::Control);
+  _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control);
   memset(_table,0,sizeof(Node*)*_max);
 }
 
@@ -63,7 +63,7 @@
   _total_insert_probes(0), _total_inserts(0),
   _insert_probes(0), _grows(0) {
   // _sentinel must be in the current node space
-  _sentinel = new (Compile::current(), 1) ProjNode(NULL, TypeFunc::Control);
+  _sentinel = new (Compile::current()) ProjNode(NULL, TypeFunc::Control);
   memset(_table,0,sizeof(Node*)*_max);
 }
 
@@ -757,6 +757,7 @@
 //------------------------------PhaseIterGVN-----------------------------------
 // Initialize hash table to fresh and clean for +VerifyOpto
 PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn, const char *dummy ) : PhaseGVN(igvn,dummy), _worklist( ),
+                                                                      _stack(C->unique() >> 1),
                                                                       _delay_transform(false) {
 }
 
@@ -764,6 +765,7 @@
 // Initialize with previous PhaseIterGVN info; used by PhaseCCP
 PhaseIterGVN::PhaseIterGVN( PhaseIterGVN *igvn ) : PhaseGVN(igvn),
                                                    _worklist( igvn->_worklist ),
+                                                   _stack( igvn->_stack ),
                                                    _delay_transform(igvn->_delay_transform)
 {
 }
@@ -772,6 +774,7 @@
 // Initialize with previous PhaseGVN info from Parser
 PhaseIterGVN::PhaseIterGVN( PhaseGVN *gvn ) : PhaseGVN(gvn),
                                               _worklist(*C->for_igvn()),
+                                              _stack(C->unique() >> 1),
                                               _delay_transform(false)
 {
   uint max;
@@ -1138,51 +1141,77 @@
 // Kill a globally dead Node.  All uses are also globally dead and are
 // aggressively trimmed.
 void PhaseIterGVN::remove_globally_dead_node( Node *dead ) {
-  assert(dead != C->root(), "killing root, eh?");
-  if (dead->is_top())  return;
-  NOT_PRODUCT( set_progress(); )
-  // Remove from iterative worklist
-  _worklist.remove(dead);
-  if (!dead->is_Con()) { // Don't kill cons but uses
-    // Remove from hash table
-    _table.hash_delete( dead );
-    // Smash all inputs to 'dead', isolating him completely
-    for( uint i = 0; i < dead->req(); i++ ) {
-      Node *in = dead->in(i);
-      if( in ) {                 // Points to something?
-        dead->set_req(i,NULL);  // Kill the edge
-        if (in->outcnt() == 0 && in != C->top()) {// Made input go dead?
-          remove_dead_node(in); // Recursively remove
-        } else if (in->outcnt() == 1 &&
-                   in->has_special_unique_user()) {
-          _worklist.push(in->unique_out());
-        } else if (in->outcnt() <= 2 && dead->is_Phi()) {
-          if( in->Opcode() == Op_Region )
-            _worklist.push(in);
-          else if( in->is_Store() ) {
-            DUIterator_Fast imax, i = in->fast_outs(imax);
-            _worklist.push(in->fast_out(i));
-            i++;
-            if(in->outcnt() == 2) {
-              _worklist.push(in->fast_out(i));
-              i++;
+  enum DeleteProgress {
+    PROCESS_INPUTS,
+    PROCESS_OUTPUTS
+  };
+  assert(_stack.is_empty(), "not empty");
+  _stack.push(dead, PROCESS_INPUTS);
+
+  while (_stack.is_nonempty()) {
+    dead = _stack.node();
+    uint progress_state = _stack.index();
+    assert(dead != C->root(), "killing root, eh?");
+    assert(!dead->is_top(), "add check for top when pushing");
+    NOT_PRODUCT( set_progress(); )
+    if (progress_state == PROCESS_INPUTS) {
+      // After following inputs, continue to outputs
+      _stack.set_index(PROCESS_OUTPUTS);
+      // Remove from iterative worklist
+      _worklist.remove(dead);
+      if (!dead->is_Con()) { // Don't kill cons but uses
+        bool recurse = false;
+        // Remove from hash table
+        _table.hash_delete( dead );
+        // Smash all inputs to 'dead', isolating him completely
+        for( uint i = 0; i < dead->req(); i++ ) {
+          Node *in = dead->in(i);
+          if( in ) {                 // Points to something?
+            dead->set_req(i,NULL);  // Kill the edge
+            if (in->outcnt() == 0 && in != C->top()) {// Made input go dead?
+              _stack.push(in, PROCESS_INPUTS); // Recursively remove
+              recurse = true;
+            } else if (in->outcnt() == 1 &&
+                       in->has_special_unique_user()) {
+              _worklist.push(in->unique_out());
+            } else if (in->outcnt() <= 2 && dead->is_Phi()) {
+              if( in->Opcode() == Op_Region )
+                _worklist.push(in);
+              else if( in->is_Store() ) {
+                DUIterator_Fast imax, i = in->fast_outs(imax);
+                _worklist.push(in->fast_out(i));
+                i++;
+                if(in->outcnt() == 2) {
+                  _worklist.push(in->fast_out(i));
+                  i++;
+                }
+                assert(!(i < imax), "sanity");
+              }
             }
-            assert(!(i < imax), "sanity");
           }
         }
+
+        if (dead->is_macro()) {
+          C->remove_macro_node(dead);
+        }
+
+        if (recurse) {
+          continue;
+        }
       }
     }
 
-    if (dead->is_macro()) {
-      C->remove_macro_node(dead);
+    // Aggressively kill globally dead uses
+    // (Rather than pushing all the outs at once, we push one at a time,
+    // plus the parent to resume later, because of the indefinite number
+    // of edge deletions per loop trip.)
+    if (dead->outcnt() > 0) {
+      // Recursively remove
+      _stack.push(dead->raw_out(0), PROCESS_INPUTS);
+    } else {
+      _stack.pop();
     }
   }
-  // Aggressively kill globally dead uses
-  // (Cannot use DUIterator_Last because of the indefinite number
-  // of edge deletions per loop trip.)
-  while (dead->outcnt() > 0) {
-    remove_globally_dead_node(dead->raw_out(0));
-  }
 }
 
 //------------------------------subsume_node-----------------------------------
@@ -1217,7 +1246,7 @@
   }
 
   // Smash all inputs to 'old', isolating him completely
-  Node *temp = new (C, 1) Node(1);
+  Node *temp = new (C) Node(1);
   temp->init_req(0,nn);     // Add a use to nn to prevent him from dying
   remove_dead_node( old );
   temp->del_req(0);         // Yank bogus edge
diff --git a/hotspot/src/share/vm/opto/phaseX.hpp b/hotspot/src/share/vm/opto/phaseX.hpp
index ef5bbb5..9338a28 100644
--- a/hotspot/src/share/vm/opto/phaseX.hpp
+++ b/hotspot/src/share/vm/opto/phaseX.hpp
@@ -193,6 +193,7 @@
   // If you want the type of a very new (untransformed) node,
   // you must use type_or_null, and test the result for NULL.
   const Type* type(const Node* n) const {
+    assert(n != NULL, "must not be null");
     const Type* t = _types.fast_lookup(n->_idx);
     assert(t != NULL, "must set before get");
     return t;
@@ -403,6 +404,8 @@
   // Subsume users of node 'old' into node 'nn'
   void subsume_node( Node *old, Node *nn );
 
+  Node_Stack _stack;      // Stack used to avoid recursion
+
 protected:
 
   // Idealize new Node 'n' with respect to its inputs and its value
@@ -438,8 +441,8 @@
   // It is significant only for debugging and profiling.
   Node* register_new_node_with_optimizer(Node* n, Node* orig = NULL);
 
-  // Kill a globally dead Node.   It is allowed to have uses which are
-  // assumed dead and left 'in limbo'.
+  // Kill a globally dead Node.  All uses are also globally dead and are
+  // aggressively trimmed.
   void remove_globally_dead_node( Node *dead );
 
   // Kill all inputs to a dead node, recursively making more dead nodes.
@@ -460,6 +463,25 @@
     subsume_node(old, nn);
   }
 
+  // Delayed node rehash: remove a node from the hash table and rehash it during
+  // next optimizing pass
+  void rehash_node_delayed(Node* n) {
+    hash_delete(n);
+    _worklist.push(n);
+  }
+
+  // Replace ith edge of "n" with "in"
+  void replace_input_of(Node* n, int i, Node* in) {
+    rehash_node_delayed(n);
+    n->set_req(i, in);
+  }
+
+  // Delete ith edge of "n"
+  void delete_input_of(Node* n, int i) {
+    rehash_node_delayed(n);
+    n->del_req(i);
+  }
+
   bool delay_transform() const { return _delay_transform; }
 
   void set_delay_transform(bool delay) {
@@ -475,8 +497,8 @@
 #ifndef PRODUCT
 protected:
   // Sub-quadratic implementation of VerifyIterativeGVN.
-  unsigned long _verify_counter;
-  unsigned long _verify_full_passes;
+  julong _verify_counter;
+  julong _verify_full_passes;
   enum { _verify_window_size = 30 };
   Node* _verify_window[_verify_window_size];
   void verify_step(Node* n);
diff --git a/hotspot/src/share/vm/opto/postaloc.cpp b/hotspot/src/share/vm/opto/postaloc.cpp
index 1a7553b..912e077 100644
--- a/hotspot/src/share/vm/opto/postaloc.cpp
+++ b/hotspot/src/share/vm/opto/postaloc.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,13 +27,15 @@
 #include "opto/chaitin.hpp"
 #include "opto/machnode.hpp"
 
-// see if this register kind does not requires two registers
-static bool is_single_register(uint x) {
-#ifdef _LP64
-  return (x != Op_RegD && x != Op_RegL && x != Op_RegP);
-#else
-  return (x != Op_RegD && x != Op_RegL);
-#endif
+// See if this register (or pairs, or vector) already contains the value.
+static bool register_contains_value(Node* val, OptoReg::Name reg, int n_regs,
+                                    Node_List& value) {
+  for (int i = 0; i < n_regs; i++) {
+    OptoReg::Name nreg = OptoReg::add(reg,-i);
+    if (value[nreg] != val)
+      return false;
+  }
+  return true;
 }
 
 //---------------------------may_be_copy_of_callee-----------------------------
@@ -167,9 +169,11 @@
   const RegMask &use_mask = n->in_RegMask(idx);
   bool can_use = ( RegMask::can_represent(def_reg) ? (use_mask.Member(def_reg) != 0)
                                                    : (use_mask.is_AllStack() != 0));
-  // Check for a copy to or from a misaligned pair.
-  can_use = can_use && !use_mask.is_misaligned_Pair() && !def_lrg.mask().is_misaligned_Pair();
-
+  if (!RegMask::is_vector(def->ideal_reg())) {
+    // Check for a copy to or from a misaligned pair.
+    // It is workaround for a sparc with misaligned pairs.
+    can_use = can_use && !use_mask.is_misaligned_pair() && !def_lrg.mask().is_misaligned_pair();
+  }
   if (!can_use)
     return 0;
 
@@ -263,18 +267,16 @@
     val = skip_copies(n->in(k));
   }
 
-  if( val == x ) return blk_adjust; // No progress?
+  if (val == x) return blk_adjust; // No progress?
 
-  bool single = is_single_register(val->ideal_reg());
+  int n_regs = RegMask::num_registers(val->ideal_reg());
   uint val_idx = n2lidx(val);
   OptoReg::Name val_reg = lrgs(val_idx).reg();
 
   // See if it happens to already be in the correct register!
   // (either Phi's direct register, or the common case of the name
   // never-clobbered original-def register)
-  if( value[val_reg] == val &&
-      // Doubles check both halves
-      ( single || value[val_reg-1] == val ) ) {
+  if (register_contains_value(val, val_reg, n_regs, value)) {
     blk_adjust += use_prior_register(n,k,regnd[val_reg],current_block,value,regnd);
     if( n->in(k) == regnd[val_reg] ) // Success!  Quit trying
       return blk_adjust;
@@ -306,9 +308,10 @@
     }
 
     Node *vv = value[reg];
-    if( !single ) {             // Doubles check for aligned-adjacent pair
-      if( (reg&1)==0 ) continue;  // Wrong half of a pair
-      if( vv != value[reg-1] ) continue; // Not a complete pair
+    if (n_regs > 1) { // Doubles and vectors check for aligned-adjacent set
+      uint last = (n_regs-1); // Looking for the last part of a set
+      if ((reg&last) != last) continue; // Wrong part of a set
+      if (!register_contains_value(vv, reg, n_regs, value)) continue; // Different value
     }
     if( vv == val ||            // Got a direct hit?
         (t && vv && vv->bottom_type() == t && vv->is_Mach() &&
@@ -526,8 +529,9 @@
       if( pidx ) {
         value.map(preg,phi);
         regnd.map(preg,phi);
-        OptoReg::Name preg_lo = OptoReg::add(preg,-1);
-        if( !is_single_register(phi->ideal_reg()) ) {
+        int n_regs = RegMask::num_registers(phi->ideal_reg());
+        for (int l = 1; l < n_regs; l++) {
+          OptoReg::Name preg_lo = OptoReg::add(preg,-l);
           value.map(preg_lo,phi);
           regnd.map(preg_lo,phi);
         }
@@ -568,13 +572,16 @@
             value.map(ureg,valdef); // record improved reaching-def info
             regnd.map(ureg,   def);
             // Record other half of doubles
-            OptoReg::Name ureg_lo = OptoReg::add(ureg,-1);
-            if( !is_single_register(def->ideal_reg()) &&
-                ( !RegMask::can_represent(ureg_lo) ||
-                  lrgs(useidx).mask().Member(ureg_lo) ) && // Nearly always adjacent
-                !value[ureg_lo] ) {
-              value.map(ureg_lo,valdef); // record improved reaching-def info
-              regnd.map(ureg_lo,   def);
+            uint def_ideal_reg = def->ideal_reg();
+            int n_regs = RegMask::num_registers(def_ideal_reg);
+            for (int l = 1; l < n_regs; l++) {
+              OptoReg::Name ureg_lo = OptoReg::add(ureg,-l);
+              if (!value[ureg_lo] &&
+                  (!RegMask::can_represent(ureg_lo) ||
+                   lrgs(useidx).mask().Member(ureg_lo))) { // Nearly always adjacent
+                value.map(ureg_lo,valdef); // record improved reaching-def info
+                regnd.map(ureg_lo,   def);
+              }
             }
           }
         }
@@ -607,7 +614,8 @@
       }
 
       uint n_ideal_reg = n->ideal_reg();
-      if( is_single_register(n_ideal_reg) ) {
+      int n_regs = RegMask::num_registers(n_ideal_reg);
+      if (n_regs == 1) {
         // If Node 'n' does not change the value mapped by the register,
         // then 'n' is a useless copy.  Do not update the register->node
         // mapping so 'n' will go dead.
@@ -625,6 +633,25 @@
           assert( n->is_Copy(), "" );
           j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
         }
+      } else if (RegMask::is_vector(n_ideal_reg)) {
+        // If Node 'n' does not change the value mapped by the register,
+        // then 'n' is a useless copy.  Do not update the register->node
+        // mapping so 'n' will go dead.
+        if (!register_contains_value(val, nreg, n_regs, value)) {
+          // Update the mapping: record new Node defined by the register
+          regnd.map(nreg,n);
+          // Update mapping for defined *value*, which is the defined
+          // Node after skipping all copies.
+          value.map(nreg,val);
+          for (int l = 1; l < n_regs; l++) {
+            OptoReg::Name nreg_lo = OptoReg::add(nreg,-l);
+            regnd.map(nreg_lo, n );
+            value.map(nreg_lo,val);
+          }
+        } else if (n->is_Copy()) {
+          // Note: vector can't be constant and can't be copy of calee.
+          j -= replace_and_yank_if_dead(n, nreg, b, value, regnd);
+        }
       } else {
         // If the value occupies a register pair, record same info
         // in both registers.
diff --git a/hotspot/src/share/vm/opto/reg_split.cpp b/hotspot/src/share/vm/opto/reg_split.cpp
index 63a11fe..e895a43 100644
--- a/hotspot/src/share/vm/opto/reg_split.cpp
+++ b/hotspot/src/share/vm/opto/reg_split.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -74,12 +74,13 @@
   const RegMask *w_i_mask = w_mask->overlap( *i_mask ) ? w_mask : i_mask;
   const RegMask *w_o_mask;
 
+  int num_regs = RegMask::num_registers(ireg);
+  bool is_vect = RegMask::is_vector(ireg);
   if( w_mask->overlap( *o_mask ) && // Overlap AND
-      ((ireg != Op_RegL && ireg != Op_RegD // Single use or aligned
-#ifdef _LP64
-        && ireg != Op_RegP
-#endif
-         ) || o_mask->is_aligned_Pairs()) ) {
+      ((num_regs == 1) // Single use or aligned
+        ||  is_vect    // or vector
+        || !is_vect && o_mask->is_aligned_pairs()) ) {
+    assert(!is_vect || o_mask->is_aligned_sets(num_regs), "vectors are aligned");
     // Don't come here for mis-aligned doubles
     w_o_mask = w_mask;
   } else {                      // wide ideal mask does not overlap with o_mask
@@ -400,15 +401,17 @@
   // CNC - Turned off 7/8/99, causes too much spilling
   // if( lrg->_is_bound ) return false;
 
+  // Use float pressure numbers for vectors.
+  bool is_float_or_vector = lrg->_is_float || lrg->_is_vector;
   // Not yet reached the high-pressure cutoff point, so low pressure
-  uint hrp_idx = lrg->_is_float ? b->_fhrp_index : b->_ihrp_index;
+  uint hrp_idx = is_float_or_vector ? b->_fhrp_index : b->_ihrp_index;
   if( insidx < hrp_idx ) return false;
   // Register pressure for the block as a whole depends on reg class
-  int block_pres = lrg->_is_float ? b->_freg_pressure : b->_reg_pressure;
+  int block_pres = is_float_or_vector ? b->_freg_pressure : b->_reg_pressure;
   // Bound live ranges will split at the binding points first;
   // Intermediate splits should assume the live range's register set
   // got "freed up" and that num_regs will become INT_PRESSURE.
-  int bound_pres = lrg->_is_float ? FLOATPRESSURE : INTPRESSURE;
+  int bound_pres = is_float_or_vector ? FLOATPRESSURE : INTPRESSURE;
   // Effective register pressure limit.
   int lrg_pres = (lrg->get_invalid_mask_size() > lrg->num_regs())
     ? (lrg->get_invalid_mask_size() >> (lrg->num_regs()-1)) : bound_pres;
@@ -446,9 +449,12 @@
 // USES: If USE is in HRP, split at use to leave main LRG on stack.
 //       Else, hoist LRG back up to register only (ie - split is also DEF)
 // We will compute a new maxlrg as we go
-uint PhaseChaitin::Split( uint maxlrg ) {
+uint PhaseChaitin::Split(uint maxlrg, ResourceArea* split_arena) {
   NOT_PRODUCT( Compile::TracePhase t3("regAllocSplit", &_t_regAllocSplit, TimeCompiler); )
 
+  // Free thread local resources used by this method on exit.
+  ResourceMark rm(split_arena);
+
   uint                 bidx, pidx, slidx, insidx, inpidx, twoidx;
   uint                 non_phi = 1, spill_cnt = 0;
   Node               **Reachblock;
@@ -458,14 +464,17 @@
   bool                 u1, u2, u3;
   Block               *b, *pred;
   PhiNode             *phi;
-  GrowableArray<uint>  lidxs;
+  GrowableArray<uint>  lidxs(split_arena, _maxlrg, 0, 0);
 
   // Array of counters to count splits per live range
-  GrowableArray<uint>  splits;
+  GrowableArray<uint>  splits(split_arena, _maxlrg, 0, 0);
+
+#define NEW_SPLIT_ARRAY(type, size)\
+  (type*) split_arena->allocate_bytes((size) * sizeof(type))
 
   //----------Setup Code----------
   // Create a convenient mapping from lrg numbers to reaches/leaves indices
-  uint *lrg2reach = NEW_RESOURCE_ARRAY( uint, _maxlrg );
+  uint *lrg2reach = NEW_SPLIT_ARRAY( uint, _maxlrg );
   // Keep track of DEFS & Phis for later passes
   defs = new Node_List();
   phis = new Node_List();
@@ -497,15 +506,15 @@
   // a Def is UP or DOWN.  UP means that it should get a register (ie -
   // it is always in LRP regions), and DOWN means that it is probably
   // on the stack (ie - it crosses HRP regions).
-  Node ***Reaches     = NEW_RESOURCE_ARRAY( Node**, _cfg._num_blocks+1 );
-  bool  **UP          = NEW_RESOURCE_ARRAY( bool*, _cfg._num_blocks+1 );
-  Node  **debug_defs  = NEW_RESOURCE_ARRAY( Node*, spill_cnt );
-  VectorSet **UP_entry= NEW_RESOURCE_ARRAY( VectorSet*, spill_cnt );
+  Node ***Reaches     = NEW_SPLIT_ARRAY( Node**, _cfg._num_blocks+1 );
+  bool  **UP          = NEW_SPLIT_ARRAY( bool*, _cfg._num_blocks+1 );
+  Node  **debug_defs  = NEW_SPLIT_ARRAY( Node*, spill_cnt );
+  VectorSet **UP_entry= NEW_SPLIT_ARRAY( VectorSet*, spill_cnt );
 
   // Initialize Reaches & UP
   for( bidx = 0; bidx < _cfg._num_blocks+1; bidx++ ) {
-    Reaches[bidx]     = NEW_RESOURCE_ARRAY( Node*, spill_cnt );
-    UP[bidx]          = NEW_RESOURCE_ARRAY( bool, spill_cnt );
+    Reaches[bidx]     = NEW_SPLIT_ARRAY( Node*, spill_cnt );
+    UP[bidx]          = NEW_SPLIT_ARRAY( bool, spill_cnt );
     Node **Reachblock = Reaches[bidx];
     bool *UPblock     = UP[bidx];
     for( slidx = 0; slidx < spill_cnt; slidx++ ) {
@@ -514,9 +523,11 @@
     }
   }
 
+#undef NEW_SPLIT_ARRAY
+
   // Initialize to array of empty vectorsets
   for( slidx = 0; slidx < spill_cnt; slidx++ )
-    UP_entry[slidx] = new VectorSet(Thread::current()->resource_area());
+    UP_entry[slidx] = new VectorSet(split_arena);
 
   //----------PASS 1----------
   //----------Propagation & Node Insertion Code----------
@@ -635,7 +646,7 @@
           // create a new phi node and insert it into the block
           // type is taken from left over pointer to a predecessor
           assert(n3,"No non-NULL reaching DEF for a Phi");
-          phi = new (C, b->num_preds()) PhiNode(b->head(), n3->bottom_type());
+          phi = new (C) PhiNode(b->head(), n3->bottom_type());
           // initialize the Reaches entry for this LRG
           Reachblock[slidx] = phi;
 
@@ -794,12 +805,15 @@
                   if( i < n->req() ) break;
                   insert_point--;
                 }
+                uint orig_eidx = b->end_idx();
                 maxlrg = split_DEF( n1, b, insert_point, maxlrg, Reachblock, debug_defs, splits, slidx);
                 // If it wasn't split bail
                 if (!maxlrg) {
                   return 0;
                 }
-                insidx++;
+                // Spill of NULL check mem op goes into the following block.
+                if (b->end_idx() > orig_eidx)
+                  insidx++;
               }
               // This is a new DEF, so update UP
               UPblock[slidx] = false;
@@ -960,7 +974,7 @@
             // Grab register mask info
             const RegMask &dmask = def->out_RegMask();
             const RegMask &umask = n->in_RegMask(inpidx);
-
+            bool is_vect = RegMask::is_vector(def->ideal_reg());
             assert(inpidx < oopoff, "cannot use-split oop map info");
 
             bool dup = UPblock[slidx];
@@ -972,7 +986,7 @@
             if( !umask.is_AllStack() &&
                 (int)umask.Size() <= lrgs(useidx).num_regs() &&
                 (!def->rematerialize() ||
-                 umask.is_misaligned_Pair())) {
+                 !is_vect && umask.is_misaligned_pair())) {
               // These need a Split regardless of overlap or pressure
               // SPLIT - NO DEF - NO CISC SPILL
               maxlrg = split_USE(def,b,n,inpidx,maxlrg,dup,false, splits,slidx);
@@ -1123,10 +1137,12 @@
         // Grab UP info for DEF
         const RegMask &dmask = n->out_RegMask();
         bool defup = dmask.is_UP();
+        int ireg = n->ideal_reg();
+        bool is_vect = RegMask::is_vector(ireg);
         // Only split at Def if this is a HRP block or bound (and spilled once)
         if( !n->rematerialize() &&
-            (((dmask.is_bound1() || dmask.is_bound2() || dmask.is_misaligned_Pair()) &&
-             (deflrg._direct_conflict || deflrg._must_spill)) ||
+            (((dmask.is_bound(ireg) || !is_vect && dmask.is_misaligned_pair()) &&
+              (deflrg._direct_conflict || deflrg._must_spill)) ||
              // Check for LRG being up in a register and we are inside a high
              // pressure area.  Spill it down immediately.
              (defup && is_high_pressure(b,&deflrg,insidx))) ) {
diff --git a/hotspot/src/share/vm/opto/regmask.cpp b/hotspot/src/share/vm/opto/regmask.cpp
index ce220f0..5941338 100644
--- a/hotspot/src/share/vm/opto/regmask.cpp
+++ b/hotspot/src/share/vm/opto/regmask.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -129,11 +129,34 @@
   0
 );
 
+//=============================================================================
+bool RegMask::is_vector(uint ireg) {
+  return (ireg == Op_VecS || ireg == Op_VecD || ireg == Op_VecX || ireg == Op_VecY);
+}
+
+int RegMask::num_registers(uint ireg) {
+    switch(ireg) {
+      case Op_VecY:
+        return 8;
+      case Op_VecX:
+        return 4;
+      case Op_VecD:
+      case Op_RegD:
+      case Op_RegL:
+#ifdef _LP64
+      case Op_RegP:
+#endif
+        return 2;
+    }
+    // Op_VecS and the rest ideal registers.
+    return 1;
+}
+
 //------------------------------find_first_pair--------------------------------
 // Find the lowest-numbered register pair in the mask.  Return the
 // HIGHEST register number in the pair, or BAD if no pairs.
 OptoReg::Name RegMask::find_first_pair() const {
-  VerifyPairs();
+  verify_pairs();
   for( int i = 0; i < RM_SIZE; i++ ) {
     if( _A[i] ) {               // Found some bits
       int bit = _A[i] & -_A[i]; // Extract low bit
@@ -146,30 +169,30 @@
 
 //------------------------------ClearToPairs-----------------------------------
 // Clear out partial bits; leave only bit pairs
-void RegMask::ClearToPairs() {
+void RegMask::clear_to_pairs() {
   for( int i = 0; i < RM_SIZE; i++ ) {
     int bits = _A[i];
     bits &= ((bits & 0x55555555)<<1); // 1 hi-bit set for each pair
     bits |= (bits>>1);          // Smear 1 hi-bit into a pair
     _A[i] = bits;
   }
-  VerifyPairs();
+  verify_pairs();
 }
 
 //------------------------------SmearToPairs-----------------------------------
 // Smear out partial bits; leave only bit pairs
-void RegMask::SmearToPairs() {
+void RegMask::smear_to_pairs() {
   for( int i = 0; i < RM_SIZE; i++ ) {
     int bits = _A[i];
     bits |= ((bits & 0x55555555)<<1); // Smear lo bit hi per pair
     bits |= ((bits & 0xAAAAAAAA)>>1); // Smear hi bit lo per pair
     _A[i] = bits;
   }
-  VerifyPairs();
+  verify_pairs();
 }
 
 //------------------------------is_aligned_pairs-------------------------------
-bool RegMask::is_aligned_Pairs() const {
+bool RegMask::is_aligned_pairs() const {
   // Assert that the register mask contains only bit pairs.
   for( int i = 0; i < RM_SIZE; i++ ) {
     int bits = _A[i];
@@ -204,7 +227,7 @@
 
 //------------------------------is_bound2--------------------------------------
 // Return TRUE if the mask contains an adjacent pair of bits and no other bits.
-int RegMask::is_bound2() const {
+int RegMask::is_bound_pair() const {
   if( is_AllStack() ) return false;
 
   int bit = -1;                 // Set to hold the one bit allowed
@@ -226,6 +249,132 @@
   return true;
 }
 
+static int low_bits[3] = { 0x55555555, 0x11111111, 0x01010101 };
+//------------------------------find_first_set---------------------------------
+// Find the lowest-numbered register set in the mask.  Return the
+// HIGHEST register number in the set, or BAD if no sets.
+// Works also for size 1.
+OptoReg::Name RegMask::find_first_set(int size) const {
+  verify_sets(size);
+  for (int i = 0; i < RM_SIZE; i++) {
+    if (_A[i]) {                // Found some bits
+      int bit = _A[i] & -_A[i]; // Extract low bit
+      // Convert to bit number, return hi bit in pair
+      return OptoReg::Name((i<<_LogWordBits)+find_lowest_bit(bit)+(size-1));
+    }
+  }
+  return OptoReg::Bad;
+}
+
+//------------------------------clear_to_sets----------------------------------
+// Clear out partial bits; leave only aligned adjacent bit pairs
+void RegMask::clear_to_sets(int size) {
+  if (size == 1) return;
+  assert(2 <= size && size <= 8, "update low bits table");
+  assert(is_power_of_2(size), "sanity");
+  int low_bits_mask = low_bits[size>>2];
+  for (int i = 0; i < RM_SIZE; i++) {
+    int bits = _A[i];
+    int sets = (bits & low_bits_mask);
+    for (int j = 1; j < size; j++) {
+      sets = (bits & (sets<<1)); // filter bits which produce whole sets
+    }
+    sets |= (sets>>1);           // Smear 1 hi-bit into a set
+    if (size > 2) {
+      sets |= (sets>>2);         // Smear 2 hi-bits into a set
+      if (size > 4) {
+        sets |= (sets>>4);       // Smear 4 hi-bits into a set
+      }
+    }
+    _A[i] = sets;
+  }
+  verify_sets(size);
+}
+
+//------------------------------smear_to_sets----------------------------------
+// Smear out partial bits to aligned adjacent bit sets
+void RegMask::smear_to_sets(int size) {
+  if (size == 1) return;
+  assert(2 <= size && size <= 8, "update low bits table");
+  assert(is_power_of_2(size), "sanity");
+  int low_bits_mask = low_bits[size>>2];
+  for (int i = 0; i < RM_SIZE; i++) {
+    int bits = _A[i];
+    int sets = 0;
+    for (int j = 0; j < size; j++) {
+      sets |= (bits & low_bits_mask);  // collect partial bits
+      bits  = bits>>1;
+    }
+    sets |= (sets<<1);           // Smear 1 lo-bit  into a set
+    if (size > 2) {
+      sets |= (sets<<2);         // Smear 2 lo-bits into a set
+      if (size > 4) {
+        sets |= (sets<<4);       // Smear 4 lo-bits into a set
+      }
+    }
+    _A[i] = sets;
+  }
+  verify_sets(size);
+}
+
+//------------------------------is_aligned_set--------------------------------
+bool RegMask::is_aligned_sets(int size) const {
+  if (size == 1) return true;
+  assert(2 <= size && size <= 8, "update low bits table");
+  assert(is_power_of_2(size), "sanity");
+  int low_bits_mask = low_bits[size>>2];
+  // Assert that the register mask contains only bit sets.
+  for (int i = 0; i < RM_SIZE; i++) {
+    int bits = _A[i];
+    while (bits) {              // Check bits for pairing
+      int bit = bits & -bits;   // Extract low bit
+      // Low bit is not odd means its mis-aligned.
+      if ((bit & low_bits_mask) == 0) return false;
+      // Do extra work since (bit << size) may overflow.
+      int hi_bit = bit << (size-1); // high bit
+      int set = hi_bit + ((hi_bit-1) & ~(bit-1));
+      // Check for aligned adjacent bits in this set
+      if ((bits & set) != set) return false;
+      bits -= set;  // Remove this set
+    }
+  }
+  return true;
+}
+
+//------------------------------is_bound_set-----------------------------------
+// Return TRUE if the mask contains one adjacent set of bits and no other bits.
+// Works also for size 1.
+int RegMask::is_bound_set(int size) const {
+  if( is_AllStack() ) return false;
+  assert(1 <= size && size <= 8, "update low bits table");
+  int bit = -1;                 // Set to hold the one bit allowed
+  for (int i = 0; i < RM_SIZE; i++) {
+    if (_A[i] ) {               // Found some bits
+      if (bit != -1)
+       return false;            // Already had bits, so fail
+      bit = _A[i] & -_A[i];     // Extract 1 bit from mask
+      int hi_bit = bit << (size-1); // high bit
+      if (hi_bit != 0) {        // Bit set stays in same word?
+        int set = hi_bit + ((hi_bit-1) & ~(bit-1));
+        if (set != _A[i])
+          return false;         // Require adjacent bit set and no more bits
+      } else {                  // Else its a split-set case
+        if (((-1) & ~(bit-1)) != _A[i])
+          return false;         // Found many bits, so fail
+        i++;                    // Skip iteration forward and check high part
+        assert(size <= 8, "update next code");
+        // The lower 24 bits should be 0 since it is split case and size <= 8.
+        int set = bit>>24;
+        set = set & -set; // Remove sign extension.
+        set = (((set << size) - 1) >> 8);
+        if (_A[i] != set) return false; // Require 1 lo bit in next word
+      }
+    }
+  }
+  // True for both the empty mask and for a bit set
+  return true;
+}
+
 //------------------------------is_UP------------------------------------------
 // UP means register only, Register plus stack, or stack only is DOWN
 bool RegMask::is_UP() const {
diff --git a/hotspot/src/share/vm/opto/regmask.hpp b/hotspot/src/share/vm/opto/regmask.hpp
index e50ff84..e4c31dc 100644
--- a/hotspot/src/share/vm/opto/regmask.hpp
+++ b/hotspot/src/share/vm/opto/regmask.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -113,7 +113,11 @@
   // the controlling alignment constraint.  Note that this alignment
   // requirement is internal to the allocator, and independent of any
   // particular platform.
-  enum { SlotsPerLong = 2 };
+  enum { SlotsPerLong = 2,
+         SlotsPerVecS = 1,
+         SlotsPerVecD = 2,
+         SlotsPerVecX = 4,
+         SlotsPerVecY = 8 };
 
   // A constructor only used by the ADLC output.  All mask fields are filled
   // in directly.  Calls to this look something like RM(1,2,3,4);
@@ -193,20 +197,53 @@
   OptoReg::Name find_first_pair() const;
 
   // Clear out partial bits; leave only aligned adjacent bit pairs.
-  void ClearToPairs();
+  void clear_to_pairs();
   // Smear out partial bits; leave only aligned adjacent bit pairs.
-  void SmearToPairs();
+  void smear_to_pairs();
   // Verify that the mask contains only aligned adjacent bit pairs
-  void VerifyPairs() const { assert( is_aligned_Pairs(), "mask is not aligned, adjacent pairs" ); }
+  void verify_pairs() const { assert( is_aligned_pairs(), "mask is not aligned, adjacent pairs" ); }
   // Test that the mask contains only aligned adjacent bit pairs
-  bool is_aligned_Pairs() const;
+  bool is_aligned_pairs() const;
 
   // mask is a pair of misaligned registers
-  bool is_misaligned_Pair() const { return Size()==2 && !is_aligned_Pairs();}
+  bool is_misaligned_pair() const { return Size()==2 && !is_aligned_pairs(); }
   // Test for single register
   int is_bound1() const;
   // Test for a single adjacent pair
-  int is_bound2() const;
+  int is_bound_pair() const;
+  // Test for a single adjacent set of ideal register's size.
+  int is_bound(uint ireg) const {
+    if (is_vector(ireg)) {
+      if (is_bound_set(num_registers(ireg)))
+        return true;
+    } else if (is_bound1() || is_bound_pair()) {
+      return true;
+    }
+    return false;
+  }
+
+  // Find the lowest-numbered register set in the mask.  Return the
+  // HIGHEST register number in the set, or BAD if no sets.
+  // Assert that the mask contains only bit sets.
+  OptoReg::Name find_first_set(int size) const;
+
+  // Clear out partial bits; leave only aligned adjacent bit sets of size.
+  void clear_to_sets(int size);
+  // Smear out partial bits to aligned adjacent bit sets.
+  void smear_to_sets(int size);
+  // Verify that the mask contains only aligned adjacent bit sets
+  void verify_sets(int size) const { assert(is_aligned_sets(size), "mask is not aligned, adjacent sets"); }
+  // Test that the mask contains only aligned adjacent bit sets
+  bool is_aligned_sets(int size) const;
+
+  // mask is a set of misaligned registers
+  bool is_misaligned_set(int size) const { return (int)Size()==size && !is_aligned_sets(size);}
+
+  // Test for a single adjacent set
+  int is_bound_set(int size) const;
+
+  static bool is_vector(uint ireg);
+  static int num_registers(uint ireg);
 
   // Fast overlap test.  Non-zero if any registers in common.
   int overlap( const RegMask &rm ) const {
@@ -280,9 +317,15 @@
 
   static bool can_represent(OptoReg::Name reg) {
     // NOTE: -1 in computation reflects the usage of the last
-    //       bit of the regmask as an infinite stack flag.
+    //       bit of the regmask as an infinite stack flag and
+    //       -7 is to keep mask aligned for largest value (VecY).
     return (int)reg < (int)(CHUNK_SIZE-1);
   }
+  static bool can_represent_arg(OptoReg::Name reg) {
+    // NOTE: -SlotsPerVecY in computation reflects the need
+    //       to keep mask aligned for largest value (VecY).
+    return (int)reg < (int)(CHUNK_SIZE-SlotsPerVecY);
+  }
 };
 
 // Do not use this constant directly in client code!
diff --git a/hotspot/src/share/vm/opto/runtime.cpp b/hotspot/src/share/vm/opto/runtime.cpp
index d315f10..e79d358 100644
--- a/hotspot/src/share/vm/opto/runtime.cpp
+++ b/hotspot/src/share/vm/opto/runtime.cpp
@@ -709,9 +709,9 @@
   return TypeFunc::make(domain, range);
 }
 
-//-------------- currentTimeMillis
+//-------------- currentTimeMillis, currentTimeNanos, etc
 
-const TypeFunc* OptoRuntime::current_time_millis_Type() {
+const TypeFunc* OptoRuntime::void_long_Type() {
   // create input type (domain)
   const Type **fields = TypeTuple::fields(0);
   const TypeTuple *domain = TypeTuple::make(TypeFunc::Parms+0, fields);
@@ -811,6 +811,48 @@
   return TypeFunc::make(domain, range);
 }
 
+// for aescrypt encrypt/decrypt operations, just three pointers returning void (length is constant)
+const TypeFunc* OptoRuntime::aescrypt_block_Type() {
+  // create input type (domain)
+  int num_args      = 3;
+  int argcnt = num_args;
+  const Type** fields = TypeTuple::fields(argcnt);
+  int argp = TypeFunc::Parms;
+  fields[argp++] = TypePtr::NOTNULL;    // src
+  fields[argp++] = TypePtr::NOTNULL;    // dest
+  fields[argp++] = TypePtr::NOTNULL;    // k array
+  assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
+  const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
+
+  // no result type needed
+  fields = TypeTuple::fields(1);
+  fields[TypeFunc::Parms+0] = NULL; // void
+  const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
+  return TypeFunc::make(domain, range);
+}
+
+// for cipherBlockChaining calls of aescrypt encrypt/decrypt, four pointers and a length, returning void
+const TypeFunc* OptoRuntime::cipherBlockChaining_aescrypt_Type() {
+  // create input type (domain)
+  int num_args      = 5;
+  int argcnt = num_args;
+  const Type** fields = TypeTuple::fields(argcnt);
+  int argp = TypeFunc::Parms;
+  fields[argp++] = TypePtr::NOTNULL;    // src
+  fields[argp++] = TypePtr::NOTNULL;    // dest
+  fields[argp++] = TypePtr::NOTNULL;    // k array
+  fields[argp++] = TypePtr::NOTNULL;    // r array
+  fields[argp++] = TypeInt::INT;        // src len
+  assert(argp == TypeFunc::Parms+argcnt, "correct decoding");
+  const TypeTuple* domain = TypeTuple::make(TypeFunc::Parms+argcnt, fields);
+
+  // no result type needed
+  fields = TypeTuple::fields(1);
+  fields[TypeFunc::Parms+0] = NULL; // void
+  const TypeTuple* range = TypeTuple::make(TypeFunc::Parms, fields);
+  return TypeFunc::make(domain, range);
+}
+
 //------------- Interpreter state access for on stack replacement
 const TypeFunc* OptoRuntime::osr_end_Type() {
   // create input type (domain)
@@ -880,46 +922,6 @@
   }
 JRT_END
 
-//-----------------------------------------------------------------------------
-// implicit exception support.
-
-static void report_null_exception_in_code_cache(address exception_pc) {
-  ResourceMark rm;
-  CodeBlob* n = CodeCache::find_blob(exception_pc);
-  if (n != NULL) {
-    tty->print_cr("#");
-    tty->print_cr("# HotSpot Runtime Error, null exception in generated code");
-    tty->print_cr("#");
-    tty->print_cr("# pc where exception happened = " INTPTR_FORMAT, exception_pc);
-
-    if (n->is_nmethod()) {
-      methodOop method = ((nmethod*)n)->method();
-      tty->print_cr("# Method where it happened %s.%s ", Klass::cast(method->method_holder())->name()->as_C_string(), method->name()->as_C_string());
-      tty->print_cr("#");
-      if (ShowMessageBoxOnError && UpdateHotSpotCompilerFileOnError &&
-          CompilerOracle::has_command_file()) {
-        const char* title    = "HotSpot Runtime Error";
-        const char* question = "Do you want to exclude compilation of this method in future runs?";
-        if (os::message_box(title, question)) {
-          CompilerOracle::append_comment_to_file("");
-          CompilerOracle::append_comment_to_file("Null exception in compiled code resulted in the following exclude");
-          CompilerOracle::append_comment_to_file("");
-          CompilerOracle::append_exclude_to_file(method);
-          tty->print_cr("#");
-          tty->print_cr("# %s has been updated to exclude the specified method", CompileCommandFile);
-          tty->print_cr("#");
-        }
-      }
-      fatal("Implicit null exception happened in compiled method");
-    } else {
-      n->print();
-      fatal("Implicit null exception happened in generated stub");
-    }
-  }
-  fatal("Implicit null exception at wrong place");
-}
-
-
 //-------------------------------------------------------------------------------------
 // register policy
 
diff --git a/hotspot/src/share/vm/opto/runtime.hpp b/hotspot/src/share/vm/opto/runtime.hpp
index 3970298..b370231 100644
--- a/hotspot/src/share/vm/opto/runtime.hpp
+++ b/hotspot/src/share/vm/opto/runtime.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -55,7 +55,7 @@
 // code in various ways.  Currently they are used by the lock coarsening code
 //
 
-class NamedCounter : public CHeapObj {
+class NamedCounter : public CHeapObj<mtCompiler> {
 public:
     enum CounterTag {
     NoTag,
@@ -268,7 +268,7 @@
   static const TypeFunc* Math_DD_D_Type(); // mod,pow & friends
   static const TypeFunc* modf_Type();
   static const TypeFunc* l2f_Type();
-  static const TypeFunc* current_time_millis_Type();
+  static const TypeFunc* void_long_Type();
 
   static const TypeFunc* flush_windows_Type();
 
@@ -280,6 +280,9 @@
 
   static const TypeFunc* array_fill_Type();
 
+  static const TypeFunc* aescrypt_block_Type();
+  static const TypeFunc* cipherBlockChaining_aescrypt_Type();
+
   // leaf on stack replacement interpreter accessor types
   static const TypeFunc* osr_end_Type();
 
diff --git a/hotspot/src/share/vm/opto/split_if.cpp b/hotspot/src/share/vm/opto/split_if.cpp
index 55de3d7..c2f89df 100644
--- a/hotspot/src/share/vm/opto/split_if.cpp
+++ b/hotspot/src/share/vm/opto/split_if.cpp
@@ -35,7 +35,7 @@
   uint wins = 0;
   assert( n->is_CFG(), "" );
   assert( region->is_Region(), "" );
-  Node *r = new (C, region->req()) RegionNode( region->req() );
+  Node *r = new (C) RegionNode( region->req() );
   IdealLoopTree *loop = get_loop( n );
   for( uint i = 1; i < region->req(); i++ ) {
     Node *x = n->clone();
@@ -137,9 +137,7 @@
             Node *iff_ctrl = iff->is_If() ? iff->in(0) : get_ctrl(iff);
             Node *x = bol->clone();
             register_new_node(x, iff_ctrl);
-            _igvn.hash_delete(iff);
-            iff->set_req(1, x);
-            _igvn._worklist.push(iff);
+            _igvn.replace_input_of(iff, 1, x);
           }
           _igvn.remove_dead_node( bol );
           --i;
@@ -151,9 +149,7 @@
         assert( bol->in(1) == n, "" );
         Node *x = n->clone();
         register_new_node(x, get_ctrl(bol));
-        _igvn.hash_delete(bol);
-        bol->set_req(1, x);
-        _igvn._worklist.push(bol);
+        _igvn.replace_input_of(bol, 1, x);
       }
       _igvn.remove_dead_node( n );
 
@@ -387,9 +383,7 @@
     if( use->in(i) == def )
       break;
   assert( i < use->req(), "def should be among use's inputs" );
-  _igvn.hash_delete(use);
-  use->set_req(i, new_def);
-  _igvn._worklist.push(use);
+  _igvn.replace_input_of(use, i, new_def);
 }
 
 //------------------------------do_split_if------------------------------------
diff --git a/hotspot/src/share/vm/opto/stringopts.cpp b/hotspot/src/share/vm/opto/stringopts.cpp
index 2f8c0f1..6be806a 100644
--- a/hotspot/src/share/vm/opto/stringopts.cpp
+++ b/hotspot/src/share/vm/opto/stringopts.cpp
@@ -69,7 +69,7 @@
     _multiple(false),
     _string_alloc(NULL),
     _stringopts(stringopts) {
-    _arguments = new (_stringopts->C, 1) Node(1);
+    _arguments = new (_stringopts->C) Node(1);
     _arguments->del_req(0);
   }
 
@@ -220,11 +220,10 @@
       // Build a new call using the jvms state of the allocate
       address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point();
       const TypeFunc* call_type = OptoRuntime::uncommon_trap_Type();
-      int size = call_type->domain()->cnt();
       const TypePtr* no_memory_effects = NULL;
       Compile* C = _stringopts->C;
-      CallStaticJavaNode* call = new (C, size) CallStaticJavaNode(call_type, call_addr, "uncommon_trap",
-                                                                  jvms->bci(), no_memory_effects);
+      CallStaticJavaNode* call = new (C) CallStaticJavaNode(call_type, call_addr, "uncommon_trap",
+                                                            jvms->bci(), no_memory_effects);
       for (int e = 0; e < TypeFunc::Parms; e++) {
         call->init_req(e, uct->in(e));
       }
@@ -533,7 +532,17 @@
         if (arg->is_Proj() && arg->in(0)->is_CallStaticJava()) {
           CallStaticJavaNode* csj = arg->in(0)->as_CallStaticJava();
           if (csj->method() != NULL &&
-              csj->method()->intrinsic_id() == vmIntrinsics::_Integer_toString) {
+              csj->method()->intrinsic_id() == vmIntrinsics::_Integer_toString &&
+              arg->outcnt() == 1) {
+            // _control is the list of StringBuilder calls nodes which
+            // will be replaced by new String code after this optimization.
+            // Integer::toString() call is not part of StringBuilder calls
+            // chain. It could be eliminated only if its result is used
+            // only by this SB calls chain.
+            // Another limitation: it should be used only once because
+            // it is unknown that it is used only by this SB calls chain
+            // until all related SB calls nodes are collected.
+            assert(arg->unique_out() == cnode, "sanity");
             sc->add_control(csj);
             sc->push_int(csj->in(TypeFunc::Parms));
             continue;
@@ -929,8 +938,8 @@
 }
 
 Node* PhaseStringOpts::fetch_static_field(GraphKit& kit, ciField* field) {
-  const TypeKlassPtr* klass_type = TypeKlassPtr::make(field->holder());
-  Node* klass_node = __ makecon(klass_type);
+  const TypeInstPtr* mirror_type = TypeInstPtr::make(field->holder()->java_mirror());
+  Node* klass_node = __ makecon(mirror_type);
   BasicType bt = field->layout_type();
   ciType* field_klass = field->type();
 
@@ -945,6 +954,7 @@
       // and may yield a vacuous result if the field is of interface type.
       type = TypeOopPtr::make_from_constant(con, true)->isa_oopptr();
       assert(type != NULL, "field singleton type must be consistent");
+      return __ makecon(type);
     } else {
       type = TypeOopPtr::make_from_klass(field_klass->as_klass());
     }
@@ -954,13 +964,13 @@
 
   return kit.make_load(NULL, kit.basic_plus_adr(klass_node, field->offset_in_bytes()),
                        type, T_OBJECT,
-                       C->get_alias_index(klass_type->add_offset(field->offset_in_bytes())));
+                       C->get_alias_index(mirror_type->add_offset(field->offset_in_bytes())));
 }
 
 Node* PhaseStringOpts::int_stringSize(GraphKit& kit, Node* arg) {
-  RegionNode *final_merge = new (C, 3) RegionNode(3);
+  RegionNode *final_merge = new (C) RegionNode(3);
   kit.gvn().set_type(final_merge, Type::CONTROL);
-  Node* final_size = new (C, 3) PhiNode(final_merge, TypeInt::INT);
+  Node* final_size = new (C) PhiNode(final_merge, TypeInt::INT);
   kit.gvn().set_type(final_size, TypeInt::INT);
 
   IfNode* iff = kit.create_and_map_if(kit.control(),
@@ -977,11 +987,11 @@
   } else {
 
     // int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
-    RegionNode *r = new (C, 3) RegionNode(3);
+    RegionNode *r = new (C) RegionNode(3);
     kit.gvn().set_type(r, Type::CONTROL);
-    Node *phi = new (C, 3) PhiNode(r, TypeInt::INT);
+    Node *phi = new (C) PhiNode(r, TypeInt::INT);
     kit.gvn().set_type(phi, TypeInt::INT);
-    Node *size = new (C, 3) PhiNode(r, TypeInt::INT);
+    Node *size = new (C) PhiNode(r, TypeInt::INT);
     kit.gvn().set_type(size, TypeInt::INT);
     Node* chk = __ CmpI(arg, __ intcon(0));
     Node* p = __ Bool(chk, BoolTest::lt);
@@ -1006,11 +1016,11 @@
     // Add loop predicate first.
     kit.add_predicate();
 
-    RegionNode *loop = new (C, 3) RegionNode(3);
+    RegionNode *loop = new (C) RegionNode(3);
     loop->init_req(1, kit.control());
     kit.gvn().set_type(loop, Type::CONTROL);
 
-    Node *index = new (C, 3) PhiNode(loop, TypeInt::INT);
+    Node *index = new (C) PhiNode(loop, TypeInt::INT);
     index->init_req(1, __ intcon(0));
     kit.gvn().set_type(index, TypeInt::INT);
     kit.set_control(loop);
@@ -1043,7 +1053,7 @@
 }
 
 void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, Node* start, Node* end) {
-  RegionNode *final_merge = new (C, 4) RegionNode(4);
+  RegionNode *final_merge = new (C) RegionNode(4);
   kit.gvn().set_type(final_merge, Type::CONTROL);
   Node *final_mem = PhiNode::make(final_merge, kit.memory(char_adr_idx), Type::MEMORY, TypeAryPtr::CHARS);
   kit.gvn().set_type(final_mem, Type::MEMORY);
@@ -1093,11 +1103,11 @@
                                         __ Bool(__ CmpI(arg, __ intcon(0)), BoolTest::lt),
                                         PROB_FAIR, COUNT_UNKNOWN);
 
-    RegionNode *merge = new (C, 3) RegionNode(3);
+    RegionNode *merge = new (C) RegionNode(3);
     kit.gvn().set_type(merge, Type::CONTROL);
-    i = new (C, 3) PhiNode(merge, TypeInt::INT);
+    i = new (C) PhiNode(merge, TypeInt::INT);
     kit.gvn().set_type(i, TypeInt::INT);
-    sign = new (C, 3) PhiNode(merge, TypeInt::INT);
+    sign = new (C) PhiNode(merge, TypeInt::INT);
     kit.gvn().set_type(sign, TypeInt::INT);
 
     merge->init_req(1, __ IfTrue(iff));
@@ -1126,10 +1136,10 @@
     // Add loop predicate first.
     kit.add_predicate();
 
-    RegionNode *head = new (C, 3) RegionNode(3);
+    RegionNode *head = new (C) RegionNode(3);
     head->init_req(1, kit.control());
     kit.gvn().set_type(head, Type::CONTROL);
-    Node *i_phi = new (C, 3) PhiNode(head, TypeInt::INT);
+    Node *i_phi = new (C) PhiNode(head, TypeInt::INT);
     i_phi->init_req(1, i);
     kit.gvn().set_type(i_phi, TypeInt::INT);
     charPos = PhiNode::make(head, charPos);
@@ -1250,7 +1260,7 @@
   // as a shim for the insertion of the new code.
   JVMState* jvms     = sc->begin()->jvms()->clone_shallow(C);
   uint size = sc->begin()->req();
-  SafePointNode* map = new (C, size) SafePointNode(size, jvms);
+  SafePointNode* map = new (C) SafePointNode(size, jvms);
 
   // copy the control and memory state from the final call into our
   // new starting state.  This allows any preceeding tests to feed
@@ -1295,12 +1305,12 @@
 
   // Create a region for the overflow checks to merge into.
   int args = MAX2(sc->num_arguments(), 1);
-  RegionNode* overflow = new (C, args) RegionNode(args);
+  RegionNode* overflow = new (C) RegionNode(args);
   kit.gvn().set_type(overflow, Type::CONTROL);
 
   // Create a hook node to hold onto the individual sizes since they
   // are need for the copying phase.
-  Node* string_sizes = new (C, args) Node(args);
+  Node* string_sizes = new (C) Node(args);
 
   Node* length = __ intcon(0);
   for (int argi = 0; argi < sc->num_arguments(); argi++) {
@@ -1344,9 +1354,9 @@
         } else if (!type->higher_equal(TypeInstPtr::NOTNULL)) {
           // s = s != null ? s : "null";
           // length = length + (s.count - s.offset);
-          RegionNode *r = new (C, 3) RegionNode(3);
+          RegionNode *r = new (C) RegionNode(3);
           kit.gvn().set_type(r, Type::CONTROL);
-          Node *phi = new (C, 3) PhiNode(r, type);
+          Node *phi = new (C) PhiNode(r, type);
           kit.gvn().set_type(phi, phi->bottom_type());
           Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
           IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
diff --git a/hotspot/src/share/vm/opto/subnode.cpp b/hotspot/src/share/vm/opto/subnode.cpp
index 51212cf..66fcdf5 100644
--- a/hotspot/src/share/vm/opto/subnode.cpp
+++ b/hotspot/src/share/vm/opto/subnode.cpp
@@ -149,7 +149,7 @@
   if( t2->base() == Type::Int ){        // Might be bottom or top...
     const TypeInt *i = t2->is_int();
     if( i->is_con() )
-      return new (phase->C, 3) AddINode(in1, phase->intcon(-i->get_con()));
+      return new (phase->C) AddINode(in1, phase->intcon(-i->get_con()));
   }
 
   // Convert "(x+c0) - y" into (x-y) + c0"
@@ -158,8 +158,8 @@
   if( op1 == Op_AddI && ok_to_convert(in1, in2) ) {
     const Type *tadd = phase->type( in1->in(2) );
     if( tadd->singleton() && tadd != Type::TOP ) {
-      Node *sub2 = phase->transform( new (phase->C, 3) SubINode( in1->in(1), in2 ));
-      return new (phase->C, 3) AddINode( sub2, in1->in(2) );
+      Node *sub2 = phase->transform( new (phase->C) SubINode( in1->in(1), in2 ));
+      return new (phase->C) AddINode( sub2, in1->in(2) );
     }
   }
 
@@ -171,9 +171,9 @@
     Node* in22 = in2->in(2);
     const TypeInt* tcon = phase->type(in22)->isa_int();
     if (tcon != NULL && tcon->is_con()) {
-      Node* sub2 = phase->transform( new (phase->C, 3) SubINode(in1, in21) );
+      Node* sub2 = phase->transform( new (phase->C) SubINode(in1, in21) );
       Node* neg_c0 = phase->intcon(- tcon->get_con());
-      return new (phase->C, 3) AddINode(sub2, neg_c0);
+      return new (phase->C) AddINode(sub2, neg_c0);
     }
   }
 
@@ -191,47 +191,47 @@
   // Convert "x - (x+y)" into "-y"
   if( op2 == Op_AddI &&
       phase->eqv( in1, in2->in(1) ) )
-    return new (phase->C, 3) SubINode( phase->intcon(0),in2->in(2));
+    return new (phase->C) SubINode( phase->intcon(0),in2->in(2));
   // Convert "(x-y) - x" into "-y"
   if( op1 == Op_SubI &&
       phase->eqv( in1->in(1), in2 ) )
-    return new (phase->C, 3) SubINode( phase->intcon(0),in1->in(2));
+    return new (phase->C) SubINode( phase->intcon(0),in1->in(2));
   // Convert "x - (y+x)" into "-y"
   if( op2 == Op_AddI &&
       phase->eqv( in1, in2->in(2) ) )
-    return new (phase->C, 3) SubINode( phase->intcon(0),in2->in(1));
+    return new (phase->C) SubINode( phase->intcon(0),in2->in(1));
 
   // Convert "0 - (x-y)" into "y-x"
   if( t1 == TypeInt::ZERO && op2 == Op_SubI )
-    return new (phase->C, 3) SubINode( in2->in(2), in2->in(1) );
+    return new (phase->C) SubINode( in2->in(2), in2->in(1) );
 
   // Convert "0 - (x+con)" into "-con-x"
   jint con;
   if( t1 == TypeInt::ZERO && op2 == Op_AddI &&
       (con = in2->in(2)->find_int_con(0)) != 0 )
-    return new (phase->C, 3) SubINode( phase->intcon(-con), in2->in(1) );
+    return new (phase->C) SubINode( phase->intcon(-con), in2->in(1) );
 
   // Convert "(X+A) - (X+B)" into "A - B"
   if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(1) )
-    return new (phase->C, 3) SubINode( in1->in(2), in2->in(2) );
+    return new (phase->C) SubINode( in1->in(2), in2->in(2) );
 
   // Convert "(A+X) - (B+X)" into "A - B"
   if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(2) )
-    return new (phase->C, 3) SubINode( in1->in(1), in2->in(1) );
+    return new (phase->C) SubINode( in1->in(1), in2->in(1) );
 
   // Convert "(A+X) - (X+B)" into "A - B"
   if( op1 == Op_AddI && op2 == Op_AddI && in1->in(2) == in2->in(1) )
-    return new (phase->C, 3) SubINode( in1->in(1), in2->in(2) );
+    return new (phase->C) SubINode( in1->in(1), in2->in(2) );
 
   // Convert "(X+A) - (B+X)" into "A - B"
   if( op1 == Op_AddI && op2 == Op_AddI && in1->in(1) == in2->in(2) )
-    return new (phase->C, 3) SubINode( in1->in(2), in2->in(1) );
+    return new (phase->C) SubINode( in1->in(2), in2->in(1) );
 
   // Convert "A-(B-C)" into (A+C)-B", since add is commutative and generally
   // nicer to optimize than subtract.
   if( op2 == Op_SubI && in2->outcnt() == 1) {
-    Node *add1 = phase->transform( new (phase->C, 3) AddINode( in1, in2->in(2) ) );
-    return new (phase->C, 3) SubINode( add1, in2->in(1) );
+    Node *add1 = phase->transform( new (phase->C) AddINode( in1, in2->in(2) ) );
+    return new (phase->C) SubINode( add1, in2->in(1) );
   }
 
   return NULL;
@@ -278,7 +278,7 @@
   // Convert "x-c0" into "x+ -c0".
   if( i &&                      // Might be bottom or top...
       i->is_con() )
-    return new (phase->C, 3) AddLNode(in1, phase->longcon(-i->get_con()));
+    return new (phase->C) AddLNode(in1, phase->longcon(-i->get_con()));
 
   // Convert "(x+c0) - y" into (x-y) + c0"
   // Do not collapse (x+c0)-y if "+" is a loop increment or
@@ -287,8 +287,8 @@
     Node *in11 = in1->in(1);
     const Type *tadd = phase->type( in1->in(2) );
     if( tadd->singleton() && tadd != Type::TOP ) {
-      Node *sub2 = phase->transform( new (phase->C, 3) SubLNode( in11, in2 ));
-      return new (phase->C, 3) AddLNode( sub2, in1->in(2) );
+      Node *sub2 = phase->transform( new (phase->C) SubLNode( in11, in2 ));
+      return new (phase->C) AddLNode( sub2, in1->in(2) );
     }
   }
 
@@ -299,9 +299,9 @@
     Node* in22 = in2->in(2);
     const TypeLong* tcon = phase->type(in22)->isa_long();
     if (tcon != NULL && tcon->is_con()) {
-      Node* sub2 = phase->transform( new (phase->C, 3) SubLNode(in1, in21) );
+      Node* sub2 = phase->transform( new (phase->C) SubLNode(in1, in21) );
       Node* neg_c0 = phase->longcon(- tcon->get_con());
-      return new (phase->C, 3) AddLNode(sub2, neg_c0);
+      return new (phase->C) AddLNode(sub2, neg_c0);
     }
   }
 
@@ -319,28 +319,28 @@
   // Convert "x - (x+y)" into "-y"
   if( op2 == Op_AddL &&
       phase->eqv( in1, in2->in(1) ) )
-    return new (phase->C, 3) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2));
+    return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO), in2->in(2));
   // Convert "x - (y+x)" into "-y"
   if( op2 == Op_AddL &&
       phase->eqv( in1, in2->in(2) ) )
-    return new (phase->C, 3) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1));
+    return new (phase->C) SubLNode( phase->makecon(TypeLong::ZERO),in2->in(1));
 
   // Convert "0 - (x-y)" into "y-x"
   if( phase->type( in1 ) == TypeLong::ZERO && op2 == Op_SubL )
-    return new (phase->C, 3) SubLNode( in2->in(2), in2->in(1) );
+    return new (phase->C) SubLNode( in2->in(2), in2->in(1) );
 
   // Convert "(X+A) - (X+B)" into "A - B"
   if( op1 == Op_AddL && op2 == Op_AddL && in1->in(1) == in2->in(1) )
-    return new (phase->C, 3) SubLNode( in1->in(2), in2->in(2) );
+    return new (phase->C) SubLNode( in1->in(2), in2->in(2) );
 
   // Convert "(A+X) - (B+X)" into "A - B"
   if( op1 == Op_AddL && op2 == Op_AddL && in1->in(2) == in2->in(2) )
-    return new (phase->C, 3) SubLNode( in1->in(1), in2->in(1) );
+    return new (phase->C) SubLNode( in1->in(1), in2->in(1) );
 
   // Convert "A-(B-C)" into (A+C)-B"
   if( op2 == Op_SubL && in2->outcnt() == 1) {
-    Node *add1 = phase->transform( new (phase->C, 3) AddLNode( in1, in2->in(2) ) );
-    return new (phase->C, 3) SubLNode( add1, in2->in(1) );
+    Node *add1 = phase->transform( new (phase->C) AddLNode( in1, in2->in(2) ) );
+    return new (phase->C) SubLNode( add1, in2->in(1) );
   }
 
   return NULL;
@@ -407,7 +407,7 @@
     // Convert "x - (x+y)" into "-y"
     if( in(2)->is_Add() &&
         phase->eqv(in(1),in(2)->in(1) ) )
-      return new (phase->C, 3) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2));
+      return new (phase->C) SubFNode( phase->makecon(TypeF::ZERO),in(2)->in(2));
   }
 
   // Cannot replace 0.0-X with -X because a 'fsub' bytecode computes
@@ -450,7 +450,7 @@
     // Convert "x - (x+y)" into "-y"
     if( in(2)->is_Add() &&
         phase->eqv(in(1),in(2)->in(1) ) )
-      return new (phase->C, 3) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2));
+      return new (phase->C) SubDNode( phase->makecon(TypeD::ZERO),in(2)->in(2));
   }
 
   // Cannot replace 0.0-X with -X because a 'dsub' bytecode computes
@@ -554,9 +554,7 @@
       return TypeInt::CC_GE;
     } else if (hi0 <= lo1) {
       // Check for special case in Hashtable::get.  (See below.)
-      if ((jint)lo0 >= 0 && (jint)lo1 >= 0 &&
-          in(1)->Opcode() == Op_ModI &&
-          in(1)->in(2) == in(2) )
+      if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check())
         return TypeInt::CC_LT;
       return TypeInt::CC_LE;
     }
@@ -567,23 +565,27 @@
   // to be positive.
   // (This is a gross hack, since the sub method never
   // looks at the structure of the node in any other case.)
-  if ((jint)lo0 >= 0 && (jint)lo1 >= 0 &&
-      in(1)->Opcode() == Op_ModI &&
-      in(1)->in(2)->uncast() == in(2)->uncast())
+  if ((jint)lo0 >= 0 && (jint)lo1 >= 0 && is_index_range_check())
     return TypeInt::CC_LT;
   return TypeInt::CC;                   // else use worst case results
 }
 
+bool CmpUNode::is_index_range_check() const {
+  // Check for the "(X ModI Y) CmpU Y" shape
+  return (in(1)->Opcode() == Op_ModI &&
+          in(1)->in(2)->eqv_uncast(in(2)));
+}
+
 //------------------------------Idealize---------------------------------------
 Node *CmpINode::Ideal( PhaseGVN *phase, bool can_reshape ) {
   if (phase->type(in(2))->higher_equal(TypeInt::ZERO)) {
     switch (in(1)->Opcode()) {
     case Op_CmpL3:              // Collapse a CmpL3/CmpI into a CmpL
-      return new (phase->C, 3) CmpLNode(in(1)->in(1),in(1)->in(2));
+      return new (phase->C) CmpLNode(in(1)->in(1),in(1)->in(2));
     case Op_CmpF3:              // Collapse a CmpF3/CmpI into a CmpF
-      return new (phase->C, 3) CmpFNode(in(1)->in(1),in(1)->in(2));
+      return new (phase->C) CmpFNode(in(1)->in(1),in(1)->in(2));
     case Op_CmpD3:              // Collapse a CmpD3/CmpI into a CmpD
-      return new (phase->C, 3) CmpDNode(in(1)->in(1),in(1)->in(2));
+      return new (phase->C) CmpDNode(in(1)->in(1),in(1)->in(2));
     //case Op_SubI:
       // If (x - y) cannot overflow, then ((x - y) <?> 0)
       // can be turned into (x <?> y).
@@ -702,12 +704,84 @@
     return TypeInt::CC;
 }
 
+static inline Node* isa_java_mirror_load(PhaseGVN* phase, Node* n) {
+  // Return the klass node for
+  //   LoadP(AddP(foo:Klass, #java_mirror))
+  //   or NULL if not matching.
+  if (n->Opcode() != Op_LoadP) return NULL;
+
+  const TypeInstPtr* tp = phase->type(n)->isa_instptr();
+  if (!tp || tp->klass() != phase->C->env()->Class_klass()) return NULL;
+
+  Node* adr = n->in(MemNode::Address);
+  intptr_t off = 0;
+  Node* k = AddPNode::Ideal_base_and_offset(adr, phase, off);
+  if (k == NULL)  return NULL;
+  const TypeKlassPtr* tkp = phase->type(k)->isa_klassptr();
+  if (!tkp || off != in_bytes(Klass::java_mirror_offset())) return NULL;
+
+  // We've found the klass node of a Java mirror load.
+  return k;
+}
+
+static inline Node* isa_const_java_mirror(PhaseGVN* phase, Node* n) {
+  // for ConP(Foo.class) return ConP(Foo.klass)
+  // otherwise return NULL
+  if (!n->is_Con()) return NULL;
+
+  const TypeInstPtr* tp = phase->type(n)->isa_instptr();
+  if (!tp) return NULL;
+
+  ciType* mirror_type = tp->java_mirror_type();
+  // TypeInstPtr::java_mirror_type() returns non-NULL for compile-
+  // time Class constants only.
+  if (!mirror_type) return NULL;
+
+  // x.getClass() == int.class can never be true (for all primitive types)
+  // Return a ConP(NULL) node for this case.
+  if (mirror_type->is_classless()) {
+    return phase->makecon(TypePtr::NULL_PTR);
+  }
+
+  // return the ConP(Foo.klass)
+  assert(mirror_type->is_klass(), "mirror_type should represent a klassOop");
+  return phase->makecon(TypeKlassPtr::make(mirror_type->as_klass()));
+}
+
 //------------------------------Ideal------------------------------------------
-// Check for the case of comparing an unknown klass loaded from the primary
+// Normalize comparisons between Java mirror loads to compare the klass instead.
+//
+// Also check for the case of comparing an unknown klass loaded from the primary
 // super-type array vs a known klass with no subtypes.  This amounts to
 // checking to see an unknown klass subtypes a known klass with no subtypes;
 // this only happens on an exact match.  We can shorten this test by 1 load.
 Node *CmpPNode::Ideal( PhaseGVN *phase, bool can_reshape ) {
+  // Normalize comparisons between Java mirrors into comparisons of the low-
+  // level klass, where a dependent load could be shortened.
+  //
+  // The new pattern has a nice effect of matching the same pattern used in the
+  // fast path of instanceof/checkcast/Class.isInstance(), which allows
+  // redundant exact type check be optimized away by GVN.
+  // For example, in
+  //   if (x.getClass() == Foo.class) {
+  //     Foo foo = (Foo) x;
+  //     // ... use a ...
+  //   }
+  // a CmpPNode could be shared between if_acmpne and checkcast
+  {
+    Node* k1 = isa_java_mirror_load(phase, in(1));
+    Node* k2 = isa_java_mirror_load(phase, in(2));
+    Node* conk2 = isa_const_java_mirror(phase, in(2));
+
+    if (k1 && (k2 || conk2)) {
+      Node* lhs = k1;
+      Node* rhs = (k2 != NULL) ? k2 : conk2;
+      this->set_req(1, lhs);
+      this->set_req(2, rhs);
+      return this;
+    }
+  }
+
   // Constant pointer on right?
   const TypeKlassPtr* t2 = phase->type(in(2))->isa_klassptr();
   if (t2 == NULL || !t2->klass_is_exact())
@@ -953,8 +1027,8 @@
         new_in2 = tmp;
       }
       CmpFNode *new_cmp = (Opcode() == Op_CmpD3)
-        ? new (phase->C, 3) CmpF3Node( new_in1, new_in2 )
-        : new (phase->C, 3) CmpFNode ( new_in1, new_in2 ) ;
+        ? new (phase->C) CmpF3Node( new_in1, new_in2 )
+        : new (phase->C) CmpFNode ( new_in1, new_in2 ) ;
       return new_cmp;           // Changed to CmpFNode
     }
     // Testing value required the precision of a double
@@ -1015,7 +1089,7 @@
   ncmp->set_req(1,cmp1);
   ncmp->set_req(2,cmp2);
   ncmp = gvn->transform( ncmp );
-  return new (gvn->C, 2) BoolNode( ncmp, test );
+  return new (gvn->C) BoolNode( ncmp, test );
 }
 
 //-------------------------------make_predicate--------------------------------
@@ -1036,9 +1110,9 @@
     // Else fall through.  The CMove gets in the way of the test.
     // It should be the case that make_predicate(bol->as_int_value()) == bol.
   }
-  Node* cmp = new (C, 3) CmpINode(test_value, phase->intcon(0));
+  Node* cmp = new (C) CmpINode(test_value, phase->intcon(0));
   cmp = phase->transform(cmp);
-  Node* bol = new (C, 2) BoolNode(cmp, BoolTest::ne);
+  Node* bol = new (C) BoolNode(cmp, BoolTest::ne);
   return phase->transform(bol);
 }
 
@@ -1054,7 +1128,7 @@
 //----------------------------------negate-------------------------------------
 BoolNode* BoolNode::negate(PhaseGVN* phase) {
   Compile* C = phase->C;
-  return new (C, 2) BoolNode(in(1), _test.negate());
+  return new (C) BoolNode(in(1), _test.negate());
 }
 
 
@@ -1088,7 +1162,7 @@
     // Swap inputs to the clone
     cmp->swap_edges(1, 2);
     cmp = phase->transform( cmp );
-    return new (phase->C, 2) BoolNode( cmp, _test.commute() );
+    return new (phase->C) BoolNode( cmp, _test.commute() );
   }
 
   // Change "bool eq/ne (cmp (xor X 1) 0)" into "bool ne/eq (cmp X 0)".
@@ -1105,8 +1179,8 @@
       phase->type( j_xor->in(2) ) == TypeInt::ONE &&
       (_test._test == BoolTest::eq ||
        _test._test == BoolTest::ne) ) {
-    Node *ncmp = phase->transform(new (phase->C, 3) CmpINode(j_xor->in(1),cmp2));
-    return new (phase->C, 2) BoolNode( ncmp, _test.negate() );
+    Node *ncmp = phase->transform(new (phase->C) CmpINode(j_xor->in(1),cmp2));
+    return new (phase->C) BoolNode( ncmp, _test.negate() );
   }
 
   // Change "bool eq/ne (cmp (Conv2B X) 0)" into "bool eq/ne (cmp X 0)".
@@ -1117,10 +1191,10 @@
       (_test._test == BoolTest::eq ||
        _test._test == BoolTest::ne) ) {
     Node *ncmp = phase->transform(phase->type(c2b->in(1))->isa_int()
-       ? (Node*)new (phase->C, 3) CmpINode(c2b->in(1),cmp2)
-       : (Node*)new (phase->C, 3) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR))
+       ? (Node*)new (phase->C) CmpINode(c2b->in(1),cmp2)
+       : (Node*)new (phase->C) CmpPNode(c2b->in(1),phase->makecon(TypePtr::NULL_PTR))
     );
-    return new (phase->C, 2) BoolNode( ncmp, _test._test );
+    return new (phase->C) BoolNode( ncmp, _test._test );
   }
 
   // Comparing a SubI against a zero is equal to comparing the SubI
@@ -1130,8 +1204,8 @@
         (cop == Op_CmpI) &&
         (cmp1->Opcode() == Op_SubI) &&
         ( cmp2_type == TypeInt::ZERO ) ) {
-    Node *ncmp = phase->transform( new (phase->C, 3) CmpINode(cmp1->in(1),cmp1->in(2)));
-    return new (phase->C, 2) BoolNode( ncmp, _test._test );
+    Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(1),cmp1->in(2)));
+    return new (phase->C) BoolNode( ncmp, _test._test );
   }
 
   // Change (-A vs 0) into (A vs 0) by commuting the test.  Disallow in the
@@ -1142,8 +1216,8 @@
       cmp2_type == TypeInt::ZERO &&
       phase->type( cmp1->in(1) ) == TypeInt::ZERO &&
       phase->type( cmp1->in(2) )->higher_equal(TypeInt::SYMINT) ) {
-    Node *ncmp = phase->transform( new (phase->C, 3) CmpINode(cmp1->in(2),cmp2));
-    return new (phase->C, 2) BoolNode( ncmp, _test.commute() );
+    Node *ncmp = phase->transform( new (phase->C) CmpINode(cmp1->in(2),cmp2));
+    return new (phase->C) BoolNode( ncmp, _test.commute() );
   }
 
   //  The transformation below is not valid for either signed or unsigned
@@ -1314,7 +1388,5 @@
   if( t2->base() != Type::DoubleCon ) return Type::DOUBLE;
   double d1 = t1->getd();
   double d2 = t2->getd();
-  if( d1 < 0.0 ) return Type::DOUBLE;
-  if( d2 < 0.0 ) return Type::DOUBLE;
   return TypeD::make( StubRoutines::intrinsic_pow( d1, d2 ) );
 }
diff --git a/hotspot/src/share/vm/opto/subnode.hpp b/hotspot/src/share/vm/opto/subnode.hpp
index bacd106..2b33e90 100644
--- a/hotspot/src/share/vm/opto/subnode.hpp
+++ b/hotspot/src/share/vm/opto/subnode.hpp
@@ -158,6 +158,7 @@
   CmpUNode( Node *in1, Node *in2 ) : CmpNode(in1,in2) {}
   virtual int Opcode() const;
   virtual const Type *sub( const Type *, const Type * ) const;
+  bool is_index_range_check() const;
 };
 
 //------------------------------CmpPNode---------------------------------------
diff --git a/hotspot/src/share/vm/opto/superword.cpp b/hotspot/src/share/vm/opto/superword.cpp
index d1d1e1c..f53c648 100644
--- a/hotspot/src/share/vm/opto/superword.cpp
+++ b/hotspot/src/share/vm/opto/superword.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, 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
@@ -67,6 +67,10 @@
 
 //------------------------------transform_loop---------------------------
 void SuperWord::transform_loop(IdealLoopTree* lpt) {
+  assert(UseSuperWord, "should be");
+  // Do vectors exist on this architecture?
+  if (Matcher::vector_width_in_bytes(T_BYTE) < 2) return;
+
   assert(lpt->_head->is_CountedLoop(), "must be");
   CountedLoopNode *cl = lpt->_head->as_CountedLoop();
 
@@ -89,15 +93,12 @@
   Node *pre_opaq1 = pre_end->limit();
   if (pre_opaq1->Opcode() != Op_Opaque1) return;
 
-  // Do vectors exist on this architecture?
-  if (vector_width_in_bytes() == 0) return;
-
   init(); // initialize data structures
 
   set_lpt(lpt);
   set_lp(cl);
 
- // For now, define one block which is the entire loop body
+  // For now, define one block which is the entire loop body
   set_bb(cl);
 
   assert(_packset.length() == 0, "packset must be empty");
@@ -177,7 +178,7 @@
   Node_List memops;
   for (int i = 0; i < _block.length(); i++) {
     Node* n = _block.at(i);
-    if (n->is_Mem() && in_bb(n) &&
+    if (n->is_Mem() && !n->is_LoadStore() && in_bb(n) &&
         is_java_primitive(n->as_Mem()->memory_type())) {
       int align = memory_alignment(n->as_Mem(), 0);
       if (align != bottom_align) {
@@ -185,54 +186,141 @@
       }
     }
   }
-  if (memops.size() == 0) return;
 
-  // Find a memory reference to align to.  The pre-loop trip count
-  // is modified to align this reference to a vector-aligned address
-  find_align_to_ref(memops);
-  if (align_to_ref() == NULL) return;
+  Node_List align_to_refs;
+  int best_iv_adjustment = 0;
+  MemNode* best_align_to_mem_ref = NULL;
 
-  SWPointer align_to_ref_p(align_to_ref(), this);
-  int offset = align_to_ref_p.offset_in_bytes();
-  int scale  = align_to_ref_p.scale_in_bytes();
-  int vw              = vector_width_in_bytes();
-  int stride_sign     = (scale * iv_stride()) > 0 ? 1 : -1;
-  int iv_adjustment   = (stride_sign * vw - (offset % vw)) % vw;
+  while (memops.size() != 0) {
+    // Find a memory reference to align to.
+    MemNode* mem_ref = find_align_to_ref(memops);
+    if (mem_ref == NULL) break;
+    align_to_refs.push(mem_ref);
+    int iv_adjustment = get_iv_adjustment(mem_ref);
 
-#ifndef PRODUCT
-  if (TraceSuperWord)
-    tty->print_cr("\noffset = %d iv_adjustment = %d  elt_align = %d scale = %d iv_stride = %d",
-                  offset, iv_adjustment, align_to_ref_p.memory_size(), align_to_ref_p.scale_in_bytes(), iv_stride());
-#endif
-
-  // Set alignment relative to "align_to_ref"
-  for (int i = memops.size() - 1; i >= 0; i--) {
-    MemNode* s = memops.at(i)->as_Mem();
-    SWPointer p2(s, this);
-    if (p2.comparable(align_to_ref_p)) {
-      int align = memory_alignment(s, iv_adjustment);
-      set_alignment(s, align);
-    } else {
-      memops.remove(i);
+    if (best_align_to_mem_ref == NULL) {
+      // Set memory reference which is the best from all memory operations
+      // to be used for alignment. The pre-loop trip count is modified to align
+      // this reference to a vector-aligned address.
+      best_align_to_mem_ref = mem_ref;
+      best_iv_adjustment = iv_adjustment;
     }
-  }
 
-  // Create initial pack pairs of memory operations
-  for (uint i = 0; i < memops.size(); i++) {
-    Node* s1 = memops.at(i);
-    for (uint j = 0; j < memops.size(); j++) {
-      Node* s2 = memops.at(j);
-      if (s1 != s2 && are_adjacent_refs(s1, s2)) {
-        int align = alignment(s1);
-        if (stmts_can_pack(s1, s2, align)) {
-          Node_List* pair = new Node_List();
-          pair->push(s1);
-          pair->push(s2);
-          _packset.append(pair);
+    SWPointer align_to_ref_p(mem_ref, this);
+    // Set alignment relative to "align_to_ref" for all related memory operations.
+    for (int i = memops.size() - 1; i >= 0; i--) {
+      MemNode* s = memops.at(i)->as_Mem();
+      if (isomorphic(s, mem_ref)) {
+        SWPointer p2(s, this);
+        if (p2.comparable(align_to_ref_p)) {
+          int align = memory_alignment(s, iv_adjustment);
+          set_alignment(s, align);
         }
       }
     }
-  }
+
+    // Create initial pack pairs of memory operations for which
+    // alignment is set and vectors will be aligned.
+    bool create_pack = true;
+    if (memory_alignment(mem_ref, best_iv_adjustment) == 0) {
+      if (!Matcher::misaligned_vectors_ok()) {
+        int vw = vector_width(mem_ref);
+        int vw_best = vector_width(best_align_to_mem_ref);
+        if (vw > vw_best) {
+          // Do not vectorize a memory access with more elements per vector
+          // if unaligned memory access is not allowed because number of
+          // iterations in pre-loop will be not enough to align it.
+          create_pack = false;
+        }
+      }
+    } else {
+      if (same_velt_type(mem_ref, best_align_to_mem_ref)) {
+        // Can't allow vectorization of unaligned memory accesses with the
+        // same type since it could be overlapped accesses to the same array.
+        create_pack = false;
+      } else {
+        // Allow independent (different type) unaligned memory operations
+        // if HW supports them.
+        if (!Matcher::misaligned_vectors_ok()) {
+          create_pack = false;
+        } else {
+          // Check if packs of the same memory type but
+          // with a different alignment were created before.
+          for (uint i = 0; i < align_to_refs.size(); i++) {
+            MemNode* mr = align_to_refs.at(i)->as_Mem();
+            if (same_velt_type(mr, mem_ref) &&
+                memory_alignment(mr, iv_adjustment) != 0)
+              create_pack = false;
+          }
+        }
+      }
+    }
+    if (create_pack) {
+      for (uint i = 0; i < memops.size(); i++) {
+        Node* s1 = memops.at(i);
+        int align = alignment(s1);
+        if (align == top_align) continue;
+        for (uint j = 0; j < memops.size(); j++) {
+          Node* s2 = memops.at(j);
+          if (alignment(s2) == top_align) continue;
+          if (s1 != s2 && are_adjacent_refs(s1, s2)) {
+            if (stmts_can_pack(s1, s2, align)) {
+              Node_List* pair = new Node_List();
+              pair->push(s1);
+              pair->push(s2);
+              _packset.append(pair);
+            }
+          }
+        }
+      }
+    } else { // Don't create unaligned pack
+      // First, remove remaining memory ops of the same type from the list.
+      for (int i = memops.size() - 1; i >= 0; i--) {
+        MemNode* s = memops.at(i)->as_Mem();
+        if (same_velt_type(s, mem_ref)) {
+          memops.remove(i);
+        }
+      }
+
+      // Second, remove already constructed packs of the same type.
+      for (int i = _packset.length() - 1; i >= 0; i--) {
+        Node_List* p = _packset.at(i);
+        MemNode* s = p->at(0)->as_Mem();
+        if (same_velt_type(s, mem_ref)) {
+          remove_pack_at(i);
+        }
+      }
+
+      // If needed find the best memory reference for loop alignment again.
+      if (same_velt_type(mem_ref, best_align_to_mem_ref)) {
+        // Put memory ops from remaining packs back on memops list for
+        // the best alignment search.
+        uint orig_msize = memops.size();
+        for (int i = 0; i < _packset.length(); i++) {
+          Node_List* p = _packset.at(i);
+          MemNode* s = p->at(0)->as_Mem();
+          assert(!same_velt_type(s, mem_ref), "sanity");
+          memops.push(s);
+        }
+        MemNode* best_align_to_mem_ref = find_align_to_ref(memops);
+        if (best_align_to_mem_ref == NULL) break;
+        best_iv_adjustment = get_iv_adjustment(best_align_to_mem_ref);
+        // Restore list.
+        while (memops.size() > orig_msize)
+          (void)memops.pop();
+      }
+    } // unaligned memory accesses
+
+    // Remove used mem nodes.
+    for (int i = memops.size() - 1; i >= 0; i--) {
+      MemNode* m = memops.at(i)->as_Mem();
+      if (alignment(m) != top_align) {
+        memops.remove(i);
+      }
+    }
+
+  } // while (memops.size() != 0
+  set_align_to_ref(best_align_to_mem_ref);
 
 #ifndef PRODUCT
   if (TraceSuperWord) {
@@ -246,7 +334,7 @@
 // Find a memory reference to align the loop induction variable to.
 // Looks first at stores then at loads, looking for a memory reference
 // with the largest number of references similar to it.
-void SuperWord::find_align_to_ref(Node_List &memops) {
+MemNode* SuperWord::find_align_to_ref(Node_List &memops) {
   GrowableArray<int> cmp_ct(arena(), memops.size(), memops.size(), 0);
 
   // Count number of comparable memory ops
@@ -270,20 +358,28 @@
     }
   }
 
-  // Find Store (or Load) with the greatest number of "comparable" references
+  // Find Store (or Load) with the greatest number of "comparable" references,
+  // biggest vector size, smallest data size and smallest iv offset.
   int max_ct        = 0;
+  int max_vw        = 0;
   int max_idx       = -1;
   int min_size      = max_jint;
   int min_iv_offset = max_jint;
   for (uint j = 0; j < memops.size(); j++) {
     MemNode* s = memops.at(j)->as_Mem();
     if (s->is_Store()) {
+      int vw = vector_width_in_bytes(s);
+      assert(vw > 1, "sanity");
       SWPointer p(s, this);
-      if (cmp_ct.at(j) > max_ct ||
-          cmp_ct.at(j) == max_ct && (data_size(s) < min_size ||
-                                     data_size(s) == min_size &&
-                                        p.offset_in_bytes() < min_iv_offset)) {
+      if (cmp_ct.at(j) >  max_ct ||
+          cmp_ct.at(j) == max_ct &&
+            (vw >  max_vw ||
+             vw == max_vw &&
+              (data_size(s) <  min_size ||
+               data_size(s) == min_size &&
+                 (p.offset_in_bytes() < min_iv_offset)))) {
         max_ct = cmp_ct.at(j);
+        max_vw = vw;
         max_idx = j;
         min_size = data_size(s);
         min_iv_offset = p.offset_in_bytes();
@@ -295,12 +391,18 @@
     for (uint j = 0; j < memops.size(); j++) {
       MemNode* s = memops.at(j)->as_Mem();
       if (s->is_Load()) {
+        int vw = vector_width_in_bytes(s);
+        assert(vw > 1, "sanity");
         SWPointer p(s, this);
-        if (cmp_ct.at(j) > max_ct ||
-            cmp_ct.at(j) == max_ct && (data_size(s) < min_size ||
-                                       data_size(s) == min_size &&
-                                          p.offset_in_bytes() < min_iv_offset)) {
+        if (cmp_ct.at(j) >  max_ct ||
+            cmp_ct.at(j) == max_ct &&
+              (vw >  max_vw ||
+               vw == max_vw &&
+                (data_size(s) <  min_size ||
+                 data_size(s) == min_size &&
+                   (p.offset_in_bytes() < min_iv_offset)))) {
           max_ct = cmp_ct.at(j);
+          max_vw = vw;
           max_idx = j;
           min_size = data_size(s);
           min_iv_offset = p.offset_in_bytes();
@@ -309,10 +411,7 @@
     }
   }
 
-  if (max_ct > 0)
-    set_align_to_ref(memops.at(max_idx)->as_Mem());
-
-#ifndef PRODUCT
+#ifdef ASSERT
   if (TraceSuperWord && Verbose) {
     tty->print_cr("\nVector memops after find_align_to_refs");
     for (uint i = 0; i < memops.size(); i++) {
@@ -321,6 +420,17 @@
     }
   }
 #endif
+
+  if (max_ct > 0) {
+#ifdef ASSERT
+    if (TraceSuperWord) {
+      tty->print("\nVector align to node: ");
+      memops.at(max_idx)->as_Mem()->dump();
+    }
+#endif
+    return memops.at(max_idx)->as_Mem();
+  }
+  return NULL;
 }
 
 //------------------------------ref_is_alignable---------------------------
@@ -341,7 +451,8 @@
 
   // If initial offset from start of object is computable,
   // compute alignment within the vector.
-  int vw = vector_width_in_bytes();
+  int vw = vector_width_in_bytes(p.mem());
+  assert(vw > 1, "sanity");
   if (vw % span == 0) {
     Node* init_nd = pre_end->init_trip();
     if (init_nd->is_Con() && p.invar() == NULL) {
@@ -361,6 +472,32 @@
   return false;
 }
 
+//---------------------------get_iv_adjustment---------------------------
+// Calculate loop's iv adjustment for this memory ops.
+int SuperWord::get_iv_adjustment(MemNode* mem_ref) {
+  SWPointer align_to_ref_p(mem_ref, this);
+  int offset = align_to_ref_p.offset_in_bytes();
+  int scale  = align_to_ref_p.scale_in_bytes();
+  int vw       = vector_width_in_bytes(mem_ref);
+  assert(vw > 1, "sanity");
+  int stride_sign   = (scale * iv_stride()) > 0 ? 1 : -1;
+  // At least one iteration is executed in pre-loop by default. As result
+  // several iterations are needed to align memory operations in main-loop even
+  // if offset is 0.
+  int iv_adjustment_in_bytes = (stride_sign * vw - (offset % vw));
+  int elt_size = align_to_ref_p.memory_size();
+  assert(((ABS(iv_adjustment_in_bytes) % elt_size) == 0),
+         err_msg_res("(%d) should be divisible by (%d)", iv_adjustment_in_bytes, elt_size));
+  int iv_adjustment = iv_adjustment_in_bytes/elt_size;
+
+#ifndef PRODUCT
+  if (TraceSuperWord)
+    tty->print_cr("\noffset = %d iv_adjust = %d elt_size = %d scale = %d iv_stride = %d vect_size %d",
+                  offset, iv_adjustment, elt_size, scale, iv_stride(), vw);
+#endif
+  return iv_adjustment;
+}
+
 //---------------------------dependence_graph---------------------------
 // Construct dependency graph.
 // Add dependence edges to load/store nodes for memory dependence
@@ -488,9 +625,13 @@
 bool SuperWord::stmts_can_pack(Node* s1, Node* s2, int align) {
 
   // Do not use superword for non-primitives
-  if((s1->is_Mem() && !is_java_primitive(s1->as_Mem()->memory_type())) ||
-     (s2->is_Mem() && !is_java_primitive(s2->as_Mem()->memory_type())))
+  BasicType bt1 = velt_basic_type(s1);
+  BasicType bt2 = velt_basic_type(s2);
+  if(!is_java_primitive(bt1) || !is_java_primitive(bt2))
     return false;
+  if (Matcher::max_vector_size(bt1) < 2) {
+    return false; // No vectors for this type
+  }
 
   if (isomorphic(s1, s2)) {
     if (independent(s1, s2)) {
@@ -552,7 +693,7 @@
   if (s1->Opcode() != s2->Opcode()) return false;
   if (s1->req() != s2->req()) return false;
   if (s1->in(0) != s2->in(0)) return false;
-  if (velt_type(s1) != velt_type(s2)) return false;
+  if (!same_velt_type(s1, s2)) return false;
   return true;
 }
 
@@ -595,14 +736,16 @@
 //------------------------------set_alignment---------------------------
 void SuperWord::set_alignment(Node* s1, Node* s2, int align) {
   set_alignment(s1, align);
-  set_alignment(s2, align + data_size(s1));
+  if (align == top_align || align == bottom_align) {
+    set_alignment(s2, align);
+  } else {
+    set_alignment(s2, align + data_size(s1));
+  }
 }
 
 //------------------------------data_size---------------------------
 int SuperWord::data_size(Node* s) {
-  const Type* t = velt_type(s);
-  BasicType  bt = t->array_element_basic_type();
-  int bsize = type2aelembytes(bt);
+  int bsize = type2aelembytes(velt_basic_type(s));
   assert(bsize != 0, "valid size");
   return bsize;
 }
@@ -631,9 +774,9 @@
 //------------------------------follow_use_defs---------------------------
 // Extend the packset by visiting operand definitions of nodes in pack p
 bool SuperWord::follow_use_defs(Node_List* p) {
+  assert(p->size() == 2, "just checking");
   Node* s1 = p->at(0);
   Node* s2 = p->at(1);
-  assert(p->size() == 2, "just checking");
   assert(s1->req() == s2->req(), "just checking");
   assert(alignment(s1) + data_size(s1) == alignment(s2), "just checking");
 
@@ -718,7 +861,12 @@
     for (i1++; i1 < ct; i1++) if (u1->in(i1) == d1) break;
     for (i2++; i2 < ct; i2++) if (u2->in(i2) == d2) break;
     if (i1 != i2) {
-      return false;
+      if ((i1 == (3-i2)) && (u2->is_Add() || u2->is_Mul())) {
+        // Further analysis relies on operands position matching.
+        u2->swap_edges(i1, i2);
+      } else {
+        return false;
+      }
     }
   } while (i1 < ct);
   return true;
@@ -727,7 +875,7 @@
 //------------------------------est_savings---------------------------
 // Estimate the savings from executing s1 and s2 as a pack
 int SuperWord::est_savings(Node* s1, Node* s2) {
-  int save = 2 - 1; // 2 operations per instruction in packed form
+  int save_in = 2 - 1; // 2 operations per instruction in packed form
 
   // inputs
   for (uint i = 1; i < s1->req(); i++) {
@@ -735,17 +883,18 @@
     Node* x2 = s2->in(i);
     if (x1 != x2) {
       if (are_adjacent_refs(x1, x2)) {
-        save += adjacent_profit(x1, x2);
+        save_in += adjacent_profit(x1, x2);
       } else if (!in_packset(x1, x2)) {
-        save -= pack_cost(2);
+        save_in -= pack_cost(2);
       } else {
-        save += unpack_cost(2);
+        save_in += unpack_cost(2);
       }
     }
   }
 
   // uses of result
   uint ct = 0;
+  int save_use = 0;
   for (DUIterator_Fast imax, i = s1->fast_outs(imax); i < imax; i++) {
     Node* s1_use = s1->fast_out(i);
     for (int j = 0; j < _packset.length(); j++) {
@@ -756,7 +905,7 @@
           if (p->at(p->size()-1) == s2_use) {
             ct++;
             if (are_adjacent_refs(s1_use, s2_use)) {
-              save += adjacent_profit(s1_use, s2_use);
+              save_use += adjacent_profit(s1_use, s2_use);
             }
           }
         }
@@ -764,10 +913,10 @@
     }
   }
 
-  if (ct < s1->outcnt()) save += unpack_cost(1);
-  if (ct < s2->outcnt()) save += unpack_cost(1);
+  if (ct < s1->outcnt()) save_use += unpack_cost(1);
+  if (ct < s2->outcnt()) save_use += unpack_cost(1);
 
-  return save;
+  return MAX2(save_in, save_use);
 }
 
 //------------------------------costs---------------------------
@@ -778,8 +927,9 @@
 //------------------------------combine_packs---------------------------
 // Combine packs A and B with A.last == B.first into A.first..,A.last,B.second,..B.last
 void SuperWord::combine_packs() {
-  bool changed;
-  do {
+  bool changed = true;
+  // Combine packs regardless max vector size.
+  while (changed) {
     changed = false;
     for (int i = 0; i < _packset.length(); i++) {
       Node_List* p1 = _packset.at(i);
@@ -787,6 +937,7 @@
       for (int j = 0; j < _packset.length(); j++) {
         Node_List* p2 = _packset.at(j);
         if (p2 == NULL) continue;
+        if (i == j) continue;
         if (p1->at(p1->size()-1) == p2->at(0)) {
           for (uint k = 1; k < p2->size(); k++) {
             p1->push(p2->at(k));
@@ -796,8 +947,39 @@
         }
       }
     }
-  } while (changed);
+  }
 
+  // Split packs which have size greater then max vector size.
+  for (int i = 0; i < _packset.length(); i++) {
+    Node_List* p1 = _packset.at(i);
+    if (p1 != NULL) {
+      BasicType bt = velt_basic_type(p1->at(0));
+      uint max_vlen = Matcher::max_vector_size(bt); // Max elements in vector
+      assert(is_power_of_2(max_vlen), "sanity");
+      uint psize = p1->size();
+      if (!is_power_of_2(psize)) {
+        // Skip pack which can't be vector.
+        // case1: for(...) { a[i] = i; }    elements values are different (i+x)
+        // case2: for(...) { a[i] = b[i+1]; }  can't align both, load and store
+        _packset.at_put(i, NULL);
+        continue;
+      }
+      if (psize > max_vlen) {
+        Node_List* pack = new Node_List();
+        for (uint j = 0; j < psize; j++) {
+          pack->push(p1->at(j));
+          if (pack->size() >= max_vlen) {
+            assert(is_power_of_2(pack->size()), "sanity");
+            _packset.append(pack);
+            pack = new Node_List();
+          }
+        }
+        _packset.at_put(i, NULL);
+      }
+    }
+  }
+
+  // Compress list.
   for (int i = _packset.length() - 1; i >= 0; i--) {
     Node_List* p1 = _packset.at(i);
     if (p1 == NULL) {
@@ -880,8 +1062,22 @@
 // Can code be generated for pack p?
 bool SuperWord::implemented(Node_List* p) {
   Node* p0 = p->at(0);
-  int vopc = VectorNode::opcode(p0->Opcode(), p->size(), velt_type(p0));
-  return vopc > 0 && Matcher::has_match_rule(vopc);
+  return VectorNode::implemented(p0->Opcode(), p->size(), velt_basic_type(p0));
+}
+
+//------------------------------same_inputs--------------------------
+// For pack p, are all idx operands the same?
+static bool same_inputs(Node_List* p, int idx) {
+  Node* p0 = p->at(0);
+  uint vlen = p->size();
+  Node* p0_def = p0->in(idx);
+  for (uint i = 1; i < vlen; i++) {
+    Node* pi = p->at(i);
+    Node* pi_def = pi->in(idx);
+    if (p0_def != pi_def)
+      return false;
+  }
+  return true;
 }
 
 //------------------------------profitable---------------------------
@@ -889,22 +1085,26 @@
 bool SuperWord::profitable(Node_List* p) {
   Node* p0 = p->at(0);
   uint start, end;
-  vector_opd_range(p0, &start, &end);
+  VectorNode::vector_operands(p0, &start, &end);
 
-  // Return false if some input is not vector and inside block
+  // Return false if some inputs are not vectors or vectors with different
+  // size or alignment.
+  // Also, for now, return false if not scalar promotion case when inputs are
+  // the same. Later, implement PackNode and allow differing, non-vector inputs
+  // (maybe just the ones from outside the block.)
   for (uint i = start; i < end; i++) {
-    if (!is_vector_use(p0, i)) {
-      // For now, return false if not scalar promotion case (inputs are the same.)
-      // Later, implement PackNode and allow differing, non-vector inputs
-      // (maybe just the ones from outside the block.)
-      Node* p0_def = p0->in(i);
-      for (uint j = 1; j < p->size(); j++) {
-        Node* use = p->at(j);
-        Node* def = use->in(i);
-        if (p0_def != def)
-          return false;
-      }
-    }
+    if (!is_vector_use(p0, i))
+      return false;
+  }
+  if (VectorNode::is_shift(p0)) {
+    // For now, return false if shift count is vector or not scalar promotion
+    // case (different shift counts) because it is not supported yet.
+    Node* cnt = p0->in(2);
+    Node_List* cnt_pk = my_pack(cnt);
+    if (cnt_pk != NULL)
+      return false;
+    if (!same_inputs(p, 2))
+      return false;
   }
   if (!p0->is_Store()) {
     // For now, return false if not all uses are vector.
@@ -939,62 +1139,56 @@
 }
 
 //-------------------------------remove_and_insert-------------------
-//remove "current" from its current position in the memory graph and insert
-//it after the appropriate insertion point (lip or uip)
+// Remove "current" from its current position in the memory graph and insert
+// it after the appropriate insertion point (lip or uip).
 void SuperWord::remove_and_insert(MemNode *current, MemNode *prev, MemNode *lip,
                                   Node *uip, Unique_Node_List &sched_before) {
   Node* my_mem = current->in(MemNode::Memory);
-  _igvn.hash_delete(current);
-  _igvn.hash_delete(my_mem);
+  bool sched_up = sched_before.member(current);
 
-  //remove current_store from its current position in the memmory graph
+  // remove current_store from its current position in the memmory graph
   for (DUIterator i = current->outs(); current->has_out(i); i++) {
     Node* use = current->out(i);
     if (use->is_Mem()) {
       assert(use->in(MemNode::Memory) == current, "must be");
-      _igvn.hash_delete(use);
       if (use == prev) { // connect prev to my_mem
-        use->set_req(MemNode::Memory, my_mem);
+          _igvn.replace_input_of(use, MemNode::Memory, my_mem);
+          --i; //deleted this edge; rescan position
       } else if (sched_before.member(use)) {
-        _igvn.hash_delete(uip);
-        use->set_req(MemNode::Memory, uip);
+        if (!sched_up) { // Will be moved together with current
+          _igvn.replace_input_of(use, MemNode::Memory, uip);
+          --i; //deleted this edge; rescan position
+        }
       } else {
-        _igvn.hash_delete(lip);
-        use->set_req(MemNode::Memory, lip);
+        if (sched_up) { // Will be moved together with current
+          _igvn.replace_input_of(use, MemNode::Memory, lip);
+          --i; //deleted this edge; rescan position
+        }
       }
-      _igvn._worklist.push(use);
-      --i; //deleted this edge; rescan position
     }
   }
 
-  bool sched_up = sched_before.member(current);
   Node *insert_pt =  sched_up ?  uip : lip;
-  _igvn.hash_delete(insert_pt);
 
   // all uses of insert_pt's memory state should use current's instead
   for (DUIterator i = insert_pt->outs(); insert_pt->has_out(i); i++) {
     Node* use = insert_pt->out(i);
     if (use->is_Mem()) {
       assert(use->in(MemNode::Memory) == insert_pt, "must be");
-      _igvn.hash_delete(use);
-      use->set_req(MemNode::Memory, current);
-      _igvn._worklist.push(use);
+      _igvn.replace_input_of(use, MemNode::Memory, current);
       --i; //deleted this edge; rescan position
     } else if (!sched_up && use->is_Phi() && use->bottom_type() == Type::MEMORY) {
       uint pos; //lip (lower insert point) must be the last one in the memory slice
-      _igvn.hash_delete(use);
       for (pos=1; pos < use->req(); pos++) {
         if (use->in(pos) == insert_pt) break;
       }
-      use->set_req(pos, current);
-      _igvn._worklist.push(use);
+      _igvn.replace_input_of(use, pos, current);
       --i;
     }
   }
 
   //connect current to insert_pt
-  current->set_req(MemNode::Memory, insert_pt);
-  _igvn._worklist.push(current);
+  _igvn.replace_input_of(current, MemNode::Memory, insert_pt);
 }
 
 //------------------------------co_locate_pack----------------------------------
@@ -1031,7 +1225,7 @@
         if (use->is_Mem() && use != previous)
           memops.push(use);
       }
-      if(current == first) break;
+      if (current == first) break;
       previous = current;
       current  = current->in(MemNode::Memory)->as_Mem();
     }
@@ -1044,27 +1238,37 @@
           Node *s2 = memops.at(j);
           if (!independent(s1, s2)) {
             if (in_pack(s2, pk) || schedule_before_pack.member(s2)) {
-              schedule_before_pack.push(s1); //s1 must be scheduled before
+              schedule_before_pack.push(s1); // s1 must be scheduled before
               Node_List* mem_pk = my_pack(s1);
               if (mem_pk != NULL) {
                 for (uint ii = 0; ii < mem_pk->size(); ii++) {
-                  Node* s = mem_pk->at(ii); // follow partner
+                  Node* s = mem_pk->at(ii);  // follow partner
                   if (memops.member(s) && !schedule_before_pack.member(s))
                     schedule_before_pack.push(s);
                 }
               }
+              break;
             }
           }
         }
       }
     }
 
-    MemNode* lower_insert_pt = last;
     Node*    upper_insert_pt = first->in(MemNode::Memory);
+    // Following code moves loads connected to upper_insert_pt below aliased stores.
+    // Collect such loads here and reconnect them back to upper_insert_pt later.
+    memops.clear();
+    for (DUIterator i = upper_insert_pt->outs(); upper_insert_pt->has_out(i); i++) {
+      Node* use = upper_insert_pt->out(i);
+      if (!use->is_Store())
+        memops.push(use);
+    }
+
+    MemNode* lower_insert_pt = last;
     previous                 = last; //previous store in pk
     current                  = last->in(MemNode::Memory)->as_Mem();
 
-    //start scheduling from "last" to "first"
+    // start scheduling from "last" to "first"
     while (true) {
       assert(in_bb(current), "stay in block");
       assert(in_pack(previous, pk), "previous stays in pack");
@@ -1072,20 +1276,15 @@
 
       if (in_pack(current, pk)) {
         // Forward users of my memory state (except "previous) to my input memory state
-        _igvn.hash_delete(current);
         for (DUIterator i = current->outs(); current->has_out(i); i++) {
           Node* use = current->out(i);
           if (use->is_Mem() && use != previous) {
             assert(use->in(MemNode::Memory) == current, "must be");
-            _igvn.hash_delete(use);
             if (schedule_before_pack.member(use)) {
-              _igvn.hash_delete(upper_insert_pt);
-              use->set_req(MemNode::Memory, upper_insert_pt);
+              _igvn.replace_input_of(use, MemNode::Memory, upper_insert_pt);
             } else {
-              _igvn.hash_delete(lower_insert_pt);
-              use->set_req(MemNode::Memory, lower_insert_pt);
+              _igvn.replace_input_of(use, MemNode::Memory, lower_insert_pt);
             }
-            _igvn._worklist.push(use);
             --i; // deleted this edge; rescan position
           }
         }
@@ -1097,6 +1296,14 @@
       if (current == first) break;
       current = my_mem->as_Mem();
     } // end while
+
+    // Reconnect loads back to upper_insert_pt.
+    for (uint i = 0; i < memops.size(); i++) {
+      Node *ld = memops.at(i);
+      if (ld->in(MemNode::Memory) != upper_insert_pt) {
+        _igvn.replace_input_of(ld, MemNode::Memory, upper_insert_pt);
+      }
+    }
   } else if (pk->at(0)->is_Load()) { //load
     // all loads in the pack should have the same memory state. By default,
     // we use the memory state of the last load. However, if any load could
@@ -1122,9 +1329,7 @@
     // Give each load the same memory state
     for (uint i = 0; i < pk->size(); i++) {
       LoadNode* ld = pk->at(i)->as_Load();
-      _igvn.hash_delete(ld);
-      ld->set_req(MemNode::Memory, mem_input);
-      _igvn._worklist.push(ld);
+      _igvn.replace_input_of(ld, MemNode::Memory, mem_input);
     }
   }
 }
@@ -1151,52 +1356,70 @@
     insert_extracts(_packset.at(i));
   }
 
+  Compile* C = _phase->C;
+  uint max_vlen_in_bytes = 0;
   for (int i = 0; i < _block.length(); i++) {
     Node* n = _block.at(i);
     Node_List* p = my_pack(n);
     if (p && n == executed_last(p)) {
       uint vlen = p->size();
+      uint vlen_in_bytes = 0;
       Node* vn = NULL;
       Node* low_adr = p->at(0);
       Node* first   = executed_first(p);
+      int   opc = n->Opcode();
       if (n->is_Load()) {
-        int   opc = n->Opcode();
         Node* ctl = n->in(MemNode::Control);
         Node* mem = first->in(MemNode::Memory);
         Node* adr = low_adr->in(MemNode::Address);
         const TypePtr* atyp = n->adr_type();
-        vn = VectorLoadNode::make(_phase->C, opc, ctl, mem, adr, atyp, vlen);
-
+        vn = LoadVectorNode::make(C, opc, ctl, mem, adr, atyp, vlen, velt_basic_type(n));
+        vlen_in_bytes = vn->as_LoadVector()->memory_size();
       } else if (n->is_Store()) {
         // Promote value to be stored to vector
         Node* val = vector_opd(p, MemNode::ValueIn);
-
-        int   opc = n->Opcode();
         Node* ctl = n->in(MemNode::Control);
         Node* mem = first->in(MemNode::Memory);
         Node* adr = low_adr->in(MemNode::Address);
         const TypePtr* atyp = n->adr_type();
-        vn = VectorStoreNode::make(_phase->C, opc, ctl, mem, adr, atyp, val, vlen);
-
+        vn = StoreVectorNode::make(C, opc, ctl, mem, adr, atyp, val, vlen);
+        vlen_in_bytes = vn->as_StoreVector()->memory_size();
       } else if (n->req() == 3) {
         // Promote operands to vector
         Node* in1 = vector_opd(p, 1);
         Node* in2 = vector_opd(p, 2);
-        vn = VectorNode::make(_phase->C, n->Opcode(), in1, in2, vlen, velt_type(n));
-
+        if (VectorNode::is_invariant_vector(in1) && (n->is_Add() || n->is_Mul())) {
+          // Move invariant vector input into second position to avoid register spilling.
+          Node* tmp = in1;
+          in1 = in2;
+          in2 = tmp;
+        }
+        vn = VectorNode::make(C, opc, in1, in2, vlen, velt_basic_type(n));
+        vlen_in_bytes = vn->as_Vector()->length_in_bytes();
       } else {
         ShouldNotReachHere();
       }
-
-      _phase->_igvn.register_new_node_with_optimizer(vn);
+      assert(vn != NULL, "sanity");
+      _igvn.register_new_node_with_optimizer(vn);
       _phase->set_ctrl(vn, _phase->get_ctrl(p->at(0)));
       for (uint j = 0; j < p->size(); j++) {
         Node* pm = p->at(j);
         _igvn.replace_node(pm, vn);
       }
       _igvn._worklist.push(vn);
+
+      if (vlen_in_bytes > max_vlen_in_bytes) {
+        max_vlen_in_bytes = vlen_in_bytes;
+      }
+#ifdef ASSERT
+      if (TraceNewVectors) {
+        tty->print("new Vector node: ");
+        vn->dump();
+      }
+#endif
     }
   }
+  C->set_max_vector_size(max_vlen_in_bytes);
 }
 
 //------------------------------vector_opd---------------------------
@@ -1206,46 +1429,78 @@
   uint vlen = p->size();
   Node* opd = p0->in(opd_idx);
 
-  bool same_opd = true;
-  for (uint i = 1; i < vlen; i++) {
-    Node* pi = p->at(i);
-    Node* in = pi->in(opd_idx);
-    if (opd != in) {
-      same_opd = false;
-      break;
-    }
-  }
-
-  if (same_opd) {
-    if (opd->is_Vector() || opd->is_VectorLoad()) {
+  if (same_inputs(p, opd_idx)) {
+    if (opd->is_Vector() || opd->is_LoadVector()) {
+      assert(((opd_idx != 2) || !VectorNode::is_shift(p0)), "shift's count can't be vector");
       return opd; // input is matching vector
     }
-    assert(!opd->is_VectorStore(), "such vector is not expected here");
-    // Convert scalar input to vector. Use p0's type because it's container
-    // maybe smaller than the operand's container.
-    const Type* opd_t = velt_type(!in_bb(opd) ? p0 : opd);
-    const Type* p0_t  = velt_type(p0);
-    if (p0_t->higher_equal(opd_t)) opd_t = p0_t;
-    VectorNode* vn    = VectorNode::scalar2vector(_phase->C, opd, vlen, opd_t);
+    if ((opd_idx == 2) && VectorNode::is_shift(p0)) {
+      Compile* C = _phase->C;
+      Node* cnt = opd;
+      // Vector instructions do not mask shift count, do it here.
+      juint mask = (p0->bottom_type() == TypeInt::INT) ? (BitsPerInt - 1) : (BitsPerLong - 1);
+      const TypeInt* t = opd->find_int_type();
+      if (t != NULL && t->is_con()) {
+        juint shift = t->get_con();
+        if (shift > mask) { // Unsigned cmp
+          cnt = ConNode::make(C, TypeInt::make(shift & mask));
+        }
+      } else {
+        if (t == NULL || t->_lo < 0 || t->_hi > (int)mask) {
+          cnt = ConNode::make(C, TypeInt::make(mask));
+          _igvn.register_new_node_with_optimizer(cnt);
+          cnt = new (C) AndINode(opd, cnt);
+          _igvn.register_new_node_with_optimizer(cnt);
+          _phase->set_ctrl(cnt, _phase->get_ctrl(opd));
+        }
+        assert(opd->bottom_type()->isa_int(), "int type only");
+        // Move non constant shift count into vector register.
+        cnt = VectorNode::shift_count(C, p0, cnt, vlen, velt_basic_type(p0));
+      }
+      if (cnt != opd) {
+        _igvn.register_new_node_with_optimizer(cnt);
+        _phase->set_ctrl(cnt, _phase->get_ctrl(opd));
+      }
+      return cnt;
+    }
+    assert(!opd->is_StoreVector(), "such vector is not expected here");
+    // Convert scalar input to vector with the same number of elements as
+    // p0's vector. Use p0's type because size of operand's container in
+    // vector should match p0's size regardless operand's size.
+    const Type* p0_t = velt_type(p0);
+    VectorNode* vn = VectorNode::scalar2vector(_phase->C, opd, vlen, p0_t);
 
-    _phase->_igvn.register_new_node_with_optimizer(vn);
+    _igvn.register_new_node_with_optimizer(vn);
     _phase->set_ctrl(vn, _phase->get_ctrl(opd));
+#ifdef ASSERT
+    if (TraceNewVectors) {
+      tty->print("new Vector node: ");
+      vn->dump();
+    }
+#endif
     return vn;
   }
 
   // Insert pack operation
-  const Type* opd_t = velt_type(!in_bb(opd) ? p0 : opd);
-  PackNode* pk = PackNode::make(_phase->C, opd, opd_t);
+  BasicType bt = velt_basic_type(p0);
+  PackNode* pk = PackNode::make(_phase->C, opd, vlen, bt);
+  DEBUG_ONLY( const BasicType opd_bt = opd->bottom_type()->basic_type(); )
 
   for (uint i = 1; i < vlen; i++) {
     Node* pi = p->at(i);
     Node* in = pi->in(opd_idx);
     assert(my_pack(in) == NULL, "Should already have been unpacked");
-    assert(opd_t == velt_type(!in_bb(in) ? pi : in), "all same type");
+    assert(opd_bt == in->bottom_type()->basic_type(), "all same type");
     pk->add_opd(in);
   }
-  _phase->_igvn.register_new_node_with_optimizer(pk);
+  _igvn.register_new_node_with_optimizer(pk);
   _phase->set_ctrl(pk, _phase->get_ctrl(opd));
+#ifdef ASSERT
+  if (TraceNewVectors) {
+    tty->print("new Vector node: ");
+    pk->dump();
+  }
+#endif
   return pk;
 }
 
@@ -1282,19 +1537,16 @@
 
     // Insert extract operation
     _igvn.hash_delete(def);
-    _igvn.hash_delete(use);
     int def_pos = alignment(def) / data_size(def);
-    const Type* def_t = velt_type(def);
 
-    Node* ex = ExtractNode::make(_phase->C, def, def_pos, def_t);
-    _phase->_igvn.register_new_node_with_optimizer(ex);
+    Node* ex = ExtractNode::make(_phase->C, def, def_pos, velt_basic_type(def));
+    _igvn.register_new_node_with_optimizer(ex);
     _phase->set_ctrl(ex, _phase->get_ctrl(def));
-    use->set_req(idx, ex);
+    _igvn.replace_input_of(use, idx, ex);
     _igvn._worklist.push(def);
-    _igvn._worklist.push(use);
 
     bb_insert_after(ex, bb_idx(def));
-    set_velt_type(ex, def_t);
+    set_velt_type(ex, velt_type(def));
   }
 }
 
@@ -1521,48 +1773,52 @@
   // Initial type
   for (int i = 0; i < _block.length(); i++) {
     Node* n = _block.at(i);
-    const Type* t  = n->is_Mem() ? Type::get_const_basic_type(n->as_Mem()->memory_type())
-                                 : _igvn.type(n);
-    const Type* vt = container_type(t);
-    set_velt_type(n, vt);
+    set_velt_type(n, container_type(n));
   }
 
-  // Propagate narrowed type backwards through operations
+  // Propagate integer narrowed type backwards through operations
   // that don't depend on higher order bits
   for (int i = _block.length() - 1; i >= 0; i--) {
     Node* n = _block.at(i);
     // Only integer types need be examined
-    if (n->bottom_type()->isa_int()) {
+    const Type* vtn = velt_type(n);
+    if (vtn->basic_type() == T_INT) {
       uint start, end;
-      vector_opd_range(n, &start, &end);
-      const Type* vt = velt_type(n);
+      VectorNode::vector_operands(n, &start, &end);
 
       for (uint j = start; j < end; j++) {
         Node* in  = n->in(j);
-        // Don't propagate through a type conversion
-        if (n->bottom_type() != in->bottom_type())
-          continue;
-        switch(in->Opcode()) {
-        case Op_AddI:    case Op_AddL:
-        case Op_SubI:    case Op_SubL:
-        case Op_MulI:    case Op_MulL:
-        case Op_AndI:    case Op_AndL:
-        case Op_OrI:     case Op_OrL:
-        case Op_XorI:    case Op_XorL:
-        case Op_LShiftI: case Op_LShiftL:
-        case Op_CMoveI:  case Op_CMoveL:
-          if (in_bb(in)) {
-            bool same_type = true;
-            for (DUIterator_Fast kmax, k = in->fast_outs(kmax); k < kmax; k++) {
-              Node *use = in->fast_out(k);
-              if (!in_bb(use) || velt_type(use) != vt) {
-                same_type = false;
-                break;
+        // Don't propagate through a memory
+        if (!in->is_Mem() && in_bb(in) && velt_type(in)->basic_type() == T_INT &&
+            data_size(n) < data_size(in)) {
+          bool same_type = true;
+          for (DUIterator_Fast kmax, k = in->fast_outs(kmax); k < kmax; k++) {
+            Node *use = in->fast_out(k);
+            if (!in_bb(use) || !same_velt_type(use, n)) {
+              same_type = false;
+              break;
+            }
+          }
+          if (same_type) {
+            // For right shifts of small integer types (bool, byte, char, short)
+            // we need precise information about sign-ness. Only Load nodes have
+            // this information because Store nodes are the same for signed and
+            // unsigned values. And any arithmetic operation after a load may
+            // expand a value to signed Int so such right shifts can't be used
+            // because vector elements do not have upper bits of Int.
+            const Type* vt = vtn;
+            if (VectorNode::is_shift(in)) {
+              Node* load = in->in(1);
+              if (load->is_Load() && in_bb(load) && (velt_type(load)->basic_type() == T_INT)) {
+                vt = velt_type(load);
+              } else if (in->Opcode() != Op_LShiftI) {
+                // Widen type to Int to avoid creation of right shift vector
+                // (align + data_size(s1) check in stmts_can_pack() will fail).
+                // Note, left shifts work regardless type.
+                vt = TypeInt::INT;
               }
             }
-            if (same_type) {
-              set_velt_type(in, vt);
-            }
+            set_velt_type(in, vt);
           }
         }
       }
@@ -1582,64 +1838,58 @@
 
 //------------------------------memory_alignment---------------------------
 // Alignment within a vector memory reference
-int SuperWord::memory_alignment(MemNode* s, int iv_adjust_in_bytes) {
+int SuperWord::memory_alignment(MemNode* s, int iv_adjust) {
   SWPointer p(s, this);
   if (!p.valid()) {
     return bottom_align;
   }
+  int vw = vector_width_in_bytes(s);
+  if (vw < 2) {
+    return bottom_align; // No vectors for this type
+  }
   int offset  = p.offset_in_bytes();
-  offset     += iv_adjust_in_bytes;
-  int off_rem = offset % vector_width_in_bytes();
-  int off_mod = off_rem >= 0 ? off_rem : off_rem + vector_width_in_bytes();
+  offset     += iv_adjust*p.memory_size();
+  int off_rem = offset % vw;
+  int off_mod = off_rem >= 0 ? off_rem : off_rem + vw;
   return off_mod;
 }
 
 //---------------------------container_type---------------------------
 // Smallest type containing range of values
-const Type* SuperWord::container_type(const Type* t) {
-  const Type* tp = t->make_ptr();
-  if (tp && tp->isa_aryptr()) {
-    t = tp->is_aryptr()->elem();
+const Type* SuperWord::container_type(Node* n) {
+  if (n->is_Mem()) {
+    BasicType bt = n->as_Mem()->memory_type();
+    if (n->is_Store() && (bt == T_CHAR)) {
+      // Use T_SHORT type instead of T_CHAR for stored values because any
+      // preceding arithmetic operation extends values to signed Int.
+      bt = T_SHORT;
+    }
+    if (n->Opcode() == Op_LoadUB) {
+      // Adjust type for unsigned byte loads, it is important for right shifts.
+      // T_BOOLEAN is used because there is no basic type representing type
+      // TypeInt::UBYTE. Use of T_BOOLEAN for vectors is fine because only
+      // size (one byte) and sign is important.
+      bt = T_BOOLEAN;
+    }
+    return Type::get_const_basic_type(bt);
   }
+  const Type* t = _igvn.type(n);
   if (t->basic_type() == T_INT) {
-    if (t->higher_equal(TypeInt::BOOL))  return TypeInt::BOOL;
-    if (t->higher_equal(TypeInt::BYTE))  return TypeInt::BYTE;
-    if (t->higher_equal(TypeInt::CHAR))  return TypeInt::CHAR;
-    if (t->higher_equal(TypeInt::SHORT)) return TypeInt::SHORT;
+    // A narrow type of arithmetic operations will be determined by
+    // propagating the type of memory operations.
     return TypeInt::INT;
   }
   return t;
 }
 
-//-------------------------vector_opd_range-----------------------
-// (Start, end] half-open range defining which operands are vector
-void SuperWord::vector_opd_range(Node* n, uint* start, uint* end) {
-  switch (n->Opcode()) {
-  case Op_LoadB:   case Op_LoadUS:
-  case Op_LoadI:   case Op_LoadL:
-  case Op_LoadF:   case Op_LoadD:
-  case Op_LoadP:
-    *start = 0;
-    *end   = 0;
-    return;
-  case Op_StoreB:  case Op_StoreC:
-  case Op_StoreI:  case Op_StoreL:
-  case Op_StoreF:  case Op_StoreD:
-  case Op_StoreP:
-    *start = MemNode::ValueIn;
-    *end   = *start + 1;
-    return;
-  case Op_LShiftI: case Op_LShiftL:
-    *start = 1;
-    *end   = 2;
-    return;
-  case Op_CMoveI:  case Op_CMoveL:  case Op_CMoveF:  case Op_CMoveD:
-    *start = 2;
-    *end   = n->req();
-    return;
+bool SuperWord::same_velt_type(Node* n1, Node* n2) {
+  const Type* vt1 = velt_type(n1);
+  const Type* vt2 = velt_type(n2);
+  if (vt1->basic_type() == T_INT && vt2->basic_type() == T_INT) {
+    // Compare vectors element sizes for integer types.
+    return data_size(n1) == data_size(n2);
   }
-  *start = 1;
-  *end   = n->req(); // default is all operands
+  return vt1 == vt2;
 }
 
 //------------------------------in_packset---------------------------
@@ -1733,12 +1983,13 @@
   assert(orig_limit != NULL && _igvn.type(orig_limit) != Type::TOP, "");
 
   SWPointer align_to_ref_p(align_to_ref, this);
+  assert(align_to_ref_p.valid(), "sanity");
 
   // Given:
   //     lim0 == original pre loop limit
   //     V == v_align (power of 2)
   //     invar == extra invariant piece of the address expression
-  //     e == k [ +/- invar ]
+  //     e == offset [ +/- invar ]
   //
   // When reassociating expressions involving '%' the basic rules are:
   //     (a - b) % k == 0   =>  a % k == b % k
@@ -1785,66 +2036,86 @@
   //     N = (V - (e - lim0)) % V
   //     lim = lim0 - (V - (e - lim0)) % V
 
+  int vw = vector_width_in_bytes(align_to_ref);
   int stride   = iv_stride();
   int scale    = align_to_ref_p.scale_in_bytes();
   int elt_size = align_to_ref_p.memory_size();
-  int v_align  = vector_width_in_bytes() / elt_size;
-  int k        = align_to_ref_p.offset_in_bytes() / elt_size;
+  int v_align  = vw / elt_size;
+  assert(v_align > 1, "sanity");
+  int offset   = align_to_ref_p.offset_in_bytes() / elt_size;
+  Node *offsn  = _igvn.intcon(offset);
 
-  Node *kn   = _igvn.intcon(k);
-
-  Node *e = kn;
+  Node *e = offsn;
   if (align_to_ref_p.invar() != NULL) {
-    // incorporate any extra invariant piece producing k +/- invar >>> log2(elt)
+    // incorporate any extra invariant piece producing (offset +/- invar) >>> log2(elt)
     Node* log2_elt = _igvn.intcon(exact_log2(elt_size));
-    Node* aref     = new (_phase->C, 3) URShiftINode(align_to_ref_p.invar(), log2_elt);
-    _phase->_igvn.register_new_node_with_optimizer(aref);
+    Node* aref     = new (_phase->C) URShiftINode(align_to_ref_p.invar(), log2_elt);
+    _igvn.register_new_node_with_optimizer(aref);
     _phase->set_ctrl(aref, pre_ctrl);
     if (align_to_ref_p.negate_invar()) {
-      e = new (_phase->C, 3) SubINode(e, aref);
+      e = new (_phase->C) SubINode(e, aref);
     } else {
-      e = new (_phase->C, 3) AddINode(e, aref);
+      e = new (_phase->C) AddINode(e, aref);
     }
-    _phase->_igvn.register_new_node_with_optimizer(e);
+    _igvn.register_new_node_with_optimizer(e);
+    _phase->set_ctrl(e, pre_ctrl);
+  }
+  if (vw > ObjectAlignmentInBytes) {
+    // incorporate base e +/- base && Mask >>> log2(elt)
+    Node* xbase = new(_phase->C) CastP2XNode(NULL, align_to_ref_p.base());
+    _igvn.register_new_node_with_optimizer(xbase);
+#ifdef _LP64
+    xbase  = new (_phase->C) ConvL2INode(xbase);
+    _igvn.register_new_node_with_optimizer(xbase);
+#endif
+    Node* mask = _igvn.intcon(vw-1);
+    Node* masked_xbase  = new (_phase->C) AndINode(xbase, mask);
+    _igvn.register_new_node_with_optimizer(masked_xbase);
+    Node* log2_elt = _igvn.intcon(exact_log2(elt_size));
+    Node* bref     = new (_phase->C) URShiftINode(masked_xbase, log2_elt);
+    _igvn.register_new_node_with_optimizer(bref);
+    _phase->set_ctrl(bref, pre_ctrl);
+    e = new (_phase->C) AddINode(e, bref);
+    _igvn.register_new_node_with_optimizer(e);
     _phase->set_ctrl(e, pre_ctrl);
   }
 
   // compute e +/- lim0
   if (scale < 0) {
-    e = new (_phase->C, 3) SubINode(e, lim0);
+    e = new (_phase->C) SubINode(e, lim0);
   } else {
-    e = new (_phase->C, 3) AddINode(e, lim0);
+    e = new (_phase->C) AddINode(e, lim0);
   }
-  _phase->_igvn.register_new_node_with_optimizer(e);
+  _igvn.register_new_node_with_optimizer(e);
   _phase->set_ctrl(e, pre_ctrl);
 
   if (stride * scale > 0) {
     // compute V - (e +/- lim0)
     Node* va  = _igvn.intcon(v_align);
-    e = new (_phase->C, 3) SubINode(va, e);
-    _phase->_igvn.register_new_node_with_optimizer(e);
+    e = new (_phase->C) SubINode(va, e);
+    _igvn.register_new_node_with_optimizer(e);
     _phase->set_ctrl(e, pre_ctrl);
   }
   // compute N = (exp) % V
   Node* va_msk = _igvn.intcon(v_align - 1);
-  Node* N = new (_phase->C, 3) AndINode(e, va_msk);
-  _phase->_igvn.register_new_node_with_optimizer(N);
+  Node* N = new (_phase->C) AndINode(e, va_msk);
+  _igvn.register_new_node_with_optimizer(N);
   _phase->set_ctrl(N, pre_ctrl);
 
   //   substitute back into (1), so that new limit
   //     lim = lim0 + N
   Node* lim;
   if (stride < 0) {
-    lim = new (_phase->C, 3) SubINode(lim0, N);
+    lim = new (_phase->C) SubINode(lim0, N);
   } else {
-    lim = new (_phase->C, 3) AddINode(lim0, N);
+    lim = new (_phase->C) AddINode(lim0, N);
   }
-  _phase->_igvn.register_new_node_with_optimizer(lim);
+  _igvn.register_new_node_with_optimizer(lim);
   _phase->set_ctrl(lim, pre_ctrl);
   Node* constrained =
-    (stride > 0) ? (Node*) new (_phase->C,3) MinINode(lim, orig_limit)
-                 : (Node*) new (_phase->C,3) MaxINode(lim, orig_limit);
-  _phase->_igvn.register_new_node_with_optimizer(constrained);
+    (stride > 0) ? (Node*) new (_phase->C) MinINode(lim, orig_limit)
+                 : (Node*) new (_phase->C) MaxINode(lim, orig_limit);
+  _igvn.register_new_node_with_optimizer(constrained);
   _phase->set_ctrl(constrained, pre_ctrl);
   _igvn.hash_delete(pre_opaq);
   pre_opaq->set_req(1, constrained);
diff --git a/hotspot/src/share/vm/opto/superword.hpp b/hotspot/src/share/vm/opto/superword.hpp
index 5093767..45c0f9a 100644
--- a/hotspot/src/share/vm/opto/superword.hpp
+++ b/hotspot/src/share/vm/opto/superword.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, 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
@@ -264,8 +264,14 @@
                                      _iv = lp->as_CountedLoop()->phi()->as_Phi(); }
   int      iv_stride()             { return lp()->as_CountedLoop()->stride_con(); }
 
-  int vector_width_in_bytes()      { return Matcher::vector_width_in_bytes(); }
-
+  int vector_width(Node* n) {
+    BasicType bt = velt_basic_type(n);
+    return MIN2(ABS(iv_stride()), Matcher::max_vector_size(bt));
+  }
+  int vector_width_in_bytes(Node* n) {
+    BasicType bt = velt_basic_type(n);
+    return vector_width(n)*type2aelembytes(bt);
+  }
   MemNode* align_to_ref()            { return _align_to_ref; }
   void  set_align_to_ref(MemNode* m) { _align_to_ref = m; }
 
@@ -298,7 +304,9 @@
 
   // vector element type
   const Type* velt_type(Node* n)             { return _node_info.adr_at(bb_idx(n))->_velt_type; }
+  BasicType velt_basic_type(Node* n)         { return velt_type(n)->array_element_basic_type(); }
   void set_velt_type(Node* n, const Type* t) { int i = bb_idx(n); grow_node_info(i); _node_info.adr_at(i)->_velt_type = t; }
+  bool same_velt_type(Node* n1, Node* n2);
 
   // my_pack
   Node_List* my_pack(Node* n)                { return !in_bb(n) ? NULL : _node_info.adr_at(bb_idx(n))->_my_pack; }
@@ -311,7 +319,9 @@
   // Find the adjacent memory references and create pack pairs for them.
   void find_adjacent_refs();
   // Find a memory reference to align the loop induction variable to.
-  void find_align_to_ref(Node_List &memops);
+  MemNode* find_align_to_ref(Node_List &memops);
+  // Calculate loop's iv adjustment for this memory ops.
+  int get_iv_adjustment(MemNode* mem);
   // Can the preloop align the reference to position zero in the vector?
   bool ref_is_alignable(SWPointer& p);
   // Construct dependency graph.
@@ -390,11 +400,11 @@
   // Return the node executed last in pack p.
   Node* executed_last(Node_List* p);
   // Alignment within a vector memory reference
-  int memory_alignment(MemNode* s, int iv_adjust_in_bytes);
+  int memory_alignment(MemNode* s, int iv_adjust);
   // (Start, end] half-open range defining which operands are vector
   void vector_opd_range(Node* n, uint* start, uint* end);
   // Smallest type containing range of values
-  static const Type* container_type(const Type* t);
+  const Type* container_type(Node* n);
   // Adjust pre-loop limit so that in main loop, a load/store reference
   // to align_to_ref will be a position zero in the vector.
   void align_initial_loop_index(MemNode* align_to_ref);
@@ -462,6 +472,7 @@
 
   Node* base()            { return _base; }
   Node* adr()             { return _adr; }
+  MemNode* mem()          { return _mem; }
   int   scale_in_bytes()  { return _scale; }
   Node* invar()           { return _invar; }
   bool  negate_invar()    { return _negate_invar; }
diff --git a/hotspot/src/share/vm/opto/type.cpp b/hotspot/src/share/vm/opto/type.cpp
index 2ae0db6..80d5830 100644
--- a/hotspot/src/share/vm/opto/type.cpp
+++ b/hotspot/src/share/vm/opto/type.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,6 +60,10 @@
 
   T_ILLEGAL,    // Tuple
   T_ARRAY,      // Array
+  T_ILLEGAL,    // VectorS
+  T_ILLEGAL,    // VectorD
+  T_ILLEGAL,    // VectorX
+  T_ILLEGAL,    // VectorY
 
   T_ADDRESS,    // AnyPtr   // shows up in factory methods for NULL_PTR
   T_ADDRESS,    // RawPtr
@@ -208,7 +212,7 @@
   // locking.
 
   Arena* save = current->type_arena();
-  Arena* shared_type_arena = new Arena();
+  Arena* shared_type_arena = new (mtCompiler)Arena();
 
   current->set_type_arena(shared_type_arena);
   _shared_type_dict =
@@ -414,6 +418,24 @@
   // get_zero_type() should not happen for T_CONFLICT
   _zero_type[T_CONFLICT]= NULL;
 
+  // Vector predefined types, it needs initialized _const_basic_type[].
+  if (Matcher::vector_size_supported(T_BYTE,4)) {
+    TypeVect::VECTS = TypeVect::make(T_BYTE,4);
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,2)) {
+    TypeVect::VECTD = TypeVect::make(T_FLOAT,2);
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,4)) {
+    TypeVect::VECTX = TypeVect::make(T_FLOAT,4);
+  }
+  if (Matcher::vector_size_supported(T_FLOAT,8)) {
+    TypeVect::VECTY = TypeVect::make(T_FLOAT,8);
+  }
+  mreg2type[Op_VecS] = TypeVect::VECTS;
+  mreg2type[Op_VecD] = TypeVect::VECTD;
+  mreg2type[Op_VecX] = TypeVect::VECTX;
+  mreg2type[Op_VecY] = TypeVect::VECTY;
+
   // Restore working type arena.
   current->set_type_arena(save);
   current->set_type_dict(NULL);
@@ -668,6 +690,10 @@
 
   Bad,          // Tuple - handled in v-call
   Bad,          // Array - handled in v-call
+  Bad,          // VectorS - handled in v-call
+  Bad,          // VectorD - handled in v-call
+  Bad,          // VectorX - handled in v-call
+  Bad,          // VectorY - handled in v-call
 
   Bad,          // AnyPtr - handled in v-call
   Bad,          // RawPtr - handled in v-call
@@ -728,8 +754,8 @@
 //------------------------------data-------------------------------------------
 const char * const Type::msg[Type::lastype] = {
   "bad","control","top","int:","long:","half", "narrowoop:",
-  "tuple:", "aryptr",
-  "anyptr:", "rawptr:", "java:", "inst:", "ary:", "klass:",
+  "tuple:", "array:", "vectors:", "vectord:", "vectorx:", "vectory:",
+  "anyptr:", "rawptr:", "java:", "inst:", "aryptr:", "klass:",
   "func", "abIO", "return_address", "memory",
   "float_top", "ftcon:", "float",
   "double_top", "dblcon:", "double",
@@ -790,7 +816,7 @@
 //------------------------------isa_oop_ptr------------------------------------
 // Return true if type is an oop pointer type.  False for raw pointers.
 static char isa_oop_ptr_tbl[Type::lastype] = {
-  0,0,0,0,0,0,0/*narrowoop*/,0/*tuple*/, 0/*ary*/,
+  0,0,0,0,0,0,0/*narrowoop*/,0/*tuple*/, 0/*array*/, 0, 0, 0, 0/*vector*/,
   0/*anyptr*/,0/*rawptr*/,1/*OopPtr*/,1/*InstPtr*/,1/*AryPtr*/,1/*KlassPtr*/,
   0/*func*/,0,0/*return_address*/,0,
   /*floats*/0,0,0, /*doubles*/0,0,0,
@@ -1926,6 +1952,121 @@
   return false;
 }
 
+//==============================TypeVect=======================================
+// Convenience common pre-built types.
+const TypeVect *TypeVect::VECTS = NULL; //  32-bit vectors
+const TypeVect *TypeVect::VECTD = NULL; //  64-bit vectors
+const TypeVect *TypeVect::VECTX = NULL; // 128-bit vectors
+const TypeVect *TypeVect::VECTY = NULL; // 256-bit vectors
+
+//------------------------------make-------------------------------------------
+const TypeVect* TypeVect::make(const Type *elem, uint length) {
+  BasicType elem_bt = elem->array_element_basic_type();
+  assert(is_java_primitive(elem_bt), "only primitive types in vector");
+  assert(length > 1 && is_power_of_2(length), "vector length is power of 2");
+  assert(Matcher::vector_size_supported(elem_bt, length), "length in range");
+  int size = length * type2aelembytes(elem_bt);
+  switch (Matcher::vector_ideal_reg(size)) {
+  case Op_VecS:
+    return (TypeVect*)(new TypeVectS(elem, length))->hashcons();
+  case Op_VecD:
+  case Op_RegD:
+    return (TypeVect*)(new TypeVectD(elem, length))->hashcons();
+  case Op_VecX:
+    return (TypeVect*)(new TypeVectX(elem, length))->hashcons();
+  case Op_VecY:
+    return (TypeVect*)(new TypeVectY(elem, length))->hashcons();
+  }
+ ShouldNotReachHere();
+  return NULL;
+}
+
+//------------------------------meet-------------------------------------------
+// Compute the MEET of two types.  It returns a new Type object.
+const Type *TypeVect::xmeet( const Type *t ) const {
+  // Perform a fast test for common case; meeting the same types together.
+  if( this == t ) return this;  // Meeting same type-rep?
+
+  // Current "this->_base" is Vector
+  switch (t->base()) {          // switch on original type
+
+  case Bottom:                  // Ye Olde Default
+    return t;
+
+  default:                      // All else is a mistake
+    typerr(t);
+
+  case VectorS:
+  case VectorD:
+  case VectorX:
+  case VectorY: {                // Meeting 2 vectors?
+    const TypeVect* v = t->is_vect();
+    assert(  base() == v->base(), "");
+    assert(length() == v->length(), "");
+    assert(element_basic_type() == v->element_basic_type(), "");
+    return TypeVect::make(_elem->xmeet(v->_elem), _length);
+  }
+  case Top:
+    break;
+  }
+  return this;
+}
+
+//------------------------------xdual------------------------------------------
+// Dual: compute field-by-field dual
+const Type *TypeVect::xdual() const {
+  return new TypeVect(base(), _elem->dual(), _length);
+}
+
+//------------------------------eq---------------------------------------------
+// Structural equality check for Type representations
+bool TypeVect::eq(const Type *t) const {
+  const TypeVect *v = t->is_vect();
+  return (_elem == v->_elem) && (_length == v->_length);
+}
+
+//------------------------------hash-------------------------------------------
+// Type-specific hashing function.
+int TypeVect::hash(void) const {
+  return (intptr_t)_elem + (intptr_t)_length;
+}
+
+//------------------------------singleton--------------------------------------
+// TRUE if Type is a singleton type, FALSE otherwise.   Singletons are simple
+// constants (Ldi nodes).  Vector is singleton if all elements are the same
+// constant value (when vector is created with Replicate code).
+bool TypeVect::singleton(void) const {
+// There is no Con node for vectors yet.
+//  return _elem->singleton();
+  return false;
+}
+
+bool TypeVect::empty(void) const {
+  return _elem->empty();
+}
+
+//------------------------------dump2------------------------------------------
+#ifndef PRODUCT
+void TypeVect::dump2(Dict &d, uint depth, outputStream *st) const {
+  switch (base()) {
+  case VectorS:
+    st->print("vectors["); break;
+  case VectorD:
+    st->print("vectord["); break;
+  case VectorX:
+    st->print("vectorx["); break;
+  case VectorY:
+    st->print("vectory["); break;
+  default:
+    ShouldNotReachHere();
+  }
+  st->print("%d]:{", _length);
+  _elem->dump2(d, depth, st);
+  st->print("}");
+}
+#endif
+
+
 //=============================================================================
 // Convenience common pre-built types.
 const TypePtr *TypePtr::NULL_PTR;
@@ -4144,7 +4285,7 @@
 // Print a 'flattened' signature
 static const char * const flat_type_msg[Type::lastype] = {
   "bad","control","top","int","long","_", "narrowoop",
-  "tuple:", "array:",
+  "tuple:", "array:", "vectors:", "vectord:", "vectorx:", "vectory:",
   "ptr", "rawptr", "ptr", "ptr", "ptr", "ptr",
   "func", "abIO", "return_address", "mem",
   "float_top", "ftcon:", "flt",
diff --git a/hotspot/src/share/vm/opto/type.hpp b/hotspot/src/share/vm/opto/type.hpp
index 133ce78..a4b5487 100644
--- a/hotspot/src/share/vm/opto/type.hpp
+++ b/hotspot/src/share/vm/opto/type.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -51,6 +51,11 @@
 class   TypeNarrowOop;
 class   TypeAry;
 class   TypeTuple;
+class   TypeVect;
+class     TypeVectS;
+class     TypeVectD;
+class     TypeVectX;
+class     TypeVectY;
 class   TypePtr;
 class     TypeRawPtr;
 class     TypeOopPtr;
@@ -78,6 +83,10 @@
 
     Tuple,                      // Method signature or object layout
     Array,                      // Array types
+    VectorS,                    //  32bit Vector types
+    VectorD,                    //  64bit Vector types
+    VectorX,                    // 128bit Vector types
+    VectorY,                    // 256bit Vector types
 
     AnyPtr,                     // Any old raw, klass, inst, or array pointer
     RawPtr,                     // Raw (non-oop) pointers
@@ -222,6 +231,8 @@
   const TypeF      *isa_float_constant() const;  // Returns NULL if not a FloatCon
   const TypeTuple  *is_tuple() const;            // Collection of fields, NOT a pointer
   const TypeAry    *is_ary() const;              // Array, NOT array pointer
+  const TypeVect   *is_vect() const;             // Vector
+  const TypeVect   *isa_vect() const;            // Returns NULL if not a Vector
   const TypePtr    *is_ptr() const;              // Asserts it is a ptr type
   const TypePtr    *isa_ptr() const;             // Returns NULL if not ptr type
   const TypeRawPtr *isa_rawptr() const;          // NOT Java oop
@@ -574,6 +585,69 @@
 #endif
 };
 
+//------------------------------TypeVect---------------------------------------
+// Class of Vector Types
+class TypeVect : public Type {
+  const Type*   _elem;  // Vector's element type
+  const uint  _length;  // Elements in vector (power of 2)
+
+protected:
+  TypeVect(TYPES t, const Type* elem, uint length) : Type(t),
+    _elem(elem), _length(length) {}
+
+public:
+  const Type* element_type() const { return _elem; }
+  BasicType element_basic_type() const { return _elem->array_element_basic_type(); }
+  uint length() const { return _length; }
+  uint length_in_bytes() const {
+   return _length * type2aelembytes(element_basic_type());
+  }
+
+  virtual bool eq(const Type *t) const;
+  virtual int  hash() const;             // Type specific hashing
+  virtual bool singleton(void) const;    // TRUE if type is a singleton
+  virtual bool empty(void) const;        // TRUE if type is vacuous
+
+  static const TypeVect *make(const BasicType elem_bt, uint length) {
+    // Use bottom primitive type.
+    return make(get_const_basic_type(elem_bt), length);
+  }
+  // Used directly by Replicate nodes to construct singleton vector.
+  static const TypeVect *make(const Type* elem, uint length);
+
+  virtual const Type *xmeet( const Type *t) const;
+  virtual const Type *xdual() const;     // Compute dual right now.
+
+  static const TypeVect *VECTS;
+  static const TypeVect *VECTD;
+  static const TypeVect *VECTX;
+  static const TypeVect *VECTY;
+
+#ifndef PRODUCT
+  virtual void dump2(Dict &d, uint, outputStream *st) const; // Specialized per-Type dumping
+#endif
+};
+
+class TypeVectS : public TypeVect {
+  friend class TypeVect;
+  TypeVectS(const Type* elem, uint length) : TypeVect(VectorS, elem, length) {}
+};
+
+class TypeVectD : public TypeVect {
+  friend class TypeVect;
+  TypeVectD(const Type* elem, uint length) : TypeVect(VectorD, elem, length) {}
+};
+
+class TypeVectX : public TypeVect {
+  friend class TypeVect;
+  TypeVectX(const Type* elem, uint length) : TypeVect(VectorX, elem, length) {}
+};
+
+class TypeVectY : public TypeVect {
+  friend class TypeVect;
+  TypeVectY(const Type* elem, uint length) : TypeVect(VectorY, elem, length) {}
+};
+
 //------------------------------TypePtr----------------------------------------
 // Class of machine Pointer Types: raw data, instances or arrays.
 // If the _base enum is AnyPtr, then this refers to all of the above.
@@ -1113,6 +1187,15 @@
   return (TypeAry*)this;
 }
 
+inline const TypeVect *Type::is_vect() const {
+  assert( _base >= VectorS && _base <= VectorY, "Not a Vector" );
+  return (TypeVect*)this;
+}
+
+inline const TypeVect *Type::isa_vect() const {
+  return (_base >= VectorS && _base <= VectorY) ? (TypeVect*)this : NULL;
+}
+
 inline const TypePtr *Type::is_ptr() const {
   // AnyPtr is the first Ptr and KlassPtr the last, with no non-ptrs between.
   assert(_base >= AnyPtr && _base <= KlassPtr, "Not a pointer");
diff --git a/hotspot/src/share/vm/opto/vectornode.cpp b/hotspot/src/share/vm/opto/vectornode.cpp
index 885a1c8..9660d4e 100644
--- a/hotspot/src/share/vm/opto/vectornode.cpp
+++ b/hotspot/src/share/vm/opto/vectornode.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,147 +28,15 @@
 
 //------------------------------VectorNode--------------------------------------
 
-// Return vector type for an element type and vector length.
-const Type* VectorNode::vect_type(BasicType elt_bt, uint len) {
-  assert(len <= VectorNode::max_vlen(elt_bt), "len in range");
-  switch(elt_bt) {
-  case T_BOOLEAN:
-  case T_BYTE:
-    switch(len) {
-    case 2:  return TypeInt::CHAR;
-    case 4:  return TypeInt::INT;
-    case 8:  return TypeLong::LONG;
-    }
-    break;
-  case T_CHAR:
-  case T_SHORT:
-    switch(len) {
-    case 2:  return TypeInt::INT;
-    case 4:  return TypeLong::LONG;
-    }
-    break;
-  case T_INT:
-    switch(len) {
-    case 2:  return TypeLong::LONG;
-    }
-    break;
-  case T_LONG:
-    break;
-  case T_FLOAT:
-    switch(len) {
-    case 2:  return Type::DOUBLE;
-    }
-    break;
-  case T_DOUBLE:
-    break;
-  }
-  ShouldNotReachHere();
-  return NULL;
-}
-
-// Scalar promotion
-VectorNode* VectorNode::scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t) {
-  BasicType bt = opd_t->array_element_basic_type();
-  assert(vlen <= VectorNode::max_vlen(bt), "vlen in range");
-  switch (bt) {
-  case T_BOOLEAN:
-  case T_BYTE:
-    if (vlen == 16) return new (C, 2) Replicate16BNode(s);
-    if (vlen ==  8) return new (C, 2) Replicate8BNode(s);
-    if (vlen ==  4) return new (C, 2) Replicate4BNode(s);
-    break;
-  case T_CHAR:
-    if (vlen == 8) return new (C, 2) Replicate8CNode(s);
-    if (vlen == 4) return new (C, 2) Replicate4CNode(s);
-    if (vlen == 2) return new (C, 2) Replicate2CNode(s);
-    break;
-  case T_SHORT:
-    if (vlen == 8) return new (C, 2) Replicate8SNode(s);
-    if (vlen == 4) return new (C, 2) Replicate4SNode(s);
-    if (vlen == 2) return new (C, 2) Replicate2SNode(s);
-    break;
-  case T_INT:
-    if (vlen == 4) return new (C, 2) Replicate4INode(s);
-    if (vlen == 2) return new (C, 2) Replicate2INode(s);
-    break;
-  case T_LONG:
-    if (vlen == 2) return new (C, 2) Replicate2LNode(s);
-    break;
-  case T_FLOAT:
-    if (vlen == 4) return new (C, 2) Replicate4FNode(s);
-    if (vlen == 2) return new (C, 2) Replicate2FNode(s);
-    break;
-  case T_DOUBLE:
-    if (vlen == 2) return new (C, 2) Replicate2DNode(s);
-    break;
-  }
-  ShouldNotReachHere();
-  return NULL;
-}
-
-// Return initial Pack node. Additional operands added with add_opd() calls.
-PackNode* PackNode::make(Compile* C, Node* s, const Type* opd_t) {
-  BasicType bt = opd_t->array_element_basic_type();
-  switch (bt) {
-  case T_BOOLEAN:
-  case T_BYTE:
-    return new (C, 2) PackBNode(s);
-  case T_CHAR:
-    return new (C, 2) PackCNode(s);
-  case T_SHORT:
-    return new (C, 2) PackSNode(s);
-  case T_INT:
-    return new (C, 2) PackINode(s);
-  case T_LONG:
-    return new (C, 2) PackLNode(s);
-  case T_FLOAT:
-    return new (C, 2) PackFNode(s);
-  case T_DOUBLE:
-    return new (C, 2) PackDNode(s);
-  }
-  ShouldNotReachHere();
-  return NULL;
-}
-
-// Create a binary tree form for Packs. [lo, hi) (half-open) range
-Node* PackNode::binaryTreePack(Compile* C, int lo, int hi) {
-  int ct = hi - lo;
-  assert(is_power_of_2(ct), "power of 2");
-  int mid = lo + ct/2;
-  Node* n1 = ct == 2 ? in(lo)   : binaryTreePack(C, lo,  mid);
-  Node* n2 = ct == 2 ? in(lo+1) : binaryTreePack(C, mid, hi );
-  int rslt_bsize = ct * type2aelembytes(elt_basic_type());
-  if (bottom_type()->is_floatingpoint()) {
-    switch (rslt_bsize) {
-    case  8: return new (C, 3) PackFNode(n1, n2);
-    case 16: return new (C, 3) PackDNode(n1, n2);
-    }
-  } else {
-    assert(bottom_type()->isa_int() || bottom_type()->isa_long(), "int or long");
-    switch (rslt_bsize) {
-    case  2: return new (C, 3) Pack2x1BNode(n1, n2);
-    case  4: return new (C, 3) Pack2x2BNode(n1, n2);
-    case  8: return new (C, 3) PackINode(n1, n2);
-    case 16: return new (C, 3) PackLNode(n1, n2);
-    }
-  }
-  ShouldNotReachHere();
-  return NULL;
-}
-
 // Return the vector operator for the specified scalar operation
-// and vector length.  One use is to check if the code generator
-// supports the vector operation.
-int VectorNode::opcode(int sopc, uint vlen, const Type* opd_t) {
-  BasicType bt = opd_t->array_element_basic_type();
-  if (!(is_power_of_2(vlen) && vlen <= max_vlen(bt)))
-    return 0; // unimplemented
+// and vector length.
+int VectorNode::opcode(int sopc, BasicType bt) {
   switch (sopc) {
   case Op_AddI:
     switch (bt) {
     case T_BOOLEAN:
     case T_BYTE:      return Op_AddVB;
-    case T_CHAR:      return Op_AddVC;
+    case T_CHAR:
     case T_SHORT:     return Op_AddVS;
     case T_INT:       return Op_AddVI;
     }
@@ -186,7 +54,7 @@
     switch (bt) {
     case T_BOOLEAN:
     case T_BYTE:   return Op_SubVB;
-    case T_CHAR:   return Op_SubVC;
+    case T_CHAR:
     case T_SHORT:  return Op_SubVS;
     case T_INT:    return Op_SubVI;
     }
@@ -200,6 +68,15 @@
   case Op_SubD:
     assert(bt == T_DOUBLE, "must be");
     return Op_SubVD;
+  case Op_MulI:
+    switch (bt) {
+    case T_BOOLEAN:
+    case T_BYTE:   return 0;   // Unimplemented
+    case T_CHAR:
+    case T_SHORT:  return Op_MulVS;
+    case T_INT:    return Op_MulVI;
+    }
+    ShouldNotReachHere();
   case Op_MulF:
     assert(bt == T_FLOAT, "must be");
     return Op_MulVF;
@@ -216,20 +93,42 @@
     switch (bt) {
     case T_BOOLEAN:
     case T_BYTE:   return Op_LShiftVB;
-    case T_CHAR:   return Op_LShiftVC;
+    case T_CHAR:
     case T_SHORT:  return Op_LShiftVS;
     case T_INT:    return Op_LShiftVI;
     }
     ShouldNotReachHere();
+  case Op_LShiftL:
+    assert(bt == T_LONG, "must be");
+    return Op_LShiftVL;
+  case Op_RShiftI:
+    switch (bt) {
+    case T_BOOLEAN:return Op_URShiftVB; // boolean is unsigned value
+    case T_CHAR:   return Op_URShiftVS; // char is unsigned value
+    case T_BYTE:   return Op_RShiftVB;
+    case T_SHORT:  return Op_RShiftVS;
+    case T_INT:    return Op_RShiftVI;
+    }
+    ShouldNotReachHere();
+  case Op_RShiftL:
+    assert(bt == T_LONG, "must be");
+    return Op_RShiftVL;
   case Op_URShiftI:
     switch (bt) {
-    case T_BOOLEAN:
-    case T_BYTE:   return Op_URShiftVB;
-    case T_CHAR:   return Op_URShiftVC;
-    case T_SHORT:  return Op_URShiftVS;
+    case T_BOOLEAN:return Op_URShiftVB;
+    case T_CHAR:   return Op_URShiftVS;
+    case T_BYTE:
+    case T_SHORT:  return 0; // Vector logical right shift for signed short
+                             // values produces incorrect Java result for
+                             // negative data because java code should convert
+                             // a short value into int value with sign
+                             // extension before a shift.
     case T_INT:    return Op_URShiftVI;
     }
     ShouldNotReachHere();
+  case Op_URShiftL:
+    assert(bt == T_LONG, "must be");
+    return Op_URShiftVL;
   case Op_AndI:
   case Op_AndL:
     return Op_AndV;
@@ -241,13 +140,14 @@
     return Op_XorV;
 
   case Op_LoadB:
+  case Op_LoadUB:
   case Op_LoadUS:
   case Op_LoadS:
   case Op_LoadI:
   case Op_LoadL:
   case Op_LoadF:
   case Op_LoadD:
-    return VectorLoadNode::opcode(sopc, vlen);
+    return Op_LoadVector;
 
   case Op_StoreB:
   case Op_StoreC:
@@ -255,226 +155,289 @@
   case Op_StoreL:
   case Op_StoreF:
   case Op_StoreD:
-    return VectorStoreNode::opcode(sopc, vlen);
+    return Op_StoreVector;
   }
   return 0; // Unimplemented
 }
 
-// Helper for above.
-int VectorLoadNode::opcode(int sopc, uint vlen) {
-  switch (sopc) {
-  case Op_LoadB:
-    switch (vlen) {
-    case  2:       return 0; // Unimplemented
-    case  4:       return Op_Load4B;
-    case  8:       return Op_Load8B;
-    case 16:       return Op_Load16B;
-    }
-    break;
-  case Op_LoadUS:
-    switch (vlen) {
-    case  2:       return Op_Load2C;
-    case  4:       return Op_Load4C;
-    case  8:       return Op_Load8C;
-    }
-    break;
-  case Op_LoadS:
-    switch (vlen) {
-    case  2:       return Op_Load2S;
-    case  4:       return Op_Load4S;
-    case  8:       return Op_Load8S;
-    }
-    break;
-  case Op_LoadI:
-    switch (vlen) {
-    case  2:       return Op_Load2I;
-    case  4:       return Op_Load4I;
-    }
-    break;
-  case Op_LoadL:
-    if (vlen == 2) return Op_Load2L;
-    break;
-  case Op_LoadF:
-    switch (vlen) {
-    case  2:       return Op_Load2F;
-    case  4:       return Op_Load4F;
-    }
-    break;
-  case Op_LoadD:
-    if (vlen == 2) return Op_Load2D;
-    break;
+// Also used to check if the code generator
+// supports the vector operation.
+bool VectorNode::implemented(int opc, uint vlen, BasicType bt) {
+  if (is_java_primitive(bt) &&
+      (vlen > 1) && is_power_of_2(vlen) &&
+      Matcher::vector_size_supported(bt, vlen)) {
+    int vopc = VectorNode::opcode(opc, bt);
+    return vopc > 0 && Matcher::match_rule_supported(vopc);
   }
-  return 0; // Unimplemented
+  return false;
 }
 
-// Helper for above
-int VectorStoreNode::opcode(int sopc, uint vlen) {
-  switch (sopc) {
-  case Op_StoreB:
-    switch (vlen) {
-    case  2:       return 0; // Unimplemented
-    case  4:       return Op_Store4B;
-    case  8:       return Op_Store8B;
-    case 16:       return Op_Store16B;
-    }
-    break;
-  case Op_StoreC:
-    switch (vlen) {
-    case  2:       return Op_Store2C;
-    case  4:       return Op_Store4C;
-    case  8:       return Op_Store8C;
-    }
-    break;
-  case Op_StoreI:
-    switch (vlen) {
-    case  2:       return Op_Store2I;
-    case  4:       return Op_Store4I;
-    }
-    break;
-  case Op_StoreL:
-    if (vlen == 2) return Op_Store2L;
-    break;
-  case Op_StoreF:
-    switch (vlen) {
-    case  2:       return Op_Store2F;
-    case  4:       return Op_Store4F;
-    }
-    break;
-  case Op_StoreD:
-    if (vlen == 2) return Op_Store2D;
-    break;
+bool VectorNode::is_shift(Node* n) {
+  switch (n->Opcode()) {
+  case Op_LShiftI:
+  case Op_LShiftL:
+  case Op_RShiftI:
+  case Op_RShiftL:
+  case Op_URShiftI:
+  case Op_URShiftL:
+    return true;
   }
-  return 0; // Unimplemented
+  return false;
+}
+
+// Check if input is loop invariant vector.
+bool VectorNode::is_invariant_vector(Node* n) {
+  // Only Replicate vector nodes are loop invariant for now.
+  switch (n->Opcode()) {
+  case Op_ReplicateB:
+  case Op_ReplicateS:
+  case Op_ReplicateI:
+  case Op_ReplicateL:
+  case Op_ReplicateF:
+  case Op_ReplicateD:
+    return true;
+  }
+  return false;
+}
+
+// [Start, end) half-open range defining which operands are vectors
+void VectorNode::vector_operands(Node* n, uint* start, uint* end) {
+  switch (n->Opcode()) {
+  case Op_LoadB:   case Op_LoadUB:
+  case Op_LoadS:   case Op_LoadUS:
+  case Op_LoadI:   case Op_LoadL:
+  case Op_LoadF:   case Op_LoadD:
+  case Op_LoadP:   case Op_LoadN:
+    *start = 0;
+    *end   = 0; // no vector operands
+    break;
+  case Op_StoreB:  case Op_StoreC:
+  case Op_StoreI:  case Op_StoreL:
+  case Op_StoreF:  case Op_StoreD:
+  case Op_StoreP:  case Op_StoreN:
+    *start = MemNode::ValueIn;
+    *end   = MemNode::ValueIn + 1; // 1 vector operand
+    break;
+  case Op_LShiftI:  case Op_LShiftL:
+  case Op_RShiftI:  case Op_RShiftL:
+  case Op_URShiftI: case Op_URShiftL:
+    *start = 1;
+    *end   = 2; // 1 vector operand
+    break;
+  case Op_AddI: case Op_AddL: case Op_AddF: case Op_AddD:
+  case Op_SubI: case Op_SubL: case Op_SubF: case Op_SubD:
+  case Op_MulI: case Op_MulL: case Op_MulF: case Op_MulD:
+  case Op_DivF: case Op_DivD:
+  case Op_AndI: case Op_AndL:
+  case Op_OrI:  case Op_OrL:
+  case Op_XorI: case Op_XorL:
+    *start = 1;
+    *end   = 3; // 2 vector operands
+    break;
+  case Op_CMoveI:  case Op_CMoveL:  case Op_CMoveF:  case Op_CMoveD:
+    *start = 2;
+    *end   = n->req();
+    break;
+  default:
+    *start = 1;
+    *end   = n->req(); // default is all operands
+  }
 }
 
 // Return the vector version of a scalar operation node.
-VectorNode* VectorNode::make(Compile* C, int sopc, Node* n1, Node* n2, uint vlen, const Type* opd_t) {
-  int vopc = opcode(sopc, vlen, opd_t);
+VectorNode* VectorNode::make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt) {
+  const TypeVect* vt = TypeVect::make(bt, vlen);
+  int vopc = VectorNode::opcode(opc, bt);
+  // This method should not be called for unimplemented vectors.
+  guarantee(vopc > 0, err_msg_res("Vector for '%s' is not implemented", NodeClassNames[opc]));
 
   switch (vopc) {
-  case Op_AddVB: return new (C, 3) AddVBNode(n1, n2, vlen);
-  case Op_AddVC: return new (C, 3) AddVCNode(n1, n2, vlen);
-  case Op_AddVS: return new (C, 3) AddVSNode(n1, n2, vlen);
-  case Op_AddVI: return new (C, 3) AddVINode(n1, n2, vlen);
-  case Op_AddVL: return new (C, 3) AddVLNode(n1, n2, vlen);
-  case Op_AddVF: return new (C, 3) AddVFNode(n1, n2, vlen);
-  case Op_AddVD: return new (C, 3) AddVDNode(n1, n2, vlen);
+  case Op_AddVB: return new (C) AddVBNode(n1, n2, vt);
+  case Op_AddVS: return new (C) AddVSNode(n1, n2, vt);
+  case Op_AddVI: return new (C) AddVINode(n1, n2, vt);
+  case Op_AddVL: return new (C) AddVLNode(n1, n2, vt);
+  case Op_AddVF: return new (C) AddVFNode(n1, n2, vt);
+  case Op_AddVD: return new (C) AddVDNode(n1, n2, vt);
 
-  case Op_SubVB: return new (C, 3) SubVBNode(n1, n2, vlen);
-  case Op_SubVC: return new (C, 3) SubVCNode(n1, n2, vlen);
-  case Op_SubVS: return new (C, 3) SubVSNode(n1, n2, vlen);
-  case Op_SubVI: return new (C, 3) SubVINode(n1, n2, vlen);
-  case Op_SubVL: return new (C, 3) SubVLNode(n1, n2, vlen);
-  case Op_SubVF: return new (C, 3) SubVFNode(n1, n2, vlen);
-  case Op_SubVD: return new (C, 3) SubVDNode(n1, n2, vlen);
+  case Op_SubVB: return new (C) SubVBNode(n1, n2, vt);
+  case Op_SubVS: return new (C) SubVSNode(n1, n2, vt);
+  case Op_SubVI: return new (C) SubVINode(n1, n2, vt);
+  case Op_SubVL: return new (C) SubVLNode(n1, n2, vt);
+  case Op_SubVF: return new (C) SubVFNode(n1, n2, vt);
+  case Op_SubVD: return new (C) SubVDNode(n1, n2, vt);
 
-  case Op_MulVF: return new (C, 3) MulVFNode(n1, n2, vlen);
-  case Op_MulVD: return new (C, 3) MulVDNode(n1, n2, vlen);
+  case Op_MulVS: return new (C) MulVSNode(n1, n2, vt);
+  case Op_MulVI: return new (C) MulVINode(n1, n2, vt);
+  case Op_MulVF: return new (C) MulVFNode(n1, n2, vt);
+  case Op_MulVD: return new (C) MulVDNode(n1, n2, vt);
 
-  case Op_DivVF: return new (C, 3) DivVFNode(n1, n2, vlen);
-  case Op_DivVD: return new (C, 3) DivVDNode(n1, n2, vlen);
+  case Op_DivVF: return new (C) DivVFNode(n1, n2, vt);
+  case Op_DivVD: return new (C) DivVDNode(n1, n2, vt);
 
-  case Op_LShiftVB: return new (C, 3) LShiftVBNode(n1, n2, vlen);
-  case Op_LShiftVC: return new (C, 3) LShiftVCNode(n1, n2, vlen);
-  case Op_LShiftVS: return new (C, 3) LShiftVSNode(n1, n2, vlen);
-  case Op_LShiftVI: return new (C, 3) LShiftVINode(n1, n2, vlen);
+  case Op_LShiftVB: return new (C) LShiftVBNode(n1, n2, vt);
+  case Op_LShiftVS: return new (C) LShiftVSNode(n1, n2, vt);
+  case Op_LShiftVI: return new (C) LShiftVINode(n1, n2, vt);
+  case Op_LShiftVL: return new (C) LShiftVLNode(n1, n2, vt);
 
-  case Op_URShiftVB: return new (C, 3) URShiftVBNode(n1, n2, vlen);
-  case Op_URShiftVC: return new (C, 3) URShiftVCNode(n1, n2, vlen);
-  case Op_URShiftVS: return new (C, 3) URShiftVSNode(n1, n2, vlen);
-  case Op_URShiftVI: return new (C, 3) URShiftVINode(n1, n2, vlen);
+  case Op_RShiftVB: return new (C) RShiftVBNode(n1, n2, vt);
+  case Op_RShiftVS: return new (C) RShiftVSNode(n1, n2, vt);
+  case Op_RShiftVI: return new (C) RShiftVINode(n1, n2, vt);
+  case Op_RShiftVL: return new (C) RShiftVLNode(n1, n2, vt);
 
-  case Op_AndV: return new (C, 3) AndVNode(n1, n2, vlen, opd_t->array_element_basic_type());
-  case Op_OrV:  return new (C, 3) OrVNode (n1, n2, vlen, opd_t->array_element_basic_type());
-  case Op_XorV: return new (C, 3) XorVNode(n1, n2, vlen, opd_t->array_element_basic_type());
+  case Op_URShiftVB: return new (C) URShiftVBNode(n1, n2, vt);
+  case Op_URShiftVS: return new (C) URShiftVSNode(n1, n2, vt);
+  case Op_URShiftVI: return new (C) URShiftVINode(n1, n2, vt);
+  case Op_URShiftVL: return new (C) URShiftVLNode(n1, n2, vt);
+
+  case Op_AndV: return new (C) AndVNode(n1, n2, vt);
+  case Op_OrV:  return new (C) OrVNode (n1, n2, vt);
+  case Op_XorV: return new (C) XorVNode(n1, n2, vt);
   }
-  ShouldNotReachHere();
+  fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[vopc]));
+  return NULL;
+
+}
+
+// Scalar promotion
+VectorNode* VectorNode::scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t) {
+  BasicType bt = opd_t->array_element_basic_type();
+  const TypeVect* vt = opd_t->singleton() ? TypeVect::make(opd_t, vlen)
+                                          : TypeVect::make(bt, vlen);
+  switch (bt) {
+  case T_BOOLEAN:
+  case T_BYTE:
+    return new (C) ReplicateBNode(s, vt);
+  case T_CHAR:
+  case T_SHORT:
+    return new (C) ReplicateSNode(s, vt);
+  case T_INT:
+    return new (C) ReplicateINode(s, vt);
+  case T_LONG:
+    return new (C) ReplicateLNode(s, vt);
+  case T_FLOAT:
+    return new (C) ReplicateFNode(s, vt);
+  case T_DOUBLE:
+    return new (C) ReplicateDNode(s, vt);
+  }
+  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
+  return NULL;
+}
+
+VectorNode* VectorNode::shift_count(Compile* C, Node* shift, Node* cnt, uint vlen, BasicType bt) {
+  assert(VectorNode::is_shift(shift) && !cnt->is_Con(), "only variable shift count");
+  // Match shift count type with shift vector type.
+  const TypeVect* vt = TypeVect::make(bt, vlen);
+  switch (shift->Opcode()) {
+  case Op_LShiftI:
+  case Op_LShiftL:
+    return new (C) LShiftCntVNode(cnt, vt);
+  case Op_RShiftI:
+  case Op_RShiftL:
+  case Op_URShiftI:
+  case Op_URShiftL:
+    return new (C) RShiftCntVNode(cnt, vt);
+  }
+  fatal(err_msg_res("Missed vector creation for '%s'", NodeClassNames[shift->Opcode()]));
+  return NULL;
+}
+
+// Return initial Pack node. Additional operands added with add_opd() calls.
+PackNode* PackNode::make(Compile* C, Node* s, uint vlen, BasicType bt) {
+  const TypeVect* vt = TypeVect::make(bt, vlen);
+  switch (bt) {
+  case T_BOOLEAN:
+  case T_BYTE:
+    return new (C) PackBNode(s, vt);
+  case T_CHAR:
+  case T_SHORT:
+    return new (C) PackSNode(s, vt);
+  case T_INT:
+    return new (C) PackINode(s, vt);
+  case T_LONG:
+    return new (C) PackLNode(s, vt);
+  case T_FLOAT:
+    return new (C) PackFNode(s, vt);
+  case T_DOUBLE:
+    return new (C) PackDNode(s, vt);
+  }
+  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
+  return NULL;
+}
+
+// Create a binary tree form for Packs. [lo, hi) (half-open) range
+PackNode* PackNode::binary_tree_pack(Compile* C, int lo, int hi) {
+  int ct = hi - lo;
+  assert(is_power_of_2(ct), "power of 2");
+  if (ct == 2) {
+    PackNode* pk = PackNode::make(C, in(lo), 2, vect_type()->element_basic_type());
+    pk->add_opd(in(lo+1));
+    return pk;
+
+  } else {
+    int mid = lo + ct/2;
+    PackNode* n1 = binary_tree_pack(C, lo,  mid);
+    PackNode* n2 = binary_tree_pack(C, mid, hi );
+
+    BasicType bt = n1->vect_type()->element_basic_type();
+    assert(bt == n2->vect_type()->element_basic_type(), "should be the same");
+    switch (bt) {
+    case T_BOOLEAN:
+    case T_BYTE:
+      return new (C) PackSNode(n1, n2, TypeVect::make(T_SHORT, 2));
+    case T_CHAR:
+    case T_SHORT:
+      return new (C) PackINode(n1, n2, TypeVect::make(T_INT, 2));
+    case T_INT:
+      return new (C) PackLNode(n1, n2, TypeVect::make(T_LONG, 2));
+    case T_LONG:
+      return new (C) Pack2LNode(n1, n2, TypeVect::make(T_LONG, 2));
+    case T_FLOAT:
+      return new (C) PackDNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
+    case T_DOUBLE:
+      return new (C) Pack2DNode(n1, n2, TypeVect::make(T_DOUBLE, 2));
+    }
+    fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
+  }
   return NULL;
 }
 
 // Return the vector version of a scalar load node.
-VectorLoadNode* VectorLoadNode::make(Compile* C, int opc, Node* ctl, Node* mem,
-                                     Node* adr, const TypePtr* atyp, uint vlen) {
-  int vopc = opcode(opc, vlen);
-
-  switch(vopc) {
-  case Op_Load16B: return new (C, 3) Load16BNode(ctl, mem, adr, atyp);
-  case Op_Load8B:  return new (C, 3) Load8BNode(ctl, mem, adr, atyp);
-  case Op_Load4B:  return new (C, 3) Load4BNode(ctl, mem, adr, atyp);
-
-  case Op_Load8C:  return new (C, 3) Load8CNode(ctl, mem, adr, atyp);
-  case Op_Load4C:  return new (C, 3) Load4CNode(ctl, mem, adr, atyp);
-  case Op_Load2C:  return new (C, 3) Load2CNode(ctl, mem, adr, atyp);
-
-  case Op_Load8S:  return new (C, 3) Load8SNode(ctl, mem, adr, atyp);
-  case Op_Load4S:  return new (C, 3) Load4SNode(ctl, mem, adr, atyp);
-  case Op_Load2S:  return new (C, 3) Load2SNode(ctl, mem, adr, atyp);
-
-  case Op_Load4I:  return new (C, 3) Load4INode(ctl, mem, adr, atyp);
-  case Op_Load2I:  return new (C, 3) Load2INode(ctl, mem, adr, atyp);
-
-  case Op_Load2L:  return new (C, 3) Load2LNode(ctl, mem, adr, atyp);
-
-  case Op_Load4F:  return new (C, 3) Load4FNode(ctl, mem, adr, atyp);
-  case Op_Load2F:  return new (C, 3) Load2FNode(ctl, mem, adr, atyp);
-
-  case Op_Load2D:  return new (C, 3) Load2DNode(ctl, mem, adr, atyp);
-  }
-  ShouldNotReachHere();
-  return NULL;
+LoadVectorNode* LoadVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem,
+                                     Node* adr, const TypePtr* atyp, uint vlen, BasicType bt) {
+  const TypeVect* vt = TypeVect::make(bt, vlen);
+  return new (C) LoadVectorNode(ctl, mem, adr, atyp, vt);
 }
 
 // Return the vector version of a scalar store node.
-VectorStoreNode* VectorStoreNode::make(Compile* C, int opc, Node* ctl, Node* mem,
+StoreVectorNode* StoreVectorNode::make(Compile* C, int opc, Node* ctl, Node* mem,
                                        Node* adr, const TypePtr* atyp, Node* val,
                                        uint vlen) {
-  int vopc = opcode(opc, vlen);
-
-  switch(vopc) {
-  case Op_Store16B: return new (C, 4) Store16BNode(ctl, mem, adr, atyp, val);
-  case Op_Store8B: return new (C, 4) Store8BNode(ctl, mem, adr, atyp, val);
-  case Op_Store4B: return new (C, 4) Store4BNode(ctl, mem, adr, atyp, val);
-
-  case Op_Store8C: return new (C, 4) Store8CNode(ctl, mem, adr, atyp, val);
-  case Op_Store4C: return new (C, 4) Store4CNode(ctl, mem, adr, atyp, val);
-  case Op_Store2C: return new (C, 4) Store2CNode(ctl, mem, adr, atyp, val);
-
-  case Op_Store4I: return new (C, 4) Store4INode(ctl, mem, adr, atyp, val);
-  case Op_Store2I: return new (C, 4) Store2INode(ctl, mem, adr, atyp, val);
-
-  case Op_Store2L: return new (C, 4) Store2LNode(ctl, mem, adr, atyp, val);
-
-  case Op_Store4F: return new (C, 4) Store4FNode(ctl, mem, adr, atyp, val);
-  case Op_Store2F: return new (C, 4) Store2FNode(ctl, mem, adr, atyp, val);
-
-  case Op_Store2D: return new (C, 4) Store2DNode(ctl, mem, adr, atyp, val);
-  }
-  ShouldNotReachHere();
-  return NULL;
+  return new (C) StoreVectorNode(ctl, mem, adr, atyp, val);
 }
 
 // Extract a scalar element of vector.
-Node* ExtractNode::make(Compile* C, Node* v, uint position, const Type* opd_t) {
-  BasicType bt = opd_t->array_element_basic_type();
-  assert(position < VectorNode::max_vlen(bt), "pos in range");
+Node* ExtractNode::make(Compile* C, Node* v, uint position, BasicType bt) {
+  assert((int)position < Matcher::max_vector_size(bt), "pos in range");
   ConINode* pos = ConINode::make(C, (int)position);
   switch (bt) {
   case T_BOOLEAN:
+    return new (C) ExtractUBNode(v, pos);
   case T_BYTE:
-    return new (C, 3) ExtractBNode(v, pos);
+    return new (C) ExtractBNode(v, pos);
   case T_CHAR:
-    return new (C, 3) ExtractCNode(v, pos);
+    return new (C) ExtractCNode(v, pos);
   case T_SHORT:
-    return new (C, 3) ExtractSNode(v, pos);
+    return new (C) ExtractSNode(v, pos);
   case T_INT:
-    return new (C, 3) ExtractINode(v, pos);
+    return new (C) ExtractINode(v, pos);
   case T_LONG:
-    return new (C, 3) ExtractLNode(v, pos);
+    return new (C) ExtractLNode(v, pos);
   case T_FLOAT:
-    return new (C, 3) ExtractFNode(v, pos);
+    return new (C) ExtractFNode(v, pos);
   case T_DOUBLE:
-    return new (C, 3) ExtractDNode(v, pos);
+    return new (C) ExtractDNode(v, pos);
   }
-  ShouldNotReachHere();
+  fatal(err_msg_res("Type '%s' is not supported for vectors", type2name(bt)));
   return NULL;
 }
+
diff --git a/hotspot/src/share/vm/opto/vectornode.hpp b/hotspot/src/share/vm/opto/vectornode.hpp
index 7d1905c..ba84406 100644
--- a/hotspot/src/share/vm/opto/vectornode.hpp
+++ b/hotspot/src/share/vm/opto/vectornode.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, 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
@@ -29,1037 +29,520 @@
 #include "opto/node.hpp"
 #include "opto/opcodes.hpp"
 
-//------------------------------VectorNode--------------------------------------
+//------------------------------VectorNode-------------------------------------
 // Vector Operation
-class VectorNode : public Node {
-  virtual uint size_of() const { return sizeof(*this); }
- protected:
-  uint _length; // vector length
-  virtual BasicType elt_basic_type() const = 0; // Vector element basic type
-
-  static const Type* vect_type(BasicType elt_bt, uint len);
-  static const Type* vect_type(const Type* elt_type, uint len) {
-    return vect_type(elt_type->array_element_basic_type(), len);
-  }
-
+class VectorNode : public TypeNode {
  public:
-  friend class VectorLoadNode;  // For vect_type
-  friend class VectorStoreNode; // ditto.
 
-  VectorNode(Node* n1, uint vlen) : Node(NULL, n1), _length(vlen) {
+  VectorNode(Node* n1, const TypeVect* vt) : TypeNode(vt, 2) {
     init_class_id(Class_Vector);
+    init_req(1, n1);
   }
-  VectorNode(Node* n1, Node* n2, uint vlen) : Node(NULL, n1, n2), _length(vlen) {
+  VectorNode(Node* n1, Node* n2, const TypeVect* vt) : TypeNode(vt, 3) {
     init_class_id(Class_Vector);
+    init_req(1, n1);
+    init_req(2, n2);
   }
+
+  const TypeVect* vect_type() const { return type()->is_vect(); }
+  uint length() const { return vect_type()->length(); } // Vector length
+  uint length_in_bytes() const { return vect_type()->length_in_bytes(); }
+
   virtual int Opcode() const;
 
-  uint length() const { return _length; } // Vector length
-
-  static uint max_vlen(BasicType bt) { // max vector length
-    return (uint)(Matcher::vector_width_in_bytes() / type2aelembytes(bt));
-  }
-
-  // Element and vector type
-  const Type* elt_type()  const { return Type::get_const_basic_type(elt_basic_type()); }
-  const Type* vect_type() const { return vect_type(elt_basic_type(), length()); }
-
-  virtual const Type *bottom_type() const { return vect_type(); }
-  virtual uint        ideal_reg()   const { return Matcher::vector_ideal_reg(); }
-
-  // Vector opcode from scalar opcode
-  static int opcode(int sopc, uint vlen, const Type* opd_t);
+  virtual uint ideal_reg() const { return Matcher::vector_ideal_reg(vect_type()->length_in_bytes()); }
 
   static VectorNode* scalar2vector(Compile* C, Node* s, uint vlen, const Type* opd_t);
+  static VectorNode* shift_count(Compile* C, Node* shift, Node* cnt, uint vlen, BasicType bt);
+  static VectorNode* make(Compile* C, int opc, Node* n1, Node* n2, uint vlen, BasicType bt);
 
-  static VectorNode* make(Compile* C, int sopc, Node* n1, Node* n2, uint vlen, const Type* elt_t);
-
+  static int  opcode(int opc, BasicType bt);
+  static bool implemented(int opc, uint vlen, BasicType bt);
+  static bool is_shift(Node* n);
+  static bool is_invariant_vector(Node* n);
+  // [Start, end) half-open range defining which operands are vectors
+  static void vector_operands(Node* n, uint* start, uint* end);
 };
 
-//===========================Vector=ALU=Operations====================================
+//===========================Vector=ALU=Operations=============================
 
-//------------------------------AddVBNode---------------------------------------
+//------------------------------AddVBNode--------------------------------------
 // Vector add byte
 class AddVBNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
  public:
-  AddVBNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  AddVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------AddVCNode---------------------------------------
-// Vector add char
-class AddVCNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  AddVCNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------AddVSNode---------------------------------------
-// Vector add short
+//------------------------------AddVSNode--------------------------------------
+// Vector add char/short
 class AddVSNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
  public:
-  AddVSNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  AddVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------AddVINode---------------------------------------
+//------------------------------AddVINode--------------------------------------
 // Vector add int
 class AddVINode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
  public:
-  AddVINode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  AddVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------AddVLNode---------------------------------------
+//------------------------------AddVLNode--------------------------------------
 // Vector add long
 class AddVLNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_LONG; }
  public:
-  AddVLNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  AddVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------AddVFNode---------------------------------------
+//------------------------------AddVFNode--------------------------------------
 // Vector add float
 class AddVFNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
  public:
-  AddVFNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  AddVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------AddVDNode---------------------------------------
+//------------------------------AddVDNode--------------------------------------
 // Vector add double
 class AddVDNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_DOUBLE; }
  public:
-  AddVDNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  AddVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------SubVBNode---------------------------------------
+//------------------------------SubVBNode--------------------------------------
 // Vector subtract byte
 class SubVBNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
  public:
-  SubVBNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  SubVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------SubVCNode---------------------------------------
-// Vector subtract char
-class SubVCNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  SubVCNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------SubVSNode---------------------------------------
+//------------------------------SubVSNode--------------------------------------
 // Vector subtract short
 class SubVSNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
  public:
-  SubVSNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  SubVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------SubVINode---------------------------------------
+//------------------------------SubVINode--------------------------------------
 // Vector subtract int
 class SubVINode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
  public:
-  SubVINode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  SubVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------SubVLNode---------------------------------------
+//------------------------------SubVLNode--------------------------------------
 // Vector subtract long
 class SubVLNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_LONG; }
  public:
-  SubVLNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  SubVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------SubVFNode---------------------------------------
+//------------------------------SubVFNode--------------------------------------
 // Vector subtract float
 class SubVFNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
  public:
-  SubVFNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  SubVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------SubVDNode---------------------------------------
+//------------------------------SubVDNode--------------------------------------
 // Vector subtract double
 class SubVDNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_DOUBLE; }
  public:
-  SubVDNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  SubVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------MulVFNode---------------------------------------
+//------------------------------MulVSNode--------------------------------------
+// Vector multiply short
+class MulVSNode : public VectorNode {
+ public:
+  MulVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------MulVINode--------------------------------------
+// Vector multiply int
+class MulVINode : public VectorNode {
+ public:
+  MulVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------MulVFNode--------------------------------------
 // Vector multiply float
 class MulVFNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
  public:
-  MulVFNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  MulVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------MulVDNode---------------------------------------
+//------------------------------MulVDNode--------------------------------------
 // Vector multiply double
 class MulVDNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_DOUBLE; }
  public:
-  MulVDNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  MulVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------DivVFNode---------------------------------------
+//------------------------------DivVFNode--------------------------------------
 // Vector divide float
 class DivVFNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
  public:
-  DivVFNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  DivVFNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------DivVDNode---------------------------------------
+//------------------------------DivVDNode--------------------------------------
 // Vector Divide double
 class DivVDNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_DOUBLE; }
  public:
-  DivVDNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  DivVDNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------LShiftVBNode---------------------------------------
-// Vector lshift byte
+//------------------------------LShiftVBNode-----------------------------------
+// Vector left shift bytes
 class LShiftVBNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
  public:
-  LShiftVBNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  LShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------LShiftVCNode---------------------------------------
-// Vector lshift chars
-class LShiftVCNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  LShiftVCNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------LShiftVSNode---------------------------------------
-// Vector lshift shorts
+//------------------------------LShiftVSNode-----------------------------------
+// Vector left shift shorts
 class LShiftVSNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
  public:
-  LShiftVSNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  LShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------LShiftVINode---------------------------------------
-// Vector lshift ints
+//------------------------------LShiftVINode-----------------------------------
+// Vector left shift ints
 class LShiftVINode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
  public:
-  LShiftVINode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  LShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------URShiftVBNode---------------------------------------
-// Vector urshift bytes
+//------------------------------LShiftVLNode-----------------------------------
+// Vector left shift longs
+class LShiftVLNode : public VectorNode {
+ public:
+  LShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------RShiftVBNode-----------------------------------
+// Vector right arithmetic (signed) shift bytes
+class RShiftVBNode : public VectorNode {
+ public:
+  RShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------RShiftVSNode-----------------------------------
+// Vector right arithmetic (signed) shift shorts
+class RShiftVSNode : public VectorNode {
+ public:
+  RShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------RShiftVINode-----------------------------------
+// Vector right arithmetic (signed) shift ints
+class RShiftVINode : public VectorNode {
+ public:
+  RShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------RShiftVLNode-----------------------------------
+// Vector right arithmetic (signed) shift longs
+class RShiftVLNode : public VectorNode {
+ public:
+  RShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------URShiftVBNode----------------------------------
+// Vector right logical (unsigned) shift bytes
 class URShiftVBNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
  public:
-  URShiftVBNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  URShiftVBNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------URShiftVCNode---------------------------------------
-// Vector urshift char
-class URShiftVCNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
- public:
-  URShiftVCNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------URShiftVSNode---------------------------------------
-// Vector urshift shorts
+//------------------------------URShiftVSNode----------------------------------
+// Vector right logical (unsigned) shift shorts
 class URShiftVSNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
  public:
-  URShiftVSNode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  URShiftVSNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------URShiftVINode---------------------------------------
-// Vector urshift ints
+//------------------------------URShiftVINode----------------------------------
+// Vector right logical (unsigned) shift ints
 class URShiftVINode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
  public:
-  URShiftVINode(Node* in1, Node* in2, uint vlen) : VectorNode(in1,in2,vlen) {}
+  URShiftVINode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
+//------------------------------URShiftVLNode----------------------------------
+// Vector right logical (unsigned) shift longs
+class URShiftVLNode : public VectorNode {
+ public:
+  URShiftVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------LShiftCntVNode---------------------------------
+// Vector left shift count
+class LShiftCntVNode : public VectorNode {
+ public:
+  LShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
+  virtual int Opcode() const;
+  virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
+};
+
+//------------------------------RShiftCntVNode---------------------------------
+// Vector right shift count
+class RShiftCntVNode : public VectorNode {
+ public:
+  RShiftCntVNode(Node* cnt, const TypeVect* vt) : VectorNode(cnt,vt) {}
+  virtual int Opcode() const;
+  virtual uint ideal_reg() const { return Matcher::vector_shift_count_ideal_reg(vect_type()->length_in_bytes()); }
+};
+
+
 //------------------------------AndVNode---------------------------------------
-// Vector and
+// Vector and integer
 class AndVNode : public VectorNode {
- protected:
-  BasicType _bt;
-  virtual BasicType elt_basic_type() const { return _bt; }
  public:
-  AndVNode(Node* in1, Node* in2, uint vlen, BasicType bt) : VectorNode(in1,in2,vlen), _bt(bt) {}
+  AndVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
 //------------------------------OrVNode---------------------------------------
-// Vector or
+// Vector or integer
 class OrVNode : public VectorNode {
- protected:
-  BasicType _bt;
-  virtual BasicType elt_basic_type() const { return _bt; }
  public:
-  OrVNode(Node* in1, Node* in2, uint vlen, BasicType bt) : VectorNode(in1,in2,vlen), _bt(bt) {}
+  OrVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
 //------------------------------XorVNode---------------------------------------
-// Vector xor
+// Vector xor integer
 class XorVNode : public VectorNode {
- protected:
-  BasicType _bt;
-  virtual BasicType elt_basic_type() const { return _bt; }
  public:
-  XorVNode(Node* in1, Node* in2, uint vlen, BasicType bt) : VectorNode(in1,in2,vlen), _bt(bt) {}
+  XorVNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1,in2,vt) {}
   virtual int Opcode() const;
 };
 
-//================================= M E M O R Y ==================================
+//================================= M E M O R Y ===============================
 
-
-//------------------------------VectorLoadNode--------------------------------------
-// Vector Load from memory
-class VectorLoadNode : public LoadNode {
-  virtual uint size_of() const { return sizeof(*this); }
-
- protected:
-  virtual BasicType elt_basic_type()  const = 0; // Vector element basic type
-  // For use in constructor
-  static const Type* vect_type(const Type* elt_type, uint len) {
-    return VectorNode::vect_type(elt_type, len);
-  }
-
+//------------------------------LoadVectorNode---------------------------------
+// Load Vector from memory
+class LoadVectorNode : public LoadNode {
  public:
-  VectorLoadNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const Type *rt)
-    : LoadNode(c,mem,adr,at,rt) {
-    init_class_id(Class_VectorLoad);
+  LoadVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeVect* vt)
+    : LoadNode(c, mem, adr, at, vt) {
+    init_class_id(Class_LoadVector);
   }
+
+  const TypeVect* vect_type() const { return type()->is_vect(); }
+  uint length() const { return vect_type()->length(); } // Vector length
+
   virtual int Opcode() const;
 
-  virtual uint  length() const = 0; // Vector length
-
-  // Element and vector type
-  const Type* elt_type()  const { return Type::get_const_basic_type(elt_basic_type()); }
-  const Type* vect_type() const { return VectorNode::vect_type(elt_basic_type(), length()); }
-
-  virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(); }
+  virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
   virtual BasicType memory_type() const { return T_VOID; }
-  virtual int memory_size() const { return length()*type2aelembytes(elt_basic_type()); }
+  virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 
-  // Vector opcode from scalar opcode
-  static int opcode(int sopc, uint vlen);
+  virtual int store_Opcode() const { return Op_StoreVector; }
 
-  static VectorLoadNode* make(Compile* C, int opc, Node* ctl, Node* mem,
-                              Node* adr, const TypePtr* atyp, uint vlen);
+  static LoadVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
+                              Node* adr, const TypePtr* atyp, uint vlen, BasicType bt);
 };
 
-//------------------------------Load16BNode--------------------------------------
-// Vector load of 16 bytes (8bits signed) from memory
-class Load16BNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
+//------------------------------StoreVectorNode--------------------------------
+// Store Vector to memory
+class StoreVectorNode : public StoreNode {
  public:
-  Load16BNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::BYTE)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,16)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store16B; }
-  virtual uint length() const { return 16; }
-};
-
-//------------------------------Load8BNode--------------------------------------
-// Vector load of 8 bytes (8bits signed) from memory
-class Load8BNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
- public:
-  Load8BNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::BYTE)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,8)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store8B; }
-  virtual uint length() const { return 8; }
-};
-
-//------------------------------Load4BNode--------------------------------------
-// Vector load of 4 bytes (8bits signed) from memory
-class Load4BNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
- public:
-  Load4BNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::BYTE)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,4)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store4B; }
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Load8CNode--------------------------------------
-// Vector load of 8 chars (16bits unsigned) from memory
-class Load8CNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  Load8CNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,8)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store8C; }
-  virtual uint length() const { return 8; }
-};
-
-//------------------------------Load4CNode--------------------------------------
-// Vector load of 4 chars (16bits unsigned) from memory
-class Load4CNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  Load4CNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,4)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store4C; }
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Load2CNode--------------------------------------
-// Vector load of 2 chars (16bits unsigned) from memory
-class Load2CNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  Load2CNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::CHAR)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,2)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store2C; }
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Load8SNode--------------------------------------
-// Vector load of 8 shorts (16bits signed) from memory
-class Load8SNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
- public:
-  Load8SNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,8)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store8C; }
-  virtual uint length() const { return 8; }
-};
-
-//------------------------------Load4SNode--------------------------------------
-// Vector load of 4 shorts (16bits signed) from memory
-class Load4SNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
- public:
-  Load4SNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,4)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store4C; }
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Load2SNode--------------------------------------
-// Vector load of 2 shorts (16bits signed) from memory
-class Load2SNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
- public:
-  Load2SNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::SHORT)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,2)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store2C; }
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Load4INode--------------------------------------
-// Vector load of 4 integers (32bits signed) from memory
-class Load4INode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
- public:
-  Load4INode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::INT)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,4)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store4I; }
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Load2INode--------------------------------------
-// Vector load of 2 integers (32bits signed) from memory
-class Load2INode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
- public:
-  Load2INode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeInt *ti = TypeInt::INT)
-    : VectorLoadNode(c,mem,adr,at,vect_type(ti,2)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store2I; }
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Load2LNode--------------------------------------
-// Vector load of 2 longs (64bits signed) from memory
-class Load2LNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_LONG; }
- public:
-  Load2LNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const TypeLong *tl = TypeLong::LONG)
-    : VectorLoadNode(c,mem,adr,at,vect_type(tl,2)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store2L; }
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Load4FNode--------------------------------------
-// Vector load of 4 floats (32bits) from memory
-class Load4FNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
- public:
-  Load4FNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const Type *t = Type::FLOAT)
-    : VectorLoadNode(c,mem,adr,at,vect_type(t,4)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store4F; }
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Load2FNode--------------------------------------
-// Vector load of 2 floats (32bits) from memory
-class Load2FNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
- public:
-  Load2FNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const Type *t = Type::FLOAT)
-    : VectorLoadNode(c,mem,adr,at,vect_type(t,2)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store2F; }
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Load2DNode--------------------------------------
-// Vector load of 2 doubles (64bits) from memory
-class Load2DNode : public VectorLoadNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_DOUBLE; }
- public:
-  Load2DNode(Node* c, Node* mem, Node* adr, const TypePtr* at, const Type *t = Type::DOUBLE)
-    : VectorLoadNode(c,mem,adr,at,vect_type(t,2)) {}
-  virtual int Opcode() const;
-  virtual int store_Opcode() const { return Op_Store2D; }
-  virtual uint length() const { return 2; }
-};
-
-
-//------------------------------VectorStoreNode--------------------------------------
-// Vector Store to memory
-class VectorStoreNode : public StoreNode {
-  virtual uint size_of() const { return sizeof(*this); }
-
- protected:
-  virtual BasicType elt_basic_type()  const = 0; // Vector element basic type
-
- public:
-  VectorStoreNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : StoreNode(c,mem,adr,at,val) {
-    init_class_id(Class_VectorStore);
+  StoreVectorNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
+    : StoreNode(c, mem, adr, at, val) {
+    assert(val->is_Vector() || val->is_LoadVector(), "sanity");
+    init_class_id(Class_StoreVector);
   }
+
+  const TypeVect* vect_type() const { return in(MemNode::ValueIn)->bottom_type()->is_vect(); }
+  uint length() const { return vect_type()->length(); } // Vector length
+
   virtual int Opcode() const;
 
-  virtual uint  length() const = 0; // Vector length
-
-  // Element and vector type
-  const Type* elt_type()  const { return Type::get_const_basic_type(elt_basic_type()); }
-  const Type* vect_type() const { return VectorNode::vect_type(elt_basic_type(), length()); }
-
-  virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(); }
+  virtual uint ideal_reg() const  { return Matcher::vector_ideal_reg(memory_size()); }
   virtual BasicType memory_type() const { return T_VOID; }
-  virtual int memory_size() const { return length()*type2aelembytes(elt_basic_type()); }
+  virtual int memory_size() const { return vect_type()->length_in_bytes(); }
 
-  // Vector opcode from scalar opcode
-  static int opcode(int sopc, uint vlen);
-
-  static VectorStoreNode* make(Compile* C, int opc, Node* ctl, Node* mem,
+  static StoreVectorNode* make(Compile* C, int opc, Node* ctl, Node* mem,
                                Node* adr, const TypePtr* atyp, Node* val,
                                uint vlen);
 };
 
-//------------------------------Store16BNode--------------------------------------
-// Vector store of 16 bytes (8bits signed) to memory
-class Store16BNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
- public:
-  Store16BNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 16; }
-};
 
-//------------------------------Store8BNode--------------------------------------
-// Vector store of 8 bytes (8bits signed) to memory
-class Store8BNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
- public:
-  Store8BNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 8; }
-};
+//=========================Promote_Scalar_to_Vector============================
 
-//------------------------------Store4BNode--------------------------------------
-// Vector store of 4 bytes (8bits signed) to memory
-class Store4BNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
+//------------------------------ReplicateBNode---------------------------------
+// Replicate byte scalar to be vector
+class ReplicateBNode : public VectorNode {
  public:
-  Store4BNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Store8CNode--------------------------------------
-// Vector store of 8 chars (16bits signed/unsigned) to memory
-class Store8CNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  Store8CNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 8; }
-};
-
-//------------------------------Store4CNode--------------------------------------
-// Vector store of 4 chars (16bits signed/unsigned) to memory
-class Store4CNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  Store4CNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Store2CNode--------------------------------------
-// Vector store of 2 chars (16bits signed/unsigned) to memory
-class Store2CNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  Store2CNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Store4INode--------------------------------------
-// Vector store of 4 integers (32bits signed) to memory
-class Store4INode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
- public:
-  Store4INode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Store2INode--------------------------------------
-// Vector store of 2 integers (32bits signed) to memory
-class Store2INode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
- public:
-  Store2INode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Store2LNode--------------------------------------
-// Vector store of 2 longs (64bits signed) to memory
-class Store2LNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_LONG; }
- public:
-  Store2LNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Store4FNode--------------------------------------
-// Vector store of 4 floats (32bits) to memory
-class Store4FNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
- public:
-  Store4FNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 4; }
-};
-
-//------------------------------Store2FNode--------------------------------------
-// Vector store of 2 floats (32bits) to memory
-class Store2FNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
- public:
-  Store2FNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 2; }
-};
-
-//------------------------------Store2DNode--------------------------------------
-// Vector store of 2 doubles (64bits) to memory
-class Store2DNode : public VectorStoreNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_DOUBLE; }
- public:
-  Store2DNode(Node* c, Node* mem, Node* adr, const TypePtr* at, Node* val)
-    : VectorStoreNode(c,mem,adr,at,val) {}
-  virtual int Opcode() const;
-  virtual uint length() const { return 2; }
-};
-
-//=========================Promote_Scalar_to_Vector====================================
-
-//------------------------------Replicate16BNode---------------------------------------
-// Replicate byte scalar to be vector of 16 bytes
-class Replicate16BNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
- public:
-  Replicate16BNode(Node* in1) : VectorNode(in1, 16) {}
+  ReplicateBNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------Replicate8BNode---------------------------------------
-// Replicate byte scalar to be vector of 8 bytes
-class Replicate8BNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
+//------------------------------ReplicateSNode---------------------------------
+// Replicate short scalar to be vector
+class ReplicateSNode : public VectorNode {
  public:
-  Replicate8BNode(Node* in1) : VectorNode(in1, 8) {}
+  ReplicateSNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------Replicate4BNode---------------------------------------
-// Replicate byte scalar to be vector of 4 bytes
-class Replicate4BNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
+//------------------------------ReplicateINode---------------------------------
+// Replicate int scalar to be vector
+class ReplicateINode : public VectorNode {
  public:
-  Replicate4BNode(Node* in1) : VectorNode(in1, 4) {}
+  ReplicateINode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------Replicate8CNode---------------------------------------
-// Replicate char scalar to be vector of 8 chars
-class Replicate8CNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
+//------------------------------ReplicateLNode---------------------------------
+// Replicate long scalar to be vector
+class ReplicateLNode : public VectorNode {
  public:
-  Replicate8CNode(Node* in1) : VectorNode(in1, 8) {}
+  ReplicateLNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------Replicate4CNode---------------------------------------
-// Replicate char scalar to be vector of 4 chars
-class Replicate4CNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
+//------------------------------ReplicateFNode---------------------------------
+// Replicate float scalar to be vector
+class ReplicateFNode : public VectorNode {
  public:
-  Replicate4CNode(Node* in1) : VectorNode(in1, 4) {}
+  ReplicateFNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------Replicate2CNode---------------------------------------
-// Replicate char scalar to be vector of 2 chars
-class Replicate2CNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
+//------------------------------ReplicateDNode---------------------------------
+// Replicate double scalar to be vector
+class ReplicateDNode : public VectorNode {
  public:
-  Replicate2CNode(Node* in1) : VectorNode(in1, 2) {}
+  ReplicateDNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------Replicate8SNode---------------------------------------
-// Replicate short scalar to be vector of 8 shorts
-class Replicate8SNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
- public:
-  Replicate8SNode(Node* in1) : VectorNode(in1, 8) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------Replicate4SNode---------------------------------------
-// Replicate short scalar to be vector of 4 shorts
-class Replicate4SNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
- public:
-  Replicate4SNode(Node* in1) : VectorNode(in1, 4) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------Replicate2SNode---------------------------------------
-// Replicate short scalar to be vector of 2 shorts
-class Replicate2SNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
- public:
-  Replicate2SNode(Node* in1) : VectorNode(in1, 2) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------Replicate4INode---------------------------------------
-// Replicate int scalar to be vector of 4 ints
-class Replicate4INode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
- public:
-  Replicate4INode(Node* in1) : VectorNode(in1, 4) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------Replicate2INode---------------------------------------
-// Replicate int scalar to be vector of 2 ints
-class Replicate2INode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
- public:
-  Replicate2INode(Node* in1) : VectorNode(in1, 2) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------Replicate2LNode---------------------------------------
-// Replicate long scalar to be vector of 2 longs
-class Replicate2LNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_LONG; }
- public:
-  Replicate2LNode(Node* in1) : VectorNode(in1, 2) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------Replicate4FNode---------------------------------------
-// Replicate float scalar to be vector of 4 floats
-class Replicate4FNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
- public:
-  Replicate4FNode(Node* in1) : VectorNode(in1, 4) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------Replicate2FNode---------------------------------------
-// Replicate float scalar to be vector of 2 floats
-class Replicate2FNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
- public:
-  Replicate2FNode(Node* in1) : VectorNode(in1, 2) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------Replicate2DNode---------------------------------------
-// Replicate double scalar to be vector of 2 doubles
-class Replicate2DNode : public VectorNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_DOUBLE; }
- public:
-  Replicate2DNode(Node* in1) : VectorNode(in1, 2) {}
-  virtual int Opcode() const;
-};
-
-//========================Pack_Scalars_into_a_Vector==============================
+//========================Pack_Scalars_into_a_Vector===========================
 
 //------------------------------PackNode---------------------------------------
 // Pack parent class (not for code generation).
 class PackNode : public VectorNode {
  public:
-  PackNode(Node* in1)  : VectorNode(in1, 1) {}
-  PackNode(Node* in1, Node* n2)  : VectorNode(in1, n2, 2) {}
+  PackNode(Node* in1, const TypeVect* vt) : VectorNode(in1, vt) {}
+  PackNode(Node* in1, Node* n2, const TypeVect* vt) : VectorNode(in1, n2, vt) {}
   virtual int Opcode() const;
 
   void add_opd(Node* n) {
     add_req(n);
-    _length++;
-    assert(_length == req() - 1, "vector length matches edge count");
   }
 
   // Create a binary tree form for Packs. [lo, hi) (half-open) range
-  Node* binaryTreePack(Compile* C, int lo, int hi);
+  PackNode* binary_tree_pack(Compile* C, int lo, int hi);
 
-  static PackNode* make(Compile* C, Node* s, const Type* elt_t);
+  static PackNode* make(Compile* C, Node* s, uint vlen, BasicType bt);
 };
 
-//------------------------------PackBNode---------------------------------------
+//------------------------------PackBNode--------------------------------------
 // Pack byte scalars into vector
 class PackBNode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
  public:
-  PackBNode(Node* in1)  : PackNode(in1) {}
+  PackBNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------PackCNode---------------------------------------
-// Pack char scalars into vector
-class PackCNode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  PackCNode(Node* in1)  : PackNode(in1) {}
-  virtual int Opcode() const;
-};
-
-//------------------------------PackSNode---------------------------------------
+//------------------------------PackSNode--------------------------------------
 // Pack short scalars into a vector
 class PackSNode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_SHORT; }
  public:
-  PackSNode(Node* in1)  : PackNode(in1) {}
+  PackSNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
+  PackSNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------PackINode---------------------------------------
+//------------------------------PackINode--------------------------------------
 // Pack integer scalars into a vector
 class PackINode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_INT; }
  public:
-  PackINode(Node* in1)  : PackNode(in1) {}
-  PackINode(Node* in1, Node* in2) : PackNode(in1, in2) {}
+  PackINode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
+  PackINode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------PackLNode---------------------------------------
+//------------------------------PackLNode--------------------------------------
 // Pack long scalars into a vector
 class PackLNode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_LONG; }
  public:
-  PackLNode(Node* in1)  : PackNode(in1) {}
-  PackLNode(Node* in1, Node* in2) : PackNode(in1, in2) {}
+  PackLNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
+  PackLNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------PackFNode---------------------------------------
+//------------------------------Pack2LNode-------------------------------------
+// Pack 2 long scalars into a vector
+class Pack2LNode : public PackNode {
+ public:
+  Pack2LNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
+  virtual int Opcode() const;
+};
+
+//------------------------------PackFNode--------------------------------------
 // Pack float scalars into vector
 class PackFNode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_FLOAT; }
  public:
-  PackFNode(Node* in1)  : PackNode(in1) {}
-  PackFNode(Node* in1, Node* in2) : PackNode(in1, in2) {}
+  PackFNode(Node* in1, const TypeVect* vt)  : PackNode(in1, vt) {}
+  PackFNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
   virtual int Opcode() const;
 };
 
-//------------------------------PackDNode---------------------------------------
+//------------------------------PackDNode--------------------------------------
 // Pack double scalars into a vector
 class PackDNode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_DOUBLE; }
  public:
-  PackDNode(Node* in1)  : PackNode(in1) {}
-  PackDNode(Node* in1, Node* in2) : PackNode(in1, in2) {}
+  PackDNode(Node* in1, const TypeVect* vt) : PackNode(in1, vt) {}
+  PackDNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
   virtual int Opcode() const;
 };
 
-// The Pack2xN nodes assist code generation.  They are created from
-// Pack4C, etc. nodes in final_graph_reshape in the form of a
-// balanced, binary tree.
-
-//------------------------------Pack2x1BNode-----------------------------------------
-// Pack 2 1-byte integers into vector of 2 bytes
-class Pack2x1BNode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_BYTE; }
+//------------------------------Pack2DNode-------------------------------------
+// Pack 2 double scalars into a vector
+class Pack2DNode : public PackNode {
  public:
-  Pack2x1BNode(Node *in1, Node* in2) : PackNode(in1, in2) {}
+  Pack2DNode(Node* in1, Node* in2, const TypeVect* vt) : PackNode(in1, in2, vt) {}
   virtual int Opcode() const;
-  virtual uint ideal_reg() const { return Op_RegI; }
 };
 
-//------------------------------Pack2x2BNode---------------------------------------
-// Pack 2 2-byte integers into vector of 4 bytes
-class Pack2x2BNode : public PackNode {
- protected:
-  virtual BasicType elt_basic_type() const { return T_CHAR; }
- public:
-  Pack2x2BNode(Node *in1, Node* in2) : PackNode(in1, in2) {}
-  virtual int Opcode() const;
-  virtual uint ideal_reg() const { return Op_RegI; }
-};
 
-//========================Extract_Scalar_from_Vector===============================
+//========================Extract_Scalar_from_Vector===========================
 
-//------------------------------ExtractNode---------------------------------------
+//------------------------------ExtractNode------------------------------------
 // Extract a scalar from a vector at position "pos"
 class ExtractNode : public Node {
  public:
@@ -1069,10 +552,10 @@
   virtual int Opcode() const;
   uint  pos() const { return in(2)->get_int(); }
 
-  static Node* make(Compile* C, Node* v, uint position, const Type* opd_t);
+  static Node* make(Compile* C, Node* v, uint position, BasicType bt);
 };
 
-//------------------------------ExtractBNode---------------------------------------
+//------------------------------ExtractBNode-----------------------------------
 // Extract a byte from a vector at position "pos"
 class ExtractBNode : public ExtractNode {
  public:
@@ -1082,7 +565,17 @@
   virtual uint ideal_reg() const { return Op_RegI; }
 };
 
-//------------------------------ExtractCNode---------------------------------------
+//------------------------------ExtractUBNode----------------------------------
+// Extract a boolean from a vector at position "pos"
+class ExtractUBNode : public ExtractNode {
+ public:
+  ExtractUBNode(Node* src, ConINode* pos) : ExtractNode(src, pos) {}
+  virtual int Opcode() const;
+  virtual const Type *bottom_type() const { return TypeInt::INT; }
+  virtual uint ideal_reg() const { return Op_RegI; }
+};
+
+//------------------------------ExtractCNode-----------------------------------
 // Extract a char from a vector at position "pos"
 class ExtractCNode : public ExtractNode {
  public:
@@ -1092,7 +585,7 @@
   virtual uint ideal_reg() const { return Op_RegI; }
 };
 
-//------------------------------ExtractSNode---------------------------------------
+//------------------------------ExtractSNode-----------------------------------
 // Extract a short from a vector at position "pos"
 class ExtractSNode : public ExtractNode {
  public:
@@ -1102,7 +595,7 @@
   virtual uint ideal_reg() const { return Op_RegI; }
 };
 
-//------------------------------ExtractINode---------------------------------------
+//------------------------------ExtractINode-----------------------------------
 // Extract an int from a vector at position "pos"
 class ExtractINode : public ExtractNode {
  public:
@@ -1112,7 +605,7 @@
   virtual uint ideal_reg() const { return Op_RegI; }
 };
 
-//------------------------------ExtractLNode---------------------------------------
+//------------------------------ExtractLNode-----------------------------------
 // Extract a long from a vector at position "pos"
 class ExtractLNode : public ExtractNode {
  public:
@@ -1122,7 +615,7 @@
   virtual uint ideal_reg() const { return Op_RegL; }
 };
 
-//------------------------------ExtractFNode---------------------------------------
+//------------------------------ExtractFNode-----------------------------------
 // Extract a float from a vector at position "pos"
 class ExtractFNode : public ExtractNode {
  public:
@@ -1132,7 +625,7 @@
   virtual uint ideal_reg() const { return Op_RegF; }
 };
 
-//------------------------------ExtractDNode---------------------------------------
+//------------------------------ExtractDNode-----------------------------------
 // Extract a double from a vector at position "pos"
 class ExtractDNode : public ExtractNode {
  public:
diff --git a/hotspot/src/share/vm/precompiled/precompiled.hpp b/hotspot/src/share/vm/precompiled/precompiled.hpp
index 686f256..789ab51 100644
--- a/hotspot/src/share/vm/precompiled/precompiled.hpp
+++ b/hotspot/src/share/vm/precompiled/precompiled.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -293,13 +293,10 @@
 # include "c1/c1_globals.hpp"
 #endif // COMPILER1
 #ifndef SERIALGC
-# include "gc_implementation/concurrentMarkSweep/binaryTreeDictionary.hpp"
 # include "gc_implementation/concurrentMarkSweep/cmsOopClosures.hpp"
 # include "gc_implementation/concurrentMarkSweep/compactibleFreeListSpace.hpp"
 # include "gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp"
-# include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp"
 # include "gc_implementation/concurrentMarkSweep/freeChunk.hpp"
-# include "gc_implementation/concurrentMarkSweep/freeList.hpp"
 # include "gc_implementation/concurrentMarkSweep/promotionInfo.hpp"
 # include "gc_implementation/g1/dirtyCardQueue.hpp"
 # include "gc_implementation/g1/g1BlockOffsetTable.hpp"
@@ -309,7 +306,6 @@
 # include "gc_implementation/g1/g1_specialized_oop_closures.hpp"
 # include "gc_implementation/g1/ptrQueue.hpp"
 # include "gc_implementation/g1/satbQueue.hpp"
-# include "gc_implementation/parNew/parGCAllocBuffer.hpp"
 # include "gc_implementation/parNew/parOopClosures.hpp"
 # include "gc_implementation/parallelScavenge/objectStartArray.hpp"
 # include "gc_implementation/parallelScavenge/parMarkBitMap.hpp"
@@ -325,6 +321,7 @@
 # include "gc_implementation/parallelScavenge/psYoungGen.hpp"
 # include "gc_implementation/shared/gcAdaptivePolicyCounters.hpp"
 # include "gc_implementation/shared/gcPolicyCounters.hpp"
+# include "gc_implementation/shared/parGCAllocBuffer.hpp"
 #endif // SERIALGC
 
 #endif // !DONT_USE_PRECOMPILED_HEADER
diff --git a/hotspot/src/share/vm/prims/jni.cpp b/hotspot/src/share/vm/prims/jni.cpp
index 166bbd6..ced5fc1 100644
--- a/hotspot/src/share/vm/prims/jni.cpp
+++ b/hotspot/src/share/vm/prims/jni.cpp
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,6 +34,7 @@
 #ifndef SERIALGC
 #include "gc_implementation/g1/g1SATBCardTableModRefBS.hpp"
 #endif // SERIALGC
+#include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/gcLocker.inline.hpp"
 #include "memory/oopFactory.hpp"
@@ -2819,10 +2821,9 @@
 JNI_QUICK_ENTRY(void, jni_Set##Result##Field(JNIEnv *env, jobject obj, jfieldID fieldID, Argument value)) \
   JNIWrapper("Set" XSTR(Result) "Field"); \
 \
-  HS_DTRACE_PROBE_CDECL_N(hotspot_jni, Set##Result##Field__entry, \
-    ( JNIEnv*, jobject, jfieldID FP_SELECT_##Result(COMMA Argument,/*empty*/) ) ); \
-  HS_DTRACE_PROBE_N(hotspot_jni, Set##Result##Field__entry, \
-    ( env, obj, fieldID FP_SELECT_##Result(COMMA value,/*empty*/) ) ); \
+  FP_SELECT_##Result( \
+    DTRACE_PROBE4(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID, value), \
+    DTRACE_PROBE3(hotspot_jni, Set##Result##Field__entry, env, obj, fieldID)); \
 \
   oop o = JNIHandles::resolve_non_null(obj); \
   klassOop k = o->klass(); \
@@ -3129,10 +3130,9 @@
 \
 JNI_ENTRY(void, jni_SetStatic##Result##Field(JNIEnv *env, jclass clazz, jfieldID fieldID, Argument value)) \
   JNIWrapper("SetStatic" XSTR(Result) "Field"); \
-  HS_DTRACE_PROBE_CDECL_N(hotspot_jni, SetStatic##Result##Field__entry,\
-    ( JNIEnv*, jclass, jfieldID FP_SELECT_##Result(COMMA Argument,/*empty*/) ) ); \
-  HS_DTRACE_PROBE_N(hotspot_jni, SetStatic##Result##Field__entry, \
-    ( env, clazz, fieldID FP_SELECT_##Result(COMMA value,/*empty*/) ) ); \
+  FP_SELECT_##Result( \
+     DTRACE_PROBE4(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID, value), \
+     DTRACE_PROBE3(hotspot_jni, SetStatic##Result##Field__entry, env, clazz, fieldID)); \
 \
   JNIid* id = jfieldIDWorkaround::from_static_jfieldID(fieldID); \
   assert(id->is_static_field_id(), "invalid static field id"); \
@@ -3270,7 +3270,7 @@
   int s_len = java_lang_String::length(s);
   typeArrayOop s_value = java_lang_String::value(s);
   int s_offset = java_lang_String::offset(s);
-  jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len + 1);  // add one for zero termination
+  jchar* buf = NEW_C_HEAP_ARRAY(jchar, s_len + 1, mtInternal);  // add one for zero termination
   if (s_len > 0) {
     memcpy(buf, s_value->char_at_addr(s_offset), sizeof(jchar)*s_len);
   }
@@ -3363,7 +3363,7 @@
 #endif /* USDT2 */
   oop java_string = JNIHandles::resolve_non_null(string);
   size_t length = java_lang_String::utf8_length(java_string);
-  char* result = AllocateHeap(length + 1, "GetStringUTFChars");
+  char* result = AllocateHeap(length + 1, mtInternal);
   java_lang_String::as_utf8_string(java_string, result, (int) length + 1);
   if (isCopy != NULL) *isCopy = JNI_TRUE;
 #ifndef USDT2
@@ -3619,7 +3619,7 @@
      * Avoid asserts in typeArrayOop. */ \
     result = (ElementType*)get_bad_address(); \
   } else { \
-    result = NEW_C_HEAP_ARRAY(ElementType, len); \
+    result = NEW_C_HEAP_ARRAY(ElementType, len, mtInternal); \
     /* copy the array to the c chunk */ \
     memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
   } \
@@ -3656,7 +3656,7 @@
      * Avoid asserts in typeArrayOop. */ \
     result = (ElementType*)get_bad_address(); \
   } else { \
-    result = NEW_C_HEAP_ARRAY(ElementType, len); \
+    result = NEW_C_HEAP_ARRAY(ElementType, len, mtInternal); \
     /* copy the array to the c chunk */ \
     memcpy(result, a->Tag##_at_addr(0), sizeof(ElementType)*len); \
   } \
diff --git a/hotspot/src/share/vm/prims/jniCheck.cpp b/hotspot/src/share/vm/prims/jniCheck.cpp
index 3bf4ecd..7e30b58 100644
--- a/hotspot/src/share/vm/prims/jniCheck.cpp
+++ b/hotspot/src/share/vm/prims/jniCheck.cpp
@@ -1308,7 +1308,7 @@
     assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringChars didn't return a copy as expected");
 
     size_t len = UNCHECKED()->GetStringLength(env,str) + 1; // + 1 for NULL termination
-    jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), "checked_jni_GetStringChars");
+    jint* tagLocation = (jint*) AllocateHeap(len * sizeof(jchar) + sizeof(jint), mtInternal);
     *tagLocation = STRING_TAG;
     jchar* newResult = (jchar*) (tagLocation + 1);
     memcpy(newResult, result, len * sizeof(jchar));
@@ -1378,13 +1378,13 @@
     assert (isCopy == NULL || *isCopy == JNI_TRUE, "GetStringUTFChars didn't return a copy as expected");
 
     size_t len = strlen(result) + 1; // + 1 for NULL termination
-    jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), "checked_jni_GetStringUTFChars");
+    jint* tagLocation = (jint*) AllocateHeap(len + sizeof(jint), mtInternal);
     *tagLocation = STRING_UTF_TAG;
     char* newResult = (char*) (tagLocation + 1);
     strcpy(newResult, result);
     // Avoiding call to UNCHECKED()->ReleaseStringUTFChars() since that will fire unexpected dtrace probes
     // Note that the dtrace arguments for the allocated memory will not match up with this solution.
-    FreeHeap((char*)result);
+    FreeHeap((char*)result, mtInternal);
 
     functionExit(env);
     return newResult;
diff --git a/hotspot/src/share/vm/prims/jvm.cpp b/hotspot/src/share/vm/prims/jvm.cpp
index 4c503fe..20f415c 100644
--- a/hotspot/src/share/vm/prims/jvm.cpp
+++ b/hotspot/src/share/vm/prims/jvm.cpp
@@ -35,6 +35,7 @@
 #include "oops/fieldStreams.hpp"
 #include "oops/instanceKlass.hpp"
 #include "oops/objArrayKlass.hpp"
+#include "oops/methodOop.hpp"
 #include "prims/jvm.h"
 #include "prims/jvm_misc.hpp"
 #include "prims/jvmtiExport.hpp"
@@ -345,9 +346,13 @@
   // Do this after setting user properties to prevent people
   // from setting the value with a -D option, as requested.
   {
-    char as_chars[256];
-    jio_snprintf(as_chars, sizeof(as_chars), INTX_FORMAT, MaxDirectMemorySize);
-    PUTPROP(props, "sun.nio.MaxDirectMemorySize", as_chars);
+    if (FLAG_IS_DEFAULT(MaxDirectMemorySize)) {
+      PUTPROP(props, "sun.nio.MaxDirectMemorySize", "-1");
+    } else {
+      char as_chars[256];
+      jio_snprintf(as_chars, sizeof(as_chars), UINTX_FORMAT, MaxDirectMemorySize);
+      PUTPROP(props, "sun.nio.MaxDirectMemorySize", as_chars);
+    }
   }
 
   // JVM monitoring and management support
@@ -1301,9 +1306,6 @@
 // Inner class reflection ///////////////////////////////////////////////////////////////////////////////
 
 JVM_ENTRY(jobjectArray, JVM_GetDeclaredClasses(JNIEnv *env, jclass ofClass))
-  const int inner_class_info_index = 0;
-  const int outer_class_info_index = 1;
-
   JvmtiVMObjectAllocEventCollector oam;
   // ofClass is a reference to a java_lang_Class object. The mirror object
   // of an instanceKlass
@@ -1315,26 +1317,26 @@
   }
 
   instanceKlassHandle k(thread, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(ofClass)));
+  InnerClassesIterator iter(k);
 
-  if (k->inner_classes()->length() == 0) {
+  if (iter.length() == 0) {
     // Neither an inner nor outer class
     oop result = oopFactory::new_objArray(SystemDictionary::Class_klass(), 0, CHECK_NULL);
     return (jobjectArray)JNIHandles::make_local(env, result);
   }
 
   // find inner class info
-  typeArrayHandle    icls(thread, k->inner_classes());
   constantPoolHandle cp(thread, k->constants());
-  int length = icls->length();
+  int length = iter.length();
 
   // Allocate temp. result array
   objArrayOop r = oopFactory::new_objArray(SystemDictionary::Class_klass(), length/4, CHECK_NULL);
   objArrayHandle result (THREAD, r);
   int members = 0;
 
-  for(int i = 0; i < length; i += 4) {
-    int ioff = icls->ushort_at(i + inner_class_info_index);
-    int ooff = icls->ushort_at(i + outer_class_info_index);
+  for (; !iter.done(); iter.next()) {
+    int ioff = iter.inner_class_info_index();
+    int ooff = iter.outer_class_info_index();
 
     if (ioff != 0 && ooff != 0) {
       // Check to see if the name matches the class we're looking for
@@ -1392,17 +1394,13 @@
                                                      bool* inner_is_member,
                                                      TRAPS) {
   Thread* thread = THREAD;
-  const int inner_class_info_index = inner_class_inner_class_info_offset;
-  const int outer_class_info_index = inner_class_outer_class_info_offset;
-
-  if (k->inner_classes()->length() == 0) {
+  InnerClassesIterator iter(k);
+  if (iter.length() == 0) {
     // No inner class info => no declaring class
     return NULL;
   }
 
-  typeArrayHandle i_icls(thread, k->inner_classes());
   constantPoolHandle i_cp(thread, k->constants());
-  int i_length = i_icls->length();
 
   bool found = false;
   klassOop ok;
@@ -1410,10 +1408,10 @@
   *inner_is_member = false;
 
   // Find inner_klass attribute
-  for (int i = 0; i < i_length && !found; i += inner_class_next_offset) {
-    int ioff = i_icls->ushort_at(i + inner_class_info_index);
-    int ooff = i_icls->ushort_at(i + outer_class_info_index);
-    int noff = i_icls->ushort_at(i + inner_class_inner_name_offset);
+  for (; !iter.done() && !found; iter.next()) {
+    int ioff = iter.inner_class_info_index();
+    int ooff = iter.outer_class_info_index();
+    int noff = iter.inner_name_index();
     if (ioff != 0) {
       // Check to see if the name matches the class we're looking for
       // before attempting to find the class.
@@ -2186,11 +2184,11 @@
   klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
   k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
   oop method = instanceKlass::cast(k)->methods()->obj_at(method_index);
-  typeArrayOop extable = methodOop(method)->exception_table();
-  entry->start_pc   = extable->int_at(entry_index * 4);
-  entry->end_pc     = extable->int_at(entry_index * 4 + 1);
-  entry->handler_pc = extable->int_at(entry_index * 4 + 2);
-  entry->catchType  = extable->int_at(entry_index * 4 + 3);
+  ExceptionTable extable((methodOop(method)));
+  entry->start_pc   = extable.start_pc(entry_index);
+  entry->end_pc     = extable.end_pc(entry_index);
+  entry->handler_pc = extable.handler_pc(entry_index);
+  entry->catchType  = extable.catch_type_index(entry_index);
 JVM_END
 
 
@@ -2199,7 +2197,7 @@
   klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
   k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
   oop method = instanceKlass::cast(k)->methods()->obj_at(method_index);
-  return methodOop(method)->exception_table()->length() / 4;
+  return methodOop(method)->exception_table_length();
 JVM_END
 
 
@@ -2243,7 +2241,7 @@
   klassOop k = java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(cls));
   k = JvmtiThreadState::class_to_verify_considering_redefinition(k, thread);
   oop method = instanceKlass::cast(k)->methods()->obj_at(method_index);
-  return methodOop(method)->max_stack();
+  return methodOop(method)->verifier_max_stack();
 JVM_END
 
 
diff --git a/hotspot/src/share/vm/prims/jvm.h b/hotspot/src/share/vm/prims/jvm.h
index a9b322c..a514f37 100644
--- a/hotspot/src/share/vm/prims/jvm.h
+++ b/hotspot/src/share/vm/prims/jvm.h
@@ -634,7 +634,7 @@
 JVM_AssertionStatusDirectives(JNIEnv *env, jclass unused);
 
 /*
- * sun.misc.AtomicLong
+ * java.util.concurrent.atomic.AtomicLong
  */
 JNIEXPORT jboolean JNICALL
 JVM_SupportsCX8(void);
diff --git a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
index 41b3b2e..8265569 100644
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -191,15 +191,14 @@
     }
   }
 
-  typeArrayHandle exception_table(thread(), const_method->exception_table());
-  int exception_table_length = exception_table->length();
-  int exception_table_entries = exception_table_length / 4;
+  ExceptionTable exception_table(method());
+  int exception_table_length = exception_table.length();
   int code_size = const_method->code_size();
   int size =
     2+2+4 +                                // max_stack, max_locals, code_length
     code_size +                            // code
     2 +                                    // exception_table_length
-    (2+2+2+2) * exception_table_entries +  // exception_table
+    (2+2+2+2) * exception_table_length +   // exception_table
     2 +                                    // attributes_count
     attr_size;                             // attributes
 
@@ -209,12 +208,12 @@
   write_u2(method->max_locals());
   write_u4(code_size);
   copy_bytecodes(method, (unsigned char*)writeable_address(code_size));
-  write_u2(exception_table_entries);
-  for (int index = 0; index < exception_table_length; ) {
-    write_u2(exception_table->int_at(index++));
-    write_u2(exception_table->int_at(index++));
-    write_u2(exception_table->int_at(index++));
-    write_u2(exception_table->int_at(index++));
+  write_u2(exception_table_length);
+  for (int index = 0; index < exception_table_length; index++) {
+    write_u2(exception_table.start_pc(index));
+    write_u2(exception_table.end_pc(index));
+    write_u2(exception_table.handler_pc(index));
+    write_u2(exception_table.catch_type_index(index));
   }
   write_u2(attr_count);
   if (line_num_cnt != 0) {
@@ -268,14 +267,18 @@
 // JSR45|   SourceDebugExtension_attribute {
 // JSR45|       u2 attribute_name_index;
 // JSR45|       u4 attribute_length;
-// JSR45|       u2 sourcefile_index;
+// JSR45|       u1 debug_extension[attribute_length];
 // JSR45|   }
 void JvmtiClassFileReconstituter::write_source_debug_extension_attribute() {
   assert(ikh()->source_debug_extension() != NULL, "caller must check");
 
   write_attribute_name_index("SourceDebugExtension");
-  write_u4(2);  // always length 2
-  write_u2(symbol_to_cpool_index(ikh()->source_debug_extension()));
+  int len = (int)strlen(ikh()->source_debug_extension());
+  write_u4(len);
+  u1* ext = (u1*)ikh()->source_debug_extension();
+  for (int i=0; i<len; i++) {
+    write_u1(ext[i]);
+  }
 }
 
 // Write (generic) Signature attribute
@@ -292,8 +295,8 @@
 
 // Compute the number of entries in the InnerClasses attribute
 u2 JvmtiClassFileReconstituter::inner_classes_attribute_length() {
-  typeArrayOop inner_class_list = ikh()->inner_classes();
-  return (inner_class_list == NULL) ? 0 : inner_class_list->length();
+  InnerClassesIterator iter(ikh());
+  return iter.length();
 }
 
 // Write an annotation attribute.  The VM stores them in raw form, so all we need
@@ -324,26 +327,20 @@
 // JVMSpec|     } classes[number_of_classes];
 // JVMSpec|   }
 void JvmtiClassFileReconstituter::write_inner_classes_attribute(int length) {
-  typeArrayOop inner_class_list = ikh()->inner_classes();
-  guarantee(inner_class_list != NULL && inner_class_list->length() == length,
+  InnerClassesIterator iter(ikh());
+  guarantee(iter.length() != 0 && iter.length() == length,
             "caller must check");
-  typeArrayHandle inner_class_list_h(thread(), inner_class_list);
-  assert (length % instanceKlass::inner_class_next_offset == 0, "just checking");
   u2 entry_count = length / instanceKlass::inner_class_next_offset;
   u4 size = 2 + entry_count * (2+2+2+2);
 
   write_attribute_name_index("InnerClasses");
   write_u4(size);
   write_u2(entry_count);
-  for (int i = 0; i < length; i += instanceKlass::inner_class_next_offset) {
-    write_u2(inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_inner_class_info_offset));
-    write_u2(inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_outer_class_info_offset));
-    write_u2(inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_inner_name_offset));
-    write_u2(inner_class_list_h->ushort_at(
-                      i + instanceKlass::inner_class_access_flags_offset));
+  for (; !iter.done(); iter.next()) {
+    write_u2(iter.inner_class_info_index());
+    write_u2(iter.outer_class_info_index());
+    write_u2(iter.inner_name_index());
+    write_u2(iter.inner_access_flags());
   }
 }
 
@@ -728,8 +725,8 @@
       case Bytecodes::_invokedynamic   :  // fall through
       case Bytecodes::_invokeinterface :
         assert(len == 3 ||
-               (code == Bytecodes::_invokeinterface && len ==5) ||
-               (code == Bytecodes::_invokedynamic   && len ==5),
+               (code == Bytecodes::_invokeinterface && len == 5) ||
+               (code == Bytecodes::_invokedynamic   && len == 5),
                "sanity check");
 
         int cpci = Bytes::get_native_u2(bcp+1);
diff --git a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp
index 565c6fe..64caf38 100644
--- a/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiClassFileReconstituter.hpp
@@ -68,11 +68,11 @@
 
   ~JvmtiConstantPoolReconstituter() {
     if (_symmap != NULL) {
-      os::free(_symmap);
+      os::free(_symmap, mtClass);
       _symmap = NULL;
     }
     if (_classmap != NULL) {
-      os::free(_classmap);
+      os::free(_classmap, mtClass);
       _classmap = NULL;
     }
   }
diff --git a/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp b/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp
index 7f20ec3a..3a9a4ea 100644
--- a/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiCodeBlobEvents.cpp
@@ -157,7 +157,7 @@
   assert(_global_code_blobs == NULL, "checking");
 
   // create the global list
-  _global_code_blobs = new (ResourceObj::C_HEAP) GrowableArray<JvmtiCodeBlobDesc*>(50,true);
+  _global_code_blobs = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiCodeBlobDesc*>(50,true);
 
   // iterate over the stub code descriptors and put them in the list first.
   int index = 0;
@@ -247,7 +247,7 @@
     int pcds_in_method;
 
     pcds_in_method = (nm->scopes_pcs_end() - nm->scopes_pcs_begin());
-    map = NEW_C_HEAP_ARRAY(jvmtiAddrLocationMap, pcds_in_method);
+    map = NEW_C_HEAP_ARRAY(jvmtiAddrLocationMap, pcds_in_method, mtInternal);
 
     address scopes_data = nm->scopes_data_begin();
     for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) {
diff --git a/hotspot/src/share/vm/prims/jvmtiEnv.cpp b/hotspot/src/share/vm/prims/jvmtiEnv.cpp
index 46519bb..20f5cf8 100644
--- a/hotspot/src/share/vm/prims/jvmtiEnv.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiEnv.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -1012,7 +1012,7 @@
 
   // growable array of jvmti monitors info on the C-heap
   GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
-      new (ResourceObj::C_HEAP) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);
+      new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);
 
   uint32_t debug_bits = 0;
   if (is_thread_fully_suspended(java_thread, true, &debug_bits)) {
@@ -1057,7 +1057,7 @@
 
   // growable array of jvmti monitors info on the C-heap
   GrowableArray<jvmtiMonitorStackDepthInfo*> *owned_monitors_list =
-         new (ResourceObj::C_HEAP) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);
+         new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiMonitorStackDepthInfo*>(1, true);
 
   uint32_t debug_bits = 0;
   if (is_thread_fully_suspended(java_thread, true, &debug_bits)) {
@@ -2541,15 +2541,12 @@
     if (!Klass::cast(k)->oop_is_instance()) {
       return JVMTI_ERROR_ABSENT_INFORMATION;
     }
-    Symbol* sdeOop = instanceKlass::cast(k)->source_debug_extension();
-    NULL_CHECK(sdeOop, JVMTI_ERROR_ABSENT_INFORMATION);
+    char* sde = instanceKlass::cast(k)->source_debug_extension();
+    NULL_CHECK(sde, JVMTI_ERROR_ABSENT_INFORMATION);
 
     {
-      JavaThread* current_thread  = JavaThread::current();
-      ResourceMark rm(current_thread);
-      const char* sdecp = (const char*) sdeOop->as_C_string();
-      *source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sdecp)+1);
-      strcpy(*source_debug_extension_ptr, sdecp);
+      *source_debug_extension_ptr = (char *) jvmtiMalloc(strlen(sde)+1);
+      strcpy(*source_debug_extension_ptr, sde);
     }
   }
 
diff --git a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp
index fd42642..2a6fd14 100644
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.cpp
@@ -381,7 +381,7 @@
     _native_method_prefixes = NULL;
   } else {
     // there are prefixes, allocate an array to hold them, and fill it
-    char** new_prefixes = (char**)os::malloc((prefix_count) * sizeof(char*));
+    char** new_prefixes = (char**)os::malloc((prefix_count) * sizeof(char*), mtInternal);
     if (new_prefixes == NULL) {
       return JVMTI_ERROR_OUT_OF_MEMORY;
     }
@@ -1150,7 +1150,7 @@
 
 ResourceTracker::ResourceTracker(JvmtiEnv* env) {
   _env = env;
-  _allocations = new (ResourceObj::C_HEAP) GrowableArray<unsigned char*>(20, true);
+  _allocations = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<unsigned char*>(20, true);
   _failed = false;
 }
 ResourceTracker::~ResourceTracker() {
diff --git a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp
index ba03746..29604db 100644
--- a/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiEnvBase.hpp
@@ -52,7 +52,7 @@
 // done via JNI GetEnv() call. Multiple attachments are
 // allowed in jvmti.
 
-class JvmtiEnvBase : public CHeapObj {
+class JvmtiEnvBase : public CHeapObj<mtInternal> {
 
  private:
 
@@ -175,7 +175,7 @@
     if (size == 0) {
       *mem_ptr = NULL;
     } else {
-      *mem_ptr = (unsigned char *)os::malloc((size_t)size);
+      *mem_ptr = (unsigned char *)os::malloc((size_t)size, mtInternal);
       if (*mem_ptr == NULL) {
         return JVMTI_ERROR_OUT_OF_MEMORY;
       }
@@ -185,7 +185,7 @@
 
   jvmtiError deallocate(unsigned char* mem) {
     if (mem != NULL) {
-      os::free(mem);
+      os::free(mem, mtInternal);
     }
     return JVMTI_ERROR_NONE;
   }
diff --git a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp
index 9df767e..8e52140 100644
--- a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.cpp
@@ -95,7 +95,7 @@
 //
 
 JvmtiFramePops::JvmtiFramePops() {
-  _pops = new (ResourceObj::C_HEAP) GrowableArray<int> (2, true);
+  _pops = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int> (2, true);
 }
 
 JvmtiFramePops::~JvmtiFramePops() {
diff --git a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp
index e2273df..f9e686c 100644
--- a/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiEnvThreadState.hpp
@@ -76,7 +76,7 @@
 // It records what frames on a threads stack should post frame_pop events when they're exited.
 //
 
-class JvmtiFramePops : public CHeapObj {
+class JvmtiFramePops : public CHeapObj<mtInternal> {
  private:
   GrowableArray<int>* _pops;
 
@@ -107,7 +107,7 @@
 // 3: Location of last executed instruction, used to filter out duplicate
 //    events due to instruction rewriting.
 
-class JvmtiEnvThreadState : public CHeapObj {
+class JvmtiEnvThreadState : public CHeapObj<mtInternal> {
 private:
   friend class JvmtiEnv;
   JavaThread        *_thread;
diff --git a/hotspot/src/share/vm/prims/jvmtiExport.cpp b/hotspot/src/share/vm/prims/jvmtiExport.cpp
index 5325073..70c5c71 100644
--- a/hotspot/src/share/vm/prims/jvmtiExport.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiExport.cpp
@@ -617,7 +617,7 @@
       if (caching_needed && *_cached_data_ptr == NULL) {
         // data has been changed by the new retransformable agent
         // and it hasn't already been cached, cache it
-        *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len);
+        *_cached_data_ptr = (unsigned char *)os::malloc(_curr_len, mtInternal);
         memcpy(*_cached_data_ptr, _curr_data, _curr_len);
         *_cached_length_ptr = _curr_len;
       }
@@ -720,7 +720,7 @@
     JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nm, &_map, &_map_length);
   }
   ~JvmtiCompiledMethodLoadEventMark() {
-     FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map);
+     FREE_C_HEAP_ARRAY(jvmtiAddrLocationMap, _map, mtInternal);
   }
 
   jint code_size() { return _code_size; }
@@ -2323,7 +2323,7 @@
 // register a stub
 void JvmtiDynamicCodeEventCollector::register_stub(const char* name, address start, address end) {
  if (_code_blobs == NULL) {
-   _code_blobs = new (ResourceObj::C_HEAP) GrowableArray<JvmtiCodeBlobDesc*>(1,true);
+   _code_blobs = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiCodeBlobDesc*>(1,true);
  }
  _code_blobs->append(new JvmtiCodeBlobDesc(name, start, end));
 }
@@ -2357,7 +2357,7 @@
 void JvmtiVMObjectAllocEventCollector::record_allocation(oop obj) {
   assert(is_enabled(), "VM object alloc event collector is not enabled");
   if (_allocated == NULL) {
-    _allocated = new (ResourceObj::C_HEAP) GrowableArray<oop>(1, true);
+    _allocated = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(1, true);
   }
   _allocated->push(obj);
 }
diff --git a/hotspot/src/share/vm/prims/jvmtiExport.hpp b/hotspot/src/share/vm/prims/jvmtiExport.hpp
index 31ee1ec..4f6e6c6 100644
--- a/hotspot/src/share/vm/prims/jvmtiExport.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiExport.hpp
@@ -350,7 +350,7 @@
 
 // Support class used by JvmtiDynamicCodeEventCollector and others. It
 // describes a single code blob by name and address range.
-class JvmtiCodeBlobDesc : public CHeapObj {
+class JvmtiCodeBlobDesc : public CHeapObj<mtInternal> {
  private:
   char _name[64];
   address _code_begin;
diff --git a/hotspot/src/share/vm/prims/jvmtiExtensions.cpp b/hotspot/src/share/vm/prims/jvmtiExtensions.cpp
index 00f99720..9f6a1b1 100644
--- a/hotspot/src/share/vm/prims/jvmtiExtensions.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiExtensions.cpp
@@ -49,8 +49,8 @@
 // event. The function and the event are registered here.
 //
 void JvmtiExtensions::register_extensions() {
-  _ext_functions = new (ResourceObj::C_HEAP) GrowableArray<jvmtiExtensionFunctionInfo*>(1,true);
-  _ext_events = new (ResourceObj::C_HEAP) GrowableArray<jvmtiExtensionEventInfo*>(1,true);
+  _ext_functions = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiExtensionFunctionInfo*>(1,true);
+  _ext_events = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jvmtiExtensionEventInfo*>(1,true);
 
   // register our extension function
   static jvmtiParamInfo func_params[] = {
diff --git a/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp b/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp
index dd07a29..050aa60 100644
--- a/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiGetLoadedClasses.cpp
@@ -152,7 +152,7 @@
 
   // Public methods that get called within the scope of the closure
   void allocate() {
-    _list = NEW_C_HEAP_ARRAY(Handle, _count);
+    _list = NEW_C_HEAP_ARRAY(Handle, _count, mtInternal);
     assert(_list != NULL, "Out of memory");
     if (_list == NULL) {
       _count = 0;
diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.cpp b/hotspot/src/share/vm/prims/jvmtiImpl.cpp
index e0d809d..2244d81 100644
--- a/hotspot/src/share/vm/prims/jvmtiImpl.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.cpp
@@ -98,8 +98,8 @@
 void GrowableCache::recache() {
   int len = _elements->length();
 
-  FREE_C_HEAP_ARRAY(address, _cache);
-  _cache = NEW_C_HEAP_ARRAY(address,len+1);
+  FREE_C_HEAP_ARRAY(address, _cache, mtInternal);
+  _cache = NEW_C_HEAP_ARRAY(address,len+1, mtInternal);
 
   for (int i=0; i<len; i++) {
     _cache[i] = _elements->at(i)->getCacheValue();
@@ -142,13 +142,13 @@
 GrowableCache::~GrowableCache() {
   clear();
   delete _elements;
-  FREE_C_HEAP_ARRAY(address, _cache);
+  FREE_C_HEAP_ARRAY(address, _cache, mtInternal);
 }
 
 void GrowableCache::initialize(void *this_obj, void listener_fun(void *, address*) ) {
   _this_obj       = this_obj;
   _listener_fun   = listener_fun;
-  _elements       = new (ResourceObj::C_HEAP) GrowableArray<GrowableElement*>(5,true);
+  _elements       = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<GrowableElement*>(5,true);
   recache();
 }
 
diff --git a/hotspot/src/share/vm/prims/jvmtiImpl.hpp b/hotspot/src/share/vm/prims/jvmtiImpl.hpp
index 704d287..f80d631 100644
--- a/hotspot/src/share/vm/prims/jvmtiImpl.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiImpl.hpp
@@ -64,7 +64,7 @@
 // to update its pointer to the address cache.
 //
 
-class GrowableElement : public CHeapObj {
+class GrowableElement : public CHeapObj<mtInternal> {
 public:
   virtual address getCacheValue()          =0;
   virtual bool equals(GrowableElement* e)  =0;
@@ -130,7 +130,7 @@
 // Note   : typesafe wrapper for GrowableCache of JvmtiBreakpoint
 //
 
-class JvmtiBreakpointCache : public CHeapObj {
+class JvmtiBreakpointCache : public CHeapObj<mtInternal> {
 
 private:
   GrowableCache _cache;
@@ -258,7 +258,7 @@
 // CHeap allocated to emphasize its similarity to JvmtiFramePops.
 //
 
-class JvmtiBreakpoints : public CHeapObj {
+class JvmtiBreakpoints : public CHeapObj<mtInternal> {
 private:
 
   JvmtiBreakpointCache _bps;
@@ -496,7 +496,7 @@
 class JvmtiDeferredEventQueue : AllStatic {
   friend class JvmtiDeferredEvent;
  private:
-  class QueueNode : public CHeapObj {
+  class QueueNode : public CHeapObj<mtInternal> {
    private:
     JvmtiDeferredEvent _event;
     QueueNode* _next;
diff --git a/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp b/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp
index 89cac00..9031bbb2 100644
--- a/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiRawMonitor.cpp
@@ -27,7 +27,7 @@
 #include "runtime/interfaceSupport.hpp"
 #include "runtime/thread.hpp"
 
-GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP) GrowableArray<JvmtiRawMonitor*>(1,true);
+GrowableArray<JvmtiRawMonitor*> *JvmtiPendingMonitors::_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JvmtiRawMonitor*>(1,true);
 
 void JvmtiPendingMonitors::transition_raw_monitors() {
   assert((Threads::number_of_threads()==1),
@@ -53,7 +53,7 @@
 
 JvmtiRawMonitor::JvmtiRawMonitor(const char *name) {
 #ifdef ASSERT
-  _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1), name);
+  _name = strcpy(NEW_C_HEAP_ARRAY(char, strlen(name) + 1, mtInternal), name);
 #else
   _name = NULL;
 #endif
diff --git a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
index 295ed86..2c0550e 100644
--- a/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiRedefineClasses.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -831,7 +831,7 @@
 jvmtiError VM_RedefineClasses::load_new_class_versions(TRAPS) {
   // For consistency allocate memory using os::malloc wrapper.
   _scratch_classes = (instanceKlassHandle *)
-    os::malloc(sizeof(instanceKlassHandle) * _class_count);
+    os::malloc(sizeof(instanceKlassHandle) * _class_count, mtInternal);
   if (_scratch_classes == NULL) {
     return JVMTI_ERROR_OUT_OF_MEMORY;
   }
@@ -2400,44 +2400,33 @@
   // new constant indices as needed. The inner classes info is a
   // quadruple:
   // (inner_class_info, outer_class_info, inner_name, inner_access_flags)
-  typeArrayOop inner_class_list = scratch_class->inner_classes();
-  int icl_length = (inner_class_list == NULL) ? 0 : inner_class_list->length();
-  if (icl_length > 0) {
-    typeArrayHandle inner_class_list_h(THREAD, inner_class_list);
-    for (int i = 0; i < icl_length;
-         i += instanceKlass::inner_class_next_offset) {
-      int cur_index = inner_class_list_h->ushort_at(i
-                        + instanceKlass::inner_class_inner_class_info_offset);
-      if (cur_index == 0) {
-        continue;  // JVM spec. allows null inner class refs so skip it
-      }
-      int new_index = find_new_index(cur_index);
-      if (new_index != 0) {
-        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
-          ("inner_class_info change: %d to %d", cur_index, new_index));
-        inner_class_list_h->ushort_at_put(i
-          + instanceKlass::inner_class_inner_class_info_offset, new_index);
-      }
-      cur_index = inner_class_list_h->ushort_at(i
-                    + instanceKlass::inner_class_outer_class_info_offset);
-      new_index = find_new_index(cur_index);
-      if (new_index != 0) {
-        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
-          ("outer_class_info change: %d to %d", cur_index, new_index));
-        inner_class_list_h->ushort_at_put(i
-          + instanceKlass::inner_class_outer_class_info_offset, new_index);
-      }
-      cur_index = inner_class_list_h->ushort_at(i
-                    + instanceKlass::inner_class_inner_name_offset);
-      new_index = find_new_index(cur_index);
-      if (new_index != 0) {
-        RC_TRACE_WITH_THREAD(0x00080000, THREAD,
-          ("inner_name change: %d to %d", cur_index, new_index));
-        inner_class_list_h->ushort_at_put(i
-          + instanceKlass::inner_class_inner_name_offset, new_index);
-      }
-    } // end for each inner class
-  } // end if we have inner classes
+  InnerClassesIterator iter(scratch_class);
+  for (; !iter.done(); iter.next()) {
+    int cur_index = iter.inner_class_info_index();
+    if (cur_index == 0) {
+      continue;  // JVM spec. allows null inner class refs so skip it
+    }
+    int new_index = find_new_index(cur_index);
+    if (new_index != 0) {
+      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
+        ("inner_class_info change: %d to %d", cur_index, new_index));
+      iter.set_inner_class_info_index(new_index);
+    }
+    cur_index = iter.outer_class_info_index();
+    new_index = find_new_index(cur_index);
+    if (new_index != 0) {
+      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
+        ("outer_class_info change: %d to %d", cur_index, new_index));
+      iter.set_outer_class_info_index(new_index);
+    }
+    cur_index = iter.inner_name_index();
+    new_index = find_new_index(cur_index);
+    if (new_index != 0) {
+      RC_TRACE_WITH_THREAD(0x00080000, THREAD,
+        ("inner_name change: %d to %d", cur_index, new_index));
+      iter.set_inner_name_index(new_index);
+    }
+  } // end for each inner class
 
   // Attach each method in klass to the new constant pool and update
   // to use new constant pool indices as needed:
@@ -2489,23 +2478,17 @@
     // to use new constant pool indices as needed. The exception table
     // holds quadruple entries of the form:
     //   (beg_bci, end_bci, handler_bci, klass_index)
-    const int beg_bci_offset     = 0;
-    const int end_bci_offset     = 1;
-    const int handler_bci_offset = 2;
-    const int klass_index_offset = 3;
-    const int entry_size         = 4;
 
-    typeArrayHandle ex_table (THREAD, method->exception_table());
-    int ext_length = ex_table->length();
-    assert(ext_length % entry_size == 0, "exception table format has changed");
+    ExceptionTable ex_table(method());
+    int ext_length = ex_table.length();
 
-    for (int j = 0; j < ext_length; j += entry_size) {
-      int cur_index = ex_table->int_at(j + klass_index_offset);
+    for (int j = 0; j < ext_length; j ++) {
+      int cur_index = ex_table.catch_type_index(j);
       int new_index = find_new_index(cur_index);
       if (new_index != 0) {
         RC_TRACE_WITH_THREAD(0x00080000, THREAD,
           ("ext-klass_index change: %d to %d", cur_index, new_index));
-        ex_table->int_at_put(j + klass_index_offset, new_index);
+        ex_table.set_catch_type_index(j, new_index);
       }
     } // end for each exception table entry
 
@@ -3247,7 +3230,9 @@
 
   // Copy the "source debug extension" attribute from new class version
   the_class->set_source_debug_extension(
-    scratch_class->source_debug_extension());
+    scratch_class->source_debug_extension(),
+    scratch_class->source_debug_extension() == NULL ? 0 :
+    (int)strlen(scratch_class->source_debug_extension()));
 
   // Use of javac -g could be different in the old and the new
   if (scratch_class->access_flags().has_localvariable_table() !=
diff --git a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
index a425430..eae9634 100644
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.cpp
@@ -55,7 +55,7 @@
 // and the tag value. In addition an entry includes a next pointer which
 // is used to chain entries together.
 
-class JvmtiTagHashmapEntry : public CHeapObj {
+class JvmtiTagHashmapEntry : public CHeapObj<mtInternal> {
  private:
   friend class JvmtiTagMap;
 
@@ -106,7 +106,7 @@
 // entries. It also provides a function to iterate over all entries
 // in the hashmap.
 
-class JvmtiTagHashmap : public CHeapObj {
+class JvmtiTagHashmap : public CHeapObj<mtInternal> {
  private:
   friend class JvmtiTagMap;
 
@@ -150,7 +150,7 @@
     _resize_threshold = (int)(_load_factor * _size);
     _resizing_enabled = true;
     size_t s = initial_size * sizeof(JvmtiTagHashmapEntry*);
-    _table = (JvmtiTagHashmapEntry**)os::malloc(s);
+    _table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal);
     if (_table == NULL) {
       vm_exit_out_of_memory(s, "unable to allocate initial hashtable for jvmti object tags");
     }
@@ -188,7 +188,7 @@
 
     // allocate new table
     size_t s = new_size * sizeof(JvmtiTagHashmapEntry*);
-    JvmtiTagHashmapEntry** new_table = (JvmtiTagHashmapEntry**)os::malloc(s);
+    JvmtiTagHashmapEntry** new_table = (JvmtiTagHashmapEntry**)os::malloc(s, mtInternal);
     if (new_table == NULL) {
       warning("unable to allocate larger hashtable for jvmti object tags");
       set_resizing_enabled(false);
@@ -585,7 +585,7 @@
     _o = klassOop_if_java_lang_Class(o);
 
     // object size
-    _obj_size = _o->size() * wordSize;
+    _obj_size = (jlong)_o->size() * wordSize;
 
     // record the context
     _tag_map = tag_map;
@@ -776,7 +776,7 @@
 // For each field it holds the field index (as defined by the JVMTI specification),
 // the field type, and the offset.
 
-class ClassFieldDescriptor: public CHeapObj {
+class ClassFieldDescriptor: public CHeapObj<mtInternal> {
  private:
   int _field_index;
   int _field_offset;
@@ -790,7 +790,7 @@
   int field_offset() const  { return _field_offset; }
 };
 
-class ClassFieldMap: public CHeapObj {
+class ClassFieldMap: public CHeapObj<mtInternal> {
  private:
   enum {
     initial_field_count = 5
@@ -821,7 +821,8 @@
 };
 
 ClassFieldMap::ClassFieldMap() {
-  _fields = new (ResourceObj::C_HEAP) GrowableArray<ClassFieldDescriptor*>(initial_field_count, true);
+  _fields = new (ResourceObj::C_HEAP, mtInternal)
+    GrowableArray<ClassFieldDescriptor*>(initial_field_count, true);
 }
 
 ClassFieldMap::~ClassFieldMap() {
@@ -892,7 +893,7 @@
 // heap iteration and avoid creating a field map for each object in the heap
 // (only need to create the map when the first instance of a class is encountered).
 //
-class JvmtiCachedClassFieldMap : public CHeapObj {
+class JvmtiCachedClassFieldMap : public CHeapObj<mtInternal> {
  private:
    enum {
      initial_class_count = 200
@@ -957,7 +958,8 @@
 // record that the given instanceKlass is caching a field map
 void JvmtiCachedClassFieldMap::add_to_class_list(instanceKlass* ik) {
   if (_class_list == NULL) {
-    _class_list = new (ResourceObj::C_HEAP) GrowableArray<instanceKlass*>(initial_class_count, true);
+    _class_list = new (ResourceObj::C_HEAP, mtInternal)
+      GrowableArray<instanceKlass*>(initial_class_count, true);
   }
   _class_list->push(ik);
 }
@@ -1160,7 +1162,7 @@
 
     // get offset and field value
     int offset = field->field_offset();
-    address addr = (address)k + offset;
+    address addr = (address)k->java_mirror() + offset;
     jvalue value;
     copy_to_jvalue(&value, addr, value_type);
 
@@ -1526,8 +1528,8 @@
     _env = env;
     _tags = (jlong*)tags;
     _tag_count = tag_count;
-    _object_results = new (ResourceObj::C_HEAP) GrowableArray<jobject>(1,true);
-    _tag_results = new (ResourceObj::C_HEAP) GrowableArray<uint64_t>(1,true);
+    _object_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<jobject>(1,true);
+    _tag_results = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<uint64_t>(1,true);
   }
 
   ~TagObjectCollector() {
@@ -1672,8 +1674,8 @@
   Universe::heap()->ensure_parsability(false);  // no need to retire TLABs
 
   // create stacks for interesting headers
-  _saved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(4000, true);
-  _saved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<oop>(4000, true);
+  _saved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(4000, true);
+  _saved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(4000, true);
 
   if (UseBiasedLocking) {
     BiasedLocking::preserve_marks();
@@ -2712,7 +2714,7 @@
   bool _reporting_string_values;
 
   GrowableArray<oop>* create_visit_stack() {
-    return new (ResourceObj::C_HEAP) GrowableArray<oop>(initial_visit_stack_size, true);
+    return new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(initial_visit_stack_size, true);
   }
 
   // accessors
@@ -2923,7 +2925,8 @@
           oop entry;
           if (tag.is_string()) {
             entry = pool->resolved_string_at(i);
-            assert(java_lang_String::is_instance(entry), "must be string");
+            assert(java_lang_String::is_instance(entry) ||
+                   pool->is_pseudo_string_at(i), "must be string");
           } else {
             entry = Klass::cast(pool->resolved_klass_at(i))->java_mirror();
           }
@@ -3162,9 +3165,6 @@
         if (fr->is_entry_frame()) {
           last_entry_frame = fr;
         }
-        if (fr->is_ricochet_frame()) {
-          fr->oops_ricochet_do(blk, vf->register_map());
-        }
       }
 
       vf = vf->sender();
diff --git a/hotspot/src/share/vm/prims/jvmtiTagMap.hpp b/hotspot/src/share/vm/prims/jvmtiTagMap.hpp
index 2a460ed..ede639e 100644
--- a/hotspot/src/share/vm/prims/jvmtiTagMap.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiTagMap.hpp
@@ -41,7 +41,7 @@
 class JvmtiTagHashmapEntry;
 class JvmtiTagHashmapEntryClosure;
 
-class JvmtiTagMap :  public CHeapObj {
+class JvmtiTagMap :  public CHeapObj<mtInternal> {
  private:
 
   enum{
diff --git a/hotspot/src/share/vm/prims/jvmtiThreadState.hpp b/hotspot/src/share/vm/prims/jvmtiThreadState.hpp
index 87d2f0b..6cc4e27 100644
--- a/hotspot/src/share/vm/prims/jvmtiThreadState.hpp
+++ b/hotspot/src/share/vm/prims/jvmtiThreadState.hpp
@@ -72,7 +72,7 @@
 //
 // The Jvmti state for each thread (across all JvmtiEnv):
 // 1. Local table of enabled events.
-class JvmtiThreadState : public CHeapObj {
+class JvmtiThreadState : public CHeapObj<mtInternal> {
  private:
   friend class JvmtiEnv;
   JavaThread        *_thread;
diff --git a/hotspot/src/share/vm/prims/jvmtiUtil.cpp b/hotspot/src/share/vm/prims/jvmtiUtil.cpp
index 6671d48..425ca1d 100644
--- a/hotspot/src/share/vm/prims/jvmtiUtil.cpp
+++ b/hotspot/src/share/vm/prims/jvmtiUtil.cpp
@@ -40,7 +40,7 @@
   if (_single_threaded_resource_area == NULL) {
     // lazily create the single threaded resource area
     // pick a size which is not a standard since the pools don't exist yet
-    _single_threaded_resource_area = new ResourceArea(Chunk::non_pool_size);
+    _single_threaded_resource_area = new (mtInternal) ResourceArea(Chunk::non_pool_size);
   }
   return _single_threaded_resource_area;
 }
diff --git a/hotspot/src/share/vm/prims/methodHandleWalk.cpp b/hotspot/src/share/vm/prims/methodHandleWalk.cpp
deleted file mode 100644
index d4d9a71..0000000
--- a/hotspot/src/share/vm/prims/methodHandleWalk.cpp
+++ /dev/null
@@ -1,2089 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- *
- */
-
-#include "precompiled.hpp"
-#include "interpreter/rewriter.hpp"
-#include "memory/oopFactory.hpp"
-#include "prims/methodHandleWalk.hpp"
-
-/*
- * JSR 292 reference implementation: method handle structure analysis
- */
-
-#ifdef PRODUCT
-#define print_method_handle(mh) {}
-#else //PRODUCT
-extern "C" void print_method_handle(oop mh);
-#endif //PRODUCT
-
-// -----------------------------------------------------------------------------
-// MethodHandleChain
-
-void MethodHandleChain::set_method_handle(Handle mh, TRAPS) {
-  if (!java_lang_invoke_MethodHandle::is_instance(mh()))  lose("bad method handle", CHECK);
-
-  // set current method handle and unpack partially
-  _method_handle = mh;
-  _is_last       = false;
-  _is_bound      = false;
-  _arg_slot      = -1;
-  _arg_type      = T_VOID;
-  _conversion    = -1;
-  _last_invoke   = Bytecodes::_nop;  //arbitrary non-garbage
-
-  if (java_lang_invoke_DirectMethodHandle::is_instance(mh())) {
-    set_last_method(mh(), THREAD);
-    return;
-  }
-  if (java_lang_invoke_AdapterMethodHandle::is_instance(mh())) {
-    _conversion = AdapterMethodHandle_conversion();
-    assert(_conversion != -1, "bad conv value");
-    assert(java_lang_invoke_BoundMethodHandle::is_instance(mh()), "also BMH");
-  }
-  if (java_lang_invoke_BoundMethodHandle::is_instance(mh())) {
-    if (!is_adapter())          // keep AMH and BMH separate in this model
-      _is_bound = true;
-    _arg_slot = BoundMethodHandle_vmargslot();
-    oop target = MethodHandle_vmtarget_oop();
-    if (!is_bound() || java_lang_invoke_MethodHandle::is_instance(target)) {
-      _arg_type = compute_bound_arg_type(target, NULL, _arg_slot, CHECK);
-    } else if (target != NULL && target->is_method()) {
-      methodOop m = (methodOop) target;
-      _arg_type = compute_bound_arg_type(NULL, m, _arg_slot, CHECK);
-      set_last_method(mh(), CHECK);
-    } else {
-      _is_bound = false;  // lose!
-    }
-  }
-  if (is_bound() && _arg_type == T_VOID) {
-    lose("bad vmargslot", CHECK);
-  }
-  if (!is_bound() && !is_adapter()) {
-    lose("unrecognized MH type", CHECK);
-  }
-}
-
-
-void MethodHandleChain::set_last_method(oop target, TRAPS) {
-  _is_last = true;
-  KlassHandle receiver_limit; int flags = 0;
-  _last_method = MethodHandles::decode_method(target, receiver_limit, flags);
-  if ((flags & MethodHandles::_dmf_has_receiver) == 0)
-    _last_invoke = Bytecodes::_invokestatic;
-  else if ((flags & MethodHandles::_dmf_does_dispatch) == 0)
-    _last_invoke = Bytecodes::_invokespecial;
-  else if ((flags & MethodHandles::_dmf_from_interface) != 0)
-    _last_invoke = Bytecodes::_invokeinterface;
-  else
-    _last_invoke = Bytecodes::_invokevirtual;
-}
-
-
-BasicType MethodHandleChain::compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS) {
-  // There is no direct indication of whether the argument is primitive or not.
-  // It is implied by the _vmentry code, and by the MethodType of the target.
-  BasicType arg_type = T_VOID;
-  if (target != NULL) {
-    oop mtype = java_lang_invoke_MethodHandle::type(target);
-    int arg_num = MethodHandles::argument_slot_to_argnum(mtype, arg_slot);
-    if (arg_num >= 0) {
-      oop ptype = java_lang_invoke_MethodType::ptype(mtype, arg_num);
-      arg_type = java_lang_Class::as_BasicType(ptype);
-    }
-  } else if (m != NULL) {
-    // figure out the argument type from the slot
-    // FIXME: make this explicit in the MH
-    int cur_slot = m->size_of_parameters();
-    if (arg_slot >= cur_slot)
-      return T_VOID;
-    if (!m->is_static()) {
-      cur_slot -= type2size[T_OBJECT];
-      if (cur_slot == arg_slot)
-        return T_OBJECT;
-    }
-    ResourceMark rm(THREAD);
-    for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) {
-      BasicType bt = ss.type();
-      cur_slot -= type2size[bt];
-      if (cur_slot <= arg_slot) {
-        if (cur_slot == arg_slot)
-          arg_type = bt;
-        break;
-      }
-    }
-  }
-  if (arg_type == T_ARRAY)
-    arg_type = T_OBJECT;
-  return arg_type;
-}
-
-
-void MethodHandleChain::lose(const char* msg, TRAPS) {
-  _lose_message = msg;
-#ifdef ASSERT
-  if (Verbose) {
-    tty->print_cr(INTPTR_FORMAT " lose: %s", _method_handle(), msg);
-    print();
-  }
-#endif
-  if (!THREAD->is_Java_thread() || ((JavaThread*)THREAD)->thread_state() != _thread_in_vm) {
-    // throw a preallocated exception
-    THROW_OOP(Universe::virtual_machine_error_instance());
-  }
-  THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
-}
-
-
-#ifdef ASSERT
-static const char* adapter_ops[] = {
-  "retype_only"  ,
-  "retype_raw"   ,
-  "check_cast"   ,
-  "prim_to_prim" ,
-  "ref_to_prim"  ,
-  "prim_to_ref"  ,
-  "swap_args"    ,
-  "rot_args"     ,
-  "dup_args"     ,
-  "drop_args"    ,
-  "collect_args" ,
-  "spread_args"  ,
-  "fold_args"
-};
-
-static const char* adapter_op_to_string(int op) {
-  if (op >= 0 && op < (int)ARRAY_SIZE(adapter_ops))
-    return adapter_ops[op];
-  return "unknown_op";
-}
-
-void MethodHandleChain::print(oopDesc* m) {
-  HandleMark hm;
-  ResourceMark rm;
-  Handle mh(m);
-  EXCEPTION_MARK;
-  MethodHandleChain mhc(mh, THREAD);
-  if (HAS_PENDING_EXCEPTION) {
-    oop ex = THREAD->pending_exception();
-    CLEAR_PENDING_EXCEPTION;
-    ex->print();
-    return;
-  }
-  mhc.print();
-}
-
-
-void MethodHandleChain::print() {
-  EXCEPTION_MARK;
-  print_impl(THREAD);
-  if (HAS_PENDING_EXCEPTION) {
-    oop ex = THREAD->pending_exception();
-    CLEAR_PENDING_EXCEPTION;
-    ex->print();
-  }
-}
-
-void MethodHandleChain::print_impl(TRAPS) {
-  ResourceMark rm;
-
-  MethodHandleChain chain(_root, CHECK);
-  for (;;) {
-    tty->print(INTPTR_FORMAT ": ", chain.method_handle()());
-    if (chain.is_bound()) {
-      tty->print("bound: arg_type %s arg_slot %d",
-                 type2name(chain.bound_arg_type()),
-                 chain.bound_arg_slot());
-      oop o = chain.bound_arg_oop();
-      if (o != NULL) {
-        if (o->is_instance()) {
-          tty->print(" instance %s", o->klass()->klass_part()->internal_name());
-          if (java_lang_invoke_CountingMethodHandle::is_instance(o)) {
-            tty->print(" vmcount: %d", java_lang_invoke_CountingMethodHandle::vmcount(o));
-          }
-        } else {
-          o->print();
-        }
-      }
-      oop vmt = chain.vmtarget_oop();
-      if (vmt != NULL) {
-        if (vmt->is_method()) {
-          tty->print(" ");
-          methodOop(vmt)->print_short_name(tty);
-        } else if (java_lang_invoke_MethodHandle::is_instance(vmt)) {
-          tty->print(" method handle " INTPTR_FORMAT, vmt);
-        } else {
-          ShouldNotReachHere();
-        }
-      }
-    } else if (chain.is_adapter()) {
-      tty->print("adapter: arg_slot %d conversion op %s",
-                 chain.adapter_arg_slot(),
-                 adapter_op_to_string(chain.adapter_conversion_op()));
-      switch (chain.adapter_conversion_op()) {
-        case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY:
-          if (java_lang_invoke_CountingMethodHandle::is_instance(chain.method_handle_oop())) {
-            tty->print(" vmcount: %d", java_lang_invoke_CountingMethodHandle::vmcount(chain.method_handle_oop()));
-          }
-        case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW:
-        case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST:
-        case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM:
-        case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM:
-          break;
-
-        case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF: {
-          tty->print(" src_type = %s", type2name(chain.adapter_conversion_src_type()));
-          break;
-        }
-
-        case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS:
-        case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
-          int dest_arg_slot = chain.adapter_conversion_vminfo();
-          tty->print(" dest_arg_slot %d type %s", dest_arg_slot, type2name(chain.adapter_conversion_src_type()));
-          break;
-        }
-
-        case java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS:
-        case java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS: {
-          int dup_slots = chain.adapter_conversion_stack_pushes();
-          tty->print(" pushes %d", dup_slots);
-          break;
-        }
-
-        case java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS:
-        case java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS: {
-          int coll_slots = chain.MethodHandle_vmslots();
-          tty->print(" coll_slots %d", coll_slots);
-          break;
-        }
-
-        case java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS: {
-          // Check the required length.
-          int spread_slots = 1 + chain.adapter_conversion_stack_pushes();
-          tty->print(" spread_slots %d", spread_slots);
-          break;
-        }
-
-        default:
-          tty->print_cr("bad adapter conversion");
-          break;
-      }
-    } else {
-      // DMH
-      tty->print("direct: ");
-      chain.last_method_oop()->print_short_name(tty);
-    }
-
-    tty->print(" (");
-    objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(chain.method_type_oop());
-    for (int i = ptypes->length() - 1; i >= 0; i--) {
-      BasicType t = java_lang_Class::as_BasicType(ptypes->obj_at(i));
-      if (t == T_ARRAY) t = T_OBJECT;
-      tty->print("%c", type2char(t));
-      if (t == T_LONG || t == T_DOUBLE) tty->print("_");
-    }
-    tty->print(")");
-    BasicType rtype = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(chain.method_type_oop()));
-    if (rtype == T_ARRAY) rtype = T_OBJECT;
-    tty->print("%c", type2char(rtype));
-    tty->cr();
-    if (!chain.is_last()) {
-      chain.next(CHECK);
-    } else {
-      break;
-    }
-  }
-}
-#endif
-
-
-// -----------------------------------------------------------------------------
-// MethodHandleWalker
-
-Bytecodes::Code MethodHandleWalker::conversion_code(BasicType src, BasicType dest) {
-  if (is_subword_type(src)) {
-    src = T_INT;          // all subword src types act like int
-  }
-  if (src == dest) {
-    return Bytecodes::_nop;
-  }
-
-#define SRC_DEST(s,d) (((int)(s) << 4) + (int)(d))
-  switch (SRC_DEST(src, dest)) {
-  case SRC_DEST(T_INT, T_LONG):           return Bytecodes::_i2l;
-  case SRC_DEST(T_INT, T_FLOAT):          return Bytecodes::_i2f;
-  case SRC_DEST(T_INT, T_DOUBLE):         return Bytecodes::_i2d;
-  case SRC_DEST(T_INT, T_BYTE):           return Bytecodes::_i2b;
-  case SRC_DEST(T_INT, T_CHAR):           return Bytecodes::_i2c;
-  case SRC_DEST(T_INT, T_SHORT):          return Bytecodes::_i2s;
-
-  case SRC_DEST(T_LONG, T_INT):           return Bytecodes::_l2i;
-  case SRC_DEST(T_LONG, T_FLOAT):         return Bytecodes::_l2f;
-  case SRC_DEST(T_LONG, T_DOUBLE):        return Bytecodes::_l2d;
-
-  case SRC_DEST(T_FLOAT, T_INT):          return Bytecodes::_f2i;
-  case SRC_DEST(T_FLOAT, T_LONG):         return Bytecodes::_f2l;
-  case SRC_DEST(T_FLOAT, T_DOUBLE):       return Bytecodes::_f2d;
-
-  case SRC_DEST(T_DOUBLE, T_INT):         return Bytecodes::_d2i;
-  case SRC_DEST(T_DOUBLE, T_LONG):        return Bytecodes::_d2l;
-  case SRC_DEST(T_DOUBLE, T_FLOAT):       return Bytecodes::_d2f;
-  }
-#undef SRC_DEST
-
-  // cannot do it in one step, or at all
-  return Bytecodes::_illegal;
-}
-
-
-// -----------------------------------------------------------------------------
-// MethodHandleWalker::walk
-//
-MethodHandleWalker::ArgToken
-MethodHandleWalker::walk(TRAPS) {
-  ArgToken empty = ArgToken();  // Empty return value.
-
-  walk_incoming_state(CHECK_(empty));
-
-  for (;;) {
-    set_method_handle(chain().method_handle_oop());
-
-    assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
-
-    if (chain().is_adapter()) {
-      int conv_op = chain().adapter_conversion_op();
-      int arg_slot = chain().adapter_arg_slot();
-
-      // Check that the arg_slot is valid.  In most cases it must be
-      // within range of the current arguments but there are some
-      // exceptions.  Those are sanity checked in their implemention
-      // below.
-      if ((arg_slot < 0 || arg_slot >= _outgoing.length()) &&
-          conv_op > java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW &&
-          conv_op != java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS &&
-          conv_op != java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS) {
-        lose(err_msg("bad argument index %d", arg_slot), CHECK_(empty));
-      }
-
-      bool retain_original_args = false;  // used by fold/collect logic
-
-      // perform the adapter action
-      switch (conv_op) {
-      case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY:
-        // No changes to arguments; pass the bits through.
-        break;
-
-      case java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW: {
-        // To keep the verifier happy, emit bitwise ("raw") conversions as needed.
-        // See MethodHandles::same_basic_type_for_arguments for allowed conversions.
-        Handle incoming_mtype(THREAD, chain().method_type_oop());
-        Handle outgoing_mtype;
-        {
-          oop outgoing_mh_oop = chain().vmtarget_oop();
-          if (!java_lang_invoke_MethodHandle::is_instance(outgoing_mh_oop))
-            lose("outgoing target not a MethodHandle", CHECK_(empty));
-          outgoing_mtype = Handle(THREAD, java_lang_invoke_MethodHandle::type(outgoing_mh_oop));
-        }
-
-        int nptypes = java_lang_invoke_MethodType::ptype_count(outgoing_mtype());
-        if (nptypes != java_lang_invoke_MethodType::ptype_count(incoming_mtype()))
-          lose("incoming and outgoing parameter count do not agree", CHECK_(empty));
-
-        // Argument types.
-        for (int i = 0, slot = _outgoing.length() - 1; slot >= 0; slot--) {
-          if (arg_type(slot) == T_VOID)  continue;
-
-          klassOop  src_klass = NULL;
-          klassOop  dst_klass = NULL;
-          BasicType src = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(incoming_mtype(), i), &src_klass);
-          BasicType dst = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(outgoing_mtype(), i), &dst_klass);
-          retype_raw_argument_type(src, dst, slot, CHECK_(empty));
-          i++;  // We need to skip void slots at the top of the loop.
-        }
-
-        // Return type.
-        {
-          BasicType src = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(incoming_mtype()));
-          BasicType dst = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(outgoing_mtype()));
-          retype_raw_return_type(src, dst, CHECK_(empty));
-        }
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST: {
-        // checkcast the Nth outgoing argument in place
-        klassOop dest_klass = NULL;
-        BasicType dest = java_lang_Class::as_BasicType(chain().adapter_arg_oop(), &dest_klass);
-        assert(dest == T_OBJECT, "");
-        ArgToken arg = _outgoing.at(arg_slot);
-        assert(dest == arg.basic_type(), "");
-        arg = make_conversion(T_OBJECT, dest_klass, Bytecodes::_checkcast, arg, CHECK_(empty));
-        // replace the object by the result of the cast, to make the compiler happy:
-        change_argument(T_OBJECT, arg_slot, T_OBJECT, arg);
-        debug_only(dest_klass = (klassOop)badOop);
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM: {
-        // i2l, etc., on the Nth outgoing argument in place
-        BasicType src = chain().adapter_conversion_src_type(),
-                  dest = chain().adapter_conversion_dest_type();
-        ArgToken arg = _outgoing.at(arg_slot);
-        Bytecodes::Code bc = conversion_code(src, dest);
-        if (bc == Bytecodes::_nop) {
-          break;
-        } else if (bc != Bytecodes::_illegal) {
-          arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty));
-        } else if (is_subword_type(dest)) {
-          bc = conversion_code(src, T_INT);
-          if (bc != Bytecodes::_illegal) {
-            arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty));
-            bc = conversion_code(T_INT, dest);
-            arg = make_conversion(dest, NULL, bc, arg, CHECK_(empty));
-          }
-        }
-        if (bc == Bytecodes::_illegal) {
-          lose(err_msg("bad primitive conversion for %s -> %s", type2name(src), type2name(dest)), CHECK_(empty));
-        }
-        change_argument(src, arg_slot, dest, arg);
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM: {
-        // checkcast to wrapper type & call intValue, etc.
-        BasicType dest = chain().adapter_conversion_dest_type();
-        ArgToken arg = _outgoing.at(arg_slot);
-        arg = make_conversion(T_OBJECT, SystemDictionary::box_klass(dest),
-                              Bytecodes::_checkcast, arg, CHECK_(empty));
-        vmIntrinsics::ID unboxer = vmIntrinsics::for_unboxing(dest);
-        if (unboxer == vmIntrinsics::_none) {
-          lose("no unboxing method", CHECK_(empty));
-        }
-        ArgToken arglist[2];
-        arglist[0] = arg;         // outgoing 'this'
-        arglist[1] = ArgToken();  // sentinel
-        arg = make_invoke(methodHandle(), unboxer, Bytecodes::_invokevirtual, false, 1, &arglist[0], CHECK_(empty));
-        change_argument(T_OBJECT, arg_slot, dest, arg);
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF: {
-        // call wrapper type.valueOf
-        BasicType src = chain().adapter_conversion_src_type();
-        vmIntrinsics::ID boxer = vmIntrinsics::for_boxing(src);
-        if (boxer == vmIntrinsics::_none) {
-          lose("no boxing method", CHECK_(empty));
-        }
-        ArgToken arg = _outgoing.at(arg_slot);
-        ArgToken arglist[2];
-        arglist[0] = arg;         // outgoing value
-        arglist[1] = ArgToken();  // sentinel
-        arg = make_invoke(methodHandle(), boxer, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(empty));
-        change_argument(src, arg_slot, T_OBJECT, arg);
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS: {
-        int dest_arg_slot = chain().adapter_conversion_vminfo();
-        if (!has_argument(dest_arg_slot)) {
-          lose("bad swap index", CHECK_(empty));
-        }
-        // a simple swap between two arguments
-        if (arg_slot > dest_arg_slot) {
-          int tmp = arg_slot;
-          arg_slot = dest_arg_slot;
-          dest_arg_slot = tmp;
-        }
-        ArgToken a1 = _outgoing.at(arg_slot);
-        ArgToken a2 = _outgoing.at(dest_arg_slot);
-        change_argument(a2.basic_type(), dest_arg_slot, a1);
-        change_argument(a1.basic_type(), arg_slot, a2);
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS: {
-        int limit_raw  = chain().adapter_conversion_vminfo();
-        bool rot_down  = (arg_slot < limit_raw);
-        int limit_bias = (rot_down ? MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS : 0);
-        int limit_slot = limit_raw - limit_bias;
-        if ((uint)limit_slot > (uint)_outgoing.length()) {
-          lose("bad rotate index", CHECK_(empty));
-        }
-        // Rotate the source argument (plus following N slots) into the
-        // position occupied by the dest argument (plus following N slots).
-        int rotate_count = type2size[chain().adapter_conversion_src_type()];
-        // (no other rotate counts are currently supported)
-        if (rot_down) {
-          for (int i = 0; i < rotate_count; i++) {
-            ArgToken temp = _outgoing.at(arg_slot);
-            _outgoing.remove_at(arg_slot);
-            _outgoing.insert_before(limit_slot - 1, temp);
-          }
-        } else { // arg_slot > limit_slot => rotate_up
-          for (int i = 0; i < rotate_count; i++) {
-            ArgToken temp = _outgoing.at(arg_slot + rotate_count - 1);
-            _outgoing.remove_at(arg_slot + rotate_count - 1);
-            _outgoing.insert_before(limit_slot, temp);
-          }
-        }
-        assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS: {
-        int dup_slots = chain().adapter_conversion_stack_pushes();
-        if (dup_slots <= 0) {
-          lose("bad dup count", CHECK_(empty));
-        }
-        for (int i = 0; i < dup_slots; i++) {
-          ArgToken dup = _outgoing.at(arg_slot + 2*i);
-          if (dup.basic_type() != T_VOID)     _outgoing_argc += 1;
-          _outgoing.insert_before(i, dup);
-        }
-        assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS: {
-        int drop_slots = -chain().adapter_conversion_stack_pushes();
-        if (drop_slots <= 0) {
-          lose("bad drop count", CHECK_(empty));
-        }
-        for (int i = 0; i < drop_slots; i++) {
-          ArgToken drop = _outgoing.at(arg_slot);
-          if (drop.basic_type() != T_VOID)    _outgoing_argc -= 1;
-          _outgoing.remove_at(arg_slot);
-        }
-        assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS:
-        retain_original_args = true;   // and fall through:
-      case java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS: {
-        // call argument MH recursively
-        //{static int x; if (!x++) print_method_handle(chain().method_handle_oop()); --x;}
-        Handle recursive_mh(THREAD, chain().adapter_arg_oop());
-        if (!java_lang_invoke_MethodHandle::is_instance(recursive_mh())) {
-          lose("recursive target not a MethodHandle", CHECK_(empty));
-        }
-        Handle recursive_mtype(THREAD, java_lang_invoke_MethodHandle::type(recursive_mh()));
-        int argc = java_lang_invoke_MethodType::ptype_count(recursive_mtype());
-        int coll_slots = java_lang_invoke_MethodHandle::vmslots(recursive_mh());
-        BasicType rtype = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(recursive_mtype()));
-        ArgToken* arglist = NEW_RESOURCE_ARRAY(ArgToken, 1 + argc + 1);  // 1+: mh, +1: sentinel
-        arglist[0] = make_oop_constant(recursive_mh(), CHECK_(empty));
-        if (arg_slot < 0 || coll_slots < 0 || arg_slot + coll_slots > _outgoing.length()) {
-          lose("bad fold/collect arg slot", CHECK_(empty));
-        }
-        for (int i = 0, slot = arg_slot + coll_slots - 1; slot >= arg_slot; slot--) {
-          ArgToken arg_state = _outgoing.at(slot);
-          BasicType  arg_type  = arg_state.basic_type();
-          if (arg_type == T_VOID)  continue;
-          ArgToken arg = _outgoing.at(slot);
-          if (i >= argc) { lose("bad fold/collect arg", CHECK_(empty)); }
-          arglist[1+i] = arg;
-          if (!retain_original_args)
-            change_argument(arg_type, slot, T_VOID, ArgToken(tt_void));
-          i++;
-        }
-        arglist[1+argc] = ArgToken();  // sentinel
-        oop invoker = java_lang_invoke_MethodTypeForm::vmlayout(
-                          java_lang_invoke_MethodType::form(recursive_mtype()) );
-        if (invoker == NULL || !invoker->is_method()) {
-          lose("bad vmlayout slot", CHECK_(empty));
-        }
-        // FIXME: consider inlining the invokee at the bytecode level
-        ArgToken ret = make_invoke(methodHandle(THREAD, methodOop(invoker)), vmIntrinsics::_invokeGeneric,
-                                   Bytecodes::_invokevirtual, false, 1+argc, &arglist[0], CHECK_(empty));
-        // The iid = _invokeGeneric really means to adjust reference types as needed.
-        DEBUG_ONLY(invoker = NULL);
-        if (rtype == T_OBJECT) {
-          klassOop rklass = java_lang_Class::as_klassOop( java_lang_invoke_MethodType::rtype(recursive_mtype()) );
-          if (rklass != SystemDictionary::Object_klass() &&
-              !Klass::cast(rklass)->is_interface()) {
-            // preserve type safety
-            ret = make_conversion(T_OBJECT, rklass, Bytecodes::_checkcast, ret, CHECK_(empty));
-          }
-        }
-        if (rtype != T_VOID) {
-          int ret_slot = arg_slot + (retain_original_args ? coll_slots : 0);
-          change_argument(T_VOID, ret_slot, rtype, ret);
-        }
-        break;
-      }
-
-      case java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS: {
-        klassOop array_klass_oop = NULL;
-        BasicType array_type = java_lang_Class::as_BasicType(chain().adapter_arg_oop(),
-                                                             &array_klass_oop);
-        assert(array_type == T_OBJECT, "");
-        assert(Klass::cast(array_klass_oop)->oop_is_array(), "");
-        arrayKlassHandle array_klass(THREAD, array_klass_oop);
-        debug_only(array_klass_oop = (klassOop)badOop);
-
-        klassOop element_klass_oop = NULL;
-        BasicType element_type = java_lang_Class::as_BasicType(array_klass->component_mirror(),
-                                                               &element_klass_oop);
-        KlassHandle element_klass(THREAD, element_klass_oop);
-        debug_only(element_klass_oop = (klassOop)badOop);
-
-        // Fetch the argument, which we will cast to the required array type.
-        ArgToken arg = _outgoing.at(arg_slot);
-        assert(arg.basic_type() == T_OBJECT, "");
-        ArgToken array_arg = arg;
-        array_arg = make_conversion(T_OBJECT, array_klass(), Bytecodes::_checkcast, array_arg, CHECK_(empty));
-        change_argument(T_OBJECT, arg_slot, T_VOID, ArgToken(tt_void));
-
-        // Check the required length.
-        int spread_slots = 1 + chain().adapter_conversion_stack_pushes();
-        int spread_length = spread_slots;
-        if (type2size[element_type] == 2) {
-          if (spread_slots % 2 != 0)  spread_slots = -1;  // force error
-          spread_length = spread_slots / 2;
-        }
-        if (spread_slots < 0) {
-          lose("bad spread length", CHECK_(empty));
-        }
-
-        jvalue   length_jvalue;  length_jvalue.i = spread_length;
-        ArgToken length_arg = make_prim_constant(T_INT, &length_jvalue, CHECK_(empty));
-        // Call a built-in method known to the JVM to validate the length.
-        ArgToken arglist[3];
-        arglist[0] = array_arg;   // value to check
-        arglist[1] = length_arg;  // length to check
-        arglist[2] = ArgToken();  // sentinel
-        make_invoke(methodHandle(), vmIntrinsics::_checkSpreadArgument,
-                    Bytecodes::_invokestatic, false, 2, &arglist[0], CHECK_(empty));
-
-        // Spread out the array elements.
-        Bytecodes::Code aload_op = Bytecodes::_nop;
-        switch (element_type) {
-        case T_INT:       aload_op = Bytecodes::_iaload; break;
-        case T_LONG:      aload_op = Bytecodes::_laload; break;
-        case T_FLOAT:     aload_op = Bytecodes::_faload; break;
-        case T_DOUBLE:    aload_op = Bytecodes::_daload; break;
-        case T_OBJECT:    aload_op = Bytecodes::_aaload; break;
-        case T_BOOLEAN:   // fall through:
-        case T_BYTE:      aload_op = Bytecodes::_baload; break;
-        case T_CHAR:      aload_op = Bytecodes::_caload; break;
-        case T_SHORT:     aload_op = Bytecodes::_saload; break;
-        default:          lose("primitive array NYI", CHECK_(empty));
-        }
-        int ap = arg_slot;
-        for (int i = 0; i < spread_length; i++) {
-          jvalue   offset_jvalue;  offset_jvalue.i = i;
-          ArgToken offset_arg = make_prim_constant(T_INT, &offset_jvalue, CHECK_(empty));
-          ArgToken element_arg = make_fetch(element_type, element_klass(), aload_op, array_arg, offset_arg, CHECK_(empty));
-          change_argument(T_VOID, ap, element_type, element_arg);
-          //ap += type2size[element_type];  // don't do this; insert next arg to *right* of previous
-        }
-        break;
-      }
-
-      default:
-        lose("bad adapter conversion", CHECK_(empty));
-        break;
-      }
-    }
-
-    if (chain().is_bound()) {
-      // push a new argument
-      BasicType arg_type  = chain().bound_arg_type();
-      jint      arg_slot  = chain().bound_arg_slot();
-      oop       arg_oop   = chain().bound_arg_oop();
-      ArgToken  arg;
-      if (arg_type == T_OBJECT) {
-        arg = make_oop_constant(arg_oop, CHECK_(empty));
-      } else {
-        jvalue arg_value;
-        BasicType bt = java_lang_boxing_object::get_value(arg_oop, &arg_value);
-        if (bt == arg_type || (bt == T_INT && is_subword_type(arg_type))) {
-          arg = make_prim_constant(arg_type, &arg_value, CHECK_(empty));
-        } else {
-          lose(err_msg("bad bound value: arg_type %s boxing %s", type2name(arg_type), type2name(bt)), CHECK_(empty));
-        }
-      }
-      DEBUG_ONLY(arg_oop = badOop);
-      change_argument(T_VOID, arg_slot, arg_type, arg);
-    }
-
-    // this test must come after the body of the loop
-    if (!chain().is_last()) {
-      chain().next(CHECK_(empty));
-    } else {
-      break;
-    }
-  }
-
-  // finish the sequence with a tail-call to the ultimate target
-  // parameters are passed in logical order (recv 1st), not slot order
-  ArgToken* arglist = NEW_RESOURCE_ARRAY(ArgToken, _outgoing.length() + 1);
-  int ap = 0;
-  for (int i = _outgoing.length() - 1; i >= 0; i--) {
-    ArgToken arg_state = _outgoing.at(i);
-    if (arg_state.basic_type() == T_VOID)  continue;
-    arglist[ap++] = _outgoing.at(i);
-  }
-  assert(ap == _outgoing_argc, "");
-  arglist[ap] = ArgToken();  // add a sentinel, for the sake of asserts
-  return make_invoke(chain().last_method(),
-                     vmIntrinsics::_none,
-                     chain().last_invoke_code(), true,
-                     ap, arglist, THREAD);
-}
-
-
-// -----------------------------------------------------------------------------
-// MethodHandleWalker::walk_incoming_state
-//
-void MethodHandleWalker::walk_incoming_state(TRAPS) {
-  Handle mtype(THREAD, chain().method_type_oop());
-  int nptypes = java_lang_invoke_MethodType::ptype_count(mtype());
-  _outgoing_argc = nptypes;
-  int argp = nptypes - 1;
-  if (argp >= 0) {
-    _outgoing.at_grow(argp, ArgToken(tt_void)); // presize
-  }
-  for (int i = 0; i < nptypes; i++) {
-    klassOop  arg_type_klass = NULL;
-    BasicType arg_type = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::ptype(mtype(), i), &arg_type_klass);
-    int index = new_local_index(arg_type);
-    ArgToken arg = make_parameter(arg_type, arg_type_klass, index, CHECK);
-    DEBUG_ONLY(arg_type_klass = (klassOop) NULL);
-    _outgoing.at_put(argp, arg);
-    if (type2size[arg_type] == 2) {
-      // add the extra slot, so we can model the JVM stack
-      _outgoing.insert_before(argp+1, ArgToken(tt_void));
-    }
-    --argp;
-  }
-  // call make_parameter at the end of the list for the return type
-  klassOop  ret_type_klass = NULL;
-  BasicType ret_type = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(mtype()), &ret_type_klass);
-  ArgToken  ret = make_parameter(ret_type, ret_type_klass, -1, CHECK);
-  // ignore ret; client can catch it if needed
-
-  assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
-
-  verify_args_and_signature(CHECK);
-}
-
-
-#ifdef ASSERT
-void MethodHandleWalker::verify_args_and_signature(TRAPS) {
-  int index = _outgoing.length() - 1;
-  objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(chain().method_type_oop());
-  for (int i = 0, limit = ptypes->length(); i < limit; i++) {
-    BasicType t = java_lang_Class::as_BasicType(ptypes->obj_at(i));
-    if (t == T_ARRAY) t = T_OBJECT;
-    if (t == T_LONG || t == T_DOUBLE) {
-      assert(T_VOID == _outgoing.at(index).basic_type(), "types must match");
-      index--;
-    }
-    assert(t == _outgoing.at(index).basic_type(), "types must match");
-    index--;
-  }
-}
-#endif
-
-
-// -----------------------------------------------------------------------------
-// MethodHandleWalker::change_argument
-//
-// This is messy because some kinds of arguments are paired with
-// companion slots containing an empty value.
-void MethodHandleWalker::change_argument(BasicType old_type, int slot, const ArgToken& new_arg) {
-  BasicType new_type = new_arg.basic_type();
-  int old_size = type2size[old_type];
-  int new_size = type2size[new_type];
-  if (old_size == new_size) {
-    // simple case first
-    _outgoing.at_put(slot, new_arg);
-  } else if (old_size > new_size) {
-    for (int i = old_size - 1; i >= new_size; i--) {
-      assert((i != 0) == (_outgoing.at(slot + i).basic_type() == T_VOID), "");
-      _outgoing.remove_at(slot + i);
-    }
-    if (new_size > 0)
-      _outgoing.at_put(slot, new_arg);
-    else
-      _outgoing_argc -= 1;      // deleted a real argument
-  } else {
-    for (int i = old_size; i < new_size; i++) {
-      _outgoing.insert_before(slot + i, ArgToken(tt_void));
-    }
-    _outgoing.at_put(slot, new_arg);
-    if (old_size == 0)
-      _outgoing_argc += 1;      // inserted a real argument
-  }
-  assert(_outgoing_argc == argument_count_slow(), "empty slots under control");
-}
-
-
-#ifdef ASSERT
-int MethodHandleWalker::argument_count_slow() {
-  int args_seen = 0;
-  for (int i = _outgoing.length() - 1; i >= 0; i--) {
-    if (_outgoing.at(i).basic_type() != T_VOID) {
-      ++args_seen;
-      if (_outgoing.at(i).basic_type() == T_LONG ||
-          _outgoing.at(i).basic_type() == T_DOUBLE) {
-        assert(_outgoing.at(i + 1).basic_type() == T_VOID, "should only follow two word");
-      }
-    } else {
-      assert(_outgoing.at(i - 1).basic_type() == T_LONG ||
-             _outgoing.at(i - 1).basic_type() == T_DOUBLE, "should only follow two word");
-    }
-  }
-  return args_seen;
-}
-#endif
-
-
-// -----------------------------------------------------------------------------
-// MethodHandleWalker::retype_raw_conversion
-//
-// Do the raw retype conversions for OP_RETYPE_RAW.
-void MethodHandleWalker::retype_raw_conversion(BasicType src, BasicType dst, bool for_return, int slot, TRAPS) {
-  if (src != dst) {
-    if (MethodHandles::same_basic_type_for_returns(src, dst, /*raw*/ true)) {
-      if (MethodHandles::is_float_fixed_reinterpretation_cast(src, dst)) {
-        vmIntrinsics::ID iid = vmIntrinsics::for_raw_conversion(src, dst);
-        if (iid == vmIntrinsics::_none) {
-          lose("no raw conversion method", CHECK);
-        }
-        ArgToken arglist[2];
-        if (!for_return) {
-          // argument type conversion
-          ArgToken arg = _outgoing.at(slot);
-          assert(arg.token_type() >= tt_symbolic || src == arg.basic_type(), "sanity");
-          arglist[0] = arg;         // outgoing 'this'
-          arglist[1] = ArgToken();  // sentinel
-          arg = make_invoke(methodHandle(), iid, Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK);
-          change_argument(src, slot, dst, arg);
-        } else {
-          // return type conversion
-          if (_return_conv == vmIntrinsics::_none) {
-            _return_conv = iid;
-          } else if (_return_conv == vmIntrinsics::for_raw_conversion(dst, src)) {
-            _return_conv = vmIntrinsics::_none;
-          } else if (_return_conv != zero_return_conv()) {
-            lose(err_msg("requested raw return conversion not allowed: %s -> %s (before %s)", type2name(src), type2name(dst), vmIntrinsics::name_at(_return_conv)), CHECK);
-          }
-        }
-      } else {
-        // Nothing to do.
-      }
-    } else if (for_return && (!is_subword_type(src) || !is_subword_type(dst))) {
-      // This can occur in exception-throwing MHs, which have a fictitious return value encoded as Void or Empty.
-      _return_conv = zero_return_conv();
-    } else if (src == T_OBJECT && is_java_primitive(dst)) {
-      // ref-to-prim: discard ref, push zero
-      lose("requested ref-to-prim conversion not expected", CHECK);
-    } else {
-      lose(err_msg("requested raw conversion not allowed: %s -> %s", type2name(src), type2name(dst)), CHECK);
-    }
-  }
-}
-
-
-// -----------------------------------------------------------------------------
-// MethodHandleCompiler
-
-MethodHandleCompiler::MethodHandleCompiler(Handle root, Symbol* name, Symbol* signature, int invoke_count, bool is_invokedynamic, TRAPS)
-  : MethodHandleWalker(root, is_invokedynamic, THREAD),
-    _invoke_count(invoke_count),
-    _thread(THREAD),
-    _bytecode(THREAD, 50),
-    _constants(THREAD, 10),
-    _non_bcp_klasses(THREAD, 5),
-    _cur_stack(0),
-    _max_stack(0),
-    _rtype(T_ILLEGAL),
-    _selectAlternative_bci(-1),
-    _taken_count(0),
-    _not_taken_count(0)
-{
-
-  // Element zero is always the null constant.
-  (void) _constants.append(NULL);
-
-  // Set name and signature index.
-  _name_index      = cpool_symbol_put(name);
-  _signature_index = cpool_symbol_put(signature);
-
-  // To make the resulting methods more recognizable by
-  // stack walkers and compiler heuristics,
-  // we put them in holder class MethodHandle.
-  // See klass_is_method_handle_adapter_holder
-  // and methodOopDesc::is_method_handle_adapter.
-  _target_klass = SystemDictionaryHandles::MethodHandle_klass();
-
-  check_non_bcp_klasses(java_lang_invoke_MethodHandle::type(root()), CHECK);
-
-  // Get return type klass.
-  Handle first_mtype(THREAD, chain().method_type_oop());
-  // _rklass is NULL for primitives.
-  _rtype = java_lang_Class::as_BasicType(java_lang_invoke_MethodType::rtype(first_mtype()), &_rklass);
-  if (_rtype == T_ARRAY)  _rtype = T_OBJECT;
-
-  ArgumentSizeComputer args(signature);
-  int params = args.size() + 1;  // Incoming arguments plus receiver.
-  _num_params = for_invokedynamic() ? params - 1 : params;  // XXX Check if callee is static?
-}
-
-
-// -----------------------------------------------------------------------------
-// MethodHandleCompiler::compile
-//
-// Compile this MethodHandle into a bytecode adapter and return a
-// methodOop.
-methodHandle MethodHandleCompiler::compile(TRAPS) {
-  assert(_thread == THREAD, "must be same thread");
-  methodHandle nullHandle;
-  (void) walk(CHECK_(nullHandle));
-  record_non_bcp_klasses();
-  return get_method_oop(CHECK_(nullHandle));
-}
-
-
-void MethodHandleCompiler::emit_bc(Bytecodes::Code op, int index, int args_size) {
-  Bytecodes::check(op);  // Are we legal?
-
-  switch (op) {
-  // b
-  case Bytecodes::_aconst_null:
-  case Bytecodes::_iconst_m1:
-  case Bytecodes::_iconst_0:
-  case Bytecodes::_iconst_1:
-  case Bytecodes::_iconst_2:
-  case Bytecodes::_iconst_3:
-  case Bytecodes::_iconst_4:
-  case Bytecodes::_iconst_5:
-  case Bytecodes::_lconst_0:
-  case Bytecodes::_lconst_1:
-  case Bytecodes::_fconst_0:
-  case Bytecodes::_fconst_1:
-  case Bytecodes::_fconst_2:
-  case Bytecodes::_dconst_0:
-  case Bytecodes::_dconst_1:
-  case Bytecodes::_iload_0:
-  case Bytecodes::_iload_1:
-  case Bytecodes::_iload_2:
-  case Bytecodes::_iload_3:
-  case Bytecodes::_lload_0:
-  case Bytecodes::_lload_1:
-  case Bytecodes::_lload_2:
-  case Bytecodes::_lload_3:
-  case Bytecodes::_fload_0:
-  case Bytecodes::_fload_1:
-  case Bytecodes::_fload_2:
-  case Bytecodes::_fload_3:
-  case Bytecodes::_dload_0:
-  case Bytecodes::_dload_1:
-  case Bytecodes::_dload_2:
-  case Bytecodes::_dload_3:
-  case Bytecodes::_aload_0:
-  case Bytecodes::_aload_1:
-  case Bytecodes::_aload_2:
-  case Bytecodes::_aload_3:
-  case Bytecodes::_istore_0:
-  case Bytecodes::_istore_1:
-  case Bytecodes::_istore_2:
-  case Bytecodes::_istore_3:
-  case Bytecodes::_lstore_0:
-  case Bytecodes::_lstore_1:
-  case Bytecodes::_lstore_2:
-  case Bytecodes::_lstore_3:
-  case Bytecodes::_fstore_0:
-  case Bytecodes::_fstore_1:
-  case Bytecodes::_fstore_2:
-  case Bytecodes::_fstore_3:
-  case Bytecodes::_dstore_0:
-  case Bytecodes::_dstore_1:
-  case Bytecodes::_dstore_2:
-  case Bytecodes::_dstore_3:
-  case Bytecodes::_astore_0:
-  case Bytecodes::_astore_1:
-  case Bytecodes::_astore_2:
-  case Bytecodes::_astore_3:
-  case Bytecodes::_iand:
-  case Bytecodes::_i2l:
-  case Bytecodes::_i2f:
-  case Bytecodes::_i2d:
-  case Bytecodes::_i2b:
-  case Bytecodes::_i2c:
-  case Bytecodes::_i2s:
-  case Bytecodes::_l2i:
-  case Bytecodes::_l2f:
-  case Bytecodes::_l2d:
-  case Bytecodes::_f2i:
-  case Bytecodes::_f2l:
-  case Bytecodes::_f2d:
-  case Bytecodes::_d2i:
-  case Bytecodes::_d2l:
-  case Bytecodes::_d2f:
-  case Bytecodes::_iaload:
-  case Bytecodes::_laload:
-  case Bytecodes::_faload:
-  case Bytecodes::_daload:
-  case Bytecodes::_aaload:
-  case Bytecodes::_baload:
-  case Bytecodes::_caload:
-  case Bytecodes::_saload:
-  case Bytecodes::_ireturn:
-  case Bytecodes::_lreturn:
-  case Bytecodes::_freturn:
-  case Bytecodes::_dreturn:
-  case Bytecodes::_areturn:
-  case Bytecodes::_return:
-    assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_b, "wrong bytecode format");
-    _bytecode.push(op);
-    break;
-
-  // bi
-  case Bytecodes::_ldc:
-    assert(Bytecodes::format_bits(op, false) == (Bytecodes::_fmt_b|Bytecodes::_fmt_has_k), "wrong bytecode format");
-    if (index == (index & 0xff)) {
-      _bytecode.push(op);
-      _bytecode.push(index);
-    } else {
-      _bytecode.push(Bytecodes::_ldc_w);
-      _bytecode.push(index >> 8);
-      _bytecode.push(index);
-    }
-    break;
-
-  case Bytecodes::_iload:
-  case Bytecodes::_lload:
-  case Bytecodes::_fload:
-  case Bytecodes::_dload:
-  case Bytecodes::_aload:
-  case Bytecodes::_istore:
-  case Bytecodes::_lstore:
-  case Bytecodes::_fstore:
-  case Bytecodes::_dstore:
-  case Bytecodes::_astore:
-    assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bi, "wrong bytecode format");
-    if (index == (index & 0xff)) {
-      _bytecode.push(op);
-      _bytecode.push(index);
-    } else {
-      // doesn't fit in a u2
-      _bytecode.push(Bytecodes::_wide);
-      _bytecode.push(op);
-      _bytecode.push(index >> 8);
-      _bytecode.push(index);
-    }
-    break;
-
-  // bkk
-  case Bytecodes::_ldc_w:
-  case Bytecodes::_ldc2_w:
-  case Bytecodes::_checkcast:
-    assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bkk, "wrong bytecode format");
-    assert((unsigned short) index == index, "index does not fit in 16-bit");
-    _bytecode.push(op);
-    _bytecode.push(index >> 8);
-    _bytecode.push(index);
-    break;
-
-  // bJJ
-  case Bytecodes::_invokestatic:
-  case Bytecodes::_invokespecial:
-  case Bytecodes::_invokevirtual:
-    assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bJJ, "wrong bytecode format");
-    assert((unsigned short) index == index, "index does not fit in 16-bit");
-    _bytecode.push(op);
-    _bytecode.push(index >> 8);
-    _bytecode.push(index);
-    break;
-
-  case Bytecodes::_invokeinterface:
-    assert(Bytecodes::format_bits(op, false) == Bytecodes::_fmt_bJJ, "wrong bytecode format");
-    assert((unsigned short) index == index, "index does not fit in 16-bit");
-    assert(args_size > 0, "valid args_size");
-    _bytecode.push(op);
-    _bytecode.push(index >> 8);
-    _bytecode.push(index);
-    _bytecode.push(args_size);
-    _bytecode.push(0);
-    break;
-
-  case Bytecodes::_ifeq:
-    assert((unsigned short) index == index, "index does not fit in 16-bit");
-    _bytecode.push(op);
-    _bytecode.push(index >> 8);
-    _bytecode.push(index);
-    break;
-
-  default:
-    ShouldNotReachHere();
-  }
-}
-
-void MethodHandleCompiler::update_branch_dest(int src, int dst) {
-  switch (_bytecode.at(src)) {
-    case Bytecodes::_ifeq:
-      dst -= src; // compute the offset
-      assert((unsigned short) dst == dst, "index does not fit in 16-bit");
-      _bytecode.at_put(src + 1, dst >> 8);
-      _bytecode.at_put(src + 2, dst);
-      break;
-    default:
-      ShouldNotReachHere();
-  }
-}
-
-void MethodHandleCompiler::emit_load(ArgToken arg) {
-  TokenType tt = arg.token_type();
-  BasicType bt = arg.basic_type();
-
-  switch (tt) {
-    case tt_parameter:
-    case tt_temporary:
-      emit_load(bt, arg.index());
-      break;
-    case tt_constant:
-      emit_load_constant(arg);
-      break;
-    case tt_illegal:
-    case tt_void:
-    default:
-      ShouldNotReachHere();
-  }
-}
-
-
-void MethodHandleCompiler::emit_load(BasicType bt, int index) {
-  if (index <= 3) {
-    switch (bt) {
-    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
-    case T_INT:    emit_bc(Bytecodes::cast(Bytecodes::_iload_0 + index)); break;
-    case T_LONG:   emit_bc(Bytecodes::cast(Bytecodes::_lload_0 + index)); break;
-    case T_FLOAT:  emit_bc(Bytecodes::cast(Bytecodes::_fload_0 + index)); break;
-    case T_DOUBLE: emit_bc(Bytecodes::cast(Bytecodes::_dload_0 + index)); break;
-    case T_OBJECT: emit_bc(Bytecodes::cast(Bytecodes::_aload_0 + index)); break;
-    default:
-      ShouldNotReachHere();
-    }
-  }
-  else {
-    switch (bt) {
-    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
-    case T_INT:    emit_bc(Bytecodes::_iload, index); break;
-    case T_LONG:   emit_bc(Bytecodes::_lload, index); break;
-    case T_FLOAT:  emit_bc(Bytecodes::_fload, index); break;
-    case T_DOUBLE: emit_bc(Bytecodes::_dload, index); break;
-    case T_OBJECT: emit_bc(Bytecodes::_aload, index); break;
-    default:
-      ShouldNotReachHere();
-    }
-  }
-  stack_push(bt);
-}
-
-void MethodHandleCompiler::emit_store(BasicType bt, int index) {
-  if (index <= 3) {
-    switch (bt) {
-    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
-    case T_INT:    emit_bc(Bytecodes::cast(Bytecodes::_istore_0 + index)); break;
-    case T_LONG:   emit_bc(Bytecodes::cast(Bytecodes::_lstore_0 + index)); break;
-    case T_FLOAT:  emit_bc(Bytecodes::cast(Bytecodes::_fstore_0 + index)); break;
-    case T_DOUBLE: emit_bc(Bytecodes::cast(Bytecodes::_dstore_0 + index)); break;
-    case T_OBJECT: emit_bc(Bytecodes::cast(Bytecodes::_astore_0 + index)); break;
-    default:
-      ShouldNotReachHere();
-    }
-  }
-  else {
-    switch (bt) {
-    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
-    case T_INT:    emit_bc(Bytecodes::_istore, index); break;
-    case T_LONG:   emit_bc(Bytecodes::_lstore, index); break;
-    case T_FLOAT:  emit_bc(Bytecodes::_fstore, index); break;
-    case T_DOUBLE: emit_bc(Bytecodes::_dstore, index); break;
-    case T_OBJECT: emit_bc(Bytecodes::_astore, index); break;
-    default:
-      ShouldNotReachHere();
-    }
-  }
-  stack_pop(bt);
-}
-
-
-void MethodHandleCompiler::emit_load_constant(ArgToken arg) {
-  BasicType bt = arg.basic_type();
-  if (is_subword_type(bt)) bt = T_INT;
-  switch (bt) {
-  case T_INT: {
-    jint value = arg.get_jint();
-    if (-1 <= value && value <= 5)
-      emit_bc(Bytecodes::cast(Bytecodes::_iconst_0 + value));
-    else
-      emit_bc(Bytecodes::_ldc, cpool_int_put(value));
-    break;
-  }
-  case T_LONG: {
-    jlong value = arg.get_jlong();
-    if (0 <= value && value <= 1)
-      emit_bc(Bytecodes::cast(Bytecodes::_lconst_0 + (int) value));
-    else
-      emit_bc(Bytecodes::_ldc2_w, cpool_long_put(value));
-    break;
-  }
-  case T_FLOAT: {
-    jfloat value  = arg.get_jfloat();
-    if (value == 0.0 || value == 1.0 || value == 2.0)
-      emit_bc(Bytecodes::cast(Bytecodes::_fconst_0 + (int) value));
-    else
-      emit_bc(Bytecodes::_ldc, cpool_float_put(value));
-    break;
-  }
-  case T_DOUBLE: {
-    jdouble value = arg.get_jdouble();
-    if (value == 0.0 || value == 1.0)
-      emit_bc(Bytecodes::cast(Bytecodes::_dconst_0 + (int) value));
-    else
-      emit_bc(Bytecodes::_ldc2_w, cpool_double_put(value));
-    break;
-  }
-  case T_OBJECT: {
-    Handle value = arg.object();
-    if (value.is_null()) {
-      emit_bc(Bytecodes::_aconst_null);
-      break;
-    }
-    if (java_lang_Class::is_instance(value())) {
-      klassOop k = java_lang_Class::as_klassOop(value());
-      if (k != NULL) {
-        emit_bc(Bytecodes::_ldc, cpool_klass_put(k));
-        break;
-      }
-    }
-    emit_bc(Bytecodes::_ldc, cpool_object_put(value));
-    break;
-  }
-  default:
-    ShouldNotReachHere();
-  }
-  stack_push(bt);
-}
-
-
-MethodHandleWalker::ArgToken
-MethodHandleCompiler::make_conversion(BasicType type, klassOop tk, Bytecodes::Code op,
-                                      const ArgToken& src, TRAPS) {
-
-  BasicType srctype = src.basic_type();
-  TokenType tt = src.token_type();
-  int index = -1;
-
-  switch (op) {
-  case Bytecodes::_i2l:
-  case Bytecodes::_i2f:
-  case Bytecodes::_i2d:
-  case Bytecodes::_i2b:
-  case Bytecodes::_i2c:
-  case Bytecodes::_i2s:
-
-  case Bytecodes::_l2i:
-  case Bytecodes::_l2f:
-  case Bytecodes::_l2d:
-
-  case Bytecodes::_f2i:
-  case Bytecodes::_f2l:
-  case Bytecodes::_f2d:
-
-  case Bytecodes::_d2i:
-  case Bytecodes::_d2l:
-  case Bytecodes::_d2f:
-    if (tt == tt_constant) {
-      emit_load_constant(src);
-    } else {
-      emit_load(srctype, src.index());
-    }
-    stack_pop(srctype);  // pop the src type
-    emit_bc(op);
-    stack_push(type);    // push the dest value
-    if (tt != tt_constant)
-      index = src.index();
-    if (srctype != type || index == -1)
-      index = new_local_index(type);
-    emit_store(type, index);
-    break;
-
-  case Bytecodes::_checkcast:
-    if (tt == tt_constant) {
-      emit_load_constant(src);
-    } else {
-      emit_load(srctype, src.index());
-      index = src.index();
-    }
-    emit_bc(op, cpool_klass_put(tk));
-    check_non_bcp_klass(tk, CHECK_(src));
-    // Allocate a new local for the type so that we don't hide the
-    // previous type from the verifier.
-    index = new_local_index(type);
-    emit_store(srctype, index);
-    break;
-
-  case Bytecodes::_nop:
-    // nothing to do
-    return src;
-
-  default:
-    if (op == Bytecodes::_illegal)
-      lose(err_msg("no such primitive conversion: %s -> %s", type2name(src.basic_type()), type2name(type)), THREAD);
-    else
-      lose(err_msg("bad primitive conversion op: %s", Bytecodes::name(op)), THREAD);
-    return make_prim_constant(type, &zero_jvalue, THREAD);
-  }
-
-  return make_parameter(type, tk, index, THREAD);
-}
-
-
-// -----------------------------------------------------------------------------
-// MethodHandleCompiler
-//
-
-// Values used by the compiler.
-jvalue MethodHandleCompiler::zero_jvalue = { 0 };
-jvalue MethodHandleCompiler::one_jvalue  = { 1 };
-
-// Fetch any values from CountingMethodHandles and capture them for profiles
-bool MethodHandleCompiler::fetch_counts(ArgToken arg1, ArgToken arg2) {
-  int count1 = -1, count2 = -1;
-  if (arg1.token_type() == tt_constant && arg1.basic_type() == T_OBJECT &&
-      java_lang_invoke_CountingMethodHandle::is_instance(arg1.object()())) {
-    count1 = java_lang_invoke_CountingMethodHandle::vmcount(arg1.object()());
-  }
-  if (arg2.token_type() == tt_constant && arg2.basic_type() == T_OBJECT &&
-      java_lang_invoke_CountingMethodHandle::is_instance(arg2.object()())) {
-    count2 = java_lang_invoke_CountingMethodHandle::vmcount(arg2.object()());
-  }
-  int total = count1 + count2;
-  if (count1 != -1 && count2 != -1 && total != 0) {
-    // Normalize the collect counts to the invoke_count
-    if (count1 != 0) _not_taken_count = (int)(_invoke_count * count1 / (double)total);
-    if (count2 != 0) _taken_count = (int)(_invoke_count * count2 / (double)total);
-    return true;
-  }
-  return false;
-}
-
-// Emit bytecodes for the given invoke instruction.
-MethodHandleWalker::ArgToken
-MethodHandleCompiler::make_invoke(methodHandle m, vmIntrinsics::ID iid,
-                                  Bytecodes::Code op, bool tailcall,
-                                  int argc, MethodHandleWalker::ArgToken* argv,
-                                  TRAPS) {
-  ArgToken zero;
-  if (m.is_null()) {
-    // Get the intrinsic methodOop.
-    m = methodHandle(THREAD, vmIntrinsics::method_for(iid));
-    if (m.is_null()) {
-      lose(vmIntrinsics::name_at(iid), CHECK_(zero));
-    }
-  }
-
-  klassOop klass     = m->method_holder();
-  Symbol*  name      = m->name();
-  Symbol*  signature = m->signature();
-
-  if (iid == vmIntrinsics::_invokeGeneric &&
-      argc >= 1 && argv[0].token_type() == tt_constant) {
-    assert(m->intrinsic_id() == vmIntrinsics::_invokeExact, "");
-    Handle receiver = argv[0].object();
-    Handle rtype(THREAD, java_lang_invoke_MethodHandle::type(receiver()));
-    Handle mtype(THREAD, m->method_handle_type());
-    if (rtype() != mtype()) {
-      assert(java_lang_invoke_MethodType::form(rtype()) ==
-             java_lang_invoke_MethodType::form(mtype()),
-             "must be the same shape");
-      // customize m to the exact required rtype
-      bool has_non_bcp_klass = check_non_bcp_klasses(rtype(), CHECK_(zero));
-      TempNewSymbol sig2 = java_lang_invoke_MethodType::as_signature(rtype(), true, CHECK_(zero));
-      methodHandle m2;
-      if (!has_non_bcp_klass) {
-        methodOop m2_oop = SystemDictionary::find_method_handle_invoke(m->name(), sig2,
-                                                                       KlassHandle(), CHECK_(zero));
-        m2 = methodHandle(THREAD, m2_oop);
-      }
-      if (m2.is_null()) {
-        // just build it fresh
-        m2 = methodOopDesc::make_invoke_method(klass, m->name(), sig2, rtype, CHECK_(zero));
-        if (m2.is_null())
-          lose(err_msg("no customized invoker %s", sig2->as_utf8()), CHECK_(zero));
-      }
-      m = m2;
-      signature = m->signature();
-    }
-  }
-
-  if (m->intrinsic_id() == vmIntrinsics::_selectAlternative &&
-      fetch_counts(argv[1], argv[2])) {
-    assert(argc == 3, "three arguments");
-    assert(tailcall, "only");
-
-    // do inline bytecodes so we can drop profile data into it,
-    //   0:   iload_0
-    emit_load(argv[0]);
-    //   1:   ifeq    8
-    _selectAlternative_bci = _bytecode.length();
-    emit_bc(Bytecodes::_ifeq, 0); // emit placeholder offset
-    //   4:   aload_1
-    emit_load(argv[1]);
-    //   5:   areturn;
-    emit_bc(Bytecodes::_areturn);
-    //   8:   aload_2
-    update_branch_dest(_selectAlternative_bci, cur_bci());
-    emit_load(argv[2]);
-    //   9:   areturn
-    emit_bc(Bytecodes::_areturn);
-    return ArgToken();  // Dummy return value.
-  }
-
-  check_non_bcp_klass(klass, CHECK_(zero));
-  if (m->is_method_handle_invoke()) {
-    check_non_bcp_klasses(m->method_handle_type(), CHECK_(zero));
-  }
-
-  // Count the number of arguments, not the size
-  ArgumentCount asc(signature);
-  assert(argc == asc.size() + ((op == Bytecodes::_invokestatic || op == Bytecodes::_invokedynamic) ? 0 : 1),
-         "argc mismatch");
-
-  for (int i = 0; i < argc; i++) {
-    ArgToken arg = argv[i];
-    TokenType tt = arg.token_type();
-    BasicType bt = arg.basic_type();
-
-    switch (tt) {
-    case tt_parameter:
-    case tt_temporary:
-      emit_load(bt, arg.index());
-      break;
-    case tt_constant:
-      emit_load_constant(arg);
-      break;
-    case tt_illegal:
-      // Sentinel.
-      assert(i == (argc - 1), "sentinel must be last entry");
-      break;
-    case tt_void:
-    default:
-      ShouldNotReachHere();
-    }
-  }
-
-  // Populate constant pool.
-  int name_index          = cpool_symbol_put(name);
-  int signature_index     = cpool_symbol_put(signature);
-  int name_and_type_index = cpool_name_and_type_put(name_index, signature_index);
-  int klass_index         = cpool_klass_put(klass);
-  int methodref_index     = cpool_methodref_put(op, klass_index, name_and_type_index, m);
-
-  // Generate invoke.
-  switch (op) {
-  case Bytecodes::_invokestatic:
-  case Bytecodes::_invokespecial:
-  case Bytecodes::_invokevirtual:
-    emit_bc(op, methodref_index);
-    break;
-
-  case Bytecodes::_invokeinterface: {
-    ArgumentSizeComputer asc(signature);
-    emit_bc(op, methodref_index, asc.size() + 1);
-    break;
-  }
-
-  default:
-    ShouldNotReachHere();
-  }
-
-  // If tailcall, we have walked all the way to a direct method handle.
-  // Otherwise, make a recursive call to some helper routine.
-  BasicType rbt = m->result_type();
-  if (rbt == T_ARRAY)  rbt = T_OBJECT;
-  stack_push(rbt);  // The return value is already pushed onto the stack.
-  ArgToken ret;
-  if (tailcall) {
-    if (return_conv() == zero_return_conv()) {
-      rbt = T_VOID;  // discard value
-    } else if (return_conv() != vmIntrinsics::_none) {
-      // return value conversion
-      int index = new_local_index(rbt);
-      emit_store(rbt, index);
-      ArgToken arglist[2];
-      arglist[0] = ArgToken(tt_temporary, rbt, index);
-      arglist[1] = ArgToken();  // sentinel
-      ret = make_invoke(methodHandle(), return_conv(), Bytecodes::_invokestatic, false, 1, &arglist[0], CHECK_(zero));
-      set_return_conv(vmIntrinsics::_none);
-      rbt = ret.basic_type();
-      emit_load(rbt, ret.index());
-    }
-    if (rbt != _rtype) {
-      if (rbt == T_VOID) {
-        // push a zero of the right sort
-        if (_rtype == T_OBJECT) {
-          zero = make_oop_constant(NULL, CHECK_(zero));
-        } else {
-          zero = make_prim_constant(_rtype, &zero_jvalue, CHECK_(zero));
-        }
-        emit_load_constant(zero);
-      } else if (_rtype == T_VOID) {
-        // We'll emit a _return with something on the stack.
-        // It's OK to ignore what's on the stack.
-      } else if (rbt == T_INT && is_subword_type(_rtype)) {
-        // Convert value to match return type.
-        switch (_rtype) {
-        case T_BOOLEAN: {
-          // boolean is treated as a one-bit unsigned integer.
-          // Cf. API documentation: java/lang/invoke/MethodHandles.html#explicitCastArguments
-          ArgToken one = make_prim_constant(T_INT, &one_jvalue, CHECK_(zero));
-          emit_load_constant(one);
-          emit_bc(Bytecodes::_iand);
-          break;
-        }
-        case T_BYTE:    emit_bc(Bytecodes::_i2b); break;
-        case T_CHAR:    emit_bc(Bytecodes::_i2c); break;
-        case T_SHORT:   emit_bc(Bytecodes::_i2s); break;
-        default: ShouldNotReachHere();
-        }
-      } else if (is_subword_type(rbt) && (is_subword_type(_rtype) || (_rtype == T_INT))) {
-        // The subword type was returned as an int and will be passed
-        // on as an int.
-      } else {
-        lose("unknown conversion", CHECK_(zero));
-      }
-    }
-    switch (_rtype) {
-    case T_BOOLEAN: case T_BYTE: case T_CHAR: case T_SHORT:
-    case T_INT:    emit_bc(Bytecodes::_ireturn); break;
-    case T_LONG:   emit_bc(Bytecodes::_lreturn); break;
-    case T_FLOAT:  emit_bc(Bytecodes::_freturn); break;
-    case T_DOUBLE: emit_bc(Bytecodes::_dreturn); break;
-    case T_VOID:   emit_bc(Bytecodes::_return);  break;
-    case T_OBJECT:
-      if (_rklass.not_null() && _rklass() != SystemDictionary::Object_klass() && !Klass::cast(_rklass())->is_interface()) {
-        emit_bc(Bytecodes::_checkcast, cpool_klass_put(_rklass()));
-        check_non_bcp_klass(_rklass(), CHECK_(zero));
-      }
-      emit_bc(Bytecodes::_areturn);
-      break;
-    default: ShouldNotReachHere();
-    }
-    ret = ArgToken();  // Dummy return value.
-  }
-  else {
-    int index = new_local_index(rbt);
-    switch (rbt) {
-    case T_BOOLEAN: case T_BYTE: case T_CHAR:  case T_SHORT:
-    case T_INT:     case T_LONG: case T_FLOAT: case T_DOUBLE:
-    case T_OBJECT:
-      emit_store(rbt, index);
-      ret = ArgToken(tt_temporary, rbt, index);
-      break;
-    case T_VOID:
-      ret = ArgToken(tt_void);
-      break;
-    default:
-      ShouldNotReachHere();
-    }
-  }
-
-  return ret;
-}
-
-MethodHandleWalker::ArgToken
-MethodHandleCompiler::make_fetch(BasicType type, klassOop tk, Bytecodes::Code op,
-                                 const MethodHandleWalker::ArgToken& base,
-                                 const MethodHandleWalker::ArgToken& offset,
-                                 TRAPS) {
-  switch (base.token_type()) {
-    case tt_parameter:
-    case tt_temporary:
-      emit_load(base.basic_type(), base.index());
-      break;
-    case tt_constant:
-      emit_load_constant(base);
-      break;
-    default:
-      ShouldNotReachHere();
-  }
-  switch (offset.token_type()) {
-    case tt_parameter:
-    case tt_temporary:
-      emit_load(offset.basic_type(), offset.index());
-      break;
-    case tt_constant:
-      emit_load_constant(offset);
-      break;
-    default:
-      ShouldNotReachHere();
-  }
-  emit_bc(op);
-  int index = new_local_index(type);
-  emit_store(type, index);
-  return ArgToken(tt_temporary, type, index);
-}
-
-
-int MethodHandleCompiler::cpool_primitive_put(BasicType bt, jvalue* con) {
-  jvalue con_copy;
-  assert(bt < T_OBJECT, "");
-  if (type2aelembytes(bt) < jintSize) {
-    // widen to int
-    con_copy = (*con);
-    con = &con_copy;
-    switch (bt) {
-    case T_BOOLEAN: con->i = (con->z ? 1 : 0); break;
-    case T_BYTE:    con->i = con->b;           break;
-    case T_CHAR:    con->i = con->c;           break;
-    case T_SHORT:   con->i = con->s;           break;
-    default: ShouldNotReachHere();
-    }
-    bt = T_INT;
-  }
-
-//   for (int i = 1, imax = _constants.length(); i < imax; i++) {
-//     ConstantValue* con = _constants.at(i);
-//     if (con != NULL && con->is_primitive() && con.basic_type() == bt) {
-//       bool match = false;
-//       switch (type2size[bt]) {
-//       case 1:  if (pcon->_value.i == con->i)  match = true;  break;
-//       case 2:  if (pcon->_value.j == con->j)  match = true;  break;
-//       }
-//       if (match)
-//         return i;
-//     }
-//   }
-  ConstantValue* cv = new ConstantValue(bt, *con);
-  int index = _constants.append(cv);
-
-  // long and double entries take 2 slots, we add another empty entry.
-  if (type2size[bt] == 2)
-    (void) _constants.append(NULL);
-
-  return index;
-}
-
-bool MethodHandleCompiler::check_non_bcp_klasses(Handle method_type, TRAPS) {
-  bool res = false;
-  for (int i = -1, len = java_lang_invoke_MethodType::ptype_count(method_type()); i < len; i++) {
-    oop ptype = (i == -1
-                 ? java_lang_invoke_MethodType::rtype(method_type())
-                 : java_lang_invoke_MethodType::ptype(method_type(), i));
-    res |= check_non_bcp_klass(java_lang_Class::as_klassOop(ptype), CHECK_(false));
-  }
-  return res;
-}
-
-bool MethodHandleCompiler::check_non_bcp_klass(klassOop klass, TRAPS) {
-  klass = methodOopDesc::check_non_bcp_klass(klass);
-  if (klass != NULL) {
-    Symbol* name = Klass::cast(klass)->name();
-    for (int i = _non_bcp_klasses.length() - 1; i >= 0; i--) {
-      klassOop k2 = _non_bcp_klasses.at(i)();
-      if (Klass::cast(k2)->name() == name) {
-        if (k2 != klass) {
-          lose(err_msg("unsupported klass name alias %s", name->as_utf8()), THREAD);
-        }
-        return true;
-      }
-    }
-    _non_bcp_klasses.append(KlassHandle(THREAD, klass));
-    return true;
-  }
-  return false;
-}
-
-void MethodHandleCompiler::record_non_bcp_klasses() {
-  // Append extra klasses to constant pool, to guide klass lookup.
-  for (int k = 0; k < _non_bcp_klasses.length(); k++) {
-    klassOop non_bcp_klass = _non_bcp_klasses.at(k)();
-    bool add_to_cp = true;
-    for (int j = 1; j < _constants.length(); j++) {
-      ConstantValue* cv = _constants.at(j);
-      if (cv != NULL && cv->tag() == JVM_CONSTANT_Class
-          && cv->klass_oop() == non_bcp_klass) {
-        add_to_cp = false;
-        break;
-      }
-    }
-    if (add_to_cp)  cpool_klass_put(non_bcp_klass);
-  }
-}
-
-constantPoolHandle MethodHandleCompiler::get_constant_pool(TRAPS) const {
-  constantPoolHandle nullHandle;
-  constantPoolOop cpool_oop = oopFactory::new_constantPool(_constants.length(),
-                                                           oopDesc::IsSafeConc,
-                                                           CHECK_(nullHandle));
-  constantPoolHandle cpool(THREAD, cpool_oop);
-
-  // Fill the real constant pool skipping the zero element.
-  for (int i = 1; i < _constants.length(); i++) {
-    ConstantValue* cv = _constants.at(i);
-    switch (cv->tag()) {
-    case JVM_CONSTANT_Utf8:        cpool->symbol_at_put(       i, cv->symbol()                         ); break;
-    case JVM_CONSTANT_Integer:     cpool->int_at_put(          i, cv->get_jint()                       ); break;
-    case JVM_CONSTANT_Float:       cpool->float_at_put(        i, cv->get_jfloat()                     ); break;
-    case JVM_CONSTANT_Long:        cpool->long_at_put(         i, cv->get_jlong()                      ); break;
-    case JVM_CONSTANT_Double:      cpool->double_at_put(       i, cv->get_jdouble()                    ); break;
-    case JVM_CONSTANT_Class:       cpool->klass_at_put(        i, cv->klass_oop()                      ); break;
-    case JVM_CONSTANT_Methodref:   cpool->method_at_put(       i, cv->first_index(), cv->second_index()); break;
-    case JVM_CONSTANT_InterfaceMethodref:
-                                cpool->interface_method_at_put(i, cv->first_index(), cv->second_index()); break;
-    case JVM_CONSTANT_NameAndType: cpool->name_and_type_at_put(i, cv->first_index(), cv->second_index()); break;
-    case JVM_CONSTANT_Object:      cpool->object_at_put(       i, cv->object_oop()                     ); break;
-    default: ShouldNotReachHere();
-    }
-
-    switch (cv->tag()) {
-    case JVM_CONSTANT_Long:
-    case JVM_CONSTANT_Double:
-      i++;  // Skip empty entry.
-      assert(_constants.at(i) == NULL, "empty entry");
-      break;
-    }
-  }
-
-  cpool->set_preresolution();
-
-  // Set the constant pool holder to the target method's class.
-  cpool->set_pool_holder(_target_klass());
-
-  return cpool;
-}
-
-
-methodHandle MethodHandleCompiler::get_method_oop(TRAPS) {
-  methodHandle empty;
-  // Create a method that holds the generated bytecode.  invokedynamic
-  // has no receiver, normal MH calls do.
-  int flags_bits;
-  if (for_invokedynamic())
-    flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SYNTHETIC | JVM_ACC_STATIC);
-  else
-    flags_bits = (/*JVM_MH_INVOKE_BITS |*/ JVM_ACC_PUBLIC | JVM_ACC_FINAL | JVM_ACC_SYNTHETIC);
-
-  // Create a new method
-  methodHandle m;
-  {
-    methodOop m_oop = oopFactory::new_method(bytecode_length(),
-                                             accessFlags_from(flags_bits),
-                                             0, 0, 0, oopDesc::IsSafeConc, CHECK_(empty));
-    m = methodHandle(THREAD, m_oop);
-  }
-
-  constantPoolHandle cpool = get_constant_pool(CHECK_(empty));
-  m->set_constants(cpool());
-
-  m->set_name_index(_name_index);
-  m->set_signature_index(_signature_index);
-
-  m->set_code((address) bytecode());
-
-  m->set_max_stack(_max_stack);
-  m->set_max_locals(max_locals());
-  m->set_size_of_parameters(_num_params);
-
-  typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
-  m->set_exception_table(exception_handlers());
-
-  // Rewrite the method and set up the constant pool cache.
-  objArrayOop m_array = oopFactory::new_system_objArray(1, CHECK_(empty));
-  objArrayHandle methods(THREAD, m_array);
-  methods->obj_at_put(0, m());
-  Rewriter::rewrite(_target_klass(), cpool, methods, CHECK_(empty));  // Use fake class.
-  Rewriter::relocate_and_link(_target_klass(), methods, CHECK_(empty));  // Use fake class.
-
-  // Pre-resolve selected CP cache entries, to avoid problems with class loader scoping.
-  constantPoolCacheHandle cpc(THREAD, cpool->cache());
-  for (int i = 0; i < cpc->length(); i++) {
-    ConstantPoolCacheEntry* e = cpc->entry_at(i);
-    assert(!e->is_secondary_entry(), "no indy instructions in here, yet");
-    int constant_pool_index = e->constant_pool_index();
-    ConstantValue* cv = _constants.at(constant_pool_index);
-    if (!cv->has_linkage())  continue;
-    methodHandle m = cv->linkage();
-    int index;
-    switch (cv->tag()) {
-    case JVM_CONSTANT_Methodref:
-      index = m->vtable_index();
-      if (m->is_static()) {
-        e->set_method(Bytecodes::_invokestatic, m, index);
-      } else {
-        e->set_method(Bytecodes::_invokespecial, m, index);
-        e->set_method(Bytecodes::_invokevirtual, m, index);
-      }
-      break;
-    case JVM_CONSTANT_InterfaceMethodref:
-      index = klassItable::compute_itable_index(m());
-      e->set_interface_call(m, index);
-      break;
-    }
-  }
-
-  // Set the invocation counter's count to the invoke count of the
-  // original call site.
-  InvocationCounter* ic = m->invocation_counter();
-  ic->set(InvocationCounter::wait_for_compile, _invoke_count);
-
-  // Create a new MDO
-  {
-    methodDataOop mdo = oopFactory::new_methodData(m, CHECK_(empty));
-    assert(m->method_data() == NULL, "there should not be an MDO yet");
-    m->set_method_data(mdo);
-
-    bool found_selectAlternative = false;
-    // Iterate over all profile data and set the count of the counter
-    // data entries to the original call site counter.
-    for (ProfileData* profile_data = mdo->first_data();
-         mdo->is_valid(profile_data);
-         profile_data = mdo->next_data(profile_data)) {
-      if (profile_data->is_CounterData()) {
-        CounterData* counter_data = profile_data->as_CounterData();
-        counter_data->set_count(_invoke_count);
-      }
-      if (profile_data->is_BranchData() &&
-          profile_data->bci() == _selectAlternative_bci) {
-        BranchData* bd = profile_data->as_BranchData();
-        bd->set_taken(_taken_count);
-        bd->set_not_taken(_not_taken_count);
-        found_selectAlternative = true;
-      }
-    }
-    assert(_selectAlternative_bci == -1 || found_selectAlternative, "must have found profile entry");
-  }
-
-#ifndef PRODUCT
-  if (TraceMethodHandles) {
-    m->print();
-    m->print_codes();
-  }
-#endif //PRODUCT
-
-  assert(m->is_method_handle_adapter(), "must be recognized as an adapter");
-  return m;
-}
-
-
-#ifndef PRODUCT
-
-// MH printer for debugging.
-
-class MethodHandlePrinter : public MethodHandleWalker {
-private:
-  outputStream* _out;
-  bool          _verbose;
-  int           _temp_num;
-  int           _param_state;
-  stringStream  _strbuf;
-  const char* strbuf() {
-    const char* s = _strbuf.as_string();
-    _strbuf.reset();
-    return s;
-  }
-  ArgToken token(const char* str, BasicType type) {
-    return ArgToken(str, type);
-  }
-  const char* string(ArgToken token) {
-    return token.str();
-  }
-  void start_params() {
-    _param_state <<= 1;
-    _out->print("(");
-  }
-  void end_params() {
-    if (_verbose)  _out->print("\n");
-    _out->print(") => {");
-    _param_state >>= 1;
-  }
-  void put_type_name(BasicType type, klassOop tk, outputStream* s) {
-    const char* kname = NULL;
-    if (tk != NULL)
-      kname = Klass::cast(tk)->external_name();
-    s->print("%s", (kname != NULL) ? kname : type2name(type));
-  }
-  ArgToken maybe_make_temp(const char* statement_op, BasicType type, const char* temp_name) {
-    const char* value = strbuf();
-    if (!_verbose)  return token(value, type);
-    // make an explicit binding for each separate value
-    _strbuf.print("%s%d", temp_name, ++_temp_num);
-    const char* temp = strbuf();
-    _out->print("\n  %s %s %s = %s;", statement_op, type2name(type), temp, value);
-    return token(temp, type);
-  }
-
-public:
-  MethodHandlePrinter(Handle root, bool verbose, outputStream* out, TRAPS)
-    : MethodHandleWalker(root, false, THREAD),
-      _out(out),
-      _verbose(verbose),
-      _param_state(0),
-      _temp_num(0)
-  {
-    out->print("MethodHandle:");
-    java_lang_invoke_MethodType::print_signature(java_lang_invoke_MethodHandle::type(root()), out);
-    out->print(" : #");
-    start_params();
-  }
-  virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) {
-    if (argnum < 0) {
-      end_params();
-      return token("return", type);
-    }
-    if ((_param_state & 1) == 0) {
-      _param_state |= 1;
-      _out->print(_verbose ? "\n  " : "");
-    } else {
-      _out->print(_verbose ? ",\n  " : ", ");
-    }
-    if (argnum >= _temp_num)
-      _temp_num = argnum;
-    // generate an argument name
-    _strbuf.print("a%d", argnum);
-    const char* arg = strbuf();
-    put_type_name(type, tk, _out);
-    _out->print(" %s", arg);
-    return token(arg, type);
-  }
-  virtual ArgToken make_oop_constant(oop con, TRAPS) {
-    if (con == NULL)
-      _strbuf.print("null");
-    else
-      con->print_value_on(&_strbuf);
-    if (_strbuf.size() == 0) {  // yuck
-      _strbuf.print("(a ");
-      put_type_name(T_OBJECT, con->klass(), &_strbuf);
-      _strbuf.print(")");
-    }
-    return maybe_make_temp("constant", T_OBJECT, "k");
-  }
-  virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) {
-    java_lang_boxing_object::print(type, con, &_strbuf);
-    return maybe_make_temp("constant", type, "k");
-  }
-  void print_bytecode_name(Bytecodes::Code op) {
-    if (Bytecodes::is_defined(op))
-      _strbuf.print("%s", Bytecodes::name(op));
-    else
-      _strbuf.print("bytecode_%d", (int) op);
-  }
-  virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS) {
-    print_bytecode_name(op);
-    _strbuf.print("(%s", string(src));
-    if (tk != NULL) {
-      _strbuf.print(", ");
-      put_type_name(type, tk, &_strbuf);
-    }
-    _strbuf.print(")");
-    return maybe_make_temp("convert", type, "v");
-  }
-  virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS) {
-    _strbuf.print("%s(%s, %s", Bytecodes::name(op), string(base), string(offset));
-    if (tk != NULL) {
-      _strbuf.print(", ");
-      put_type_name(type, tk, &_strbuf);
-    }
-    _strbuf.print(")");
-    return maybe_make_temp("fetch", type, "x");
-  }
-  virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid,
-                               Bytecodes::Code op, bool tailcall,
-                               int argc, ArgToken* argv, TRAPS) {
-    Symbol* name;
-    Symbol* sig;
-    if (m.not_null()) {
-      name = m->name();
-      sig  = m->signature();
-    } else {
-      name = vmSymbols::symbol_at(vmIntrinsics::name_for(iid));
-      sig  = vmSymbols::symbol_at(vmIntrinsics::signature_for(iid));
-    }
-    _strbuf.print("%s %s%s(", Bytecodes::name(op), name->as_C_string(), sig->as_C_string());
-    for (int i = 0; i < argc; i++) {
-      _strbuf.print("%s%s", (i > 0 ? ", " : ""), string(argv[i]));
-    }
-    _strbuf.print(")");
-    if (!tailcall) {
-      BasicType rt = char2type(sig->byte_at(sig->utf8_length()-1));
-      if (rt == T_ILLEGAL)  rt = T_OBJECT;  // ';' at the end of '(...)L...;'
-      return maybe_make_temp("invoke", rt, "x");
-    } else {
-      const char* ret = strbuf();
-      _out->print(_verbose ? "\n  return " : " ");
-      _out->print("%s", ret);
-      _out->print(_verbose ? "\n}\n" : " }");
-    }
-    return ArgToken();
-  }
-
-  virtual void set_method_handle(oop mh) {
-    if (WizardMode && Verbose) {
-      tty->print("\n--- next target: ");
-      mh->print();
-    }
-  }
-
-  static void print(Handle root, bool verbose, outputStream* out, TRAPS) {
-    ResourceMark rm;
-    MethodHandlePrinter printer(root, verbose, out, CHECK);
-    printer.walk(CHECK);
-    out->print("\n");
-  }
-  static void print(Handle root, bool verbose = Verbose, outputStream* out = tty) {
-    Thread* THREAD = Thread::current();
-    ResourceMark rm;
-    MethodHandlePrinter printer(root, verbose, out, THREAD);
-    if (!HAS_PENDING_EXCEPTION)
-      printer.walk(THREAD);
-    if (HAS_PENDING_EXCEPTION) {
-      oop ex = PENDING_EXCEPTION;
-      CLEAR_PENDING_EXCEPTION;
-      out->print(" *** ");
-      if (printer.lose_message() != NULL)  out->print("%s ", printer.lose_message());
-      out->print("}");
-    }
-    out->print("\n");
-  }
-};
-
-extern "C"
-void print_method_handle(oop mh) {
-  if (!mh->is_oop()) {
-    tty->print_cr("*** not a method handle: "PTR_FORMAT, (intptr_t)mh);
-  } else if (java_lang_invoke_MethodHandle::is_instance(mh)) {
-    MethodHandlePrinter::print(mh);
-  } else {
-    tty->print("*** not a method handle: ");
-    mh->print();
-  }
-}
-
-#endif // PRODUCT
diff --git a/hotspot/src/share/vm/prims/methodHandleWalk.hpp b/hotspot/src/share/vm/prims/methodHandleWalk.hpp
deleted file mode 100644
index 8697c0b..0000000
--- a/hotspot/src/share/vm/prims/methodHandleWalk.hpp
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * 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.
- *
- */
-
-#ifndef SHARE_VM_PRIMS_METHODHANDLEWALK_HPP
-#define SHARE_VM_PRIMS_METHODHANDLEWALK_HPP
-
-#include "prims/methodHandles.hpp"
-
-// Low-level parser for method handle chains.
-class MethodHandleChain : StackObj {
-public:
-  typedef MethodHandles::EntryKind EntryKind;
-
-private:
-  Handle        _root;          // original target
-  Handle        _method_handle; // current target
-  bool          _is_last;       // final guy in chain
-  bool          _is_bound;      // has a bound argument
-  BasicType     _arg_type;      // if is_bound, the bound argument type
-  int           _arg_slot;      // if is_bound or is_adapter, affected argument slot
-  jint          _conversion;    // conversion field of AMH or -1
-  methodHandle  _last_method;   // if is_last, which method we target
-  Bytecodes::Code _last_invoke; // if is_last, type of invoke
-  const char*   _lose_message;  // saved argument to lose()
-
-  void set_method_handle(Handle target, TRAPS);
-  void set_last_method(oop target, TRAPS);
-  static BasicType compute_bound_arg_type(oop target, methodOop m, int arg_slot, TRAPS);
-
-  oop MethodHandle_type_oop()          { return java_lang_invoke_MethodHandle::type(method_handle_oop()); }
-  oop MethodHandle_vmtarget_oop()      { return java_lang_invoke_MethodHandle::vmtarget(method_handle_oop()); }
-  int MethodHandle_vmslots()           { return java_lang_invoke_MethodHandle::vmslots(method_handle_oop()); }
-  int DirectMethodHandle_vmindex()     { return java_lang_invoke_DirectMethodHandle::vmindex(method_handle_oop()); }
-  oop BoundMethodHandle_argument_oop() { return java_lang_invoke_BoundMethodHandle::argument(method_handle_oop()); }
-  int BoundMethodHandle_vmargslot()    { return java_lang_invoke_BoundMethodHandle::vmargslot(method_handle_oop()); }
-  int AdapterMethodHandle_conversion() { return java_lang_invoke_AdapterMethodHandle::conversion(method_handle_oop()); }
-
-#ifdef ASSERT
-  void print_impl(TRAPS);
-#endif
-
-public:
-  MethodHandleChain(Handle root, TRAPS)
-    : _root(root)
-  { set_method_handle(root, THREAD); }
-
-  bool is_adapter()             { return _conversion != -1; }
-  bool is_bound()               { return _is_bound; }
-  bool is_last()                { return _is_last; }
-
-  void next(TRAPS) {
-    assert(!is_last(), "");
-    set_method_handle(MethodHandle_vmtarget_oop(), THREAD);
-  }
-
-  Handle root()                 { return _root; }
-  Handle method_handle()        { return _method_handle; }
-  oop    method_handle_oop()    { return _method_handle(); }
-  oop    method_type_oop()      { return MethodHandle_type_oop(); }
-  oop    vmtarget_oop()         { return MethodHandle_vmtarget_oop(); }
-
-  jint adapter_conversion()     { assert(is_adapter(), ""); return _conversion; }
-  int  adapter_conversion_op()  { return MethodHandles::adapter_conversion_op(adapter_conversion()); }
-  BasicType adapter_conversion_src_type()
-                                { return MethodHandles::adapter_conversion_src_type(adapter_conversion()); }
-  BasicType adapter_conversion_dest_type()
-                                { return MethodHandles::adapter_conversion_dest_type(adapter_conversion()); }
-  int  adapter_conversion_stack_move()
-                                { return MethodHandles::adapter_conversion_stack_move(adapter_conversion()); }
-  int  adapter_conversion_stack_pushes()
-                                { return adapter_conversion_stack_move() / MethodHandles::stack_move_unit(); }
-  int  adapter_conversion_vminfo()
-                                { return MethodHandles::adapter_conversion_vminfo(adapter_conversion()); }
-  int adapter_arg_slot()        { assert(is_adapter(), ""); return _arg_slot; }
-  oop adapter_arg_oop()         { assert(is_adapter(), ""); return BoundMethodHandle_argument_oop(); }
-
-  BasicType bound_arg_type()    { assert(is_bound(), ""); return _arg_type; }
-  int       bound_arg_slot()    { assert(is_bound(), ""); return _arg_slot; }
-  oop       bound_arg_oop()     { assert(is_bound(), ""); return BoundMethodHandle_argument_oop(); }
-
-  methodHandle last_method()    { assert(is_last(), ""); return _last_method; }
-  methodOop last_method_oop()   { assert(is_last(), ""); return _last_method(); }
-  Bytecodes::Code last_invoke_code() { assert(is_last(), ""); return _last_invoke; }
-
-  void lose(const char* msg, TRAPS);
-  const char* lose_message()    { return _lose_message; }
-
-#ifdef ASSERT
-  // Print a symbolic description of a method handle chain, including
-  // the signature for each method.  The signatures are printed in
-  // slot order to make it easier to understand.
-  void print();
-  static void print(oopDesc* mh);
-#endif
-};
-
-
-// Structure walker for method handles.
-// Does abstract interpretation on top of low-level parsing.
-// You supply the tokens shuffled by the abstract interpretation.
-class MethodHandleWalker : StackObj {
-public:
-  // Stack values:
-  enum TokenType {
-    tt_void,
-    tt_parameter,
-    tt_temporary,
-    tt_constant,
-    tt_symbolic,
-    tt_illegal
-  };
-
-  // Argument token:
-  class ArgToken {
-  private:
-    TokenType _tt;
-    BasicType _bt;
-    jvalue    _value;
-    Handle    _handle;
-
-  public:
-    ArgToken(TokenType tt = tt_illegal) : _tt(tt), _bt(tt == tt_void ? T_VOID : T_ILLEGAL) {
-      assert(tt == tt_illegal || tt == tt_void, "invalid token type");
-    }
-
-    ArgToken(TokenType tt, BasicType bt, int index) : _tt(tt), _bt(bt) {
-      assert(_tt == tt_parameter || _tt == tt_temporary, "must have index");
-      _value.i = index;
-    }
-
-    ArgToken(BasicType bt, jvalue value) : _tt(tt_constant), _bt(bt), _value(value) { assert(_bt != T_OBJECT, "wrong constructor"); }
-    ArgToken(Handle handle) : _tt(tt_constant), _bt(T_OBJECT), _handle(handle) {}
-
-
-    ArgToken(const char* str, BasicType type) : _tt(tt_symbolic), _bt(type) {
-      _value.j = (intptr_t)str;
-    }
-
-    TokenType token_type()  const { return _tt; }
-    BasicType basic_type()  const { return _bt; }
-    bool      has_index()   const { return _tt == tt_parameter || _tt == tt_temporary; }
-    int       index()       const { assert(has_index(), "must have index");; return _value.i; }
-    Handle    object()      const { assert(_bt == T_OBJECT, "wrong accessor"); assert(_tt == tt_constant, "value type"); return _handle; }
-    const char* str()       const { assert(_tt == tt_symbolic, "string type"); return (const char*)(intptr_t)_value.j; }
-
-    jint      get_jint()    const { assert(_bt == T_INT || is_subword_type(_bt), "wrong accessor"); assert(_tt == tt_constant, "value types"); return _value.i; }
-    jlong     get_jlong()   const { assert(_bt == T_LONG, "wrong accessor");   assert(_tt == tt_constant, "value types"); return _value.j; }
-    jfloat    get_jfloat()  const { assert(_bt == T_FLOAT, "wrong accessor");  assert(_tt == tt_constant, "value types"); return _value.f; }
-    jdouble   get_jdouble() const { assert(_bt == T_DOUBLE, "wrong accessor"); assert(_tt == tt_constant, "value types"); return _value.d; }
-  };
-
-private:
-  MethodHandleChain _chain;
-  bool              _for_invokedynamic;
-  int               _local_index;
-
-  // This array is kept in an unusual order, indexed by low-level "slot number".
-  // TOS is always _outgoing.at(0), so simple pushes and pops shift the whole _outgoing array.
-  // If there is a receiver in the current argument list, it is at _outgoing.at(_outgoing.length()-1).
-  // If a value at _outgoing.at(n) is T_LONG or T_DOUBLE, the value at _outgoing.at(n+1) is T_VOID.
-  GrowableArray<ArgToken>  _outgoing;       // current outgoing parameter slots
-  int                      _outgoing_argc;  // # non-empty outgoing slots
-
-  vmIntrinsics::ID _return_conv;            // Return conversion required by raw retypes.
-
-  // Replace a value of type old_type at slot (and maybe slot+1) with the new value.
-  // If old_type != T_VOID, remove the old argument at that point.
-  // If new_type != T_VOID, insert the new argument at that point.
-  // Insert or delete a second empty slot as needed.
-  void change_argument(BasicType old_type, int slot, const ArgToken& new_arg);
-  void change_argument(BasicType old_type, int slot, BasicType type, const ArgToken& new_arg) {
-    assert(type == new_arg.basic_type(), "must agree");
-    change_argument(old_type, slot, new_arg);
-  }
-
-  // Raw retype conversions for OP_RAW_RETYPE.
-  void retype_raw_conversion(BasicType src, BasicType dst, bool for_return, int slot, TRAPS);
-  void retype_raw_argument_type(BasicType src, BasicType dst, int slot, TRAPS) { retype_raw_conversion(src, dst, false, slot, CHECK); }
-  void retype_raw_return_type(  BasicType src, BasicType dst,           TRAPS) { retype_raw_conversion(src, dst, true,  -1,   CHECK); }
-
-  BasicType arg_type(int slot) {
-    return _outgoing.at(slot).basic_type();
-  }
-  bool has_argument(int slot) {
-    return arg_type(slot) < T_VOID;
-  }
-
-#ifdef ASSERT
-  int argument_count_slow();
-#endif
-
-  // Return a bytecode for converting src to dest, if one exists.
-  Bytecodes::Code conversion_code(BasicType src, BasicType dest);
-
-  void walk_incoming_state(TRAPS);
-
-  void verify_args_and_signature(TRAPS) NOT_DEBUG_RETURN;
-
-public:
-  MethodHandleWalker(Handle root, bool for_invokedynamic, TRAPS)
-    : _chain(root, THREAD),
-      _for_invokedynamic(for_invokedynamic),
-      _outgoing(THREAD, 10),
-      _outgoing_argc(0),
-      _return_conv(vmIntrinsics::_none)
-  {
-    _local_index = for_invokedynamic ? 0 : 1;
-  }
-
-  MethodHandleChain& chain() { return _chain; }
-
-  bool for_invokedynamic() const { return _for_invokedynamic; }
-
-  vmIntrinsics::ID return_conv() const { return _return_conv; }
-  void set_return_conv(vmIntrinsics::ID c) { _return_conv = c; }
-  static vmIntrinsics::ID zero_return_conv() { return vmIntrinsics::_min; }
-
-  int new_local_index(BasicType bt) {
-    //int index = _for_invokedynamic ? _local_index : _local_index - 1;
-    int index = _local_index;
-    _local_index += type2size[bt];
-    return index;
-  }
-
-  int max_locals() const { return _local_index; }
-
-  // plug-in abstract interpretation steps:
-  virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) = 0;
-  virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) = 0;
-  virtual ArgToken make_oop_constant(oop con, TRAPS) = 0;
-  virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS) = 0;
-  virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS) = 0;
-  virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS) = 0;
-
-  // For make_invoke, the methodHandle can be NULL if the intrinsic ID
-  // is something other than vmIntrinsics::_none.
-
-  // and in case anyone cares to related the previous actions to the chain:
-  virtual void set_method_handle(oop mh) { }
-
-  void lose(const char* msg, TRAPS) { chain().lose(msg, THREAD); }
-  const char* lose_message()        { return chain().lose_message(); }
-
-  ArgToken walk(TRAPS);
-};
-
-
-// An abstract interpreter for method handle chains.
-// Produces an account of the semantics of a chain, in terms of a static IR.
-// The IR happens to be JVM bytecodes.
-class MethodHandleCompiler : public MethodHandleWalker {
-private:
-  int          _invoke_count;  // count the original call site has been executed
-  KlassHandle  _rklass;        // Return type for casting.
-  BasicType    _rtype;
-  KlassHandle  _target_klass;
-  Thread*      _thread;
-
-  int          _selectAlternative_bci; // These are used for capturing profiles from GWTs
-  int          _taken_count;
-  int          _not_taken_count;
-
-  // Values used by the compiler.
-  static jvalue zero_jvalue;
-  static jvalue one_jvalue;
-
-  // Fake constant pool entry.
-  class ConstantValue : public ResourceObj {
-  private:
-    int       _tag;   // Constant pool tag type.
-    JavaValue _value;
-    Handle    _handle;
-    Symbol*   _sym;
-    methodHandle _method;  // pre-linkage
-
-  public:
-    // Constructor for oop types.
-    ConstantValue(int tag, Handle con) : _tag(tag), _handle(con) {
-      assert(tag == JVM_CONSTANT_Class  ||
-             tag == JVM_CONSTANT_String ||
-             tag == JVM_CONSTANT_Object, "must be oop type");
-    }
-
-    ConstantValue(int tag, Symbol* con) : _tag(tag), _sym(con) {
-      assert(tag == JVM_CONSTANT_Utf8, "must be symbol type");
-    }
-
-    // Constructor for oop reference types.
-    ConstantValue(int tag, int index) : _tag(tag) {
-      assert(JVM_CONSTANT_Fieldref <= tag && tag <= JVM_CONSTANT_NameAndType, "must be ref type");
-      _value.set_jint(index);
-    }
-    ConstantValue(int tag, int first_index, int second_index) : _tag(tag) {
-      assert(JVM_CONSTANT_Fieldref <= tag && tag <= JVM_CONSTANT_NameAndType, "must be ref type");
-      _value.set_jint(first_index << 16 | second_index);
-    }
-
-    // Constructor for primitive types.
-    ConstantValue(BasicType bt, jvalue con) {
-      _value.set_type(bt);
-      switch (bt) {
-      case T_INT:    _tag = JVM_CONSTANT_Integer; _value.set_jint(   con.i); break;
-      case T_LONG:   _tag = JVM_CONSTANT_Long;    _value.set_jlong(  con.j); break;
-      case T_FLOAT:  _tag = JVM_CONSTANT_Float;   _value.set_jfloat( con.f); break;
-      case T_DOUBLE: _tag = JVM_CONSTANT_Double;  _value.set_jdouble(con.d); break;
-      default: ShouldNotReachHere();
-      }
-    }
-
-    int       tag()          const { return _tag; }
-    Symbol*   symbol()       const { return _sym; }
-    klassOop  klass_oop()    const { return (klassOop)  _handle(); }
-    oop       object_oop()   const { return _handle(); }
-    int       index()        const { return _value.get_jint(); }
-    int       first_index()  const { return _value.get_jint() >> 16; }
-    int       second_index() const { return _value.get_jint() & 0x0000FFFF; }
-
-    bool      is_primitive() const { return is_java_primitive(_value.get_type()); }
-    jint      get_jint()     const { return _value.get_jint();    }
-    jlong     get_jlong()    const { return _value.get_jlong();   }
-    jfloat    get_jfloat()   const { return _value.get_jfloat();  }
-    jdouble   get_jdouble()  const { return _value.get_jdouble(); }
-
-    void set_linkage(methodHandle method) {
-      assert(_method.is_null(), "");
-      _method = method;
-    }
-    bool     has_linkage()   const { return _method.not_null(); }
-    methodHandle linkage()   const { return _method; }
-  };
-
-  // Fake constant pool.
-  GrowableArray<ConstantValue*> _constants;
-
-  // Non-BCP classes that appear in associated MethodTypes (require special handling).
-  GrowableArray<KlassHandle> _non_bcp_klasses;
-
-  // Accumulated compiler state:
-  GrowableArray<unsigned char> _bytecode;
-
-  int _cur_stack;
-  int _max_stack;
-  int _num_params;
-  int _name_index;
-  int _signature_index;
-
-  void stack_push(BasicType bt) {
-    _cur_stack += type2size[bt];
-    if (_cur_stack > _max_stack) _max_stack = _cur_stack;
-  }
-  void stack_pop(BasicType bt) {
-    _cur_stack -= type2size[bt];
-    assert(_cur_stack >= 0, "sanity");
-  }
-
-  unsigned char* bytecode()        const { return _bytecode.adr_at(0); }
-  int            bytecode_length() const { return _bytecode.length(); }
-  int            cur_bci()         const { return _bytecode.length(); }
-
-  // Fake constant pool.
-  int cpool_oop_put(int tag, Handle con) {
-    if (con.is_null())  return 0;
-    ConstantValue* cv = new ConstantValue(tag, con);
-    return _constants.append(cv);
-  }
-
-  int cpool_symbol_put(int tag, Symbol* con) {
-    if (con == NULL)  return 0;
-    ConstantValue* cv = new ConstantValue(tag, con);
-    con->increment_refcount();
-    return _constants.append(cv);
-  }
-
-  int cpool_oop_reference_put(int tag, int first_index, int second_index, methodHandle method) {
-    if (first_index == 0 && second_index == 0)  return 0;
-    assert(first_index != 0 && second_index != 0, "no zero indexes");
-    ConstantValue* cv = new ConstantValue(tag, first_index, second_index);
-    if (method.not_null())  cv->set_linkage(method);
-    return _constants.append(cv);
-  }
-
-  int cpool_primitive_put(BasicType type, jvalue* con);
-
-  bool check_non_bcp_klasses(Handle method_type, TRAPS);
-  bool check_non_bcp_klass(klassOop klass, TRAPS);
-  void record_non_bcp_klasses();
-
-  int cpool_int_put(jint value) {
-    jvalue con; con.i = value;
-    return cpool_primitive_put(T_INT, &con);
-  }
-  int cpool_long_put(jlong value) {
-    jvalue con; con.j = value;
-    return cpool_primitive_put(T_LONG, &con);
-  }
-  int cpool_float_put(jfloat value) {
-    jvalue con; con.f = value;
-    return cpool_primitive_put(T_FLOAT, &con);
-  }
-  int cpool_double_put(jdouble value) {
-    jvalue con; con.d = value;
-    return cpool_primitive_put(T_DOUBLE, &con);
-  }
-
-  int cpool_object_put(Handle obj) {
-    return cpool_oop_put(JVM_CONSTANT_Object, obj);
-  }
-  int cpool_symbol_put(Symbol* sym) {
-    return cpool_symbol_put(JVM_CONSTANT_Utf8, sym);
-  }
-  int cpool_klass_put(klassOop klass) {
-    return cpool_oop_put(JVM_CONSTANT_Class, klass);
-  }
-  int cpool_methodref_put(Bytecodes::Code op, int class_index, int name_and_type_index, methodHandle method) {
-    int tag = (op == Bytecodes::_invokeinterface ? JVM_CONSTANT_InterfaceMethodref : JVM_CONSTANT_Methodref);
-    return cpool_oop_reference_put(tag, class_index, name_and_type_index, method);
-  }
-  int cpool_name_and_type_put(int name_index, int signature_index) {
-    return cpool_oop_reference_put(JVM_CONSTANT_NameAndType, name_index, signature_index, methodHandle());
-  }
-
-  void emit_bc(Bytecodes::Code op, int index = 0, int args_size = -1);
-  void update_branch_dest(int src, int dst);
-  void emit_load(ArgToken arg);
-  void emit_load(BasicType bt, int index);
-  void emit_store(BasicType bt, int index);
-  void emit_load_constant(ArgToken arg);
-
-  virtual ArgToken make_parameter(BasicType type, klassOop tk, int argnum, TRAPS) {
-    return ArgToken(tt_parameter, type, argnum);
-  }
-  virtual ArgToken make_oop_constant(oop con, TRAPS) {
-    Handle h(THREAD, con);
-    return ArgToken(h);
-  }
-  virtual ArgToken make_prim_constant(BasicType type, jvalue* con, TRAPS) {
-    return ArgToken(type, *con);
-  }
-
-  virtual ArgToken make_conversion(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& src, TRAPS);
-  virtual ArgToken make_fetch(BasicType type, klassOop tk, Bytecodes::Code op, const ArgToken& base, const ArgToken& offset, TRAPS);
-  virtual ArgToken make_invoke(methodHandle m, vmIntrinsics::ID iid, Bytecodes::Code op, bool tailcall, int argc, ArgToken* argv, TRAPS);
-
-  // Check for profiling information on a GWT and return true if it's found
-  bool fetch_counts(ArgToken a1, ArgToken a2);
-
-  // Get a real constant pool.
-  constantPoolHandle get_constant_pool(TRAPS) const;
-
-  // Get a real methodOop.
-  methodHandle get_method_oop(TRAPS);
-
-public:
-  MethodHandleCompiler(Handle root, Symbol* name, Symbol* signature, int invoke_count, bool for_invokedynamic, TRAPS);
-
-  // Compile the given MH chain into bytecode.
-  methodHandle compile(TRAPS);
-
-  // Tests if the given class is a MH adapter holder.
-  static bool klass_is_method_handle_adapter_holder(klassOop klass) {
-    return (klass == SystemDictionary::MethodHandle_klass());
-  }
-};
-
-#endif // SHARE_VM_PRIMS_METHODHANDLEWALK_HPP
diff --git a/hotspot/src/share/vm/prims/methodHandles.cpp b/hotspot/src/share/vm/prims/methodHandles.cpp
index 552fbe6..5eeb749 100644
--- a/hotspot/src/share/vm/prims/methodHandles.cpp
+++ b/hotspot/src/share/vm/prims/methodHandles.cpp
@@ -30,166 +30,30 @@
 #include "memory/allocation.inline.hpp"
 #include "memory/oopFactory.hpp"
 #include "prims/methodHandles.hpp"
-#include "prims/methodHandleWalk.hpp"
 #include "runtime/compilationPolicy.hpp"
 #include "runtime/javaCalls.hpp"
 #include "runtime/reflection.hpp"
 #include "runtime/signature.hpp"
 #include "runtime/stubRoutines.hpp"
 
+
 /*
  * JSR 292 reference implementation: method handles
+ * The JDK 7 reference implementation represented method handle
+ * combinations as chains.  Each link in the chain had a "vmentry"
+ * field which pointed at a bit of assembly code which performed
+ * one transformation before dispatching to the next link in the chain.
+ *
+ * The current reference implementation pushes almost all code generation
+ * responsibility to (trusted) Java code.  A method handle contains a
+ * pointer to its "LambdaForm", which embodies all details of the method
+ * handle's behavior.  The LambdaForm is a normal Java object, managed
+ * by a runtime coded in Java.
  */
 
 bool MethodHandles::_enabled = false; // set true after successful native linkage
-
-MethodHandleEntry* MethodHandles::_entries[MethodHandles::_EK_LIMIT] = {NULL};
-const char*        MethodHandles::_entry_names[_EK_LIMIT+1] = {
-  "raise_exception",
-  "invokestatic",               // how a MH emulates invokestatic
-  "invokespecial",              // ditto for the other invokes...
-  "invokevirtual",
-  "invokeinterface",
-  "bound_ref",                  // these are for BMH...
-  "bound_int",
-  "bound_long",
-  "bound_ref_direct",           // (direct versions have a direct methodOop)
-  "bound_int_direct",
-  "bound_long_direct",
-
-  // starting at _adapter_mh_first:
-  "adapter_retype_only",       // these are for AMH...
-  "adapter_retype_raw",
-  "adapter_check_cast",
-  "adapter_prim_to_prim",
-  "adapter_ref_to_prim",
-  "adapter_prim_to_ref",
-  "adapter_swap_args",
-  "adapter_rot_args",
-  "adapter_dup_args",
-  "adapter_drop_args",
-  "adapter_collect_args",
-  "adapter_spread_args",
-  "adapter_fold_args",
-  "adapter_unused_13",
-
-  // optimized adapter types:
-  "adapter_swap_args/1",
-  "adapter_swap_args/2",
-  "adapter_rot_args/1,up",
-  "adapter_rot_args/1,down",
-  "adapter_rot_args/2,up",
-  "adapter_rot_args/2,down",
-  "adapter_prim_to_prim/i2i",
-  "adapter_prim_to_prim/l2i",
-  "adapter_prim_to_prim/d2f",
-  "adapter_prim_to_prim/i2l",
-  "adapter_prim_to_prim/f2d",
-  "adapter_ref_to_prim/unboxi",
-  "adapter_ref_to_prim/unboxl",
-
-  // return value handlers for collect/filter/fold adapters:
-  "return/ref",
-  "return/int",
-  "return/long",
-  "return/float",
-  "return/double",
-  "return/void",
-  "return/S0/ref",
-  "return/S1/ref",
-  "return/S2/ref",
-  "return/S3/ref",
-  "return/S4/ref",
-  "return/S5/ref",
-  "return/any",
-
-  // spreading (array length cases 0, 1, ...)
-  "adapter_spread/0",
-  "adapter_spread/1/ref",
-  "adapter_spread/2/ref",
-  "adapter_spread/3/ref",
-  "adapter_spread/4/ref",
-  "adapter_spread/5/ref",
-  "adapter_spread/ref",
-  "adapter_spread/byte",
-  "adapter_spread/char",
-  "adapter_spread/short",
-  "adapter_spread/int",
-  "adapter_spread/long",
-  "adapter_spread/float",
-  "adapter_spread/double",
-
-  // blocking filter/collect conversions:
-  "adapter_collect/ref",
-  "adapter_collect/int",
-  "adapter_collect/long",
-  "adapter_collect/float",
-  "adapter_collect/double",
-  "adapter_collect/void",
-  "adapter_collect/0/ref",
-  "adapter_collect/1/ref",
-  "adapter_collect/2/ref",
-  "adapter_collect/3/ref",
-  "adapter_collect/4/ref",
-  "adapter_collect/5/ref",
-  "adapter_filter/S0/ref",
-  "adapter_filter/S1/ref",
-  "adapter_filter/S2/ref",
-  "adapter_filter/S3/ref",
-  "adapter_filter/S4/ref",
-  "adapter_filter/S5/ref",
-  "adapter_collect/2/S0/ref",
-  "adapter_collect/2/S1/ref",
-  "adapter_collect/2/S2/ref",
-  "adapter_collect/2/S3/ref",
-  "adapter_collect/2/S4/ref",
-  "adapter_collect/2/S5/ref",
-
-  // blocking fold conversions:
-  "adapter_fold/ref",
-  "adapter_fold/int",
-  "adapter_fold/long",
-  "adapter_fold/float",
-  "adapter_fold/double",
-  "adapter_fold/void",
-  "adapter_fold/1/ref",
-  "adapter_fold/2/ref",
-  "adapter_fold/3/ref",
-  "adapter_fold/4/ref",
-  "adapter_fold/5/ref",
-
-  "adapter_opt_profiling",
-
-  NULL
-};
-
-// Adapters.
 MethodHandlesAdapterBlob* MethodHandles::_adapter_code = NULL;
 
-jobject MethodHandles::_raise_exception_method;
-
-address MethodHandles::_adapter_return_handlers[CONV_TYPE_MASK+1];
-
-#ifdef ASSERT
-bool MethodHandles::spot_check_entry_names() {
-  assert(!strcmp(entry_name(_invokestatic_mh), "invokestatic"), "");
-  assert(!strcmp(entry_name(_bound_ref_mh), "bound_ref"), "");
-  assert(!strcmp(entry_name(_adapter_retype_only), "adapter_retype_only"), "");
-  assert(!strcmp(entry_name(_adapter_fold_args), "adapter_fold_args"), "");
-  assert(!strcmp(entry_name(_adapter_opt_unboxi), "adapter_ref_to_prim/unboxi"), "");
-  assert(!strcmp(entry_name(_adapter_opt_spread_char), "adapter_spread/char"), "");
-  assert(!strcmp(entry_name(_adapter_opt_spread_double), "adapter_spread/double"), "");
-  assert(!strcmp(entry_name(_adapter_opt_collect_int), "adapter_collect/int"), "");
-  assert(!strcmp(entry_name(_adapter_opt_collect_0_ref), "adapter_collect/0/ref"), "");
-  assert(!strcmp(entry_name(_adapter_opt_collect_2_S3_ref), "adapter_collect/2/S3/ref"), "");
-  assert(!strcmp(entry_name(_adapter_opt_filter_S5_ref), "adapter_filter/S5/ref"), "");
-  assert(!strcmp(entry_name(_adapter_opt_fold_3_ref), "adapter_fold/3/ref"), "");
-  assert(!strcmp(entry_name(_adapter_opt_fold_void), "adapter_fold/void"), "");
-  return true;
-}
-#endif
-
-
 //------------------------------------------------------------------------------
 // MethodHandles::generate_adapters
 //
@@ -216,36 +80,20 @@
 //
 void MethodHandlesAdapterGenerator::generate() {
   // Generate generic method handle adapters.
-  for (MethodHandles::EntryKind ek = MethodHandles::_EK_FIRST;
-       ek < MethodHandles::_EK_LIMIT;
-       ek = MethodHandles::EntryKind(1 + (int)ek)) {
-    if (MethodHandles::ek_supported(ek)) {
-      StubCodeMark mark(this, "MethodHandle", MethodHandles::entry_name(ek));
-      MethodHandles::generate_method_handle_stub(_masm, ek);
+  // Generate interpreter entries
+  for (Interpreter::MethodKind mk = Interpreter::method_handle_invoke_FIRST;
+       mk <= Interpreter::method_handle_invoke_LAST;
+       mk = Interpreter::MethodKind(1 + (int)mk)) {
+    vmIntrinsics::ID iid = Interpreter::method_handle_intrinsic(mk);
+    StubCodeMark mark(this, "MethodHandle::interpreter_entry", vmIntrinsics::name_at(iid));
+    address entry = MethodHandles::generate_method_handle_interpreter_entry(_masm, iid);
+    if (entry != NULL) {
+      Interpreter::set_entry_for_kind(mk, entry);
     }
+    // If the entry is not set, it will throw AbstractMethodError.
   }
 }
 
-
-//------------------------------------------------------------------------------
-// MethodHandles::ek_supported
-//
-bool MethodHandles::ek_supported(MethodHandles::EntryKind ek) {
-  MethodHandles::EntryKind ek_orig = MethodHandles::ek_original_kind(ek);
-  switch (ek_orig) {
-  case _adapter_unused_13:
-    return false;  // not defined yet
-  case _adapter_prim_to_ref:
-    return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF);
-  case _adapter_collect_args:
-    return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS);
-  case _adapter_fold_args:
-    return conv_op_supported(java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS);
-  }
-  return true;
-}
-
-
 void MethodHandles::set_enabled(bool z) {
   if (_enabled != z) {
     guarantee(z && EnableInvokeDynamic, "can only enable once, and only if -XX:+EnableInvokeDynamic");
@@ -253,217 +101,6 @@
   }
 }
 
-// Note: A method which does not have a TRAPS argument cannot block in the GC
-// or throw exceptions.  Such methods are used in this file to do something quick
-// and local, like parse a data structure.  For speed, such methods work on plain
-// oops, not handles.  Trapping methods uniformly operate on handles.
-
-methodHandle MethodHandles::decode_vmtarget(oop vmtarget, int vmindex, oop mtype,
-                                            KlassHandle& receiver_limit_result, int& decode_flags_result) {
-  if (vmtarget == NULL)  return methodHandle();
-  assert(methodOopDesc::nonvirtual_vtable_index < 0, "encoding");
-  if (vmindex < 0) {
-    // this DMH performs no dispatch; it is directly bound to a methodOop
-    // A MemberName may either be directly bound to a methodOop,
-    // or it may use the klass/index form; both forms mean the same thing.
-    methodOop m = decode_methodOop(methodOop(vmtarget), decode_flags_result);
-    if ((decode_flags_result & _dmf_has_receiver) != 0
-        && java_lang_invoke_MethodType::is_instance(mtype)) {
-      // Extract receiver type restriction from mtype.ptypes[0].
-      objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(mtype);
-      oop ptype0 = (ptypes == NULL || ptypes->length() < 1) ? oop(NULL) : ptypes->obj_at(0);
-      if (java_lang_Class::is_instance(ptype0))
-        receiver_limit_result = java_lang_Class::as_klassOop(ptype0);
-    }
-    if (vmindex == methodOopDesc::nonvirtual_vtable_index) {
-      // this DMH can be an "invokespecial" version
-      decode_flags_result &= ~_dmf_does_dispatch;
-    } else {
-      assert(vmindex == methodOopDesc::invalid_vtable_index, "random vmindex?");
-    }
-    return m;
-  } else {
-    assert(vmtarget->is_klass(), "must be class or interface");
-    decode_flags_result |= MethodHandles::_dmf_does_dispatch;
-    decode_flags_result |= MethodHandles::_dmf_has_receiver;
-    receiver_limit_result = (klassOop)vmtarget;
-    Klass* tk = Klass::cast((klassOop)vmtarget);
-    if (tk->is_interface()) {
-      // an itable linkage is <interface, itable index>
-      decode_flags_result |= MethodHandles::_dmf_from_interface;
-      return klassItable::method_for_itable_index((klassOop)vmtarget, vmindex);
-    } else {
-      if (!tk->oop_is_instance())
-        tk = instanceKlass::cast(SystemDictionary::Object_klass());
-      return ((instanceKlass*)tk)->method_at_vtable(vmindex);
-    }
-  }
-}
-
-// MemberName and DirectMethodHandle have the same linkage to the JVM internals.
-// (MemberName is the non-operational name used for queries and setup.)
-
-methodHandle MethodHandles::decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
-  oop vmtarget = java_lang_invoke_DirectMethodHandle::vmtarget(mh);
-  int vmindex  = java_lang_invoke_DirectMethodHandle::vmindex(mh);
-  oop mtype    = java_lang_invoke_DirectMethodHandle::type(mh);
-  return decode_vmtarget(vmtarget, vmindex, mtype, receiver_limit_result, decode_flags_result);
-}
-
-methodHandle MethodHandles::decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
-  assert(java_lang_invoke_BoundMethodHandle::is_instance(mh), "");
-  assert(mh->klass() != SystemDictionary::AdapterMethodHandle_klass(), "");
-  for (oop bmh = mh;;) {
-    // Bound MHs can be stacked to bind several arguments.
-    oop target = java_lang_invoke_MethodHandle::vmtarget(bmh);
-    if (target == NULL)  return methodHandle();
-    decode_flags_result |= MethodHandles::_dmf_binds_argument;
-    klassOop tk = target->klass();
-    if (tk == SystemDictionary::BoundMethodHandle_klass()) {
-      bmh = target;
-      continue;
-    } else {
-      if (java_lang_invoke_MethodHandle::is_subclass(tk)) {
-        //assert(tk == SystemDictionary::DirectMethodHandle_klass(), "end of BMH chain must be DMH");
-        return decode_MethodHandle(target, receiver_limit_result, decode_flags_result);
-      } else {
-        // Optimized case:  binding a receiver to a non-dispatched DMH
-        // short-circuits directly to the methodOop.
-        // (It might be another argument besides a receiver also.)
-        assert(target->is_method(), "must be a simple method");
-        decode_flags_result |= MethodHandles::_dmf_binds_method;
-        methodOop m = (methodOop) target;
-        if (!m->is_static())
-          decode_flags_result |= MethodHandles::_dmf_has_receiver;
-        return m;
-      }
-    }
-  }
-}
-
-methodHandle MethodHandles::decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
-  assert(mh->klass() == SystemDictionary::AdapterMethodHandle_klass(), "");
-  for (oop amh = mh;;) {
-    // Adapter MHs can be stacked to convert several arguments.
-    int conv_op = adapter_conversion_op(java_lang_invoke_AdapterMethodHandle::conversion(amh));
-    decode_flags_result |= (_dmf_adapter_lsb << conv_op) & _DMF_ADAPTER_MASK;
-    oop target = java_lang_invoke_MethodHandle::vmtarget(amh);
-    if (target == NULL)  return methodHandle();
-    klassOop tk = target->klass();
-    if (tk == SystemDictionary::AdapterMethodHandle_klass()) {
-      amh = target;
-      continue;
-    } else {
-      // must be a BMH (which will bind some more arguments) or a DMH (for the final call)
-      return MethodHandles::decode_MethodHandle(target, receiver_limit_result, decode_flags_result);
-    }
-  }
-}
-
-methodHandle MethodHandles::decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result) {
-  if (mh == NULL)  return methodHandle();
-  klassOop mhk = mh->klass();
-  assert(java_lang_invoke_MethodHandle::is_subclass(mhk), "must be a MethodHandle");
-  if (mhk == SystemDictionary::DirectMethodHandle_klass()) {
-    return decode_DirectMethodHandle(mh, receiver_limit_result, decode_flags_result);
-  } else if (mhk == SystemDictionary::BoundMethodHandle_klass()) {
-    return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
-  } else if (mhk == SystemDictionary::AdapterMethodHandle_klass()) {
-    return decode_AdapterMethodHandle(mh, receiver_limit_result, decode_flags_result);
-  } else if (java_lang_invoke_BoundMethodHandle::is_subclass(mhk)) {
-    // could be a JavaMethodHandle (but not an adapter MH)
-    return decode_BoundMethodHandle(mh, receiver_limit_result, decode_flags_result);
-  } else {
-    assert(false, "cannot parse this MH");
-    return methodHandle();  // random MH?
-  }
-}
-
-methodOop MethodHandles::decode_methodOop(methodOop m, int& decode_flags_result) {
-  assert(m->is_method(), "");
-  if (m->is_static()) {
-    // check that signature begins '(L' or '([' (not '(I', '()', etc.)
-    Symbol* sig = m->signature();
-    BasicType recv_bt = char2type(sig->byte_at(1));
-    // Note: recv_bt might be T_ILLEGAL if byte_at(2) is ')'
-    assert(sig->byte_at(0) == '(', "must be method sig");
-//     if (recv_bt == T_OBJECT || recv_bt == T_ARRAY)
-//       decode_flags_result |= _dmf_has_receiver;
-  } else {
-    // non-static method
-    decode_flags_result |= _dmf_has_receiver;
-    if (!m->can_be_statically_bound() && !m->is_initializer()) {
-      decode_flags_result |= _dmf_does_dispatch;
-      if (Klass::cast(m->method_holder())->is_interface())
-        decode_flags_result |= _dmf_from_interface;
-    }
-  }
-  return m;
-}
-
-
-// A trusted party is handing us a cookie to determine a method.
-// Let's boil it down to the method oop they really want.
-methodHandle MethodHandles::decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result) {
-  decode_flags_result = 0;
-  receiver_limit_result = KlassHandle();
-  klassOop xk = x->klass();
-  if (xk == Universe::methodKlassObj()) {
-    return decode_methodOop((methodOop) x, decode_flags_result);
-  } else if (xk == SystemDictionary::MemberName_klass()) {
-    // Note: This only works if the MemberName has already been resolved.
-    return decode_MemberName(x, receiver_limit_result, decode_flags_result);
-  } else if (java_lang_invoke_MethodHandle::is_subclass(xk)) {
-    return decode_MethodHandle(x, receiver_limit_result, decode_flags_result);
-  } else if (xk == SystemDictionary::reflect_Method_klass()) {
-    oop clazz  = java_lang_reflect_Method::clazz(x);
-    int slot   = java_lang_reflect_Method::slot(x);
-    klassOop k = java_lang_Class::as_klassOop(clazz);
-    if (k != NULL && Klass::cast(k)->oop_is_instance())
-      return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot),
-                              decode_flags_result);
-  } else if (xk == SystemDictionary::reflect_Constructor_klass()) {
-    oop clazz  = java_lang_reflect_Constructor::clazz(x);
-    int slot   = java_lang_reflect_Constructor::slot(x);
-    klassOop k = java_lang_Class::as_klassOop(clazz);
-    if (k != NULL && Klass::cast(k)->oop_is_instance())
-      return decode_methodOop(instanceKlass::cast(k)->method_with_idnum(slot),
-                              decode_flags_result);
-  } else {
-    // unrecognized object
-    assert(!x->is_method(), "already checked");
-    assert(!java_lang_invoke_MemberName::is_instance(x), "already checked");
-  }
-  return methodHandle();
-}
-
-
-int MethodHandles::decode_MethodHandle_stack_pushes(oop mh) {
-  if (mh->klass() == SystemDictionary::DirectMethodHandle_klass())
-    return 0;                   // no push/pop
-  int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh);
-  int last_vmslots = 0;
-  oop last_mh = mh;
-  for (;;) {
-    oop target = java_lang_invoke_MethodHandle::vmtarget(last_mh);
-    if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
-      last_vmslots = java_lang_invoke_MethodHandle::vmslots(target);
-      break;
-    } else if (!java_lang_invoke_MethodHandle::is_instance(target)) {
-      // might be klass or method
-      assert(target->is_method(), "must get here with a direct ref to method");
-      last_vmslots = methodOop(target)->size_of_parameters();
-      break;
-    }
-    last_mh = target;
-  }
-  // If I am called with fewer VM slots than my ultimate callee,
-  // it must be that I push the additionally needed slots.
-  // Likewise if am called with more VM slots, I will pop them.
-  return (last_vmslots - this_vmslots);
-}
-
-
 // MemberName support
 
 // import java_lang_invoke_MemberName.*
@@ -472,10 +109,11 @@
   IS_CONSTRUCTOR = java_lang_invoke_MemberName::MN_IS_CONSTRUCTOR,
   IS_FIELD       = java_lang_invoke_MemberName::MN_IS_FIELD,
   IS_TYPE        = java_lang_invoke_MemberName::MN_IS_TYPE,
+  REFERENCE_KIND_SHIFT = java_lang_invoke_MemberName::MN_REFERENCE_KIND_SHIFT,
+  REFERENCE_KIND_MASK  = java_lang_invoke_MemberName::MN_REFERENCE_KIND_MASK,
   SEARCH_SUPERCLASSES = java_lang_invoke_MemberName::MN_SEARCH_SUPERCLASSES,
   SEARCH_INTERFACES   = java_lang_invoke_MemberName::MN_SEARCH_INTERFACES,
-  ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE,
-  VM_INDEX_UNINITIALIZED = java_lang_invoke_MemberName::VM_INDEX_UNINITIALIZED
+  ALL_KINDS      = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE
 };
 
 Handle MethodHandles::new_MemberName(TRAPS) {
@@ -485,72 +123,265 @@
   return Handle(THREAD, k->allocate_instance(THREAD));
 }
 
-void MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
-  if (target_oop->klass() == SystemDictionary::reflect_Field_klass()) {
+oop MethodHandles::init_MemberName(oop mname_oop, oop target_oop) {
+  klassOop target_klass = target_oop->klass();
+  if (target_klass == SystemDictionary::reflect_Field_klass()) {
     oop clazz = java_lang_reflect_Field::clazz(target_oop); // fd.field_holder()
     int slot  = java_lang_reflect_Field::slot(target_oop);  // fd.index()
     int mods  = java_lang_reflect_Field::modifiers(target_oop);
+    oop type  = java_lang_reflect_Field::type(target_oop);
+    oop name  = java_lang_reflect_Field::name(target_oop);
     klassOop k = java_lang_Class::as_klassOop(clazz);
-    int offset = instanceKlass::cast(k)->field_offset(slot);
-    init_MemberName(mname_oop, k, accessFlags_from(mods), offset);
-  } else {
-    KlassHandle receiver_limit; int decode_flags = 0;
-    methodHandle m = MethodHandles::decode_method(target_oop, receiver_limit, decode_flags);
-    bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
-    init_MemberName(mname_oop, m(), do_dispatch);
+    intptr_t offset = instanceKlass::cast(k)->field_offset(slot);
+    return init_field_MemberName(mname_oop, k, accessFlags_from(mods), type, name, offset);
+  } else if (target_klass == SystemDictionary::reflect_Method_klass()) {
+    oop clazz  = java_lang_reflect_Method::clazz(target_oop);
+    int slot   = java_lang_reflect_Method::slot(target_oop);
+    klassOop k = java_lang_Class::as_klassOop(clazz);
+    if (k != NULL && Klass::cast(k)->oop_is_instance()) {
+      methodOop m = instanceKlass::cast(k)->method_with_idnum(slot);
+      return init_method_MemberName(mname_oop, m, true, k);
+    }
+  } else if (target_klass == SystemDictionary::reflect_Constructor_klass()) {
+    oop clazz  = java_lang_reflect_Constructor::clazz(target_oop);
+    int slot   = java_lang_reflect_Constructor::slot(target_oop);
+    klassOop k = java_lang_Class::as_klassOop(clazz);
+    if (k != NULL && Klass::cast(k)->oop_is_instance()) {
+      methodOop m = instanceKlass::cast(k)->method_with_idnum(slot);
+      return init_method_MemberName(mname_oop, m, false, k);
+    }
+  } else if (target_klass == SystemDictionary::MemberName_klass()) {
+    // Note: This only works if the MemberName has already been resolved.
+    oop clazz        = java_lang_invoke_MemberName::clazz(target_oop);
+    int flags        = java_lang_invoke_MemberName::flags(target_oop);
+    oop vmtarget     = java_lang_invoke_MemberName::vmtarget(target_oop);
+    intptr_t vmindex = java_lang_invoke_MemberName::vmindex(target_oop);
+    klassOop k       = java_lang_Class::as_klassOop(clazz);
+    int ref_kind     = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
+    if (vmtarget == NULL)  return NULL;  // not resolved
+    if ((flags & IS_FIELD) != 0) {
+      assert(vmtarget->is_klass(), "field vmtarget is klassOop");
+      int basic_mods = (ref_kind_is_static(ref_kind) ? JVM_ACC_STATIC : 0);
+      // FIXME:  how does k (receiver_limit) contribute?
+      return init_field_MemberName(mname_oop, klassOop(vmtarget), accessFlags_from(basic_mods), NULL, NULL, vmindex);
+    } else if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) != 0) {
+      assert(vmtarget->is_method(), "method or constructor vmtarget is methodOop");
+      return init_method_MemberName(mname_oop, methodOop(vmtarget), ref_kind_does_dispatch(ref_kind), k);
+    } else {
+      return NULL;
+    }
   }
+  return NULL;
 }
 
-void MethodHandles::init_MemberName(oop mname_oop, methodOop m, bool do_dispatch) {
-  int flags = ((m->is_initializer() ? IS_CONSTRUCTOR : IS_METHOD)
-               | (jushort)( m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS ));
-  oop vmtarget = m;
-  int vmindex  = methodOopDesc::invalid_vtable_index;  // implies no info yet
-  if (!do_dispatch || (flags & IS_CONSTRUCTOR) || m->can_be_statically_bound())
-    vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
-  assert(vmindex != VM_INDEX_UNINITIALIZED, "Java sentinel value");
-  java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
-  java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);
+oop MethodHandles::init_method_MemberName(oop mname_oop, methodOop m, bool do_dispatch,
+                                          klassOop receiver_limit) {
+  AccessFlags mods = m->access_flags();
+  int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS );
+  int vmindex = methodOopDesc::nonvirtual_vtable_index; // implies never any dispatch
+  klassOop mklass = m->method_holder();
+  if (receiver_limit == NULL)
+    receiver_limit = mklass;
+  if (m->is_initializer()) {
+    flags |= IS_CONSTRUCTOR | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
+  } else if (mods.is_static()) {
+    flags |= IS_METHOD | (JVM_REF_invokeStatic << REFERENCE_KIND_SHIFT);
+  } else if (receiver_limit != mklass &&
+             !Klass::cast(receiver_limit)->is_subtype_of(mklass)) {
+    return NULL;  // bad receiver limit
+  } else if (Klass::cast(receiver_limit)->is_interface() &&
+             Klass::cast(mklass)->is_interface()) {
+    flags |= IS_METHOD | (JVM_REF_invokeInterface << REFERENCE_KIND_SHIFT);
+    receiver_limit = mklass;  // ignore passed-in limit; interfaces are interconvertible
+    vmindex = klassItable::compute_itable_index(m);
+  } else if (mklass != receiver_limit && Klass::cast(mklass)->is_interface()) {
+    flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
+    // it is a miranda method, so m->vtable_index is not what we want
+    ResourceMark rm;
+    klassVtable* vt = instanceKlass::cast(receiver_limit)->vtable();
+    vmindex = vt->index_of_miranda(m->name(), m->signature());
+  } else if (!do_dispatch || m->can_be_statically_bound()) {
+    flags |= IS_METHOD | (JVM_REF_invokeSpecial << REFERENCE_KIND_SHIFT);
+  } else {
+    flags |= IS_METHOD | (JVM_REF_invokeVirtual << REFERENCE_KIND_SHIFT);
+    vmindex = m->vtable_index();
+  }
+
   java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
-  java_lang_invoke_MemberName::set_clazz(mname_oop,    Klass::cast(m->method_holder())->java_mirror());
+  java_lang_invoke_MemberName::set_vmtarget(mname_oop, m);
+  java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);   // vtable/itable index
+  java_lang_invoke_MemberName::set_clazz(mname_oop,    Klass::cast(receiver_limit)->java_mirror());
+  // Note:  name and type can be lazily computed by resolve_MemberName,
+  // if Java code needs them as resolved String and MethodType objects.
+  // The clazz must be eagerly stored, because it provides a GC
+  // root to help keep alive the methodOop.
+  // If relevant, the vtable or itable value is stored as vmindex.
+  // This is done eagerly, since it is readily available without
+  // constructing any new objects.
+  // TO DO: maybe intern mname_oop
+  return mname_oop;
 }
 
-void MethodHandles::init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset) {
-  int flags = (IS_FIELD | (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS ));
+Handle MethodHandles::init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS) {
+  Handle empty;
+  if (info.resolved_appendix().not_null()) {
+    // The resolved MemberName must not be accompanied by an appendix argument,
+    // since there is no way to bind this value into the MemberName.
+    // Caller is responsible to prevent this from happening.
+    THROW_MSG_(vmSymbols::java_lang_InternalError(), "appendix", empty);
+  }
+  methodHandle m = info.resolved_method();
+  KlassHandle defc = info.resolved_klass();
+  int vmindex = -1;
+  if (defc->is_interface() && Klass::cast(m->method_holder())->is_interface()) {
+    // LinkResolver does not report itable indexes!  (fix this?)
+    vmindex = klassItable::compute_itable_index(m());
+  } else if (m->can_be_statically_bound()) {
+    // LinkResolver reports vtable index even for final methods!
+    vmindex = methodOopDesc::nonvirtual_vtable_index;
+  } else {
+    vmindex = info.vtable_index();
+  }
+  oop res = init_method_MemberName(mname_oop, m(), (vmindex >= 0), defc());
+  assert(res == NULL || (java_lang_invoke_MemberName::vmindex(res) == vmindex), "");
+  return Handle(THREAD, res);
+}
+
+oop MethodHandles::init_field_MemberName(oop mname_oop, klassOop field_holder,
+                                         AccessFlags mods, oop type, oop name,
+                                         intptr_t offset, bool is_setter) {
+  int flags = (jushort)( mods.as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS );
+  flags |= IS_FIELD | ((mods.is_static() ? JVM_REF_getStatic : JVM_REF_getField) << REFERENCE_KIND_SHIFT);
+  if (is_setter)  flags += ((JVM_REF_putField - JVM_REF_getField) << REFERENCE_KIND_SHIFT);
   oop vmtarget = field_holder;
   int vmindex  = offset;  // determines the field uniquely when combined with static bit
-  assert(vmindex != VM_INDEX_UNINITIALIZED, "bad alias on vmindex");
+  java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
   java_lang_invoke_MemberName::set_vmtarget(mname_oop, vmtarget);
   java_lang_invoke_MemberName::set_vmindex(mname_oop,  vmindex);
-  java_lang_invoke_MemberName::set_flags(mname_oop,    flags);
   java_lang_invoke_MemberName::set_clazz(mname_oop,    Klass::cast(field_holder)->java_mirror());
+  if (name != NULL)
+    java_lang_invoke_MemberName::set_name(mname_oop,   name);
+  if (type != NULL)
+    java_lang_invoke_MemberName::set_type(mname_oop,   type);
+  // Note:  name and type can be lazily computed by resolve_MemberName,
+  // if Java code needs them as resolved String and Class objects.
+  // Note that the incoming type oop might be pre-resolved (non-null).
+  // The base clazz and field offset (vmindex) must be eagerly stored,
+  // because they unambiguously identify the field.
+  // Although the fieldDescriptor::_index would also identify the field,
+  // we do not use it, because it is harder to decode.
+  // TO DO: maybe intern mname_oop
+  return mname_oop;
+}
+
+Handle MethodHandles::init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS) {
+  return Handle();
+#if 0
+  KlassHandle field_holder = info.klass();
+  intptr_t    field_offset = info.field_offset();
+  return init_field_MemberName(mname_oop, field_holder(),
+                               info.access_flags(),
+                               type, name,
+                               field_offset, false /*is_setter*/);
+#endif
 }
 
 
-methodHandle MethodHandles::decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result) {
-  methodHandle empty;
-  int flags  = java_lang_invoke_MemberName::flags(mname);
-  if ((flags & (IS_METHOD | IS_CONSTRUCTOR)) == 0)  return empty;  // not invocable
-  oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname);
-  int vmindex  = java_lang_invoke_MemberName::vmindex(mname);
-  if (vmindex == VM_INDEX_UNINITIALIZED)  return empty;  // not resolved
-  methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit_result, decode_flags_result);
-  oop clazz = java_lang_invoke_MemberName::clazz(mname);
-  if (clazz != NULL && java_lang_Class::is_instance(clazz)) {
-    klassOop klass = java_lang_Class::as_klassOop(clazz);
-    if (klass != NULL)  receiver_limit_result = klass;
+// JVM 2.9 Special Methods:
+// A method is signature polymorphic if and only if all of the following conditions hold :
+// * It is declared in the java.lang.invoke.MethodHandle class.
+// * It has a single formal parameter of type Object[].
+// * It has a return type of Object.
+// * It has the ACC_VARARGS and ACC_NATIVE flags set.
+bool MethodHandles::is_method_handle_invoke_name(klassOop klass, Symbol* name) {
+  if (klass == NULL)
+    return false;
+  // The following test will fail spuriously during bootstrap of MethodHandle itself:
+  //    if (klass != SystemDictionary::MethodHandle_klass())
+  // Test the name instead:
+  if (Klass::cast(klass)->name() != vmSymbols::java_lang_invoke_MethodHandle())
+    return false;
+  Symbol* poly_sig = vmSymbols::object_array_object_signature();
+  methodOop m = instanceKlass::cast(klass)->find_method(name, poly_sig);
+  if (m == NULL)  return false;
+  int required = JVM_ACC_NATIVE | JVM_ACC_VARARGS;
+  int flags = m->access_flags().as_int();
+  return (flags & required) == required;
+}
+
+
+Symbol* MethodHandles::signature_polymorphic_intrinsic_name(vmIntrinsics::ID iid) {
+  assert(is_signature_polymorphic_intrinsic(iid), err_msg("iid=%d", iid));
+  switch (iid) {
+  case vmIntrinsics::_invokeBasic:      return vmSymbols::invokeBasic_name();
+  case vmIntrinsics::_linkToVirtual:    return vmSymbols::linkToVirtual_name();
+  case vmIntrinsics::_linkToStatic:     return vmSymbols::linkToStatic_name();
+  case vmIntrinsics::_linkToSpecial:    return vmSymbols::linkToSpecial_name();
+  case vmIntrinsics::_linkToInterface:  return vmSymbols::linkToInterface_name();
   }
-  return m;
+  assert(false, "");
+  return 0;
 }
 
+int MethodHandles::signature_polymorphic_intrinsic_ref_kind(vmIntrinsics::ID iid) {
+  switch (iid) {
+  case vmIntrinsics::_invokeBasic:      return 0;
+  case vmIntrinsics::_linkToVirtual:    return JVM_REF_invokeVirtual;
+  case vmIntrinsics::_linkToStatic:     return JVM_REF_invokeStatic;
+  case vmIntrinsics::_linkToSpecial:    return JVM_REF_invokeSpecial;
+  case vmIntrinsics::_linkToInterface:  return JVM_REF_invokeInterface;
+  }
+  assert(false, err_msg("iid=%d", iid));
+  return 0;
+}
+
+vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(Symbol* name) {
+  vmSymbols::SID name_id = vmSymbols::find_sid(name);
+  switch (name_id) {
+  // The ID _invokeGeneric stands for all non-static signature-polymorphic methods, except built-ins.
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(invoke_name):           return vmIntrinsics::_invokeGeneric;
+  // The only built-in non-static signature-polymorphic method is MethodHandle.invokeBasic:
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(invokeBasic_name):      return vmIntrinsics::_invokeBasic;
+
+  // There is one static signature-polymorphic method for each JVM invocation mode.
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(linkToVirtual_name):    return vmIntrinsics::_linkToVirtual;
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(linkToStatic_name):     return vmIntrinsics::_linkToStatic;
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(linkToSpecial_name):    return vmIntrinsics::_linkToSpecial;
+  case vmSymbols::VM_SYMBOL_ENUM_NAME(linkToInterface_name):  return vmIntrinsics::_linkToInterface;
+  }
+
+  // Cover the case of invokeExact and any future variants of invokeFoo.
+  klassOop mh_klass = SystemDictionary::well_known_klass(
+                              SystemDictionary::WK_KLASS_ENUM_NAME(MethodHandle_klass) );
+  if (mh_klass != NULL && is_method_handle_invoke_name(mh_klass, name))
+    return vmIntrinsics::_invokeGeneric;
+
+  // Note: The pseudo-intrinsic _compiledLambdaForm is never linked against.
+  // Instead it is used to mark lambda forms bound to invokehandle or invokedynamic.
+  return vmIntrinsics::_none;
+}
+
+vmIntrinsics::ID MethodHandles::signature_polymorphic_name_id(klassOop klass, Symbol* name) {
+  if (klass != NULL &&
+      Klass::cast(klass)->name() == vmSymbols::java_lang_invoke_MethodHandle()) {
+    vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
+    if (iid != vmIntrinsics::_none)
+      return iid;
+    if (is_method_handle_invoke_name(klass, name))
+      return vmIntrinsics::_invokeGeneric;
+  }
+  return vmIntrinsics::_none;
+}
+
+
 // convert the external string or reflective type to an internal signature
-Symbol* MethodHandles::convert_to_signature(oop type_str, bool polymorphic, TRAPS) {
+Symbol* MethodHandles::lookup_signature(oop type_str, bool intern_if_not_found, TRAPS) {
   if (java_lang_invoke_MethodType::is_instance(type_str)) {
-    return java_lang_invoke_MethodType::as_signature(type_str, polymorphic, CHECK_NULL);
+    return java_lang_invoke_MethodType::as_signature(type_str, intern_if_not_found, CHECK_NULL);
   } else if (java_lang_Class::is_instance(type_str)) {
     return java_lang_Class::as_signature(type_str, false, CHECK_NULL);
   } else if (java_lang_String::is_instance(type_str)) {
-    if (polymorphic) {
+    if (intern_if_not_found) {
       return java_lang_String::as_symbol(type_str, CHECK_NULL);
     } else {
       return java_lang_String::as_symbol_or_null(type_str);
@@ -560,121 +391,294 @@
   }
 }
 
+static const char OBJ_SIG[] = "Ljava/lang/Object;";
+enum { OBJ_SIG_LEN = 18 };
+
+bool MethodHandles::is_basic_type_signature(Symbol* sig) {
+  assert(vmSymbols::object_signature()->utf8_length() == (int)OBJ_SIG_LEN, "");
+  assert(vmSymbols::object_signature()->equals(OBJ_SIG), "");
+  const int len = sig->utf8_length();
+  for (int i = 0; i < len; i++) {
+    switch (sig->byte_at(i)) {
+    case 'L':
+      // only java/lang/Object is valid here
+      if (sig->index_of_at(i, OBJ_SIG, OBJ_SIG_LEN) != i)
+        return false;
+      i += OBJ_SIG_LEN-1;  //-1 because of i++ in loop
+      continue;
+    case '(': case ')': case 'V':
+    case 'I': case 'J': case 'F': case 'D':
+      continue;
+    //case '[':
+    //case 'Z': case 'B': case 'C': case 'S':
+    default:
+      return false;
+    }
+  }
+  return true;
+}
+
+Symbol* MethodHandles::lookup_basic_type_signature(Symbol* sig, bool keep_last_arg, TRAPS) {
+  Symbol* bsig = NULL;
+  if (sig == NULL) {
+    return sig;
+  } else if (is_basic_type_signature(sig)) {
+    sig->increment_refcount();
+    return sig;  // that was easy
+  } else if (sig->byte_at(0) != '(') {
+    BasicType bt = char2type(sig->byte_at(0));
+    if (is_subword_type(bt)) {
+      bsig = vmSymbols::int_signature();
+    } else {
+      assert(bt == T_OBJECT || bt == T_ARRAY, "is_basic_type_signature was false");
+      bsig = vmSymbols::object_signature();
+    }
+  } else {
+    ResourceMark rm;
+    stringStream buffer(128);
+    buffer.put('(');
+    int arg_pos = 0, keep_arg_pos = -1;
+    if (keep_last_arg)
+      keep_arg_pos = ArgumentCount(sig).size() - 1;
+    for (SignatureStream ss(sig); !ss.is_done(); ss.next()) {
+      BasicType bt = ss.type();
+      size_t this_arg_pos = buffer.size();
+      if (ss.at_return_type()) {
+        buffer.put(')');
+      }
+      if (arg_pos == keep_arg_pos) {
+        buffer.write((char*) ss.raw_bytes(),
+                     (int)   ss.raw_length());
+      } else if (bt == T_OBJECT || bt == T_ARRAY) {
+        buffer.write(OBJ_SIG, OBJ_SIG_LEN);
+      } else {
+        if (is_subword_type(bt))
+          bt = T_INT;
+        buffer.put(type2char(bt));
+      }
+      arg_pos++;
+    }
+    const char* sigstr =       buffer.base();
+    int         siglen = (int) buffer.size();
+    bsig = SymbolTable::new_symbol(sigstr, siglen, THREAD);
+  }
+  assert(is_basic_type_signature(bsig) ||
+         // detune assert in case the injected argument is not a basic type:
+         keep_last_arg, "");
+  return bsig;
+}
+
+void MethodHandles::print_as_basic_type_signature_on(outputStream* st,
+                                                     Symbol* sig,
+                                                     bool keep_arrays,
+                                                     bool keep_basic_names) {
+  st = st ? st : tty;
+  int len  = sig->utf8_length();
+  int array = 0;
+  bool prev_type = false;
+  for (int i = 0; i < len; i++) {
+    char ch = sig->byte_at(i);
+    switch (ch) {
+    case '(': case ')':
+      prev_type = false;
+      st->put(ch);
+      continue;
+    case '[':
+      if (!keep_basic_names && keep_arrays)
+        st->put(ch);
+      array++;
+      continue;
+    case 'L':
+      {
+        if (prev_type)  st->put(',');
+        int start = i+1, slash = start;
+        while (++i < len && (ch = sig->byte_at(i)) != ';') {
+          if (ch == '/' || ch == '.' || ch == '$')  slash = i+1;
+        }
+        if (slash < i)  start = slash;
+        if (!keep_basic_names) {
+          st->put('L');
+        } else {
+          for (int j = start; j < i; j++)
+            st->put(sig->byte_at(j));
+          prev_type = true;
+        }
+        break;
+      }
+    default:
+      {
+        if (array && char2type(ch) != T_ILLEGAL && !keep_arrays) {
+          ch = '[';
+          array = 0;
+        }
+        if (prev_type)  st->put(',');
+        const char* n = NULL;
+        if (keep_basic_names)
+          n = type2name(char2type(ch));
+        if (n == NULL) {
+          // unknown letter, or we don't want to know its name
+          st->put(ch);
+        } else {
+          st->print(n);
+          prev_type = true;
+        }
+        break;
+      }
+    }
+    // Switch break goes here to take care of array suffix:
+    if (prev_type) {
+      while (array > 0) {
+        st->print("[]");
+        --array;
+      }
+    }
+    array = 0;
+  }
+}
+
+
+
+static oop object_java_mirror() {
+  return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
+}
+
+static oop field_name_or_null(Symbol* s) {
+  if (s == NULL)  return NULL;
+  return StringTable::lookup(s);
+}
+
+static oop field_signature_type_or_null(Symbol* s) {
+  if (s == NULL)  return NULL;
+  BasicType bt = FieldType::basic_type(s);
+  if (is_java_primitive(bt)) {
+    assert(s->utf8_length() == 1, "");
+    return java_lang_Class::primitive_mirror(bt);
+  }
+  // Here are some more short cuts for common types.
+  // They are optional, since reference types can be resolved lazily.
+  if (bt == T_OBJECT) {
+    if (s == vmSymbols::object_signature()) {
+      return object_java_mirror();
+    } else if (s == vmSymbols::class_signature()) {
+      return Klass::cast(SystemDictionary::Class_klass())->java_mirror();
+    } else if (s == vmSymbols::string_signature()) {
+      return Klass::cast(SystemDictionary::String_klass())->java_mirror();
+    }
+  }
+  return NULL;
+}
+
 // An unresolved member name is a mere symbolic reference.
 // Resolving it plants a vmtarget/vmindex in it,
 // which refers dirctly to JVM internals.
-void MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
+Handle MethodHandles::resolve_MemberName(Handle mname, TRAPS) {
+  Handle empty;
   assert(java_lang_invoke_MemberName::is_instance(mname()), "");
-#ifdef ASSERT
-  // If this assert throws, renegotiate the sentinel value used by the Java code,
-  // so that it is distinct from any valid vtable index value, and any special
-  // values defined in methodOopDesc::VtableIndexFlag.
-  // The point of the slop is to give the Java code and the JVM some room
-  // to independently specify sentinel values.
-  const int sentinel_slop  = 10;
-  const int sentinel_limit = methodOopDesc::highest_unused_vtable_index_value - sentinel_slop;
-  assert(VM_INDEX_UNINITIALIZED < sentinel_limit, "Java sentinel != JVM sentinels");
-#endif
-  if (java_lang_invoke_MemberName::vmindex(mname()) != VM_INDEX_UNINITIALIZED)
-    return;  // already resolved
+
+  if (java_lang_invoke_MemberName::vmtarget(mname()) != NULL) {
+    // Already resolved.
+    DEBUG_ONLY(int vmindex = java_lang_invoke_MemberName::vmindex(mname()));
+    assert(vmindex >= methodOopDesc::nonvirtual_vtable_index, "");
+    return mname;
+  }
+
   Handle defc_oop(THREAD, java_lang_invoke_MemberName::clazz(mname()));
   Handle name_str(THREAD, java_lang_invoke_MemberName::name( mname()));
   Handle type_str(THREAD, java_lang_invoke_MemberName::type( mname()));
   int    flags    =       java_lang_invoke_MemberName::flags(mname());
+  int    ref_kind =       (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
+  if (!ref_kind_is_valid(ref_kind)) {
+    THROW_MSG_(vmSymbols::java_lang_InternalError(), "obsolete MemberName format", empty);
+  }
+
+  DEBUG_ONLY(int old_vmindex);
+  assert((old_vmindex = java_lang_invoke_MemberName::vmindex(mname())) == 0, "clean input");
 
   if (defc_oop.is_null() || name_str.is_null() || type_str.is_null()) {
-    THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve");
+    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "nothing to resolve", empty);
   }
 
   instanceKlassHandle defc;
   {
     klassOop defc_klassOop = java_lang_Class::as_klassOop(defc_oop());
-    if (defc_klassOop == NULL)  return;  // a primitive; no resolution possible
+    if (defc_klassOop == NULL)  return empty;  // a primitive; no resolution possible
     if (!Klass::cast(defc_klassOop)->oop_is_instance()) {
-      if (!Klass::cast(defc_klassOop)->oop_is_array())  return;
+      if (!Klass::cast(defc_klassOop)->oop_is_array())  return empty;
       defc_klassOop = SystemDictionary::Object_klass();
     }
     defc = instanceKlassHandle(THREAD, defc_klassOop);
   }
   if (defc.is_null()) {
-    THROW_MSG(vmSymbols::java_lang_InternalError(), "primitive class");
+    THROW_MSG_(vmSymbols::java_lang_InternalError(), "primitive class", empty);
   }
-  defc->link_class(CHECK);  // possible safepoint
+  defc->link_class(CHECK_(empty));  // possible safepoint
 
   // convert the external string name to an internal symbol
   TempNewSymbol name = java_lang_String::as_symbol_or_null(name_str());
-  if (name == NULL)  return;  // no such name
+  if (name == NULL)  return empty;  // no such name
   if (name == vmSymbols::class_initializer_name())
-    return; // illegal name
+    return empty; // illegal name
 
-  Handle polymorphic_method_type;
-  bool polymorphic_signature = false;
+  vmIntrinsics::ID mh_invoke_id = vmIntrinsics::_none;
   if ((flags & ALL_KINDS) == IS_METHOD &&
-      (defc() == SystemDictionary::MethodHandle_klass() &&
-       methodOopDesc::is_method_handle_invoke_name(name))) {
-    polymorphic_signature = true;
+      (defc() == SystemDictionary::MethodHandle_klass()) &&
+      (ref_kind == JVM_REF_invokeVirtual ||
+       ref_kind == JVM_REF_invokeSpecial ||
+       // static invocation mode is required for _linkToVirtual, etc.:
+       ref_kind == JVM_REF_invokeStatic)) {
+    vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
+    if (iid != vmIntrinsics::_none &&
+        ((ref_kind == JVM_REF_invokeStatic) == is_signature_polymorphic_static(iid))) {
+      // Virtual methods invoke and invokeExact, plus internal invokers like _invokeBasic.
+      // For a static reference it could an internal linkage routine like _linkToVirtual, etc.
+      mh_invoke_id = iid;
+    }
   }
 
   // convert the external string or reflective type to an internal signature
-  TempNewSymbol type = convert_to_signature(type_str(), polymorphic_signature, CHECK);
-  if (java_lang_invoke_MethodType::is_instance(type_str()) && polymorphic_signature) {
-    polymorphic_method_type = type_str;  // preserve exactly
-  }
-  if (type == NULL)  return;  // no such signature exists in the VM
+  TempNewSymbol type = lookup_signature(type_str(), (mh_invoke_id != vmIntrinsics::_none), CHECK_(empty));
+  if (type == NULL)  return empty;  // no such signature exists in the VM
 
   // Time to do the lookup.
   switch (flags & ALL_KINDS) {
   case IS_METHOD:
     {
       CallInfo result;
+      bool do_dispatch = true;  // default, neutral setting
       {
-        EXCEPTION_MARK;
-        if ((flags & JVM_ACC_STATIC) != 0) {
+        assert(!HAS_PENDING_EXCEPTION, "");
+        if (ref_kind == JVM_REF_invokeStatic) {
+          //do_dispatch = false;  // no need, since statics are never dispatched
           LinkResolver::resolve_static_call(result,
                         defc, name, type, KlassHandle(), false, false, THREAD);
-        } else if (defc->is_interface()) {
+        } else if (ref_kind == JVM_REF_invokeInterface) {
           LinkResolver::resolve_interface_call(result, Handle(), defc,
                         defc, name, type, KlassHandle(), false, false, THREAD);
-        } else {
+        } else if (mh_invoke_id != vmIntrinsics::_none) {
+          assert(!is_signature_polymorphic_static(mh_invoke_id), "");
+          LinkResolver::resolve_handle_call(result,
+                        defc, name, type, KlassHandle(), THREAD);
+        } else if (ref_kind == JVM_REF_invokeSpecial) {
+          do_dispatch = false;  // force non-virtual linkage
+          LinkResolver::resolve_special_call(result,
+                        defc, name, type, KlassHandle(), false, THREAD);
+        } else if (ref_kind == JVM_REF_invokeVirtual) {
           LinkResolver::resolve_virtual_call(result, Handle(), defc,
                         defc, name, type, KlassHandle(), false, false, THREAD);
+        } else {
+          assert(false, err_msg("ref_kind=%d", ref_kind));
         }
         if (HAS_PENDING_EXCEPTION) {
-          CLEAR_PENDING_EXCEPTION;
-          break;  // go to second chance
+          return empty;
         }
       }
-      methodHandle m = result.resolved_method();
-      oop vmtarget = NULL;
-      int vmindex = methodOopDesc::nonvirtual_vtable_index;
-      if (defc->is_interface()) {
-        vmindex = klassItable::compute_itable_index(m());
-        assert(vmindex >= 0, "");
-      } else if (result.has_vtable_index()) {
-        vmindex = result.vtable_index();
-        assert(vmindex >= 0, "");
-      }
-      assert(vmindex != VM_INDEX_UNINITIALIZED, "");
-      if (vmindex < 0) {
-        assert(result.is_statically_bound(), "");
-        vmtarget = m();
-      } else {
-        vmtarget = result.resolved_klass()->as_klassOop();
-      }
-      int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
-      java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
-      java_lang_invoke_MemberName::set_vmindex(mname(),  vmindex);
-      java_lang_invoke_MemberName::set_modifiers(mname(), mods);
-      DEBUG_ONLY(KlassHandle junk1; int junk2);
-      assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(),
-             "properly stored for later decoding");
-      return;
+      return init_method_MemberName(mname(), result, THREAD);
     }
   case IS_CONSTRUCTOR:
     {
       CallInfo result;
       {
-        EXCEPTION_MARK;
+        assert(!HAS_PENDING_EXCEPTION, "");
         if (name == vmSymbols::object_initializer_name()) {
           LinkResolver::resolve_special_call(result,
                         defc, name, type, KlassHandle(), false, THREAD);
@@ -682,22 +686,11 @@
           break;                // will throw after end of switch
         }
         if (HAS_PENDING_EXCEPTION) {
-          CLEAR_PENDING_EXCEPTION;
-          return;
+          return empty;
         }
       }
       assert(result.is_statically_bound(), "");
-      methodHandle m = result.resolved_method();
-      oop vmtarget = m();
-      int vmindex  = methodOopDesc::nonvirtual_vtable_index;
-      int mods     = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
-      java_lang_invoke_MemberName::set_vmtarget(mname(), vmtarget);
-      java_lang_invoke_MemberName::set_vmindex(mname(),  vmindex);
-      java_lang_invoke_MemberName::set_modifiers(mname(), mods);
-      DEBUG_ONLY(KlassHandle junk1; int junk2);
-      assert(decode_MemberName(mname(), junk1, junk2) == result.resolved_method(),
-             "properly stored for later decoding");
-      return;
+      return init_method_MemberName(mname(), result, THREAD);
     }
   case IS_FIELD:
     {
@@ -705,54 +698,20 @@
       fieldDescriptor fd; // find_field initializes fd if found
       KlassHandle sel_klass(THREAD, instanceKlass::cast(defc())->find_field(name, type, &fd));
       // check if field exists; i.e., if a klass containing the field def has been selected
-      if (sel_klass.is_null())  return;
-      oop vmtarget = sel_klass->as_klassOop();
-      int vmindex  = fd.offset();
-      int mods     = (fd.access_flags().as_short() & JVM_RECOGNIZED_FIELD_MODIFIERS);
-      if (vmindex == VM_INDEX_UNINITIALIZED)  break;  // should not happen
-      java_lang_invoke_MemberName::set_vmtarget(mname(),  vmtarget);
-      java_lang_invoke_MemberName::set_vmindex(mname(),   vmindex);
-      java_lang_invoke_MemberName::set_modifiers(mname(), mods);
-      return;
+      if (sel_klass.is_null())  return empty;  // should not happen
+      oop type = field_signature_type_or_null(fd.signature());
+      oop name = field_name_or_null(fd.name());
+      bool is_setter = (ref_kind_is_valid(ref_kind) && ref_kind_is_setter(ref_kind));
+      mname = Handle(THREAD,
+                     init_field_MemberName(mname(), sel_klass->as_klassOop(),
+                                           fd.access_flags(), type, name, fd.offset(), is_setter));
+      return mname;
     }
   default:
-    THROW_MSG(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format");
+    THROW_MSG_(vmSymbols::java_lang_InternalError(), "unrecognized MemberName format", empty);
   }
 
-  // Second chance.
-  if (polymorphic_method_type.not_null()) {
-    // Look on a non-null class loader.
-    Handle cur_class_loader;
-    const int nptypes = java_lang_invoke_MethodType::ptype_count(polymorphic_method_type());
-    for (int i = 0; i <= nptypes; i++) {
-      oop type_mirror;
-      if (i < nptypes)  type_mirror = java_lang_invoke_MethodType::ptype(polymorphic_method_type(), i);
-      else              type_mirror = java_lang_invoke_MethodType::rtype(polymorphic_method_type());
-      klassOop example_type = java_lang_Class::as_klassOop(type_mirror);
-      if (example_type == NULL)  continue;
-      oop class_loader = Klass::cast(example_type)->class_loader();
-      if (class_loader == NULL || class_loader == cur_class_loader())  continue;
-      cur_class_loader = Handle(THREAD, class_loader);
-      methodOop m = SystemDictionary::find_method_handle_invoke(name,
-                                                                type,
-                                                                KlassHandle(THREAD, example_type),
-                                                                THREAD);
-      if (HAS_PENDING_EXCEPTION) {
-        CLEAR_PENDING_EXCEPTION;
-        m = NULL;
-        // try again with a different class loader...
-      }
-      if (m != NULL &&
-          m->is_method_handle_invoke() &&
-          java_lang_invoke_MethodType::equals(polymorphic_method_type(), m->method_handle_type())) {
-        int mods = (m->access_flags().as_short() & JVM_RECOGNIZED_METHOD_MODIFIERS);
-        java_lang_invoke_MemberName::set_vmtarget(mname(),  m);
-        java_lang_invoke_MemberName::set_vmindex(mname(),   m->vtable_index());
-        java_lang_invoke_MemberName::set_modifiers(mname(), mods);
-        return;
-      }
-    }
-  }
+  return empty;
 }
 
 // Conversely, a member name which is only initialized from JVM internals
@@ -763,7 +722,7 @@
   assert(java_lang_invoke_MemberName::is_instance(mname()), "");
   oop vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
   int vmindex  = java_lang_invoke_MemberName::vmindex(mname());
-  if (vmtarget == NULL || vmindex == VM_INDEX_UNINITIALIZED) {
+  if (vmtarget == NULL) {
     THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), "nothing to expand");
   }
 
@@ -784,14 +743,12 @@
   case IS_METHOD:
   case IS_CONSTRUCTOR:
     {
-      KlassHandle receiver_limit; int decode_flags = 0;
-      methodHandle m = decode_vmtarget(vmtarget, vmindex, NULL, receiver_limit, decode_flags);
+      assert(vmtarget->is_method(), "method or constructor vmtarget is methodOop");
+      methodHandle m(THREAD, methodOop(vmtarget));
+      DEBUG_ONLY(vmtarget = NULL);  // safety
       if (m.is_null())  break;
       if (!have_defc) {
         klassOop defc = m->method_holder();
-        if (receiver_limit.not_null() && receiver_limit() != defc
-            && Klass::cast(receiver_limit())->is_subtype_of(defc))
-          defc = receiver_limit();
         java_lang_invoke_MemberName::set_clazz(mname(), Klass::cast(defc)->java_mirror());
       }
       if (!have_name) {
@@ -808,9 +765,10 @@
   case IS_FIELD:
     {
       // This is taken from LinkResolver::resolve_field, sans access checks.
-      if (!vmtarget->is_klass())  break;
+      assert(vmtarget->is_klass(), "field vmtarget is klassOop");
       if (!Klass::cast((klassOop) vmtarget)->oop_is_instance())  break;
       instanceKlassHandle defc(THREAD, (klassOop) vmtarget);
+      DEBUG_ONLY(vmtarget = NULL);  // safety
       bool is_static = ((flags & JVM_ACC_STATIC) != 0);
       fieldDescriptor fd; // find_field initializes fd if found
       if (!defc->find_field_from_offset(vmindex, is_static, &fd))
@@ -824,7 +782,11 @@
         java_lang_invoke_MemberName::set_name(mname(), name());
       }
       if (!have_type) {
-        Handle type = java_lang_String::create_from_symbol(fd.signature(), CHECK);
+        // If it is a primitive field type, don't mess with short strings like "I".
+        Handle type = field_signature_type_or_null(fd.signature());
+        if (type.is_null()) {
+          java_lang_String::create_from_symbol(fd.signature(), CHECK);
+        }
         java_lang_invoke_MemberName::set_type(mname(), type());
       }
       return;
@@ -882,7 +844,13 @@
         oop result = results->obj_at(rfill++);
         if (!java_lang_invoke_MemberName::is_instance(result))
           return -99;  // caller bug!
-        MethodHandles::init_MemberName(result, st.klass()->as_klassOop(), st.access_flags(), st.offset());
+        oop type = field_signature_type_or_null(st.signature());
+        oop name = field_name_or_null(st.name());
+        oop saved = MethodHandles::init_field_MemberName(result, st.klass()->as_klassOop(),
+                                                         st.access_flags(), type, name,
+                                                         st.offset());
+        if (saved != result)
+          results->obj_at_put(rfill-1, saved);  // show saved instance to user
       } else if (++overflow >= overflow_limit) {
         match_flags = 0; break; // got tired of looking at overflow
       }
@@ -930,7 +898,9 @@
         oop result = results->obj_at(rfill++);
         if (!java_lang_invoke_MemberName::is_instance(result))
           return -99;  // caller bug!
-        MethodHandles::init_MemberName(result, m, true);
+        oop saved = MethodHandles::init_method_MemberName(result, m, true, NULL);
+        if (saved != result)
+          results->obj_at_put(rfill-1, saved);  // show saved instance to user
       } else if (++overflow >= overflow_limit) {
         match_flags = 0; break; // got tired of looking at overflow
       }
@@ -941,1925 +911,16 @@
   return rfill + overflow;
 }
 
-
-// Decode this java.lang.Class object into an instanceKlass, if possible.
-// Throw IAE if not
-instanceKlassHandle MethodHandles::resolve_instance_klass(oop java_mirror_oop, TRAPS) {
-  instanceKlassHandle empty;
-  klassOop caller = NULL;
-  if (java_lang_Class::is_instance(java_mirror_oop)) {
-    caller = java_lang_Class::as_klassOop(java_mirror_oop);
-  }
-  if (caller == NULL || !Klass::cast(caller)->oop_is_instance()) {
-    THROW_MSG_(vmSymbols::java_lang_IllegalArgumentException(), "not a class", empty);
-  }
-  return instanceKlassHandle(THREAD, caller);
-}
-
-
-
-// Decode the vmtarget field of a method handle.
-// Sanitize out methodOops, klassOops, and any other non-Java data.
-// This is for debugging and reflection.
-oop MethodHandles::encode_target(Handle mh, int format, TRAPS) {
-  assert(java_lang_invoke_MethodHandle::is_instance(mh()), "must be a MH");
-  if (format == ETF_FORCE_DIRECT_HANDLE ||
-      format == ETF_COMPILE_DIRECT_HANDLE) {
-    // Internal function for stress testing.
-    Handle mt = java_lang_invoke_MethodHandle::type(mh());
-    int invocation_count = 10000;
-    TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK_NULL);
-    bool omit_receiver_argument = true;
-    MethodHandleCompiler mhc(mh, vmSymbols::invoke_name(), signature, invocation_count, omit_receiver_argument, CHECK_NULL);
-    methodHandle m = mhc.compile(CHECK_NULL);
-    if (StressMethodHandleWalk && Verbose || PrintMiscellaneous) {
-      tty->print_cr("MethodHandleNatives.getTarget(%s)",
-                    format == ETF_FORCE_DIRECT_HANDLE ? "FORCE_DIRECT" : "COMPILE_DIRECT");
-      if (Verbose) {
-        m->print_codes();
-      }
-    }
-    if (StressMethodHandleWalk) {
-      InterpreterOopMap mask;
-      OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask);
-    }
-    if ((format == ETF_COMPILE_DIRECT_HANDLE ||
-         CompilationPolicy::must_be_compiled(m))
-        && !instanceKlass::cast(m->method_holder())->is_not_initialized()
-        && CompilationPolicy::can_be_compiled(m)) {
-      // Force compilation
-      CompileBroker::compile_method(m, InvocationEntryBci,
-                                    CompilationPolicy::policy()->initial_compile_level(),
-                                    methodHandle(), 0, "MethodHandleNatives.getTarget",
-                                    CHECK_NULL);
-    }
-    // Now wrap m in a DirectMethodHandle.
-    instanceKlassHandle dmh_klass(THREAD, SystemDictionary::DirectMethodHandle_klass());
-    Handle dmh = dmh_klass->allocate_instance_handle(CHECK_NULL);
-    JavaValue ignore_result(T_VOID);
-    Symbol* init_name = vmSymbols::object_initializer_name();
-    Symbol* init_sig  = vmSymbols::notifyGenericMethodType_signature();
-    JavaCalls::call_special(&ignore_result, dmh,
-                            SystemDictionaryHandles::MethodHandle_klass(), init_name, init_sig,
-                            java_lang_invoke_MethodHandle::type(mh()), CHECK_NULL);
-    MethodHandles::init_DirectMethodHandle(dmh, m, false, CHECK_NULL);
-    return dmh();
-  }
-  if (format == ETF_HANDLE_OR_METHOD_NAME) {
-    oop target = java_lang_invoke_MethodHandle::vmtarget(mh());
-    if (target == NULL) {
-      return NULL;                // unformed MH
-    }
-    klassOop tklass = target->klass();
-    if (Klass::cast(tklass)->is_subclass_of(SystemDictionary::Object_klass())) {
-      return target;              // target is another MH (or something else?)
-    }
-  }
-  if (format == ETF_DIRECT_HANDLE) {
-    oop target = mh();
-    for (;;) {
-      if (target->klass() == SystemDictionary::DirectMethodHandle_klass()) {
-        return target;
-      }
-      if (!java_lang_invoke_MethodHandle::is_instance(target)){
-        return NULL;                // unformed MH
-      }
-      target = java_lang_invoke_MethodHandle::vmtarget(target);
-    }
-  }
-  // cases of metadata in MH.vmtarget:
-  // - AMH can have methodOop for static invoke with bound receiver
-  // - DMH can have methodOop for static invoke (on variable receiver)
-  // - DMH can have klassOop for dispatched (non-static) invoke
-  KlassHandle receiver_limit; int decode_flags = 0;
-  methodHandle m = decode_MethodHandle(mh(), receiver_limit, decode_flags);
-  if (m.is_null())  return NULL;
-  switch (format) {
-  case ETF_REFLECT_METHOD:
-    // same as jni_ToReflectedMethod:
-    if (m->is_initializer()) {
-      return Reflection::new_constructor(m, THREAD);
-    } else {
-      return Reflection::new_method(m, UseNewReflection, false, THREAD);
-    }
-
-  case ETF_HANDLE_OR_METHOD_NAME:   // method, not handle
-  case ETF_METHOD_NAME:
-    {
-      if (SystemDictionary::MemberName_klass() == NULL)  break;
-      instanceKlassHandle mname_klass(THREAD, SystemDictionary::MemberName_klass());
-      mname_klass->initialize(CHECK_NULL);
-      Handle mname = mname_klass->allocate_instance_handle(CHECK_NULL);  // possible safepoint
-      java_lang_invoke_MemberName::set_vmindex(mname(), VM_INDEX_UNINITIALIZED);
-      bool do_dispatch = ((decode_flags & MethodHandles::_dmf_does_dispatch) != 0);
-      init_MemberName(mname(), m(), do_dispatch);
-      expand_MemberName(mname, 0, CHECK_NULL);
-      return mname();
-    }
-  }
-
-  // Unknown format code.
-  char msg[50];
-  jio_snprintf(msg, sizeof(msg), "unknown getTarget format=%d", format);
-  THROW_MSG_NULL(vmSymbols::java_lang_IllegalArgumentException(), msg);
-}
-
-static const char* always_null_names[] = {
-  "java/lang/Void",
-  "java/lang/Null",
-  //"java/lang/Nothing",
-  "sun/dyn/empty/Empty",
-  "sun/invoke/empty/Empty",
-  NULL
-};
-
-static bool is_always_null_type(klassOop klass) {
-  if (klass == NULL)  return false;  // safety
-  if (!Klass::cast(klass)->oop_is_instance())  return false;
-  instanceKlass* ik = instanceKlass::cast(klass);
-  // Must be on the boot class path:
-  if (ik->class_loader() != NULL)  return false;
-  // Check the name.
-  Symbol* name = ik->name();
-  for (int i = 0; ; i++) {
-    const char* test_name = always_null_names[i];
-    if (test_name == NULL)  break;
-    if (name->equals(test_name))
-      return true;
-  }
-  return false;
-}
-
-bool MethodHandles::class_cast_needed(klassOop src, klassOop dst) {
-  if (dst == NULL)  return true;
-  if (src == NULL)  return (dst != SystemDictionary::Object_klass());
-  if (src == dst || dst == SystemDictionary::Object_klass())
-    return false;                               // quickest checks
-  Klass* srck = Klass::cast(src);
-  Klass* dstk = Klass::cast(dst);
-  if (dstk->is_interface()) {
-    // interface receivers can safely be viewed as untyped,
-    // because interface calls always include a dynamic check
-    //dstk = Klass::cast(SystemDictionary::Object_klass());
-    return false;
-  }
-  if (srck->is_interface()) {
-    // interface arguments must be viewed as untyped
-    //srck = Klass::cast(SystemDictionary::Object_klass());
-    return true;
-  }
-  if (is_always_null_type(src)) {
-    // some source types are known to be never instantiated;
-    // they represent references which are always null
-    // such null references never fail to convert safely
-    return false;
-  }
-  return !srck->is_subclass_of(dstk->as_klassOop());
-}
-
-static oop object_java_mirror() {
-  return Klass::cast(SystemDictionary::Object_klass())->java_mirror();
-}
-
-bool MethodHandles::is_float_fixed_reinterpretation_cast(BasicType src, BasicType dst) {
-  if (src == T_FLOAT)   return dst == T_INT;
-  if (src == T_INT)     return dst == T_FLOAT;
-  if (src == T_DOUBLE)  return dst == T_LONG;
-  if (src == T_LONG)    return dst == T_DOUBLE;
-  return false;
-}
-
-bool MethodHandles::same_basic_type_for_arguments(BasicType src,
-                                                  BasicType dst,
-                                                  bool raw,
-                                                  bool for_return) {
-  if (for_return) {
-    // return values can always be forgotten:
-    if (dst == T_VOID)  return true;
-    if (src == T_VOID)  return raw && (dst == T_INT);
-    // We allow caller to receive a garbage int, which is harmless.
-    // This trick is pulled by trusted code (see VerifyType.canPassRaw).
-  }
-  assert(src != T_VOID && dst != T_VOID, "should not be here");
-  if (src == dst)  return true;
-  if (type2size[src] != type2size[dst])  return false;
-  if (src == T_OBJECT || dst == T_OBJECT)  return false;
-  if (raw)  return true;  // bitwise reinterpretation; caller guarantees safety
-  // allow reinterpretation casts for integral widening
-  if (is_subword_type(src)) { // subwords can fit in int or other subwords
-    if (dst == T_INT)         // any subword fits in an int
-      return true;
-    if (src == T_BOOLEAN)     // boolean fits in any subword
-      return is_subword_type(dst);
-    if (src == T_BYTE && dst == T_SHORT)
-      return true;            // remaining case: byte fits in short
-  }
-  // allow float/fixed reinterpretation casts
-  if (is_float_fixed_reinterpretation_cast(src, dst))
-    return true;
-  return false;
-}
-
-const char* MethodHandles::check_method_receiver(methodOop m,
-                                                 klassOop passed_recv_type) {
-  assert(!m->is_static(), "caller resp.");
-  if (passed_recv_type == NULL)
-    return "receiver type is primitive";
-  if (class_cast_needed(passed_recv_type, m->method_holder())) {
-    Klass* formal = Klass::cast(m->method_holder());
-    return SharedRuntime::generate_class_cast_message("receiver type",
-                                                      formal->external_name());
-  }
-  return NULL;                  // checks passed
-}
-
-// Verify that m's signature can be called type-safely by a method handle
-// of the given method type 'mtype'.
-// It takes a TRAPS argument because it must perform symbol lookups.
-void MethodHandles::verify_method_signature(methodHandle m,
-                                            Handle mtype,
-                                            int first_ptype_pos,
-                                            KlassHandle insert_ptype,
-                                            TRAPS) {
-  Handle mhi_type;
-  if (m->is_method_handle_invoke()) {
-    // use this more exact typing instead of the symbolic signature:
-    mhi_type = Handle(THREAD, m->method_handle_type());
-  }
-  objArrayHandle ptypes(THREAD, java_lang_invoke_MethodType::ptypes(mtype()));
-  int pnum = first_ptype_pos;
-  int pmax = ptypes->length();
-  int anum = 0;                 // method argument
-  const char* err = NULL;
-  ResourceMark rm(THREAD);
-  for (SignatureStream ss(m->signature()); !ss.is_done(); ss.next()) {
-    oop ptype_oop = NULL;
-    if (ss.at_return_type()) {
-      if (pnum != pmax)
-        { err = "too many arguments"; break; }
-      ptype_oop = java_lang_invoke_MethodType::rtype(mtype());
-    } else {
-      if (pnum >= pmax)
-        { err = "not enough arguments"; break; }
-      if (pnum >= 0)
-        ptype_oop = ptypes->obj_at(pnum);
-      else if (insert_ptype.is_null())
-        ptype_oop = NULL;
-      else
-        ptype_oop = insert_ptype->java_mirror();
-      pnum += 1;
-      anum += 1;
-    }
-    KlassHandle pklass;
-    BasicType   ptype = T_OBJECT;
-    bool   have_ptype = false;
-    // missing ptype_oop does not match any non-reference; use Object to report the error
-    pklass = SystemDictionaryHandles::Object_klass();
-    if (ptype_oop != NULL) {
-      have_ptype = true;
-      klassOop pklass_oop = NULL;
-      ptype = java_lang_Class::as_BasicType(ptype_oop, &pklass_oop);
-      pklass = KlassHandle(THREAD, pklass_oop);
-    }
-    ptype_oop = NULL; //done with this
-    KlassHandle aklass;
-    BasicType   atype = ss.type();
-    if (atype == T_ARRAY)  atype = T_OBJECT; // fold all refs to T_OBJECT
-    if (atype == T_OBJECT) {
-      if (!have_ptype) {
-        // null matches any reference
-        continue;
-      }
-      if (mhi_type.is_null()) {
-        // If we fail to resolve types at this point, we will usually throw an error.
-        TempNewSymbol name = ss.as_symbol_or_null();
-        if (name != NULL) {
-          instanceKlass* mk = instanceKlass::cast(m->method_holder());
-          Handle loader(THREAD, mk->class_loader());
-          Handle domain(THREAD, mk->protection_domain());
-          klassOop aklass_oop = SystemDictionary::resolve_or_null(name, loader, domain, CHECK);
-          if (aklass_oop != NULL)
-            aklass = KlassHandle(THREAD, aklass_oop);
-          if (aklass.is_null() &&
-              pklass.not_null() &&
-              loader.is_null() &&
-              pklass->name() == name)
-            // accept name equivalence here, since that's the best we can do
-            aklass = pklass;
-        }
-      } else {
-        // for method handle invokers we don't look at the name in the signature
-        oop atype_oop;
-        if (ss.at_return_type())
-          atype_oop = java_lang_invoke_MethodType::rtype(mhi_type());
-        else
-          atype_oop = java_lang_invoke_MethodType::ptype(mhi_type(), anum-1);
-        klassOop aklass_oop = NULL;
-        atype = java_lang_Class::as_BasicType(atype_oop, &aklass_oop);
-        aklass = KlassHandle(THREAD, aklass_oop);
-      }
-    }
-    if (!ss.at_return_type()) {
-      err = check_argument_type_change(ptype, pklass(), atype, aklass(), anum);
-    } else {
-      err = check_return_type_change(atype, aklass(), ptype, pklass()); // note reversal!
-    }
-    if (err != NULL)  break;
-  }
-
-  if (err != NULL) {
-#ifndef PRODUCT
-    if (PrintMiscellaneous && (Verbose || WizardMode)) {
-      tty->print("*** verify_method_signature failed: ");
-      java_lang_invoke_MethodType::print_signature(mtype(), tty);
-      tty->cr();
-      tty->print_cr("    first_ptype_pos = %d, insert_ptype = "UINTX_FORMAT, first_ptype_pos, insert_ptype());
-      tty->print("    Failing method: ");
-      m->print();
-    }
-#endif //PRODUCT
-    THROW_MSG(vmSymbols::java_lang_InternalError(), err);
-  }
-}
-
-// Main routine for verifying the MethodHandle.type of a proposed
-// direct or bound-direct method handle.
-void MethodHandles::verify_method_type(methodHandle m,
-                                       Handle mtype,
-                                       bool has_bound_recv,
-                                       KlassHandle bound_recv_type,
-                                       TRAPS) {
-  bool m_needs_receiver = !m->is_static();
-
-  const char* err = NULL;
-
-  int first_ptype_pos = m_needs_receiver ? 1 : 0;
-  if (has_bound_recv) {
-    first_ptype_pos -= 1;  // ptypes do not include the bound argument; start earlier in them
-    if (m_needs_receiver && bound_recv_type.is_null())
-      { err = "bound receiver is not an object"; goto die; }
-  }
-
-  if (m_needs_receiver && err == NULL) {
-    objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(mtype());
-    if (ptypes->length() < first_ptype_pos)
-      { err = "receiver argument is missing"; goto die; }
-    if (has_bound_recv)
-      err = check_method_receiver(m(), bound_recv_type->as_klassOop());
-    else
-      err = check_method_receiver(m(), java_lang_Class::as_klassOop(ptypes->obj_at(first_ptype_pos-1)));
-    if (err != NULL)  goto die;
-  }
-
-  // Check the other arguments for mistypes.
-  verify_method_signature(m, mtype, first_ptype_pos, bound_recv_type, CHECK);
-  return;
-
- die:
-  THROW_MSG(vmSymbols::java_lang_InternalError(), err);
-}
-
-void MethodHandles::verify_vmslots(Handle mh, TRAPS) {
-  // Verify vmslots.
-  int check_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(mh()));
-  if (java_lang_invoke_MethodHandle::vmslots(mh()) != check_slots) {
-    THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH");
-  }
-}
-
-void MethodHandles::verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS) {
-  // Verify that argslot points at the given argnum.
-  int check_slot = argument_slot(java_lang_invoke_MethodHandle::type(mh()), argnum);
-  if (argslot != check_slot || argslot < 0) {
-    ResourceMark rm;
-    const char* fmt = "for argnum of %d, vmargslot is %d, should be %d";
-    size_t msglen = strlen(fmt) + 3*11 + 1;
-    char* msg = NEW_RESOURCE_ARRAY(char, msglen);
-    jio_snprintf(msg, msglen, fmt, argnum, argslot, check_slot);
-    THROW_MSG(vmSymbols::java_lang_InternalError(), msg);
-  }
-}
-
-// Verify the correspondence between two method types.
-// Apart from the advertised changes, caller method type X must
-// be able to invoke the callee method Y type with no violations
-// of type integrity.
-// Return NULL if all is well, else a short error message.
-const char* MethodHandles::check_method_type_change(oop src_mtype, int src_beg, int src_end,
-                                                    int insert_argnum, oop insert_type,
-                                                    int change_argnum, oop change_type,
-                                                    int delete_argnum,
-                                                    oop dst_mtype, int dst_beg, int dst_end,
-                                                    bool raw) {
-  objArrayOop src_ptypes = java_lang_invoke_MethodType::ptypes(src_mtype);
-  objArrayOop dst_ptypes = java_lang_invoke_MethodType::ptypes(dst_mtype);
-
-  int src_max = src_ptypes->length();
-  int dst_max = dst_ptypes->length();
-
-  if (src_end == -1)  src_end = src_max;
-  if (dst_end == -1)  dst_end = dst_max;
-
-  assert(0 <= src_beg && src_beg <= src_end && src_end <= src_max, "oob");
-  assert(0 <= dst_beg && dst_beg <= dst_end && dst_end <= dst_max, "oob");
-
-  // pending actions; set to -1 when done:
-  int ins_idx = insert_argnum, chg_idx = change_argnum, del_idx = delete_argnum;
-
-  const char* err = NULL;
-
-  // Walk along each array of parameter types, including a virtual
-  // NULL end marker at the end of each.
-  for (int src_idx = src_beg, dst_idx = dst_beg;
-       (src_idx <= src_end && dst_idx <= dst_end);
-       src_idx++, dst_idx++) {
-    oop src_type = (src_idx == src_end) ? oop(NULL) : src_ptypes->obj_at(src_idx);
-    oop dst_type = (dst_idx == dst_end) ? oop(NULL) : dst_ptypes->obj_at(dst_idx);
-    bool fix_null_src_type = false;
-
-    // Perform requested edits.
-    if (ins_idx == src_idx) {
-      // note that the inserted guy is never affected by a change or deletion
-      ins_idx = -1;
-      src_type = insert_type;
-      fix_null_src_type = true;
-      --src_idx;                // back up to process src type on next loop
-      src_idx = src_end;
-    } else {
-      // note that the changed guy can be immediately deleted
-      if (chg_idx == src_idx) {
-        chg_idx = -1;
-        assert(src_idx < src_end, "oob");
-        src_type = change_type;
-        fix_null_src_type = true;
-      }
-      if (del_idx == src_idx) {
-        del_idx = -1;
-        assert(src_idx < src_end, "oob");
-        --dst_idx;
-        continue;               // rerun loop after skipping this position
-      }
-    }
-
-    if (src_type == NULL && fix_null_src_type)
-      // explicit null in this case matches any dest reference
-      src_type = (java_lang_Class::is_primitive(dst_type) ? object_java_mirror() : dst_type);
-
-    // Compare the two argument types.
-    if (src_type != dst_type) {
-      if (src_type == NULL)  return "not enough arguments";
-      if (dst_type == NULL)  return "too many arguments";
-      err = check_argument_type_change(src_type, dst_type, dst_idx, raw);
-      if (err != NULL)  return err;
-    }
-  }
-
-  // Now compare return types also.
-  oop src_rtype = java_lang_invoke_MethodType::rtype(src_mtype);
-  oop dst_rtype = java_lang_invoke_MethodType::rtype(dst_mtype);
-  if (src_rtype != dst_rtype) {
-    err = check_return_type_change(dst_rtype, src_rtype, raw); // note reversal!
-    if (err != NULL)  return err;
-  }
-
-  assert(err == NULL, "");
-  return NULL;  // all is well
-}
-
-
-const char* MethodHandles::check_argument_type_change(BasicType src_type,
-                                                      klassOop src_klass,
-                                                      BasicType dst_type,
-                                                      klassOop dst_klass,
-                                                      int argnum,
-                                                      bool raw) {
-  const char* err = NULL;
-  const bool for_return = (argnum < 0);
-
-  // just in case:
-  if (src_type == T_ARRAY)  src_type = T_OBJECT;
-  if (dst_type == T_ARRAY)  dst_type = T_OBJECT;
-
-  // Produce some nice messages if VerifyMethodHandles is turned on:
-  if (!same_basic_type_for_arguments(src_type, dst_type, raw, for_return)) {
-    if (src_type == T_OBJECT) {
-      if (raw && is_java_primitive(dst_type))
-        return NULL;    // ref-to-prim discards ref and returns zero
-      err = (!for_return
-             ? "type mismatch: passing a %s for method argument #%d, which expects primitive %s"
-             : "type mismatch: returning a %s, but caller expects primitive %s");
-    } else if (dst_type == T_OBJECT) {
-      err = (!for_return
-             ? "type mismatch: passing a primitive %s for method argument #%d, which expects %s"
-             : "type mismatch: returning a primitive %s, but caller expects %s");
-    } else {
-      err = (!for_return
-             ? "type mismatch: passing a %s for method argument #%d, which expects %s"
-             : "type mismatch: returning a %s, but caller expects %s");
-    }
-  } else if (src_type == T_OBJECT && dst_type == T_OBJECT &&
-             class_cast_needed(src_klass, dst_klass)) {
-    if (!class_cast_needed(dst_klass, src_klass)) {
-      if (raw)
-        return NULL;    // reverse cast is OK; the MH target is trusted to enforce it
-      err = (!for_return
-             ? "cast required: passing a %s for method argument #%d, which expects %s"
-             : "cast required: returning a %s, but caller expects %s");
-    } else {
-      err = (!for_return
-             ? "reference mismatch: passing a %s for method argument #%d, which expects %s"
-             : "reference mismatch: returning a %s, but caller expects %s");
-    }
-  } else {
-    // passed the obstacle course
-    return NULL;
-  }
-
-  // format, format, format
-  const char* src_name = type2name(src_type);
-  const char* dst_name = type2name(dst_type);
-  if (src_name == NULL)  src_name = "unknown type";
-  if (dst_name == NULL)  dst_name = "unknown type";
-  if (src_type == T_OBJECT)
-    src_name = (src_klass != NULL) ? Klass::cast(src_klass)->external_name() : "an unresolved class";
-  if (dst_type == T_OBJECT)
-    dst_name = (dst_klass != NULL) ? Klass::cast(dst_klass)->external_name() : "an unresolved class";
-
-  size_t msglen = strlen(err) + strlen(src_name) + strlen(dst_name) + (argnum < 10 ? 1 : 11);
-  char* msg = NEW_RESOURCE_ARRAY(char, msglen + 1);
-  if (!for_return) {
-    assert(strstr(err, "%d") != NULL, "");
-    jio_snprintf(msg, msglen, err, src_name, argnum, dst_name);
-  } else {
-    assert(strstr(err, "%d") == NULL, "");
-    jio_snprintf(msg, msglen, err, src_name,         dst_name);
-  }
-  return msg;
-}
-
-// Compute the depth within the stack of the given argument, i.e.,
-// the combined size of arguments to the right of the given argument.
-// For the last argument (ptypes.length-1) this will be zero.
-// For the first argument (0) this will be the size of all
-// arguments but that one.  For the special number -1, this
-// will be the size of all arguments, including the first.
-// If the argument is neither -1 nor a valid argument index,
-// then return a negative number.  Otherwise, the result
-// is in the range [0..vmslots] inclusive.
-int MethodHandles::argument_slot(oop method_type, int arg) {
-  objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(method_type);
-  int argslot = 0;
-  int len = ptypes->length();
-  if (arg < -1 || arg >= len)  return -99;
-  for (int i = len-1; i > arg; i--) {
-    BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i));
-    argslot += type2size[bt];
-  }
-  assert(argument_slot_to_argnum(method_type, argslot) == arg, "inverse works");
-  return argslot;
-}
-
-// Given a slot number, return the argument number.
-int MethodHandles::argument_slot_to_argnum(oop method_type, int query_argslot) {
-  objArrayOop ptypes = java_lang_invoke_MethodType::ptypes(method_type);
-  int argslot = 0;
-  int len = ptypes->length();
-  for (int i = len-1; i >= 0; i--) {
-    if (query_argslot == argslot)  return i;
-    BasicType bt = java_lang_Class::as_BasicType(ptypes->obj_at(i));
-    argslot += type2size[bt];
-  }
-  // return pseudo-arg deepest in stack:
-  if (query_argslot == argslot)  return -1;
-  return -99;                   // oob slot, or splitting a double-slot arg
-}
-
-methodHandle MethodHandles::dispatch_decoded_method(methodHandle m,
-                                                    KlassHandle receiver_limit,
-                                                    int decode_flags,
-                                                    KlassHandle receiver_klass,
-                                                    TRAPS) {
-  assert((decode_flags & ~_DMF_DIRECT_MASK) == 0, "must be direct method reference");
-  assert((decode_flags & _dmf_has_receiver) != 0, "must have a receiver or first reference argument");
-
-  if (!m->is_static() &&
-      (receiver_klass.is_null() || !receiver_klass->is_subtype_of(m->method_holder())))
-    // given type does not match class of method, or receiver is null!
-    // caller should have checked this, but let's be extra careful...
-    return methodHandle();
-
-  if (receiver_limit.not_null() &&
-      (receiver_klass.not_null() && !receiver_klass->is_subtype_of(receiver_limit())))
-    // given type is not limited to the receiver type
-    // note that a null receiver can match any reference value, for a static method
-    return methodHandle();
-
-  if (!(decode_flags & MethodHandles::_dmf_does_dispatch)) {
-    // pre-dispatched or static method (null receiver is OK for static)
-    return m;
-
-  } else if (receiver_klass.is_null()) {
-    // null receiver value; cannot dispatch
-    return methodHandle();
-
-  } else if (!(decode_flags & MethodHandles::_dmf_from_interface)) {
-    // perform virtual dispatch
-    int vtable_index = m->vtable_index();
-    guarantee(vtable_index >= 0, "valid vtable index");
-
-    // receiver_klass might be an arrayKlassOop but all vtables start at
-    // the same place. The cast is to avoid virtual call and assertion.
-    // See also LinkResolver::runtime_resolve_virtual_method.
-    instanceKlass* inst = (instanceKlass*)Klass::cast(receiver_klass());
-    DEBUG_ONLY(inst->verify_vtable_index(vtable_index));
-    methodOop m_oop = inst->method_at_vtable(vtable_index);
-    return methodHandle(THREAD, m_oop);
-
-  } else {
-    // perform interface dispatch
-    int itable_index = klassItable::compute_itable_index(m());
-    guarantee(itable_index >= 0, "valid itable index");
-    instanceKlass* inst = instanceKlass::cast(receiver_klass());
-    methodOop m_oop = inst->method_at_itable(m->method_holder(), itable_index, THREAD);
-    return methodHandle(THREAD, m_oop);
-  }
-}
-
-void MethodHandles::verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS) {
-  // Verify type.
-  Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
-  verify_method_type(m, mtype, false, KlassHandle(), CHECK);
-
-  // Verify vmslots.
-  if (java_lang_invoke_MethodHandle::vmslots(mh()) != m->size_of_parameters()) {
-    THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in DMH");
-  }
-}
-
-void MethodHandles::init_DirectMethodHandle(Handle mh, methodHandle m, bool do_dispatch, TRAPS) {
-  // Check arguments.
-  if (mh.is_null() || m.is_null() ||
-      (!do_dispatch && m->is_abstract())) {
-    THROW(vmSymbols::java_lang_InternalError());
-  }
-
-  if (VerifyMethodHandles) {
-    // The privileged code which invokes this routine should not make
-    // a mistake about types, but it's better to verify.
-    verify_DirectMethodHandle(mh, m, CHECK);
-  }
-
-  // Finally, after safety checks are done, link to the target method.
-  // We will follow the same path as the latter part of
-  // InterpreterRuntime::resolve_invoke(), which first finds the method
-  // and then decides how to populate the constant pool cache entry
-  // that links the interpreter calls to the method.  We need the same
-  // bits, and will use the same calling sequence code.
-
-  int    vmindex = methodOopDesc::garbage_vtable_index;
-  Handle vmtarget;
-
-  instanceKlass::cast(m->method_holder())->link_class(CHECK);
-
-  MethodHandleEntry* me = NULL;
-  if (do_dispatch && Klass::cast(m->method_holder())->is_interface()) {
-    // We are simulating an invokeinterface instruction.
-    // (We might also be simulating an invokevirtual on a miranda method,
-    // but it is safe to treat it as an invokeinterface.)
-    assert(!m->can_be_statically_bound(), "no final methods on interfaces");
-    vmindex = klassItable::compute_itable_index(m());
-    assert(vmindex >= 0, "(>=0) == do_dispatch");
-    // Set up same bits as ConstantPoolCacheEntry::set_interface_call().
-    vmtarget = m->method_holder(); // the interface
-    me = MethodHandles::entry(MethodHandles::_invokeinterface_mh);
-  } else if (!do_dispatch || m->can_be_statically_bound()) {
-    // We are simulating an invokestatic or invokespecial instruction.
-    // Set up the method pointer, just like ConstantPoolCacheEntry::set_method().
-    vmtarget = m;
-    // this does not help dispatch, but it will make it possible to parse this MH:
-    vmindex  = methodOopDesc::nonvirtual_vtable_index;
-    assert(vmindex < 0, "(>=0) == do_dispatch");
-    if (!m->is_static()) {
-      me = MethodHandles::entry(MethodHandles::_invokespecial_mh);
-    } else {
-      me = MethodHandles::entry(MethodHandles::_invokestatic_mh);
-      // Part of the semantics of a static call is an initialization barrier.
-      // For a DMH, it is done now, when the handle is created.
-      Klass* k = Klass::cast(m->method_holder());
-      if (k->should_be_initialized()) {
-        k->initialize(CHECK);  // possible safepoint
-      }
-    }
-  } else {
-    // We are simulating an invokevirtual instruction.
-    // Set up the vtable index, just like ConstantPoolCacheEntry::set_method().
-    // The key logic is LinkResolver::runtime_resolve_virtual_method.
-    vmindex  = m->vtable_index();
-    vmtarget = m->method_holder();
-    me = MethodHandles::entry(MethodHandles::_invokevirtual_mh);
-  }
-
-  if (me == NULL) { THROW(vmSymbols::java_lang_InternalError()); }
-
-  java_lang_invoke_DirectMethodHandle::set_vmtarget(mh(), vmtarget());
-  java_lang_invoke_DirectMethodHandle::set_vmindex( mh(), vmindex);
-  DEBUG_ONLY(KlassHandle rlimit; int flags);
-  assert(MethodHandles::decode_method(mh(), rlimit, flags) == m,
-         "properly stored for later decoding");
-  DEBUG_ONLY(bool actual_do_dispatch = ((flags & _dmf_does_dispatch) != 0));
-  assert(!(actual_do_dispatch && !do_dispatch),
-         "do not perform dispatch if !do_dispatch specified");
-  assert(actual_do_dispatch == (vmindex >= 0), "proper later decoding of do_dispatch");
-  assert(decode_MethodHandle_stack_pushes(mh()) == 0, "DMH does not move stack");
-
-  // Done!
-  java_lang_invoke_MethodHandle::set_vmentry(mh(), me);
-}
-
-void MethodHandles::verify_BoundMethodHandle_with_receiver(Handle mh,
-                                                           methodHandle m,
-                                                           TRAPS) {
-  // Verify type.
-  KlassHandle bound_recv_type;
-  {
-    oop receiver = java_lang_invoke_BoundMethodHandle::argument(mh());
-    if (receiver != NULL)
-      bound_recv_type = KlassHandle(THREAD, receiver->klass());
-  }
-  Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
-  verify_method_type(m, mtype, true, bound_recv_type, CHECK);
-
-  int receiver_pos = m->size_of_parameters() - 1;
-
-  // Verify MH.vmargslot, which should point at the bound receiver.
-  verify_vmargslot(mh, -1, java_lang_invoke_BoundMethodHandle::vmargslot(mh()), CHECK);
-  //verify_vmslots(mh, CHECK);
-
-  // Verify vmslots.
-  if (java_lang_invoke_MethodHandle::vmslots(mh()) != receiver_pos) {
-    THROW_MSG(vmSymbols::java_lang_InternalError(), "bad vmslots in BMH (receiver)");
-  }
-}
-
-// Initialize a BMH with a receiver bound directly to a methodOop.
-void MethodHandles::init_BoundMethodHandle_with_receiver(Handle mh,
-                                                         methodHandle original_m,
-                                                         KlassHandle receiver_limit,
-                                                         int decode_flags,
-                                                         TRAPS) {
-  // Check arguments.
-  if (mh.is_null() || original_m.is_null()) {
-    THROW(vmSymbols::java_lang_InternalError());
-  }
-
-  KlassHandle receiver_klass;
-  {
-    oop receiver_oop = java_lang_invoke_BoundMethodHandle::argument(mh());
-    if (receiver_oop != NULL)
-      receiver_klass = KlassHandle(THREAD, receiver_oop->klass());
-  }
-  methodHandle m = dispatch_decoded_method(original_m,
-                                           receiver_limit, decode_flags,
-                                           receiver_klass,
-                                           CHECK);
-  if (m.is_null())      { THROW(vmSymbols::java_lang_InternalError()); }
-  if (m->is_abstract()) { THROW(vmSymbols::java_lang_AbstractMethodError()); }
-
-  int vmargslot = m->size_of_parameters() - 1;
-  assert(java_lang_invoke_BoundMethodHandle::vmargslot(mh()) == vmargslot, "");
-
-  if (VerifyMethodHandles) {
-    verify_BoundMethodHandle_with_receiver(mh, m, CHECK);
-  }
-
-  java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
-
-  DEBUG_ONLY(KlassHandle junk1; int junk2);
-  assert(MethodHandles::decode_method(mh(), junk1, junk2) == m, "properly stored for later decoding");
-  assert(decode_MethodHandle_stack_pushes(mh()) == 1, "BMH pushes one stack slot");
-
-  // Done!
-  java_lang_invoke_MethodHandle::set_vmentry(mh(), MethodHandles::entry(MethodHandles::_bound_ref_direct_mh));
-}
-
-void MethodHandles::verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
-                                             bool direct_to_method, TRAPS) {
-  ResourceMark rm;
-  Handle ptype_handle(THREAD,
-                           java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum));
-  KlassHandle ptype_klass;
-  BasicType ptype = java_lang_Class::as_BasicType(ptype_handle(), &ptype_klass);
-  int slots_pushed = type2size[ptype];
-
-  oop argument = java_lang_invoke_BoundMethodHandle::argument(mh());
-
-  const char* err = NULL;
-
-  switch (ptype) {
-  case T_OBJECT:
-    if (argument != NULL)
-      // we must implicitly convert from the arg type to the outgoing ptype
-      err = check_argument_type_change(T_OBJECT, argument->klass(), ptype, ptype_klass(), argnum);
-    break;
-
-  case T_ARRAY: case T_VOID:
-    assert(false, "array, void do not appear here");
-  default:
-    if (ptype != T_INT && !is_subword_type(ptype)) {
-      err = "unexpected parameter type";
-      break;
-    }
-    // check subrange of Integer.value, if necessary
-    if (argument == NULL || argument->klass() != SystemDictionary::Integer_klass()) {
-      err = "bound integer argument must be of type java.lang.Integer";
-      break;
-    }
-    if (ptype != T_INT) {
-      int value_offset = java_lang_boxing_object::value_offset_in_bytes(T_INT);
-      jint value = argument->int_field(value_offset);
-      int vminfo = adapter_unbox_subword_vminfo(ptype);
-      jint subword = truncate_subword_from_vminfo(value, vminfo);
-      if (value != subword) {
-        err = "bound subword value does not fit into the subword type";
-        break;
-      }
-    }
-    break;
-  case T_FLOAT:
-  case T_DOUBLE:
-  case T_LONG:
-    {
-      // we must implicitly convert from the unboxed arg type to the outgoing ptype
-      BasicType argbox = java_lang_boxing_object::basic_type(argument);
-      if (argbox != ptype) {
-        err = check_argument_type_change(T_OBJECT, (argument == NULL
-                                                    ? SystemDictionary::Object_klass()
-                                                    : argument->klass()),
-                                         ptype, ptype_klass(), argnum);
-        assert(err != NULL, "this must be an error");
-      }
-      break;
-    }
-  }
-
-  if (err == NULL) {
-    DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-    if (direct_to_method) {
-      assert(this_pushes == slots_pushed, "BMH pushes one or two stack slots");
-    } else {
-      int target_pushes = decode_MethodHandle_stack_pushes(target());
-      assert(this_pushes == slots_pushed + target_pushes, "BMH stack motion must be correct");
-    }
-  }
-
-  if (err == NULL) {
-    // Verify the rest of the method type.
-    err = check_method_type_insertion(java_lang_invoke_MethodHandle::type(mh()),
-                                      argnum, ptype_handle(),
-                                      java_lang_invoke_MethodHandle::type(target()));
-  }
-
-  if (err != NULL) {
-    THROW_MSG(vmSymbols::java_lang_InternalError(), err);
-  }
-}
-
-void MethodHandles::init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
-  // Check arguments.
-  if (mh.is_null() || target.is_null() || !java_lang_invoke_MethodHandle::is_instance(target())) {
-    THROW(vmSymbols::java_lang_InternalError());
-  }
-
-  int argslot = java_lang_invoke_BoundMethodHandle::vmargslot(mh());
-
-  if (VerifyMethodHandles) {
-    int insert_after = argnum - 1;
-    verify_vmargslot(mh, insert_after, argslot, CHECK);
-    verify_vmslots(mh, CHECK);
-  }
-
-  // Get bound type and required slots.
-  BasicType ptype;
-  {
-    oop ptype_oop = java_lang_invoke_MethodType::ptype(java_lang_invoke_MethodHandle::type(target()), argnum);
-    ptype = java_lang_Class::as_BasicType(ptype_oop);
-  }
-  int slots_pushed = type2size[ptype];
-
-  // If (a) the target is a direct non-dispatched method handle,
-  // or (b) the target is a dispatched direct method handle and we
-  // are binding the receiver, cut out the middle-man.
-  // Do this by decoding the DMH and using its methodOop directly as vmtarget.
-  bool direct_to_method = false;
-  if (OptimizeMethodHandles &&
-      target->klass() == SystemDictionary::DirectMethodHandle_klass() &&
-      (argnum != 0 || java_lang_invoke_BoundMethodHandle::argument(mh()) != NULL) &&
-      (argnum == 0 || java_lang_invoke_DirectMethodHandle::vmindex(target()) < 0)) {
-    KlassHandle receiver_limit; int decode_flags = 0;
-    methodHandle m = decode_method(target(), receiver_limit, decode_flags);
-    if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "DMH failed to decode"); }
-    DEBUG_ONLY(int m_vmslots = m->size_of_parameters() - slots_pushed); // pos. of 1st arg.
-    assert(java_lang_invoke_BoundMethodHandle::vmslots(mh()) == m_vmslots, "type w/ m sig");
-    if (argnum == 0 && (decode_flags & _dmf_has_receiver) != 0) {
-      init_BoundMethodHandle_with_receiver(mh, m,
-                                           receiver_limit, decode_flags,
-                                           CHECK);
-      return;
-    }
-
-    // Even if it is not a bound receiver, we still might be able
-    // to bind another argument and still invoke the methodOop directly.
-    if (!(decode_flags & _dmf_does_dispatch)) {
-      direct_to_method = true;
-      java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), m());
-    }
-  }
-  if (!direct_to_method)
-    java_lang_invoke_BoundMethodHandle::set_vmtarget(mh(), target());
-
-  if (VerifyMethodHandles) {
-    verify_BoundMethodHandle(mh, target, argnum, direct_to_method, CHECK);
-  }
-
-  // Next question:  Is this a ref, int, or long bound value?
-  MethodHandleEntry* me = NULL;
-  if (ptype == T_OBJECT) {
-    if (direct_to_method)  me = MethodHandles::entry(_bound_ref_direct_mh);
-    else                   me = MethodHandles::entry(_bound_ref_mh);
-  } else if (slots_pushed == 2) {
-    if (direct_to_method)  me = MethodHandles::entry(_bound_long_direct_mh);
-    else                   me = MethodHandles::entry(_bound_long_mh);
-  } else if (slots_pushed == 1) {
-    if (direct_to_method)  me = MethodHandles::entry(_bound_int_direct_mh);
-    else                   me = MethodHandles::entry(_bound_int_mh);
-  } else {
-    assert(false, "");
-  }
-
-  // Done!
-  java_lang_invoke_MethodHandle::set_vmentry(mh(), me);
-}
-
-static void throw_InternalError_for_bad_conversion(int conversion, const char* err, TRAPS) {
-  char msg[200];
-  jio_snprintf(msg, sizeof(msg), "bad adapter (conversion=0x%08x): %s", conversion, err);
-  THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), msg);
-}
-
-void MethodHandles::verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS) {
-  ResourceMark rm;
-  jint conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
-  int  argslot    = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
-
-  verify_vmargslot(mh, argnum, argslot, CHECK);
-  verify_vmslots(mh, CHECK);
-
-  jint conv_op    = adapter_conversion_op(conversion);
-  if (!conv_op_valid(conv_op)) {
-    throw_InternalError_for_bad_conversion(conversion, "unknown conversion op", THREAD);
-    return;
-  }
-  EntryKind ek = adapter_entry_kind(conv_op);
-
-  int stack_move = adapter_conversion_stack_move(conversion);
-  BasicType src  = adapter_conversion_src_type(conversion);
-  BasicType dest = adapter_conversion_dest_type(conversion);
-  int vminfo     = adapter_conversion_vminfo(conversion); // should be zero
-
-  Handle argument(THREAD,  java_lang_invoke_AdapterMethodHandle::argument(mh()));
-  Handle target(THREAD,    java_lang_invoke_AdapterMethodHandle::vmtarget(mh()));
-  Handle src_mtype(THREAD, java_lang_invoke_MethodHandle::type(mh()));
-  Handle dst_mtype(THREAD, java_lang_invoke_MethodHandle::type(target()));
-  Handle arg_mtype;
-
-  const char* err = NULL;
-
-  if (err == NULL) {
-    // Check that the correct argument is supplied, but only if it is required.
-    switch (ek) {
-    case _adapter_check_cast:     // target type of cast
-    case _adapter_ref_to_prim:    // wrapper type from which to unbox
-    case _adapter_spread_args:    // array type to spread from
-      if (!java_lang_Class::is_instance(argument())
-          || java_lang_Class::is_primitive(argument()))
-        { err = "adapter requires argument of type java.lang.Class"; break; }
-      if (ek == _adapter_spread_args) {
-        // Make sure it is a suitable collection type.  (Array, for now.)
-        Klass* ak = Klass::cast(java_lang_Class::as_klassOop(argument()));
-        if (!ak->oop_is_array())
-          { err = "spread adapter requires argument representing an array class"; break; }
-        BasicType et = arrayKlass::cast(ak->as_klassOop())->element_type();
-        if (et != dest && stack_move <= 0)
-          { err = "spread adapter requires array class argument of correct type"; break; }
-      }
-      break;
-    case _adapter_prim_to_ref:    // boxer MH to use
-    case _adapter_collect_args:   // method handle which collects the args
-    case _adapter_fold_args:      // method handle which collects the args
-      if (!java_lang_invoke_MethodHandle::is_instance(argument()))
-        { err = "MethodHandle adapter argument required"; break; }
-      arg_mtype = Handle(THREAD, java_lang_invoke_MethodHandle::type(argument()));
-      break;
-    default:
-      if (argument.not_null())
-        { err = "adapter has spurious argument"; break; }
-      break;
-    }
-  }
-
-  if (err == NULL) {
-    // Check that the src/dest types are supplied if needed.
-    // Also check relevant parameter or return types.
-    switch (ek) {
-    case _adapter_check_cast:
-      if (src != T_OBJECT || dest != T_OBJECT) {
-        err = "adapter requires object src/dest conversion subfields";
-      }
-      break;
-    case _adapter_prim_to_prim:
-      if (!is_java_primitive(src) || !is_java_primitive(dest) || src == dest) {
-        err = "adapter requires primitive src/dest conversion subfields"; break;
-      }
-      if ( (src == T_FLOAT || src == T_DOUBLE) && !(dest == T_FLOAT || dest == T_DOUBLE) ||
-          !(src == T_FLOAT || src == T_DOUBLE) &&  (dest == T_FLOAT || dest == T_DOUBLE)) {
-        err = "adapter cannot convert beween floating and fixed-point"; break;
-      }
-      break;
-    case _adapter_ref_to_prim:
-      if (src != T_OBJECT || !is_java_primitive(dest)
-          || argument() != Klass::cast(SystemDictionary::box_klass(dest))->java_mirror()) {
-        err = "adapter requires primitive dest conversion subfield"; break;
-      }
-      break;
-    case _adapter_prim_to_ref:
-      if (!is_java_primitive(src) || dest != T_OBJECT) {
-        err = "adapter requires primitive src conversion subfield"; break;
-      }
-      break;
-    case _adapter_swap_args:
-      {
-        if (!src || !dest) {
-          err = "adapter requires src/dest conversion subfields for swap"; break;
-        }
-        int src_size  = type2size[src];
-        if (src_size != type2size[dest]) {
-          err = "adapter requires equal sizes for src/dest"; break;
-        }
-        int src_slot   = argslot;
-        int dest_slot  = vminfo;
-        int src_arg    = argnum;
-        int dest_arg   = argument_slot_to_argnum(src_mtype(), dest_slot);
-        verify_vmargslot(mh, dest_arg, dest_slot, CHECK);
-        if (!(dest_slot >= src_slot + src_size) &&
-            !(src_slot >= dest_slot + src_size)) {
-          err = "source, destination slots must be distinct"; break;
-        } else if (!(src_slot > dest_slot)) {
-          err = "source of swap must be deeper in stack"; break;
-        }
-        err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), dest_arg),
-                                         java_lang_invoke_MethodType::ptype(dst_mtype(), src_arg),
-                                         dest_arg);
-        if (err == NULL)
-          err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
-                                           java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
-                                           src_arg);
-        break;
-      }
-    case _adapter_rot_args:
-      {
-        if (!src || !dest) {
-          err = "adapter requires src/dest conversion subfields for rotate"; break;
-        }
-        int src_slot   = argslot;
-        int limit_raw  = vminfo;
-        bool rot_down  = (src_slot < limit_raw);
-        int limit_bias = (rot_down ? MethodHandles::OP_ROT_ARGS_DOWN_LIMIT_BIAS : 0);
-        int limit_slot = limit_raw - limit_bias;
-        int src_arg    = argnum;
-        int limit_arg  = argument_slot_to_argnum(src_mtype(), limit_slot);
-        verify_vmargslot(mh, limit_arg, limit_slot, CHECK);
-        if (src_slot == limit_slot) {
-          err = "source, destination slots must be distinct"; break;
-        }
-        if (!rot_down) {  // rotate slots up == shift arguments left
-          // limit_slot is an inclusive lower limit
-          assert((src_slot > limit_slot) && (src_arg < limit_arg), "");
-          // rotate up: [limit_slot..src_slot-ss] --> [limit_slot+ss..src_slot]
-          // that is:   [src_arg+1..limit_arg] --> [src_arg..limit_arg-1]
-          for (int i = src_arg+1; i <= limit_arg && err == NULL; i++) {
-            err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
-                                             java_lang_invoke_MethodType::ptype(dst_mtype(), i-1),
-                                             i);
-          }
-        } else { // rotate slots down == shfit arguments right
-          // limit_slot is an exclusive upper limit
-          assert((src_slot < limit_slot - limit_bias) && (src_arg > limit_arg + limit_bias), "");
-          // rotate down: [src_slot+ss..limit_slot) --> [src_slot..limit_slot-ss)
-          // that is:     (limit_arg..src_arg-1] --> (dst_arg+1..src_arg]
-          for (int i = limit_arg+1; i <= src_arg-1 && err == NULL; i++) {
-            err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), i),
-                                             java_lang_invoke_MethodType::ptype(dst_mtype(), i+1),
-                                             i);
-          }
-        }
-        if (err == NULL) {
-          int dest_arg = (rot_down ? limit_arg+1 : limit_arg);
-          err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), src_arg),
-                                           java_lang_invoke_MethodType::ptype(dst_mtype(), dest_arg),
-                                           src_arg);
-        }
-      }
-      break;
-    case _adapter_spread_args:
-    case _adapter_collect_args:
-    case _adapter_fold_args:
-      {
-        bool is_spread = (ek == _adapter_spread_args);
-        bool is_fold   = (ek == _adapter_fold_args);
-        BasicType coll_type = is_spread ? src : dest;
-        BasicType elem_type = is_spread ? dest : src;
-        // coll_type is type of args in collected form (or T_VOID if none)
-        // elem_type is common type of args in spread form (or T_VOID if missing or heterogeneous)
-        if (coll_type == 0 || elem_type == 0) {
-          err = "adapter requires src/dest subfields for spread or collect"; break;
-        }
-        if (is_spread && coll_type != T_OBJECT) {
-          err = "spread adapter requires object type for argument bundle"; break;
-        }
-        Handle spread_mtype = (is_spread ? dst_mtype : src_mtype);
-        int spread_slot = argslot;
-        int spread_arg  = argnum;
-        int slots_pushed = stack_move / stack_move_unit();
-        int coll_slot_count = type2size[coll_type];
-        int spread_slot_count = (is_spread ? slots_pushed : -slots_pushed) + coll_slot_count;
-        if (is_fold)  spread_slot_count = argument_slot_count(arg_mtype());
-        if (!is_spread) {
-          int init_slots = argument_slot_count(src_mtype());
-          int coll_slots = argument_slot_count(arg_mtype());
-          if (spread_slot_count > init_slots ||
-              spread_slot_count != coll_slots) {
-            err = "collect adapter has inconsistent arg counts"; break;
-          }
-          int next_slots = argument_slot_count(dst_mtype());
-          int unchanged_slots_in  = (init_slots - spread_slot_count);
-          int unchanged_slots_out = (next_slots - coll_slot_count - (is_fold ? spread_slot_count : 0));
-          if (unchanged_slots_in != unchanged_slots_out) {
-            err = "collect adapter continuation has inconsistent arg counts"; break;
-          }
-        }
-      }
-      break;
-    default:
-      if (src != 0 || dest != 0) {
-        err = "adapter has spurious src/dest conversion subfields"; break;
-      }
-      break;
-    }
-  }
-
-  if (err == NULL) {
-    // Check the stack_move subfield.
-    // It must always report the net change in stack size, positive or negative.
-    int slots_pushed = stack_move / stack_move_unit();
-    switch (ek) {
-    case _adapter_prim_to_prim:
-    case _adapter_ref_to_prim:
-    case _adapter_prim_to_ref:
-      if (slots_pushed != type2size[dest] - type2size[src]) {
-        err = "wrong stack motion for primitive conversion";
-      }
-      break;
-    case _adapter_dup_args:
-      if (slots_pushed <= 0) {
-        err = "adapter requires conversion subfield slots_pushed > 0";
-      }
-      break;
-    case _adapter_drop_args:
-      if (slots_pushed >= 0) {
-        err = "adapter requires conversion subfield slots_pushed < 0";
-      }
-      break;
-    case _adapter_collect_args:
-    case _adapter_fold_args:
-      if (slots_pushed > 2) {
-        err = "adapter requires conversion subfield slots_pushed <= 2";
-      }
-      break;
-    case _adapter_spread_args:
-      if (slots_pushed < -1) {
-        err = "adapter requires conversion subfield slots_pushed >= -1";
-      }
-      break;
-    default:
-      if (stack_move != 0) {
-        err = "adapter has spurious stack_move conversion subfield";
-      }
-      break;
-    }
-    if (err == NULL && stack_move != slots_pushed * stack_move_unit()) {
-      err = "stack_move conversion subfield must be multiple of stack_move_unit";
-    }
-  }
-
-  if (err == NULL) {
-    // Make sure this adapter's stack pushing is accurately recorded.
-    int slots_pushed = stack_move / stack_move_unit();
-    int this_vmslots = java_lang_invoke_MethodHandle::vmslots(mh());
-    int target_vmslots = java_lang_invoke_MethodHandle::vmslots(target());
-    int target_pushes = decode_MethodHandle_stack_pushes(target());
-    if (slots_pushed != (target_vmslots - this_vmslots)) {
-      err = "stack_move inconsistent with previous and current MethodType vmslots";
-    } else {
-      int this_pushes = decode_MethodHandle_stack_pushes(mh());
-      if (slots_pushed + target_pushes != this_pushes) {
-        if (this_pushes == 0)
-          err = "adapter push count not initialized";
-        else
-          err = "adapter push count is wrong";
-      }
-    }
-
-    // While we're at it, check that the stack motion decoder works:
-    DEBUG_ONLY(int this_pushes = decode_MethodHandle_stack_pushes(mh()));
-    assert(this_pushes == slots_pushed + target_pushes, "AMH stack motion must be correct");
-  }
-
-  if (err == NULL && vminfo != 0) {
-    switch (ek) {
-    case _adapter_swap_args:
-    case _adapter_rot_args:
-    case _adapter_prim_to_ref:
-    case _adapter_collect_args:
-    case _adapter_fold_args:
-      break;                // OK
-    default:
-      err = "vminfo subfield is reserved to the JVM";
-    }
-  }
-
-  // Do additional ad hoc checks.
-  if (err == NULL) {
-    switch (ek) {
-    case _adapter_retype_only:
-      err = check_method_type_passthrough(src_mtype(), dst_mtype(), false);
-      break;
-
-    case _adapter_retype_raw:
-      err = check_method_type_passthrough(src_mtype(), dst_mtype(), true);
-      break;
-
-    case _adapter_check_cast:
-      {
-        // The actual value being checked must be a reference:
-        err = check_argument_type_change(java_lang_invoke_MethodType::ptype(src_mtype(), argnum),
-                                         object_java_mirror(), argnum);
-        if (err != NULL)  break;
-
-        // The output of the cast must fit with the destination argument:
-        Handle cast_class = argument;
-        err = check_method_type_conversion(src_mtype(),
-                                           argnum, cast_class(),
-                                           dst_mtype());
-      }
-      break;
-
-      // %%% TO DO: continue in remaining cases to verify src/dst_mtype if VerifyMethodHandles
-    }
-  }
-
-  if (err != NULL) {
-    throw_InternalError_for_bad_conversion(conversion, err, THREAD);
-    return;
-  }
-
-}
-
-void MethodHandles::init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS) {
-  Handle argument   = java_lang_invoke_AdapterMethodHandle::argument(mh());
-  int    argslot    = java_lang_invoke_AdapterMethodHandle::vmargslot(mh());
-  jint   conversion = java_lang_invoke_AdapterMethodHandle::conversion(mh());
-  jint   conv_op    = adapter_conversion_op(conversion);
-
-  // adjust the adapter code to the internal EntryKind enumeration:
-  EntryKind ek_orig = adapter_entry_kind(conv_op);
-  EntryKind ek_opt  = ek_orig;  // may be optimized
-  EntryKind ek_try;             // temp
-
-  // Finalize the vmtarget field (Java initialized it to null).
-  if (!java_lang_invoke_MethodHandle::is_instance(target())) {
-    throw_InternalError_for_bad_conversion(conversion, "bad target", THREAD);
-    return;
-  }
-  java_lang_invoke_AdapterMethodHandle::set_vmtarget(mh(), target());
-
-  int stack_move = adapter_conversion_stack_move(conversion);
-  BasicType src  = adapter_conversion_src_type(conversion);
-  BasicType dest = adapter_conversion_dest_type(conversion);
-  int vminfo     = adapter_conversion_vminfo(conversion); // should be zero
-
-  int slots_pushed = stack_move / stack_move_unit();
-
-  if (VerifyMethodHandles) {
-    verify_AdapterMethodHandle(mh, argnum, CHECK);
-  }
-
-  const char* err = NULL;
-
-  if (!conv_op_supported(conv_op)) {
-    err = "adapter not yet implemented in the JVM";
-  }
-
-  // Now it's time to finish the case analysis and pick a MethodHandleEntry.
-  switch (ek_orig) {
-  case _adapter_retype_only:
-  case _adapter_retype_raw:
-  case _adapter_check_cast:
-  case _adapter_dup_args:
-  case _adapter_drop_args:
-    // these work fine via general case code
-    break;
-
-  case _adapter_prim_to_prim:
-    {
-      // Non-subword cases are {int,float,long,double} -> {int,float,long,double}.
-      // And, the {float,double} -> {int,long} cases must be handled by Java.
-      switch (type2size[src] *4+ type2size[dest]) {
-      case 1 *4+ 1:
-        assert(src == T_INT || is_subword_type(src), "source is not float");
-        // Subword-related cases are int -> {boolean,byte,char,short}.
-        ek_opt = _adapter_opt_i2i;
-        vminfo = adapter_prim_to_prim_subword_vminfo(dest);
-        break;
-      case 2 *4+ 1:
-        if (src == T_LONG && (dest == T_INT || is_subword_type(dest))) {
-          ek_opt = _adapter_opt_l2i;
-          vminfo = adapter_prim_to_prim_subword_vminfo(dest);
-        } else if (src == T_DOUBLE && dest == T_FLOAT) {
-          ek_opt = _adapter_opt_d2f;
-        } else {
-          goto throw_not_impl;        // runs user code, hence could block
-        }
-        break;
-      case 1 *4+ 2:
-        if ((src == T_INT || is_subword_type(src)) && dest == T_LONG) {
-          ek_opt = _adapter_opt_i2l;
-        } else if (src == T_FLOAT && dest == T_DOUBLE) {
-          ek_opt = _adapter_opt_f2d;
-        } else {
-          goto throw_not_impl;        // runs user code, hence could block
-        }
-        break;
-      default:
-        goto throw_not_impl;        // runs user code, hence could block
-        break;
-      }
-    }
-    break;
-
-  case _adapter_ref_to_prim:
-    {
-      switch (type2size[dest]) {
-      case 1:
-        ek_opt = _adapter_opt_unboxi;
-        vminfo = adapter_unbox_subword_vminfo(dest);
-        break;
-      case 2:
-        ek_opt = _adapter_opt_unboxl;
-        break;
-      default:
-        goto throw_not_impl;
-        break;
-      }
-    }
-    break;
-
-  case _adapter_prim_to_ref:
-    {
-      // vminfo will be the location to insert the return value
-      vminfo = argslot;
-      ek_opt = _adapter_opt_collect_ref;
-      ensure_vmlayout_field(target, CHECK);
-      // for MethodHandleWalk:
-      if (java_lang_invoke_AdapterMethodHandle::is_instance(argument()))
-        ensure_vmlayout_field(argument, CHECK);
-      if (!OptimizeMethodHandles)  break;
-      switch (type2size[src]) {
-      case 1:
-        ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot);
-        if (ek_try < _adapter_opt_collect_LAST &&
-            ek_adapter_opt_collect_slot(ek_try) == argslot) {
-          assert(ek_adapter_opt_collect_count(ek_try) == 1 &&
-                 ek_adapter_opt_collect_type(ek_try) == T_OBJECT, "");
-          ek_opt = ek_try;
-          break;
-        }
-        // else downgrade to variable slot:
-        ek_opt = _adapter_opt_collect_1_ref;
-        break;
-      case 2:
-        ek_try = EntryKind(_adapter_opt_collect_2_S0_ref + argslot);
-        if (ek_try < _adapter_opt_collect_LAST &&
-            ek_adapter_opt_collect_slot(ek_try) == argslot) {
-          assert(ek_adapter_opt_collect_count(ek_try) == 2 &&
-                 ek_adapter_opt_collect_type(ek_try) == T_OBJECT, "");
-          ek_opt = ek_try;
-          break;
-        }
-        // else downgrade to variable slot:
-        ek_opt = _adapter_opt_collect_2_ref;
-        break;
-      default:
-        goto throw_not_impl;
-        break;
-      }
-    }
-    break;
-
-  case _adapter_swap_args:
-  case _adapter_rot_args:
-    {
-      int swap_slots = type2size[src];
-      int src_slot   = argslot;
-      int dest_slot  = vminfo;
-      int rotate     = (ek_orig == _adapter_swap_args) ? 0 : (src_slot > dest_slot) ? 1 : -1;
-      switch (swap_slots) {
-      case 1:
-        ek_opt = (!rotate    ? _adapter_opt_swap_1 :
-                  rotate > 0 ? _adapter_opt_rot_1_up : _adapter_opt_rot_1_down);
-        break;
-      case 2:
-        ek_opt = (!rotate    ? _adapter_opt_swap_2 :
-                  rotate > 0 ? _adapter_opt_rot_2_up : _adapter_opt_rot_2_down);
-        break;
-      default:
-        goto throw_not_impl;
-        break;
-      }
-    }
-    break;
-
-  case _adapter_spread_args:
-    {
-      // vminfo will be the required length of the array
-      int array_size = (slots_pushed + 1) / (type2size[dest] == 2 ? 2 : 1);
-      vminfo = array_size;
-      // general case
-      switch (dest) {
-      case T_BOOLEAN : // fall through to T_BYTE:
-      case T_BYTE    : ek_opt = _adapter_opt_spread_byte;    break;
-      case T_CHAR    : ek_opt = _adapter_opt_spread_char;    break;
-      case T_SHORT   : ek_opt = _adapter_opt_spread_short;   break;
-      case T_INT     : ek_opt = _adapter_opt_spread_int;     break;
-      case T_LONG    : ek_opt = _adapter_opt_spread_long;    break;
-      case T_FLOAT   : ek_opt = _adapter_opt_spread_float;   break;
-      case T_DOUBLE  : ek_opt = _adapter_opt_spread_double;  break;
-      case T_OBJECT  : ek_opt = _adapter_opt_spread_ref;     break;
-      case T_VOID    : if (array_size != 0)  goto throw_not_impl;
-                       ek_opt = _adapter_opt_spread_ref;     break;
-      default        : goto throw_not_impl;
-      }
-      assert(array_size == 0 ||  // it doesn't matter what the spreader is
-             (ek_adapter_opt_spread_count(ek_opt) == -1 &&
-              (ek_adapter_opt_spread_type(ek_opt) == dest ||
-               (ek_adapter_opt_spread_type(ek_opt) == T_BYTE && dest == T_BOOLEAN))),
-             err_msg("dest=%d ek_opt=%d", dest, ek_opt));
-
-      if (array_size <= 0) {
-        // since the general case does not handle length 0, this case is required:
-        ek_opt = _adapter_opt_spread_0;
-        break;
-      }
-      if (dest == T_OBJECT) {
-        ek_try = EntryKind(_adapter_opt_spread_1_ref - 1 + array_size);
-        if (ek_try < _adapter_opt_spread_LAST &&
-            ek_adapter_opt_spread_count(ek_try) == array_size) {
-          assert(ek_adapter_opt_spread_type(ek_try) == dest, "");
-          ek_opt = ek_try;
-          break;
-        }
-      }
-      break;
-    }
-    break;
-
-  case _adapter_collect_args:
-    {
-      int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
-      // vminfo will be the location to insert the return value
-      vminfo = argslot;
-      ensure_vmlayout_field(target, CHECK);
-      ensure_vmlayout_field(argument, CHECK);
-
-      // general case:
-      switch (dest) {
-      default       : if (!is_subword_type(dest))  goto throw_not_impl;
-                    // else fall through:
-      case T_INT    : ek_opt = _adapter_opt_collect_int;     break;
-      case T_LONG   : ek_opt = _adapter_opt_collect_long;    break;
-      case T_FLOAT  : ek_opt = _adapter_opt_collect_float;   break;
-      case T_DOUBLE : ek_opt = _adapter_opt_collect_double;  break;
-      case T_OBJECT : ek_opt = _adapter_opt_collect_ref;     break;
-      case T_VOID   : ek_opt = _adapter_opt_collect_void;    break;
-      }
-      assert(ek_adapter_opt_collect_slot(ek_opt) == -1 &&
-             ek_adapter_opt_collect_count(ek_opt) == -1 &&
-             (ek_adapter_opt_collect_type(ek_opt) == dest ||
-              ek_adapter_opt_collect_type(ek_opt) == T_INT && is_subword_type(dest)),
-             "");
-
-      if (dest == T_OBJECT && elem_slots == 1 && OptimizeMethodHandles) {
-        // filter operation on a ref
-        ek_try = EntryKind(_adapter_opt_filter_S0_ref + argslot);
-        if (ek_try < _adapter_opt_collect_LAST &&
-            ek_adapter_opt_collect_slot(ek_try) == argslot) {
-          assert(ek_adapter_opt_collect_count(ek_try) == elem_slots &&
-                 ek_adapter_opt_collect_type(ek_try) == dest, "");
-          ek_opt = ek_try;
-          break;
-        }
-        ek_opt = _adapter_opt_collect_1_ref;
-        break;
-      }
-
-      if (dest == T_OBJECT && elem_slots == 2 && OptimizeMethodHandles) {
-        // filter of two arguments
-        ek_try = EntryKind(_adapter_opt_collect_2_S0_ref + argslot);
-        if (ek_try < _adapter_opt_collect_LAST &&
-            ek_adapter_opt_collect_slot(ek_try) == argslot) {
-          assert(ek_adapter_opt_collect_count(ek_try) == elem_slots &&
-                 ek_adapter_opt_collect_type(ek_try) == dest, "");
-          ek_opt = ek_try;
-          break;
-        }
-        ek_opt = _adapter_opt_collect_2_ref;
-        break;
-      }
-
-      if (dest == T_OBJECT && OptimizeMethodHandles) {
-        // try to use a fixed length adapter
-        ek_try = EntryKind(_adapter_opt_collect_0_ref + elem_slots);
-        if (ek_try < _adapter_opt_collect_LAST &&
-            ek_adapter_opt_collect_count(ek_try) == elem_slots) {
-          assert(ek_adapter_opt_collect_slot(ek_try) == -1 &&
-                 ek_adapter_opt_collect_type(ek_try) == dest, "");
-          ek_opt = ek_try;
-          break;
-        }
-      }
-
-      break;
-    }
-
-  case _adapter_fold_args:
-    {
-      int elem_slots = argument_slot_count(java_lang_invoke_MethodHandle::type(argument()));
-      // vminfo will be the location to insert the return value
-      vminfo = argslot + elem_slots;
-      ensure_vmlayout_field(target, CHECK);
-      ensure_vmlayout_field(argument, CHECK);
-
-      switch (dest) {
-      default       : if (!is_subword_type(dest))  goto throw_not_impl;
-                    // else fall through:
-      case T_INT    : ek_opt = _adapter_opt_fold_int;     break;
-      case T_LONG   : ek_opt = _adapter_opt_fold_long;    break;
-      case T_FLOAT  : ek_opt = _adapter_opt_fold_float;   break;
-      case T_DOUBLE : ek_opt = _adapter_opt_fold_double;  break;
-      case T_OBJECT : ek_opt = _adapter_opt_fold_ref;     break;
-      case T_VOID   : ek_opt = _adapter_opt_fold_void;    break;
-      }
-      assert(ek_adapter_opt_collect_slot(ek_opt) == -1 &&
-             ek_adapter_opt_collect_count(ek_opt) == -1 &&
-             (ek_adapter_opt_collect_type(ek_opt) == dest ||
-              ek_adapter_opt_collect_type(ek_opt) == T_INT && is_subword_type(dest)),
-             "");
-
-      if (dest == T_OBJECT && elem_slots == 0 && OptimizeMethodHandles) {
-        // if there are no args, just pretend it's a collect
-        ek_opt = _adapter_opt_collect_0_ref;
-        break;
-      }
-
-      if (dest == T_OBJECT && OptimizeMethodHandles) {
-        // try to use a fixed length adapter
-        ek_try = EntryKind(_adapter_opt_fold_1_ref - 1 + elem_slots);
-        if (ek_try < _adapter_opt_fold_LAST &&
-            ek_adapter_opt_collect_count(ek_try) == elem_slots) {
-          assert(ek_adapter_opt_collect_slot(ek_try) == -1 &&
-                 ek_adapter_opt_collect_type(ek_try) == dest, "");
-          ek_opt = ek_try;
-          break;
-        }
-      }
-
-      break;
-    }
-
-  default:
-    // should have failed much earlier; must be a missing case here
-    assert(false, "incomplete switch");
-    // and fall through:
-
-  throw_not_impl:
-    if (err == NULL)
-      err = "unknown adapter type";
-    break;
-  }
-
-  if (err == NULL && (vminfo & CONV_VMINFO_MASK) != vminfo) {
-    // should not happen, since vminfo is used to encode arg/slot indexes < 255
-    err = "vminfo overflow";
-  }
-
-  if (err == NULL && !have_entry(ek_opt)) {
-    err = "adapter stub for this kind of method handle is missing";
-  }
-
-  if (err == NULL && ek_opt == ek_orig) {
-    switch (ek_opt) {
-    case _adapter_prim_to_prim:
-    case _adapter_ref_to_prim:
-    case _adapter_prim_to_ref:
-    case _adapter_swap_args:
-    case _adapter_rot_args:
-    case _adapter_collect_args:
-    case _adapter_fold_args:
-    case _adapter_spread_args:
-      // should be handled completely by optimized cases; see above
-      err = "init_AdapterMethodHandle should not issue this";
-      break;
-    }
-  }
-
-  if (err != NULL) {
-    throw_InternalError_for_bad_conversion(conversion, err_msg("%s: conv_op %d ek_opt %d", err, conv_op, ek_opt), THREAD);
-    return;
-  }
-
-  // Rebuild the conversion value; maybe parts of it were changed.
-  jint new_conversion = adapter_conversion(conv_op, src, dest, stack_move, vminfo);
-
-  // Finalize the conversion field.  (Note that it is final to Java code.)
-  java_lang_invoke_AdapterMethodHandle::set_conversion(mh(), new_conversion);
-
-  if (java_lang_invoke_CountingMethodHandle::is_instance(mh())) {
-    assert(ek_orig == _adapter_retype_only, "only one handled");
-    ek_opt = _adapter_opt_profiling;
-  }
-
-  // Done!
-  java_lang_invoke_MethodHandle::set_vmentry(mh(), entry(ek_opt));
-
-  // There should be enough memory barriers on exit from native methods
-  // to ensure that the MH is fully initialized to all threads before
-  // Java code can publish it in global data structures.
-}
-
-void MethodHandles::ensure_vmlayout_field(Handle target, TRAPS) {
-  Handle mtype(THREAD, java_lang_invoke_MethodHandle::type(target()));
-  Handle mtform(THREAD, java_lang_invoke_MethodType::form(mtype()));
-  if (mtform.is_null()) { THROW(vmSymbols::java_lang_InternalError()); }
-  if (java_lang_invoke_MethodTypeForm::vmlayout_offset_in_bytes() > 0) {
-    if (java_lang_invoke_MethodTypeForm::vmlayout(mtform()) == NULL) {
-      // fill it in
-      Handle erased_mtype(THREAD, java_lang_invoke_MethodTypeForm::erasedType(mtform()));
-      TempNewSymbol erased_signature
-        = java_lang_invoke_MethodType::as_signature(erased_mtype(), /*intern:*/true, CHECK);
-      methodOop cookie
-        = SystemDictionary::find_method_handle_invoke(vmSymbols::invokeExact_name(),
-                                                      erased_signature,
-                                                      SystemDictionaryHandles::Object_klass(),
-                                                      THREAD);
-      java_lang_invoke_MethodTypeForm::init_vmlayout(mtform(), cookie);
-    }
-  }
-  assert(java_lang_invoke_MethodTypeForm::vmslots(mtform()) == argument_slot_count(mtype()), "must agree");
-}
-
-#ifdef ASSERT
-
-extern "C"
-void print_method_handle(oop mh);
-
-static void stress_method_handle_walk_impl(Handle mh, TRAPS) {
-  if (StressMethodHandleWalk) {
-    // Exercise the MethodHandleWalk code in various ways and validate
-    // the resulting method oop.  Some of these produce output so they
-    // are guarded under Verbose.
-    ResourceMark rm;
-    HandleMark hm;
-    if (Verbose) {
-      print_method_handle(mh());
-    }
-    TempNewSymbol name = SymbolTable::new_symbol("invoke", CHECK);
-    Handle mt = java_lang_invoke_MethodHandle::type(mh());
-    TempNewSymbol signature = java_lang_invoke_MethodType::as_signature(mt(), true, CHECK);
-    MethodHandleCompiler mhc(mh, name, signature, 10000, false, CHECK);
-    methodHandle m = mhc.compile(CHECK);
-    if (Verbose) {
-      m->print_codes();
-    }
-    InterpreterOopMap mask;
-    OopMapCache::compute_one_oop_map(m, m->code_size() - 1, &mask);
-    // compile to object code if -Xcomp or WizardMode
-    if ((WizardMode ||
-         CompilationPolicy::must_be_compiled(m))
-        && !instanceKlass::cast(m->method_holder())->is_not_initialized()
-        && CompilationPolicy::can_be_compiled(m)) {
-      // Force compilation
-      CompileBroker::compile_method(m, InvocationEntryBci,
-                                    CompilationPolicy::policy()->initial_compile_level(),
-                                    methodHandle(), 0, "StressMethodHandleWalk",
-                                    CHECK);
-    }
-  }
-}
-
-static void stress_method_handle_walk(Handle mh, TRAPS) {
-  stress_method_handle_walk_impl(mh, THREAD);
-  if (HAS_PENDING_EXCEPTION) {
-    oop ex = PENDING_EXCEPTION;
-    CLEAR_PENDING_EXCEPTION;
-    tty->print("StressMethodHandleWalk: ");
-    java_lang_Throwable::print(ex, tty);
-    tty->cr();
-  }
-}
-#else
-
-static void stress_method_handle_walk(Handle mh, TRAPS) {}
-
-#endif
-
 //
-// Here are the native methods on sun.invoke.MethodHandleImpl.
+// Here are the native methods in java.lang.invoke.MethodHandleNatives
 // They are the private interface between this JVM and the HotSpot-specific
 // Java code that implements JSR 292 method handles.
 //
 // Note:  We use a JVM_ENTRY macro to define each of these, for this is the way
 // that intrinsic (non-JNI) native methods are defined in HotSpot.
 //
-
-// direct method handles for invokestatic or invokespecial
-// void init(DirectMethodHandle self, MemberName ref, boolean doDispatch, Class<?> caller);
-JVM_ENTRY(void, MHN_init_DMH(JNIEnv *env, jobject igcls, jobject mh_jh,
-                             jobject target_jh, jboolean do_dispatch, jobject caller_jh)) {
-  ResourceMark rm;              // for error messages
-
-  // This is the guy we are initializing:
-  if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
-  Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
-
-  // Early returns out of this method leave the DMH in an unfinished state.
-  assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
-
-  // which method are we really talking about?
-  if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
-  Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
-  if (java_lang_invoke_MemberName::is_instance(target()) &&
-      java_lang_invoke_MemberName::vmindex(target()) == VM_INDEX_UNINITIALIZED) {
-    MethodHandles::resolve_MemberName(target, CHECK);
-  }
-
-  KlassHandle receiver_limit; int decode_flags = 0;
-  methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
-  if (m.is_null()) { THROW_MSG(vmSymbols::java_lang_InternalError(), "no such method"); }
-
-  // The trusted Java code that calls this method should already have performed
-  // access checks on behalf of the given caller.  But, we can verify this.
-  if (VerifyMethodHandles && caller_jh != NULL) {
-    KlassHandle caller(THREAD, java_lang_Class::as_klassOop(JNIHandles::resolve_non_null(caller_jh)));
-    // If this were a bytecode, the first access check would be against
-    // the "reference class" mentioned in the CONSTANT_Methodref.
-    // We don't know at this point which class that was, and if we
-    // check against m.method_holder we might get the wrong answer.
-    // So we just make sure to handle this check when the resolution
-    // happens, when we call resolve_MemberName.
-    //
-    // (A public class can inherit public members from private supers,
-    // and it would be wrong to check access against the private super
-    // if the original symbolic reference was against the public class.)
-    //
-    // If there were a bytecode, the next step would be to lookup the method
-    // in the reference class, then then check the method's access bits.
-    // Emulate LinkResolver::check_method_accessability.
-    klassOop resolved_klass = m->method_holder();
-    if (!Reflection::verify_field_access(caller->as_klassOop(),
-                                         resolved_klass, resolved_klass,
-                                         m->access_flags(),
-                                         true)) {
-      // %%% following cutout belongs in Reflection::verify_field_access?
-      bool same_pm = Reflection::is_same_package_member(caller->as_klassOop(),
-                                                        resolved_klass, THREAD);
-      if (!same_pm) {
-        THROW_MSG(vmSymbols::java_lang_InternalError(), m->name_and_sig_as_C_string());
-      }
-    }
-  }
-
-  MethodHandles::init_DirectMethodHandle(mh, m, (do_dispatch != JNI_FALSE), CHECK);
-  stress_method_handle_walk(mh, CHECK);
-}
-JVM_END
-
-// bound method handles
-JVM_ENTRY(void, MHN_init_BMH(JNIEnv *env, jobject igcls, jobject mh_jh,
-                             jobject target_jh, int argnum)) {
-  ResourceMark rm;              // for error messages
-
-  // This is the guy we are initializing:
-  if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
-  Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
-
-  // Early returns out of this method leave the BMH in an unfinished state.
-  assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
-
-  if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
-  Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
-
-  if (!java_lang_invoke_MethodHandle::is_instance(target())) {
-    // Target object is a reflective method.  (%%% Do we need this alternate path?)
-    Untested("init_BMH of non-MH");
-    if (argnum != 0) { THROW(vmSymbols::java_lang_InternalError()); }
-    KlassHandle receiver_limit; int decode_flags = 0;
-    methodHandle m = MethodHandles::decode_method(target(), receiver_limit, decode_flags);
-    MethodHandles::init_BoundMethodHandle_with_receiver(mh, m,
-                                                       receiver_limit,
-                                                       decode_flags,
-                                                       CHECK);
-  } else {
-    // Build a BMH on top of a DMH or another BMH:
-    MethodHandles::init_BoundMethodHandle(mh, target, argnum, CHECK);
-  }
-
-  if (StressMethodHandleWalk) {
-    if (mh->klass() == SystemDictionary::BoundMethodHandle_klass())
-      stress_method_handle_walk(mh, CHECK);
-    // else don't, since the subclass has not yet initialized its own fields
-  }
-}
-JVM_END
-
-// adapter method handles
-JVM_ENTRY(void, MHN_init_AMH(JNIEnv *env, jobject igcls, jobject mh_jh,
-                             jobject target_jh, int argnum)) {
-  // This is the guy we are initializing:
-  if (mh_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "self is null"); }
-  if (target_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "target is null"); }
-  Handle mh(THREAD, JNIHandles::resolve_non_null(mh_jh));
-  Handle target(THREAD, JNIHandles::resolve_non_null(target_jh));
-
-  // Early returns out of this method leave the AMH in an unfinished state.
-  assert(java_lang_invoke_MethodHandle::vmentry(mh()) == NULL, "must be safely null");
-
-  MethodHandles::init_AdapterMethodHandle(mh, target, argnum, CHECK);
-  stress_method_handle_walk(mh, CHECK);
-}
-JVM_END
-
-// method type forms
-JVM_ENTRY(void, MHN_init_MT(JNIEnv *env, jobject igcls, jobject erased_jh)) {
-  if (erased_jh == NULL)  return;
-  if (TraceMethodHandles) {
-    tty->print("creating MethodType form ");
-    if (WizardMode || Verbose) {   // Warning: this calls Java code on the MH!
-      // call Object.toString()
-      Symbol* name = vmSymbols::toString_name();
-      Symbol* sig = vmSymbols::void_string_signature();
-      JavaCallArguments args(Handle(THREAD, JNIHandles::resolve_non_null(erased_jh)));
-      JavaValue result(T_OBJECT);
-      JavaCalls::call_virtual(&result, SystemDictionary::Object_klass(), name, sig,
-                              &args, CHECK);
-      Handle str(THREAD, (oop)result.get_jobject());
-      java_lang_String::print(str, tty);
-    }
-    tty->cr();
-  }
-}
-JVM_END
-
-// debugging and reflection
-JVM_ENTRY(jobject, MHN_getTarget(JNIEnv *env, jobject igcls, jobject mh_jh, jint format)) {
-  Handle mh(THREAD, JNIHandles::resolve(mh_jh));
-  if (!java_lang_invoke_MethodHandle::is_instance(mh())) {
-    THROW_NULL(vmSymbols::java_lang_IllegalArgumentException());
-  }
-  oop target = MethodHandles::encode_target(mh, format, CHECK_NULL);
-  return JNIHandles::make_local(THREAD, target);
-}
-JVM_END
-
 JVM_ENTRY(jint, MHN_getConstant(JNIEnv *env, jobject igcls, jint which)) {
   switch (which) {
-  case MethodHandles::GC_JVM_PUSH_LIMIT:
-    guarantee(MethodHandlePushLimit >= 2 && MethodHandlePushLimit <= 0xFF,
-              "MethodHandlePushLimit parameter must be in valid range");
-    return MethodHandlePushLimit;
-  case MethodHandles::GC_JVM_STACK_MOVE_UNIT:
-    // return number of words per slot, signed according to stack direction
-    return MethodHandles::stack_move_unit();
-  case MethodHandles::GC_CONV_OP_IMPLEMENTED_MASK:
-    return MethodHandles::adapter_conversion_ops_supported_mask();
   case MethodHandles::GC_COUNT_GWT:
 #ifdef COMPILER2
     return true;
@@ -2872,64 +933,54 @@
 JVM_END
 
 #ifndef PRODUCT
-#define EACH_NAMED_CON(template) \
-  /* hold back this one until JDK stabilizes */ \
-  /* template(MethodHandles,GC_JVM_PUSH_LIMIT) */  \
-  /* hold back this one until JDK stabilizes */ \
-  /* template(MethodHandles,GC_JVM_STACK_MOVE_UNIT) */ \
-  /* hold back this one until JDK stabilizes */ \
-  /* template(MethodHandles,GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS) */ \
-    template(MethodHandles,ETF_HANDLE_OR_METHOD_NAME) \
-    template(MethodHandles,ETF_DIRECT_HANDLE) \
-    template(MethodHandles,ETF_METHOD_NAME) \
-    template(MethodHandles,ETF_REFLECT_METHOD) \
+#define EACH_NAMED_CON(template, requirement) \
+    template(MethodHandles,GC_COUNT_GWT) \
     template(java_lang_invoke_MemberName,MN_IS_METHOD) \
     template(java_lang_invoke_MemberName,MN_IS_CONSTRUCTOR) \
     template(java_lang_invoke_MemberName,MN_IS_FIELD) \
     template(java_lang_invoke_MemberName,MN_IS_TYPE) \
     template(java_lang_invoke_MemberName,MN_SEARCH_SUPERCLASSES) \
     template(java_lang_invoke_MemberName,MN_SEARCH_INTERFACES) \
-    template(java_lang_invoke_MemberName,VM_INDEX_UNINITIALIZED) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_ONLY) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_RETYPE_RAW) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_CHECK_CAST) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_PRIM) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_REF_TO_PRIM) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_PRIM_TO_REF) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_SWAP_ARGS) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_ROT_ARGS) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_DUP_ARGS) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_DROP_ARGS) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_COLLECT_ARGS) \
-    template(java_lang_invoke_AdapterMethodHandle,OP_SPREAD_ARGS) \
-      /* hold back this one until JDK stabilizes */ \
-      /*template(java_lang_invoke_AdapterMethodHandle,CONV_OP_LIMIT)*/  \
-    template(java_lang_invoke_AdapterMethodHandle,CONV_OP_MASK) \
-    template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_MASK) \
-    template(java_lang_invoke_AdapterMethodHandle,CONV_VMINFO_SHIFT) \
-    template(java_lang_invoke_AdapterMethodHandle,CONV_OP_SHIFT) \
-    template(java_lang_invoke_AdapterMethodHandle,CONV_DEST_TYPE_SHIFT) \
-    template(java_lang_invoke_AdapterMethodHandle,CONV_SRC_TYPE_SHIFT) \
-    template(java_lang_invoke_AdapterMethodHandle,CONV_STACK_MOVE_SHIFT) \
-    template(java_lang_invoke_AdapterMethodHandle,CONV_STACK_MOVE_MASK) \
+    template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_SHIFT) \
+    template(java_lang_invoke_MemberName,MN_REFERENCE_KIND_MASK) \
+    template(MethodHandles,GC_LAMBDA_SUPPORT) \
     /*end*/
 
+#define IGNORE_REQ(req_expr) /* req_expr */
 #define ONE_PLUS(scope,value) 1+
-static const int con_value_count = EACH_NAMED_CON(ONE_PLUS) 0;
+static const int con_value_count = EACH_NAMED_CON(ONE_PLUS, IGNORE_REQ) 0;
 #define VALUE_COMMA(scope,value) scope::value,
-static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA) 0 };
+static const int con_values[con_value_count+1] = { EACH_NAMED_CON(VALUE_COMMA, IGNORE_REQ) 0 };
 #define STRING_NULL(scope,value) #value "\0"
-static const char con_names[] = { EACH_NAMED_CON(STRING_NULL) };
+static const char con_names[] = { EACH_NAMED_CON(STRING_NULL, IGNORE_REQ) };
+
+static bool advertise_con_value(int which) {
+  if (which < 0)  return false;
+  bool ok = true;
+  int count = 0;
+#define INC_COUNT(scope,value) \
+  ++count;
+#define CHECK_REQ(req_expr) \
+  if (which < count)  return ok; \
+  ok = (req_expr);
+  EACH_NAMED_CON(INC_COUNT, CHECK_REQ);
+#undef INC_COUNT
+#undef CHECK_REQ
+  assert(count == con_value_count, "");
+  if (which < count)  return ok;
+  return false;
+}
 
 #undef ONE_PLUS
 #undef VALUE_COMMA
 #undef STRING_NULL
 #undef EACH_NAMED_CON
-#endif
+#endif // PRODUCT
 
 JVM_ENTRY(jint, MHN_getNamedCon(JNIEnv *env, jobject igcls, jint which, jobjectArray box_jh)) {
 #ifndef PRODUCT
-  if (which >= 0 && which < con_value_count) {
+  if (advertise_con_value(which)) {
+    assert(which >= 0 && which < con_value_count, "");
     int con = con_values[which];
     objArrayHandle box(THREAD, (objArrayOop) JNIHandles::resolve(box_jh));
     if (box.not_null() && box->klass() == Universe::objectArrayKlassObj() && box->length() > 0) {
@@ -2965,13 +1016,14 @@
 JVM_END
 
 // void resolve(MemberName self, Class<?> caller)
-JVM_ENTRY(void, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
-  if (mname_jh == NULL) { THROW_MSG(vmSymbols::java_lang_InternalError(), "mname is null"); }
+JVM_ENTRY(jobject, MHN_resolve_Mem(JNIEnv *env, jobject igcls, jobject mname_jh, jclass caller_jh)) {
+  if (mname_jh == NULL) { THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "mname is null"); }
   Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
 
   // The trusted Java code that calls this method should already have performed
   // access checks on behalf of the given caller.  But, we can verify this.
-  if (VerifyMethodHandles && caller_jh != NULL) {
+  if (VerifyMethodHandles && caller_jh != NULL &&
+      java_lang_invoke_MemberName::clazz(mname()) != NULL) {
     klassOop reference_klass = java_lang_Class::as_klassOop(java_lang_invoke_MemberName::clazz(mname()));
     if (reference_klass != NULL) {
       // Emulate LinkResolver::check_klass_accessability.
@@ -2979,15 +1031,97 @@
       if (!Reflection::verify_class_access(caller,
                                            reference_klass,
                                            true)) {
-        THROW_MSG(vmSymbols::java_lang_InternalError(), Klass::cast(reference_klass)->external_name());
+        THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), Klass::cast(reference_klass)->external_name());
       }
     }
   }
 
-  MethodHandles::resolve_MemberName(mname, CHECK);
+  Handle resolved = MethodHandles::resolve_MemberName(mname, CHECK_NULL);
+  if (resolved.is_null()) {
+    int flags = java_lang_invoke_MemberName::flags(mname());
+    int ref_kind = (flags >> REFERENCE_KIND_SHIFT) & REFERENCE_KIND_MASK;
+    if (!MethodHandles::ref_kind_is_valid(ref_kind)) {
+      THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "obsolete MemberName format");
+    }
+    if ((flags & ALL_KINDS) == IS_FIELD) {
+      THROW_MSG_NULL(vmSymbols::java_lang_NoSuchMethodError(), "field resolution failed");
+    } else if ((flags & ALL_KINDS) == IS_METHOD ||
+               (flags & ALL_KINDS) == IS_CONSTRUCTOR) {
+      THROW_MSG_NULL(vmSymbols::java_lang_NoSuchFieldError(), "method resolution failed");
+    } else {
+      THROW_MSG_NULL(vmSymbols::java_lang_LinkageError(), "resolution failed");
+    }
+  }
+
+  return JNIHandles::make_local(THREAD, resolved());
 }
 JVM_END
 
+static jlong find_member_field_offset(oop mname, bool must_be_static, TRAPS) {
+  if (mname == NULL ||
+      java_lang_invoke_MemberName::vmtarget(mname) == NULL) {
+    THROW_MSG_0(vmSymbols::java_lang_InternalError(), "mname not resolved");
+  } else {
+    int flags = java_lang_invoke_MemberName::flags(mname);
+    if ((flags & IS_FIELD) != 0 &&
+        (must_be_static
+         ? (flags & JVM_ACC_STATIC) != 0
+         : (flags & JVM_ACC_STATIC) == 0)) {
+      int vmindex = java_lang_invoke_MemberName::vmindex(mname);
+      return (jlong) vmindex;
+    }
+  }
+  const char* msg = (must_be_static ? "static field required" : "non-static field required");
+  THROW_MSG_0(vmSymbols::java_lang_InternalError(), msg);
+  return 0;
+}
+
+JVM_ENTRY(jlong, MHN_objectFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
+  return find_member_field_offset(JNIHandles::resolve(mname_jh), false, THREAD);
+}
+JVM_END
+
+JVM_ENTRY(jlong, MHN_staticFieldOffset(JNIEnv *env, jobject igcls, jobject mname_jh)) {
+  return find_member_field_offset(JNIHandles::resolve(mname_jh), true, THREAD);
+}
+JVM_END
+
+JVM_ENTRY(jobject, MHN_staticFieldBase(JNIEnv *env, jobject igcls, jobject mname_jh)) {
+  // use the other function to perform sanity checks:
+  jlong ignore = find_member_field_offset(JNIHandles::resolve(mname_jh), true, CHECK_NULL);
+  oop clazz = java_lang_invoke_MemberName::clazz(JNIHandles::resolve_non_null(mname_jh));
+  return JNIHandles::make_local(THREAD, clazz);
+}
+JVM_END
+
+JVM_ENTRY(jobject, MHN_getMemberVMInfo(JNIEnv *env, jobject igcls, jobject mname_jh)) {
+  if (mname_jh == NULL)  return NULL;
+  Handle mname(THREAD, JNIHandles::resolve_non_null(mname_jh));
+  intptr_t vmindex  = java_lang_invoke_MemberName::vmindex(mname());
+  Handle   vmtarget = java_lang_invoke_MemberName::vmtarget(mname());
+  objArrayHandle result = oopFactory::new_objArray(SystemDictionary::Object_klass(), 2, CHECK_NULL);
+  jvalue vmindex_value; vmindex_value.j = (long)vmindex;
+  oop x = java_lang_boxing_object::create(T_LONG, &vmindex_value, CHECK_NULL);
+  result->obj_at_put(0, x);
+  x = NULL;
+  if (vmtarget.is_null() || vmtarget->is_instance()) {
+    x = vmtarget();
+  } else if (vmtarget->is_klass()) {
+    x = Klass::cast((klassOop) vmtarget())->java_mirror();
+  } else {
+    Handle mname2 = MethodHandles::new_MemberName(CHECK_NULL);
+    if (vmtarget->is_method())
+      x = MethodHandles::init_method_MemberName(mname2(), methodOop(vmtarget()), false, NULL);
+    else
+      x = MethodHandles::init_MemberName(mname2(), vmtarget());
+  }
+  result->obj_at_put(1, x);
+  return JNIHandles::make_local(env, result());
+}
+JVM_END
+
+
+
 //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
 //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
 JVM_ENTRY(jint, MHN_getMembers(JNIEnv *env, jobject igcls,
@@ -3053,60 +1187,6 @@
 }
 JVM_END
 
-methodOop MethodHandles::resolve_raise_exception_method(TRAPS) {
-  if (_raise_exception_method != NULL) {
-    // no need to do it twice
-    return raise_exception_method();
-  }
-  // LinkResolver::resolve_invokedynamic can reach this point
-  // because an invokedynamic has failed very early (7049415)
-  KlassHandle MHN_klass = SystemDictionaryHandles::MethodHandleNatives_klass();
-  if (MHN_klass.not_null()) {
-    TempNewSymbol raiseException_name = SymbolTable::new_symbol("raiseException", CHECK_NULL);
-    TempNewSymbol raiseException_sig = SymbolTable::new_symbol("(ILjava/lang/Object;Ljava/lang/Object;)V", CHECK_NULL);
-    methodOop raiseException_method  = instanceKlass::cast(MHN_klass->as_klassOop())
-                  ->find_method(raiseException_name, raiseException_sig);
-    if (raiseException_method != NULL && raiseException_method->is_static()) {
-      return raiseException_method;
-    }
-  }
-  // not found; let the caller deal with it
-  return NULL;
-}
-void MethodHandles::raise_exception(int code, oop actual, oop required, TRAPS) {
-  methodOop raiseException_method = resolve_raise_exception_method(CHECK);
-  if (raiseException_method != NULL &&
-      instanceKlass::cast(raiseException_method->method_holder())->is_not_initialized()) {
-    instanceKlass::cast(raiseException_method->method_holder())->initialize(CHECK);
-    // it had better be resolved by now, or maybe JSR 292 failed to load
-    raiseException_method = raise_exception_method();
-  }
-  if (raiseException_method == NULL) {
-    THROW_MSG(vmSymbols::java_lang_InternalError(), "no raiseException method");
-  }
-  JavaCallArguments args;
-  args.push_int(code);
-  args.push_oop(actual);
-  args.push_oop(required);
-  JavaValue result(T_VOID);
-  JavaCalls::call(&result, raiseException_method, &args, CHECK);
-}
-
-JVM_ENTRY(jobject, MH_invoke_UOE(JNIEnv *env, jobject igmh, jobjectArray igargs)) {
-    TempNewSymbol UOE_name = SymbolTable::new_symbol("java/lang/UnsupportedOperationException", CHECK_NULL);
-    THROW_MSG_NULL(UOE_name, "MethodHandle.invoke cannot be invoked reflectively");
-    return NULL;
-}
-JVM_END
-
-JVM_ENTRY(jobject, MH_invokeExact_UOE(JNIEnv *env, jobject igmh, jobjectArray igargs)) {
-    TempNewSymbol UOE_name = SymbolTable::new_symbol("java/lang/UnsupportedOperationException", CHECK_NULL);
-    THROW_MSG_NULL(UOE_name, "MethodHandle.invokeExact cannot be invoked reflectively");
-    return NULL;
-}
-JVM_END
-
-
 /// JVM_RegisterMethodHandleMethods
 
 #undef CS  // Solaris builds complain
@@ -3121,48 +1201,32 @@
 #define MT    JLINV"MethodType;"
 #define MH    JLINV"MethodHandle;"
 #define MEM   JLINV"MemberName;"
-#define AMH   JLINV"AdapterMethodHandle;"
-#define BMH   JLINV"BoundMethodHandle;"
-#define DMH   JLINV"DirectMethodHandle;"
 
 #define CC (char*)  /*cast a literal from (const char*)*/
 #define FN_PTR(f) CAST_FROM_FN_PTR(void*, &f)
 
 // These are the native methods on java.lang.invoke.MethodHandleNatives.
-static JNINativeMethod methods[] = {
-  // void init(MemberName self, AccessibleObject ref)
-  {CC"init",                      CC"("AMH""MH"I)V",                     FN_PTR(MHN_init_AMH)},
-  {CC"init",                      CC"("BMH""OBJ"I)V",                    FN_PTR(MHN_init_BMH)},
-  {CC"init",                      CC"("DMH""OBJ"Z"CLS")V",               FN_PTR(MHN_init_DMH)},
-  {CC"init",                      CC"("MT")V",                           FN_PTR(MHN_init_MT)},
+static JNINativeMethod required_methods_JDK8[] = {
   {CC"init",                      CC"("MEM""OBJ")V",                     FN_PTR(MHN_init_Mem)},
   {CC"expand",                    CC"("MEM")V",                          FN_PTR(MHN_expand_Mem)},
-  {CC"resolve",                   CC"("MEM""CLS")V",                     FN_PTR(MHN_resolve_Mem)},
-  {CC"getTarget",                 CC"("MH"I)"OBJ,                        FN_PTR(MHN_getTarget)},
+  {CC"resolve",                   CC"("MEM""CLS")"MEM,                   FN_PTR(MHN_resolve_Mem)},
   {CC"getConstant",               CC"(I)I",                              FN_PTR(MHN_getConstant)},
   //  static native int getNamedCon(int which, Object[] name)
   {CC"getNamedCon",               CC"(I["OBJ")I",                        FN_PTR(MHN_getNamedCon)},
   //  static native int getMembers(Class<?> defc, String matchName, String matchSig,
   //          int matchFlags, Class<?> caller, int skip, MemberName[] results);
-  {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)}
-};
-
-static JNINativeMethod call_site_methods[] = {
+  {CC"getMembers",                CC"("CLS""STRG""STRG"I"CLS"I["MEM")I", FN_PTR(MHN_getMembers)},
+  {CC"objectFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_objectFieldOffset)},
   {CC"setCallSiteTargetNormal",   CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetNormal)},
-  {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)}
-};
-
-static JNINativeMethod invoke_methods[] = {
-  // void init(MemberName self, AccessibleObject ref)
-  {CC"invoke",                    CC"(["OBJ")"OBJ,                       FN_PTR(MH_invoke_UOE)},
-  {CC"invokeExact",               CC"(["OBJ")"OBJ,                       FN_PTR(MH_invokeExact_UOE)}
+  {CC"setCallSiteTargetVolatile", CC"("CS""MH")V",                       FN_PTR(MHN_setCallSiteTargetVolatile)},
+  {CC"staticFieldOffset",         CC"("MEM")J",                          FN_PTR(MHN_staticFieldOffset)},
+  {CC"staticFieldBase",           CC"("MEM")"OBJ,                        FN_PTR(MHN_staticFieldBase)},
+  {CC"getMemberVMInfo",           CC"("MEM")"OBJ,                        FN_PTR(MHN_getMemberVMInfo)}
 };
 
 // This one function is exported, used by NativeLookup.
 
 JVM_ENTRY(void, JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass MHN_class)) {
-  assert(MethodHandles::spot_check_entry_names(), "entry enum is OK");
-
   if (!EnableInvokeDynamic) {
     warning("JSR 292 is disabled in this JVM.  Use -XX:+UnlockDiagnosticVMOptions -XX:+EnableInvokeDynamic to enable.");
     return;  // bind nothing
@@ -3171,36 +1235,29 @@
   assert(!MethodHandles::enabled(), "must not be enabled");
   bool enable_MH = true;
 
-  {
+  jclass MH_class = NULL;
+  if (SystemDictionary::MethodHandle_klass() == NULL) {
+    enable_MH = false;
+  } else {
+    oop mirror = Klass::cast(SystemDictionary::MethodHandle_klass())->java_mirror();
+    MH_class = (jclass) JNIHandles::make_local(env, mirror);
+  }
+
+  int status;
+
+  if (enable_MH) {
     ThreadToNativeFromVM ttnfv(thread);
-    int status = env->RegisterNatives(MHN_class, methods, sizeof(methods)/sizeof(JNINativeMethod));
-    if (!env->ExceptionOccurred()) {
-      const char* L_MH_name = (JLINV "MethodHandle");
-      const char* MH_name = L_MH_name+1;
-      jclass MH_class = env->FindClass(MH_name);
-      status = env->RegisterNatives(MH_class, invoke_methods, sizeof(invoke_methods)/sizeof(JNINativeMethod));
-    }
-    if (env->ExceptionOccurred()) {
+
+    status = env->RegisterNatives(MHN_class, required_methods_JDK8, sizeof(required_methods_JDK8)/sizeof(JNINativeMethod));
+    if (status != JNI_OK || env->ExceptionOccurred()) {
       warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
       enable_MH = false;
       env->ExceptionClear();
     }
-
-    status = env->RegisterNatives(MHN_class, call_site_methods, sizeof(call_site_methods)/sizeof(JNINativeMethod));
-    if (env->ExceptionOccurred()) {
-      // Exception is okay until 7087357
-      env->ExceptionClear();
-    }
   }
 
-  if (enable_MH) {
-    methodOop raiseException_method = MethodHandles::resolve_raise_exception_method(CHECK);
-    if (raiseException_method != NULL) {
-      MethodHandles::set_raise_exception_method(raiseException_method);
-    } else {
-      warning("JSR 292 method handle code is mismatched to this JVM.  Disabling support.");
-      enable_MH = false;
-    }
+  if (TraceInvokeDynamic) {
+    tty->print_cr("MethodHandle support loaded (using LambdaForms)");
   }
 
   if (enable_MH) {
diff --git a/hotspot/src/share/vm/prims/methodHandles.hpp b/hotspot/src/share/vm/prims/methodHandles.hpp
index 514ba6a..c96f0e5 100644
--- a/hotspot/src/share/vm/prims/methodHandles.hpp
+++ b/hotspot/src/share/vm/prims/methodHandles.hpp
@@ -33,523 +33,36 @@
 
 class MacroAssembler;
 class Label;
-class MethodHandleEntry;
 
 class MethodHandles: AllStatic {
   // JVM support for MethodHandle, MethodType, and related types
   // in java.lang.invoke and sun.invoke.
   // See also  javaClasses for layouts java_lang_invoke_Method{Handle,Type,Type::Form}.
  public:
-  enum EntryKind {
-    _raise_exception,           // stub for error generation from other stubs
-    _invokestatic_mh,           // how a MH emulates invokestatic
-    _invokespecial_mh,          // ditto for the other invokes...
-    _invokevirtual_mh,
-    _invokeinterface_mh,
-    _bound_ref_mh,              // reference argument is bound
-    _bound_int_mh,              // int argument is bound (via an Integer or Float)
-    _bound_long_mh,             // long argument is bound (via a Long or Double)
-    _bound_ref_direct_mh,       // same as above, with direct linkage to methodOop
-    _bound_int_direct_mh,
-    _bound_long_direct_mh,
-
-    _adapter_mh_first,     // adapter sequence goes here...
-    _adapter_retype_only   = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_RETYPE_ONLY,
-    _adapter_retype_raw    = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_RETYPE_RAW,
-    _adapter_check_cast    = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_CHECK_CAST,
-    _adapter_prim_to_prim  = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_PRIM,
-    _adapter_ref_to_prim   = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_REF_TO_PRIM,
-    _adapter_prim_to_ref   = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_PRIM_TO_REF,
-    _adapter_swap_args     = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_SWAP_ARGS,
-    _adapter_rot_args      = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_ROT_ARGS,
-    _adapter_dup_args      = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_DUP_ARGS,
-    _adapter_drop_args     = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_DROP_ARGS,
-    _adapter_collect_args  = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_COLLECT_ARGS,
-    _adapter_spread_args   = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_SPREAD_ARGS,
-    _adapter_fold_args     = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::OP_FOLD_ARGS,
-    _adapter_unused_13     = _adapter_mh_first + 13,  //hole in the CONV_OP enumeration
-    _adapter_mh_last       = _adapter_mh_first + java_lang_invoke_AdapterMethodHandle::CONV_OP_LIMIT - 1,
-
-    // Optimized adapter types
-
-    // argument list reordering
-    _adapter_opt_swap_1,
-    _adapter_opt_swap_2,
-    _adapter_opt_rot_1_up,
-    _adapter_opt_rot_1_down,
-    _adapter_opt_rot_2_up,
-    _adapter_opt_rot_2_down,
-    // primitive single to single:
-    _adapter_opt_i2i,           // i2c, i2z, i2b, i2s
-    // primitive double to single:
-    _adapter_opt_l2i,
-    _adapter_opt_d2f,
-    // primitive single to double:
-    _adapter_opt_i2l,
-    _adapter_opt_f2d,
-    // conversion between floating point and integer type is handled by Java
-
-    // reference to primitive:
-    _adapter_opt_unboxi,
-    _adapter_opt_unboxl,
-
-    // %% Maybe tame the following with a VM_SYMBOLS_DO type macro?
-
-    // how a blocking adapter returns (platform-dependent)
-    _adapter_opt_return_ref,
-    _adapter_opt_return_int,
-    _adapter_opt_return_long,
-    _adapter_opt_return_float,
-    _adapter_opt_return_double,
-    _adapter_opt_return_void,
-    _adapter_opt_return_S0_ref,  // return ref to S=0 (last slot)
-    _adapter_opt_return_S1_ref,  // return ref to S=1 (2nd-to-last slot)
-    _adapter_opt_return_S2_ref,
-    _adapter_opt_return_S3_ref,
-    _adapter_opt_return_S4_ref,
-    _adapter_opt_return_S5_ref,
-    _adapter_opt_return_any,     // dynamically select r/i/l/f/d
-    _adapter_opt_return_FIRST = _adapter_opt_return_ref,
-    _adapter_opt_return_LAST  = _adapter_opt_return_any,
-
-    // spreading (array length cases 0, 1, ...)
-    _adapter_opt_spread_0,       // spread empty array to N=0 arguments
-    _adapter_opt_spread_1_ref,   // spread Object[] to N=1 argument
-    _adapter_opt_spread_2_ref,   // spread Object[] to N=2 arguments
-    _adapter_opt_spread_3_ref,   // spread Object[] to N=3 arguments
-    _adapter_opt_spread_4_ref,   // spread Object[] to N=4 arguments
-    _adapter_opt_spread_5_ref,   // spread Object[] to N=5 arguments
-    _adapter_opt_spread_ref,     // spread Object[] to N arguments
-    _adapter_opt_spread_byte,    // spread byte[] or boolean[] to N arguments
-    _adapter_opt_spread_char,    // spread char[], etc., to N arguments
-    _adapter_opt_spread_short,   // spread short[], etc., to N arguments
-    _adapter_opt_spread_int,     // spread int[], short[], etc., to N arguments
-    _adapter_opt_spread_long,    // spread long[] to N arguments
-    _adapter_opt_spread_float,   // spread float[] to N arguments
-    _adapter_opt_spread_double,  // spread double[] to N arguments
-    _adapter_opt_spread_FIRST = _adapter_opt_spread_0,
-    _adapter_opt_spread_LAST  = _adapter_opt_spread_double,
-
-    // blocking filter/collect conversions
-    // These collect N arguments and replace them (at slot S) by a return value
-    // which is passed to the final target, along with the unaffected arguments.
-    // collect_{N}_{T} collects N arguments at any position into a T value
-    // collect_{N}_S{S}_{T} collects N arguments at slot S into a T value
-    // collect_{T} collects any number of arguments at any position
-    // filter_S{S}_{T} is the same as collect_1_S{S}_{T} (a unary collection)
-    // (collect_2 is also usable as a filter, with long or double arguments)
-    _adapter_opt_collect_ref,    // combine N arguments, replace with a reference
-    _adapter_opt_collect_int,    // combine N arguments, replace with an int, short, etc.
-    _adapter_opt_collect_long,   // combine N arguments, replace with a long
-    _adapter_opt_collect_float,  // combine N arguments, replace with a float
-    _adapter_opt_collect_double, // combine N arguments, replace with a double
-    _adapter_opt_collect_void,   // combine N arguments, replace with nothing
-    // if there is a small fixed number to push, do so without a loop:
-    _adapter_opt_collect_0_ref,  // collect N=0 arguments, insert a reference
-    _adapter_opt_collect_1_ref,  // collect N=1 argument, replace with a reference
-    _adapter_opt_collect_2_ref,  // combine N=2 arguments, replace with a reference
-    _adapter_opt_collect_3_ref,  // combine N=3 arguments, replace with a reference
-    _adapter_opt_collect_4_ref,  // combine N=4 arguments, replace with a reference
-    _adapter_opt_collect_5_ref,  // combine N=5 arguments, replace with a reference
-    // filters are an important special case because they never move arguments:
-    _adapter_opt_filter_S0_ref,  // filter N=1 argument at S=0, replace with a reference
-    _adapter_opt_filter_S1_ref,  // filter N=1 argument at S=1, replace with a reference
-    _adapter_opt_filter_S2_ref,  // filter N=1 argument at S=2, replace with a reference
-    _adapter_opt_filter_S3_ref,  // filter N=1 argument at S=3, replace with a reference
-    _adapter_opt_filter_S4_ref,  // filter N=1 argument at S=4, replace with a reference
-    _adapter_opt_filter_S5_ref,  // filter N=1 argument at S=5, replace with a reference
-    // these move arguments, but they are important for boxing
-    _adapter_opt_collect_2_S0_ref,  // combine last N=2 arguments, replace with a reference
-    _adapter_opt_collect_2_S1_ref,  // combine N=2 arguments at S=1, replace with a reference
-    _adapter_opt_collect_2_S2_ref,  // combine N=2 arguments at S=2, replace with a reference
-    _adapter_opt_collect_2_S3_ref,  // combine N=2 arguments at S=3, replace with a reference
-    _adapter_opt_collect_2_S4_ref,  // combine N=2 arguments at S=4, replace with a reference
-    _adapter_opt_collect_2_S5_ref,  // combine N=2 arguments at S=5, replace with a reference
-    _adapter_opt_collect_FIRST = _adapter_opt_collect_ref,
-    _adapter_opt_collect_LAST  = _adapter_opt_collect_2_S5_ref,
-
-    // blocking folding conversions
-    // these are like collects, but retain all the N arguments for the final target
-    //_adapter_opt_fold_0_ref,   // same as _adapter_opt_collect_0_ref
-    // fold_{N}_{T} processes N arguments at any position into a T value, which it inserts
-    // fold_{T} processes any number of arguments at any position
-    _adapter_opt_fold_ref,       // process N arguments, prepend a reference
-    _adapter_opt_fold_int,       // process N arguments, prepend an int, short, etc.
-    _adapter_opt_fold_long,      // process N arguments, prepend a long
-    _adapter_opt_fold_float,     // process N arguments, prepend a float
-    _adapter_opt_fold_double,    // process N arguments, prepend a double
-    _adapter_opt_fold_void,      // process N arguments, but leave the list unchanged
-    _adapter_opt_fold_1_ref,     // process N=1 argument, prepend a reference
-    _adapter_opt_fold_2_ref,     // process N=2 arguments, prepend a reference
-    _adapter_opt_fold_3_ref,     // process N=3 arguments, prepend a reference
-    _adapter_opt_fold_4_ref,     // process N=4 arguments, prepend a reference
-    _adapter_opt_fold_5_ref,     // process N=5 arguments, prepend a reference
-    _adapter_opt_fold_FIRST = _adapter_opt_fold_ref,
-    _adapter_opt_fold_LAST  = _adapter_opt_fold_5_ref,
-
-    _adapter_opt_profiling,
-
-    _EK_LIMIT,
-    _EK_FIRST = 0
-  };
-
  public:
   static bool enabled()                         { return _enabled; }
   static void set_enabled(bool z);
 
  private:
-  enum {  // import java_lang_invoke_AdapterMethodHandle::CONV_OP_*
-    CONV_OP_LIMIT         = java_lang_invoke_AdapterMethodHandle::CONV_OP_LIMIT,
-    CONV_OP_MASK          = java_lang_invoke_AdapterMethodHandle::CONV_OP_MASK,
-    CONV_TYPE_MASK        = java_lang_invoke_AdapterMethodHandle::CONV_TYPE_MASK,
-    CONV_VMINFO_MASK      = java_lang_invoke_AdapterMethodHandle::CONV_VMINFO_MASK,
-    CONV_VMINFO_SHIFT     = java_lang_invoke_AdapterMethodHandle::CONV_VMINFO_SHIFT,
-    CONV_OP_SHIFT         = java_lang_invoke_AdapterMethodHandle::CONV_OP_SHIFT,
-    CONV_DEST_TYPE_SHIFT  = java_lang_invoke_AdapterMethodHandle::CONV_DEST_TYPE_SHIFT,
-    CONV_SRC_TYPE_SHIFT   = java_lang_invoke_AdapterMethodHandle::CONV_SRC_TYPE_SHIFT,
-    CONV_STACK_MOVE_SHIFT = java_lang_invoke_AdapterMethodHandle::CONV_STACK_MOVE_SHIFT,
-    CONV_STACK_MOVE_MASK  = java_lang_invoke_AdapterMethodHandle::CONV_STACK_MOVE_MASK
-  };
-
   static bool _enabled;
-  static MethodHandleEntry* _entries[_EK_LIMIT];
-  static const char*        _entry_names[_EK_LIMIT+1];
-  static jobject            _raise_exception_method;
-  static address            _adapter_return_handlers[CONV_TYPE_MASK+1];
 
   // Adapters.
   static MethodHandlesAdapterBlob* _adapter_code;
 
-  static bool ek_valid(EntryKind ek)            { return (uint)ek < (uint)_EK_LIMIT; }
-  static bool conv_op_valid(int op)             { return (uint)op < (uint)CONV_OP_LIMIT; }
-
- public:
-  static bool    have_entry(EntryKind ek)       { return ek_valid(ek) && _entries[ek] != NULL; }
-  static MethodHandleEntry* entry(EntryKind ek) { assert(ek_valid(ek), "initialized");
-                                                  return _entries[ek]; }
-  static const char* entry_name(EntryKind ek)   { assert(ek_valid(ek), "oob");
-                                                  return _entry_names[ek]; }
-  static EntryKind adapter_entry_kind(int op)   { assert(conv_op_valid(op), "oob");
-                                                  return EntryKind(_adapter_mh_first + op); }
-
-  static void init_entry(EntryKind ek, MethodHandleEntry* me) {
-    assert(ek_valid(ek), "oob");
-    assert(_entries[ek] == NULL, "no double initialization");
-    _entries[ek] = me;
-  }
-
-  // Some adapter helper functions.
-  static EntryKind ek_original_kind(EntryKind ek) {
-    if (ek <= _adapter_mh_last)  return ek;
-    switch (ek) {
-    case _adapter_opt_swap_1:
-    case _adapter_opt_swap_2:
-      return _adapter_swap_args;
-    case _adapter_opt_rot_1_up:
-    case _adapter_opt_rot_1_down:
-    case _adapter_opt_rot_2_up:
-    case _adapter_opt_rot_2_down:
-      return _adapter_rot_args;
-    case _adapter_opt_i2i:
-    case _adapter_opt_l2i:
-    case _adapter_opt_d2f:
-    case _adapter_opt_i2l:
-    case _adapter_opt_f2d:
-      return _adapter_prim_to_prim;
-    case _adapter_opt_unboxi:
-    case _adapter_opt_unboxl:
-      return _adapter_ref_to_prim;
-    }
-    if (ek >= _adapter_opt_spread_FIRST && ek <= _adapter_opt_spread_LAST)
-      return _adapter_spread_args;
-    if (ek >= _adapter_opt_collect_FIRST && ek <= _adapter_opt_collect_LAST)
-      return _adapter_collect_args;
-    if (ek >= _adapter_opt_fold_FIRST && ek <= _adapter_opt_fold_LAST)
-      return _adapter_fold_args;
-    if (ek >= _adapter_opt_return_FIRST && ek <= _adapter_opt_return_LAST)
-      return _adapter_opt_return_any;
-    if (ek == _adapter_opt_profiling)
-      return _adapter_retype_only;
-    assert(false, "oob");
-    return _EK_LIMIT;
-  }
-
-  static bool ek_supported(MethodHandles::EntryKind ek);
-
-  static BasicType ek_bound_mh_arg_type(EntryKind ek) {
-    switch (ek) {
-    case _bound_int_mh         : // fall-thru
-    case _bound_int_direct_mh  : return T_INT;
-    case _bound_long_mh        : // fall-thru
-    case _bound_long_direct_mh : return T_LONG;
-    default                    : return T_OBJECT;
-    }
-  }
-
-  static int ek_adapter_opt_swap_slots(EntryKind ek) {
-    switch (ek) {
-    case _adapter_opt_swap_1        : return  1;
-    case _adapter_opt_swap_2        : return  2;
-    case _adapter_opt_rot_1_up      : return  1;
-    case _adapter_opt_rot_1_down    : return  1;
-    case _adapter_opt_rot_2_up      : return  2;
-    case _adapter_opt_rot_2_down    : return  2;
-    default : ShouldNotReachHere();   return -1;
-    }
-  }
-
-  static int ek_adapter_opt_swap_mode(EntryKind ek) {
-    switch (ek) {
-    case _adapter_opt_swap_1       : return  0;
-    case _adapter_opt_swap_2       : return  0;
-    case _adapter_opt_rot_1_up     : return  1;
-    case _adapter_opt_rot_1_down   : return -1;
-    case _adapter_opt_rot_2_up     : return  1;
-    case _adapter_opt_rot_2_down   : return -1;
-    default : ShouldNotReachHere();  return  0;
-    }
-  }
-
-  static int ek_adapter_opt_collect_count(EntryKind ek) {
-    assert(ek >= _adapter_opt_collect_FIRST && ek <= _adapter_opt_collect_LAST ||
-           ek >= _adapter_opt_fold_FIRST    && ek <= _adapter_opt_fold_LAST, "");
-    switch (ek) {
-    case _adapter_opt_collect_0_ref    : return  0;
-    case _adapter_opt_filter_S0_ref    :
-    case _adapter_opt_filter_S1_ref    :
-    case _adapter_opt_filter_S2_ref    :
-    case _adapter_opt_filter_S3_ref    :
-    case _adapter_opt_filter_S4_ref    :
-    case _adapter_opt_filter_S5_ref    :
-    case _adapter_opt_fold_1_ref       :
-    case _adapter_opt_collect_1_ref    : return  1;
-    case _adapter_opt_collect_2_S0_ref :
-    case _adapter_opt_collect_2_S1_ref :
-    case _adapter_opt_collect_2_S2_ref :
-    case _adapter_opt_collect_2_S3_ref :
-    case _adapter_opt_collect_2_S4_ref :
-    case _adapter_opt_collect_2_S5_ref :
-    case _adapter_opt_fold_2_ref       :
-    case _adapter_opt_collect_2_ref    : return  2;
-    case _adapter_opt_fold_3_ref       :
-    case _adapter_opt_collect_3_ref    : return  3;
-    case _adapter_opt_fold_4_ref       :
-    case _adapter_opt_collect_4_ref    : return  4;
-    case _adapter_opt_fold_5_ref       :
-    case _adapter_opt_collect_5_ref    : return  5;
-    default                            : return -1;  // sentinel value for "variable"
-    }
-  }
-
-  static int ek_adapter_opt_collect_slot(EntryKind ek) {
-    assert(ek >= _adapter_opt_collect_FIRST && ek <= _adapter_opt_collect_LAST ||
-           ek >= _adapter_opt_fold_FIRST    && ek <= _adapter_opt_fold_LAST, "");
-    switch (ek) {
-    case _adapter_opt_collect_2_S0_ref  :
-    case _adapter_opt_filter_S0_ref     : return 0;
-    case _adapter_opt_collect_2_S1_ref  :
-    case _adapter_opt_filter_S1_ref     : return 1;
-    case _adapter_opt_collect_2_S2_ref  :
-    case _adapter_opt_filter_S2_ref     : return 2;
-    case _adapter_opt_collect_2_S3_ref  :
-    case _adapter_opt_filter_S3_ref     : return 3;
-    case _adapter_opt_collect_2_S4_ref  :
-    case _adapter_opt_filter_S4_ref     : return 4;
-    case _adapter_opt_collect_2_S5_ref  :
-    case _adapter_opt_filter_S5_ref     : return 5;
-    default                             : return -1;  // sentinel value for "variable"
-    }
-  }
-
-  static BasicType ek_adapter_opt_collect_type(EntryKind ek) {
-    assert(ek >= _adapter_opt_collect_FIRST && ek <= _adapter_opt_collect_LAST ||
-           ek >= _adapter_opt_fold_FIRST    && ek <= _adapter_opt_fold_LAST, "");
-    switch (ek) {
-    case _adapter_opt_fold_int          :
-    case _adapter_opt_collect_int       : return T_INT;
-    case _adapter_opt_fold_long         :
-    case _adapter_opt_collect_long      : return T_LONG;
-    case _adapter_opt_fold_float        :
-    case _adapter_opt_collect_float     : return T_FLOAT;
-    case _adapter_opt_fold_double       :
-    case _adapter_opt_collect_double    : return T_DOUBLE;
-    case _adapter_opt_fold_void         :
-    case _adapter_opt_collect_void      : return T_VOID;
-    default                             : return T_OBJECT;
-    }
-  }
-
-  static int ek_adapter_opt_return_slot(EntryKind ek) {
-    assert(ek >= _adapter_opt_return_FIRST && ek <= _adapter_opt_return_LAST, "");
-    switch (ek) {
-    case _adapter_opt_return_S0_ref : return 0;
-    case _adapter_opt_return_S1_ref : return 1;
-    case _adapter_opt_return_S2_ref : return 2;
-    case _adapter_opt_return_S3_ref : return 3;
-    case _adapter_opt_return_S4_ref : return 4;
-    case _adapter_opt_return_S5_ref : return 5;
-    default                         : return -1;  // sentinel value for "variable"
-    }
-  }
-
-  static BasicType ek_adapter_opt_return_type(EntryKind ek) {
-    assert(ek >= _adapter_opt_return_FIRST && ek <= _adapter_opt_return_LAST, "");
-    switch (ek) {
-    case _adapter_opt_return_int    : return T_INT;
-    case _adapter_opt_return_long   : return T_LONG;
-    case _adapter_opt_return_float  : return T_FLOAT;
-    case _adapter_opt_return_double : return T_DOUBLE;
-    case _adapter_opt_return_void   : return T_VOID;
-    case _adapter_opt_return_any    : return T_CONFLICT;  // sentinel value for "variable"
-    default                         : return T_OBJECT;
-    }
-  }
-
-  static int ek_adapter_opt_spread_count(EntryKind ek) {
-    assert(ek >= _adapter_opt_spread_FIRST && ek <= _adapter_opt_spread_LAST, "");
-    switch (ek) {
-    case _adapter_opt_spread_0     : return  0;
-    case _adapter_opt_spread_1_ref : return  1;
-    case _adapter_opt_spread_2_ref : return  2;
-    case _adapter_opt_spread_3_ref : return  3;
-    case _adapter_opt_spread_4_ref : return  4;
-    case _adapter_opt_spread_5_ref : return  5;
-    default                        : return -1;  // sentinel value for "variable"
-    }
-  }
-
-  static BasicType ek_adapter_opt_spread_type(EntryKind ek) {
-    assert(ek >= _adapter_opt_spread_FIRST && ek <= _adapter_opt_spread_LAST, "");
-    switch (ek) {
-    // (there is no _adapter_opt_spread_boolean; we use byte)
-    case _adapter_opt_spread_byte   : return T_BYTE;
-    case _adapter_opt_spread_char   : return T_CHAR;
-    case _adapter_opt_spread_short  : return T_SHORT;
-    case _adapter_opt_spread_int    : return T_INT;
-    case _adapter_opt_spread_long   : return T_LONG;
-    case _adapter_opt_spread_float  : return T_FLOAT;
-    case _adapter_opt_spread_double : return T_DOUBLE;
-    default                         : return T_OBJECT;
-    }
-  }
-
-  static methodOop raise_exception_method() {
-    oop rem = JNIHandles::resolve(_raise_exception_method);
-    assert(rem == NULL || rem->is_method(), "");
-    return (methodOop) rem;
-  }
-  static void set_raise_exception_method(methodOop rem) {
-    assert(_raise_exception_method == NULL, "");
-    _raise_exception_method = JNIHandles::make_global(Handle(rem));
-  }
-  static methodOop resolve_raise_exception_method(TRAPS);
-  // call raise_exception_method from C code:
-  static void raise_exception(int code, oop actual, oop required, TRAPS);
-
-  static jint adapter_conversion(int conv_op, BasicType src, BasicType dest,
-                                 int stack_move = 0, int vminfo = 0) {
-    assert(conv_op_valid(conv_op), "oob");
-    jint conv = ((conv_op      << CONV_OP_SHIFT)
-                 | (src        << CONV_SRC_TYPE_SHIFT)
-                 | (dest       << CONV_DEST_TYPE_SHIFT)
-                 | (stack_move << CONV_STACK_MOVE_SHIFT)
-                 | (vminfo     << CONV_VMINFO_SHIFT)
-                 );
-    assert(adapter_conversion_op(conv) == conv_op, "decode conv_op");
-    assert(adapter_conversion_src_type(conv) == src, "decode src");
-    assert(adapter_conversion_dest_type(conv) == dest, "decode dest");
-    assert(adapter_conversion_stack_move(conv) == stack_move, "decode stack_move");
-    assert(adapter_conversion_vminfo(conv) == vminfo, "decode vminfo");
-    return conv;
-  }
-  static int adapter_conversion_op(jint conv) {
-    return ((conv >> CONV_OP_SHIFT) & 0xF);
-  }
-  static BasicType adapter_conversion_src_type(jint conv) {
-    return (BasicType)((conv >> CONV_SRC_TYPE_SHIFT) & 0xF);
-  }
-  static BasicType adapter_conversion_dest_type(jint conv) {
-    return (BasicType)((conv >> CONV_DEST_TYPE_SHIFT) & 0xF);
-  }
-  static int adapter_conversion_stack_move(jint conv) {
-    return (conv >> CONV_STACK_MOVE_SHIFT);
-  }
-  static int adapter_conversion_vminfo(jint conv) {
-    return (conv >> CONV_VMINFO_SHIFT) & CONV_VMINFO_MASK;
-  }
-
-  // Bit mask of conversion_op values.  May vary by platform.
-  static int adapter_conversion_ops_supported_mask();
-
-  static bool conv_op_supported(int conv_op) {
-    assert(conv_op_valid(conv_op), "");
-    return ((adapter_conversion_ops_supported_mask() & nth_bit(conv_op)) != 0);
-  }
-
-  // Offset in words that the interpreter stack pointer moves when an argument is pushed.
-  // The stack_move value must always be a multiple of this.
-  static int stack_move_unit() {
-    return frame::interpreter_frame_expression_stack_direction() * Interpreter::stackElementWords;
-  }
-
-  // Adapter frame traversal.  (Implementation-specific.)
-  static frame ricochet_frame_sender(const frame& fr, RegisterMap* reg_map);
-  static void ricochet_frame_oops_do(const frame& fr, OopClosure* blk, const RegisterMap* reg_map);
-
-  enum { CONV_VMINFO_SIGN_FLAG = 0x80 };
-  // Shift values for prim-to-prim conversions.
-  static int adapter_prim_to_prim_subword_vminfo(BasicType dest) {
-    if (dest == T_BOOLEAN) return (BitsPerInt - 1);  // boolean is 1 bit
-    if (dest == T_CHAR)    return (BitsPerInt - BitsPerShort);
-    if (dest == T_BYTE)    return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG;
-    if (dest == T_SHORT)   return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG;
-    return 0;                   // case T_INT
-  }
-  // Shift values for unboxing a primitive.
-  static int adapter_unbox_subword_vminfo(BasicType dest) {
-    if (dest == T_BOOLEAN) return (BitsPerInt - BitsPerByte );  // implemented as 1 byte
-    if (dest == T_CHAR)    return (BitsPerInt - BitsPerShort);
-    if (dest == T_BYTE)    return (BitsPerInt - BitsPerByte ) | CONV_VMINFO_SIGN_FLAG;
-    if (dest == T_SHORT)   return (BitsPerInt - BitsPerShort) | CONV_VMINFO_SIGN_FLAG;
-    return 0;                   // case T_INT
-  }
-  // Here is the transformation the i2i adapter must perform:
-  static int truncate_subword_from_vminfo(jint value, int vminfo) {
-    int shift = vminfo & ~CONV_VMINFO_SIGN_FLAG;
-    jint tem = value << shift;
-    if ((vminfo & CONV_VMINFO_SIGN_FLAG) != 0) {
-      return (jint)tem >> shift;
-    } else {
-      return (juint)tem >> shift;
-    }
-  }
-
-  static inline address from_compiled_entry(EntryKind ek);
-  static inline address from_interpreted_entry(EntryKind ek);
-
-  // helpers for decode_method.
-  static methodOop    decode_methodOop(methodOop m, int& decode_flags_result);
-  static methodHandle decode_vmtarget(oop vmtarget, int vmindex, oop mtype, KlassHandle& receiver_limit_result, int& decode_flags_result);
-  static methodHandle decode_MemberName(oop mname, KlassHandle& receiver_limit_result, int& decode_flags_result);
-  static methodHandle decode_MethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
-  static methodHandle decode_DirectMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
-  static methodHandle decode_BoundMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
-  static methodHandle decode_AdapterMethodHandle(oop mh, KlassHandle& receiver_limit_result, int& decode_flags_result);
-
-  // Find out how many stack slots an mh pushes or pops.
-  // The result is *not* reported as a multiple of stack_move_unit();
-  // It is a signed net number of pushes (a difference in vmslots).
-  // To compare with a stack_move value, first multiply by stack_move_unit().
-  static int decode_MethodHandle_stack_pushes(oop mh);
-
  public:
   // working with member names
-  static void resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type
+  static Handle resolve_MemberName(Handle mname, TRAPS); // compute vmtarget/vmindex from name/type
   static void expand_MemberName(Handle mname, int suppress, TRAPS);  // expand defc/name/type if missing
   static Handle new_MemberName(TRAPS);  // must be followed by init_MemberName
-  static void init_MemberName(oop mname_oop, oop target); // compute vmtarget/vmindex from target
-  static void init_MemberName(oop mname_oop, methodOop m, bool do_dispatch = true);
-  static void init_MemberName(oop mname_oop, klassOop field_holder, AccessFlags mods, int offset);
+  static oop init_MemberName(oop mname_oop, oop target_oop); // compute vmtarget/vmindex from target
+  static oop init_method_MemberName(oop mname_oop, methodOop m, bool do_dispatch,
+                                    klassOop receiver_limit);
+  static oop init_field_MemberName(oop mname_oop, klassOop field_holder,
+                                   AccessFlags mods, oop type, oop name,
+                                   intptr_t offset, bool is_setter = false);
+  static Handle init_method_MemberName(oop mname_oop, CallInfo& info, TRAPS);
+  static Handle init_field_MemberName(oop mname_oop, FieldAccessInfo& info, TRAPS);
+  static int method_ref_kind(methodOop m, bool do_dispatch_if_possible = true);
   static int find_MemberNames(klassOop k, Symbol* name, Symbol* sig,
                               int mflags, klassOop caller,
                               int skip, objArrayOop results);
@@ -559,169 +72,113 @@
   // Generate MethodHandles adapters.
   static void generate_adapters();
 
-  // Called from InterpreterGenerator and MethodHandlesAdapterGenerator.
-  static address generate_method_handle_interpreter_entry(MacroAssembler* _masm);
-  static void generate_method_handle_stub(MacroAssembler* _masm, EntryKind ek);
+  // Called from MethodHandlesAdapterGenerator.
+  static address generate_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid);
+  static void generate_method_handle_dispatch(MacroAssembler* _masm,
+                                              vmIntrinsics::ID iid,
+                                              Register receiver_reg,
+                                              Register member_reg,
+                                              bool for_compiler_entry);
 
-  // argument list parsing
-  static int argument_slot(oop method_type, int arg);
-  static int argument_slot_count(oop method_type) { return argument_slot(method_type, -1); }
-  static int argument_slot_to_argnum(oop method_type, int argslot);
+  // Queries
+  static bool is_signature_polymorphic(vmIntrinsics::ID iid) {
+    return (iid >= vmIntrinsics::FIRST_MH_SIG_POLY &&
+            iid <= vmIntrinsics::LAST_MH_SIG_POLY);
+  }
 
-  // Runtime support
-  enum {                        // bit-encoded flags from decode_method or decode_vmref
-    _dmf_has_receiver   = 0x01, // target method has leading reference argument
-    _dmf_does_dispatch  = 0x02, // method handle performs virtual or interface dispatch
-    _dmf_from_interface = 0x04, // peforms interface dispatch
-    _DMF_DIRECT_MASK    = (_dmf_from_interface*2 - _dmf_has_receiver),
-    _dmf_binds_method   = 0x08,
-    _dmf_binds_argument = 0x10,
-    _DMF_BOUND_MASK     = (_dmf_binds_argument*2 - _dmf_binds_method),
-    _dmf_adapter_lsb    = 0x20,
-    _DMF_ADAPTER_MASK   = (_dmf_adapter_lsb << CONV_OP_LIMIT) - _dmf_adapter_lsb
-  };
-  static methodHandle decode_method(oop x, KlassHandle& receiver_limit_result, int& decode_flags_result);
+  static bool is_signature_polymorphic_intrinsic(vmIntrinsics::ID iid) {
+    assert(is_signature_polymorphic(iid), "");
+    // Most sig-poly methods are intrinsics which do not require an
+    // appeal to Java for adapter code.
+    return (iid != vmIntrinsics::_invokeGeneric);
+  }
+
+  static bool is_signature_polymorphic_static(vmIntrinsics::ID iid) {
+    assert(is_signature_polymorphic(iid), "");
+    return (iid >= vmIntrinsics::FIRST_MH_STATIC &&
+            iid <= vmIntrinsics::LAST_MH_SIG_POLY);
+  }
+
+  static bool has_member_arg(vmIntrinsics::ID iid) {
+    assert(is_signature_polymorphic(iid), "");
+    return (iid >= vmIntrinsics::_linkToVirtual &&
+            iid <= vmIntrinsics::_linkToInterface);
+  }
+  static bool has_member_arg(Symbol* klass, Symbol* name) {
+    if ((klass == vmSymbols::java_lang_invoke_MethodHandle()) &&
+        is_signature_polymorphic_name(name)) {
+      vmIntrinsics::ID iid = signature_polymorphic_name_id(name);
+      return has_member_arg(iid);
+    }
+    return false;
+  }
+
+  static Symbol* signature_polymorphic_intrinsic_name(vmIntrinsics::ID iid);
+  static int signature_polymorphic_intrinsic_ref_kind(vmIntrinsics::ID iid);
+
+  static vmIntrinsics::ID signature_polymorphic_name_id(klassOop klass, Symbol* name);
+  static vmIntrinsics::ID signature_polymorphic_name_id(Symbol* name);
+  static bool is_signature_polymorphic_name(Symbol* name) {
+    return signature_polymorphic_name_id(name) != vmIntrinsics::_none;
+  }
+  static bool is_method_handle_invoke_name(klassOop klass, Symbol* name);
+  static bool is_signature_polymorphic_name(klassOop klass, Symbol* name) {
+    return signature_polymorphic_name_id(klass, name) != vmIntrinsics::_none;
+  }
+
   enum {
     // format of query to getConstant:
-    GC_JVM_PUSH_LIMIT = 0,
-    GC_JVM_STACK_MOVE_UNIT = 1,
-    GC_CONV_OP_IMPLEMENTED_MASK = 2,
-    GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS = 3,
     GC_COUNT_GWT = 4,
-
-    // format of result from getTarget / encode_target:
-    ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
-    ETF_DIRECT_HANDLE         = 1, // ultimate method handle (will be a DMH, may be self)
-    ETF_METHOD_NAME           = 2, // ultimate method as MemberName
-    ETF_REFLECT_METHOD        = 3, // ultimate method as java.lang.reflect object (sans refClass)
-    ETF_FORCE_DIRECT_HANDLE   = 64,
-    ETF_COMPILE_DIRECT_HANDLE = 65,
-
-    // ad hoc constants
-    OP_ROT_ARGS_DOWN_LIMIT_BIAS = -1
+    GC_LAMBDA_SUPPORT = 5
   };
   static int get_named_constant(int which, Handle name_box, TRAPS);
-  static oop encode_target(Handle mh, int format, TRAPS); // report vmtarget (to Java code)
-  static bool class_cast_needed(klassOop src, klassOop dst);
-
-  static instanceKlassHandle resolve_instance_klass(oop    java_mirror_oop, TRAPS);
-  static instanceKlassHandle resolve_instance_klass(jclass java_mirror_jh,  TRAPS) {
-    return resolve_instance_klass(JNIHandles::resolve(java_mirror_jh), THREAD);
-  }
-
- private:
-  // These checkers operate on a pair of whole MethodTypes:
-  static const char* check_method_type_change(oop src_mtype, int src_beg, int src_end,
-                                              int insert_argnum, oop insert_type,
-                                              int change_argnum, oop change_type,
-                                              int delete_argnum,
-                                              oop dst_mtype, int dst_beg, int dst_end,
-                                              bool raw = false);
-  static const char* check_method_type_insertion(oop src_mtype,
-                                                 int insert_argnum, oop insert_type,
-                                                 oop dst_mtype) {
-    oop no_ref = NULL;
-    return check_method_type_change(src_mtype, 0, -1,
-                                    insert_argnum, insert_type,
-                                    -1, no_ref, -1, dst_mtype, 0, -1);
-  }
-  static const char* check_method_type_conversion(oop src_mtype,
-                                                  int change_argnum, oop change_type,
-                                                  oop dst_mtype) {
-    oop no_ref = NULL;
-    return check_method_type_change(src_mtype, 0, -1, -1, no_ref,
-                                    change_argnum, change_type,
-                                    -1, dst_mtype, 0, -1);
-  }
-  static const char* check_method_type_passthrough(oop src_mtype, oop dst_mtype, bool raw) {
-    oop no_ref = NULL;
-    return check_method_type_change(src_mtype, 0, -1,
-                                    -1, no_ref, -1, no_ref, -1,
-                                    dst_mtype, 0, -1, raw);
-  }
-
-  // These checkers operate on pairs of argument or return types:
-  static const char* check_argument_type_change(BasicType src_type, klassOop src_klass,
-                                                BasicType dst_type, klassOop dst_klass,
-                                                int argnum, bool raw = false);
-
-  static const char* check_argument_type_change(oop src_type, oop dst_type,
-                                                int argnum, bool raw = false) {
-    klassOop src_klass = NULL, dst_klass = NULL;
-    BasicType src_bt = java_lang_Class::as_BasicType(src_type, &src_klass);
-    BasicType dst_bt = java_lang_Class::as_BasicType(dst_type, &dst_klass);
-    return check_argument_type_change(src_bt, src_klass,
-                                      dst_bt, dst_klass, argnum, raw);
-  }
-
-  static const char* check_return_type_change(oop src_type, oop dst_type, bool raw = false) {
-    return check_argument_type_change(src_type, dst_type, -1, raw);
-  }
-
-  static const char* check_return_type_change(BasicType src_type, klassOop src_klass,
-                                              BasicType dst_type, klassOop dst_klass) {
-    return check_argument_type_change(src_type, src_klass, dst_type, dst_klass, -1);
-  }
-
-  static const char* check_method_receiver(methodOop m, klassOop passed_recv_type);
-
-  // These verifiers can block, and will throw an error if the checking fails:
-  static void verify_vmslots(Handle mh, TRAPS);
-  static void verify_vmargslot(Handle mh, int argnum, int argslot, TRAPS);
-
-  static void verify_method_type(methodHandle m, Handle mtype,
-                                 bool has_bound_oop,
-                                 KlassHandle bound_oop_type,
-                                 TRAPS);
-
-  static void verify_method_signature(methodHandle m, Handle mtype,
-                                      int first_ptype_pos,
-                                      KlassHandle insert_ptype, TRAPS);
-
-  static void verify_DirectMethodHandle(Handle mh, methodHandle m, TRAPS);
-  static void verify_BoundMethodHandle(Handle mh, Handle target, int argnum,
-                                       bool direct_to_method, TRAPS);
-  static void verify_BoundMethodHandle_with_receiver(Handle mh, methodHandle m, TRAPS);
-  static void verify_AdapterMethodHandle(Handle mh, int argnum, TRAPS);
-
- public:
-
-  // Fill in the fields of a DirectMethodHandle mh.  (MH.type must be pre-filled.)
-  static void init_DirectMethodHandle(Handle mh, methodHandle method, bool do_dispatch, TRAPS);
-
-  // Fill in the fields of a BoundMethodHandle mh.  (MH.type, BMH.argument must be pre-filled.)
-  static void init_BoundMethodHandle(Handle mh, Handle target, int argnum, TRAPS);
-  static void init_BoundMethodHandle_with_receiver(Handle mh,
-                                                   methodHandle original_m,
-                                                   KlassHandle receiver_limit,
-                                                   int decode_flags,
-                                                   TRAPS);
-
-  // Fill in the fields of an AdapterMethodHandle mh.  (MH.type must be pre-filled.)
-  static void init_AdapterMethodHandle(Handle mh, Handle target, int argnum, TRAPS);
-  static void ensure_vmlayout_field(Handle target, TRAPS);
-
-#ifdef ASSERT
-  static bool spot_check_entry_names();
-#endif
-
- private:
-  static methodHandle dispatch_decoded_method(methodHandle m,
-                                              KlassHandle receiver_limit,
-                                              int decode_flags,
-                                              KlassHandle receiver_klass,
-                                              TRAPS);
 
 public:
-  static bool is_float_fixed_reinterpretation_cast(BasicType src, BasicType dst);
-  static bool same_basic_type_for_arguments(BasicType src, BasicType dst,
-                                            bool raw = false,
-                                            bool for_return = false);
-  static bool same_basic_type_for_returns(BasicType src, BasicType dst, bool raw = false) {
-    return same_basic_type_for_arguments(src, dst, raw, true);
+  static Symbol* lookup_signature(oop type_str, bool polymorphic, TRAPS);  // use TempNewSymbol
+  static Symbol* lookup_basic_type_signature(Symbol* sig, bool keep_last_arg, TRAPS);  // use TempNewSymbol
+  static Symbol* lookup_basic_type_signature(Symbol* sig, TRAPS) {
+    return lookup_basic_type_signature(sig, false, THREAD);
+  }
+  static bool is_basic_type_signature(Symbol* sig);
+
+  static Symbol* lookup_method_type(Symbol* msig, Handle mtype, TRAPS);
+
+  static void print_as_method_type_on(outputStream* st, Symbol* sig) {
+    print_as_basic_type_signature_on(st, sig, true, true);
+  }
+  static void print_as_basic_type_signature_on(outputStream* st, Symbol* sig, bool keep_arrays = false, bool keep_basic_names = false);
+
+  // decoding CONSTANT_MethodHandle constants
+  enum { JVM_REF_MIN = JVM_REF_getField, JVM_REF_MAX = JVM_REF_invokeInterface };
+  static bool ref_kind_is_valid(int ref_kind) {
+    return (ref_kind >= JVM_REF_MIN && ref_kind <= JVM_REF_MAX);
+  }
+  static bool ref_kind_is_field(int ref_kind) {
+    assert(ref_kind_is_valid(ref_kind), "");
+    return (ref_kind <= JVM_REF_putStatic);
+  }
+  static bool ref_kind_is_getter(int ref_kind) {
+    assert(ref_kind_is_valid(ref_kind), "");
+    return (ref_kind <= JVM_REF_getStatic);
+  }
+  static bool ref_kind_is_setter(int ref_kind) {
+    return ref_kind_is_field(ref_kind) && !ref_kind_is_getter(ref_kind);
+  }
+  static bool ref_kind_is_method(int ref_kind) {
+    return !ref_kind_is_field(ref_kind) && (ref_kind != JVM_REF_newInvokeSpecial);
+  }
+  static bool ref_kind_has_receiver(int ref_kind) {
+    assert(ref_kind_is_valid(ref_kind), "");
+    return (ref_kind & 1) != 0;
+  }
+  static bool ref_kind_is_static(int ref_kind) {
+    return !ref_kind_has_receiver(ref_kind) && (ref_kind != JVM_REF_newInvokeSpecial);
+  }
+  static bool ref_kind_does_dispatch(int ref_kind) {
+    return (ref_kind == JVM_REF_invokeVirtual ||
+            ref_kind == JVM_REF_invokeInterface);
   }
 
-  static Symbol* convert_to_signature(oop type_str, bool polymorphic, TRAPS);
 
 #ifdef TARGET_ARCH_x86
 # include "methodHandles_x86.hpp"
@@ -738,63 +195,31 @@
 #ifdef TARGET_ARCH_ppc
 # include "methodHandles_ppc.hpp"
 #endif
+
+  // Tracing
+  static void trace_method_handle(MacroAssembler* _masm, const char* adaptername) PRODUCT_RETURN;
+  static void trace_method_handle_interpreter_entry(MacroAssembler* _masm, vmIntrinsics::ID iid) {
+    if (TraceMethodHandles) {
+      const char* name = vmIntrinsics::name_at(iid);
+      if (*name == '_')  name += 1;
+      const size_t len = strlen(name) + 50;
+      char* qname = NEW_C_HEAP_ARRAY(char, len, mtInternal);
+      const char* suffix = "";
+      if (is_signature_polymorphic(iid)) {
+        if (is_signature_polymorphic_static(iid))
+          suffix = "/static";
+        else
+          suffix = "/private";
+      }
+      jio_snprintf(qname, len, "MethodHandle::interpreter_entry::%s%s", name, suffix);
+      trace_method_handle(_masm, qname);
+      // Note:  Don't free the allocated char array because it's used
+      // during runtime.
+    }
+  }
 };
 
 
-// Access methods for the "entry" field of a java.lang.invoke.MethodHandle.
-// The field is primarily a jump target for compiled calls.
-// However, we squirrel away some nice pointers for other uses,
-// just before the jump target.
-// Aspects of a method handle entry:
-//  - from_compiled_entry - stub used when compiled code calls the MH
-//  - from_interpreted_entry - stub used when the interpreter calls the MH
-//  - type_checking_entry - stub for runtime casting between MHForm siblings (NYI)
-class MethodHandleEntry {
- public:
-  class Data {
-    friend class MethodHandleEntry;
-    size_t              _total_size; // size including Data and code stub
-    MethodHandleEntry*  _type_checking_entry;
-    address             _from_interpreted_entry;
-    MethodHandleEntry* method_entry() { return (MethodHandleEntry*)(this + 1); }
-  };
-
-  Data*     data()                              { return (Data*)this - 1; }
-
-  address   start_address()                     { return (address) data(); }
-  address   end_address()                       { return start_address() + data()->_total_size; }
-
-  address   from_compiled_entry()               { return (address) this; }
-
-  address   from_interpreted_entry()            { return data()->_from_interpreted_entry; }
-  void  set_from_interpreted_entry(address e)   { data()->_from_interpreted_entry = e; }
-
-  MethodHandleEntry* type_checking_entry()           { return data()->_type_checking_entry; }
-  void set_type_checking_entry(MethodHandleEntry* e) { data()->_type_checking_entry = e; }
-
-  void set_end_address(address end_addr) {
-    size_t total_size = end_addr - start_address();
-    assert(total_size > 0 && total_size < 0x1000, "reasonable end address");
-    data()->_total_size = total_size;
-  }
-
-  // Compiler support:
-  static int from_interpreted_entry_offset_in_bytes() {
-    return (int)( offset_of(Data, _from_interpreted_entry) - sizeof(Data) );
-  }
-  static int type_checking_entry_offset_in_bytes() {
-    return (int)( offset_of(Data, _from_interpreted_entry) - sizeof(Data) );
-  }
-
-  static address            start_compiled_entry(MacroAssembler* _masm,
-                                                 address interpreted_entry = NULL);
-  static MethodHandleEntry* finish_compiled_entry(MacroAssembler* masm, address start_addr);
-};
-
-address MethodHandles::from_compiled_entry(EntryKind ek) { return entry(ek)->from_compiled_entry(); }
-address MethodHandles::from_interpreted_entry(EntryKind ek) { return entry(ek)->from_interpreted_entry(); }
-
-
 //------------------------------------------------------------------------------
 // MethodHandlesAdapterGenerator
 //
diff --git a/hotspot/src/share/vm/prims/nativeLookup.cpp b/hotspot/src/share/vm/prims/nativeLookup.cpp
index f8c627d..b8e58a0 100644
--- a/hotspot/src/share/vm/prims/nativeLookup.cpp
+++ b/hotspot/src/share/vm/prims/nativeLookup.cpp
@@ -121,6 +121,7 @@
   void JNICALL JVM_RegisterUnsafeMethods(JNIEnv *env, jclass unsafecls);
   void JNICALL JVM_RegisterMethodHandleMethods(JNIEnv *env, jclass unsafecls);
   void JNICALL JVM_RegisterPerfMethods(JNIEnv *env, jclass perfclass);
+  void JNICALL JVM_RegisterWhiteBoxMethods(JNIEnv *env, jclass wbclass);
 }
 
 #define CC (char*)  /* cast a literal from (const char*) */
@@ -133,7 +134,8 @@
 
   { CC"Java_sun_misc_Unsafe_registerNatives",                      NULL, FN_PTR(JVM_RegisterUnsafeMethods)       },
   { CC"Java_java_lang_invoke_MethodHandleNatives_registerNatives", NULL, FN_PTR(JVM_RegisterMethodHandleMethods) },
-  { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         }
+  { CC"Java_sun_misc_Perf_registerNatives",                        NULL, FN_PTR(JVM_RegisterPerfMethods)         },
+  { CC"Java_sun_hotspot_WhiteBox_registerNatives",                 NULL, FN_PTR(JVM_RegisterWhiteBoxMethods)     },
 };
 
 static address lookup_special_native(char* jni_name) {
@@ -379,7 +381,10 @@
 
 address NativeLookup::lookup(methodHandle method, bool& in_base_library, TRAPS) {
   if (!method->has_native_function()) {
-    address entry = lookup_base(method, in_base_library, CHECK_NULL);
+    address entry =
+        method->intrinsic_id() == vmIntrinsics::_invokeGeneric ?
+            SharedRuntime::native_method_throw_unsupported_operation_exception_entry() :
+            lookup_base(method, in_base_library, CHECK_NULL);
     method->set_native_function(entry,
       methodOopDesc::native_bind_event_is_interesting);
     // -verbose:jni printing
diff --git a/hotspot/src/share/vm/prims/unsafe.cpp b/hotspot/src/share/vm/prims/unsafe.cpp
index 19f77a5..0bdd624 100644
--- a/hotspot/src/share/vm/prims/unsafe.cpp
+++ b/hotspot/src/share/vm/prims/unsafe.cpp
@@ -124,6 +124,8 @@
       assert((void*)p->obj_field_addr<oop>((jint)byte_offset) == ptr_plus_disp,
              "raw [ptr+disp] must be consistent with oop::field_base");
     }
+    jlong p_size = HeapWordSize * (jlong)(p->size());
+    assert(byte_offset < p_size, err_msg("Unsafe access: offset " INT64_FORMAT " > object's size " INT64_FORMAT, byte_offset, p_size));
   }
 #endif
   if (sizeof(char*) == sizeof(jint))    // (this constant folds!)
@@ -178,17 +180,6 @@
     v = *(oop*)index_oop_from_field_offset_long(p, offset);                 \
   }
 
-#define GET_OOP_FIELD_VOLATILE(obj, offset, v) \
-  oop p = JNIHandles::resolve(obj);   \
-  volatile oop v;                     \
-  if (UseCompressedOops) {            \
-    volatile narrowOop n = *(volatile narrowOop*)index_oop_from_field_offset_long(p, offset); \
-    v = oopDesc::decode_heap_oop(n);                               \
-  } else {                            \
-    v = *(volatile oop*)index_oop_from_field_offset_long(p, offset);       \
-  } \
-  OrderAccess::acquire();
-
 
 // Get/SetObject must be special-cased, since it works with handles.
 
@@ -296,28 +287,21 @@
 
 UNSAFE_ENTRY(jobject, Unsafe_GetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset))
   UnsafeWrapper("Unsafe_GetObjectVolatile");
-  GET_OOP_FIELD_VOLATILE(obj, offset, v)
+  oop p = JNIHandles::resolve(obj);
+  void* addr = index_oop_from_field_offset_long(p, offset);
+  volatile oop v;
+  if (UseCompressedOops) {
+    volatile narrowOop n = *(volatile narrowOop*) addr;
+    v = oopDesc::decode_heap_oop(n);
+  } else {
+    v = *(volatile oop*) addr;
+  }
+  OrderAccess::acquire();
   return JNIHandles::make_local(env, v);
 UNSAFE_END
 
 UNSAFE_ENTRY(void, Unsafe_SetObjectVolatile(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jobject x_h))
   UnsafeWrapper("Unsafe_SetObjectVolatile");
-  {
-    // Catch VolatileCallSite.target stores (via
-    // CallSite.setTargetVolatile) and check call site dependencies.
-    oop p = JNIHandles::resolve(obj);
-    if ((offset == java_lang_invoke_CallSite::target_offset_in_bytes()) && p->is_a(SystemDictionary::CallSite_klass())) {
-      Handle call_site    (THREAD, p);
-      Handle method_handle(THREAD, JNIHandles::resolve(x_h));
-      assert(call_site    ->is_a(SystemDictionary::CallSite_klass()),     "must be");
-      assert(method_handle->is_a(SystemDictionary::MethodHandle_klass()), "must be");
-      {
-        // Walk all nmethods depending on this call site.
-        MutexLocker mu(Compile_lock, thread);
-        Universe::flush_dependents_on(call_site(), method_handle());
-      }
-    }
-  }
   oop x = JNIHandles::resolve(x_h);
   oop p = JNIHandles::resolve(obj);
   void* addr = index_oop_from_field_offset_long(p, offset);
@@ -596,7 +580,7 @@
     return 0;
   }
   sz = round_to(sz, HeapWordSize);
-  void* x = os::malloc(sz);
+  void* x = os::malloc(sz, mtInternal);
   if (x == NULL) {
     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   }
@@ -616,7 +600,7 @@
     return 0;
   }
   sz = round_to(sz, HeapWordSize);
-  void* x = (p == NULL) ? os::malloc(sz) : os::realloc(p, sz);
+  void* x = (p == NULL) ? os::malloc(sz, mtInternal) : os::realloc(p, sz, mtInternal);
   if (x == NULL) {
     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   }
@@ -779,16 +763,33 @@
   return JNIHandles::make_local(env, JNIHandles::resolve_non_null(clazz));
 UNSAFE_END
 
-UNSAFE_ENTRY(void, Unsafe_EnsureClassInitialized(JNIEnv *env, jobject unsafe, jobject clazz))
+UNSAFE_ENTRY(void, Unsafe_EnsureClassInitialized(JNIEnv *env, jobject unsafe, jobject clazz)) {
   UnsafeWrapper("Unsafe_EnsureClassInitialized");
   if (clazz == NULL) {
     THROW(vmSymbols::java_lang_NullPointerException());
   }
   oop mirror = JNIHandles::resolve_non_null(clazz);
-  instanceKlass* k = instanceKlass::cast(java_lang_Class::as_klassOop(mirror));
-  if (k != NULL) {
+
+  klassOop klass = java_lang_Class::as_klassOop(mirror);
+  if (klass != NULL && Klass::cast(klass)->should_be_initialized()) {
+    instanceKlass* k = instanceKlass::cast(klass);
     k->initialize(CHECK);
   }
+}
+UNSAFE_END
+
+UNSAFE_ENTRY(jboolean, Unsafe_ShouldBeInitialized(JNIEnv *env, jobject unsafe, jobject clazz)) {
+  UnsafeWrapper("Unsafe_ShouldBeInitialized");
+  if (clazz == NULL) {
+    THROW_(vmSymbols::java_lang_NullPointerException(), false);
+  }
+  oop mirror = JNIHandles::resolve_non_null(clazz);
+  klassOop klass = java_lang_Class::as_klassOop(mirror);
+  if (klass != NULL && Klass::cast(klass)->should_be_initialized()) {
+    return true;
+  }
+  return false;
+}
 UNSAFE_END
 
 static void getBaseAndScale(int& base, int& scale, jclass acls, TRAPS) {
@@ -877,7 +878,7 @@
         return 0;
     }
 
-    body = NEW_C_HEAP_ARRAY(jbyte, length);
+    body = NEW_C_HEAP_ARRAY(jbyte, length, mtInternal);
 
     if (body == 0) {
         throw_new(env, "OutOfMemoryError");
@@ -893,7 +894,7 @@
         uint len = env->GetStringUTFLength(name);
         int unicode_len = env->GetStringLength(name);
         if (len >= sizeof(buf)) {
-            utfName = NEW_C_HEAP_ARRAY(char, len + 1);
+            utfName = NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
             if (utfName == NULL) {
                 throw_new(env, "OutOfMemoryError");
                 goto free_body;
@@ -913,10 +914,10 @@
     result = JVM_DefineClass(env, utfName, loader, body, length, pd);
 
     if (utfName && utfName != buf)
-        FREE_C_HEAP_ARRAY(char, utfName);
+        FREE_C_HEAP_ARRAY(char, utfName, mtInternal);
 
  free_body:
-    FREE_C_HEAP_ARRAY(jbyte, body);
+    FREE_C_HEAP_ARRAY(jbyte, body, mtInternal);
     return result;
   }
 }
@@ -1011,7 +1012,7 @@
 
   jint length = typeArrayOop(JNIHandles::resolve_non_null(data))->length();
   jint word_length = (length + sizeof(HeapWord)-1) / sizeof(HeapWord);
-  HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length);
+  HeapWord* body = NEW_C_HEAP_ARRAY(HeapWord, word_length, mtInternal);
   if (body == NULL) {
     THROW_0(vmSymbols::java_lang_OutOfMemoryError());
   }
@@ -1095,7 +1096,7 @@
 
   // try/finally clause:
   if (temp_alloc != NULL) {
-    FREE_C_HEAP_ARRAY(HeapWord, temp_alloc);
+    FREE_C_HEAP_ARRAY(HeapWord, temp_alloc, mtInternal);
   }
 
   return (jclass) res_jh;
@@ -1584,6 +1585,10 @@
     {CC"defineAnonymousClass", CC"("DAC_Args")"CLS,      FN_PTR(Unsafe_DefineAnonymousClass)},
 };
 
+JNINativeMethod lform_methods[] = {
+    {CC"shouldBeInitialized",CC"("CLS")Z",               FN_PTR(Unsafe_ShouldBeInitialized)},
+};
+
 #undef CC
 #undef FN_PTR
 
@@ -1654,6 +1659,15 @@
         env->ExceptionClear();
       }
     }
+    if (EnableInvokeDynamic) {
+      env->RegisterNatives(unsafecls, lform_methods, sizeof(lform_methods)/sizeof(JNINativeMethod));
+      if (env->ExceptionOccurred()) {
+        if (PrintMiscellaneous && (Verbose || WizardMode)) {
+          tty->print_cr("Warning:  SDK 1.7 LambdaForm support in Unsafe not found.");
+        }
+        env->ExceptionClear();
+      }
+    }
     int status = env->RegisterNatives(unsafecls, methods, sizeof(methods)/sizeof(JNINativeMethod));
     if (env->ExceptionOccurred()) {
       if (PrintMiscellaneous && (Verbose || WizardMode)) {
diff --git a/hotspot/src/share/vm/prims/wbtestmethods/parserTests.cpp b/hotspot/src/share/vm/prims/wbtestmethods/parserTests.cpp
new file mode 100644
index 0000000..54c8a31
--- /dev/null
+++ b/hotspot/src/share/vm/prims/wbtestmethods/parserTests.cpp
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "classfile/symbolTable.hpp"
+
+#include "prims/jni.h"
+#include "prims/whitebox.hpp"
+#include "prims/wbtestmethods/parserTests.hpp"
+#include "runtime/interfaceSupport.hpp"
+
+#include "memory/oopFactory.hpp"
+
+#include "services/diagnosticArgument.hpp"
+#include "services/diagnosticFramework.hpp"
+
+//There's no way of beforeahnd knowing an upper size
+//Of the length of a string representation of
+//the value of an argument.
+#define VALUE_MAXLEN 256
+
+// DiagnosticFramework test utility methods
+
+/*
+ * The DiagnosticArgumentType class contains an enum that says which type
+ * this argument represents. (JLONG, BOOLEAN etc).
+ * This method Returns a char* representation of that enum value.
+ */
+static const char* lookup_diagnosticArgumentEnum(const char* field_name, oop object) {
+  Thread* THREAD = Thread::current();
+  const char* enum_sig = "Lsun/hotspot/parser/DiagnosticCommand$DiagnosticArgumentType;";
+  TempNewSymbol enumSigSymbol = SymbolTable::lookup(enum_sig, (int) strlen(enum_sig), THREAD);
+  int offset = WhiteBox::offset_for_field(field_name, object, enumSigSymbol);
+  oop enumOop = object->obj_field(offset);
+
+  const char* ret = WhiteBox::lookup_jstring("name", enumOop);
+  return ret;
+}
+
+/*
+ * Takes an oop to a DiagnosticArgumentType-instance and
+ * reads the fields from it. Fills an native DCmdParser with
+ * this info.
+ */
+static void fill_in_parser(DCmdParser* parser, oop argument)
+{
+  const char* name = WhiteBox::lookup_jstring("name", argument);
+  const char* desc = WhiteBox::lookup_jstring("desc", argument);
+  const char* default_value = WhiteBox::lookup_jstring("defaultValue", argument);
+  bool mandatory = WhiteBox::lookup_bool("mandatory", argument);
+  const char*  type = lookup_diagnosticArgumentEnum("type", argument);
+
+   if (strcmp(type, "STRING") == 0) {
+     DCmdArgument<char*>* argument = new DCmdArgument<char*>(
+     name, desc,
+     "STRING", mandatory, default_value);
+     parser->add_dcmd_option(argument);
+   } else if (strcmp(type, "NANOTIME") == 0) {
+     DCmdArgument<NanoTimeArgument>* argument = new DCmdArgument<NanoTimeArgument>(
+     name, desc,
+     "NANOTIME", mandatory, default_value);
+     parser->add_dcmd_option(argument);
+   } else if (strcmp(type, "JLONG") == 0) {
+     DCmdArgument<jlong>* argument = new DCmdArgument<jlong>(
+     name, desc,
+     "JLONG", mandatory, default_value);
+     parser->add_dcmd_option(argument);
+   } else if (strcmp(type, "BOOLEAN") == 0) {
+     DCmdArgument<bool>* argument = new DCmdArgument<bool>(
+     name, desc,
+     "BOOLEAN", mandatory, default_value);
+     parser->add_dcmd_option(argument);
+   } else if (strcmp(type, "MEMORYSIZE") == 0) {
+     DCmdArgument<MemorySizeArgument>* argument = new DCmdArgument<MemorySizeArgument>(
+     name, desc,
+     "MEMORY SIZE", mandatory, default_value);
+     parser->add_dcmd_option(argument);
+   } else if (strcmp(type, "STRINGARRAY") == 0) {
+     DCmdArgument<StringArrayArgument*>* argument = new DCmdArgument<StringArrayArgument*>(
+     name, desc,
+     "STRING SET", mandatory);
+     parser->add_dcmd_option(argument);
+   }
+}
+
+/*
+ * Will Fill in a java object array with alternating names of parsed command line options and
+ * the value that has been parsed for it:
+ * { name, value, name, value ... }
+ * This can then be checked from java.
+ */
+WB_ENTRY(jobjectArray, WB_ParseCommandLine(JNIEnv* env, jobject o, jstring j_cmdline, jobjectArray arguments))
+  ResourceMark rm;
+  DCmdParser parser;
+
+  const char* c_cmdline = java_lang_String::as_utf8_string(JNIHandles::resolve(j_cmdline));
+  objArrayOop argumentArray = objArrayOop(JNIHandles::resolve_non_null(arguments));
+
+  int length = argumentArray->length();
+
+  for (int i = 0; i < length; i++) {
+    oop argument_oop = argumentArray->obj_at(i);
+    fill_in_parser(&parser, argument_oop);
+  }
+
+  CmdLine cmdline(c_cmdline, strlen(c_cmdline), true);
+  parser.parse(&cmdline,',',CHECK_NULL);
+
+  klassOop k = SystemDictionary::Object_klass();
+  objArrayOop returnvalue_array = oopFactory::new_objArray(k, parser.num_arguments() * 2, CHECK_NULL);
+
+  GrowableArray<const char *>*parsedArgNames = parser.argument_name_array();
+
+  for (int i = 0; i < parser.num_arguments(); i++) {
+    oop parsedName = java_lang_String::create_oop_from_str(parsedArgNames->at(i), CHECK_NULL);
+    returnvalue_array->obj_at_put(i*2, parsedName);
+    GenDCmdArgument* arg = parser.lookup_dcmd_option(parsedArgNames->at(i), strlen(parsedArgNames->at(i)));
+    char buf[VALUE_MAXLEN];
+    arg->value_as_str(buf, sizeof(buf));
+    oop parsedValue = java_lang_String::create_oop_from_str(buf, CHECK_NULL);
+    returnvalue_array->obj_at_put(i*2+1, parsedValue);
+  }
+
+  return (jobjectArray) JNIHandles::make_local(returnvalue_array);
+
+WB_END
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp
similarity index 71%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp
index 077886f..8efdd9d 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/hotspot/src/share/vm/prims/wbtestmethods/parserTests.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,14 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+#ifndef SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
+#define SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
 
-    public FileFormatException() {
-        super();
-    }
+#include "prims/jni.h"
+#include "prims/whitebox.hpp"
 
-    public FileFormatException(String s) {
-        super(s);
-    }
-}
+WB_METHOD_DECLARE WB_ParseCommandLine(JNIEnv* env, jobject o, jstring args, jobjectArray arguments);
+
+#endif //SHARE_VM_PRIMS_WBTESTMETHODS_PARSERTESTS_H
diff --git a/hotspot/src/share/vm/prims/whitebox.cpp b/hotspot/src/share/vm/prims/whitebox.cpp
new file mode 100644
index 0000000..e93b910
--- /dev/null
+++ b/hotspot/src/share/vm/prims/whitebox.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "memory/universe.hpp"
+#include "oops/oop.inline.hpp"
+
+#include "classfile/symbolTable.hpp"
+
+#include "prims/whitebox.hpp"
+#include "prims/wbtestmethods/parserTests.hpp"
+
+#include "runtime/interfaceSupport.hpp"
+#include "runtime/os.hpp"
+#include "utilities/debug.hpp"
+
+#ifndef SERIALGC
+#include "gc_implementation/g1/concurrentMark.hpp"
+#include "gc_implementation/g1/g1CollectedHeap.inline.hpp"
+#include "gc_implementation/g1/heapRegionRemSet.hpp"
+#endif // !SERIALGC
+
+bool WhiteBox::_used = false;
+
+WB_ENTRY(jlong, WB_GetObjectAddress(JNIEnv* env, jobject o, jobject obj))
+  return (jlong)(void*)JNIHandles::resolve(obj);
+WB_END
+
+WB_ENTRY(jint, WB_GetHeapOopSize(JNIEnv* env, jobject o))
+  return heapOopSize;
+WB_END
+
+#ifndef SERIALGC
+WB_ENTRY(jboolean, WB_G1IsHumongous(JNIEnv* env, jobject o, jobject obj))
+  G1CollectedHeap* g1 = G1CollectedHeap::heap();
+  oop result = JNIHandles::resolve(obj);
+  const HeapRegion* hr = g1->heap_region_containing(result);
+  return hr->isHumongous();
+WB_END
+
+WB_ENTRY(jlong, WB_G1NumFreeRegions(JNIEnv* env, jobject o))
+  G1CollectedHeap* g1 = G1CollectedHeap::heap();
+  size_t nr = g1->free_regions();
+  return (jlong)nr;
+WB_END
+
+WB_ENTRY(jboolean, WB_G1InConcurrentMark(JNIEnv* env, jobject o))
+  G1CollectedHeap* g1 = G1CollectedHeap::heap();
+  ConcurrentMark* cm = g1->concurrent_mark();
+  return cm->concurrent_marking_in_progress();
+WB_END
+
+WB_ENTRY(jint, WB_G1RegionSize(JNIEnv* env, jobject o))
+  return (jint)HeapRegion::GrainBytes;
+WB_END
+#endif // !SERIALGC
+
+//Some convenience methods to deal with objects from java
+int WhiteBox::offset_for_field(const char* field_name, oop object,
+    Symbol* signature_symbol) {
+  assert(field_name != NULL && strlen(field_name) > 0, "Field name not valid");
+  Thread* THREAD = Thread::current();
+
+  //Get the class of our object
+  klassOop arg_klass = object->klass();
+  //Turn it into an instance-klass
+  instanceKlass* ik = instanceKlass::cast(arg_klass);
+
+  //Create symbols to look for in the class
+  TempNewSymbol name_symbol = SymbolTable::lookup(field_name, (int) strlen(field_name),
+      THREAD);
+
+  //To be filled in with an offset of the field we're looking for
+  fieldDescriptor fd;
+
+  klassOop res = ik->find_field(name_symbol, signature_symbol, &fd);
+  if (res == NULL) {
+    tty->print_cr("Invalid layout of %s at %s", ik->external_name(),
+        name_symbol->as_C_string());
+    fatal("Invalid layout of preloaded class");
+  }
+
+  //fetch the field at the offset we've found
+  int dest_offset = fd.offset();
+
+  return dest_offset;
+}
+
+
+const char* WhiteBox::lookup_jstring(const char* field_name, oop object) {
+  int offset = offset_for_field(field_name, object,
+      vmSymbols::string_signature());
+  oop string = object->obj_field(offset);
+  if (string == NULL) {
+    return NULL;
+  }
+  const char* ret = java_lang_String::as_utf8_string(string);
+  return ret;
+}
+
+bool WhiteBox::lookup_bool(const char* field_name, oop object) {
+  int offset =
+      offset_for_field(field_name, object, vmSymbols::bool_signature());
+  bool ret = (object->bool_field(offset) == JNI_TRUE);
+  return ret;
+}
+
+
+#define CC (char*)
+
+static JNINativeMethod methods[] = {
+  {CC"getObjectAddress",   CC"(Ljava/lang/Object;)J", (void*)&WB_GetObjectAddress  },
+  {CC"getHeapOopSize",     CC"()I",                   (void*)&WB_GetHeapOopSize    },
+  {CC "parseCommandLine",
+      CC "(Ljava/lang/String;[Lsun/hotspot/parser/DiagnosticCommand;)[Ljava/lang/Object;",
+      (void*) &WB_ParseCommandLine
+  },
+#ifndef SERIALGC
+  {CC"g1InConcurrentMark", CC"()Z",                   (void*)&WB_G1InConcurrentMark},
+  {CC"g1IsHumongous",      CC"(Ljava/lang/Object;)Z", (void*)&WB_G1IsHumongous     },
+  {CC"g1NumFreeRegions",   CC"()J",                   (void*)&WB_G1NumFreeRegions  },
+  {CC"g1RegionSize",       CC"()I",                   (void*)&WB_G1RegionSize      },
+#endif // !SERIALGC
+};
+
+#undef CC
+
+JVM_ENTRY(void, JVM_RegisterWhiteBoxMethods(JNIEnv* env, jclass wbclass))
+  {
+    if (WhiteBoxAPI) {
+      // Make sure that wbclass is loaded by the null classloader
+      instanceKlassHandle ikh = instanceKlassHandle(JNIHandles::resolve(wbclass)->klass());
+      Handle loader(ikh->class_loader());
+      if (loader.is_null()) {
+        ThreadToNativeFromVM ttnfv(thread); // can't be in VM when we call JNI
+        jint result = env->RegisterNatives(wbclass, methods, sizeof(methods)/sizeof(methods[0]));
+        if (result == 0) {
+          WhiteBox::set_used();
+        }
+      }
+    }
+  }
+JVM_END
diff --git a/hotspot/src/share/vm/prims/whitebox.hpp b/hotspot/src/share/vm/prims/whitebox.hpp
new file mode 100644
index 0000000..a5dda9b
--- /dev/null
+++ b/hotspot/src/share/vm/prims/whitebox.hpp
@@ -0,0 +1,53 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_PRIMS_WHITEBOX_HPP
+#define SHARE_VM_PRIMS_WHITEBOX_HPP
+
+#include "prims/jni.h"
+
+#include "memory/allocation.hpp"
+#include "oops/oopsHierarchy.hpp"
+
+// Entry macro to transition from JNI to VM state.
+
+#define WB_ENTRY(result_type, header) JNI_ENTRY(result_type, header)
+#define WB_END JNI_END
+#define WB_METHOD_DECLARE extern "C" jobjectArray JNICALL
+
+class WhiteBox : public AllStatic {
+ private:
+  static bool _used;
+ public:
+  static bool used()     { return _used; }
+  static void set_used() { _used = true; }
+  static int offset_for_field(const char* field_name, oop object,
+    Symbol* signature_symbol);
+  static const char* lookup_jstring(const char* field_name, oop object);
+  static bool lookup_bool(const char* field_name, oop object);
+};
+
+
+
+#endif // SHARE_VM_PRIMS_WHITEBOX_HPP
diff --git a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
index 29453b8..bc8a04f 100644
--- a/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
+++ b/hotspot/src/share/vm/runtime/advancedThresholdPolicy.cpp
@@ -30,12 +30,12 @@
 // Print an event.
 void AdvancedThresholdPolicy::print_specific(EventType type, methodHandle mh, methodHandle imh,
                                              int bci, CompLevel level) {
-  tty->print(" rate: ");
+  tty->print(" rate=");
   if (mh->prev_time() == 0) tty->print("n/a");
   else tty->print("%f", mh->rate());
 
-  tty->print(" k: %.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
-                                threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
+  tty->print(" k=%.2lf,%.2lf", threshold_scale(CompLevel_full_profile, Tier3LoadFeedback),
+                               threshold_scale(CompLevel_full_optimization, Tier4LoadFeedback));
 
 }
 
diff --git a/hotspot/src/share/vm/runtime/arguments.cpp b/hotspot/src/share/vm/runtime/arguments.cpp
index 1d3b887..b62c857 100644
--- a/hotspot/src/share/vm/runtime/arguments.cpp
+++ b/hotspot/src/share/vm/runtime/arguments.cpp
@@ -35,6 +35,7 @@
 #include "runtime/globals_extension.hpp"
 #include "runtime/java.hpp"
 #include "services/management.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/taskqueue.hpp"
 #ifdef TARGET_OS_FAMILY_linux
@@ -368,7 +369,7 @@
 inline void SysClassPath::reset_item_at(int index) {
   assert(index < _scp_nitems && index != _scp_base, "just checking");
   if (_items[index] != NULL) {
-    FREE_C_HEAP_ARRAY(char, _items[index]);
+    FREE_C_HEAP_ARRAY(char, _items[index], mtInternal);
     _items[index] = NULL;
   }
 }
@@ -400,11 +401,11 @@
       expanded_path = add_jars_to_path(expanded_path, path);
       path = end;
     } else {
-      char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1);
+      char* dirpath = NEW_C_HEAP_ARRAY(char, tmp_end - path + 1, mtInternal);
       memcpy(dirpath, path, tmp_end - path);
       dirpath[tmp_end - path] = '\0';
       expanded_path = add_jars_to_path(expanded_path, dirpath);
-      FREE_C_HEAP_ARRAY(char, dirpath);
+      FREE_C_HEAP_ARRAY(char, dirpath, mtInternal);
       path = tmp_end + 1;
     }
   }
@@ -435,7 +436,7 @@
   assert(total_len > 0, "empty sysclasspath not allowed");
 
   // Copy the _items to a single string.
-  char* cp = NEW_C_HEAP_ARRAY(char, total_len);
+  char* cp = NEW_C_HEAP_ARRAY(char, total_len, mtInternal);
   char* cp_tmp = cp;
   for (i = 0; i < _scp_nitems; ++i) {
     if (_items[i] != NULL) {
@@ -456,7 +457,7 @@
   assert(str != NULL, "just checking");
   if (path == NULL) {
     size_t len = strlen(str) + 1;
-    cp = NEW_C_HEAP_ARRAY(char, len);
+    cp = NEW_C_HEAP_ARRAY(char, len, mtInternal);
     memcpy(cp, str, len);                       // copy the trailing null
   } else {
     const char separator = *os::path_separator();
@@ -465,15 +466,15 @@
     size_t len = old_len + str_len + 2;
 
     if (prepend) {
-      cp = NEW_C_HEAP_ARRAY(char, len);
+      cp = NEW_C_HEAP_ARRAY(char, len, mtInternal);
       char* cp_tmp = cp;
       memcpy(cp_tmp, str, str_len);
       cp_tmp += str_len;
       *cp_tmp = separator;
       memcpy(++cp_tmp, path, old_len + 1);      // copy the trailing null
-      FREE_C_HEAP_ARRAY(char, path);
+      FREE_C_HEAP_ARRAY(char, path, mtInternal);
     } else {
-      cp = REALLOC_C_HEAP_ARRAY(char, path, len);
+      cp = REALLOC_C_HEAP_ARRAY(char, path, len, mtInternal);
       char* cp_tmp = cp + old_len;
       *cp_tmp = separator;
       memcpy(++cp_tmp, str, str_len + 1);       // copy the trailing null
@@ -495,7 +496,7 @@
 
   /* Scan the directory for jars/zips, appending them to path. */
   struct dirent *entry;
-  char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory));
+  char *dbuf = NEW_C_HEAP_ARRAY(char, os::readdir_buf_size(directory), mtInternal);
   while ((entry = os::readdir(dir, (dirent *) dbuf)) != NULL) {
     const char* name = entry->d_name;
     const char* ext = name + strlen(name) - 4;
@@ -503,13 +504,13 @@
       (os::file_name_strcmp(ext, ".jar") == 0 ||
        os::file_name_strcmp(ext, ".zip") == 0);
     if (isJarOrZip) {
-      char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name));
+      char* jarpath = NEW_C_HEAP_ARRAY(char, directory_len + 2 + strlen(name), mtInternal);
       sprintf(jarpath, "%s%s%s", directory, dir_sep, name);
       path = add_to_path(path, jarpath, false);
-      FREE_C_HEAP_ARRAY(char, jarpath);
+      FREE_C_HEAP_ARRAY(char, jarpath, mtInternal);
     }
   }
-  FREE_C_HEAP_ARRAY(char, dbuf);
+  FREE_C_HEAP_ARRAY(char, dbuf, mtInternal);
   os::closedir(dir);
   return path;
 }
@@ -631,7 +632,7 @@
 static bool set_string_flag(char* name, const char* value, FlagValueOrigin origin) {
   if (!CommandLineFlags::ccstrAtPut(name, &value, origin))  return false;
   // Contract:  CommandLineFlags always returns a pointer that needs freeing.
-  FREE_C_HEAP_ARRAY(char, value);
+  FREE_C_HEAP_ARRAY(char, value, mtInternal);
   return true;
 }
 
@@ -647,7 +648,7 @@
   } else if (new_len == 0) {
     value = old_value;
   } else {
-    char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1);
+    char* buf = NEW_C_HEAP_ARRAY(char, old_len + 1 + new_len + 1, mtInternal);
     // each new setting adds another LINE to the switch:
     sprintf(buf, "%s\n%s", old_value, new_value);
     value = buf;
@@ -655,10 +656,10 @@
   }
   (void) CommandLineFlags::ccstrAtPut(name, &value, origin);
   // CommandLineFlags always returns a pointer that needs freeing.
-  FREE_C_HEAP_ARRAY(char, value);
+  FREE_C_HEAP_ARRAY(char, value, mtInternal);
   if (free_this_too != NULL) {
     // CommandLineFlags made its own copy, so I must delete my own temp. buffer.
-    FREE_C_HEAP_ARRAY(char, free_this_too);
+    FREE_C_HEAP_ARRAY(char, free_this_too, mtInternal);
   }
   return true;
 }
@@ -735,9 +736,9 @@
   // expand the array and add arg to the last element
   (*count)++;
   if (*bldarray == NULL) {
-    *bldarray = NEW_C_HEAP_ARRAY(char*, *count);
+    *bldarray = NEW_C_HEAP_ARRAY(char*, *count, mtInternal);
   } else {
-    *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, *count);
+    *bldarray = REALLOC_C_HEAP_ARRAY(char*, *bldarray, *count, mtInternal);
   }
   (*bldarray)[index] = strdup(arg);
 }
@@ -917,13 +918,13 @@
   char* value = (char *)ns;
 
   size_t key_len = (eq == NULL) ? strlen(prop) : (eq - prop);
-  key = AllocateHeap(key_len + 1, "add_property");
+  key = AllocateHeap(key_len + 1, mtInternal);
   strncpy(key, prop, key_len);
   key[key_len] = '\0';
 
   if (eq != NULL) {
     size_t value_len = strlen(prop) - key_len - 1;
-    value = AllocateHeap(value_len + 1, "add_property");
+    value = AllocateHeap(value_len + 1, mtInternal);
     strncpy(value, &prop[key_len + 1], value_len + 1);
   }
 
@@ -1915,7 +1916,7 @@
       (ExplicitGCInvokesConcurrent ||
        ExplicitGCInvokesConcurrentAndUnloadsClasses)) {
     jio_fprintf(defaultStream::error_stream(),
-                "error: +ExplictGCInvokesConcurrent[AndUnloadsClasses] conflicts"
+                "error: +ExplicitGCInvokesConcurrent[AndUnloadsClasses] conflicts"
                 " with -UseAsyncConcMarkSweepGC");
     status = false;
   }
@@ -1945,6 +1946,25 @@
 
   status = status && verify_object_alignment();
 
+#ifdef SPARC
+  if (UseConcMarkSweepGC || UseG1GC) {
+    // Issue a stern warning if the user has explicitly set
+    // UseMemSetInBOT (it is known to cause issues), but allow
+    // use for experimentation and debugging.
+    if (VM_Version::is_sun4v() && UseMemSetInBOT) {
+      assert(!FLAG_IS_DEFAULT(UseMemSetInBOT), "Error");
+      warning("Experimental flag -XX:+UseMemSetInBOT is known to cause instability"
+          " on sun4v; please understand that you are using at your own risk!");
+    }
+  }
+#endif // SPARC
+
+  // check native memory tracking flags
+  if (PrintNMTStatistics && MemTracker::tracking_level() == MemTracker::NMT_off) {
+    warning("PrintNMTStatistics is disabled, because native memory tracking is not enabled");
+    PrintNMTStatistics = false;
+  }
+
   return status;
 }
 
@@ -2058,12 +2078,25 @@
     const char* altclasses_jar = "alt-rt.jar";
     size_t altclasses_path_len = strlen(get_meta_index_dir()) + 1 +
                                  strlen(altclasses_jar);
-    char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len);
+    char* altclasses_path = NEW_C_HEAP_ARRAY(char, altclasses_path_len, mtInternal);
     strcpy(altclasses_path, get_meta_index_dir());
     strcat(altclasses_path, altclasses_jar);
     scp.add_suffix_to_prefix(altclasses_path);
     scp_assembly_required = true;
-    FREE_C_HEAP_ARRAY(char, altclasses_path);
+    FREE_C_HEAP_ARRAY(char, altclasses_path, mtInternal);
+  }
+
+  if (WhiteBoxAPI) {
+    // Append wb.jar to bootclasspath if enabled
+    const char* wb_jar = "wb.jar";
+    size_t wb_path_len = strlen(get_meta_index_dir()) + 1 +
+                         strlen(wb_jar);
+    char* wb_path = NEW_C_HEAP_ARRAY(char, wb_path_len, mtInternal);
+    strcpy(wb_path, get_meta_index_dir());
+    strcat(wb_path, wb_jar);
+    scp.add_suffix(wb_path);
+    scp_assembly_required = true;
+    FREE_C_HEAP_ARRAY(char, wb_path, mtInternal);
   }
 
   // Parse _JAVA_OPTIONS environment variable (if present) (mimics classic VM)
@@ -2148,13 +2181,13 @@
       if (tail != NULL) {
         const char* pos = strchr(tail, ':');
         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
-        char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1), tail, len);
+        char* name = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
         name[len] = '\0';
 
         char *options = NULL;
         if(pos != NULL) {
           size_t len2 = strlen(pos+1) + 1; // options start after ':'.  Final zero must be copied.
-          options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2), pos+1, len2);
+          options = (char*)memcpy(NEW_C_HEAP_ARRAY(char, len2, mtInternal), pos+1, len2);
         }
 #ifdef JVMTI_KERNEL
         if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
@@ -2169,12 +2202,12 @@
       if(tail != NULL) {
         const char* pos = strchr(tail, '=');
         size_t len = (pos == NULL) ? strlen(tail) : pos - tail;
-        char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1), tail, len);
+        char* name = strncpy(NEW_C_HEAP_ARRAY(char, len + 1, mtInternal), tail, len);
         name[len] = '\0';
 
         char *options = NULL;
         if(pos != NULL) {
-          options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(pos + 1) + 1), pos + 1);
+          options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(pos + 1) + 1, mtInternal), pos + 1);
         }
 #ifdef JVMTI_KERNEL
         if ((strcmp(name, "hprof") == 0) || (strcmp(name, "jdwp") == 0)) {
@@ -2187,7 +2220,7 @@
     // -javaagent
     } else if (match_option(option, "-javaagent:", &tail)) {
       if(tail != NULL) {
-        char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1), tail);
+        char *options = strcpy(NEW_C_HEAP_ARRAY(char, strlen(tail) + 1, mtInternal), tail);
         add_init_agent("instrument", options, false);
       }
     // -Xnoclassgc
@@ -2695,6 +2728,17 @@
         return JNI_EINVAL;
       }
       FLAG_SET_CMDLINE(uintx, ConcGCThreads, conc_threads);
+    } else if (match_option(option, "-XX:MaxDirectMemorySize=", &tail)) {
+      julong max_direct_memory_size = 0;
+      ArgsRange errcode = parse_memory_size(tail, &max_direct_memory_size, 0);
+      if (errcode != arg_in_range) {
+        jio_fprintf(defaultStream::error_stream(),
+                    "Invalid maximum direct memory size: %s\n",
+                    option->optionString);
+        describe_range_error(errcode);
+        return JNI_EINVAL;
+      }
+      FLAG_SET_CMDLINE(uintx, MaxDirectMemorySize, max_direct_memory_size);
     } else if (match_option(option, "-XX:", &tail)) { // -XX:xxxx
       // Skip -XX:Flags= since that case has already been handled
       if (strncmp(tail, "Flags=", strlen("Flags=")) != 0) {
@@ -2945,7 +2989,7 @@
   char *end = strrchr(jvm_path, *os::file_separator());
   if (end != NULL) *end = '\0';
   char *shared_archive_path = NEW_C_HEAP_ARRAY(char, strlen(jvm_path) +
-                                        strlen(os::file_separator()) + 20);
+      strlen(os::file_separator()) + 20, mtInternal);
   if (shared_archive_path == NULL) return JNI_ENOMEM;
   strcpy(shared_archive_path, jvm_path);
   strcat(shared_archive_path, os::file_separator());
@@ -2986,6 +3030,10 @@
       CommandLineFlags::printFlags(tty, false);
       vm_exit(0);
     }
+    if (match_option(option, "-XX:NativeMemoryTracking", &tail)) {
+      MemTracker::init_tracking_options(tail);
+    }
+
 
 #ifndef PRODUCT
     if (match_option(option, "-XX:+PrintFlagsWithComments", &tail)) {
@@ -3058,15 +3106,6 @@
   }
 #endif // PRODUCT
 
-  // Transitional
-  if (EnableMethodHandles || AnonymousClasses) {
-    if (!EnableInvokeDynamic && !FLAG_IS_DEFAULT(EnableInvokeDynamic)) {
-      warning("EnableMethodHandles and AnonymousClasses are obsolete.  Keeping EnableInvokeDynamic disabled.");
-    } else {
-      EnableInvokeDynamic = true;
-    }
-  }
-
   // JSR 292 is not supported before 1.7
   if (!JDK_Version::is_gte_jdk17x_version()) {
     if (EnableInvokeDynamic) {
@@ -3095,6 +3134,14 @@
     PrintGC = true;
   }
 
+  if (!JDK_Version::is_gte_jdk18x_version()) {
+    // To avoid changing the log format for 7 updates this flag is only
+    // true by default in JDK8 and above.
+    if (FLAG_IS_DEFAULT(PrintGCCause)) {
+      FLAG_SET_DEFAULT(PrintGCCause, false);
+    }
+  }
+
   // Set object alignment values.
   set_object_alignment();
 
@@ -3326,7 +3373,7 @@
     }
   }
   // Add one for null terminator.
-  char *props = AllocateHeap(length + 1, "get_kernel_properties");
+  char *props = AllocateHeap(length + 1, mtInternal);
   if (length != 0) {
     int pos = 0;
     for (prop = _system_properties; prop != NULL; prop = prop->next()) {
diff --git a/hotspot/src/share/vm/runtime/arguments.hpp b/hotspot/src/share/vm/runtime/arguments.hpp
index 076b486..e78e45c 100644
--- a/hotspot/src/share/vm/runtime/arguments.hpp
+++ b/hotspot/src/share/vm/runtime/arguments.hpp
@@ -44,7 +44,7 @@
 
 // Element describing System and User (-Dkey=value flags) defined property.
 
-class SystemProperty: public CHeapObj {
+class SystemProperty: public CHeapObj<mtInternal> {
  private:
   char*           _key;
   char*           _value;
@@ -63,7 +63,7 @@
       if (_value != NULL) {
         FreeHeap(_value);
       }
-      _value = AllocateHeap(strlen(value)+1);
+      _value = AllocateHeap(strlen(value)+1, mtInternal);
       if (_value != NULL) {
         strcpy(_value, value);
       }
@@ -80,7 +80,7 @@
       if (_value != NULL) {
         len += strlen(_value);
       }
-      sp = AllocateHeap(len+2);
+      sp = AllocateHeap(len+2, mtInternal);
       if (sp != NULL) {
         if (_value != NULL) {
           strcpy(sp, _value);
@@ -100,13 +100,13 @@
     if (key == NULL) {
       _key = NULL;
     } else {
-      _key = AllocateHeap(strlen(key)+1);
+      _key = AllocateHeap(strlen(key)+1, mtInternal);
       strcpy(_key, key);
     }
     if (value == NULL) {
       _value = NULL;
     } else {
-      _value = AllocateHeap(strlen(value)+1);
+      _value = AllocateHeap(strlen(value)+1, mtInternal);
       strcpy(_value, value);
     }
     _next = NULL;
@@ -116,7 +116,7 @@
 
 
 // For use by -agentlib, -agentpath and -Xrun
-class AgentLibrary : public CHeapObj {
+class AgentLibrary : public CHeapObj<mtInternal> {
   friend class AgentLibraryList;
  private:
   char*           _name;
@@ -136,12 +136,12 @@
 
   // Constructor
   AgentLibrary(const char* name, const char* options, bool is_absolute_path, void* os_lib) {
-    _name = AllocateHeap(strlen(name)+1);
+    _name = AllocateHeap(strlen(name)+1, mtInternal);
     strcpy(_name, name);
     if (options == NULL) {
       _options = NULL;
     } else {
-      _options = AllocateHeap(strlen(options)+1);
+      _options = AllocateHeap(strlen(options)+1, mtInternal);
       strcpy(_options, options);
     }
     _is_absolute_path = is_absolute_path;
diff --git a/hotspot/src/share/vm/runtime/biasedLocking.cpp b/hotspot/src/share/vm/runtime/biasedLocking.cpp
index ba49d80..de739ec 100644
--- a/hotspot/src/share/vm/runtime/biasedLocking.cpp
+++ b/hotspot/src/share/vm/runtime/biasedLocking.cpp
@@ -687,8 +687,8 @@
   // monitors in a prepass and, if they are biased, preserve their
   // mark words here. This should be a relatively small set of objects
   // especially compared to the number of objects in the heap.
-  _preserved_mark_stack = new (ResourceObj::C_HEAP) GrowableArray<markOop>(10, true);
-  _preserved_oop_stack = new (ResourceObj::C_HEAP) GrowableArray<Handle>(10, true);
+  _preserved_mark_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<markOop>(10, true);
+  _preserved_oop_stack = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Handle>(10, true);
 
   ResourceMark rm;
   Thread* cur = Thread::current();
diff --git a/hotspot/src/share/vm/runtime/compilationPolicy.cpp b/hotspot/src/share/vm/runtime/compilationPolicy.cpp
index dadfb1e..4ee6083 100644
--- a/hotspot/src/share/vm/runtime/compilationPolicy.cpp
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.cpp
@@ -394,28 +394,27 @@
 // SimpleCompPolicy - compile current method
 
 void SimpleCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
-  int hot_count = m->invocation_count();
+  const int comp_level = CompLevel_highest_tier;
+  const int hot_count = m->invocation_count();
   reset_counter_for_invocation_event(m);
   const char* comment = "count";
 
   if (is_compilation_enabled() && can_be_compiled(m)) {
     nmethod* nm = m->code();
     if (nm == NULL ) {
-      const char* comment = "count";
-      CompileBroker::compile_method(m, InvocationEntryBci, CompLevel_highest_tier,
-                                    m, hot_count, comment, thread);
+      CompileBroker::compile_method(m, InvocationEntryBci, comp_level, m, hot_count, comment, thread);
     }
   }
 }
 
 void SimpleCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
-  int hot_count = m->backedge_count();
+  const int comp_level = CompLevel_highest_tier;
+  const int hot_count = m->backedge_count();
   const char* comment = "backedge_count";
 
-  if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) {
-    CompileBroker::compile_method(m, bci, CompLevel_highest_tier,
-                                  m, hot_count, comment, thread);
-    NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));)
+  if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m)) {
+    CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
+    NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
   }
 }
 // StackWalkCompPolicy - walk up stack to find a suitable method to compile
@@ -426,7 +425,8 @@
 
 // Consider m for compilation
 void StackWalkCompPolicy::method_invocation_event(methodHandle m, JavaThread* thread) {
-  int hot_count = m->invocation_count();
+  const int comp_level = CompLevel_highest_tier;
+  const int hot_count = m->invocation_count();
   reset_counter_for_invocation_event(m);
   const char* comment = "count";
 
@@ -457,20 +457,20 @@
       if (TimeCompilationPolicy) accumulated_time()->stop();
       assert(top != NULL, "findTopInlinableFrame returned null");
       if (TraceCompilationPolicy) top->print();
-      CompileBroker::compile_method(top->top_method(), InvocationEntryBci, CompLevel_highest_tier,
+      CompileBroker::compile_method(top->top_method(), InvocationEntryBci, comp_level,
                                     m, hot_count, comment, thread);
     }
   }
 }
 
 void StackWalkCompPolicy::method_back_branch_event(methodHandle m, int bci, JavaThread* thread) {
-  int hot_count = m->backedge_count();
+  const int comp_level = CompLevel_highest_tier;
+  const int hot_count = m->backedge_count();
   const char* comment = "backedge_count";
 
-  if (is_compilation_enabled() && !m->is_not_osr_compilable() && can_be_compiled(m)) {
-    CompileBroker::compile_method(m, bci, CompLevel_highest_tier, m, hot_count, comment, thread);
-
-    NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, CompLevel_highest_tier, true));)
+  if (is_compilation_enabled() && !m->is_not_osr_compilable(comp_level) && can_be_compiled(m)) {
+    CompileBroker::compile_method(m, bci, comp_level, m, hot_count, comment, thread);
+    NOT_PRODUCT(trace_osr_completion(m->lookup_osr_nmethod_for(bci, comp_level, true));)
   }
 }
 
diff --git a/hotspot/src/share/vm/runtime/compilationPolicy.hpp b/hotspot/src/share/vm/runtime/compilationPolicy.hpp
index 1d8427c..a0912be 100644
--- a/hotspot/src/share/vm/runtime/compilationPolicy.hpp
+++ b/hotspot/src/share/vm/runtime/compilationPolicy.hpp
@@ -37,7 +37,7 @@
 class CompileTask;
 class CompileQueue;
 
-class CompilationPolicy : public CHeapObj {
+class CompilationPolicy : public CHeapObj<mtCompiler> {
   static CompilationPolicy* _policy;
   // Accumulated time
   static elapsedTimer       _accumulated_time;
diff --git a/hotspot/src/share/vm/runtime/deoptimization.cpp b/hotspot/src/share/vm/runtime/deoptimization.cpp
index 0e2a983..f3e6c94 100644
--- a/hotspot/src/share/vm/runtime/deoptimization.cpp
+++ b/hotspot/src/share/vm/runtime/deoptimization.cpp
@@ -101,7 +101,7 @@
   _number_of_frames          = number_of_frames;
   _frame_sizes               = frame_sizes;
   _frame_pcs                 = frame_pcs;
-  _register_block            = NEW_C_HEAP_ARRAY(intptr_t, RegisterMap::reg_count * 2);
+  _register_block            = NEW_C_HEAP_ARRAY(intptr_t, RegisterMap::reg_count * 2, mtCompiler);
   _return_type               = return_type;
   _initial_info              = 0;
   // PD (x86 only)
@@ -114,9 +114,9 @@
 
 
 Deoptimization::UnrollBlock::~UnrollBlock() {
-  FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes);
-  FREE_C_HEAP_ARRAY(intptr_t, _frame_pcs);
-  FREE_C_HEAP_ARRAY(intptr_t, _register_block);
+  FREE_C_HEAP_ARRAY(intptr_t, _frame_sizes, mtCompiler);
+  FREE_C_HEAP_ARRAY(intptr_t, _frame_pcs, mtCompiler);
+  FREE_C_HEAP_ARRAY(intptr_t, _register_block, mtCompiler);
 }
 
 
@@ -233,6 +233,7 @@
         return_value = Handle(thread, result);
         assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
         if (TraceDeoptimization) {
+          ttyLocker ttyl;
           tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread);
         }
       }
@@ -358,9 +359,9 @@
 
   // Compute the vframes' sizes.  Note that frame_sizes[] entries are ordered from outermost to innermost
   // virtual activation, which is the reverse of the elements in the vframes array.
-  intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames);
+  intptr_t* frame_sizes = NEW_C_HEAP_ARRAY(intptr_t, number_of_frames, mtCompiler);
   // +1 because we always have an interpreter return address for the final slot.
-  address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1);
+  address* frame_pcs = NEW_C_HEAP_ARRAY(address, number_of_frames + 1, mtCompiler);
   int popframe_extra_args = 0;
   // Create an interpreter return address for the stub to use as its return
   // address so the skeletal frames are perfectly walkable
@@ -388,7 +389,7 @@
   if (deopt_sender.is_interpreted_frame()) {
     methodHandle method = deopt_sender.interpreter_frame_method();
     Bytecode_invoke cur = Bytecode_invoke_check(method, deopt_sender.interpreter_frame_bci());
-    if (cur.is_method_handle_invoke()) {
+    if (cur.is_invokedynamic() || cur.is_invokehandle()) {
       // Method handle invokes may involve fairly arbitrary chains of
       // calls so it's impossible to know how much actual space the
       // caller has for locals.
@@ -493,6 +494,7 @@
 
   if (array->frames() > 1) {
     if (VerifyStack && TraceDeoptimization) {
+      ttyLocker ttyl;
       tty->print_cr("Deoptimizing method containing inlining");
     }
   }
@@ -573,6 +575,7 @@
 
 #ifndef PRODUCT
   if (TraceDeoptimization) {
+    ttyLocker ttyl;
     tty->print_cr("DEOPT UNPACKING thread " INTPTR_FORMAT " vframeArray " INTPTR_FORMAT " mode %d", thread, array, exec_mode);
   }
 #endif
@@ -1322,9 +1325,9 @@
       if (TraceDeoptimization) {  // make noise on the tty
         tty->print("Uncommon trap occurred in");
         nm->method()->print_short_name(tty);
-        tty->print(" (@" INTPTR_FORMAT ") thread=%d reason=%s action=%s unloaded_class_index=%d",
+        tty->print(" (@" INTPTR_FORMAT ") thread=" UINTX_FORMAT " reason=%s action=%s unloaded_class_index=%d",
                    fr.pc(),
-                   (int) os::current_thread_id(),
+                   os::current_thread_id(),
                    trap_reason_name(reason),
                    trap_action_name(action),
                    unloaded_class_index);
diff --git a/hotspot/src/share/vm/runtime/deoptimization.hpp b/hotspot/src/share/vm/runtime/deoptimization.hpp
index 1822546..23870b4 100644
--- a/hotspot/src/share/vm/runtime/deoptimization.hpp
+++ b/hotspot/src/share/vm/runtime/deoptimization.hpp
@@ -129,7 +129,7 @@
 
   // UnrollBlock is returned by fetch_unroll_info() to the deoptimization handler (blob).
   // This is only a CheapObj to ease debugging after a deopt failure
-  class UnrollBlock : public CHeapObj {
+  class UnrollBlock : public CHeapObj<mtCompiler> {
    private:
     int       _size_of_deoptimized_frame; // Size, in bytes, of current deoptimized frame
     int       _caller_adjustment;         // Adjustment, in bytes, to caller's SP by initial interpreted frame
diff --git a/hotspot/src/share/vm/runtime/dtraceJSDT.hpp b/hotspot/src/share/vm/runtime/dtraceJSDT.hpp
index bff4310..670eabf 100644
--- a/hotspot/src/share/vm/runtime/dtraceJSDT.hpp
+++ b/hotspot/src/share/vm/runtime/dtraceJSDT.hpp
@@ -63,7 +63,7 @@
   static jboolean is_supported();
 };
 
-class RegisteredProbes : public CHeapObj {
+class RegisteredProbes : public CHeapObj<mtInternal> {
  private:
   nmethod** _nmethods;      // all the probe methods
   size_t    _count;         // number of probe methods
@@ -72,7 +72,7 @@
  public:
   RegisteredProbes(size_t count) {
     _count = count;
-    _nmethods = NEW_C_HEAP_ARRAY(nmethod*, count);
+    _nmethods = NEW_C_HEAP_ARRAY(nmethod*, count, mtInternal);
   }
 
   ~RegisteredProbes() {
@@ -81,7 +81,7 @@
       _nmethods[i]->make_not_entrant();
       _nmethods[i]->method()->clear_code();
     }
-    FREE_C_HEAP_ARRAY(nmethod*, _nmethods);
+    FREE_C_HEAP_ARRAY(nmethod*, _nmethods, mtInternal);
     _nmethods = NULL;
     _count = 0;
   }
diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
index 1fb0ce0..3d5213f 100644
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.cpp
@@ -28,6 +28,7 @@
 #include "memory/resourceArea.hpp"
 #include "memory/universe.inline.hpp"
 #include "oops/instanceKlass.hpp"
+#include "oops/fieldStreams.hpp"
 #include "runtime/fieldDescriptor.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/signature.hpp"
@@ -37,6 +38,24 @@
   return instanceKlass::cast(_cp->pool_holder())->class_loader();
 }
 
+Symbol* fieldDescriptor::generic_signature() const {
+  if (!has_generic_signature()) {
+    return NULL;
+  }
+
+  int idx = 0;
+  instanceKlass* ik = instanceKlass::cast(field_holder());
+  for (AllFieldStream fs(ik); !fs.done(); fs.next()) {
+    if (idx == _index) {
+      return fs.generic_signature();
+    } else {
+      idx ++;
+    }
+  }
+  assert(false, "should never happen");
+  return NULL;
+}
+
 typeArrayOop fieldDescriptor::annotations() const {
   instanceKlass* ik = instanceKlass::cast(field_holder());
   objArrayOop md = ik->fields_annotations();
diff --git a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
index e68b5c5..12c2fd9 100644
--- a/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
+++ b/hotspot/src/share/vm/runtime/fieldDescriptor.hpp
@@ -67,7 +67,7 @@
   oop loader() const;
   // Offset (in words) of field from start of instanceOop / klassOop
   int offset() const                   { return field()->offset(); }
-  Symbol* generic_signature() const    { return field()->generic_signature(_cp); }
+  Symbol* generic_signature() const;
   int index() const                    { return _index; }
   typeArrayOop annotations() const;
 
@@ -100,6 +100,7 @@
   bool is_field_access_watched() const    { return access_flags().is_field_access_watched(); }
   bool is_field_modification_watched() const
                                           { return access_flags().is_field_modification_watched(); }
+  bool has_generic_signature() const      { return access_flags().field_has_generic_signature(); }
 
   void set_is_field_access_watched(const bool value) {
     _access_flags.set_is_field_access_watched(value);
@@ -115,6 +116,7 @@
   void initialize(klassOop k, int index);
 
   // Print
+  void print() { print_on(tty); }
   void print_on(outputStream* st) const         PRODUCT_RETURN;
   void print_on_for(outputStream* st, oop obj)  PRODUCT_RETURN;
 };
diff --git a/hotspot/src/share/vm/runtime/fprofiler.cpp b/hotspot/src/share/vm/runtime/fprofiler.cpp
index 3c100aa..2f045c2 100644
--- a/hotspot/src/share/vm/runtime/fprofiler.cpp
+++ b/hotspot/src/share/vm/runtime/fprofiler.cpp
@@ -70,12 +70,12 @@
 ThreadProfiler::ThreadProfiler() {
   // Space for the ProfilerNodes
   const int area_size = 1 * ProfilerNodeSize * 1024;
-  area_bottom = AllocateHeap(area_size, "fprofiler");
+  area_bottom = AllocateHeap(area_size, mtInternal);
   area_top    = area_bottom;
   area_limit  = area_bottom + area_size;
 
   // ProfilerNode pointer table
-  table = NEW_C_HEAP_ARRAY(ProfilerNode*, table_size);
+  table = NEW_C_HEAP_ARRAY(ProfilerNode*, table_size, mtInternal);
   initialize();
   engaged = false;
 }
@@ -157,7 +157,7 @@
 void PCRecorder::init() {
   MutexLockerEx lm(CodeCache_lock, Mutex::_no_safepoint_check_flag);
   int s = size();
-  counters = NEW_C_HEAP_ARRAY(int, s);
+  counters = NEW_C_HEAP_ARRAY(int, s, mtInternal);
   for (int index = 0; index < s; index++) {
     counters[index] = 0;
   }
@@ -337,11 +337,13 @@
       char c = (char) n->byte_at(i);
       st->print("%c", c);
     }
-    if( Verbose ) {
+    if (Verbose || WizardMode) {
       // Disambiguate overloaded methods
       Symbol* sig = m->signature();
       sig->print_symbol_on(st);
-    }
+    } else if (MethodHandles::is_signature_polymorphic(m->intrinsic_id()))
+      // compare with methodOopDesc::print_short_name
+      MethodHandles::print_as_basic_type_signature_on(st, m->signature(), true);
   }
 
   virtual void print(outputStream* st, int total_ticks) {
@@ -850,7 +852,7 @@
   if (Threads_lock->try_lock()) {
     {  // Threads_lock scope
       maxthreads = Threads::number_of_threads();
-      threadsList = NEW_C_HEAP_ARRAY(JavaThread *, maxthreads);
+      threadsList = NEW_C_HEAP_ARRAY(JavaThread *, maxthreads, mtInternal);
       suspendedthreadcount = 0;
       for (JavaThread* tp = Threads::first(); tp != NULL; tp = tp->next()) {
         if (tp->is_Compiler_thread()) {
@@ -1195,8 +1197,8 @@
 
 void FlatProfiler::allocate_table() {
   { // Bytecode table
-    bytecode_ticks      = NEW_C_HEAP_ARRAY(int, Bytecodes::number_of_codes);
-    bytecode_ticks_stub = NEW_C_HEAP_ARRAY(int, Bytecodes::number_of_codes);
+    bytecode_ticks      = NEW_C_HEAP_ARRAY(int, Bytecodes::number_of_codes, mtInternal);
+    bytecode_ticks_stub = NEW_C_HEAP_ARRAY(int, Bytecodes::number_of_codes, mtInternal);
     for(int index = 0; index < Bytecodes::number_of_codes; index++) {
       bytecode_ticks[index]      = 0;
       bytecode_ticks_stub[index] = 0;
@@ -1205,7 +1207,7 @@
 
   if (ProfilerRecordPC) PCRecorder::init();
 
-  interval_data         = NEW_C_HEAP_ARRAY(IntervalData, interval_print_size);
+  interval_data         = NEW_C_HEAP_ARRAY(IntervalData, interval_print_size, mtInternal);
   FlatProfiler::interval_reset();
 }
 
diff --git a/hotspot/src/share/vm/runtime/fprofiler.hpp b/hotspot/src/share/vm/runtime/fprofiler.hpp
index 2f8d615..25c2f2a 100644
--- a/hotspot/src/share/vm/runtime/fprofiler.hpp
+++ b/hotspot/src/share/vm/runtime/fprofiler.hpp
@@ -121,7 +121,7 @@
 };
 #endif // FPROF_KERNEL
 
-class ThreadProfiler: public CHeapObj {
+class ThreadProfiler: public CHeapObj<mtInternal> {
 public:
   ThreadProfiler()    KERNEL_RETURN;
   ~ThreadProfiler()   KERNEL_RETURN;
diff --git a/hotspot/src/share/vm/runtime/frame.cpp b/hotspot/src/share/vm/runtime/frame.cpp
index 7ae9aa8..5afdd86 100644
--- a/hotspot/src/share/vm/runtime/frame.cpp
+++ b/hotspot/src/share/vm/runtime/frame.cpp
@@ -170,11 +170,9 @@
 }
 
 // type testers
-bool frame::is_ricochet_frame() const {
-  RicochetBlob* rcb = SharedRuntime::ricochet_blob();
-  return (_cb == rcb && rcb != NULL && rcb->returns_to_bounce_addr(_pc));
+bool frame::is_ignored_frame() const {
+  return false;  // FIXME: some LambdaForm frames should be ignored
 }
-
 bool frame::is_deoptimized_frame() const {
   assert(_deopt_state != unknown, "not answerable");
   return _deopt_state == is_deoptimized;
@@ -348,17 +346,12 @@
 frame frame::real_sender(RegisterMap* map) const {
   frame result = sender(map);
   while (result.is_runtime_frame() ||
-         result.is_ricochet_frame()) {
+         result.is_ignored_frame()) {
     result = result.sender(map);
   }
   return result;
 }
 
-frame frame::sender_for_ricochet_frame(RegisterMap* map) const {
-  assert(is_ricochet_frame(), "");
-  return MethodHandles::ricochet_frame_sender(*this, map);
-}
-
 // Note: called by profiler - NOT for current thread
 frame frame::profile_find_Java_sender_frame(JavaThread *thread) {
 // If we don't recognize this frame, walk back up the stack until we do
@@ -541,7 +534,6 @@
 const char* frame::print_name() const {
   if (is_native_frame())      return "Native";
   if (is_interpreted_frame()) return "Interpreted";
-  if (is_ricochet_frame())    return "Ricochet";
   if (is_compiled_frame()) {
     if (is_deoptimized_frame()) return "Deoptimized";
     return "Compiled";
@@ -728,8 +720,6 @@
       st->print("v  ~RuntimeStub::%s", ((RuntimeStub *)_cb)->name());
     } else if (_cb->is_deoptimization_stub()) {
       st->print("v  ~DeoptimizationBlob");
-    } else if (_cb->is_ricochet_stub()) {
-      st->print("v  ~RichochetBlob");
     } else if (_cb->is_exception_stub()) {
       st->print("v  ~ExceptionBlob");
     } else if (_cb->is_safepoint_stub()) {
@@ -993,9 +983,6 @@
 
 void frame::oops_code_blob_do(OopClosure* f, CodeBlobClosure* cf, const RegisterMap* reg_map) {
   assert(_cb != NULL, "sanity check");
-  if (_cb == SharedRuntime::ricochet_blob()) {
-    oops_ricochet_do(f, reg_map);
-  }
   if (_cb->oop_maps() != NULL) {
     OopMapSet::oops_do(this, reg_map, f);
 
@@ -1014,11 +1001,6 @@
     cf->do_code_blob(_cb);
 }
 
-void frame::oops_ricochet_do(OopClosure* f, const RegisterMap* map) {
-  assert(is_ricochet_frame(), "");
-  MethodHandles::ricochet_frame_oops_do(*this, f, map);
-}
-
 class CompiledArgumentOopFinder: public SignatureInfo {
  protected:
   OopClosure*     _f;
@@ -1087,7 +1069,7 @@
   // First consult the ADLC on where it puts parameter 0 for this signature.
   VMReg reg = SharedRuntime::name_for_receiver();
   oop r = *caller.oopmapreg_to_location(reg, reg_map);
-  assert( Universe::heap()->is_in_or_null(r), "bad receiver" );
+  assert(Universe::heap()->is_in_or_null(r), err_msg("bad receiver: " INTPTR_FORMAT " (" INTX_FORMAT ")", (intptr_t) r, (intptr_t) r));
   return r;
 }
 
@@ -1407,8 +1389,6 @@
     values.describe(-1, info_address,
                     FormatBuffer<1024>("#%d nmethod " INTPTR_FORMAT " for native method %s", frame_no,
                                        nm, nm->method()->name_and_sig_as_C_string()), 2);
-  } else if (is_ricochet_frame()) {
-      values.describe(-1, info_address, err_msg("#%d ricochet frame", frame_no), 2);
   } else {
     // provide default info if not handled before
     char *info = (char *) "special frame";
diff --git a/hotspot/src/share/vm/runtime/frame.hpp b/hotspot/src/share/vm/runtime/frame.hpp
index c55380e..9ebda0f 100644
--- a/hotspot/src/share/vm/runtime/frame.hpp
+++ b/hotspot/src/share/vm/runtime/frame.hpp
@@ -135,7 +135,7 @@
   bool is_interpreted_frame()    const;
   bool is_java_frame()           const;
   bool is_entry_frame()          const;             // Java frame called from C?
-  bool is_ricochet_frame()       const;
+  bool is_ignored_frame()        const;
   bool is_native_frame()         const;
   bool is_runtime_frame()        const;
   bool is_compiled_frame()       const;
@@ -176,7 +176,6 @@
   // Helper methods for better factored code in frame::sender
   frame sender_for_compiled_frame(RegisterMap* map) const;
   frame sender_for_entry_frame(RegisterMap* map) const;
-  frame sender_for_ricochet_frame(RegisterMap* map) const;
   frame sender_for_interpreter_frame(RegisterMap* map) const;
   frame sender_for_native_frame(RegisterMap* map) const;
 
@@ -415,7 +414,6 @@
   // Oops-do's
   void oops_compiled_arguments_do(Symbol* signature, bool has_receiver, const RegisterMap* reg_map, OopClosure* f);
   void oops_interpreted_do(OopClosure* f, const RegisterMap* map, bool query_oop_map_cache = true);
-  void oops_ricochet_do(OopClosure* f, const RegisterMap* map);
 
  private:
   void oops_interpreted_arguments_do(Symbol* signature, bool has_receiver, OopClosure* f);
diff --git a/hotspot/src/share/vm/runtime/globals.cpp b/hotspot/src/share/vm/runtime/globals.cpp
index 38088e3..569a3f4 100644
--- a/hotspot/src/share/vm/runtime/globals.cpp
+++ b/hotspot/src/share/vm/runtime/globals.cpp
@@ -43,7 +43,6 @@
 #include "shark/shark_globals.hpp"
 #endif
 
-
 RUNTIME_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PD_DEVELOPER_FLAG, \
               MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
               MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
@@ -55,6 +54,10 @@
                  MATERIALIZE_PRODUCT_FLAG, MATERIALIZE_PD_PRODUCT_FLAG, \
                  MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_NOTPRODUCT_FLAG)
 
+ARCH_FLAGS(MATERIALIZE_DEVELOPER_FLAG, MATERIALIZE_PRODUCT_FLAG, \
+           MATERIALIZE_DIAGNOSTIC_FLAG, MATERIALIZE_EXPERIMENTAL_FLAG, \
+           MATERIALIZE_NOTPRODUCT_FLAG)
+
 MATERIALIZE_FLAGS_EXT
 
 
@@ -81,7 +84,8 @@
   }
 }
 
-// Get custom message for this locked flag, if any.
+// Get custom message for this locked flag, or return NULL if
+// none is available.
 void Flag::get_locked_message(char* buf, int buflen) const {
   get_locked_message_ext(buf, buflen);
 }
@@ -147,6 +151,8 @@
     st->print("-XX:%s=" UINTX_FORMAT, name, get_uintx());
   } else if (is_uint64_t()) {
     st->print("-XX:%s=" UINT64_FORMAT, name, get_uint64_t());
+  } else if (is_double()) {
+    st->print("-XX:%s=%f", name, get_double());
   } else if (is_ccstr()) {
     st->print("-XX:%s=", name);
     const char* cp = get_ccstr();
@@ -209,7 +215,6 @@
   #define C1_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C1 notproduct}", DEFAULT },
 #endif
 
-
 #define C2_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 product}", DEFAULT },
 #define C2_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 pd product}", DEFAULT },
 #define C2_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{C2 diagnostic}", DEFAULT },
@@ -224,6 +229,17 @@
   #define C2_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{C2 notproduct}", DEFAULT },
 #endif
 
+#define ARCH_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH product}", DEFAULT },
+#define ARCH_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH diagnostic}", DEFAULT },
+#define ARCH_EXPERIMENTAL_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{ARCH experimental}", DEFAULT },
+#ifdef PRODUCT
+  #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) /* flag is constant */
+  #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc)
+#else
+  #define ARCH_DEVELOP_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH}", DEFAULT },
+  #define ARCH_NOTPRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, doc, "{ARCH notproduct}", DEFAULT },
+#endif
+
 #define SHARK_PRODUCT_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark product}", DEFAULT },
 #define SHARK_PD_PRODUCT_FLAG_STRUCT(type, name, doc)     { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark pd product}", DEFAULT },
 #define SHARK_DIAGNOSTIC_FLAG_STRUCT(type, name, value, doc) { #type, XSTR(name), &name, NOT_PRODUCT_ARG(doc) "{Shark diagnostic}", DEFAULT },
@@ -252,6 +268,7 @@
 #ifdef SHARK
  SHARK_FLAGS(SHARK_DEVELOP_FLAG_STRUCT, SHARK_PD_DEVELOP_FLAG_STRUCT, SHARK_PRODUCT_FLAG_STRUCT, SHARK_PD_PRODUCT_FLAG_STRUCT, SHARK_DIAGNOSTIC_FLAG_STRUCT, SHARK_NOTPRODUCT_FLAG_STRUCT)
 #endif
+ ARCH_FLAGS(ARCH_DEVELOP_FLAG_STRUCT, ARCH_PRODUCT_FLAG_STRUCT, ARCH_DIAGNOSTIC_FLAG_STRUCT, ARCH_EXPERIMENTAL_FLAG_STRUCT, ARCH_NOTPRODUCT_FLAG_STRUCT)
  FLAGTABLE_EXT
  {0, NULL, NULL}
 };
@@ -462,13 +479,13 @@
   ccstr old_value = result->get_ccstr();
   char* new_value = NULL;
   if (*value != NULL) {
-    new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1);
+    new_value = NEW_C_HEAP_ARRAY(char, strlen(*value)+1, mtInternal);
     strcpy(new_value, *value);
   }
   result->set_ccstr(new_value);
   if (result->origin == DEFAULT && old_value != NULL) {
     // Prior value is NOT heap allocated, but was a literal constant.
-    char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1);
+    char* old_value_to_free = NEW_C_HEAP_ARRAY(char, strlen(old_value)+1, mtInternal);
     strcpy(old_value_to_free, old_value);
     old_value = old_value_to_free;
   }
@@ -482,12 +499,12 @@
   Flag* faddr = address_of_flag(flag);
   guarantee(faddr != NULL && faddr->is_ccstr(), "wrong flag type");
   ccstr old_value = faddr->get_ccstr();
-  char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1);
+  char* new_value = NEW_C_HEAP_ARRAY(char, strlen(value)+1, mtInternal);
   strcpy(new_value, value);
   faddr->set_ccstr(new_value);
   if (faddr->origin != DEFAULT && old_value != NULL) {
     // Prior value is heap allocated so free it.
-    FREE_C_HEAP_ARRAY(char, old_value);
+    FREE_C_HEAP_ARRAY(char, old_value, mtInternal);
   }
   faddr->origin = origin;
 }
@@ -508,7 +525,7 @@
   while (flagTable[length].name != NULL) length++;
 
   // Sort
-  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length);
+  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
   for (int index = 0; index < length; index++) {
     array[index] = &flagTable[index];
   }
@@ -522,7 +539,7 @@
     }
   }
   out->cr();
-  FREE_C_HEAP_ARRAY(Flag*, array);
+  FREE_C_HEAP_ARRAY(Flag*, array, mtInternal);
 }
 
 #ifndef PRODUCT
@@ -544,7 +561,7 @@
   while (flagTable[length].name != NULL) length++;
 
   // Sort
-  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length);
+  Flag** array = NEW_C_HEAP_ARRAY(Flag*, length, mtInternal);
   for (int index = 0; index < length; index++) {
     array[index] = &flagTable[index];
   }
@@ -557,5 +574,5 @@
       array[i]->print_on(out, withComments);
     }
   }
-  FREE_C_HEAP_ARRAY(Flag*, array);
+  FREE_C_HEAP_ARRAY(Flag*, array, mtInternal);
 }
diff --git a/hotspot/src/share/vm/runtime/globals.hpp b/hotspot/src/share/vm/runtime/globals.hpp
index e41e2e3..8e26b21 100644
--- a/hotspot/src/share/vm/runtime/globals.hpp
+++ b/hotspot/src/share/vm/runtime/globals.hpp
@@ -190,7 +190,6 @@
 
 #endif // no compilers
 
-
 // string type aliases used only in this file
 typedef const char* ccstr;
 typedef const char* ccstrlist;   // represents string arguments which accumulate
@@ -531,11 +530,8 @@
   product(intx, UseSSE, 99,                                                 \
           "Highest supported SSE instructions set on x86/x64")              \
                                                                             \
-  product(intx, UseAVX, 99,                                                 \
-          "Highest supported AVX instructions set on x86/x64")              \
-                                                                            \
-  product(intx, UseVIS, 99,                                                 \
-          "Highest supported VIS instructions set on Sparc")                \
+  product(bool, UseAES, false,                                               \
+          "Control whether AES instructions can be used on x86/x64")        \
                                                                             \
   product(uintx, LargePageSizeInBytes, 0,                                   \
           "Large page size (0 to let VM choose the page size")              \
@@ -573,10 +569,6 @@
   product(bool, PrintVMQWaitTime, false,                                    \
           "Prints out the waiting time in VM operation queue")              \
                                                                             \
-  develop(bool, BailoutToInterpreterForThrows, false,                       \
-          "Compiled methods which throws/catches exceptions will be "       \
-          "deopt and intp.")                                                \
-                                                                            \
   develop(bool, NoYieldsInMicrolock, false,                                 \
           "Disable yields in microlock")                                    \
                                                                             \
@@ -619,9 +611,6 @@
           "inline Object::hashCode() native that is known to be part "      \
           "of base library DLL")                                            \
                                                                             \
-  develop(bool, InlineObjectCopy, true,                                     \
-          "inline Object.clone and Arrays.copyOf[Range] intrinsics")        \
-                                                                            \
   develop(bool, InlineNatives, true,                                        \
           "inline natives that are known to be part of base library DLL")   \
                                                                             \
@@ -631,37 +620,12 @@
   develop(bool, InlineClassNatives, true,                                   \
           "inline Class.isInstance, etc")                                   \
                                                                             \
-  develop(bool, InlineAtomicLong, true,                                     \
-          "inline sun.misc.AtomicLong")                                     \
-                                                                            \
   develop(bool, InlineThreadNatives, true,                                  \
           "inline Thread.currentThread, etc")                               \
                                                                             \
-  develop(bool, InlineReflectionGetCallerClass, true,                       \
-          "inline sun.reflect.Reflection.getCallerClass(), known to be part "\
-          "of base library DLL")                                            \
-                                                                            \
   develop(bool, InlineUnsafeOps, true,                                      \
           "inline memory ops (native methods) from sun.misc.Unsafe")        \
                                                                             \
-  develop(bool, ConvertCmpD2CmpF, true,                                     \
-          "Convert cmpD to cmpF when one input is constant in float range") \
-                                                                            \
-  develop(bool, ConvertFloat2IntClipping, true,                             \
-          "Convert float2int clipping idiom to integer clipping")           \
-                                                                            \
-  develop(bool, SpecialStringCompareTo, true,                               \
-          "special version of string compareTo")                            \
-                                                                            \
-  develop(bool, SpecialStringIndexOf, true,                                 \
-          "special version of string indexOf")                              \
-                                                                            \
-  develop(bool, SpecialStringEquals, true,                                  \
-          "special version of string equals")                               \
-                                                                            \
-  develop(bool, SpecialArraysEquals, true,                                  \
-          "special version of Arrays.equals(char[],char[])")                \
-                                                                            \
   product(bool, CriticalJNINatives, true,                                   \
           "check for critical JNI entry points")                            \
                                                                             \
@@ -671,8 +635,8 @@
   product(bool, UseSSE42Intrinsics, false,                                  \
           "SSE4.2 versions of intrinsics")                                  \
                                                                             \
-  product(bool, UseCondCardMark, false,                                     \
-          "Check for already marked card before updating card table")       \
+  product(bool, UseAESIntrinsics, false,                                    \
+          "use intrinsics for AES versions of crypto")                      \
                                                                             \
   develop(bool, TraceCallFixup, false,                                      \
           "traces all call fixups")                                         \
@@ -760,9 +724,6 @@
   develop(bool, ForceFloatExceptions, trueInDebug,                          \
           "Force exceptions on FP stack under/overflow")                    \
                                                                             \
-  develop(bool, SoftMatchFailure, trueInProduct,                            \
-          "If the DFA fails to match a node, print a message and bail out") \
-                                                                            \
   develop(bool, VerifyStackAtCalls, false,                                  \
           "Verify that the stack pointer is unchanged after calls")         \
                                                                             \
@@ -833,6 +794,9 @@
   product(bool, PrintGCApplicationStoppedTime, false,                       \
           "Print the time the application has been stopped")                \
                                                                             \
+  diagnostic(bool, VerboseVerification, false,                              \
+             "Display detailed verification details")                       \
+                                                                            \
   notproduct(uintx, ErrorHandlerTest, 0,                                    \
           "If > 0, provokes an error after VM initialization; the value"    \
           "determines which error to provoke.  See test_error_handler()"    \
@@ -899,6 +863,12 @@
   develop(bool, UseFakeTimers, false,                                       \
           "Tells whether the VM should use system time or a fake timer")    \
                                                                             \
+  product(ccstr, NativeMemoryTracking, "off",                               \
+          "Native memory tracking options")                                 \
+                                                                            \
+  diagnostic(bool, PrintNMTStatistics, false,                               \
+          "Print native memory tracking summary data if it is on")          \
+                                                                            \
   diagnostic(bool, LogCompilation, false,                                   \
           "Log compilation activity in detail to hotspot.log or LogFile")   \
                                                                             \
@@ -913,15 +883,6 @@
              "1: allow scavenging from the code cache; "                    \
              "2: emit as many constants as the compiler can see")           \
                                                                             \
-  diagnostic(bool, TraceOSRBreakpoint, false,                               \
-             "Trace OSR Breakpoint ")                                       \
-                                                                            \
-  diagnostic(bool, TraceCompileTriggered, false,                            \
-             "Trace compile triggered")                                     \
-                                                                            \
-  diagnostic(bool, TraceTriggers, false,                                    \
-             "Trace triggers")                                              \
-                                                                            \
   product(bool, AlwaysRestoreFPU, false,                                    \
           "Restore the FPU control word after every JNI call (expensive)")  \
                                                                             \
@@ -931,6 +892,9 @@
   diagnostic(bool, PrintAdapterHandlers, false,                             \
           "Print code generated for i2c/c2i adapters")                      \
                                                                             \
+  diagnostic(bool, VerifyAdapterCalls, trueInDebug,                         \
+          "Verify that i2c/c2i adapters are called properly")               \
+                                                                            \
   develop(bool, VerifyAdapterSharing, false,                                \
           "Verify that the code for shared adapters is the equivalent")     \
                                                                             \
@@ -1032,9 +996,6 @@
   develop(bool, UsePrivilegedStack, true,                                   \
           "Enable the security JVM functions")                              \
                                                                             \
-  develop(bool, IEEEPrecision, true,                                        \
-          "Enables IEEE precision (for INTEL only)")                        \
-                                                                            \
   develop(bool, ProtectionDomainVerification, true,                         \
           "Verifies protection domain before resolution in system "         \
           "dictionary")                                                     \
@@ -1042,9 +1003,6 @@
   product(bool, ClassUnloading, true,                                       \
           "Do unloading of classes")                                        \
                                                                             \
-  diagnostic(bool, LinkWellKnownClasses, false,                             \
-          "Resolve a well known class as soon as its name is seen")         \
-                                                                            \
   develop(bool, DisableStartThread, false,                                  \
           "Disable starting of additional Java threads "                    \
           "(for debugging only)")                                           \
@@ -1104,8 +1062,6 @@
           "(Unsafe,Unstable) "                                              \
           " Controls emission of inline sync fast-path code")               \
                                                                             \
-  product(intx, AlwaysInflate, 0, "(Unstable) Force inflation")             \
-                                                                            \
   product(intx, MonitorBound, 0, "Bound Monitor population")                \
                                                                             \
   product(bool, MonitorInUseLists, false, "Track Monitors for Deflation")   \
@@ -1113,9 +1069,6 @@
   product(intx, Atomics, 0,                                                 \
           "(Unsafe,Unstable) Diagnostic - Controls emission of atomics")    \
                                                                             \
-  product(intx, FenceInstruction, 0,                                        \
-          "(Unsafe,Unstable) Experimental")                                 \
-                                                                            \
   product(intx, SyncFlags, 0, "(Unsafe,Unstable) Experimental Sync flags" ) \
                                                                             \
   product(intx, SyncVerbose, 0, "(Unstable)" )                              \
@@ -1145,10 +1098,6 @@
           "call thr_setconcurrency at thread create time to avoid "         \
           "LWP starvation on MP systems (For Solaris Only)")                \
                                                                             \
-  develop(bool, UpdateHotSpotCompilerFileOnError, true,                     \
-          "Should the system attempt to update the compiler file when "     \
-          "an error occurs?")                                               \
-                                                                            \
   product(bool, ReduceSignalUsage, false,                                   \
           "Reduce the use of OS signals in Java and/or the VM")             \
                                                                             \
@@ -1183,15 +1132,6 @@
           "Use alternate signals instead of SIGUSR1 & SIGUSR2 for VM "      \
           "internal signals (Solaris only)")                                \
                                                                             \
-  product(bool, UseSpinning, false,                                         \
-          "Use spinning in monitor inflation and before entry")             \
-                                                                            \
-  product(bool, PreSpinYield, false,                                        \
-          "Yield before inner spinning loop")                               \
-                                                                            \
-  product(bool, PostSpinYield, true,                                        \
-          "Yield after inner spinning loop")                                \
-                                                                            \
   product(bool, AllowJNIEnvProxy, false,                                    \
           "Allow JNIEnv proxies for jdbx")                                  \
                                                                             \
@@ -1220,39 +1160,9 @@
   product(bool, LazyBootClassLoader, true,                                  \
           "Enable/disable lazy opening of boot class path entries")         \
                                                                             \
-  diagnostic(bool, UseIncDec, true,                                         \
-          "Use INC, DEC instructions on x86")                               \
-                                                                            \
-  product(bool, UseNewLongLShift, false,                                    \
-          "Use optimized bitwise shift left")                               \
-                                                                            \
-  product(bool, UseStoreImmI16, true,                                       \
-          "Use store immediate 16-bits value instruction on x86")           \
-                                                                            \
-  product(bool, UseAddressNop, false,                                       \
-          "Use '0F 1F [addr]' NOP instructions on x86 cpus")                \
-                                                                            \
-  product(bool, UseXmmLoadAndClearUpper, true,                              \
-          "Load low part of XMM register and clear upper part")             \
-                                                                            \
-  product(bool, UseXmmRegToRegMoveAll, false,                               \
-          "Copy all XMM register bits when moving value between registers") \
-                                                                            \
-  product(bool, UseXmmI2D, false,                                           \
-          "Use SSE2 CVTDQ2PD instruction to convert Integer to Double")     \
-                                                                            \
-  product(bool, UseXmmI2F, false,                                           \
-          "Use SSE2 CVTDQ2PS instruction to convert Integer to Float")      \
-                                                                            \
   product(bool, UseXMMForArrayCopy, false,                                  \
           "Use SSE2 MOVQ instruction for Arraycopy")                        \
                                                                             \
-  product(bool, UseUnalignedLoadStores, false,                              \
-          "Use SSE2 MOVDQU instruction for Arraycopy")                      \
-                                                                            \
-  product(bool, UseCBCond, false,                                           \
-          "Use compare and branch instruction on SPARC")                    \
-                                                                            \
   product(intx, FieldsAllocationStyle, 1,                                   \
           "0 - type based with oops first, 1 - with oops last, "            \
           "2 - oops in super and sub classes are together")                 \
@@ -1382,9 +1292,6 @@
   develop(bool, TraceStartupTime, false,                                    \
           "Trace setup time")                                               \
                                                                             \
-  product(ccstr, HPILibPath, NULL,                                          \
-          "Specify alternate path to HPI library")                          \
-                                                                            \
   develop(bool, TraceProtectionDomainVerification, false,                   \
           "Trace protection domain verifcation")                            \
                                                                             \
@@ -1400,10 +1307,6 @@
   product(bool, TraceMonitorInflation, false,                               \
           "Trace monitor inflation in JVM")                                 \
                                                                             \
-  /* assembler */                                                           \
-  product(bool, Use486InstrsOnly, false,                                    \
-          "Use 80486 Compliant instruction subset")                         \
-                                                                            \
   /* gc */                                                                  \
                                                                             \
   product(bool, UseSerialGC, false,                                         \
@@ -1462,9 +1365,6 @@
   develop(uintx, ParallelOldGCSplitInterval, 3,                             \
           "How often to provoke splitting a young gen space")               \
                                                                             \
-  develop(bool, TraceRegionTasksQueuing, false,                             \
-          "Trace the queuing of the region tasks")                          \
-                                                                            \
   product(uintx, ConcGCThreads, 0,                                          \
           "Number of threads concurrent gc will use")                       \
                                                                             \
@@ -1616,10 +1516,6 @@
           "The gain in the feedback loop for on-the-fly PLAB resizing"      \
           " during a scavenge")                                             \
                                                                             \
-  product(uintx, CMSOldPLABReactivityCeiling, 10,                           \
-          "The clamping of the gain in the feedback loop for on-the-fly"    \
-          " PLAB resizing during a scavenge")                               \
-                                                                            \
   product(bool, AlwaysPreTouch, false,                                      \
           "It forces all freshly committed pages to be pre-touched.")       \
                                                                             \
@@ -1627,12 +1523,6 @@
           "The maximum size of young gen chosen by default per GC worker "  \
           "thread available")                                               \
                                                                             \
-  product(bool, GCOverheadReporting, false,                                 \
-         "Enables the GC overhead reporting facility")                      \
-                                                                            \
-  product(intx, GCOverheadReportingPeriodMS, 100,                           \
-          "Reporting period for conc GC overhead reporting, in ms ")        \
-                                                                            \
   product(bool, CMSIncrementalMode, false,                                  \
           "Whether CMS GC should operate in \"incremental\" mode")          \
                                                                             \
@@ -2012,9 +1902,6 @@
   experimental(uintx, WorkStealingSpinToYieldRatio, 10,                     \
           "Ratio of hard spins to calls to yield")                          \
                                                                             \
-  product(uintx, PreserveMarkStackSize, 1024,                               \
-          "Size for stack used in promotion failure handling")              \
-                                                                            \
   develop(uintx, ObjArrayMarkingStride, 512,                                \
           "Number of ObjArray elements to push onto the marking stack"      \
           "before pushing a continuation entry")                            \
@@ -2039,18 +1926,6 @@
   product(bool, TLABStats, true,                                            \
           "Print various TLAB related information")                         \
                                                                             \
-  product(bool, UseBlockZeroing, false,                                     \
-          "Use special cpu instructions for block zeroing")                 \
-                                                                            \
-  product(intx, BlockZeroingLowLimit, 2048,                                 \
-          "Minimum size in bytes when block zeroing will be used")          \
-                                                                            \
-  product(bool, UseBlockCopy, false,                                        \
-          "Use special cpu instructions for block copy")                    \
-                                                                            \
-  product(intx, BlockCopyLowLimit, 2048,                                    \
-          "Minimum size in bytes when block copy will be used")             \
-                                                                            \
   product(bool, PrintRevisitStats, false,                                   \
           "Print revisit (klass and MDO) stack related information")        \
                                                                             \
@@ -2243,9 +2118,6 @@
   product(intx, PrefetchFieldsAhead, -1,                                    \
           "How many fields ahead to prefetch in oop scan (<= 0 means off)") \
                                                                             \
-  develop(bool, UsePrefetchQueue, true,                                     \
-          "Use the prefetch queue during PS promotion")                     \
-                                                                            \
   diagnostic(bool, VerifyBeforeExit, trueInDebug,                           \
           "Verify system before exiting")                                   \
                                                                             \
@@ -2462,7 +2334,7 @@
   develop(bool, CITimeEach, false,                                          \
           "display timing information after each successful compilation")   \
                                                                             \
-  develop(bool, CICountOSR, true,                                           \
+  develop(bool, CICountOSR, false,                                          \
           "use a separate counter when assigning ids to osr compilations")  \
                                                                             \
   develop(bool, CICompileNatives, true,                                     \
@@ -2481,27 +2353,9 @@
   develop(bool, CITraceTypeFlow, false,                                     \
           "detailed per-bytecode tracing of ciTypeFlow analysis")           \
                                                                             \
-  develop(intx, CICloneLoopTestLimit, 100,                                  \
-          "size limit for blocks heuristically cloned in ciTypeFlow")       \
-                                                                            \
   develop(intx, OSROnlyBCI, -1,                                             \
           "OSR only at this bci.  Negative values mean exclude that bci")   \
                                                                             \
-  /* temp diagnostics */                                                    \
-                                                                            \
-  diagnostic(bool, TraceRedundantCompiles, false,                           \
-          "Have compile broker print when a request already in the queue is"\
-          " requested again")                                               \
-                                                                            \
-  diagnostic(bool, InitialCompileFast, false,                               \
-          "Initial compile at CompLevel_fast_compile")                      \
-                                                                            \
-  diagnostic(bool, InitialCompileReallyFast, false,                         \
-          "Initial compile at CompLevel_really_fast_compile (no profile)")  \
-                                                                            \
-  diagnostic(bool, FullProfileOnReInterpret, true,                          \
-          "On re-interpret unc-trap compile next at CompLevel_fast_compile")\
-                                                                            \
   /* compiler */                                                            \
                                                                             \
   product(intx, CICompilerCount, CI_COMPILER_COUNT,                         \
@@ -2515,12 +2369,6 @@
           "proper StackOverflow handling; disable only to measure cost "    \
           "of stackbanging)")                                               \
                                                                             \
-  develop(bool, Use24BitFPMode, true,                                       \
-          "Set 24-bit FPU mode on a per-compile basis ")                    \
-                                                                            \
-  develop(bool, Use24BitFP, true,                                           \
-          "use FP instructions that produce 24-bit precise results")        \
-                                                                            \
   develop(bool, UseStrictFP, true,                                          \
           "use strict fp if modifier strictfp is set")                      \
                                                                             \
@@ -2552,9 +2400,6 @@
           "print the break down of clean up tasks performed during"         \
           " safepoint")                                                     \
                                                                             \
-  develop(bool, InlineAccessors, true,                                      \
-          "inline accessor methods (get/set)")                              \
-                                                                            \
   product(bool, Inline, true,                                               \
           "enable inlining")                                                \
                                                                             \
@@ -2567,33 +2412,15 @@
   product(bool, UseTypeProfile, true,                                       \
           "Check interpreter profile for historically monomorphic calls")   \
                                                                             \
-  product(intx, TypeProfileMajorReceiverPercent, 90,                        \
-          "% of major receiver type to all profiled receivers")             \
-                                                                            \
   notproduct(bool, TimeCompiler, false,                                     \
           "time the compiler")                                              \
                                                                             \
-  notproduct(bool, TimeCompiler2, false,                                    \
-          "detailed time the compiler (requires +TimeCompiler)")            \
-                                                                            \
   diagnostic(bool, PrintInlining, false,                                    \
           "prints inlining optimizations")                                  \
                                                                             \
-  diagnostic(bool, PrintIntrinsics, false,                                  \
-          "prints attempted and successful inlining of intrinsics")         \
-                                                                            \
-  product(bool, UseCountLeadingZerosInstruction, false,                     \
-          "Use count leading zeros instruction")                            \
-                                                                            \
   product(bool, UsePopCountInstruction, false,                              \
           "Use population count instruction")                               \
                                                                             \
-  diagnostic(ccstrlist, DisableIntrinsic, "",                               \
-          "do not expand intrinsics whose (internal) names appear here")    \
-                                                                            \
-  develop(bool, StressReflectiveCode, false,                                \
-          "Use inexact types at allocations, etc., to test reflection")     \
-                                                                            \
   develop(bool, EagerInitialization, false,                                 \
           "Eagerly initialize classes if possible")                         \
                                                                             \
@@ -2603,10 +2430,6 @@
   develop(bool, PrintMethodFlushing, false,                                 \
           "print the nmethods being flushed")                               \
                                                                             \
-  notproduct(bool, LogMultipleMutexLocking, false,                          \
-          "log locking and unlocking of mutexes (only if multiple locks "   \
-          "are held)")                                                      \
-                                                                            \
   develop(bool, UseRelocIndex, false,                                       \
          "use an index to speed random access to relocations")              \
                                                                             \
@@ -2616,9 +2439,6 @@
   diagnostic(bool, DebugNonSafepoints, trueInDebug,                         \
          "Generate extra debugging info for non-safepoints in nmethods")    \
                                                                             \
-  diagnostic(bool, DebugInlinedCalls, true,                                 \
-         "If false, restricts profiled locations to the root method only")  \
-                                                                            \
   product(bool, PrintVMOptions, false,                                      \
          "Print flags that appeared on the command line")                   \
                                                                             \
@@ -2695,9 +2515,6 @@
   notproduct(bool, IgnoreLockingAssertions, false,                          \
           "disable locking assertions (for speed)")                         \
                                                                             \
-  notproduct(bool, VerifyLoopOptimizations, false,                          \
-          "verify major loop optimizations")                                \
-                                                                            \
   product(bool, RangeCheckElimination, true,                                \
           "Split loop iterations to eliminate range checks")                \
                                                                             \
@@ -2707,12 +2524,6 @@
   develop(bool, TypeProfileCasts,  true,                                    \
           "treat casts like calls for purposes of type profiling")          \
                                                                             \
-  develop(bool, MonomorphicArrayCheck, true,                                \
-          "Uncommon-trap array store checks that require full type check")  \
-                                                                            \
-  diagnostic(bool, ProfileDynamicTypes, true,                               \
-          "do extra type profiling and use it more aggressively")           \
-                                                                            \
   develop(bool, DelayCompilationDuringStartup, true,                        \
           "Delay invoking the compiler until main application class is "    \
           "loaded")                                                         \
@@ -2727,19 +2538,9 @@
   notproduct(intx, CompileTheWorldSafepointInterval, 100,                   \
           "Force a safepoint every n compiles so sweeper can keep up")      \
                                                                             \
-  develop(bool, TraceIterativeGVN, false,                                   \
-          "Print progress during Iterative Global Value Numbering")         \
-                                                                            \
   develop(bool, FillDelaySlots, true,                                       \
           "Fill delay slots (on SPARC only)")                               \
                                                                             \
-  develop(bool, VerifyIterativeGVN, false,                                  \
-          "Verify Def-Use modifications during sparse Iterative Global "    \
-          "Value Numbering")                                                \
-                                                                            \
-  notproduct(bool, TracePhaseCCP, false,                                    \
-          "Print progress during Conditional Constant Propagation")         \
-                                                                            \
   develop(bool, TimeLivenessAnalysis, false,                                \
           "Time computation of bytecode liveness analysis")                 \
                                                                             \
@@ -2752,22 +2553,9 @@
   notproduct(bool, CollectIndexSetStatistics, false,                        \
           "Collect information about IndexSets")                            \
                                                                             \
-  develop(bool, PrintDominators, false,                                     \
-          "Print out dominator trees for GVN")                              \
-                                                                            \
   develop(bool, UseLoopSafepoints, true,                                    \
           "Generate Safepoint nodes in every loop")                         \
                                                                             \
-  notproduct(bool, TraceCISCSpill, false,                                   \
-          "Trace allocators use of cisc spillable instructions")            \
-                                                                            \
-  notproduct(bool, TraceSpilling, false,                                    \
-          "Trace spilling")                                                 \
-                                                                            \
-  product(bool, SplitIfBlocks, true,                                        \
-          "Clone compares and control flow through merge points to fold "   \
-          "some branches")                                                  \
-                                                                            \
   develop(intx, FastAllocateSizeLimit, 128*K,                               \
           /* Note:  This value is zero mod 1<<13 for a cheap sparc set. */  \
           "Inline allocations larger than this in doublewords must go slow")\
@@ -2824,15 +2612,6 @@
   develop(bool, UseFastSignatureHandlers, true,                             \
           "Use fast signature handlers for native calls")                   \
                                                                             \
-  develop(bool, UseV8InstrsOnly, false,                                     \
-          "Use SPARC-V8 Compliant instruction subset")                      \
-                                                                            \
-  product(bool, UseNiagaraInstrs, false,                                    \
-          "Use Niagara-efficient instruction subset")                       \
-                                                                            \
-  develop(bool, UseCASForSwap, false,                                       \
-          "Do not use swap instructions, but only CAS (in a loop) on SPARC")\
-                                                                            \
   product(bool, UseLoopCounter, true,                                       \
           "Increment invocation counter on backward branch")                \
                                                                             \
@@ -2849,9 +2628,6 @@
   notproduct(bool, TraceOnStackReplacement, false,                          \
           "Trace on stack replacement")                                     \
                                                                             \
-  develop(bool, PoisonOSREntry, true,                                       \
-           "Detect abnormal calls to OSR code")                             \
-                                                                            \
   product_pd(bool, PreferInterpreterNativeStubs,                            \
           "Use always interpreter stubs for native methods invoked via "    \
           "interpreter")                                                    \
@@ -2894,9 +2670,6 @@
   develop(bool, TraceFrequencyInlining, false,                              \
           "Trace frequency based inlining")                                 \
                                                                             \
-  notproduct(bool, TraceTypeProfile, false,                                 \
-          "Trace type profile")                                             \
-                                                                            \
   develop_pd(bool, InlineIntrinsics,                                        \
            "Inline intrinsics that can be statically resolved")             \
                                                                             \
@@ -2984,15 +2757,6 @@
   product(intx,  AllocatePrefetchInstr, 0,                                  \
           "Prefetch instruction to prefetch ahead of allocation pointer")   \
                                                                             \
-  product(intx,  ReadPrefetchInstr, 0,                                      \
-          "Prefetch instruction to prefetch ahead")                         \
-                                                                            \
-  product(uintx,  ArraycopySrcPrefetchDistance, 0,                          \
-          "Distance to prefetch source array in arracopy")                  \
-                                                                            \
-  product(uintx,  ArraycopyDstPrefetchDistance, 0,                          \
-          "Distance to prefetch destination array in arracopy")             \
-                                                                            \
   /* deoptimization */                                                      \
   develop(bool, TraceDeoptimization, false,                                 \
           "Trace deoptimization")                                           \
@@ -3083,9 +2847,6 @@
   product(intx, MinInliningThreshold, 250,                                  \
           "min. invocation count a method needs to have to be inlined")     \
                                                                             \
-  develop(intx, AlignEntryCode, 4,                                          \
-          "aligns entry code to specified value (in bytes)")                \
-                                                                            \
   develop(intx, MethodHistogramCutoff, 100,                                 \
           "cutoff value for method invoc. histogram (+CountCalls)")         \
                                                                             \
@@ -3125,9 +2886,6 @@
           "Minimum sleep() interval (milliseconds) when "                   \
           "ConvertSleepToYield is off (used for SOLARIS)")                  \
                                                                             \
-  product(intx, EventLogLength,  2000,                                      \
-          "maximum nof events in event log")                                \
-                                                                            \
   develop(intx, ProfilerPCTickThreshold,    15,                             \
           "Number of ticks in a PC buckets to be a hotspot")                \
                                                                             \
@@ -3166,9 +2924,6 @@
   product(intx, PerBytecodeTrapLimit,  4,                                   \
           "Limit on traps (of one kind) at a particular BCI")               \
                                                                             \
-  develop(intx, FreqCountInvocations,  1,                                   \
-          "Scaling factor for branch frequencies (deprecated)")             \
-                                                                            \
   develop(intx, InlineFrequencyRatio,    20,                                \
           "Ratio of call site execution to caller method invocation")       \
                                                                             \
@@ -3182,29 +2937,12 @@
   develop(intx, InlineThrowMaxSize,   200,                                  \
           "Force inlining of throwing methods smaller than this")           \
                                                                             \
-  product(intx, AliasLevel,     3,                                          \
-          "0 for no aliasing, 1 for oop/field/static/array split, "         \
-          "2 for class split, 3 for unique instances")                      \
-                                                                            \
-  develop(bool, VerifyAliases, false,                                       \
-          "perform extra checks on the results of alias analysis")          \
-                                                                            \
   develop(intx, ProfilerNodeSize,  1024,                                    \
           "Size in K to allocate for the Profile Nodes of each thread")     \
                                                                             \
-  develop(intx, V8AtomicOperationUnderLockSpinCount,    50,                 \
-          "Number of times to spin wait on a v8 atomic operation lock")     \
-                                                                            \
-  product(intx, ReadSpinIterations,   100,                                  \
-          "Number of read attempts before a yield (spin inner loop)")       \
-                                                                            \
   product_pd(intx, PreInflateSpin,                                          \
           "Number of times to spin wait before inflation")                  \
                                                                             \
-  product(intx, PreBlockSpin,    10,                                        \
-          "Number of times to spin in an inflated lock before going to "    \
-          "an OS lock")                                                     \
-                                                                            \
   /* gc parameters */                                                       \
   product(uintx, InitialHeapSize, 0,                                        \
           "Initial heap size (in bytes); zero means OldSize + NewSize")     \
@@ -3288,9 +3026,6 @@
   diagnostic(intx, VerifyGCLevel,     0,                                    \
           "Generation level at which to start +VerifyBefore/AfterGC")       \
                                                                             \
-  develop(uintx, ExitAfterGCNum,   0,                                       \
-          "If non-zero, exit after this GC.")                               \
-                                                                            \
   product(intx, MaxTenuringThreshold,    15,                                \
           "Maximum value for tenuring threshold")                           \
                                                                             \
@@ -3464,10 +3199,6 @@
           "(non-negative value throws OOM after this many CI accesses "     \
           "in each compile)")                                               \
                                                                             \
-  develop(intx, CIFireOOMAtDelay, -1,                                       \
-          "Wait for this many CI accesses to occur in all compiles before " \
-          "beginning to throw OutOfMemoryErrors in each compile")           \
-                                                                            \
   notproduct(bool, CIObjectFactoryVerify, false,                            \
           "enable potentially expensive verification in ciObjectFactory")   \
                                                                             \
@@ -3661,9 +3392,6 @@
   product(bool, PrintTieredEvents, false,                                   \
           "Print tiered events notifications")                              \
                                                                             \
-  product(bool, StressTieredRuntime, false,                                 \
-          "Alternate client and server compiler on compile requests")       \
-                                                                            \
   product_pd(intx, OnStackReplacePercentage,                                \
           "NON_TIERED number of method invocations/branches (expressed as %"\
           "of CompileThreshold) before (re-)compiling OSR code")            \
@@ -3709,7 +3437,7 @@
                                                                             \
   /* Properties for Java libraries  */                                      \
                                                                             \
-  product(intx, MaxDirectMemorySize, -1,                                    \
+  product(uintx, MaxDirectMemorySize, 0,                                    \
           "Maximum total size of NIO direct-buffer allocations")            \
                                                                             \
   /* temporary developer defined flags  */                                  \
@@ -3810,7 +3538,7 @@
   product(uintx, SharedReadOnlySize,   10*M,                                \
           "Size of read-only space in permanent generation (in bytes)")     \
                                                                             \
-  product(uintx, SharedMiscDataSize,    NOT_LP64(4*M) LP64_ONLY(5*M),       \
+  product(uintx, SharedMiscDataSize, NOT_LP64(4*M) LP64_ONLY(5*M) NOT_PRODUCT(+1*M),       \
           "Size of the shared data area adjacent to the heap (in bytes)")   \
                                                                             \
   product(uintx, SharedMiscCodeSize,    4*M,                                \
@@ -3833,15 +3561,6 @@
           "support JSR 292 (method handles, invokedynamic, "                \
           "anonymous classes")                                              \
                                                                             \
-  product(bool, AnonymousClasses, false,                                    \
-          "support sun.misc.Unsafe.defineAnonymousClass (deprecated)")      \
-                                                                            \
-  experimental(bool, EnableMethodHandles, false,                            \
-          "support method handles (deprecated)")                            \
-                                                                            \
-  diagnostic(intx, MethodHandlePushLimit, 3,                                \
-          "number of additional stack slots a method handle may push")      \
-                                                                            \
   diagnostic(bool, PrintMethodHandleStubs, false,                           \
           "Print generated stub code for method handles")                   \
                                                                             \
@@ -3851,19 +3570,12 @@
   diagnostic(bool, VerifyMethodHandles, trueInDebug,                        \
           "perform extra checks when constructing method handles")          \
                                                                             \
-  diagnostic(bool, OptimizeMethodHandles, true,                             \
-          "when constructing method handles, try to improve them")          \
-                                                                            \
-  develop(bool, StressMethodHandleWalk, false,                              \
-          "Process all method handles with MethodHandleWalk")               \
+  diagnostic(bool, ShowHiddenFrames, false,                                 \
+          "show method handle implementation frames (usually hidden)")      \
                                                                             \
   experimental(bool, TrustFinalNonStaticFields, false,                      \
           "trust final non-static declarations for constant folding")       \
                                                                             \
-  experimental(bool, AllowInvokeGeneric, false,                             \
-          "accept MethodHandle.invoke and MethodHandle.invokeGeneric "      \
-          "as equivalent methods")                                          \
-                                                                            \
   develop(bool, TraceInvokeDynamic, false,                                  \
           "trace internal invoke dynamic operations")                       \
                                                                             \
@@ -3902,7 +3614,13 @@
   product(bool, UseVMInterruptibleIO, false,                                \
           "(Unstable, Solaris-specific) Thread interrupt before or with "   \
           "EINTR for I/O operations results in OS_INTRPT. The default value"\
-          " of this flag is true for JDK 6 and earlier")
+          " of this flag is true for JDK 6 and earlier")                    \
+                                                                            \
+  diagnostic(bool, WhiteBoxAPI, false,                                      \
+          "Enable internal testing APIs")                                   \
+                                                                            \
+  product(bool, PrintGCCause, true,                                         \
+          "Include GC cause in GC logging")
 
 /*
  *  Macros for factoring of globals
@@ -3957,6 +3675,8 @@
 
 RUNTIME_OS_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PD_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_PD_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_NOTPRODUCT_FLAG)
 
+ARCH_FLAGS(DECLARE_DEVELOPER_FLAG, DECLARE_PRODUCT_FLAG, DECLARE_DIAGNOSTIC_FLAG, DECLARE_EXPERIMENTAL_FLAG, DECLARE_NOTPRODUCT_FLAG)
+
 // Extensions
 
 #include "runtime/globals_ext.hpp"
diff --git a/hotspot/src/share/vm/runtime/globals_extension.hpp b/hotspot/src/share/vm/runtime/globals_extension.hpp
index a87e781..064b489 100644
--- a/hotspot/src/share/vm/runtime/globals_extension.hpp
+++ b/hotspot/src/share/vm/runtime/globals_extension.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -66,7 +66,6 @@
   #define C1_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
 #endif
 
-
 #define C2_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
 #define C2_PD_PRODUCT_FLAG_MEMBER(type, name, doc)             FLAG_MEMBER(name),
 #define C2_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
@@ -81,6 +80,17 @@
   #define C2_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
 #endif
 
+#define ARCH_PRODUCT_FLAG_MEMBER(type, name, value, doc)         FLAG_MEMBER(name),
+#define ARCH_DIAGNOSTIC_FLAG_MEMBER(type, name, value, doc)      FLAG_MEMBER(name),
+#define ARCH_EXPERIMENTAL_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
+#ifdef PRODUCT
+  #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)       /* flag is constant */
+  #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)
+#else
+  #define ARCH_DEVELOP_FLAG_MEMBER(type, name, value, doc)       FLAG_MEMBER(name),
+  #define ARCH_NOTPRODUCT_FLAG_MEMBER(type, name, value, doc)    FLAG_MEMBER(name),
+#endif
+
 typedef enum {
  RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_EXPERIMENTAL_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER, RUNTIME_MANAGEABLE_FLAG_MEMBER, RUNTIME_PRODUCT_RW_FLAG_MEMBER, RUNTIME_LP64_PRODUCT_FLAG_MEMBER)
  RUNTIME_OS_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER, RUNTIME_PD_DEVELOP_FLAG_MEMBER, RUNTIME_PRODUCT_FLAG_MEMBER, RUNTIME_PD_PRODUCT_FLAG_MEMBER, RUNTIME_DIAGNOSTIC_FLAG_MEMBER, RUNTIME_NOTPRODUCT_FLAG_MEMBER)
@@ -93,6 +103,7 @@
 #ifdef COMPILER2
  C2_FLAGS(C2_DEVELOP_FLAG_MEMBER, C2_PD_DEVELOP_FLAG_MEMBER, C2_PRODUCT_FLAG_MEMBER, C2_PD_PRODUCT_FLAG_MEMBER, C2_DIAGNOSTIC_FLAG_MEMBER, C2_EXPERIMENTAL_FLAG_MEMBER, C2_NOTPRODUCT_FLAG_MEMBER)
 #endif
+ ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER, ARCH_PRODUCT_FLAG_MEMBER, ARCH_DIAGNOSTIC_FLAG_MEMBER, ARCH_EXPERIMENTAL_FLAG_MEMBER, ARCH_NOTPRODUCT_FLAG_MEMBER)
  COMMANDLINEFLAG_EXT
  NUM_CommandLineFlag
 } CommandLineFlag;
@@ -134,7 +145,6 @@
 #define RUNTIME_LP64_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    /* flag is constant */
 #endif // _LP64
 
-
 #define C2_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
 #define C2_PD_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, doc)             FLAG_MEMBER_WITH_TYPE(name,type),
 #define C2_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
@@ -149,6 +159,17 @@
   #define C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
 #endif
 
+#define ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)         FLAG_MEMBER_WITH_TYPE(name,type),
+#define ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
+#define ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)      FLAG_MEMBER_WITH_TYPE(name,type),
+#ifdef PRODUCT
+  #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       /* flag is constant */
+  #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)
+#else
+  #define ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)       FLAG_MEMBER_WITH_TYPE(name,type),
+  #define ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE(type, name, value, doc)    FLAG_MEMBER_WITH_TYPE(name,type),
+#endif
+
 typedef enum {
  RUNTIME_FLAGS(RUNTIME_DEVELOP_FLAG_MEMBER_WITH_TYPE,
                RUNTIME_PD_DEVELOP_FLAG_MEMBER_WITH_TYPE,
@@ -193,6 +214,11 @@
           C2_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
           C2_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
 #endif
+ ARCH_FLAGS(ARCH_DEVELOP_FLAG_MEMBER_WITH_TYPE,
+          ARCH_PRODUCT_FLAG_MEMBER_WITH_TYPE,
+          ARCH_DIAGNOSTIC_FLAG_MEMBER_WITH_TYPE,
+          ARCH_EXPERIMENTAL_FLAG_MEMBER_WITH_TYPE,
+          ARCH_NOTPRODUCT_FLAG_MEMBER_WITH_TYPE)
  COMMANDLINEFLAGWITHTYPE_EXT
  NUM_CommandLineFlagWithType
 } CommandLineFlagWithType;
diff --git a/hotspot/src/share/vm/runtime/handles.cpp b/hotspot/src/share/vm/runtime/handles.cpp
index 3c24f81..661a533 100644
--- a/hotspot/src/share/vm/runtime/handles.cpp
+++ b/hotspot/src/share/vm/runtime/handles.cpp
@@ -111,7 +111,7 @@
   _chunk = _area->_chunk;
   _hwm   = _area->_hwm;
   _max   = _area->_max;
-  NOT_PRODUCT(_size_in_bytes = _area->_size_in_bytes;)
+  _size_in_bytes = _area->_size_in_bytes;
   debug_only(_area->_handle_mark_nesting++);
   assert(_area->_handle_mark_nesting > 0, "must stack allocate HandleMarks");
   debug_only(Atomic::inc(&_nof_handlemarks);)
@@ -153,13 +153,18 @@
 
   // Delete later chunks
   if( _chunk->next() ) {
+    // reset arena size before delete chunks. Otherwise, the total
+    // arena size could exceed total chunk size
+    assert(area->size_in_bytes() > size_in_bytes(), "Sanity check");
+    area->set_size_in_bytes(size_in_bytes());
     _chunk->next_chop();
+  } else {
+    assert(area->size_in_bytes() == size_in_bytes(), "Sanity check");
   }
   // Roll back arena to saved top markers
   area->_chunk = _chunk;
   area->_hwm = _hwm;
   area->_max = _max;
-  NOT_PRODUCT(area->set_size_in_bytes(_size_in_bytes);)
 #ifdef ASSERT
   // clear out first chunk (to detect allocation bugs)
   if (ZapVMHandleArea) {
diff --git a/hotspot/src/share/vm/runtime/handles.hpp b/hotspot/src/share/vm/runtime/handles.hpp
index d9d71e6..e68d300 100644
--- a/hotspot/src/share/vm/runtime/handles.hpp
+++ b/hotspot/src/share/vm/runtime/handles.hpp
@@ -238,7 +238,6 @@
 
 //------------------------------------------------------------------------------------------------------------------------
 // Thread local handle area
-
 class HandleArea: public Arena {
   friend class HandleMark;
   friend class NoHandleMark;
@@ -312,7 +311,7 @@
   HandleArea *_area;            // saved handle area
   Chunk *_chunk;                // saved arena chunk
   char *_hwm, *_max;            // saved arena info
-  NOT_PRODUCT(size_t _size_in_bytes;) // size of handle area
+  size_t _size_in_bytes;        // size of handle area
   // Link to previous active HandleMark in thread
   HandleMark* _previous_handle_mark;
 
@@ -320,6 +319,7 @@
   void set_previous_handle_mark(HandleMark* mark) { _previous_handle_mark = mark; }
   HandleMark* previous_handle_mark() const        { return _previous_handle_mark; }
 
+  size_t size_in_bytes() const { return _size_in_bytes; }
  public:
   HandleMark();                            // see handles_inline.hpp
   HandleMark(Thread* thread)                      { initialize(thread); }
diff --git a/hotspot/src/share/vm/runtime/handles.inline.hpp b/hotspot/src/share/vm/runtime/handles.inline.hpp
index 3bd42fb..da9bc54 100644
--- a/hotspot/src/share/vm/runtime/handles.inline.hpp
+++ b/hotspot/src/share/vm/runtime/handles.inline.hpp
@@ -79,13 +79,18 @@
   HandleArea* area = _area;   // help compilers with poor alias analysis
   // Delete later chunks
   if( _chunk->next() ) {
+    // reset arena size before delete chunks. Otherwise, the total
+    // arena size could exceed total chunk size
+    assert(area->size_in_bytes() > size_in_bytes(), "Sanity check");
+    area->set_size_in_bytes(size_in_bytes());
     _chunk->next_chop();
+  } else {
+    assert(area->size_in_bytes() == size_in_bytes(), "Sanity check");
   }
   // Roll back arena to saved top markers
   area->_chunk = _chunk;
   area->_hwm = _hwm;
   area->_max = _max;
-  NOT_PRODUCT(area->set_size_in_bytes(_size_in_bytes);)
   debug_only(area->_handle_mark_nesting--);
 }
 
diff --git a/hotspot/src/share/vm/runtime/interfaceSupport.hpp b/hotspot/src/share/vm/runtime/interfaceSupport.hpp
index e1001ee..2875ee0 100644
--- a/hotspot/src/share/vm/runtime/interfaceSupport.hpp
+++ b/hotspot/src/share/vm/runtime/interfaceSupport.hpp
@@ -436,6 +436,7 @@
 #define VM_LEAF_BASE(result_type, header)                            \
   TRACE_CALL(result_type, header)                                    \
   debug_only(NoHandleMark __hm;)                                     \
+  os::verify_stack_alignment();                                      \
   /* begin of body */
 
 
@@ -445,6 +446,7 @@
   TRACE_CALL(result_type, header)                                    \
   HandleMarkCleaner __hm(thread);                                    \
   Thread* THREAD = thread;                                           \
+  os::verify_stack_alignment();                                      \
   /* begin of body */
 
 
@@ -454,6 +456,7 @@
   TRACE_CALL(result_type, header)                                    \
   debug_only(NoHandleMark __hm;)                                     \
   Thread* THREAD = thread;                                           \
+  os::verify_stack_alignment();                                      \
   /* begin of body */
 
 
diff --git a/hotspot/src/share/vm/runtime/java.cpp b/hotspot/src/share/vm/runtime/java.cpp
index f256e51..c37f713 100644
--- a/hotspot/src/share/vm/runtime/java.cpp
+++ b/hotspot/src/share/vm/runtime/java.cpp
@@ -57,6 +57,8 @@
 #include "runtime/task.hpp"
 #include "runtime/timer.hpp"
 #include "runtime/vm_operations.hpp"
+#include "services/memReporter.hpp"
+#include "services/memTracker.hpp"
 #include "trace/tracing.hpp"
 #include "trace/traceEventTypes.hpp"
 #include "utilities/dtrace.hpp"
@@ -356,6 +358,15 @@
   }
 #endif // COMPILER2
 #endif // ENABLE_ZAP_DEAD_LOCALS
+  // Native memory tracking data
+  if (PrintNMTStatistics) {
+    if (MemTracker::is_on()) {
+      BaselineTTYOutputer outputer(tty);
+      MemTracker::print_memory_usage(outputer, K, false);
+    } else {
+      tty->print_cr(MemTracker::reason());
+    }
+  }
 }
 
 #else // PRODUCT MODE STATISTICS
@@ -373,6 +384,16 @@
   if (PrintBiasedLockingStatistics) {
     BiasedLocking::print_counters();
   }
+
+  // Native memory tracking data
+  if (PrintNMTStatistics) {
+    if (MemTracker::is_on()) {
+      BaselineTTYOutputer outputer(tty);
+      MemTracker::print_memory_usage(outputer, K, false);
+    } else {
+      tty->print_cr(MemTracker::reason());
+    }
+  }
 }
 
 #endif
@@ -384,7 +405,7 @@
     typedef void (*__exit_proc)(void);
 }
 
-class ExitProc : public CHeapObj {
+class ExitProc : public CHeapObj<mtInternal> {
  private:
   __exit_proc _proc;
   // void (*_proc)(void);
@@ -660,6 +681,8 @@
 }
 
 JDK_Version JDK_Version::_current;
+const char* JDK_Version::_runtime_name;
+const char* JDK_Version::_runtime_version;
 
 void JDK_Version::initialize() {
   jdk_version_info info;
diff --git a/hotspot/src/share/vm/runtime/java.hpp b/hotspot/src/share/vm/runtime/java.hpp
index 307fcc2..b9b33d0 100644
--- a/hotspot/src/share/vm/runtime/java.hpp
+++ b/hotspot/src/share/vm/runtime/java.hpp
@@ -74,6 +74,8 @@
  private:
 
   static JDK_Version _current;
+  static const char* _runtime_name;
+  static const char* _runtime_version;
 
   // In this class, we promote the minor version of release to be the
   // major version for releases >= 5 in anticipation of the JDK doing the
@@ -181,6 +183,20 @@
 
   void to_string(char* buffer, size_t buflen) const;
 
+  static const char* runtime_name() {
+    return _runtime_name;
+  }
+  static void set_runtime_name(const char* name) {
+    _runtime_name = name;
+  }
+
+  static const char* runtime_version() {
+    return _runtime_version;
+  }
+  static void set_runtime_version(const char* version) {
+    _runtime_version = version;
+  }
+
   // Convenience methods for queries on the current major/minor version
   static bool is_jdk12x_version() {
     return current().compare_major(2) == 0;
@@ -206,6 +222,10 @@
     return current().compare_major(7) == 0;
   }
 
+  static bool is_jdk18x_version() {
+    return current().compare_major(8) == 0;
+  }
+
   static bool is_gte_jdk13x_version() {
     return current().compare_major(3) >= 0;
   }
@@ -225,6 +245,10 @@
   static bool is_gte_jdk17x_version() {
     return current().compare_major(7) >= 0;
   }
+
+  static bool is_gte_jdk18x_version() {
+    return current().compare_major(8) >= 0;
+  }
 };
 
 #endif // SHARE_VM_RUNTIME_JAVA_HPP
diff --git a/hotspot/src/share/vm/runtime/jniHandles.hpp b/hotspot/src/share/vm/runtime/jniHandles.hpp
index a3b2f9c..71bb1dd 100644
--- a/hotspot/src/share/vm/runtime/jniHandles.hpp
+++ b/hotspot/src/share/vm/runtime/jniHandles.hpp
@@ -109,7 +109,7 @@
 
 // JNI handle blocks holding local/global JNI handles
 
-class JNIHandleBlock : public CHeapObj {
+class JNIHandleBlock : public CHeapObj<mtInternal> {
   friend class VMStructs;
   friend class CppInterpreter;
 
diff --git a/hotspot/src/share/vm/runtime/monitorChunk.cpp b/hotspot/src/share/vm/runtime/monitorChunk.cpp
index 1a4be79..f8793fd 100644
--- a/hotspot/src/share/vm/runtime/monitorChunk.cpp
+++ b/hotspot/src/share/vm/runtime/monitorChunk.cpp
@@ -29,7 +29,7 @@
 
 MonitorChunk::MonitorChunk(int number_on_monitors) {
   _number_of_monitors = number_on_monitors;
-  _monitors           = NEW_C_HEAP_ARRAY(BasicObjectLock, number_on_monitors);
+  _monitors           = NEW_C_HEAP_ARRAY(BasicObjectLock, number_on_monitors, mtInternal);
   _next               = NULL;
 }
 
diff --git a/hotspot/src/share/vm/runtime/monitorChunk.hpp b/hotspot/src/share/vm/runtime/monitorChunk.hpp
index 66d6243..eca92a6 100644
--- a/hotspot/src/share/vm/runtime/monitorChunk.hpp
+++ b/hotspot/src/share/vm/runtime/monitorChunk.hpp
@@ -30,7 +30,7 @@
 // Data structure for holding monitors for one activation during
 // deoptimization.
 
-class MonitorChunk: public CHeapObj {
+class MonitorChunk: public CHeapObj<mtInternal> {
  private:
   int              _number_of_monitors;
   BasicObjectLock* _monitors;
diff --git a/hotspot/src/share/vm/runtime/mutex.hpp b/hotspot/src/share/vm/runtime/mutex.hpp
index 66a3295..7d2cd82 100644
--- a/hotspot/src/share/vm/runtime/mutex.hpp
+++ b/hotspot/src/share/vm/runtime/mutex.hpp
@@ -84,7 +84,7 @@
 // The default length of monitor name is chosen to be 64 to avoid false sharing.
 static const int MONITOR_NAME_LEN = 64;
 
-class Monitor : public CHeapObj {
+class Monitor : public CHeapObj<mtInternal> {
 
  public:
   // A special lock: Is a lock where you are guaranteed not to block while you are
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.cpp b/hotspot/src/share/vm/runtime/mutexLocker.cpp
index f1911ea..a2c91ff 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.cpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.cpp
@@ -140,6 +140,7 @@
 Monitor* JfrMsg_lock                  = NULL;
 Mutex*   JfrBuffer_lock               = NULL;
 Mutex*   JfrStream_lock               = NULL;
+Monitor* PeriodicTask_lock            = NULL;
 
 #define MAX_NUM_MUTEX 128
 static Monitor * _mutex_array[MAX_NUM_MUTEX];
@@ -285,6 +286,7 @@
   def(JfrMsg_lock                  , Monitor, nonleaf+2,   true);
   def(JfrBuffer_lock               , Mutex,   nonleaf+3,   true);
   def(JfrStream_lock               , Mutex,   nonleaf+4,   true);
+  def(PeriodicTask_lock            , Monitor, nonleaf+5,   true);
 }
 
 GCMutexLocker::GCMutexLocker(Monitor * mutex) {
diff --git a/hotspot/src/share/vm/runtime/mutexLocker.hpp b/hotspot/src/share/vm/runtime/mutexLocker.hpp
index 846b2d4..7fae11b 100644
--- a/hotspot/src/share/vm/runtime/mutexLocker.hpp
+++ b/hotspot/src/share/vm/runtime/mutexLocker.hpp
@@ -142,6 +142,7 @@
 extern Monitor* JfrMsg_lock;                     // protects JFR messaging
 extern Mutex*   JfrBuffer_lock;                  // protects JFR buffer operations
 extern Mutex*   JfrStream_lock;                  // protects JFR stream access
+extern Monitor* PeriodicTask_lock;               // protects the periodic task structure
 
 // A MutexLocker provides mutual exclusion with respect to a given mutex
 // for the scope which contains the locker.  The lock is an OS lock, not
diff --git a/hotspot/src/share/vm/runtime/os.cpp b/hotspot/src/share/vm/runtime/os.cpp
index 33495d6..09f9b30 100644
--- a/hotspot/src/share/vm/runtime/os.cpp
+++ b/hotspot/src/share/vm/runtime/os.cpp
@@ -45,6 +45,7 @@
 #include "runtime/os.hpp"
 #include "runtime/stubRoutines.hpp"
 #include "services/attachListener.hpp"
+#include "services/memTracker.hpp"
 #include "services/threadService.hpp"
 #include "utilities/defaultStream.hpp"
 #include "utilities/events.hpp"
@@ -433,9 +434,9 @@
 
 // --------------------- heap allocation utilities ---------------------
 
-char *os::strdup(const char *str) {
+char *os::strdup(const char *str, MEMFLAGS flags) {
   size_t size = strlen(str);
-  char *dup_str = (char *)malloc(size + 1);
+  char *dup_str = (char *)malloc(size + 1, flags);
   if (dup_str == NULL) return NULL;
   strcpy(dup_str, str);
   return dup_str;
@@ -559,7 +560,7 @@
 }
 #endif
 
-void* os::malloc(size_t size) {
+void* os::malloc(size_t size, MEMFLAGS memflags, address caller) {
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
 
@@ -571,6 +572,7 @@
 
   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   u_char* ptr = (u_char*)::malloc(size + space_before + space_after);
+
 #ifdef ASSERT
   if (ptr == NULL) return NULL;
   if (MallocCushion) {
@@ -589,18 +591,27 @@
   }
   debug_only(if (paranoid) verify_block(memblock));
   if (PrintMalloc && tty != NULL) tty->print_cr("os::malloc " SIZE_FORMAT " bytes --> " PTR_FORMAT, size, memblock);
+
+  // we do not track MallocCushion memory
+    MemTracker::record_malloc((address)memblock, size, memflags, caller == 0 ? CALLER_PC : caller);
+
   return memblock;
 }
 
 
-void* os::realloc(void *memblock, size_t size) {
+void* os::realloc(void *memblock, size_t size, MEMFLAGS memflags, address caller) {
 #ifndef ASSERT
   NOT_PRODUCT(inc_stat_counter(&num_mallocs, 1));
   NOT_PRODUCT(inc_stat_counter(&alloc_bytes, size));
-  return ::realloc(memblock, size);
+  void* ptr = ::realloc(memblock, size);
+  if (ptr != NULL) {
+    MemTracker::record_realloc((address)memblock, (address)ptr, size, memflags,
+     caller == 0 ? CALLER_PC : caller);
+  }
+  return ptr;
 #else
   if (memblock == NULL) {
-    return malloc(size);
+    return malloc(size, memflags, (caller == 0 ? CALLER_PC : caller));
   }
   if ((intptr_t)memblock == (intptr_t)MallocCatchPtr) {
     tty->print_cr("os::realloc caught " PTR_FORMAT, memblock);
@@ -610,7 +621,7 @@
   NOT_PRODUCT(if (MallocVerifyInterval > 0) check_heap());
   if (size == 0) return NULL;
   // always move the block
-  void* ptr = malloc(size);
+  void* ptr = malloc(size, memflags, caller == 0 ? CALLER_PC : caller);
   if (PrintMalloc) tty->print_cr("os::remalloc " SIZE_FORMAT " bytes, " PTR_FORMAT " --> " PTR_FORMAT, size, memblock, ptr);
   // Copy to new memory if malloc didn't fail
   if ( ptr != NULL ) {
@@ -627,7 +638,7 @@
 }
 
 
-void  os::free(void *memblock) {
+void  os::free(void *memblock, MEMFLAGS memflags) {
   NOT_PRODUCT(inc_stat_counter(&num_frees, 1));
 #ifdef ASSERT
   if (memblock == NULL) return;
@@ -660,6 +671,8 @@
     fprintf(stderr, "os::free " PTR_FORMAT "\n", (uintptr_t)memblock);
   }
 #endif
+  MemTracker::record_free((address)memblock, memflags);
+
   ::free((char*)memblock - space_before);
 }
 
@@ -807,7 +820,7 @@
       // the interpreter is generated into a buffer blob
       InterpreterCodelet* i = Interpreter::codelet_containing(addr);
       if (i != NULL) {
-        st->print_cr(INTPTR_FORMAT " is an Interpreter codelet", addr);
+        st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an Interpreter codelet", addr, (int)(addr - i->code_begin()));
         i->print_on(st);
         return;
       }
@@ -818,14 +831,15 @@
       }
       //
       if (AdapterHandlerLibrary::contains(b)) {
-        st->print_cr(INTPTR_FORMAT " is an AdapterHandler", addr);
+        st->print_cr(INTPTR_FORMAT " is at code_begin+%d in an AdapterHandler", addr, (int)(addr - b->code_begin()));
         AdapterHandlerLibrary::print_handler_on(st, b);
       }
       // the stubroutines are generated into a buffer blob
       StubCodeDesc* d = StubCodeDesc::desc_for(addr);
       if (d != NULL) {
+        st->print_cr(INTPTR_FORMAT " is at begin+%d in a stub", addr, (int)(addr - d->begin()));
         d->print_on(st);
-        if (verbose) st->cr();
+        st->cr();
         return;
       }
       if (StubRoutines::contains(addr)) {
@@ -840,26 +854,25 @@
       }
       VtableStub* v = VtableStubs::stub_containing(addr);
       if (v != NULL) {
+        st->print_cr(INTPTR_FORMAT " is at entry_point+%d in a vtable stub", addr, (int)(addr - v->entry_point()));
         v->print_on(st);
+        st->cr();
         return;
       }
     }
-    if (verbose && b->is_nmethod()) {
+    nmethod* nm = b->as_nmethod_or_null();
+    if (nm != NULL) {
       ResourceMark rm;
-      st->print("%#p: Compiled ", addr);
-      ((nmethod*)b)->method()->print_value_on(st);
-      st->print("  = (CodeBlob*)" INTPTR_FORMAT, b);
-      st->cr();
+      st->print(INTPTR_FORMAT " is at entry_point+%d in (nmethod*)" INTPTR_FORMAT,
+                addr, (int)(addr - nm->entry_point()), nm);
+      if (verbose) {
+        st->print(" for ");
+        nm->method()->print_value_on(st);
+      }
+      nm->print_nmethod(verbose);
       return;
     }
-    st->print(INTPTR_FORMAT " ", b);
-    if ( b->is_nmethod()) {
-      if (b->is_zombie()) {
-        st->print_cr("is zombie nmethod");
-      } else if (b->is_not_entrant()) {
-        st->print_cr("is non-entrant nmethod");
-      }
-    }
+    st->print_cr(INTPTR_FORMAT " is at code_begin+%d in ", addr, (int)(addr - b->code_begin()));
     b->print_on(st);
     return;
   }
@@ -1048,7 +1061,7 @@
         ++formatted_path_len;
     }
 
-    char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1);
+    char* formatted_path = NEW_C_HEAP_ARRAY(char, formatted_path_len + 1, mtInternal);
     if (formatted_path == NULL) {
         return NULL;
     }
@@ -1127,7 +1140,7 @@
     return NULL;
   }
   const char psepchar = *os::path_separator();
-  char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1);
+  char* inpath = (char*)NEW_C_HEAP_ARRAY(char, strlen(path) + 1, mtInternal);
   if (inpath == NULL) {
     return NULL;
   }
@@ -1140,7 +1153,7 @@
     p++;
     p = strchr(p, psepchar);
   }
-  char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count);
+  char** opath = (char**) NEW_C_HEAP_ARRAY(char*, count, mtInternal);
   if (opath == NULL) {
     return NULL;
   }
@@ -1153,7 +1166,7 @@
       return NULL;
     }
     // allocate the string and add terminator storage
-    char* s  = (char*)NEW_C_HEAP_ARRAY(char, len + 1);
+    char* s  = (char*)NEW_C_HEAP_ARRAY(char, len + 1, mtInternal);
     if (s == NULL) {
       return NULL;
     }
@@ -1162,7 +1175,7 @@
     opath[i] = s;
     p += len + 1;
   }
-  FREE_C_HEAP_ARRAY(char, inpath);
+  FREE_C_HEAP_ARRAY(char, inpath, mtInternal);
   *n = count;
   return opath;
 }
@@ -1366,3 +1379,99 @@
 
   return (int) i;
 }
+
+bool os::create_stack_guard_pages(char* addr, size_t bytes) {
+  return os::pd_create_stack_guard_pages(addr, bytes);
+}
+
+
+char* os::reserve_memory(size_t bytes, char* addr, size_t alignment_hint) {
+  char* result = pd_reserve_memory(bytes, addr, alignment_hint);
+  if (result != NULL) {
+    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+  }
+
+  return result;
+}
+char* os::attempt_reserve_memory_at(size_t bytes, char* addr) {
+  char* result = pd_attempt_reserve_memory_at(bytes, addr);
+  if (result != NULL) {
+    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+  }
+  return result;
+}
+
+void os::split_reserved_memory(char *base, size_t size,
+                                 size_t split, bool realloc) {
+  pd_split_reserved_memory(base, size, split, realloc);
+}
+
+bool os::commit_memory(char* addr, size_t bytes, bool executable) {
+  bool res = pd_commit_memory(addr, bytes, executable);
+  if (res) {
+    MemTracker::record_virtual_memory_commit((address)addr, bytes, CALLER_PC);
+  }
+  return res;
+}
+
+bool os::commit_memory(char* addr, size_t size, size_t alignment_hint,
+                              bool executable) {
+  bool res = os::pd_commit_memory(addr, size, alignment_hint, executable);
+  if (res) {
+    MemTracker::record_virtual_memory_commit((address)addr, size, CALLER_PC);
+  }
+  return res;
+}
+
+bool os::uncommit_memory(char* addr, size_t bytes) {
+  bool res = pd_uncommit_memory(addr, bytes);
+  if (res) {
+    MemTracker::record_virtual_memory_uncommit((address)addr, bytes);
+  }
+  return res;
+}
+
+bool os::release_memory(char* addr, size_t bytes) {
+  bool res = pd_release_memory(addr, bytes);
+  if (res) {
+    MemTracker::record_virtual_memory_release((address)addr, bytes);
+  }
+  return res;
+}
+
+
+char* os::map_memory(int fd, const char* file_name, size_t file_offset,
+                           char *addr, size_t bytes, bool read_only,
+                           bool allow_exec) {
+  char* result = pd_map_memory(fd, file_name, file_offset, addr, bytes, read_only, allow_exec);
+  if (result != NULL) {
+    MemTracker::record_virtual_memory_reserve((address)result, bytes, CALLER_PC);
+    MemTracker::record_virtual_memory_commit((address)result, bytes, CALLER_PC);
+  }
+  return result;
+}
+
+char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
+                             char *addr, size_t bytes, bool read_only,
+                             bool allow_exec) {
+  return pd_remap_memory(fd, file_name, file_offset, addr, bytes,
+                    read_only, allow_exec);
+}
+
+bool os::unmap_memory(char *addr, size_t bytes) {
+  bool result = pd_unmap_memory(addr, bytes);
+  if (result) {
+    MemTracker::record_virtual_memory_uncommit((address)addr, bytes);
+    MemTracker::record_virtual_memory_release((address)addr, bytes);
+  }
+  return result;
+}
+
+void os::free_memory(char *addr, size_t bytes, size_t alignment_hint) {
+  pd_free_memory(addr, bytes, alignment_hint);
+}
+
+void os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
+  pd_realign_memory(addr, bytes, alignment_hint);
+}
+
diff --git a/hotspot/src/share/vm/runtime/os.hpp b/hotspot/src/share/vm/runtime/os.hpp
index a6ae80a..d4222a1 100644
--- a/hotspot/src/share/vm/runtime/os.hpp
+++ b/hotspot/src/share/vm/runtime/os.hpp
@@ -99,6 +99,28 @@
     _page_sizes[1] = 0; // sentinel
   }
 
+  static char*  pd_reserve_memory(size_t bytes, char* addr = 0,
+                               size_t alignment_hint = 0);
+  static char*  pd_attempt_reserve_memory_at(size_t bytes, char* addr);
+  static void   pd_split_reserved_memory(char *base, size_t size,
+                                      size_t split, bool realloc);
+  static bool   pd_commit_memory(char* addr, size_t bytes, bool executable = false);
+  static bool   pd_commit_memory(char* addr, size_t size, size_t alignment_hint,
+                              bool executable = false);
+  static bool   pd_uncommit_memory(char* addr, size_t bytes);
+  static bool   pd_release_memory(char* addr, size_t bytes);
+
+  static char*  pd_map_memory(int fd, const char* file_name, size_t file_offset,
+                           char *addr, size_t bytes, bool read_only = false,
+                           bool allow_exec = false);
+  static char*  pd_remap_memory(int fd, const char* file_name, size_t file_offset,
+                             char *addr, size_t bytes, bool read_only,
+                             bool allow_exec);
+  static bool   pd_unmap_memory(char *addr, size_t bytes);
+  static void   pd_free_memory(char *addr, size_t bytes, size_t alignment_hint);
+  static void   pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint);
+
+
  public:
   static void init(void);                      // Called before command line parsing
   static jint init_2(void);                    // Called after command line parsing
@@ -233,11 +255,11 @@
   static int    vm_allocation_granularity();
   static char*  reserve_memory(size_t bytes, char* addr = 0,
                                size_t alignment_hint = 0);
+  static char*  reserve_memory_aligned(size_t size, size_t alignment);
   static char*  attempt_reserve_memory_at(size_t bytes, char* addr);
   static void   split_reserved_memory(char *base, size_t size,
                                       size_t split, bool realloc);
-  static bool   commit_memory(char* addr, size_t bytes,
-                              bool executable = false);
+  static bool   commit_memory(char* addr, size_t bytes, bool executable = false);
   static bool   commit_memory(char* addr, size_t size, size_t alignment_hint,
                               bool executable = false);
   static bool   uncommit_memory(char* addr, size_t bytes);
@@ -250,6 +272,7 @@
   static bool   guard_memory(char* addr, size_t bytes);
   static bool   unguard_memory(char* addr, size_t bytes);
   static bool   create_stack_guard_pages(char* addr, size_t bytes);
+  static bool   pd_create_stack_guard_pages(char* addr, size_t bytes);
   static bool   remove_stack_guard_pages(char* addr, size_t bytes);
 
   static char*  map_memory(int fd, const char* file_name, size_t file_offset,
@@ -365,7 +388,7 @@
   static void pd_start_thread(Thread* thread);
   static void start_thread(Thread* thread);
 
-  static void initialize_thread();
+  static void initialize_thread(Thread* thr);
   static void free_thread(OSThread* osthread);
 
   // thread id on Linux/64bit is 64bit, on Windows and Solaris, it's 32bit
@@ -404,6 +427,8 @@
   static address current_stack_base();
   static size_t current_stack_size();
 
+  static void verify_stack_alignment() PRODUCT_RETURN;
+
   static int message_box(const char* title, const char* message);
   static char* do_you_want_to_debug(const char* message);
 
@@ -571,12 +596,15 @@
   static void* thread_local_storage_at(int index);
   static void  free_thread_local_storage(int index);
 
+  // Stack walk
+  static address get_caller_pc(int n = 0);
+
   // General allocation (must be MT-safe)
-  static void* malloc  (size_t size);
-  static void* realloc (void *memblock, size_t size);
-  static void  free    (void *memblock);
+  static void* malloc  (size_t size, MEMFLAGS flags, address caller_pc = 0);
+  static void* realloc (void *memblock, size_t size, MEMFLAGS flags, address caller_pc = 0);
+  static void  free    (void *memblock, MEMFLAGS flags = mtNone);
   static bool  check_heap(bool force = false);      // verify C heap integrity
-  static char* strdup(const char *);  // Like strdup
+  static char* strdup(const char *, MEMFLAGS flags = mtInternal);  // Like strdup
 
 #ifndef PRODUCT
   static julong num_mallocs;         // # of calls to malloc/realloc
@@ -638,6 +666,10 @@
   // On Windows this will create an actual minidump, on Linux/Solaris it will simply check core dump limits
   static void check_or_create_dump(void* exceptionRecord, void* contextRecord, char* buffer, size_t bufferSize);
 
+  // Get the default path to the core file
+  // Returns the length of the string
+  static int get_core_path(char* buffer, size_t bufferSize);
+
   // JVMTI & JVM monitoring and management support
   // The thread_cpu_time() and current_thread_cpu_time() are only
   // supported if is_thread_cpu_time_supported() returns true.
diff --git a/hotspot/src/share/vm/runtime/osThread.hpp b/hotspot/src/share/vm/runtime/osThread.hpp
index 984bc9b..1dfcb37 100644
--- a/hotspot/src/share/vm/runtime/osThread.hpp
+++ b/hotspot/src/share/vm/runtime/osThread.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -58,10 +58,9 @@
 // the main thread into its own Thread at will.
 
 
-class OSThread: public CHeapObj {
+class OSThread: public CHeapObj<mtThread> {
   friend class VMStructs;
  private:
-  //void* _start_proc;            // Thread start routine
   OSThreadStartFunc _start_proc;  // Thread start routine
   void* _start_parm;              // Thread start routine parameter
   volatile ThreadState _state;    // Thread state *hint*
@@ -77,10 +76,7 @@
   void set_state(ThreadState state)                { _state = state; }
   ThreadState get_state()                          { return _state; }
 
-  // Constructor
   OSThread(OSThreadStartFunc start_proc, void* start_parm);
-
-  // Destructor
   ~OSThread();
 
   // Accessors
@@ -113,6 +109,19 @@
 # include "osThread_bsd.hpp"
 #endif
 
+ public:
+  static ByteSize thread_id_offset()              { return byte_offset_of(OSThread, _thread_id); }
+  static size_t thread_id_size()                  { return sizeof(thread_id_t); }
+
+  thread_id_t thread_id() const                   { return _thread_id; }
+
+  void set_thread_id(thread_id_t id)              { _thread_id = id; }
+
+ private:
+  // _thread_id is kernel thread id (similar to LWP id on Solaris). Each
+  // thread has a unique thread_id (BsdThreads or NPTL). It can be used
+  // to access /proc.
+  thread_id_t _thread_id;
 };
 
 
diff --git a/hotspot/src/share/vm/runtime/park.cpp b/hotspot/src/share/vm/runtime/park.cpp
index 1be5733..8d91d0b 100644
--- a/hotspot/src/share/vm/runtime/park.cpp
+++ b/hotspot/src/share/vm/runtime/park.cpp
@@ -141,7 +141,7 @@
 // although Niagara's hash function should help.
 
 void * ParkEvent::operator new (size_t sz) {
-  return (void *) ((intptr_t (CHeapObj::operator new (sz + 256)) + 256) & -256) ;
+  return (void *) ((intptr_t (AllocateHeap(sz + 256, mtInternal, CALLER_PC)) + 256) & -256) ;
 }
 
 void ParkEvent::operator delete (void * a) {
diff --git a/hotspot/src/share/vm/runtime/perfData.cpp b/hotspot/src/share/vm/runtime/perfData.cpp
index 04631ec..3d4bf2d 100644
--- a/hotspot/src/share/vm/runtime/perfData.cpp
+++ b/hotspot/src/share/vm/runtime/perfData.cpp
@@ -81,7 +81,7 @@
 
   const char* prefix = PerfDataManager::ns_to_string(ns);
 
-  _name = NEW_C_HEAP_ARRAY(char, strlen(name) + strlen(prefix) + 2);
+  _name = NEW_C_HEAP_ARRAY(char, strlen(name) + strlen(prefix) + 2, mtInternal);
   assert(_name != NULL && strlen(name) != 0, "invalid name");
 
   if (ns == NULL_NS) {
@@ -111,10 +111,10 @@
 
 PerfData::~PerfData() {
   if (_name != NULL) {
-    FREE_C_HEAP_ARRAY(char, _name);
+    FREE_C_HEAP_ARRAY(char, _name, mtInternal);
   }
   if (is_on_c_heap()) {
-    FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep);
+    FREE_C_HEAP_ARRAY(PerfDataEntry, _pdep, mtInternal);
   }
 }
 
@@ -137,7 +137,7 @@
   if (psmp == NULL) {
     // out of PerfMemory memory resources. allocate on the C heap
     // to avoid vm termination.
-    psmp = NEW_C_HEAP_ARRAY(char, size);
+    psmp = NEW_C_HEAP_ARRAY(char, size, mtInternal);
     _on_c_heap = true;
   }
 
@@ -559,12 +559,12 @@
 
 PerfDataList::PerfDataList(int length) {
 
-  _set = new(ResourceObj::C_HEAP) PerfDataArray(length, true);
+  _set = new(ResourceObj::C_HEAP, mtInternal) PerfDataArray(length, true);
 }
 
 PerfDataList::PerfDataList(PerfDataList* p) {
 
-  _set = new(ResourceObj::C_HEAP) PerfDataArray(p->length(), true);
+  _set = new(ResourceObj::C_HEAP, mtInternal) PerfDataArray(p->length(), true);
 
   _set->appendAll(p->get_impl());
 }
diff --git a/hotspot/src/share/vm/runtime/perfData.hpp b/hotspot/src/share/vm/runtime/perfData.hpp
index 2f84ee6..2552fe8 100644
--- a/hotspot/src/share/vm/runtime/perfData.hpp
+++ b/hotspot/src/share/vm/runtime/perfData.hpp
@@ -240,7 +240,7 @@
  * be removed from the product in the future.
  *
  */
-class PerfData : public CHeapObj {
+class PerfData : public CHeapObj<mtInternal> {
 
   friend class StatSampler;      // for access to protected void sample()
   friend class PerfDataManager;  // for access to protected destructor
@@ -342,7 +342,7 @@
  * invoke the take_sample() method and write the value returned to its
  * appropriate location in the PerfData memory region.
  */
-class PerfLongSampleHelper : public CHeapObj {
+class PerfLongSampleHelper : public CHeapObj<mtInternal> {
   public:
     virtual jlong take_sample() = 0;
 };
@@ -591,7 +591,7 @@
  * some other implementation, as long as that implementation provides
  * a mechanism to iterate over the container by index.
  */
-class PerfDataList : public CHeapObj {
+class PerfDataList : public CHeapObj<mtInternal> {
 
   private:
 
diff --git a/hotspot/src/share/vm/runtime/perfMemory.cpp b/hotspot/src/share/vm/runtime/perfMemory.cpp
index 0855b38..26ef55e 100644
--- a/hotspot/src/share/vm/runtime/perfMemory.cpp
+++ b/hotspot/src/share/vm/runtime/perfMemory.cpp
@@ -112,7 +112,7 @@
       warning("Could not create PerfData Memory region, reverting to malloc");
     }
 
-    _prologue = NEW_C_HEAP_OBJ(PerfDataPrologue);
+    _prologue = NEW_C_HEAP_OBJ(PerfDataPrologue, mtInternal);
   }
   else {
 
@@ -244,10 +244,10 @@
   if (PerfDataSaveFile != NULL) {
     // dest_file_name stores the validated file name if file_name
     // contains %p which will be replaced by pid.
-    dest_file = NEW_C_HEAP_ARRAY(char, JVM_MAXPATHLEN);
+    dest_file = NEW_C_HEAP_ARRAY(char, JVM_MAXPATHLEN, mtInternal);
     if(!Arguments::copy_expand_pid(PerfDataSaveFile, strlen(PerfDataSaveFile),
                                    dest_file, JVM_MAXPATHLEN)) {
-      FREE_C_HEAP_ARRAY(char, dest_file);
+      FREE_C_HEAP_ARRAY(char, dest_file, mtInternal);
       if (PrintMiscellaneous && Verbose) {
         warning("Invalid performance data file path name specified, "\
                 "fall back to a default name");
@@ -257,7 +257,7 @@
     }
   }
   // create the name of the file for retaining the instrumentation memory.
-  dest_file = NEW_C_HEAP_ARRAY(char, PERFDATA_FILENAME_LEN);
+  dest_file = NEW_C_HEAP_ARRAY(char, PERFDATA_FILENAME_LEN, mtInternal);
   jio_snprintf(dest_file, PERFDATA_FILENAME_LEN,
                "%s_%d", PERFDATA_NAME, os::current_process_id());
 
diff --git a/hotspot/src/share/vm/runtime/reflection.cpp b/hotspot/src/share/vm/runtime/reflection.cpp
index 29858be..cd009ed 100644
--- a/hotspot/src/share/vm/runtime/reflection.cpp
+++ b/hotspot/src/share/vm/runtime/reflection.cpp
@@ -36,7 +36,6 @@
 #include "oops/objArrayKlass.hpp"
 #include "oops/objArrayOop.hpp"
 #include "prims/jvm.h"
-#include "prims/methodHandleWalk.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/handles.inline.hpp"
 #include "runtime/javaCalls.hpp"
@@ -502,11 +501,6 @@
       under_host_klass(accessee_ik, accessor))
     return true;
 
-  // Adapter frames can access anything.
-  if (MethodHandleCompiler::klass_is_method_handle_adapter_holder(accessor))
-    // This is an internal adapter frame from the MethodHandleCompiler.
-    return true;
-
   if (RelaxAccessControlCheck ||
       (accessor_ik->major_version() < JAVA_1_5_VERSION &&
        accessee_ik->major_version() < JAVA_1_5_VERSION)) {
@@ -591,14 +585,11 @@
 // Caller is responsible for figuring out in advance which case must be true.
 void Reflection::check_for_inner_class(instanceKlassHandle outer, instanceKlassHandle inner,
                                        bool inner_is_member, TRAPS) {
-  const int inner_class_info_index = 0;
-  const int outer_class_info_index = 1;
-
-  typeArrayHandle    icls (THREAD, outer->inner_classes());
+  InnerClassesIterator iter(outer);
   constantPoolHandle cp   (THREAD, outer->constants());
-  for(int i = 0; i < icls->length(); i += 4) {
-     int ioff = icls->ushort_at(i + inner_class_info_index);
-     int ooff = icls->ushort_at(i + outer_class_info_index);
+  for (; !iter.done(); iter.next()) {
+     int ioff = iter.inner_class_info_index();
+     int ooff = iter.outer_class_info_index();
 
      if (inner_is_member && ioff != 0 && ooff != 0) {
         klassOop o = cp->klass_at(ooff, CHECK);
@@ -832,7 +823,7 @@
   java_lang_reflect_Field::set_modifiers(rh(), fd->access_flags().as_int() & JVM_RECOGNIZED_FIELD_MODIFIERS);
   java_lang_reflect_Field::set_override(rh(), false);
   if (java_lang_reflect_Field::has_signature_field() &&
-      fd->generic_signature() != NULL) {
+      fd->has_generic_signature()) {
     Symbol*  gs = fd->generic_signature();
     Handle sig = java_lang_String::create_from_symbol(gs, CHECK_NULL);
     java_lang_reflect_Field::set_signature(rh(), sig());
diff --git a/hotspot/src/share/vm/runtime/reflectionUtils.cpp b/hotspot/src/share/vm/runtime/reflectionUtils.cpp
index 6c6e8c3..e8a986a 100644
--- a/hotspot/src/share/vm/runtime/reflectionUtils.cpp
+++ b/hotspot/src/share/vm/runtime/reflectionUtils.cpp
@@ -59,7 +59,7 @@
 
 
 GrowableArray<FilteredField*> *FilteredFieldsMap::_filtered_fields =
-  new (ResourceObj::C_HEAP) GrowableArray<FilteredField*>(3,true);
+  new (ResourceObj::C_HEAP, mtInternal) GrowableArray<FilteredField*>(3,true);
 
 
 void FilteredFieldsMap::initialize() {
diff --git a/hotspot/src/share/vm/runtime/relocator.cpp b/hotspot/src/share/vm/runtime/relocator.cpp
index a397090..9759b5e 100644
--- a/hotspot/src/share/vm/runtime/relocator.cpp
+++ b/hotspot/src/share/vm/runtime/relocator.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -392,16 +392,16 @@
 // The width of instruction at "pc" is changing by "delta".  Adjust the
 // exception table, if any, of "rc->mb".
 void Relocator::adjust_exception_table(int bci, int delta) {
-  typeArrayOop table = method()->exception_table();
-  for (int index = 0; index < table->length(); index +=4) {
-    if (table->int_at(index) > bci) {
-      table->int_at_put(index+0, table->int_at(index+0) + delta);
-      table->int_at_put(index+1, table->int_at(index+1) + delta);
-    } else if (bci < table->int_at(index+1)) {
-      table->int_at_put(index+1, table->int_at(index+1) + delta);
+  ExceptionTable table(_method());
+  for (int index = 0; index < table.length(); index ++) {
+    if (table.start_pc(index) > bci) {
+      table.set_start_pc(index, table.start_pc(index) + delta);
+      table.set_end_pc(index, table.end_pc(index) + delta);
+    } else if (bci < table.end_pc(index)) {
+      table.set_end_pc(index, table.end_pc(index) + delta);
     }
-    if (table->int_at(index+2) > bci)
-      table->int_at_put(index+2, table->int_at(index+2) + delta);
+    if (table.handler_pc(index) > bci)
+      table.set_handler_pc(index, table.handler_pc(index) + delta);
   }
 }
 
@@ -465,13 +465,12 @@
 void Relocator::adjust_stack_map_table(int bci, int delta) {
   if (method()->has_stackmap_table()) {
     typeArrayOop data = method()->stackmap_data();
-    // The data in the array is a classfile representation of the stackmap
-    // table attribute, less the initial u2 tag and u4 attribute_length fields.
-    stack_map_table_attribute* attr = stack_map_table_attribute::at(
-        (address)data->byte_at_addr(0) - (sizeof(u2) + sizeof(u4)));
+    // The data in the array is a classfile representation of the stackmap table
+    stack_map_table* sm_table =
+        stack_map_table::at((address)data->byte_at_addr(0));
 
-    int count = attr->number_of_entries();
-    stack_map_frame* frame = attr->entries();
+    int count = sm_table->number_of_entries();
+    stack_map_frame* frame = sm_table->entries();
     int bci_iter = -1;
     bool offset_adjusted = false; // only need to adjust one offset
 
@@ -486,7 +485,7 @@
           frame->set_offset_delta(new_offset_delta);
         } else {
           assert(frame->is_same_frame() ||
-                 frame->is_same_frame_1_stack_item_frame(),
+                 frame->is_same_locals_1_stack_item_frame(),
                  "Frame must be one of the compressed forms");
           // The new delta exceeds the capacity of the 'same_frame' or
           // 'same_frame_1_stack_item_frame' frame types.  We need to
@@ -513,7 +512,7 @@
           if (frame->is_same_frame()) {
             same_frame_extended::create_at(frame_addr, new_offset_delta);
           } else {
-            same_frame_1_stack_item_extended::create_at(
+            same_locals_1_stack_item_extended::create_at(
               frame_addr, new_offset_delta, NULL);
             // the verification_info_type should already be at the right spot
           }
diff --git a/hotspot/src/share/vm/runtime/safepoint.cpp b/hotspot/src/share/vm/runtime/safepoint.cpp
index c29d257..31b33e3 100644
--- a/hotspot/src/share/vm/runtime/safepoint.cpp
+++ b/hotspot/src/share/vm/runtime/safepoint.cpp
@@ -48,6 +48,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/sweeper.hpp"
 #include "runtime/synchronizer.hpp"
+#include "services/memTracker.hpp"
 #include "services/runtimeService.hpp"
 #include "utilities/events.hpp"
 #ifdef TARGET_ARCH_x86
@@ -546,6 +547,10 @@
   if (UseGCLogFileRotation) {
     gclog_or_tty->rotate_log();
   }
+
+  if (MemTracker::is_on()) {
+    MemTracker::sync();
+  }
 }
 
 
@@ -1157,7 +1162,7 @@
     stats_array_size = PrintSafepointStatisticsCount;
   }
   _safepoint_stats = (SafepointStats*)os::malloc(stats_array_size
-                                                 * sizeof(SafepointStats));
+                                                 * sizeof(SafepointStats), mtInternal);
   guarantee(_safepoint_stats != NULL,
             "not enough memory for safepoint instrumentation data");
 
diff --git a/hotspot/src/share/vm/runtime/safepoint.hpp b/hotspot/src/share/vm/runtime/safepoint.hpp
index 71255a2..005ea4d 100644
--- a/hotspot/src/share/vm/runtime/safepoint.hpp
+++ b/hotspot/src/share/vm/runtime/safepoint.hpp
@@ -190,7 +190,7 @@
 };
 
 // State class for a thread suspended at a safepoint
-class ThreadSafepointState: public CHeapObj {
+class ThreadSafepointState: public CHeapObj<mtInternal> {
  public:
   // These states are maintained by VM thread while threads are being brought
   // to a safepoint.  After SafepointSynchronize::end(), they are reset to
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.cpp b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
index 503ad07..db24783 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.cpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.cpp
@@ -88,8 +88,7 @@
 RuntimeStub*        SharedRuntime::_resolve_static_call_blob;
 
 DeoptimizationBlob* SharedRuntime::_deopt_blob;
-RicochetBlob*       SharedRuntime::_ricochet_blob;
-
+SafepointBlob*      SharedRuntime::_polling_page_vectors_safepoint_handler_blob;
 SafepointBlob*      SharedRuntime::_polling_page_safepoint_handler_blob;
 SafepointBlob*      SharedRuntime::_polling_page_return_handler_blob;
 
@@ -106,10 +105,15 @@
   _resolve_virtual_call_blob           = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C),      "resolve_virtual_call");
   _resolve_static_call_blob            = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C),       "resolve_static_call");
 
-  _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), false);
-  _polling_page_return_handler_blob    = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), true);
+#ifdef COMPILER2
+  // Vectors are generated only by C2.
+  if (is_wide_vector(MaxVectorSize)) {
+    _polling_page_vectors_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_VECTOR_LOOP);
+  }
+#endif // COMPILER2
+  _polling_page_safepoint_handler_blob = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_LOOP);
+  _polling_page_return_handler_blob    = generate_handler_blob(CAST_FROM_FN_PTR(address, SafepointSynchronize::handle_polling_page_exception), POLL_AT_RETURN);
 
-  generate_ricochet_blob();
   generate_deopt_blob();
 
 #ifdef COMPILER2
@@ -117,33 +121,6 @@
 #endif // COMPILER2
 }
 
-//----------------------------generate_ricochet_blob---------------------------
-void SharedRuntime::generate_ricochet_blob() {
-  if (!EnableInvokeDynamic)  return;  // leave it as a null
-
-  // allocate space for the code
-  ResourceMark rm;
-  // setup code generation tools
-  CodeBuffer buffer("ricochet_blob", 256 LP64_ONLY(+ 256), 256);  // XXX x86 LP64L: 512, 512
-  MacroAssembler* masm = new MacroAssembler(&buffer);
-
-  int bounce_offset = -1, exception_offset = -1, frame_size_in_words = -1;
-  MethodHandles::RicochetFrame::generate_ricochet_blob(masm, &bounce_offset, &exception_offset, &frame_size_in_words);
-
-  // -------------
-  // make sure all code is generated
-  masm->flush();
-
-  // failed to generate?
-  if (bounce_offset < 0 || exception_offset < 0 || frame_size_in_words < 0) {
-    assert(false, "bad ricochet blob");
-    return;
-  }
-
-  _ricochet_blob = RicochetBlob::create(&buffer, bounce_offset, exception_offset, frame_size_in_words);
-}
-
-
 #include <math.h>
 
 #ifndef USDT2
@@ -527,10 +504,6 @@
   if (Interpreter::contains(return_address)) {
     return Interpreter::rethrow_exception_entry();
   }
-  // Ricochet frame unwind code
-  if (SharedRuntime::ricochet_blob() != NULL && SharedRuntime::ricochet_blob()->returns_to_bounce_addr(return_address)) {
-    return SharedRuntime::ricochet_blob()->exception_addr();
-  }
 
   guarantee(blob == NULL || !blob->is_runtime_stub(), "caller should have skipped stub");
   guarantee(!VtableStubs::contains(return_address), "NULL exceptions in vtables should have been handled already!");
@@ -569,10 +542,15 @@
     "Only polling locations are used for safepoint");
 
   bool at_poll_return = ((nmethod*)cb)->is_at_poll_return(pc);
+  bool has_wide_vectors = ((nmethod*)cb)->has_wide_vectors();
   if (at_poll_return) {
     assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
            "polling page return stub not created yet");
     stub = SharedRuntime::polling_page_return_handler_blob()->entry_point();
+  } else if (has_wide_vectors) {
+    assert(SharedRuntime::polling_page_vectors_safepoint_handler_blob() != NULL,
+           "polling page vectors safepoint stub not created yet");
+    stub = SharedRuntime::polling_page_vectors_safepoint_handler_blob()->entry_point();
   } else {
     assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL,
            "polling page safepoint stub not created yet");
@@ -768,13 +746,6 @@
   throw_and_post_jvmti_exception(thread, exception);
 JRT_END
 
-JRT_ENTRY(void, SharedRuntime::throw_WrongMethodTypeException(JavaThread* thread, oopDesc* required, oopDesc* actual))
-  assert(thread == JavaThread::current() && required->is_oop() && actual->is_oop(), "bad args");
-  ResourceMark rm;
-  char* message = SharedRuntime::generate_wrong_method_type_message(thread, required, actual);
-  throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_invoke_WrongMethodTypeException(), message);
-JRT_END
-
 address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
                                                            address pc,
                                                            SharedRuntime::ImplicitExceptionKind exception_kind)
@@ -857,6 +828,12 @@
             return StubRoutines::throw_NullPointerException_at_call_entry();
           }
 
+          if (nm->method()->is_method_handle_intrinsic()) {
+            // exception happened inside MH dispatch code, similar to a vtable stub
+            Events::log_exception(thread, "NullPointerException in MH adapter " INTPTR_FORMAT, pc);
+            return StubRoutines::throw_NullPointerException_at_call_entry();
+          }
+
 #ifndef PRODUCT
           _implicit_null_throws++;
 #endif
@@ -909,11 +886,20 @@
 }
 JNI_END
 
+JNI_ENTRY(void, throw_unsupported_operation_exception(JNIEnv* env, ...))
+{
+  THROW(vmSymbols::java_lang_UnsupportedOperationException());
+}
+JNI_END
 
 address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() {
   return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error);
 }
 
+address SharedRuntime::native_method_throw_unsupported_operation_exception_entry() {
+  return CAST_FROM_FN_PTR(address, &throw_unsupported_operation_exception);
+}
+
 
 #ifndef PRODUCT
 JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
@@ -1045,16 +1031,17 @@
   assert(!vfst.at_end(), "Java frame must exist");
 
   // Find caller and bci from vframe
-  methodHandle caller (THREAD, vfst.method());
-  int          bci    = vfst.bci();
+  methodHandle caller(THREAD, vfst.method());
+  int          bci   = vfst.bci();
 
   // Find bytecode
   Bytecode_invoke bytecode(caller, bci);
-  bc = bytecode.java_code();
+  bc = bytecode.invoke_code();
   int bytecode_index = bytecode.index();
 
   // Find receiver for non-static call
-  if (bc != Bytecodes::_invokestatic) {
+  if (bc != Bytecodes::_invokestatic &&
+      bc != Bytecodes::_invokedynamic) {
     // This register map must be update since we need to find the receiver for
     // compiled frames. The receiver might be in a register.
     RegisterMap reg_map2(thread);
@@ -1075,25 +1062,32 @@
   }
 
   // Resolve method. This is parameterized by bytecode.
-  constantPoolHandle constants (THREAD, caller->constants());
-  assert (receiver.is_null() || receiver->is_oop(), "wrong receiver");
+  constantPoolHandle constants(THREAD, caller->constants());
+  assert(receiver.is_null() || receiver->is_oop(), "wrong receiver");
   LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_(nullHandle));
 
 #ifdef ASSERT
   // Check that the receiver klass is of the right subtype and that it is initialized for virtual calls
   if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic) {
     assert(receiver.not_null(), "should have thrown exception");
-    KlassHandle receiver_klass (THREAD, receiver->klass());
+    KlassHandle receiver_klass(THREAD, receiver->klass());
     klassOop rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle));
                             // klass is already loaded
-    KlassHandle static_receiver_klass (THREAD, rk);
-    assert(receiver_klass->is_subtype_of(static_receiver_klass()), "actual receiver must be subclass of static receiver klass");
+    KlassHandle static_receiver_klass(THREAD, rk);
+    // Method handle invokes might have been optimized to a direct call
+    // so don't check for the receiver class.
+    // FIXME this weakens the assert too much
+    methodHandle callee = callinfo.selected_method();
+    assert(receiver_klass->is_subtype_of(static_receiver_klass()) ||
+           callee->is_method_handle_intrinsic() ||
+           callee->is_compiled_lambda_form(),
+           "actual receiver must be subclass of static receiver klass");
     if (receiver_klass->oop_is_instance()) {
       if (instanceKlass::cast(receiver_klass())->is_not_initialized()) {
         tty->print_cr("ERROR: Klass not yet initialized!!");
         receiver_klass.print();
       }
-      assert (!instanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized");
+      assert(!instanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized");
     }
   }
 #endif
@@ -1186,8 +1180,10 @@
                                      call_info, CHECK_(methodHandle()));
   methodHandle callee_method = call_info.selected_method();
 
-  assert((!is_virtual && invoke_code == Bytecodes::_invokestatic) ||
-         ( is_virtual && invoke_code != Bytecodes::_invokestatic), "inconsistent bytecode");
+  assert((!is_virtual && invoke_code == Bytecodes::_invokestatic ) ||
+         (!is_virtual && invoke_code == Bytecodes::_invokehandle ) ||
+         (!is_virtual && invoke_code == Bytecodes::_invokedynamic) ||
+         ( is_virtual && invoke_code != Bytecodes::_invokestatic ), "inconsistent bytecode");
 
 #ifndef PRODUCT
   // tracing/debugging/statistics
@@ -1202,16 +1198,17 @@
       (is_optimized) ? "optimized " : "", (is_virtual) ? "virtual" : "static",
       Bytecodes::name(invoke_code));
     callee_method->print_short_name(tty);
-    tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
+    tty->print_cr(" at pc: " INTPTR_FORMAT " to code: " INTPTR_FORMAT, caller_frame.pc(), callee_method->code());
   }
 #endif
 
-  // JSR 292
+  // JSR 292 key invariant:
   // If the resolved method is a MethodHandle invoke target the call
-  // site must be a MethodHandle call site.
-  if (callee_method->is_method_handle_invoke()) {
-    assert(caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
-  }
+  // site must be a MethodHandle call site, because the lambda form might tail-call
+  // leaving the stack in a state unknown to either caller or callee
+  // TODO detune for now but we might need it again
+//  assert(!callee_method->is_compiled_lambda_form() ||
+//         caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site");
 
   // Compute entry points. This might require generation of C2I converter
   // frames, so we cannot be holding any locks here. Furthermore, the
@@ -1284,7 +1281,6 @@
   assert(stub_frame.is_runtime_frame(), "sanity check");
   frame caller_frame = stub_frame.sender(&reg_map);
   assert(!caller_frame.is_interpreted_frame() && !caller_frame.is_entry_frame(), "unexpected frame");
-  assert(!caller_frame.is_ricochet_frame(), "unexpected frame");
 #endif /* ASSERT */
 
   methodHandle callee_method;
@@ -1320,21 +1316,9 @@
   address   sender_pc = caller_frame.pc();
   CodeBlob* sender_cb = caller_frame.cb();
   nmethod*  sender_nm = sender_cb->as_nmethod_or_null();
-  bool is_mh_invoke_via_adapter = false;  // Direct c2c call or via adapter?
-  if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) {
-    // If the callee_target is set, then we have come here via an i2c
-    // adapter.
-    methodOop callee = thread->callee_target();
-    if (callee != NULL) {
-      assert(callee->is_method(), "sanity");
-      is_mh_invoke_via_adapter = true;
-    }
-  }
 
   if (caller_frame.is_interpreted_frame() ||
-      caller_frame.is_entry_frame()       ||
-      caller_frame.is_ricochet_frame()    ||
-      is_mh_invoke_via_adapter) {
+      caller_frame.is_entry_frame()) {
     methodOop callee = thread->callee_target();
     guarantee(callee != NULL && callee->is_method(), "bad handshake");
     thread->set_vm_result(callee);
@@ -1644,6 +1628,31 @@
   return callee_method;
 }
 
+#ifdef ASSERT
+void SharedRuntime::check_member_name_argument_is_last_argument(methodHandle method,
+                                                                const BasicType* sig_bt,
+                                                                const VMRegPair* regs) {
+  ResourceMark rm;
+  const int total_args_passed = method->size_of_parameters();
+  const VMRegPair*    regs_with_member_name = regs;
+        VMRegPair* regs_without_member_name = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed - 1);
+
+  const int member_arg_pos = total_args_passed - 1;
+  assert(member_arg_pos >= 0 && member_arg_pos < total_args_passed, "oob");
+  assert(sig_bt[member_arg_pos] == T_OBJECT, "dispatch argument must be an object");
+
+  const bool is_outgoing = method->is_method_handle_intrinsic();
+  int comp_args_on_stack = java_calling_convention(sig_bt, regs_without_member_name, total_args_passed - 1, is_outgoing);
+
+  for (int i = 0; i < member_arg_pos; i++) {
+    VMReg a =    regs_with_member_name[i].first();
+    VMReg b = regs_without_member_name[i].first();
+    assert(a->value() == b->value(), err_msg_res("register allocation mismatch: a=%d, b=%d", a->value(), b->value()));
+  }
+  assert(regs_with_member_name[member_arg_pos].first()->is_valid(), "bad member arg");
+}
+#endif
+
 // ---------------------------------------------------------------------------
 // We are calling the interpreter via a c2i. Normally this would mean that
 // we were called by a compiled method. However we could have lost a race
@@ -1677,12 +1686,6 @@
   // Get the return PC for the passed caller PC.
   address return_pc = caller_pc + frame::pc_return_offset;
 
-  // Don't fixup method handle call sites as the executed method
-  // handle adapters are doing the required MethodHandle chain work.
-  if (nm->is_method_handle_return(return_pc)) {
-    return;
-  }
-
   // There is a benign race here. We could be attempting to patch to a compiled
   // entry point at the same time the callee is being deoptimized. If that is
   // the case then entry_point may in fact point to a c2i and we'd patch the
@@ -1788,97 +1791,6 @@
   return generate_class_cast_message(objName, targetKlass->external_name());
 }
 
-char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread,
-                                                        oopDesc* required,
-                                                        oopDesc* actual) {
-  if (TraceMethodHandles) {
-    tty->print_cr("WrongMethodType thread="PTR_FORMAT" req="PTR_FORMAT" act="PTR_FORMAT"",
-                  thread, required, actual);
-  }
-  assert(EnableInvokeDynamic, "");
-  oop singleKlass = wrong_method_type_is_for_single_argument(thread, required);
-  char* message = NULL;
-  if (singleKlass != NULL) {
-    const char* objName = "argument or return value";
-    if (actual != NULL) {
-      // be flexible about the junk passed in:
-      klassOop ak = (actual->is_klass()
-                     ? (klassOop)actual
-                     : actual->klass());
-      objName = Klass::cast(ak)->external_name();
-    }
-    Klass* targetKlass = Klass::cast(required->is_klass()
-                                     ? (klassOop)required
-                                     : java_lang_Class::as_klassOop(required));
-    message = generate_class_cast_message(objName, targetKlass->external_name());
-  } else {
-    // %%% need to get the MethodType string, without messing around too much
-    const char* desc = NULL;
-    // Get a signature from the invoke instruction
-    const char* mhName = "method handle";
-    const char* targetType = "the required signature";
-    int targetArity = -1, mhArity = -1;
-    vframeStream vfst(thread, true);
-    if (!vfst.at_end()) {
-      Bytecode_invoke call(vfst.method(), vfst.bci());
-      methodHandle target;
-      {
-        EXCEPTION_MARK;
-        target = call.static_target(THREAD);
-        if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; }
-      }
-      if (target.not_null()
-          && target->is_method_handle_invoke()
-          && required == target->method_handle_type()) {
-        targetType = target->signature()->as_C_string();
-        targetArity = ArgumentCount(target->signature()).size();
-      }
-    }
-    KlassHandle kignore; int dmf_flags = 0;
-    methodHandle actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags);
-    if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver |
-                       MethodHandles::_dmf_does_dispatch |
-                       MethodHandles::_dmf_from_interface)) != 0)
-      actual_method = methodHandle();  // MH does extra binds, drops, etc.
-    bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0);
-    if (actual_method.not_null()) {
-      mhName = actual_method->signature()->as_C_string();
-      mhArity = ArgumentCount(actual_method->signature()).size();
-      if (!actual_method->is_static())  mhArity += 1;
-    } else if (java_lang_invoke_MethodHandle::is_instance(actual)) {
-      oopDesc* mhType = java_lang_invoke_MethodHandle::type(actual);
-      mhArity = java_lang_invoke_MethodType::ptype_count(mhType);
-      stringStream st;
-      java_lang_invoke_MethodType::print_signature(mhType, &st);
-      mhName = st.as_string();
-    }
-    if (targetArity != -1 && targetArity != mhArity) {
-      if (has_receiver && targetArity == mhArity-1)
-        desc = " cannot be called without a receiver argument as ";
-      else
-        desc = " cannot be called with a different arity as ";
-    }
-    message = generate_class_cast_message(mhName, targetType,
-                                          desc != NULL ? desc :
-                                          " cannot be called as ");
-  }
-  if (TraceMethodHandles) {
-    tty->print_cr("WrongMethodType => message=%s", message);
-  }
-  return message;
-}
-
-oop SharedRuntime::wrong_method_type_is_for_single_argument(JavaThread* thr,
-                                                            oopDesc* required) {
-  if (required == NULL)  return NULL;
-  if (required->klass() == SystemDictionary::Class_klass())
-    return required;
-  if (required->is_klass())
-    return Klass::cast(klassOop(required))->java_mirror();
-  return NULL;
-}
-
-
 char* SharedRuntime::generate_class_cast_message(
     const char* objName, const char* targetKlassName, const char* desc) {
   size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1;
@@ -2117,10 +2029,19 @@
 
 // A simple wrapper class around the calling convention information
 // that allows sharing of adapters for the same calling convention.
-class AdapterFingerPrint : public CHeapObj {
+class AdapterFingerPrint : public CHeapObj<mtCode> {
  private:
+  enum {
+    _basic_type_bits = 4,
+    _basic_type_mask = right_n_bits(_basic_type_bits),
+    _basic_types_per_int = BitsPerInt / _basic_type_bits,
+    _compact_int_count = 3
+  };
+  // TO DO:  Consider integrating this with a more global scheme for compressing signatures.
+  // For now, 4 bits per components (plus T_VOID gaps after double/long) is not excessive.
+
   union {
-    int  _compact[3];
+    int  _compact[_compact_int_count];
     int* _fingerprint;
   } _value;
   int _length; // A negative length indicates the fingerprint is in the compact form,
@@ -2129,8 +2050,7 @@
   // Remap BasicTypes that are handled equivalently by the adapters.
   // These are correct for the current system but someday it might be
   // necessary to make this mapping platform dependent.
-  static BasicType adapter_encoding(BasicType in) {
-    assert((~0xf & in) == 0, "must fit in 4 bits");
+  static int adapter_encoding(BasicType in) {
     switch(in) {
       case T_BOOLEAN:
       case T_BYTE:
@@ -2141,6 +2061,8 @@
 
       case T_OBJECT:
       case T_ARRAY:
+        // In other words, we assume that any register good enough for
+        // an int or long is good enough for a managed pointer.
 #ifdef _LP64
         return T_LONG;
 #else
@@ -2165,8 +2087,9 @@
     // The fingerprint is based on the BasicType signature encoded
     // into an array of ints with eight entries per int.
     int* ptr;
-    int len = (total_args_passed + 7) >> 3;
-    if (len <= (int)(sizeof(_value._compact) / sizeof(int))) {
+    int len = (total_args_passed + (_basic_types_per_int-1)) / _basic_types_per_int;
+    if (len <= _compact_int_count) {
+      assert(_compact_int_count == 3, "else change next line");
       _value._compact[0] = _value._compact[1] = _value._compact[2] = 0;
       // Storing the signature encoded as signed chars hits about 98%
       // of the time.
@@ -2174,7 +2097,7 @@
       ptr = _value._compact;
     } else {
       _length = len;
-      _value._fingerprint = NEW_C_HEAP_ARRAY(int, _length);
+      _value._fingerprint = NEW_C_HEAP_ARRAY(int, _length, mtCode);
       ptr = _value._fingerprint;
     }
 
@@ -2182,10 +2105,12 @@
     int sig_index = 0;
     for (int index = 0; index < len; index++) {
       int value = 0;
-      for (int byte = 0; byte < 8; byte++) {
-        if (sig_index < total_args_passed) {
-          value = (value << 4) | adapter_encoding(sig_bt[sig_index++]);
-        }
+      for (int byte = 0; byte < _basic_types_per_int; byte++) {
+        int bt = ((sig_index < total_args_passed)
+                  ? adapter_encoding(sig_bt[sig_index++])
+                  : 0);
+        assert((bt & _basic_type_mask) == bt, "must fit in 4 bits");
+        value = (value << _basic_type_bits) | bt;
       }
       ptr[index] = value;
     }
@@ -2193,7 +2118,7 @@
 
   ~AdapterFingerPrint() {
     if (_length > 0) {
-      FREE_C_HEAP_ARRAY(int, _value._fingerprint);
+      FREE_C_HEAP_ARRAY(int, _value._fingerprint, mtCode);
     }
   }
 
@@ -2235,6 +2160,7 @@
       return false;
     }
     if (_length < 0) {
+      assert(_compact_int_count == 3, "else change next line");
       return _value._compact[0] == other->_value._compact[0] &&
              _value._compact[1] == other->_value._compact[1] &&
              _value._compact[2] == other->_value._compact[2];
@@ -2251,7 +2177,7 @@
 
 
 // A hashtable mapping from AdapterFingerPrints to AdapterHandlerEntries
-class AdapterHandlerTable : public BasicHashtable {
+class AdapterHandlerTable : public BasicHashtable<mtCode> {
   friend class AdapterHandlerTableIterator;
 
  private:
@@ -2265,16 +2191,16 @@
 #endif
 
   AdapterHandlerEntry* bucket(int i) {
-    return (AdapterHandlerEntry*)BasicHashtable::bucket(i);
+    return (AdapterHandlerEntry*)BasicHashtable<mtCode>::bucket(i);
   }
 
  public:
   AdapterHandlerTable()
-    : BasicHashtable(293, sizeof(AdapterHandlerEntry)) { }
+    : BasicHashtable<mtCode>(293, sizeof(AdapterHandlerEntry)) { }
 
   // Create a new entry suitable for insertion in the table
   AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) {
-    AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable::new_entry(fingerprint->compute_hash());
+    AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable<mtCode>::new_entry(fingerprint->compute_hash());
     entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry);
     return entry;
   }
@@ -2287,7 +2213,7 @@
 
   void free_entry(AdapterHandlerEntry* entry) {
     entry->deallocate();
-    BasicHashtable::free_entry(entry);
+    BasicHashtable<mtCode>::free_entry(entry);
   }
 
   // Find a entry with the same fingerprint if it exists
@@ -2531,13 +2457,20 @@
     entry->relocate(B->content_begin());
 #ifndef PRODUCT
     // debugging suppport
-    if (PrintAdapterHandlers) {
-      tty->cr();
-      tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = %s, %d bytes generated)",
+    if (PrintAdapterHandlers || PrintStubCode) {
+      ttyLocker ttyl;
+      entry->print_adapter_on(tty);
+      tty->print_cr("i2c argument handler #%d for: %s %s (%d bytes generated)",
                     _adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"),
-                    method->signature()->as_C_string(), fingerprint->as_string(), insts_size );
+                    method->signature()->as_C_string(), insts_size);
       tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry());
-      Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + insts_size);
+      if (Verbose || PrintStubCode) {
+        address first_pc = entry->base_address();
+        if (first_pc != NULL) {
+          Disassembler::decode(first_pc, first_pc + insts_size);
+          tty->cr();
+        }
+      }
     }
 #endif
 
@@ -2561,19 +2494,33 @@
   return entry;
 }
 
+address AdapterHandlerEntry::base_address() {
+  address base = _i2c_entry;
+  if (base == NULL)  base = _c2i_entry;
+  assert(base <= _c2i_entry || _c2i_entry == NULL, "");
+  assert(base <= _c2i_unverified_entry || _c2i_unverified_entry == NULL, "");
+  return base;
+}
+
 void AdapterHandlerEntry::relocate(address new_base) {
-    ptrdiff_t delta = new_base - _i2c_entry;
+  address old_base = base_address();
+  assert(old_base != NULL, "");
+  ptrdiff_t delta = new_base - old_base;
+  if (_i2c_entry != NULL)
     _i2c_entry += delta;
+  if (_c2i_entry != NULL)
     _c2i_entry += delta;
+  if (_c2i_unverified_entry != NULL)
     _c2i_unverified_entry += delta;
+  assert(base_address() == new_base, "");
 }
 
 
 void AdapterHandlerEntry::deallocate() {
   delete _fingerprint;
 #ifdef ASSERT
-  if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code);
-  if (_saved_sig)  FREE_C_HEAP_ARRAY(Basictype, _saved_sig);
+  if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code, mtCode);
+  if (_saved_sig)  FREE_C_HEAP_ARRAY(Basictype, _saved_sig, mtCode);
 #endif
 }
 
@@ -2583,11 +2530,11 @@
 // against other versions.  If the code is captured after relocation
 // then relative instructions won't be equivalent.
 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) {
-  _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length);
+  _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length, mtCode);
   _code_length = length;
   memcpy(_saved_code, buffer, length);
   _total_args_passed = total_args_passed;
-  _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed);
+  _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed, mtCode);
   memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType));
 }
 
@@ -2614,7 +2561,9 @@
   ResourceMark rm;
   nmethod* nm = NULL;
 
-  assert(method->has_native_function(), "must have something valid to call!");
+  assert(method->is_native(), "must be native");
+  assert(method->is_method_handle_intrinsic() ||
+         method->has_native_function(), "must have something valid to call!");
 
   {
     // perform the work while holding the lock, but perform any printing outside the lock
@@ -2635,10 +2584,10 @@
       MacroAssembler _masm(&buffer);
 
       // Fill in the signature array, for the calling-convention call.
-      int total_args_passed = method->size_of_parameters();
+      const int total_args_passed = method->size_of_parameters();
 
-      BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed);
-      VMRegPair*   regs = NEW_RESOURCE_ARRAY(VMRegPair,total_args_passed);
+      BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed);
+      VMRegPair*   regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed);
       int i=0;
       if( !method->is_static() )  // Pass in receiver first
         sig_bt[i++] = T_OBJECT;
@@ -2648,20 +2597,21 @@
         if( ss.type() == T_LONG || ss.type() == T_DOUBLE )
           sig_bt[i++] = T_VOID;   // Longs & doubles take 2 Java slots
       }
-      assert( i==total_args_passed, "" );
+      assert(i == total_args_passed, "");
       BasicType ret_type = ss.type();
 
-      // Now get the compiled-Java layout as input arguments
-      int comp_args_on_stack;
-      comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
+      // Now get the compiled-Java layout as input (or output) arguments.
+      // NOTE: Stubs for compiled entry points of method handle intrinsics
+      // are just trampolines so the argument registers must be outgoing ones.
+      const bool is_outgoing = method->is_method_handle_intrinsic();
+      int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, is_outgoing);
 
       // Generate the compiled-to-native wrapper code
       nm = SharedRuntime::generate_native_wrapper(&_masm,
                                                   method,
                                                   compile_id,
-                                                  total_args_passed,
-                                                  comp_args_on_stack,
-                                                  sig_bt,regs,
+                                                  sig_bt,
+                                                  regs,
                                                   ret_type);
     }
   }
@@ -2893,7 +2843,7 @@
   int max_locals = moop->max_locals();
   // Allocate temp buffer, 1 word per local & 2 per active monitor
   int buf_size_words = max_locals + active_monitor_count*2;
-  intptr_t *buf = NEW_C_HEAP_ARRAY(intptr_t,buf_size_words);
+  intptr_t *buf = NEW_C_HEAP_ARRAY(intptr_t,buf_size_words, mtCode);
 
   // Copy the locals.  Order is preserved so that loading of longs works.
   // Since there's no GC I can copy the oops blindly.
@@ -2923,7 +2873,7 @@
 JRT_END
 
 JRT_LEAF(void, SharedRuntime::OSR_migration_end( intptr_t* buf) )
-  FREE_C_HEAP_ARRAY(intptr_t,buf);
+  FREE_C_HEAP_ARRAY(intptr_t,buf, mtCode);
 JRT_END
 
 bool AdapterHandlerLibrary::contains(CodeBlob* b) {
@@ -2939,18 +2889,22 @@
   AdapterHandlerTableIterator iter(_adapters);
   while (iter.has_next()) {
     AdapterHandlerEntry* a = iter.next();
-    if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) {
+    if (b == CodeCache::find_blob(a->get_i2c_entry())) {
       st->print("Adapter for signature: ");
-      st->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
-                   a->fingerprint()->as_string(),
-                   a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry());
-
+      a->print_adapter_on(tty);
       return;
     }
   }
   assert(false, "Should have found handler");
 }
 
+void AdapterHandlerEntry::print_adapter_on(outputStream* st) const {
+  st->print_cr("AHE@" INTPTR_FORMAT ": %s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
+               (intptr_t) this, fingerprint()->as_string(),
+               get_i2c_entry(), get_c2i_entry(), get_c2i_unverified_entry());
+
+}
+
 #ifndef PRODUCT
 
 void AdapterHandlerLibrary::print_statistics() {
diff --git a/hotspot/src/share/vm/runtime/sharedRuntime.hpp b/hotspot/src/share/vm/runtime/sharedRuntime.hpp
index 9650c6e..0027547 100644
--- a/hotspot/src/share/vm/runtime/sharedRuntime.hpp
+++ b/hotspot/src/share/vm/runtime/sharedRuntime.hpp
@@ -61,8 +61,8 @@
   static RuntimeStub*        _resolve_static_call_blob;
 
   static DeoptimizationBlob* _deopt_blob;
-  static RicochetBlob*       _ricochet_blob;
 
+  static SafepointBlob*      _polling_page_vectors_safepoint_handler_blob;
   static SafepointBlob*      _polling_page_safepoint_handler_blob;
   static SafepointBlob*      _polling_page_return_handler_blob;
 
@@ -76,7 +76,8 @@
 #endif // !PRODUCT
 
  private:
-  static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return);
+  enum { POLL_AT_RETURN,  POLL_AT_LOOP, POLL_AT_VECTOR_LOOP };
+  static SafepointBlob* generate_handler_blob(address call_ptr, int poll_type);
   static RuntimeStub*   generate_resolve_blob(address destination, const char* name);
 
  public:
@@ -187,7 +188,6 @@
   static void    throw_NullPointerException(JavaThread* thread);
   static void    throw_NullPointerException_at_call(JavaThread* thread);
   static void    throw_StackOverflowError(JavaThread* thread);
-  static void    throw_WrongMethodTypeException(JavaThread* thread, oopDesc* required, oopDesc* actual);
   static address continuation_for_implicit_exception(JavaThread* thread,
                                                      address faulting_pc,
                                                      ImplicitExceptionKind exception_kind);
@@ -223,18 +223,9 @@
     return _resolve_static_call_blob->entry_point();
   }
 
-  static RicochetBlob* ricochet_blob() {
-#ifdef X86
-    // Currently only implemented on x86
-    assert(!EnableInvokeDynamic || _ricochet_blob != NULL, "oops");
-#endif
-    return _ricochet_blob;
-  }
-
-  static void generate_ricochet_blob();
-
   static SafepointBlob* polling_page_return_handler_blob()     { return _polling_page_return_handler_blob; }
   static SafepointBlob* polling_page_safepoint_handler_blob()  { return _polling_page_safepoint_handler_blob; }
+  static SafepointBlob* polling_page_vectors_safepoint_handler_blob()  { return _polling_page_vectors_safepoint_handler_blob; }
 
   // Counters
 #ifndef PRODUCT
@@ -250,6 +241,7 @@
 
   // To be used as the entry point for unresolved native methods.
   static address native_method_throw_unsatisfied_link_error_entry();
+  static address native_method_throw_unsupported_operation_exception_entry();
 
   // bytecode tracing is only used by the TraceBytecodes
   static intptr_t trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2) PRODUCT_RETURN0;
@@ -291,27 +283,6 @@
   static char* generate_class_cast_message(JavaThread* thr, const char* name);
 
   /**
-   * Fill in the message for a WrongMethodTypeException
-   *
-   * @param thr the current thread
-   * @param mtype (optional) expected method type (or argument class)
-   * @param mhandle (optional) actual method handle (or argument)
-   * @return the dynamically allocated exception message
-   *
-   * BCP for the frame on top of the stack must refer to an
-   * 'invokevirtual' op for a method handle, or an 'invokedyamic' op.
-   * The caller (or one of its callers) must use a ResourceMark
-   * in order to correctly free the result.
-   */
-  static char* generate_wrong_method_type_message(JavaThread* thr,
-                                                  oopDesc* mtype = NULL,
-                                                  oopDesc* mhandle = NULL);
-
-  /** Return non-null if the mtype is a klass or Class, not a MethodType. */
-  static oop wrong_method_type_is_for_single_argument(JavaThread* thr,
-                                                      oopDesc* mtype);
-
-  /**
    * Fill in the "X cannot be cast to a Y" message for ClassCastException
    *
    * @param name the name of the class of the object attempted to be cast
@@ -377,7 +348,11 @@
   // the bottom of the frame the first 16 words will be skipped and SharedInfo::stack0
   // will be just above it. (
   // return value is the maximum number of VMReg stack slots the convention will use.
-  static int java_calling_convention(const BasicType *sig_bt, VMRegPair *regs, int total_args_passed, int is_outgoing);
+  static int java_calling_convention(const BasicType* sig_bt, VMRegPair* regs, int total_args_passed, int is_outgoing);
+
+  static void check_member_name_argument_is_last_argument(methodHandle method,
+                                                          const BasicType* sig_bt,
+                                                          const VMRegPair* regs) NOT_DEBUG_RETURN;
 
   // Ditto except for calling C
   static int c_calling_convention(const BasicType *sig_bt, VMRegPair *regs, int total_args_passed);
@@ -444,6 +419,10 @@
   // when an interrupt occurs.
   static uint out_preserve_stack_slots();
 
+  // Is vector's size (in bytes) bigger than a size saved by default?
+  // For example, on x86 16 bytes XMM registers are saved by default.
+  static bool is_wide_vector(int size);
+
   // Save and restore a native result
   static void    save_native_result(MacroAssembler *_masm, BasicType ret_type, int frame_slots );
   static void restore_native_result(MacroAssembler *_masm, BasicType ret_type, int frame_slots );
@@ -453,13 +432,15 @@
   // convention (handlizes oops, etc), transitions to native, makes the call,
   // returns to java state (possibly blocking), unhandlizes any result and
   // returns.
-  static nmethod *generate_native_wrapper(MacroAssembler* masm,
+  //
+  // The wrapper may contain special-case code if the given method
+  // is a JNI critical method, or a compiled method handle adapter,
+  // such as _invokeBasic, _linkToVirtual, etc.
+  static nmethod* generate_native_wrapper(MacroAssembler* masm,
                                           methodHandle method,
                                           int compile_id,
-                                          int total_args_passed,
-                                          int max_arg,
-                                          BasicType *sig_bt,
-                                          VMRegPair *regs,
+                                          BasicType* sig_bt,
+                                          VMRegPair* regs,
                                           BasicType ret_type );
 
   // Block before entering a JNI critical method
@@ -610,7 +591,7 @@
 // used by the adapters.  The code generation happens here because it's very
 // similar to what the adapters have to do.
 
-class AdapterHandlerEntry : public BasicHashtableEntry {
+class AdapterHandlerEntry : public BasicHashtableEntry<mtCode> {
   friend class AdapterHandlerTable;
 
  private:
@@ -647,16 +628,17 @@
   AdapterHandlerEntry();
 
  public:
-  address get_i2c_entry()            { return _i2c_entry; }
-  address get_c2i_entry()            { return _c2i_entry; }
-  address get_c2i_unverified_entry() { return _c2i_unverified_entry; }
+  address get_i2c_entry()            const { return _i2c_entry; }
+  address get_c2i_entry()            const { return _c2i_entry; }
+  address get_c2i_unverified_entry() const { return _c2i_unverified_entry; }
 
+  address base_address();
   void relocate(address new_base);
 
-  AdapterFingerPrint* fingerprint()  { return _fingerprint; }
+  AdapterFingerPrint* fingerprint() const { return _fingerprint; }
 
   AdapterHandlerEntry* next() {
-    return (AdapterHandlerEntry*)BasicHashtableEntry::next();
+    return (AdapterHandlerEntry*)BasicHashtableEntry<mtCode>::next();
   }
 
 #ifdef ASSERT
@@ -665,7 +647,8 @@
   bool compare_code(unsigned char* code, int length, int total_args_passed, BasicType* sig_bt);
 #endif
 
-  void print();
+  //virtual void print_on(outputStream* st) const;  DO NOT USE
+  void print_adapter_on(outputStream* st) const;
 };
 
 class AdapterHandlerLibrary: public AllStatic {
diff --git a/hotspot/src/share/vm/runtime/signature.hpp b/hotspot/src/share/vm/runtime/signature.hpp
index 2d7a35d..6d211f0 100644
--- a/hotspot/src/share/vm/runtime/signature.hpp
+++ b/hotspot/src/share/vm/runtime/signature.hpp
@@ -396,6 +396,8 @@
   enum FailureMode { ReturnNull, CNFException, NCDFError };
   klassOop as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
   oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS);
+  const jbyte* raw_bytes()  { return _signature->bytes() + _begin; }
+  int          raw_length() { return _end - _begin; }
 
   // return same as_symbol except allocation of new symbols is avoided.
   Symbol* as_symbol_or_null();
diff --git a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
index 0ebc560..e9cd802 100644
--- a/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
+++ b/hotspot/src/share/vm/runtime/simpleThresholdPolicy.cpp
@@ -43,11 +43,11 @@
     mdo_invocations_start = mdh->invocation_count_start();
     mdo_backedges_start = mdh->backedge_count_start();
   }
-  tty->print(" %stotal: %d,%d %smdo: %d(%d),%d(%d)", prefix,
+  tty->print(" %stotal=%d,%d %smdo=%d(%d),%d(%d)", prefix,
       invocation_count, backedge_count, prefix,
       mdo_invocations, mdo_invocations_start,
       mdo_backedges, mdo_backedges_start);
-  tty->print(" %smax levels: %d,%d", prefix,
+  tty->print(" %smax levels=%d,%d", prefix,
       mh->highest_comp_level(), mh->highest_osr_comp_level());
 }
 
@@ -85,7 +85,7 @@
     tty->print("unknown");
   }
 
-  tty->print(" level: %d ", level);
+  tty->print(" level=%d ", level);
 
   ResourceMark rm;
   char *method_name = mh->name_and_sig_as_C_string();
@@ -95,8 +95,8 @@
     tty->print(" [%s]] ", inlinee_name);
   }
   else tty->print("] ");
-  tty->print("@%d queues: %d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile),
-                                       CompileBroker::queue_size(CompLevel_full_optimization));
+  tty->print("@%d queues=%d,%d", bci, CompileBroker::queue_size(CompLevel_full_profile),
+                                      CompileBroker::queue_size(CompLevel_full_optimization));
 
   print_specific(type, mh, imh, bci, level);
 
@@ -105,25 +105,30 @@
     if (inlinee_event) {
       print_counters("inlinee ", imh);
     }
-    tty->print(" compilable: ");
+    tty->print(" compilable=");
     bool need_comma = false;
     if (!mh->is_not_compilable(CompLevel_full_profile)) {
       tty->print("c1");
       need_comma = true;
     }
+    if (!mh->is_not_osr_compilable(CompLevel_full_profile)) {
+      if (need_comma) tty->print(",");
+      tty->print("c1-osr");
+      need_comma = true;
+    }
     if (!mh->is_not_compilable(CompLevel_full_optimization)) {
-      if (need_comma) tty->print(", ");
+      if (need_comma) tty->print(",");
       tty->print("c2");
       need_comma = true;
     }
-    if (!mh->is_not_osr_compilable()) {
-      if (need_comma) tty->print(", ");
-      tty->print("osr");
+    if (!mh->is_not_osr_compilable(CompLevel_full_optimization)) {
+      if (need_comma) tty->print(",");
+      tty->print("c2-osr");
     }
-    tty->print(" status:");
+    tty->print(" status=");
     if (mh->queued_for_compilation()) {
-      tty->print(" in queue");
-    } else tty->print(" idle");
+      tty->print("in-queue");
+    } else tty->print("idle");
   }
   tty->print_cr("]");
 }
@@ -223,7 +228,7 @@
     }
     return;
   }
-  if (bci != InvocationEntryBci && mh->is_not_osr_compilable()) {
+  if (bci != InvocationEntryBci && mh->is_not_osr_compilable(level)) {
     return;
   }
   if (!CompileBroker::compilation_is_in_queue(mh, bci)) {
diff --git a/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp b/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp
index bc81f5a..3fb5161 100644
--- a/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp
+++ b/hotspot/src/share/vm/runtime/stubCodeGenerator.hpp
@@ -36,7 +36,7 @@
 // Currently, code descriptors are simply chained in a linked list,
 // this may have to change if searching becomes too slow.
 
-class StubCodeDesc: public CHeapObj {
+class StubCodeDesc: public CHeapObj<mtCode> {
  protected:
   static StubCodeDesc* _list;                  // the list of all descriptors
   static int           _count;                 // length of list
diff --git a/hotspot/src/share/vm/runtime/stubRoutines.cpp b/hotspot/src/share/vm/runtime/stubRoutines.cpp
index f38173f..6991637 100644
--- a/hotspot/src/share/vm/runtime/stubRoutines.cpp
+++ b/hotspot/src/share/vm/runtime/stubRoutines.cpp
@@ -53,7 +53,6 @@
 address StubRoutines::_throw_IncompatibleClassChangeError_entry = NULL;
 address StubRoutines::_throw_NullPointerException_at_call_entry = NULL;
 address StubRoutines::_throw_StackOverflowError_entry           = NULL;
-address StubRoutines::_throw_WrongMethodTypeException_entry     = NULL;
 address StubRoutines::_handler_for_unsafe_access_entry          = NULL;
 jint    StubRoutines::_verify_oop_count                         = 0;
 address StubRoutines::_verify_oop_subroutine_entry              = NULL;
@@ -121,6 +120,10 @@
 address StubRoutines::_arrayof_jshort_fill;
 address StubRoutines::_arrayof_jint_fill;
 
+address StubRoutines::_aescrypt_encryptBlock               = NULL;
+address StubRoutines::_aescrypt_decryptBlock               = NULL;
+address StubRoutines::_cipherBlockChaining_encryptAESCrypt = NULL;
+address StubRoutines::_cipherBlockChaining_decryptAESCrypt = NULL;
 
 double (* StubRoutines::_intrinsic_log   )(double) = NULL;
 double (* StubRoutines::_intrinsic_log10 )(double) = NULL;
diff --git a/hotspot/src/share/vm/runtime/stubRoutines.hpp b/hotspot/src/share/vm/runtime/stubRoutines.hpp
index 8481dce..7c2146f 100644
--- a/hotspot/src/share/vm/runtime/stubRoutines.hpp
+++ b/hotspot/src/share/vm/runtime/stubRoutines.hpp
@@ -130,7 +130,6 @@
   static address _throw_IncompatibleClassChangeError_entry;
   static address _throw_NullPointerException_at_call_entry;
   static address _throw_StackOverflowError_entry;
-  static address _throw_WrongMethodTypeException_entry;
   static address _handler_for_unsafe_access_entry;
 
   static address _atomic_xchg_entry;
@@ -200,6 +199,11 @@
   // zero heap space aligned to jlong (8 bytes)
   static address _zero_aligned_words;
 
+  static address _aescrypt_encryptBlock;
+  static address _aescrypt_decryptBlock;
+  static address _cipherBlockChaining_encryptAESCrypt;
+  static address _cipherBlockChaining_decryptAESCrypt;
+
   // These are versions of the java.lang.Math methods which perform
   // the same operations as the intrinsic version.  They are used for
   // constant folding in the compiler to ensure equivalence.  If the
@@ -225,6 +229,9 @@
       (_code2 != NULL && _code2->blob_contains(addr)) ;
   }
 
+  static CodeBlob* code1() { return _code1; }
+  static CodeBlob* code2() { return _code2; }
+
   // Debugging
   static jint    verify_oop_count()                        { return _verify_oop_count; }
   static jint*   verify_oop_count_addr()                   { return &_verify_oop_count; }
@@ -254,7 +261,6 @@
   static address throw_IncompatibleClassChangeError_entry(){ return _throw_IncompatibleClassChangeError_entry; }
   static address throw_NullPointerException_at_call_entry(){ return _throw_NullPointerException_at_call_entry; }
   static address throw_StackOverflowError_entry()          { return _throw_StackOverflowError_entry; }
-  static address throw_WrongMethodTypeException_entry()    { return _throw_WrongMethodTypeException_entry; }
 
   // Exceptions during unsafe access - should throw Java exception rather
   // than crash.
@@ -329,6 +335,11 @@
   static address arrayof_jshort_fill() { return _arrayof_jshort_fill; }
   static address arrayof_jint_fill()   { return _arrayof_jint_fill; }
 
+  static address aescrypt_encryptBlock()                { return _aescrypt_encryptBlock; }
+  static address aescrypt_decryptBlock()                { return _aescrypt_decryptBlock; }
+  static address cipherBlockChaining_encryptAESCrypt()  { return _cipherBlockChaining_encryptAESCrypt; }
+  static address cipherBlockChaining_decryptAESCrypt()  { return _cipherBlockChaining_decryptAESCrypt; }
+
   static address select_fill_function(BasicType t, bool aligned, const char* &name);
 
   static address zero_aligned_words()   { return _zero_aligned_words; }
diff --git a/hotspot/src/share/vm/runtime/sweeper.cpp b/hotspot/src/share/vm/runtime/sweeper.cpp
index 7f8561b..2dea6d7 100644
--- a/hotspot/src/share/vm/runtime/sweeper.cpp
+++ b/hotspot/src/share/vm/runtime/sweeper.cpp
@@ -228,7 +228,7 @@
 #ifdef ASSERT
     if (LogSweeper && _records == NULL) {
       // Create the ring buffer for the logging code
-      _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries);
+      _records = NEW_C_HEAP_ARRAY(SweeperRecord, SweeperLogEntries, mtGC);
       memset(_records, 0, sizeof(SweeperRecord) * SweeperLogEntries);
     }
 #endif
diff --git a/hotspot/src/share/vm/runtime/task.cpp b/hotspot/src/share/vm/runtime/task.cpp
index bd45d65..689f385 100644
--- a/hotspot/src/share/vm/runtime/task.cpp
+++ b/hotspot/src/share/vm/runtime/task.cpp
@@ -61,7 +61,7 @@
 }
 #endif
 
-void PeriodicTask::real_time_tick(size_t delay_time) {
+void PeriodicTask::real_time_tick(int delay_time) {
 #ifndef PRODUCT
   if (ProfilerCheckIntervals) {
     _ticks++;
@@ -73,19 +73,39 @@
     _intervalHistogram[ms]++;
   }
 #endif
-  int orig_num_tasks = _num_tasks;
-  for(int index = 0; index < _num_tasks; index++) {
-    _tasks[index]->execute_if_pending(delay_time);
-    if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself
-      index--;  // re-do current slot as it has changed
-      orig_num_tasks = _num_tasks;
+
+  {
+    MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+    int orig_num_tasks = _num_tasks;
+
+    for(int index = 0; index < _num_tasks; index++) {
+      _tasks[index]->execute_if_pending(delay_time);
+      if (_num_tasks < orig_num_tasks) { // task dis-enrolled itself
+        index--;  // re-do current slot as it has changed
+        orig_num_tasks = _num_tasks;
+      }
     }
   }
 }
 
+int PeriodicTask::time_to_wait() {
+  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
+                     NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+
+  if (_num_tasks == 0) {
+    return 0; // sleep until shutdown or a task is enrolled
+  }
+
+  int delay = _tasks[0]->time_to_next_interval();
+  for (int index = 1; index < _num_tasks; index++) {
+    delay = MIN2(delay, _tasks[index]->time_to_next_interval());
+  }
+  return delay;
+}
+
 
 PeriodicTask::PeriodicTask(size_t interval_time) :
-  _counter(0), _interval(interval_time) {
+  _counter(0), _interval((int) interval_time) {
   // Sanity check the interval time
   assert(_interval >= PeriodicTask::min_interval &&
          _interval <= PeriodicTask::max_interval &&
@@ -94,33 +114,40 @@
 }
 
 PeriodicTask::~PeriodicTask() {
-  if (is_enrolled())
-    disenroll();
-}
-
-bool PeriodicTask::is_enrolled() const {
-  for(int index = 0; index < _num_tasks; index++)
-    if (_tasks[index] == this) return true;
-  return false;
+  disenroll();
 }
 
 void PeriodicTask::enroll() {
-  assert(WatcherThread::watcher_thread() == NULL, "dynamic enrollment of tasks not yet supported");
+  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
+                     NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
 
-  if (_num_tasks == PeriodicTask::max_tasks)
+  if (_num_tasks == PeriodicTask::max_tasks) {
     fatal("Overflow in PeriodicTask table");
+  }
   _tasks[_num_tasks++] = this;
+
+  WatcherThread* thread = WatcherThread::watcher_thread();
+  if (thread) {
+    thread->unpark();
+  } else {
+    WatcherThread::start();
+  }
 }
 
 void PeriodicTask::disenroll() {
-  assert(WatcherThread::watcher_thread() == NULL ||
-         Thread::current() == WatcherThread::watcher_thread(),
-         "dynamic disenrollment currently only handled from WatcherThread from within task() method");
+  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ?
+                     NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
 
   int index;
-  for(index = 0; index < _num_tasks && _tasks[index] != this; index++);
-  if (index == _num_tasks) return;
+  for(index = 0; index < _num_tasks && _tasks[index] != this; index++)
+    ;
+
+  if (index == _num_tasks) {
+    return;
+  }
+
   _num_tasks--;
+
   for (; index < _num_tasks; index++) {
     _tasks[index] = _tasks[index+1];
   }
diff --git a/hotspot/src/share/vm/runtime/task.hpp b/hotspot/src/share/vm/runtime/task.hpp
index 2357e83..4a967d5 100644
--- a/hotspot/src/share/vm/runtime/task.hpp
+++ b/hotspot/src/share/vm/runtime/task.hpp
@@ -35,7 +35,7 @@
 //   ...
 //   pf.disenroll();
 
-class PeriodicTask: public CHeapObj {
+class PeriodicTask: public CHeapObj<mtInternal> {
  public:
   // Useful constants.
   // The interval constants are used to ensure the declared interval
@@ -49,12 +49,12 @@
   static int num_tasks()   { return _num_tasks; }
 
  private:
-  size_t _counter;
-  const size_t _interval;
+  int _counter;
+  const int _interval;
 
   static int _num_tasks;
   static PeriodicTask* _tasks[PeriodicTask::max_tasks];
-  static void real_time_tick(size_t delay_time);
+  static void real_time_tick(int delay_time);
 
 #ifndef PRODUCT
   static elapsedTimer _timer;                      // measures time between ticks
@@ -69,51 +69,36 @@
   PeriodicTask(size_t interval_time); // interval is in milliseconds of elapsed time
   ~PeriodicTask();
 
-  // Tells whether is enrolled
-  bool is_enrolled() const;
-
   // Make the task active
-  // NOTE: this may only be called before the WatcherThread has been started
+  // For dynamic enrollment at the time T, the task will execute somewhere
+  // between T and T + interval_time.
   void enroll();
 
   // Make the task deactive
-  // NOTE: this may only be called either while the WatcherThread is
-  // inactive or by a task from within its task() method. One-shot or
-  // several-shot tasks may be implemented this way.
   void disenroll();
 
-  void execute_if_pending(size_t delay_time) {
-    _counter += delay_time;
-    if (_counter >= _interval) {
+  void execute_if_pending(int delay_time) {
+    // make sure we don't overflow
+    jlong tmp = (jlong) _counter + (jlong) delay_time;
+
+    if (tmp >= (jlong) _interval) {
       _counter = 0;
       task();
+    } else {
+      _counter += delay_time;
     }
   }
 
   // Returns how long (time in milliseconds) before the next time we should
   // execute this task.
-  size_t time_to_next_interval() const {
+  int time_to_next_interval() const {
     assert(_interval > _counter,  "task counter greater than interval?");
     return _interval - _counter;
   }
 
   // Calculate when the next periodic task will fire.
   // Called by the WatcherThread's run method.
-  // This assumes that periodic tasks aren't entering the system
-  // dynamically, except for during startup.
-  static size_t time_to_wait() {
-    if (_num_tasks == 0) {
-      // Don't wait any more; shut down the thread since we don't
-      // currently support dynamic enrollment.
-      return 0;
-    }
-
-    size_t delay = _tasks[0]->time_to_next_interval();
-    for (int index = 1; index < _num_tasks; index++) {
-      delay = MIN2(delay, _tasks[index]->time_to_next_interval());
-    }
-    return delay;
-  }
+  static int time_to_wait();
 
   // The task to perform at each period
   virtual void task() = 0;
diff --git a/hotspot/src/share/vm/runtime/thread.cpp b/hotspot/src/share/vm/runtime/thread.cpp
index 7676682..af0dbf3 100644
--- a/hotspot/src/share/vm/runtime/thread.cpp
+++ b/hotspot/src/share/vm/runtime/thread.cpp
@@ -73,6 +73,7 @@
 #include "runtime/vm_operations.hpp"
 #include "services/attachListener.hpp"
 #include "services/management.hpp"
+#include "services/memTracker.hpp"
 #include "services/threadService.hpp"
 #include "trace/traceEventTypes.hpp"
 #include "utilities/defaultStream.hpp"
@@ -159,6 +160,7 @@
 
 #endif // ndef DTRACE_ENABLED
 
+
 // Class hierarchy
 // - Thread
 //   - VMThread
@@ -168,13 +170,13 @@
 //     - CompilerThread
 
 // ======= Thread ========
-
 // Support for forcing alignment of thread objects for biased locking
-void* Thread::operator new(size_t size) {
+void* Thread::allocate(size_t size, bool throw_excpt, MEMFLAGS flags) {
   if (UseBiasedLocking) {
     const int alignment = markOopDesc::biased_lock_alignment;
     size_t aligned_size = size + (alignment - sizeof(intptr_t));
-    void* real_malloc_addr = CHeapObj::operator new(aligned_size);
+    void* real_malloc_addr = throw_excpt? AllocateHeap(aligned_size, flags, CURRENT_PC)
+                                          : os::malloc(aligned_size, flags, CURRENT_PC);
     void* aligned_addr     = (void*) align_size_up((intptr_t) real_malloc_addr, alignment);
     assert(((uintptr_t) aligned_addr + (uintptr_t) size) <=
            ((uintptr_t) real_malloc_addr + (uintptr_t) aligned_size),
@@ -187,16 +189,17 @@
     ((Thread*) aligned_addr)->_real_malloc_address = real_malloc_addr;
     return aligned_addr;
   } else {
-    return CHeapObj::operator new(size);
+    return throw_excpt? AllocateHeap(size, flags, CURRENT_PC)
+                       : os::malloc(size, flags, CURRENT_PC);
   }
 }
 
 void Thread::operator delete(void* p) {
   if (UseBiasedLocking) {
     void* real_malloc_addr = ((Thread*) p)->_real_malloc_address;
-    CHeapObj::operator delete(real_malloc_addr);
+    FreeHeap(real_malloc_addr, mtThread);
   } else {
-    CHeapObj::operator delete(p);
+    FreeHeap(p, mtThread);
   }
 }
 
@@ -214,8 +217,8 @@
 
   // allocated data structures
   set_osthread(NULL);
-  set_resource_area(new ResourceArea());
-  set_handle_area(new HandleArea(NULL));
+  set_resource_area(new (mtThread)ResourceArea());
+  set_handle_area(new (mtThread) HandleArea(NULL));
   set_active_handles(NULL);
   set_free_handle_block(NULL);
   set_last_handle_mark(NULL);
@@ -303,15 +306,25 @@
 
   // initialize structure dependent on thread local storage
   ThreadLocalStorage::set_thread(this);
-
-  // set up any platform-specific state.
-  os::initialize_thread();
-
 }
 
 void Thread::record_stack_base_and_size() {
   set_stack_base(os::current_stack_base());
   set_stack_size(os::current_stack_size());
+  // CR 7190089: on Solaris, primordial thread's stack is adjusted
+  // in initialize_thread(). Without the adjustment, stack size is
+  // incorrect if stack is set to unlimited (ulimit -s unlimited).
+  // So far, only Solaris has real implementation of initialize_thread().
+  //
+  // set up any platform-specific state.
+  os::initialize_thread(this);
+
+   // record thread's native stack, stack grows downward
+  if (MemTracker::is_on()) {
+    address stack_low_addr = stack_base() - stack_size();
+    MemTracker::record_thread_stack(stack_low_addr, stack_size(), this,
+      CURRENT_PC);
+  }
 }
 
 
@@ -319,6 +332,18 @@
   // Reclaim the objectmonitors from the omFreeList of the moribund thread.
   ObjectSynchronizer::omFlush (this) ;
 
+  // stack_base can be NULL if the thread is never started or exited before
+  // record_stack_base_and_size called. Although, we would like to ensure
+  // that all started threads do call record_stack_base_and_size(), there is
+  // not proper way to enforce that.
+  if (_stack_base != NULL) {
+    address low_stack_addr = stack_base() - stack_size();
+    MemTracker::release_thread_stack(low_stack_addr, stack_size(), this);
+#ifdef ASSERT
+    set_stack_base(NULL);
+#endif
+  }
+
   // deallocate data structures
   delete resource_area();
   // since the handle marks are using the handle area, we have to deallocated the root
@@ -996,6 +1021,51 @@
                                          vmSymbols::void_method_signature(), CHECK);
 }
 
+char java_runtime_name[128] = "";
+char java_runtime_version[128] = "";
+
+// extract the JRE name from sun.misc.Version.java_runtime_name
+static const char* get_java_runtime_name(TRAPS) {
+  klassOop k = SystemDictionary::find(vmSymbols::sun_misc_Version(),
+                                      Handle(), Handle(), CHECK_AND_CLEAR_NULL);
+  fieldDescriptor fd;
+  bool found = k != NULL &&
+               instanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_name_name(),
+                                                        vmSymbols::string_signature(), &fd);
+  if (found) {
+    oop name_oop = k->java_mirror()->obj_field(fd.offset());
+    if (name_oop == NULL)
+      return NULL;
+    const char* name = java_lang_String::as_utf8_string(name_oop,
+                                                        java_runtime_name,
+                                                        sizeof(java_runtime_name));
+    return name;
+  } else {
+    return NULL;
+  }
+}
+
+// extract the JRE version from sun.misc.Version.java_runtime_version
+static const char* get_java_runtime_version(TRAPS) {
+  klassOop k = SystemDictionary::find(vmSymbols::sun_misc_Version(),
+                                      Handle(), Handle(), CHECK_AND_CLEAR_NULL);
+  fieldDescriptor fd;
+  bool found = k != NULL &&
+               instanceKlass::cast(k)->find_local_field(vmSymbols::java_runtime_version_name(),
+                                                        vmSymbols::string_signature(), &fd);
+  if (found) {
+    oop name_oop = k->java_mirror()->obj_field(fd.offset());
+    if (name_oop == NULL)
+      return NULL;
+    const char* name = java_lang_String::as_utf8_string(name_oop,
+                                                        java_runtime_version,
+                                                        sizeof(java_runtime_version));
+    return name;
+  } else {
+    return NULL;
+  }
+}
+
 // General purpose hook into Java code, run once when the VM is initialized.
 // The Java library method itself may be changed independently from the VM.
 static void call_postVMInitHook(TRAPS) {
@@ -1105,14 +1175,14 @@
 
 NamedThread::~NamedThread() {
   if (_name != NULL) {
-    FREE_C_HEAP_ARRAY(char, _name);
+    FREE_C_HEAP_ARRAY(char, _name, mtThread);
     _name = NULL;
   }
 }
 
 void NamedThread::set_name(const char* format, ...) {
   guarantee(_name == NULL, "Only get to set name once.");
-  _name = NEW_C_HEAP_ARRAY(char, max_name_len);
+  _name = NEW_C_HEAP_ARRAY(char, max_name_len, mtThread);
   guarantee(_name != NULL, "alloc failure");
   va_list ap;
   va_start(ap, format);
@@ -1127,6 +1197,7 @@
 // timer interrupts exists on the platform.
 
 WatcherThread* WatcherThread::_watcher_thread   = NULL;
+bool WatcherThread::_startable = false;
 volatile bool  WatcherThread::_should_terminate = false;
 
 WatcherThread::WatcherThread() : Thread() {
@@ -1147,6 +1218,55 @@
   }
 }
 
+int WatcherThread::sleep() const {
+  MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+
+  // remaining will be zero if there are no tasks,
+  // causing the WatcherThread to sleep until a task is
+  // enrolled
+  int remaining = PeriodicTask::time_to_wait();
+  int time_slept = 0;
+
+  // we expect this to timeout - we only ever get unparked when
+  // we should terminate or when a new task has been enrolled
+  OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */);
+
+  jlong time_before_loop = os::javaTimeNanos();
+
+  for (;;) {
+    bool timedout = PeriodicTask_lock->wait(Mutex::_no_safepoint_check_flag, remaining);
+    jlong now = os::javaTimeNanos();
+
+    if (remaining == 0) {
+        // if we didn't have any tasks we could have waited for a long time
+        // consider the time_slept zero and reset time_before_loop
+        time_slept = 0;
+        time_before_loop = now;
+    } else {
+        // need to recalulate since we might have new tasks in _tasks
+        time_slept = (int) ((now - time_before_loop) / 1000000);
+    }
+
+    // Change to task list or spurious wakeup of some kind
+    if (timedout || _should_terminate) {
+        break;
+    }
+
+    remaining = PeriodicTask::time_to_wait();
+    if (remaining == 0) {
+        // Last task was just disenrolled so loop around and wait until
+        // another task gets enrolled
+        continue;
+    }
+
+    remaining -= time_slept;
+    if (remaining <= 0)
+      break;
+  }
+
+  return time_slept;
+}
+
 void WatcherThread::run() {
   assert(this == watcher_thread(), "just checking");
 
@@ -1159,26 +1279,7 @@
 
     // Calculate how long it'll be until the next PeriodicTask work
     // should be done, and sleep that amount of time.
-    size_t time_to_wait = PeriodicTask::time_to_wait();
-
-    // we expect this to timeout - we only ever get unparked when
-    // we should terminate
-    {
-      OSThreadWaitState osts(this->osthread(), false /* not Object.wait() */);
-
-      jlong prev_time = os::javaTimeNanos();
-      for (;;) {
-        int res= _SleepEvent->park(time_to_wait);
-        if (res == OS_TIMEOUT || _should_terminate)
-          break;
-        // spurious wakeup of some kind
-        jlong now = os::javaTimeNanos();
-        time_to_wait -= (now - prev_time) / 1000000;
-        if (time_to_wait <= 0)
-          break;
-        prev_time = now;
-      }
-    }
+    int time_waited = sleep();
 
     if (is_error_reported()) {
       // A fatal error has happened, the error handler(VMError::report_and_die)
@@ -1208,13 +1309,7 @@
       }
     }
 
-    PeriodicTask::real_time_tick(time_to_wait);
-
-    // If we have no more tasks left due to dynamic disenrollment,
-    // shut down the thread since we don't currently support dynamic enrollment
-    if (PeriodicTask::num_tasks() == 0) {
-      _should_terminate = true;
-    }
+    PeriodicTask::real_time_tick(time_waited);
   }
 
   // Signal that it is terminated
@@ -1229,22 +1324,33 @@
 }
 
 void WatcherThread::start() {
-  if (watcher_thread() == NULL) {
+  assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
+
+  if (watcher_thread() == NULL && _startable) {
     _should_terminate = false;
     // Create the single instance of WatcherThread
     new WatcherThread();
   }
 }
 
+void WatcherThread::make_startable() {
+  assert(PeriodicTask_lock->owned_by_self(), "PeriodicTask_lock required");
+  _startable = true;
+}
+
 void WatcherThread::stop() {
+  {
+    MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+    _should_terminate = true;
+    OrderAccess::fence();  // ensure WatcherThread sees update in main loop
+
+    WatcherThread* watcher = watcher_thread();
+    if (watcher != NULL)
+      watcher->unpark();
+  }
+
   // it is ok to take late safepoints here, if needed
   MutexLocker mu(Terminator_lock);
-  _should_terminate = true;
-  OrderAccess::fence();  // ensure WatcherThread sees update in main loop
-
-  Thread* watcher = watcher_thread();
-  if (watcher != NULL)
-    watcher->_SleepEvent->unpark();
 
   while(watcher_thread() != NULL) {
     // This wait should make safepoint checks, wait without a timeout,
@@ -1262,6 +1368,11 @@
   }
 }
 
+void WatcherThread::unpark() {
+  MutexLockerEx ml(PeriodicTask_lock->owned_by_self() ? NULL : PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+  PeriodicTask_lock->notify();
+}
+
 void WatcherThread::print_on(outputStream* st) const {
   st->print("\"%s\" ", name());
   Thread::print_on(st);
@@ -1295,6 +1406,7 @@
   set_monitor_chunks(NULL);
   set_next(NULL);
   set_thread_state(_thread_new);
+  set_recorder(NULL);
   _terminated = _not_terminated;
   _privileged_stack_top = NULL;
   _array_for_gc = NULL;
@@ -1370,6 +1482,7 @@
     _jni_attach_state = _not_attaching_via_jni;
   }
   assert(_deferred_card_mark.is_empty(), "Default MemRegion ctor");
+  _safepoint_visible = false;
 }
 
 bool JavaThread::reguard_stack(address cur_sp) {
@@ -1432,7 +1545,7 @@
   thr_type = entry_point == &compiler_thread_entry ? os::compiler_thread :
                                                      os::java_thread;
   os::create_thread(this, thr_type, stack_sz);
-
+  _safepoint_visible = false;
   // The _osthread may be NULL here because we ran out of memory (too many threads active).
   // We need to throw and OutOfMemoryError - however we cannot do this here because the caller
   // may hold a lock and all locks must be unlocked before throwing the exception (throwing
@@ -1450,6 +1563,13 @@
       tty->print_cr("terminate thread %p", this);
   }
 
+  // By now, this thread should already be invisible to safepoint,
+  // and its per-thread recorder also collected.
+  assert(!is_safepoint_visible(), "wrong state");
+#if INCLUDE_NMT
+  assert(get_recorder() == NULL, "Already collected");
+#endif // INCLUDE_NMT
+
   // JSR166 -- return the parker to the free list
   Parker::Release(_parker);
   _parker = NULL ;
@@ -2349,6 +2469,7 @@
 }
 
 void JavaThread::remove_stack_guard_pages() {
+  assert(Thread::current() == this, "from different thread");
   if (_stack_guard_state == stack_guard_unused) return;
   address low_addr = stack_base() - stack_size();
   size_t len = (StackYellowPages + StackRedPages) * os::vm_page_size();
@@ -2514,6 +2635,12 @@
   StackFrameStream fst(this, UseBiasedLocking);
   for(; !fst.is_done(); fst.next()) {
     if (fst.current()->should_be_deoptimized()) {
+      if (LogCompilation && xtty != NULL) {
+        nmethod* nm = fst.current()->cb()->as_nmethod_or_null();
+        xtty->elem("deoptimized thread='" UINTX_FORMAT "' compile_id='%d'",
+                   this->name(), nm != NULL ? nm->compile_id() : -1);
+      }
+
       Deoptimization::deoptimize(this, *fst.current(), fst.register_map());
     }
   }
@@ -2892,7 +3019,7 @@
 void JavaThread::popframe_preserve_args(ByteSize size_in_bytes, void* start) {
   assert(_popframe_preserved_args == NULL, "should not wipe out old PopFrame preserved arguments");
   if (in_bytes(size_in_bytes) != 0) {
-    _popframe_preserved_args = NEW_C_HEAP_ARRAY(char, in_bytes(size_in_bytes));
+    _popframe_preserved_args = NEW_C_HEAP_ARRAY(char, in_bytes(size_in_bytes), mtThread);
     _popframe_preserved_args_size = in_bytes(size_in_bytes);
     Copy::conjoint_jbytes(start, _popframe_preserved_args, _popframe_preserved_args_size);
   }
@@ -2914,7 +3041,7 @@
 
 void JavaThread::popframe_free_preserved_args() {
   assert(_popframe_preserved_args != NULL, "should not free PopFrame preserved arguments twice");
-  FREE_C_HEAP_ARRAY(char, (char*) _popframe_preserved_args);
+  FREE_C_HEAP_ARRAY(char, (char*) _popframe_preserved_args, mtThread);
   _popframe_preserved_args = NULL;
   _popframe_preserved_args_size = 0;
 }
@@ -3163,6 +3290,14 @@
   jint os_init_2_result = os::init_2();
   if (os_init_2_result != JNI_OK) return os_init_2_result;
 
+  // intialize TLS
+  ThreadLocalStorage::init();
+
+  // Bootstrap native memory tracking, so it can start recording memory
+  // activities before worker thread is started. This is the first phase
+  // of bootstrapping, VM is currently running in single-thread mode.
+  MemTracker::bootstrap_single_thread();
+
   // Initialize output stream logging
   ostream_init_log();
 
@@ -3182,9 +3317,6 @@
   _number_of_threads = 0;
   _number_of_non_daemon_threads = 0;
 
-  // Initialize TLS
-  ThreadLocalStorage::init();
-
   // Initialize global data structures and create system classes in heap
   vm_init_globals();
 
@@ -3216,6 +3348,9 @@
   // Initialize Java-Level synchronization subsystem
   ObjectMonitor::Initialize() ;
 
+  // Second phase of bootstrapping, VM is about entering multi-thread mode
+  MemTracker::bootstrap_multi_thread();
+
   // Initialize global modules
   jint status = init_globals();
   if (status != JNI_OK) {
@@ -3243,6 +3378,9 @@
     Universe::verify();   // make sure we're starting with a clean slate
   }
 
+  // Fully start NMT
+  MemTracker::start();
+
   // Create the VMThread
   { TraceTime timer("Start VMThread", TraceStartupTime);
     VMThread::create();
@@ -3352,6 +3490,10 @@
       // The VM creates & returns objects of this class. Make sure it's initialized.
       initialize_class(vmSymbols::java_lang_Class(), CHECK_0);
       call_initializeSystemClass(CHECK_0);
+
+      // get the Java runtime name after java.lang.System is initialized
+      JDK_Version::set_runtime_name(get_java_runtime_name(THREAD));
+      JDK_Version::set_runtime_version(get_java_runtime_version(THREAD));
     } else {
       warning("java.lang.System not initialized");
     }
@@ -3468,13 +3610,13 @@
     create_vm_init_libraries();
   }
 
+  // Notify JVMTI agents that VM initialization is complete - nop if no agents.
+  JvmtiExport::post_vm_initialized();
+
   if (!TRACE_START()) {
     vm_exit_during_initialization(Handle(THREAD, PENDING_EXCEPTION));
   }
 
-  // Notify JVMTI agents that VM initialization is complete - nop if no agents.
-  JvmtiExport::post_vm_initialized();
-
   if (CleanChunkPoolAsync) {
     Chunk::start_chunk_pool_cleaner_task();
   }
@@ -3507,12 +3649,18 @@
     }
   }
 
-  // Start up the WatcherThread if there are any periodic tasks
-  // NOTE:  All PeriodicTasks should be registered by now. If they
-  //   aren't, late joiners might appear to start slowly (we might
-  //   take a while to process their first tick).
-  if (PeriodicTask::num_tasks() > 0) {
-    WatcherThread::start();
+  {
+      MutexLockerEx ml(PeriodicTask_lock, Mutex::_no_safepoint_check_flag);
+      // Make sure the watcher thread can be started by WatcherThread::start()
+      // or by dynamic enrollment.
+      WatcherThread::make_startable();
+      // Start up the WatcherThread if there are any periodic tasks
+      // NOTE:  All PeriodicTasks should be registered by now. If they
+      //   aren't, late joiners might appear to start slowly (we might
+      //   take a while to process their first tick).
+      if (PeriodicTask::num_tasks() > 0) {
+          WatcherThread::start();
+      }
   }
 
   // Give os specific code one last chance to start
@@ -3544,11 +3692,11 @@
       if (library == NULL) {
         const char *sub_msg = " in absolute path, with error: ";
         size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
-        char *buf = NEW_C_HEAP_ARRAY(char, len);
+        char *buf = NEW_C_HEAP_ARRAY(char, len, mtThread);
         jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
         // If we can't find the agent, exit.
         vm_exit_during_initialization(buf, NULL);
-        FREE_C_HEAP_ARRAY(char, buf);
+        FREE_C_HEAP_ARRAY(char, buf, mtThread);
       }
     } else {
       // Try to load the agent from the standard dll directory
@@ -3562,7 +3710,7 @@
         const char *fmt   = "%s/bin/java %s -Dkernel.background.download=false"
                       " sun.jkernel.DownloadManager -download client_jvm";
         size_t length = strlen(props) + strlen(home) + strlen(fmt) + 1;
-        char *cmd = NEW_C_HEAP_ARRAY(char, length);
+        char *cmd = NEW_C_HEAP_ARRAY(char, length, mtThread);
         jio_snprintf(cmd, length, fmt, home, props);
         int status = os::fork_and_exec(cmd);
         FreeHeap(props);
@@ -3571,7 +3719,7 @@
           vm_exit_during_initialization("fork_and_exec failed: %s",
                                          strerror(errno));
         }
-        FREE_C_HEAP_ARRAY(char, cmd);
+        FREE_C_HEAP_ARRAY(char, cmd, mtThread);
         // when this comes back the instrument.dll should be where it belongs.
         library = os::dll_load(buffer, ebuf, sizeof ebuf);
       }
@@ -3583,11 +3731,11 @@
         if (library == NULL) {
           const char *sub_msg = " on the library path, with error: ";
           size_t len = strlen(msg) + strlen(name) + strlen(sub_msg) + strlen(ebuf) + 1;
-          char *buf = NEW_C_HEAP_ARRAY(char, len);
+          char *buf = NEW_C_HEAP_ARRAY(char, len, mtThread);
           jio_snprintf(buf, len, "%s%s%s%s", msg, name, sub_msg, ebuf);
           // If we can't find the agent, exit.
           vm_exit_during_initialization(buf, NULL);
-          FREE_C_HEAP_ARRAY(char, buf);
+          FREE_C_HEAP_ARRAY(char, buf, mtThread);
         }
       }
     }
@@ -3756,6 +3904,7 @@
 // and VM_Exit op at VM level.
 //
 // Shutdown sequence:
+//   + Shutdown native memory tracking if it is on
 //   + Wait until we are the last non-daemon thread to execute
 //     <-- every thing is still working at this moment -->
 //   + Call java.lang.Shutdown.shutdown(), which will invoke Java level
@@ -3801,6 +3950,10 @@
                          Mutex::_as_suspend_equivalent_flag);
   }
 
+  // Shutdown NMT before exit. Otherwise,
+  // it will run into trouble when system destroys static variables.
+  MemTracker::shutdown(MemTracker::NMT_normal);
+
   // Hang forever on exit if we are reporting an error.
   if (ShowMessageBoxOnError && is_error_reported()) {
     os::infinite_sleep();
@@ -3907,6 +4060,8 @@
     daemon = false;
   }
 
+  p->set_safepoint_visible(true);
+
   ThreadService::add_thread(p, daemon);
 
   // Possible GC point.
@@ -3952,6 +4107,13 @@
     // to do callbacks into the safepoint code. However, the safepoint code is not aware
     // of this thread since it is removed from the queue.
     p->set_terminated_value();
+
+    // Now, this thread is not visible to safepoint
+    p->set_safepoint_visible(false);
+    // once the thread becomes safepoint invisible, we can not use its per-thread
+    // recorder. And Threads::do_threads() no longer walks this thread, so we have
+    // to release its per-thread recorder here.
+    MemTracker::thread_exiting(p);
   } // unlock Threads_lock
 
   // Since Events::log uses a lock, we grab it outside the Threads_lock
diff --git a/hotspot/src/share/vm/runtime/thread.hpp b/hotspot/src/share/vm/runtime/thread.hpp
index 7846cc0..86a1dd6 100644
--- a/hotspot/src/share/vm/runtime/thread.hpp
+++ b/hotspot/src/share/vm/runtime/thread.hpp
@@ -41,6 +41,7 @@
 #include "runtime/stubRoutines.hpp"
 #include "runtime/threadLocalStorage.hpp"
 #include "runtime/unhandledOops.hpp"
+#include "services/memRecorder.hpp"
 #include "trace/tracing.hpp"
 #include "utilities/exceptions.hpp"
 #include "utilities/top.hpp"
@@ -100,12 +101,16 @@
   //oop       _pending_exception;                // pending exception for current thread
   // const char* _exception_file;                   // file information for exception (debugging only)
   // int         _exception_line;                   // line information for exception (debugging only)
-
+ protected:
   // Support for forcing alignment of thread objects for biased locking
   void*       _real_malloc_address;
  public:
-  void* operator new(size_t size);
+  void* operator new(size_t size) { return allocate(size, true); }
+  void* operator new(size_t size, std::nothrow_t& nothrow_constant) { return allocate(size, false); }
   void  operator delete(void* p);
+
+ protected:
+   static void* allocate(size_t size, bool throw_excpt, MEMFLAGS flags = mtThread);
  private:
 
   // ***************************************************************
@@ -548,7 +553,6 @@
   virtual void print_on_error(outputStream* st, char* buf, int buflen) const;
 
   // Debug-only code
-
 #ifdef ASSERT
  private:
   // Deadlock detection support for Mutex locks. List of locks own by thread.
@@ -707,6 +711,7 @@
  private:
   static WatcherThread* _watcher_thread;
 
+  static bool _startable;
   volatile static bool _should_terminate; // updated without holding lock
  public:
   enum SomeConstants {
@@ -723,6 +728,7 @@
   char* name() const { return (char*)"VM Periodic Task Thread"; }
   void print_on(outputStream* st) const;
   void print() const { print_on(tty); }
+  void unpark();
 
   // Returns the single instance of WatcherThread
   static WatcherThread* watcher_thread()         { return _watcher_thread; }
@@ -730,6 +736,12 @@
   // Create and start the single instance of WatcherThread, or stop it on shutdown
   static void start();
   static void stop();
+  // Only allow start once the VM is sufficiently initialized
+  // Otherwise the first task to enroll will trigger the start
+  static void make_startable();
+
+ private:
+  int sleep() const;
 };
 
 
@@ -1027,9 +1039,15 @@
   bool do_not_unlock_if_synchronized()             { return _do_not_unlock_if_synchronized; }
   void set_do_not_unlock_if_synchronized(bool val) { _do_not_unlock_if_synchronized = val; }
 
+  // native memory tracking
+  inline MemRecorder* get_recorder() const          { return (MemRecorder*)_recorder; }
+  inline void         set_recorder(MemRecorder* rc) { _recorder = (volatile MemRecorder*)rc; }
+
+ private:
+  // per-thread memory recorder
+  volatile MemRecorder* _recorder;
 
   // Suspend/resume support for JavaThread
-
  private:
   void set_ext_suspended()       { set_suspend_flag (_ext_suspended);  }
   void clear_ext_suspended()     { clear_suspend_flag(_ext_suspended); }
@@ -1453,6 +1471,18 @@
      return result;
    }
 
+ // NMT (Native memory tracking) support.
+ // This flag helps NMT to determine if this JavaThread will be blocked
+ // at safepoint. If not, ThreadCritical is needed for writing memory records.
+ // JavaThread is only safepoint visible when it is in Threads' thread list,
+ // it is not visible until it is added to the list and becomes invisible
+ // once it is removed from the list.
+ public:
+  bool is_safepoint_visible() const { return _safepoint_visible; }
+  void set_safepoint_visible(bool visible) { _safepoint_visible = visible; }
+ private:
+  bool _safepoint_visible;
+
   // Static operations
  public:
   // Returns the running thread as a JavaThread
diff --git a/hotspot/src/share/vm/runtime/timer.cpp b/hotspot/src/share/vm/runtime/timer.cpp
index ea05533..8382626 100644
--- a/hotspot/src/share/vm/runtime/timer.cpp
+++ b/hotspot/src/share/vm/runtime/timer.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -120,10 +120,7 @@
 
   if (_active) {
     _accum = NULL;
-    if (PrintGCTimeStamps) {
-      _logfile->stamp();
-      _logfile->print(": ");
-    }
+    _logfile->stamp(PrintGCTimeStamps);
     _logfile->print("[%s", title);
     _logfile->flush();
     _t.start();
@@ -141,10 +138,7 @@
   _logfile = (logfile != NULL) ? logfile : tty;
   if (_active) {
     if (_verbose) {
-      if (PrintGCTimeStamps) {
-        _logfile->stamp();
-        _logfile->print(": ");
-      }
+      _logfile->stamp(PrintGCTimeStamps);
       _logfile->print("[%s", title);
       _logfile->flush();
     }
@@ -216,8 +210,9 @@
     } else {
       _logfile->print("[Error in TraceCPUTime]");
     }
-     if (_print_cr) {
+    if (_print_cr) {
       _logfile->print_cr("");
     }
+    _logfile->flush();
   }
 }
diff --git a/hotspot/src/share/vm/runtime/unhandledOops.cpp b/hotspot/src/share/vm/runtime/unhandledOops.cpp
index 9b7211c..3216da1 100644
--- a/hotspot/src/share/vm/runtime/unhandledOops.cpp
+++ b/hotspot/src/share/vm/runtime/unhandledOops.cpp
@@ -37,7 +37,7 @@
 
 UnhandledOops::UnhandledOops(Thread* thread) {
   _thread = thread;
-  _oop_list = new (ResourceObj::C_HEAP)
+  _oop_list = new (ResourceObj::C_HEAP, mtInternal)
                     GrowableArray<UnhandledOopEntry>(free_list_size, true);
   _level = 0;
 }
diff --git a/hotspot/src/share/vm/runtime/vframe.cpp b/hotspot/src/share/vm/runtime/vframe.cpp
index 323d735..09e324f 100644
--- a/hotspot/src/share/vm/runtime/vframe.cpp
+++ b/hotspot/src/share/vm/runtime/vframe.cpp
@@ -410,8 +410,9 @@
               Klass::cast(method()->method_holder())
                  ->is_subclass_of(SystemDictionary::reflect_MethodAccessorImpl_klass())) {
       // This is an auxilary frame -- skip it
-    } else if (method()->is_method_handle_adapter()) {
-      // This is an internal adapter frame from the MethodHandleCompiler -- skip it
+    } else if (method()->is_method_handle_intrinsic() ||
+               method()->is_compiled_lambda_form()) {
+      // This is an internal adapter frame for method handles -- skip it
     } else {
       // This is non-excluded frame, we need to count it against the depth
       if (depth-- <= 0) {
diff --git a/hotspot/src/share/vm/runtime/vframeArray.cpp b/hotspot/src/share/vm/runtime/vframeArray.cpp
index 52b0809..a5faf37 100644
--- a/hotspot/src/share/vm/runtime/vframeArray.cpp
+++ b/hotspot/src/share/vm/runtime/vframeArray.cpp
@@ -24,6 +24,7 @@
 
 #include "precompiled.hpp"
 #include "classfile/vmSymbols.hpp"
+#include "interpreter/bytecode.hpp"
 #include "interpreter/interpreter.hpp"
 #include "memory/allocation.inline.hpp"
 #include "memory/resourceArea.hpp"
@@ -443,7 +444,7 @@
   // Allocate the vframeArray
   vframeArray * result = (vframeArray*) AllocateHeap(sizeof(vframeArray) + // fixed part
                                                      sizeof(vframeArrayElement) * (chunk->length() - 1), // variable part
-                                                     "vframeArray::allocate");
+                                                     mtCompiler);
   result->_frames = chunk->length();
   result->_owner_thread = thread;
   result->_sender = sender;
@@ -510,7 +511,8 @@
   //  in the above picture.
 
   // Find the skeletal interpreter frames to unpack into
-  RegisterMap map(JavaThread::current(), false);
+  JavaThread* THREAD = JavaThread::current();
+  RegisterMap map(THREAD, false);
   // Get the youngest frame we will unpack (last to be unpacked)
   frame me = unpack_frame.sender(&map);
   int index;
@@ -520,29 +522,37 @@
     me = me.sender(&map);
   }
 
-  frame caller_frame = me;
-
   // Do the unpacking of interpreter frames; the frame at index 0 represents the top activation, so it has no callee
-
   // Unpack the frames from the oldest (frames() -1) to the youngest (0)
-
+  frame caller_frame = me;
   for (index = frames() - 1; index >= 0 ; index--) {
-    int callee_parameters = index == 0 ? 0 : element(index-1)->method()->size_of_parameters();
-    int callee_locals     = index == 0 ? 0 : element(index-1)->method()->max_locals();
-    element(index)->unpack_on_stack(caller_actual_parameters,
-                                    callee_parameters,
-                                    callee_locals,
-                                    &caller_frame,
-                                    index == 0,
-                                    exec_mode);
-    if (index == frames() - 1) {
-      Deoptimization::unwind_callee_save_values(element(index)->iframe(), this);
+    vframeArrayElement* elem = element(index);  // caller
+    int callee_parameters, callee_locals;
+    if (index == 0) {
+      callee_parameters = callee_locals = 0;
+    } else {
+      methodHandle caller = elem->method();
+      methodHandle callee = element(index - 1)->method();
+      Bytecode_invoke inv(caller, elem->bci());
+      // invokedynamic instructions don't have a class but obviously don't have a MemberName appendix.
+      // NOTE:  Use machinery here that avoids resolving of any kind.
+      const bool has_member_arg =
+          !inv.is_invokedynamic() && MethodHandles::has_member_arg(inv.klass(), inv.name());
+      callee_parameters = callee->size_of_parameters() + (has_member_arg ? 1 : 0);
+      callee_locals     = callee->max_locals();
     }
-    caller_frame = *element(index)->iframe();
+    elem->unpack_on_stack(caller_actual_parameters,
+                          callee_parameters,
+                          callee_locals,
+                          &caller_frame,
+                          index == 0,
+                          exec_mode);
+    if (index == frames() - 1) {
+      Deoptimization::unwind_callee_save_values(elem->iframe(), this);
+    }
+    caller_frame = *elem->iframe();
     caller_actual_parameters = callee_parameters;
   }
-
-
   deallocate_monitor_chunks();
 }
 
diff --git a/hotspot/src/share/vm/runtime/vframeArray.hpp b/hotspot/src/share/vm/runtime/vframeArray.hpp
index 6f8d436..2eeeb39 100644
--- a/hotspot/src/share/vm/runtime/vframeArray.hpp
+++ b/hotspot/src/share/vm/runtime/vframeArray.hpp
@@ -108,7 +108,7 @@
 // but it does make debugging easier even if we can't look
 // at the data in each vframeElement
 
-class vframeArray: public CHeapObj {
+class vframeArray: public CHeapObj<mtCompiler> {
   friend class VMStructs;
 
  private:
diff --git a/hotspot/src/share/vm/runtime/vframe_hp.cpp b/hotspot/src/share/vm/runtime/vframe_hp.cpp
index 274bfc6..4f63575 100644
--- a/hotspot/src/share/vm/runtime/vframe_hp.cpp
+++ b/hotspot/src/share/vm/runtime/vframe_hp.cpp
@@ -154,7 +154,7 @@
   } else {
     // No deferred updates pending for this thread.
     // allocate in C heap
-    deferred =  new(ResourceObj::C_HEAP) GrowableArray<jvmtiDeferredLocalVariableSet*> (1, true);
+    deferred =  new(ResourceObj::C_HEAP, mtCompiler) GrowableArray<jvmtiDeferredLocalVariableSet*> (1, true);
     thread()->set_deferred_locals(deferred);
   }
   deferred->push(new jvmtiDeferredLocalVariableSet(method(), bci(), fr().id()));
@@ -323,7 +323,7 @@
   _bci = bci;
   _id = id;
   // Alway will need at least one, must be on C heap
-  _locals = new(ResourceObj::C_HEAP) GrowableArray<jvmtiDeferredLocalVariable*> (1, true);
+  _locals = new(ResourceObj::C_HEAP, mtCompiler) GrowableArray<jvmtiDeferredLocalVariable*> (1, true);
 }
 
 jvmtiDeferredLocalVariableSet::~jvmtiDeferredLocalVariableSet() {
diff --git a/hotspot/src/share/vm/runtime/vframe_hp.hpp b/hotspot/src/share/vm/runtime/vframe_hp.hpp
index 6d0bd37..4edb53b 100644
--- a/hotspot/src/share/vm/runtime/vframe_hp.hpp
+++ b/hotspot/src/share/vm/runtime/vframe_hp.hpp
@@ -89,7 +89,7 @@
 // any updated locals.
 
 class jvmtiDeferredLocalVariable;
-class jvmtiDeferredLocalVariableSet : public CHeapObj {
+class jvmtiDeferredLocalVariableSet : public CHeapObj<mtCompiler> {
 private:
 
   methodOop _method;           // must be GC'd
@@ -119,7 +119,7 @@
 
 };
 
-class jvmtiDeferredLocalVariable : public CHeapObj {
+class jvmtiDeferredLocalVariable : public CHeapObj<mtCompiler> {
   public:
 
     jvmtiDeferredLocalVariable(int index, BasicType type, jvalue value);
diff --git a/hotspot/src/share/vm/runtime/virtualspace.cpp b/hotspot/src/share/vm/runtime/virtualspace.cpp
index c7e6bf8..31b8d7a 100644
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp
@@ -26,6 +26,7 @@
 #include "oops/markOop.hpp"
 #include "oops/oop.inline.hpp"
 #include "runtime/virtualspace.hpp"
+#include "services/memTracker.hpp"
 #ifdef TARGET_OS_FAMILY_linux
 # include "os_linux.inline.hpp"
 #endif
@@ -340,20 +341,9 @@
     if ((((size_t)base + noaccess_prefix) & (alignment - 1)) != 0) {
       // Base not aligned, retry
       if (!os::release_memory(base, size)) fatal("os::release_memory failed");
-      // Reserve size large enough to do manual alignment and
-      // increase size to a multiple of the desired alignment
+      // Make sure that size is aligned
       size = align_size_up(size, alignment);
-      size_t extra_size = size + alignment;
-      do {
-        char* extra_base = os::reserve_memory(extra_size, NULL, alignment);
-        if (extra_base == NULL) return;
-        // Do manual alignement
-        base = (char*) align_size_up((uintptr_t) extra_base, alignment);
-        assert(base >= extra_base, "just checking");
-        // Re-reserve the region at the aligned base address.
-        os::release_memory(extra_base, extra_size);
-        base = os::reserve_memory(size, base);
-      } while (base == NULL);
+      base = os::reserve_memory_aligned(size, alignment);
 
       if (requested_address != 0 &&
           failed_to_reserve_as_requested(base, requested_address, size, false)) {
@@ -489,6 +479,10 @@
                 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&
                  Universe::narrow_oop_use_implicit_null_checks()) ?
                   lcm(os::vm_page_size(), alignment) : 0) {
+  if (base() > 0) {
+    MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap);
+  }
+
   // Only reserved space for the java heap should have a noaccess_prefix
   // if using compressed oops.
   protect_noaccess_prefix(size);
@@ -504,6 +498,10 @@
                 (UseCompressedOops && (Universe::narrow_oop_base() != NULL) &&
                  Universe::narrow_oop_use_implicit_null_checks()) ?
                   lcm(os::vm_page_size(), prefix_align) : 0) {
+  if (base() > 0) {
+    MemTracker::record_virtual_memory_type((address)base(), mtJavaHeap);
+  }
+
   protect_noaccess_prefix(prefix_size+suffix_size);
 }
 
@@ -513,6 +511,7 @@
                                      size_t rs_align,
                                      bool large) :
   ReservedSpace(r_size, rs_align, large, /*executable*/ true) {
+  MemTracker::record_virtual_memory_type((address)base(), mtCode);
 }
 
 // VirtualSpace
diff --git a/hotspot/src/share/vm/runtime/vmStructs.cpp b/hotspot/src/share/vm/runtime/vmStructs.cpp
index 924cde1..fe6ba25 100644
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp
@@ -44,7 +44,6 @@
 #include "code/vmreg.hpp"
 #include "compiler/oopMap.hpp"
 #include "compiler/compileBroker.hpp"
-#include "gc_implementation/concurrentMarkSweep/freeBlockDictionary.hpp"
 #include "gc_implementation/shared/immutableSpace.hpp"
 #include "gc_implementation/shared/markSweep.hpp"
 #include "gc_implementation/shared/mutableSpace.hpp"
@@ -55,6 +54,7 @@
 #include "memory/cardTableRS.hpp"
 #include "memory/compactPermGen.hpp"
 #include "memory/defNewGeneration.hpp"
+#include "memory/freeBlockDictionary.hpp"
 #include "memory/genCollectedHeap.hpp"
 #include "memory/generation.hpp"
 #include "memory/generationSpec.hpp"
@@ -235,7 +235,6 @@
 #ifndef REG_COUNT
   #define REG_COUNT 0
 #endif
-
 // whole purpose of this function is to work around bug c++/27724 in gcc 4.1.1
 // with optimization turned on it doesn't affect produced code
 static inline uint64_t cast_uint64_t(size_t x)
@@ -244,6 +243,16 @@
 }
 
 
+typedef HashtableEntry<intptr_t, mtInternal>  IntptrHashtableEntry;
+typedef Hashtable<intptr_t, mtInternal>       IntptrHashtable;
+typedef Hashtable<Symbol*, mtSymbol>          SymbolHashtable;
+typedef HashtableEntry<Symbol*, mtClass>      SymbolHashtableEntry;
+typedef Hashtable<oop, mtSymbol>              StringHashtable;
+typedef TwoOopHashtable<klassOop, mtClass>    klassOopTwoOopHashtable;
+typedef Hashtable<klassOop, mtClass>          klassOopHashtable;
+typedef HashtableEntry<klassOop, mtClass>     klassHashtableEntry;
+typedef TwoOopHashtable<Symbol*, mtClass>     SymbolTwoOopHashtable;
+
 //--------------------------------------------------------------------------------
 // VM_STRUCTS
 //
@@ -292,8 +301,6 @@
   nonstatic_field(instanceKlass,               _method_ordering,                              typeArrayOop)                          \
   nonstatic_field(instanceKlass,               _local_interfaces,                             objArrayOop)                           \
   nonstatic_field(instanceKlass,               _transitive_interfaces,                        objArrayOop)                           \
-  nonstatic_field(instanceKlass,               _nof_implementors,                             int)                                   \
-  nonstatic_field(instanceKlass,               _implementors[0],                              klassOop)                              \
   nonstatic_field(instanceKlass,               _fields,                                       typeArrayOop)                          \
   nonstatic_field(instanceKlass,               _java_fields_count,                            u2)                                    \
   nonstatic_field(instanceKlass,               _constants,                                    constantPoolOop)                       \
@@ -301,7 +308,7 @@
   nonstatic_field(instanceKlass,               _protection_domain,                            oop)                                   \
   nonstatic_field(instanceKlass,               _signers,                                      objArrayOop)                           \
   nonstatic_field(instanceKlass,               _source_file_name,                             Symbol*)                               \
-  nonstatic_field(instanceKlass,               _source_debug_extension,                       Symbol*)                               \
+  nonstatic_field(instanceKlass,               _source_debug_extension,                       char*)                                 \
   nonstatic_field(instanceKlass,               _inner_classes,                                typeArrayOop)                          \
   nonstatic_field(instanceKlass,               _nonstatic_field_size,                         int)                                   \
   nonstatic_field(instanceKlass,               _static_field_size,                            int)                                   \
@@ -360,7 +367,6 @@
   nonstatic_field(methodDataOopDesc,           _arg_stack,                                    intx)                                  \
   nonstatic_field(methodDataOopDesc,           _arg_returned,                                 intx)                                  \
   nonstatic_field(methodOopDesc,               _constMethod,                                  constMethodOop)                        \
-  nonstatic_field(methodOopDesc,               _constants,                                    constantPoolOop)                       \
   nonstatic_field(methodOopDesc,               _method_data,                                  methodDataOop)                         \
   nonstatic_field(methodOopDesc,               _interpreter_invocation_count,                 int)                                   \
   nonstatic_field(methodOopDesc,               _access_flags,                                 AccessFlags)                           \
@@ -380,9 +386,8 @@
   volatile_nonstatic_field(methodOopDesc,      _from_compiled_entry,                          address)                               \
   volatile_nonstatic_field(methodOopDesc,      _from_interpreted_entry,                       address)                               \
   volatile_nonstatic_field(constMethodOopDesc, _fingerprint,                                  uint64_t)                              \
-  nonstatic_field(constMethodOopDesc,          _method,                                       methodOop)                             \
+  nonstatic_field(constMethodOopDesc,          _constants,                                    constantPoolOop)                       \
   nonstatic_field(constMethodOopDesc,          _stackmap_data,                                typeArrayOop)                          \
-  nonstatic_field(constMethodOopDesc,          _exception_table,                              typeArrayOop)                          \
   nonstatic_field(constMethodOopDesc,          _constMethod_size,                             int)                                   \
   nonstatic_field(constMethodOopDesc,          _interpreter_kind,                             jbyte)                                 \
   nonstatic_field(constMethodOopDesc,          _flags,                                        jbyte)                                 \
@@ -419,6 +424,10 @@
   nonstatic_field(LocalVariableTableElement,   descriptor_cp_index,                           u2)                                    \
   nonstatic_field(LocalVariableTableElement,   signature_cp_index,                            u2)                                    \
   nonstatic_field(LocalVariableTableElement,   slot,                                          u2)                                    \
+  nonstatic_field(ExceptionTableElement,       start_pc,                                      u2)                                    \
+  nonstatic_field(ExceptionTableElement,       end_pc,                                        u2)                                    \
+  nonstatic_field(ExceptionTableElement,       handler_pc,                                    u2)                                    \
+  nonstatic_field(ExceptionTableElement,       catch_type_index,                              u2)                                    \
   nonstatic_field(BreakpointInfo,              _orig_bytecode,                                Bytecodes::Code)                       \
   nonstatic_field(BreakpointInfo,              _bci,                                          int)                                   \
   nonstatic_field(BreakpointInfo,              _name_index,                                   u2)                                    \
@@ -714,26 +723,26 @@
   /* HashtableBucket */                                                                                                              \
   /*******************/                                                                                                              \
                                                                                                                                      \
-  nonstatic_field(HashtableBucket,             _entry,                                        BasicHashtableEntry*)                  \
+  nonstatic_field(HashtableBucket<mtInternal>,  _entry,                                        BasicHashtableEntry<mtInternal>*)     \
                                                                                                                                      \
   /******************/                                                                                                               \
   /* HashtableEntry */                                                                                                               \
   /******************/                                                                                                               \
                                                                                                                                      \
-  nonstatic_field(BasicHashtableEntry,         _next,                                         BasicHashtableEntry*)                  \
-  nonstatic_field(BasicHashtableEntry,         _hash,                                         unsigned int)                          \
-  nonstatic_field(HashtableEntry<intptr_t>,    _literal,                                      intptr_t) \
+  nonstatic_field(BasicHashtableEntry<mtInternal>, _next,                                     BasicHashtableEntry<mtInternal>*)      \
+  nonstatic_field(BasicHashtableEntry<mtInternal>, _hash,                                     unsigned int)                          \
+  nonstatic_field(IntptrHashtableEntry,            _literal,                                  intptr_t)                              \
                                                                                                                                      \
   /*************/                                                                                                                    \
   /* Hashtable */                                                                                                                    \
   /*************/                                                                                                                    \
                                                                                                                                      \
-  nonstatic_field(BasicHashtable,              _table_size,                                   int)                                   \
-  nonstatic_field(BasicHashtable,              _buckets,                                      HashtableBucket*)                      \
-  nonstatic_field(BasicHashtable,              _free_list,                                    BasicHashtableEntry*)                  \
-  nonstatic_field(BasicHashtable,              _first_free_entry,                             char*)                                 \
-  nonstatic_field(BasicHashtable,              _end_block,                                    char*)                                 \
-  nonstatic_field(BasicHashtable,              _entry_size,                                   int)                                   \
+  nonstatic_field(BasicHashtable<mtInternal>, _table_size,                                   int)                                   \
+  nonstatic_field(BasicHashtable<mtInternal>, _buckets,                                      HashtableBucket<mtInternal>*)          \
+  nonstatic_field(BasicHashtable<mtInternal>, _free_list,                                    BasicHashtableEntry<mtInternal>*)      \
+  nonstatic_field(BasicHashtable<mtInternal>, _first_free_entry,                             char*)                                 \
+  nonstatic_field(BasicHashtable<mtInternal>, _end_block,                                    char*)                                 \
+  nonstatic_field(BasicHashtable<mtInternal>, _entry_size,                                   int)                                   \
                                                                                                                                      \
   /*******************/                                                                                                              \
   /* DictionaryEntry */                                                                                                              \
@@ -827,13 +836,6 @@
   /* CodeBlobs (NOTE: incomplete, but only a little) */                                                                              \
   /***************************************************/                                                                              \
                                                                                                                                      \
-  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_pc,                                     address))                   \
-  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _exact_sender_sp,                              intptr_t*))                  \
-  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _sender_link,                                  intptr_t*))                  \
-  X86_ONLY(nonstatic_field(MethodHandles::RicochetFrame, _saved_args_base,                              intptr_t*))                  \
-                                                                                                                                     \
-     static_field(SharedRuntime,               _ricochet_blob,                                RicochetBlob*)                         \
-                                                                                                                                     \
   nonstatic_field(CodeBlob,                    _name,                                         const char*)                           \
   nonstatic_field(CodeBlob,                    _size,                                         int)                                   \
   nonstatic_field(CodeBlob,                    _header_size,                                  int)                                   \
@@ -878,11 +880,8 @@
   nonstatic_field(nmethod,             _compile_id,                                   int)                                   \
   nonstatic_field(nmethod,             _exception_cache,                              ExceptionCache*)                       \
   nonstatic_field(nmethod,             _marked_for_deoptimization,                    bool)                                  \
-                                                                                                                                     \
-  nonstatic_field(RicochetBlob,        _bounce_offset,                                int)                                           \
-  nonstatic_field(RicochetBlob,        _exception_offset,                             int)                                           \
-                                                                                                                                     \
-  unchecked_c2_static_field(Deoptimization,         _trap_reason_name,                   void*)                                         \
+                                                                                                                             \
+  unchecked_c2_static_field(Deoptimization,         _trap_reason_name,                   void*)                              \
                                                                                                                                      \
   /********************************/                                                                                                 \
   /* JavaCalls (NOTE: incomplete) */                                                                                                 \
@@ -1454,6 +1453,7 @@
                                                                           \
   declare_toplevel_type(CheckedExceptionElement)                          \
   declare_toplevel_type(LocalVariableTableElement)                        \
+  declare_toplevel_type(ExceptionTableElement)                            \
                                                                           \
   /******************************************/                            \
   /* Generation and space hierarchies       */                            \
@@ -1541,20 +1541,20 @@
   /* SymbolTable, SystemDictionary */                                     \
   /*********************************/                                     \
                                                                           \
-  declare_toplevel_type(BasicHashtable)                                   \
-    declare_type(Hashtable<intptr_t>, BasicHashtable)                     \
-  declare_type(SymbolTable, Hashtable<Symbol*>)                           \
-  declare_type(StringTable, Hashtable<oop>)                               \
-    declare_type(LoaderConstraintTable, Hashtable<klassOop>)              \
-    declare_type(TwoOopHashtable<klassOop>, Hashtable<klassOop>)          \
-    declare_type(Dictionary, TwoOopHashtable<klassOop>)                   \
-    declare_type(PlaceholderTable, TwoOopHashtable<Symbol*>)              \
-  declare_toplevel_type(BasicHashtableEntry)                              \
-  declare_type(HashtableEntry<intptr_t>, BasicHashtableEntry)             \
-    declare_type(DictionaryEntry, HashtableEntry<klassOop>)               \
-    declare_type(PlaceholderEntry, HashtableEntry<Symbol*>)               \
-    declare_type(LoaderConstraintEntry, HashtableEntry<klassOop>)         \
-  declare_toplevel_type(HashtableBucket)                                  \
+  declare_toplevel_type(BasicHashtable<mtInternal>)                       \
+    declare_type(IntptrHashtable, BasicHashtable<mtInternal>)             \
+  declare_type(SymbolTable, SymbolHashtable)                              \
+  declare_type(StringTable, StringHashtable)                              \
+    declare_type(LoaderConstraintTable, klassOopHashtable)                \
+    declare_type(klassOopTwoOopHashtable, klassOopHashtable)              \
+    declare_type(Dictionary, klassOopTwoOopHashtable)                     \
+    declare_type(PlaceholderTable, SymbolTwoOopHashtable)                 \
+  declare_toplevel_type(BasicHashtableEntry<mtInternal>)                  \
+  declare_type(IntptrHashtableEntry, BasicHashtableEntry<mtInternal>)     \
+    declare_type(DictionaryEntry, klassHashtableEntry)                    \
+    declare_type(PlaceholderEntry, SymbolHashtableEntry)                  \
+    declare_type(LoaderConstraintEntry, klassHashtableEntry)              \
+  declare_toplevel_type(HashtableBucket<mtInternal>)                      \
   declare_toplevel_type(SystemDictionary)                                 \
   declare_toplevel_type(vmSymbols)                                        \
   declare_toplevel_type(ProtectionDomainEntry)                            \
@@ -1623,7 +1623,6 @@
   /*************************************************************/         \
                                                                           \
   declare_toplevel_type(SharedRuntime)                                    \
-  X86_ONLY(declare_toplevel_type(MethodHandles::RicochetFrame))           \
                                                                           \
   declare_toplevel_type(CodeBlob)                                         \
   declare_type(BufferBlob,               CodeBlob)                        \
@@ -1634,7 +1633,6 @@
   declare_type(SingletonBlob,            CodeBlob)                        \
   declare_type(SafepointBlob,            SingletonBlob)                   \
   declare_type(DeoptimizationBlob,       SingletonBlob)                   \
-  declare_type(RicochetBlob,             SingletonBlob)                   \
   declare_c2_type(ExceptionBlob,         SingletonBlob)                   \
   declare_c2_type(UncommonTrapBlob,      CodeBlob)                        \
                                                                           \
@@ -1878,7 +1876,6 @@
   declare_c2_type(StoreNNode, StoreNode)                                  \
   declare_c2_type(StoreCMNode, StoreNode)                                 \
   declare_c2_type(LoadPLockedNode, LoadPNode)                             \
-  declare_c2_type(LoadLLockedNode, LoadLNode)                             \
   declare_c2_type(SCMemProjNode, ProjNode)                                \
   declare_c2_type(LoadStoreNode, Node)                                    \
   declare_c2_type(StorePConditionalNode, LoadStoreNode)                   \
@@ -1948,90 +1945,58 @@
   declare_c2_type(ReverseBytesLNode, Node)                                \
   declare_c2_type(VectorNode, Node)                                       \
   declare_c2_type(AddVBNode, VectorNode)                                  \
-  declare_c2_type(AddVCNode, VectorNode)                                  \
   declare_c2_type(AddVSNode, VectorNode)                                  \
   declare_c2_type(AddVINode, VectorNode)                                  \
   declare_c2_type(AddVLNode, VectorNode)                                  \
   declare_c2_type(AddVFNode, VectorNode)                                  \
   declare_c2_type(AddVDNode, VectorNode)                                  \
   declare_c2_type(SubVBNode, VectorNode)                                  \
-  declare_c2_type(SubVCNode, VectorNode)                                  \
   declare_c2_type(SubVSNode, VectorNode)                                  \
   declare_c2_type(SubVINode, VectorNode)                                  \
   declare_c2_type(SubVLNode, VectorNode)                                  \
   declare_c2_type(SubVFNode, VectorNode)                                  \
   declare_c2_type(SubVDNode, VectorNode)                                  \
+  declare_c2_type(MulVSNode, VectorNode)                                  \
+  declare_c2_type(MulVINode, VectorNode)                                  \
   declare_c2_type(MulVFNode, VectorNode)                                  \
   declare_c2_type(MulVDNode, VectorNode)                                  \
   declare_c2_type(DivVFNode, VectorNode)                                  \
   declare_c2_type(DivVDNode, VectorNode)                                  \
   declare_c2_type(LShiftVBNode, VectorNode)                               \
-  declare_c2_type(LShiftVCNode, VectorNode)                               \
   declare_c2_type(LShiftVSNode, VectorNode)                               \
   declare_c2_type(LShiftVINode, VectorNode)                               \
+  declare_c2_type(LShiftVLNode, VectorNode)                               \
+  declare_c2_type(RShiftVBNode, VectorNode)                               \
+  declare_c2_type(RShiftVSNode, VectorNode)                               \
+  declare_c2_type(RShiftVINode, VectorNode)                               \
+  declare_c2_type(RShiftVLNode, VectorNode)                               \
   declare_c2_type(URShiftVBNode, VectorNode)                              \
-  declare_c2_type(URShiftVCNode, VectorNode)                              \
   declare_c2_type(URShiftVSNode, VectorNode)                              \
   declare_c2_type(URShiftVINode, VectorNode)                              \
+  declare_c2_type(URShiftVLNode, VectorNode)                              \
   declare_c2_type(AndVNode, VectorNode)                                   \
   declare_c2_type(OrVNode, VectorNode)                                    \
   declare_c2_type(XorVNode, VectorNode)                                   \
-  declare_c2_type(VectorLoadNode, LoadNode)                               \
-  declare_c2_type(Load16BNode, VectorLoadNode)                            \
-  declare_c2_type(Load8BNode, VectorLoadNode)                             \
-  declare_c2_type(Load4BNode, VectorLoadNode)                             \
-  declare_c2_type(Load8CNode, VectorLoadNode)                             \
-  declare_c2_type(Load4CNode, VectorLoadNode)                             \
-  declare_c2_type(Load2CNode, VectorLoadNode)                             \
-  declare_c2_type(Load8SNode, VectorLoadNode)                             \
-  declare_c2_type(Load4SNode, VectorLoadNode)                             \
-  declare_c2_type(Load2SNode, VectorLoadNode)                             \
-  declare_c2_type(Load4INode, VectorLoadNode)                             \
-  declare_c2_type(Load2INode, VectorLoadNode)                             \
-  declare_c2_type(Load2LNode, VectorLoadNode)                             \
-  declare_c2_type(Load4FNode, VectorLoadNode)                             \
-  declare_c2_type(Load2FNode, VectorLoadNode)                             \
-  declare_c2_type(Load2DNode, VectorLoadNode)                             \
-  declare_c2_type(VectorStoreNode, StoreNode)                             \
-  declare_c2_type(Store16BNode, VectorStoreNode)                          \
-  declare_c2_type(Store8BNode, VectorStoreNode)                           \
-  declare_c2_type(Store4BNode, VectorStoreNode)                           \
-  declare_c2_type(Store8CNode, VectorStoreNode)                           \
-  declare_c2_type(Store4CNode, VectorStoreNode)                           \
-  declare_c2_type(Store2CNode, VectorStoreNode)                           \
-  declare_c2_type(Store4INode, VectorStoreNode)                           \
-  declare_c2_type(Store2INode, VectorStoreNode)                           \
-  declare_c2_type(Store2LNode, VectorStoreNode)                           \
-  declare_c2_type(Store4FNode, VectorStoreNode)                           \
-  declare_c2_type(Store2FNode, VectorStoreNode)                           \
-  declare_c2_type(Store2DNode, VectorStoreNode)                           \
-  declare_c2_type(Replicate16BNode, VectorNode)                           \
-  declare_c2_type(Replicate8BNode, VectorNode)                            \
-  declare_c2_type(Replicate4BNode, VectorNode)                            \
-  declare_c2_type(Replicate8CNode, VectorNode)                            \
-  declare_c2_type(Replicate4CNode, VectorNode)                            \
-  declare_c2_type(Replicate2CNode, VectorNode)                            \
-  declare_c2_type(Replicate8SNode, VectorNode)                            \
-  declare_c2_type(Replicate4SNode, VectorNode)                            \
-  declare_c2_type(Replicate2SNode, VectorNode)                            \
-  declare_c2_type(Replicate4INode, VectorNode)                            \
-  declare_c2_type(Replicate2INode, VectorNode)                            \
-  declare_c2_type(Replicate2LNode, VectorNode)                            \
-  declare_c2_type(Replicate4FNode, VectorNode)                            \
-  declare_c2_type(Replicate2FNode, VectorNode)                            \
-  declare_c2_type(Replicate2DNode, VectorNode)                            \
+  declare_c2_type(LoadVectorNode, LoadNode)                               \
+  declare_c2_type(StoreVectorNode, StoreNode)                             \
+  declare_c2_type(ReplicateBNode, VectorNode)                             \
+  declare_c2_type(ReplicateSNode, VectorNode)                             \
+  declare_c2_type(ReplicateINode, VectorNode)                             \
+  declare_c2_type(ReplicateLNode, VectorNode)                             \
+  declare_c2_type(ReplicateFNode, VectorNode)                             \
+  declare_c2_type(ReplicateDNode, VectorNode)                             \
   declare_c2_type(PackNode, VectorNode)                                   \
   declare_c2_type(PackBNode, PackNode)                                    \
-  declare_c2_type(PackCNode, PackNode)                                    \
   declare_c2_type(PackSNode, PackNode)                                    \
   declare_c2_type(PackINode, PackNode)                                    \
   declare_c2_type(PackLNode, PackNode)                                    \
   declare_c2_type(PackFNode, PackNode)                                    \
   declare_c2_type(PackDNode, PackNode)                                    \
-  declare_c2_type(Pack2x1BNode, PackNode)                                 \
-  declare_c2_type(Pack2x2BNode, PackNode)                                 \
+  declare_c2_type(Pack2LNode, PackNode)                                   \
+  declare_c2_type(Pack2DNode, PackNode)                                   \
   declare_c2_type(ExtractNode, Node)                                      \
   declare_c2_type(ExtractBNode, ExtractNode)                              \
+  declare_c2_type(ExtractUBNode, ExtractNode)                             \
   declare_c2_type(ExtractCNode, ExtractNode)                              \
   declare_c2_type(ExtractSNode, ExtractNode)                              \
   declare_c2_type(ExtractINode, ExtractNode)                              \
@@ -2180,6 +2145,7 @@
   /******************/                                                    \
                                                                           \
   declare_constant(UseTLAB)                                               \
+  declare_constant(EnableInvokeDynamic)                                   \
                                                                           \
   /**************/                                                        \
   /* Stack bias */                                                        \
@@ -2278,7 +2244,7 @@
   declare_constant(JVM_ACC_HAS_LOOPS)                                     \
   declare_constant(JVM_ACC_LOOPS_FLAG_INIT)                               \
   declare_constant(JVM_ACC_QUEUED)                                        \
-  declare_constant(JVM_ACC_NOT_OSR_COMPILABLE)                            \
+  declare_constant(JVM_ACC_NOT_C2_OSR_COMPILABLE)                         \
   declare_constant(JVM_ACC_HAS_LINE_NUMBER_TABLE)                         \
   declare_constant(JVM_ACC_HAS_CHECKED_EXCEPTIONS)                        \
   declare_constant(JVM_ACC_HAS_JSRS)                                      \
@@ -2338,12 +2304,12 @@
   declare_constant(constMethodOopDesc::_has_linenumber_table)             \
   declare_constant(constMethodOopDesc::_has_checked_exceptions)           \
   declare_constant(constMethodOopDesc::_has_localvariable_table)          \
+  declare_constant(constMethodOopDesc::_has_exception_table)              \
                                                                           \
   /*************************************/                                 \
   /* instanceKlass enum                */                                 \
   /*************************************/                                 \
                                                                           \
-  declare_constant(instanceKlass::implementors_limit)                     \
                                                                           \
   /*************************************/                                 \
   /* FieldInfo FieldOffset enum        */                                 \
@@ -2355,7 +2321,6 @@
   declare_constant(FieldInfo::initval_index_offset)                       \
   declare_constant(FieldInfo::low_offset)                                 \
   declare_constant(FieldInfo::high_offset)                                \
-  declare_constant(FieldInfo::generic_signature_offset)                   \
   declare_constant(FieldInfo::field_slots)                                \
                                                                           \
   /************************************************/                      \
@@ -2381,7 +2346,7 @@
   declare_constant(instanceKlass::initialization_error)                   \
                                                                           \
   /*********************************/                                     \
-  /* Symbol* - symbol max length */                                     \
+  /* Symbol* - symbol max length */                                       \
   /*********************************/                                     \
                                                                           \
   declare_constant(Symbol::max_symbol_length)                             \
@@ -2394,21 +2359,16 @@
   declare_constant(constantPoolOopDesc::_indy_argc_offset)                \
   declare_constant(constantPoolOopDesc::_indy_argv_offset)                \
                                                                           \
-  /*********************************************/                         \
-  /* ConstantPoolCacheEntry FlagBitValues enum */                         \
-  /*********************************************/                         \
+  /********************************/                                      \
+  /* ConstantPoolCacheEntry enums */                                      \
+  /********************************/                                      \
                                                                           \
-  declare_constant(ConstantPoolCacheEntry::hotSwapBit)                    \
-  declare_constant(ConstantPoolCacheEntry::methodInterface)               \
-  declare_constant(ConstantPoolCacheEntry::volatileField)                 \
-  declare_constant(ConstantPoolCacheEntry::vfinalMethod)                  \
-  declare_constant(ConstantPoolCacheEntry::finalField)                    \
-                                                                          \
-  /******************************************/                            \
-  /* ConstantPoolCacheEntry FlagValues enum */                            \
-  /******************************************/                            \
-                                                                          \
-  declare_constant(ConstantPoolCacheEntry::tosBits)                       \
+  declare_constant(ConstantPoolCacheEntry::is_volatile_shift)             \
+  declare_constant(ConstantPoolCacheEntry::is_final_shift)                \
+  declare_constant(ConstantPoolCacheEntry::is_forced_virtual_shift)       \
+  declare_constant(ConstantPoolCacheEntry::is_vfinal_shift)               \
+  declare_constant(ConstantPoolCacheEntry::is_field_entry_shift)          \
+  declare_constant(ConstantPoolCacheEntry::tos_state_shift)               \
                                                                           \
   /***************************************/                               \
   /* java_lang_Thread::ThreadStatus enum */                               \
diff --git a/hotspot/src/share/vm/runtime/vmThread.cpp b/hotspot/src/share/vm/runtime/vmThread.cpp
index d4fced2..9e42148 100644
--- a/hotspot/src/share/vm/runtime/vmThread.cpp
+++ b/hotspot/src/share/vm/runtime/vmThread.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -304,7 +304,7 @@
     os::check_heap();
     // Silent verification so as not to pollute normal output,
     // unless we really asked for it.
-    Universe::verify(true, !(PrintGCDetails || Verbose));
+    Universe::verify(!(PrintGCDetails || Verbose));
   }
 
   CompileBroker::set_should_block();
diff --git a/hotspot/src/share/vm/runtime/vmThread.hpp b/hotspot/src/share/vm/runtime/vmThread.hpp
index f784496..acf9584 100644
--- a/hotspot/src/share/vm/runtime/vmThread.hpp
+++ b/hotspot/src/share/vm/runtime/vmThread.hpp
@@ -46,7 +46,7 @@
 // Encapsulates both queue management and
 // and priority policy
 //
-class VMOperationQueue : public CHeapObj {
+class VMOperationQueue : public CHeapObj<mtInternal> {
  private:
   enum Priorities {
      SafepointPriority, // Highest priority (operation executed at a safepoint)
diff --git a/hotspot/src/share/vm/runtime/vm_operations.hpp b/hotspot/src/share/vm/runtime/vm_operations.hpp
index 081c428..ccbad94 100644
--- a/hotspot/src/share/vm/runtime/vm_operations.hpp
+++ b/hotspot/src/share/vm/runtime/vm_operations.hpp
@@ -96,7 +96,7 @@
   template(JFRCheckpoint)                         \
   template(Exit)                                  \
 
-class VM_Operation: public CHeapObj {
+class VM_Operation: public CHeapObj<mtInternal> {
  public:
   enum Mode {
     _safepoint,       // blocking,        safepoint, vm_op C-heap allocated
diff --git a/hotspot/src/share/vm/runtime/vm_version.cpp b/hotspot/src/share/vm/runtime/vm_version.cpp
index 2d51b67..09d49e3 100644
--- a/hotspot/src/share/vm/runtime/vm_version.cpp
+++ b/hotspot/src/share/vm/runtime/vm_version.cpp
@@ -45,6 +45,10 @@
 const char* Abstract_VM_Version::_s_vm_release = Abstract_VM_Version::vm_release();
 const char* Abstract_VM_Version::_s_internal_vm_info_string = Abstract_VM_Version::internal_vm_info_string();
 bool Abstract_VM_Version::_supports_cx8 = false;
+bool Abstract_VM_Version::_supports_atomic_getset4 = false;
+bool Abstract_VM_Version::_supports_atomic_getset8 = false;
+bool Abstract_VM_Version::_supports_atomic_getadd4 = false;
+bool Abstract_VM_Version::_supports_atomic_getadd8 = false;
 unsigned int Abstract_VM_Version::_logical_processors_per_package = 1U;
 int Abstract_VM_Version::_reserve_for_allocation_prefetch = 0;
 
@@ -237,19 +241,21 @@
 
   #ifndef FLOAT_ARCH
     #if defined(__SOFTFP__)
-      #define FLOAT_ARCH "-sflt"
+      #define FLOAT_ARCH_STR "-sflt"
     #elif defined(E500V2)
-      #define FLOAT_ARCH "-e500v2"
+      #define FLOAT_ARCH_STR "-e500v2"
     #elif defined(ARM)
-      #define FLOAT_ARCH "-vfp"
+      #define FLOAT_ARCH_STR "-vfp"
     #elif defined(PPC)
-      #define FLOAT_ARCH "-hflt"
+      #define FLOAT_ARCH_STR "-hflt"
     #else
-      #define FLOAT_ARCH ""
+      #define FLOAT_ARCH_STR ""
     #endif
+  #else
+    #define FLOAT_ARCH_STR XSTR(FLOAT_ARCH)
   #endif
 
-  return VMNAME " (" VM_RELEASE ") for " OS "-" CPU FLOAT_ARCH
+  return VMNAME " (" VM_RELEASE ") for " OS "-" CPU FLOAT_ARCH_STR
          " JRE (" JRE_RELEASE_VERSION "), built on " __DATE__ " " __TIME__
          " by " XSTR(HOTSPOT_BUILD_USER) " with " HOTSPOT_BUILD_COMPILER;
 }
diff --git a/hotspot/src/share/vm/runtime/vm_version.hpp b/hotspot/src/share/vm/runtime/vm_version.hpp
index 0d35522..6506103 100644
--- a/hotspot/src/share/vm/runtime/vm_version.hpp
+++ b/hotspot/src/share/vm/runtime/vm_version.hpp
@@ -37,6 +37,10 @@
   static const char*  _s_internal_vm_info_string;
   // These are set by machine-dependent initializations
   static bool         _supports_cx8;
+  static bool         _supports_atomic_getset4;
+  static bool         _supports_atomic_getset8;
+  static bool         _supports_atomic_getadd4;
+  static bool         _supports_atomic_getadd8;
   static unsigned int _logical_processors_per_package;
   static int          _vm_major_version;
   static int          _vm_minor_version;
@@ -75,6 +79,13 @@
 
   // does HW support an 8-byte compare-exchange operation?
   static bool supports_cx8()  {return _supports_cx8;}
+  // does HW support atomic get-and-set or atomic get-and-add?  Used
+  // to guide intrinsification decisions for Unsafe atomic ops
+  static bool supports_atomic_getset4()  {return _supports_atomic_getset4;}
+  static bool supports_atomic_getset8()  {return _supports_atomic_getset8;}
+  static bool supports_atomic_getadd4()  {return _supports_atomic_getadd4;}
+  static bool supports_atomic_getadd8()  {return _supports_atomic_getadd8;}
+
   static unsigned int logical_processors_per_package() {
     return _logical_processors_per_package;
   }
diff --git a/hotspot/src/share/vm/services/attachListener.cpp b/hotspot/src/share/vm/services/attachListener.cpp
index 3753a64..bc6c7e2 100644
--- a/hotspot/src/share/vm/services/attachListener.cpp
+++ b/hotspot/src/share/vm/services/attachListener.cpp
@@ -320,7 +320,7 @@
   }
   bool res = CommandLineFlags::ccstrAtPut((char*)name, &value, ATTACH_ON_DEMAND);
   if (res) {
-    FREE_C_HEAP_ARRAY(char, value);
+    FREE_C_HEAP_ARRAY(char, value, mtInternal);
   } else {
     out->print_cr("setting flag %s failed", name);
   }
@@ -404,6 +404,8 @@
 static void attach_listener_thread_entry(JavaThread* thread, TRAPS) {
   os::set_priority(thread, NearMaxPriority);
 
+  thread->record_stack_base_and_size();
+
   if (AttachListener::pd_init() != 0) {
     return;
   }
diff --git a/hotspot/src/share/vm/services/attachListener.hpp b/hotspot/src/share/vm/services/attachListener.hpp
index ba8fb93..e39c3fd 100644
--- a/hotspot/src/share/vm/services/attachListener.hpp
+++ b/hotspot/src/share/vm/services/attachListener.hpp
@@ -98,7 +98,7 @@
 };
 
 #ifndef SERVICES_KERNEL
-class AttachOperation: public CHeapObj {
+class AttachOperation: public CHeapObj<mtInternal> {
  public:
   enum {
     name_length_max = 16,       // maximum length of  name
diff --git a/hotspot/src/share/vm/services/diagnosticArgument.cpp b/hotspot/src/share/vm/services/diagnosticArgument.cpp
index a3a6982..23267fa 100644
--- a/hotspot/src/share/vm/services/diagnosticArgument.cpp
+++ b/hotspot/src/share/vm/services/diagnosticArgument.cpp
@@ -43,6 +43,47 @@
   set_is_set(true);
 }
 
+void GenDCmdArgument::to_string(jlong l, char* buf, size_t len) {
+  jio_snprintf(buf, len, INT64_FORMAT, l);
+}
+
+void GenDCmdArgument::to_string(bool b, char* buf, size_t len) {
+  jio_snprintf(buf, len, b ? "true" : "false");
+}
+
+void GenDCmdArgument::to_string(NanoTimeArgument n, char* buf, size_t len) {
+  jio_snprintf(buf, len, INT64_FORMAT, n._nanotime);
+}
+
+void GenDCmdArgument::to_string(MemorySizeArgument m, char* buf, size_t len) {
+  jio_snprintf(buf, len, INT64_FORMAT, m._size);
+}
+
+void GenDCmdArgument::to_string(char* c, char* buf, size_t len) {
+  jio_snprintf(buf, len, "%s", c);
+}
+
+void GenDCmdArgument::to_string(StringArrayArgument* f, char* buf, size_t len) {
+  int length = f->array()->length();
+  size_t written = 0;
+  buf[0] = 0;
+  for (int i = 0; i < length; i++) {
+    char* next_str = f->array()->at(i);
+    size_t next_size = strlen(next_str);
+    //Check if there's room left to write next element
+    if (written + next_size > len) {
+      return;
+    }
+    //Actually write element
+    strcat(buf, next_str);
+    written += next_size;
+    //Check if there's room left for the comma
+    if (i < length-1 && len - written > 0) {
+      strcat(buf, ",");
+    }
+  }
+}
+
 template <> void DCmdArgument<jlong>::parse_value(const char* str,
                                                   size_t len, TRAPS) {
     if (str == NULL || sscanf(str, INT64_FORMAT, &_value) != 1) {
@@ -99,7 +140,7 @@
   if (str == NULL) {
     _value = NULL;
   } else {
-    _value = NEW_C_HEAP_ARRAY(char, len+1);
+    _value = NEW_C_HEAP_ARRAY(char, len+1, mtInternal);
     strncpy(_value, str, len);
     _value[len] = 0;
   }
@@ -118,7 +159,7 @@
 
 template <> void DCmdArgument<char*>::destroy_value() {
   if (_value != NULL) {
-    FREE_C_HEAP_ARRAY(char, _value);
+    FREE_C_HEAP_ARRAY(char, _value, mtInternal);
     set_value(NULL);
   }
 }
diff --git a/hotspot/src/share/vm/services/diagnosticArgument.hpp b/hotspot/src/share/vm/services/diagnosticArgument.hpp
index 380f7eb..596353b 100644
--- a/hotspot/src/share/vm/services/diagnosticArgument.hpp
+++ b/hotspot/src/share/vm/services/diagnosticArgument.hpp
@@ -31,17 +31,17 @@
 #include "runtime/thread.hpp"
 #include "utilities/exceptions.hpp"
 
-class StringArrayArgument : public CHeapObj {
+class StringArrayArgument : public CHeapObj<mtInternal> {
 private:
   GrowableArray<char*>* _array;
 public:
   StringArrayArgument() {
-    _array = new(ResourceObj::C_HEAP)GrowableArray<char *>(32, true);
+    _array = new(ResourceObj::C_HEAP, mtInternal)GrowableArray<char *>(32, true);
     assert(_array != NULL, "Sanity check");
   }
   void add(const char* str, size_t len) {
     if (str != NULL) {
-      char* ptr = NEW_C_HEAP_ARRAY(char, len+1);
+      char* ptr = NEW_C_HEAP_ARRAY(char, len+1, mtInternal);
       strncpy(ptr, str, len);
       ptr[len] = 0;
       _array->append(ptr);
@@ -53,7 +53,7 @@
   ~StringArrayArgument() {
     for (int i=0; i<_array->length(); i++) {
       if(_array->at(i) != NULL) { // Safety check
-        FREE_C_HEAP_ARRAY(char, _array->at(i));
+        FREE_C_HEAP_ARRAY(char, _array->at(i), mtInternal);
       }
     }
     delete _array;
@@ -110,12 +110,20 @@
   virtual void init_value(TRAPS) = 0;
   virtual void reset(TRAPS) = 0;
   virtual void cleanup() = 0;
+  virtual void value_as_str(char* buf, size_t len) = 0;
   void set_next(GenDCmdArgument* arg) {
     _next = arg;
   }
   GenDCmdArgument* next() {
     return _next;
   }
+
+  void to_string(jlong l, char* buf, size_t len);
+  void to_string(bool b, char* buf, size_t len);
+  void to_string(char* c, char* buf, size_t len);
+  void to_string(NanoTimeArgument n, char* buf, size_t len);
+  void to_string(MemorySizeArgument f, char* buf, size_t len);
+  void to_string(StringArrayArgument* s, char* buf, size_t len);
 };
 
 template <class ArgType> class DCmdArgument: public GenDCmdArgument {
@@ -143,6 +151,7 @@
   void parse_value(const char* str, size_t len, TRAPS);
   void init_value(TRAPS);
   void destroy_value();
+  void value_as_str(char *buf, size_t len) { return to_string(_value, buf, len);}
 };
 
 #endif  /* SHARE_VM_SERVICES_DIAGNOSTICARGUMENT_HPP */
diff --git a/hotspot/src/share/vm/services/diagnosticCommand.hpp b/hotspot/src/share/vm/services/diagnosticCommand.hpp
index d5c5cd17..cf4134f4 100644
--- a/hotspot/src/share/vm/services/diagnosticCommand.hpp
+++ b/hotspot/src/share/vm/services/diagnosticCommand.hpp
@@ -48,7 +48,7 @@
            "With no argument this will show a list of available commands. "
            "'help all' will show help for all commands.";
   }
-  static const char* impact() { return "Low: "; }
+  static const char* impact() { return "Low"; }
   static int num_arguments();
   virtual void execute(TRAPS);
 };
@@ -60,7 +60,7 @@
   static const char* description() {
     return "Print JVM version information.";
   }
-  static const char* impact() { return "Low: "; }
+  static const char* impact() { return "Low"; }
   static int num_arguments() { return 0; }
   virtual void execute(TRAPS);
 };
@@ -72,7 +72,7 @@
   static const char* description() {
     return "Print the command line used to start this VM instance.";
   }
-  static const char* impact() { return "Low: "; }
+  static const char* impact() { return "Low"; }
   static int num_arguments() { return 0; }
   virtual void execute(TRAPS) {
     Arguments::print_on(_output);
@@ -88,7 +88,7 @@
       return "Print system properties.";
     }
     static const char* impact() {
-      return "Low: ";
+      return "Low";
     }
     static int num_arguments() { return 0; }
     virtual void execute(TRAPS);
@@ -105,7 +105,7 @@
     return "Print VM flag options and their current values.";
   }
   static const char* impact() {
-    return "Low: ";
+    return "Low";
   }
   static int num_arguments();
   virtual void execute(TRAPS);
@@ -121,7 +121,7 @@
     return "Print VM uptime.";
   }
   static const char* impact() {
-    return "Low: ";
+    return "Low";
   }
   static int num_arguments();
   virtual void execute(TRAPS);
diff --git a/hotspot/src/share/vm/services/diagnosticFramework.cpp b/hotspot/src/share/vm/services/diagnosticFramework.cpp
index 73e9bdc..2ae7866 100644
--- a/hotspot/src/share/vm/services/diagnosticFramework.cpp
+++ b/hotspot/src/share/vm/services/diagnosticFramework.cpp
@@ -75,11 +75,13 @@
   }
   // extracting first item, argument or option name
   _key_addr = &_buffer[_cursor];
+  bool arg_had_quotes = false;
   while (_cursor <= _len - 1 && _buffer[_cursor] != '=' && _buffer[_cursor] != _delim) {
     // argument can be surrounded by single or double quotes
     if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') {
       _key_addr++;
       char quote = _buffer[_cursor];
+      arg_had_quotes = true;
       while (_cursor < _len - 1) {
         _cursor++;
         if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') {
@@ -95,16 +97,22 @@
     _cursor++;
   }
   _key_len = &_buffer[_cursor] - _key_addr;
+  if (arg_had_quotes) {
+    // if the argument was quoted, we need to step past the last quote here
+    _cursor++;
+  }
   // check if the argument has the <key>=<value> format
   if (_cursor <= _len -1 && _buffer[_cursor] == '=') {
     _cursor++;
     _value_addr = &_buffer[_cursor];
+    bool value_had_quotes = false;
     // extract the value
     while (_cursor <= _len - 1 && _buffer[_cursor] != _delim) {
       // value can be surrounded by simple or double quotes
       if (_buffer[_cursor] == '\"' || _buffer[_cursor] == '\'') {
         _value_addr++;
         char quote = _buffer[_cursor];
+        value_had_quotes = true;
         while (_cursor < _len - 1) {
           _cursor++;
           if (_buffer[_cursor] == quote && _buffer[_cursor - 1] != '\\') {
@@ -120,6 +128,10 @@
       _cursor++;
     }
     _value_len = &_buffer[_cursor] - _value_addr;
+    if (value_had_quotes) {
+      // if the value was quoted, we need to step past the last quote here
+      _cursor++;
+    }
   } else {
     _value_addr = NULL;
     _value_len = 0;
@@ -185,8 +197,17 @@
         arg->read_value(iter.key_addr(), iter.key_length(), CHECK);
         next_argument = next_argument->next();
       } else {
-        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-          "Unknown argument in diagnostic command");
+        const size_t buflen    = 120;
+        const size_t argbuflen = 30;
+        char buf[buflen];
+        char argbuf[argbuflen];
+        size_t len = MIN2<size_t>(iter.key_length(), argbuflen - 1);
+
+        strncpy(argbuf, iter.key_addr(), len);
+        argbuf[len] = '\0';
+        jio_snprintf(buf, buflen - 1, "Unknown argument '%s' in diagnostic command.", argbuf);
+
+        THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf);
       }
     }
     cont = iter.next(CHECK);
@@ -207,19 +228,21 @@
 }
 
 void DCmdParser::check(TRAPS) {
+  const size_t buflen = 256;
+  char buf[buflen];
   GenDCmdArgument* arg = _arguments_list;
   while (arg != NULL) {
     if (arg->is_mandatory() && !arg->has_value()) {
-      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-              "Missing argument for diagnostic command");
+      jio_snprintf(buf, buflen - 1, "The argument '%s' is mandatory.", arg->name());
+      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf);
     }
     arg = arg->next();
   }
   arg = _options;
   while (arg != NULL) {
     if (arg->is_mandatory() && !arg->has_value()) {
-      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-              "Missing option for diagnostic command");
+      jio_snprintf(buf, buflen - 1, "The option '%s' is mandatory.", arg->name());
+      THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(), buf);
     }
     arg = arg->next();
   }
diff --git a/hotspot/src/share/vm/services/diagnosticFramework.hpp b/hotspot/src/share/vm/services/diagnosticFramework.hpp
index f9ea562..08b24e0 100644
--- a/hotspot/src/share/vm/services/diagnosticFramework.hpp
+++ b/hotspot/src/share/vm/services/diagnosticFramework.hpp
@@ -238,6 +238,16 @@
   static const char* name() { return "No Name";}
   static const char* description() { return "No Help";}
   static const char* disabled_message() { return "Diagnostic command currently disabled"; }
+  // The impact() method returns a description of the intrusiveness of the diagnostic
+  // command on the Java Virtual Machine behavior. The rational for this method is that some
+  // diagnostic commands can seriously disrupt the behavior of the Java Virtual Machine
+  // (for instance a Thread Dump for an application with several tens of thousands of threads,
+  // or a Head Dump with a 40GB+ heap size) and other diagnostic commands have no serious
+  // impact on the JVM (for instance, getting the command line arguments or the JVM version).
+  // The recommended format for the description is <impact level>: [longer description],
+  // where the impact level is selected among this list: {Low, Medium, High}. The optional
+  // longer description can provide more specific details like the fact that Thread Dump
+  // impact depends on the heap size.
   static const char* impact() { return "Low: No impact"; }
   static int num_arguments() { return 0; }
   outputStream* output() { return _output; }
@@ -250,7 +260,7 @@
     bool has_arg = iter.next(CHECK);
     if (has_arg) {
       THROW_MSG(vmSymbols::java_lang_IllegalArgumentException(),
-                "Unknown argument in diagnostic command");
+                "The argument list of this diagnostic command should be empty.");
     }
   }
   virtual void execute(TRAPS) { }
@@ -310,7 +320,7 @@
 // manages the status of the diagnostic command (hidden, enabled). A DCmdFactory
 // has to be registered to make the diagnostic command available (see
 // management.cpp)
-class DCmdFactory: public CHeapObj {
+class DCmdFactory: public CHeapObj<mtInternal> {
 private:
   static Mutex*       _dcmdFactory_lock;
   // Pointer to the next factory in the singly-linked list of registered
@@ -368,7 +378,7 @@
     DCmdFactory(DCmdClass::num_arguments(), enabled, hidden) { }
   // Returns a C-heap allocated instance
   virtual DCmd* create_Cheap_instance(outputStream* output) {
-    return new (ResourceObj::C_HEAP) DCmdClass(output, true);
+    return new (ResourceObj::C_HEAP, mtInternal) DCmdClass(output, true);
   }
   // Returns a resourceArea allocated instance
   virtual DCmd* create_resource_instance(outputStream* output) {
diff --git a/hotspot/src/share/vm/services/gcNotifier.cpp b/hotspot/src/share/vm/services/gcNotifier.cpp
index 1670242..abb2dd6 100644
--- a/hotspot/src/share/vm/services/gcNotifier.cpp
+++ b/hotspot/src/share/vm/services/gcNotifier.cpp
@@ -45,7 +45,7 @@
   // GC may occur between now and the creation of the notification
   int num_pools = MemoryService::num_memory_pools();
   // stat is deallocated inside GCNotificationRequest
-  GCStatInfo* stat = new(ResourceObj::C_HEAP) GCStatInfo(num_pools);
+  GCStatInfo* stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(num_pools);
   mgr->get_last_gc_stat(stat);
   GCNotificationRequest *request = new GCNotificationRequest(os::javaTimeMillis(),mgr,action,cause,stat);
   addRequest(request);
@@ -163,8 +163,8 @@
   constructor_args.push_oop(gcInfo_instance);
   constructor_args.push_oop(getGcInfoBuilder(gcManager,THREAD));
   constructor_args.push_long(gcStatInfo->gc_index());
-  constructor_args.push_long(gcStatInfo->start_time());
-  constructor_args.push_long(gcStatInfo->end_time());
+  constructor_args.push_long(Management::ticks_to_ms(gcStatInfo->start_time()));
+  constructor_args.push_long(Management::ticks_to_ms(gcStatInfo->end_time()));
   constructor_args.push_oop(usage_before_gc_ah);
   constructor_args.push_oop(usage_after_gc_ah);
   constructor_args.push_oop(extra_array);
diff --git a/hotspot/src/share/vm/services/gcNotifier.hpp b/hotspot/src/share/vm/services/gcNotifier.hpp
index c26765e..1ac807b 100644
--- a/hotspot/src/share/vm/services/gcNotifier.hpp
+++ b/hotspot/src/share/vm/services/gcNotifier.hpp
@@ -30,7 +30,7 @@
 #include "services/memoryService.hpp"
 #include "services/memoryManager.hpp"
 
-class GCNotificationRequest : public CHeapObj {
+class GCNotificationRequest : public CHeapObj<mtInternal> {
   friend class GCNotifier;
   GCNotificationRequest *next;
   jlong timestamp;
diff --git a/hotspot/src/share/vm/services/heapDumper.cpp b/hotspot/src/share/vm/services/heapDumper.cpp
index 3cc0e5b..9fc8ee9 100644
--- a/hotspot/src/share/vm/services/heapDumper.cpp
+++ b/hotspot/src/share/vm/services/heapDumper.cpp
@@ -436,7 +436,7 @@
   // sufficient memory then reduce size until we can allocate something.
   _size = io_buffer_size;
   do {
-    _buffer = (char*)os::malloc(_size);
+    _buffer = (char*)os::malloc(_size, mtInternal);
     if (_buffer == NULL) {
       _size = _size >> 1;
     }
@@ -1405,7 +1405,7 @@
     _gc_before_heap_dump = gc_before_heap_dump;
     _is_segmented_dump = false;
     _dump_start = (jlong)-1;
-    _klass_map = new (ResourceObj::C_HEAP) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
+    _klass_map = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<Klass*>(INITIAL_CLASS_COUNT, true);
     _stack_traces = NULL;
     _num_threads = 0;
     if (oome) {
@@ -1426,7 +1426,7 @@
       for (int i=0; i < _num_threads; i++) {
         delete _stack_traces[i];
       }
-      FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces);
+      FREE_C_HEAP_ARRAY(ThreadStackTrace*, _stack_traces, mtInternal);
     }
     delete _klass_map;
   }
@@ -1650,9 +1650,6 @@
         if (fr->is_entry_frame()) {
           last_entry_frame = fr;
         }
-        if (fr->is_ricochet_frame()) {
-          fr->oops_ricochet_do(&blk, vf->register_map());
-        }
       }
       vf = vf->sender();
     }
@@ -1806,7 +1803,7 @@
   writer()->write_u4(0);                    // thread number
   writer()->write_u4(0);                    // frame count
 
-  _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads());
+  _stack_traces = NEW_C_HEAP_ARRAY(ThreadStackTrace*, Threads::number_of_threads(), mtInternal);
   int frame_serial_num = 0;
   for (JavaThread* thread = Threads::first(); thread != NULL ; thread = thread->next()) {
     oop threadObj = thread->threadObj();
@@ -2005,7 +2002,7 @@
                    dump_file_name, os::current_process_id(), dump_file_ext);
     }
     const size_t len = strlen(base_path) + 1;
-    my_path = (char*)os::malloc(len);
+    my_path = (char*)os::malloc(len, mtInternal);
     if (my_path == NULL) {
       warning("Cannot create heap dump file.  Out of system memory.");
       return;
@@ -2014,7 +2011,7 @@
   } else {
     // Append a sequence number id for dumps following the first
     const size_t len = strlen(base_path) + max_digit_chars + 2; // for '.' and \0
-    my_path = (char*)os::malloc(len);
+    my_path = (char*)os::malloc(len, mtInternal);
     if (my_path == NULL) {
       warning("Cannot create heap dump file.  Out of system memory.");
       return;
diff --git a/hotspot/src/share/vm/services/lowMemoryDetector.hpp b/hotspot/src/share/vm/services/lowMemoryDetector.hpp
index ce15bad..311a3a4 100644
--- a/hotspot/src/share/vm/services/lowMemoryDetector.hpp
+++ b/hotspot/src/share/vm/services/lowMemoryDetector.hpp
@@ -63,7 +63,7 @@
 class OopClosure;
 class MemoryPool;
 
-class ThresholdSupport : public CHeapObj {
+class ThresholdSupport : public CHeapObj<mtInternal> {
  private:
   bool            _support_high_threshold;
   bool            _support_low_threshold;
@@ -112,7 +112,7 @@
   }
 };
 
-class SensorInfo : public CHeapObj {
+class SensorInfo : public CHeapObj<mtInternal> {
 private:
   instanceOop     _sensor_obj;
   bool            _sensor_on;
diff --git a/hotspot/src/share/vm/services/management.cpp b/hotspot/src/share/vm/services/management.cpp
index 48a5b6a..a33ea21 100644
--- a/hotspot/src/share/vm/services/management.cpp
+++ b/hotspot/src/share/vm/services/management.cpp
@@ -47,6 +47,7 @@
 #include "services/jmm.h"
 #include "services/lowMemoryDetector.hpp"
 #include "services/gcNotifier.hpp"
+#include "services/nmtDCmd.hpp"
 #include "services/management.hpp"
 #include "services/memoryManager.hpp"
 #include "services/memoryPool.hpp"
@@ -121,6 +122,7 @@
   // Registration of the diagnostic commands
   DCmdRegistrant::register_dcmds();
   DCmdRegistrant::register_dcmds_ext();
+  DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<NMTDCmd>(true, false));
 }
 
 void Management::initialize(TRAPS) {
@@ -1810,31 +1812,37 @@
 
 class ThreadTimesClosure: public ThreadClosure {
  private:
-  objArrayOop _names;
+  objArrayHandle _names_strings;
+  char **_names_chars;
   typeArrayOop _times;
   int _names_len;
   int _times_len;
   int _count;
 
  public:
-  ThreadTimesClosure(objArrayOop names, typeArrayOop times);
+  ThreadTimesClosure(objArrayHandle names, typeArrayOop times);
+  ~ThreadTimesClosure();
   virtual void do_thread(Thread* thread);
+  void do_unlocked();
   int count() { return _count; }
 };
 
-ThreadTimesClosure::ThreadTimesClosure(objArrayOop names,
+ThreadTimesClosure::ThreadTimesClosure(objArrayHandle names,
                                        typeArrayOop times) {
-  assert(names != NULL, "names was NULL");
+  assert(names() != NULL, "names was NULL");
   assert(times != NULL, "times was NULL");
-  _names = names;
+  _names_strings = names;
   _names_len = names->length();
+  _names_chars = NEW_C_HEAP_ARRAY(char*, _names_len, mtInternal);
   _times = times;
   _times_len = times->length();
   _count = 0;
 }
 
+//
+// Called with Threads_lock held
+//
 void ThreadTimesClosure::do_thread(Thread* thread) {
-  Handle s;
   assert(thread != NULL, "thread was NULL");
 
   // exclude externally visible JavaThreads
@@ -1848,16 +1856,32 @@
   }
 
   EXCEPTION_MARK;
+  ResourceMark rm(THREAD); // thread->name() uses ResourceArea
 
   assert(thread->name() != NULL, "All threads should have a name");
-  s = java_lang_String::create_from_str(thread->name(), CHECK);
-  _names->obj_at_put(_count, s());
-
+  _names_chars[_count] = strdup(thread->name());
   _times->long_at_put(_count, os::is_thread_cpu_time_supported() ?
                         os::thread_cpu_time(thread) : -1);
   _count++;
 }
 
+// Called without Threads_lock, we can allocate String objects.
+void ThreadTimesClosure::do_unlocked() {
+
+  EXCEPTION_MARK;
+  for (int i = 0; i < _count; i++) {
+    Handle s = java_lang_String::create_from_str(_names_chars[i],  CHECK);
+    _names_strings->obj_at_put(i, s());
+  }
+}
+
+ThreadTimesClosure::~ThreadTimesClosure() {
+  for (int i = 0; i < _count; i++) {
+    free(_names_chars[i]);
+  }
+  FREE_C_HEAP_ARRAY(char *, _names_chars, mtInternal);
+}
+
 // Fills names with VM internal thread names and times with the corresponding
 // CPU times.  If names or times is NULL, a NullPointerException is thrown.
 // If the element type of names is not String, an IllegalArgumentException is
@@ -1884,12 +1908,12 @@
   typeArrayOop ta = typeArrayOop(JNIHandles::resolve_non_null(times));
   typeArrayHandle times_ah(THREAD, ta);
 
-  ThreadTimesClosure ttc(names_ah(), times_ah());
+  ThreadTimesClosure ttc(names_ah, times_ah());
   {
     MutexLockerEx ml(Threads_lock);
     Threads::threads_do(&ttc);
   }
-
+  ttc.do_unlocked();
   return ttc.count();
 JVM_END
 
diff --git a/hotspot/src/share/vm/services/memBaseline.cpp b/hotspot/src/share/vm/services/memBaseline.cpp
new file mode 100644
index 0000000..9127e00
--- /dev/null
+++ b/hotspot/src/share/vm/services/memBaseline.cpp
@@ -0,0 +1,468 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+#include "precompiled.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "memory/allocation.hpp"
+#include "services/memBaseline.hpp"
+#include "services/memTracker.hpp"
+
+MemType2Name MemBaseline::MemType2NameMap[NUMBER_OF_MEMORY_TYPE] = {
+  {mtJavaHeap,   "Java Heap"},
+  {mtClass,      "Class"},
+  {mtThreadStack,"Thread Stack"},
+  {mtThread,     "Thread"},
+  {mtCode,       "Code"},
+  {mtGC,         "GC"},
+  {mtCompiler,   "Compiler"},
+  {mtInternal,   "Internal"},
+  {mtOther,      "Other"},
+  {mtSymbol,     "Symbol"},
+  {mtNMT,        "Memory Tracking"},
+  {mtChunk,      "Pooled Free Chunks"},
+  {mtClassShared,"Shared spaces for classes"},
+  {mtNone,       "Unknown"}  // It can happen when type tagging records are lagging
+                             // behind
+};
+
+MemBaseline::MemBaseline() {
+  _baselined = false;
+
+  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+    _malloc_data[index].set_type(MemType2NameMap[index]._flag);
+    _vm_data[index].set_type(MemType2NameMap[index]._flag);
+    _arena_data[index].set_type(MemType2NameMap[index]._flag);
+  }
+
+  _malloc_cs = NULL;
+  _vm_cs = NULL;
+  _vm_map = NULL;
+
+  _number_of_classes = 0;
+  _number_of_threads = 0;
+}
+
+
+void MemBaseline::clear() {
+  if (_malloc_cs != NULL) {
+    delete _malloc_cs;
+    _malloc_cs = NULL;
+  }
+
+  if (_vm_cs != NULL) {
+    delete _vm_cs;
+    _vm_cs = NULL;
+  }
+
+  if (_vm_map != NULL) {
+    delete _vm_map;
+    _vm_map = NULL;
+  }
+
+  reset();
+}
+
+
+void MemBaseline::reset() {
+  _baselined = false;
+  _total_vm_reserved = 0;
+  _total_vm_committed = 0;
+  _total_malloced = 0;
+  _number_of_classes = 0;
+
+  if (_malloc_cs != NULL) _malloc_cs->clear();
+  if (_vm_cs != NULL) _vm_cs->clear();
+  if (_vm_map != NULL) _vm_map->clear();
+
+  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+    _malloc_data[index].clear();
+    _vm_data[index].clear();
+    _arena_data[index].clear();
+  }
+}
+
+MemBaseline::~MemBaseline() {
+  clear();
+}
+
+// baseline malloc'd memory records, generate overall summary and summaries by
+// memory types
+bool MemBaseline::baseline_malloc_summary(const MemPointerArray* malloc_records) {
+  MemPointerArrayIteratorImpl malloc_itr((MemPointerArray*)malloc_records);
+  MemPointerRecord* malloc_ptr = (MemPointerRecord*)malloc_itr.current();
+  size_t used_arena_size = 0;
+  int index;
+  while (malloc_ptr != NULL) {
+    index = flag2index(FLAGS_TO_MEMORY_TYPE(malloc_ptr->flags()));
+    size_t size = malloc_ptr->size();
+    if (malloc_ptr->is_arena_memory_record()) {
+      // We do have anonymous arenas, they are either used as value objects,
+      // which are embedded inside other objects, or used as stack objects.
+      _arena_data[index].inc(size);
+      used_arena_size += size;
+    } else {
+      _total_malloced += size;
+      _malloc_data[index].inc(size);
+      if (malloc_ptr->is_arena_record()) {
+        // see if arena memory record present
+        MemPointerRecord* next_malloc_ptr = (MemPointerRecordEx*)malloc_itr.peek_next();
+        if (next_malloc_ptr->is_arena_memory_record()) {
+          assert(next_malloc_ptr->is_memory_record_of_arena(malloc_ptr),
+             "Arena records do not match");
+          size = next_malloc_ptr->size();
+          _arena_data[index].inc(size);
+          used_arena_size += size;
+          malloc_itr.next();
+        }
+      }
+    }
+    malloc_ptr = (MemPointerRecordEx*)malloc_itr.next();
+  }
+
+  // substract used arena size to get size of arena chunk in free list
+  index = flag2index(mtChunk);
+  _malloc_data[index].reduce(used_arena_size);
+  // we really don't know how many chunks in free list, so just set to
+  // 0
+  _malloc_data[index].overwrite_counter(0);
+
+  return true;
+}
+
+// baseline mmap'd memory records, generate overall summary and summaries by
+// memory types
+bool MemBaseline::baseline_vm_summary(const MemPointerArray* vm_records) {
+  MemPointerArrayIteratorImpl vm_itr((MemPointerArray*)vm_records);
+  VMMemRegion* vm_ptr = (VMMemRegion*)vm_itr.current();
+  int index;
+  while (vm_ptr != NULL) {
+    if (vm_ptr->is_reserved_region()) {
+      index = flag2index(FLAGS_TO_MEMORY_TYPE(vm_ptr->flags()));
+    // we use the number of thread stack to count threads
+      if (IS_MEMORY_TYPE(vm_ptr->flags(), mtThreadStack)) {
+      _number_of_threads ++;
+    }
+      _total_vm_reserved += vm_ptr->size();
+      _vm_data[index].inc(vm_ptr->size(), 0);
+    } else {
+      _total_vm_committed += vm_ptr->size();
+      _vm_data[index].inc(0, vm_ptr->size());
+    }
+    vm_ptr = (VMMemRegion*)vm_itr.next();
+  }
+  return true;
+}
+
+// baseline malloc'd memory by callsites, but only the callsites with memory allocation
+// over 1KB are stored.
+bool MemBaseline::baseline_malloc_details(const MemPointerArray* malloc_records) {
+  assert(MemTracker::track_callsite(), "detail tracking is off");
+
+  MemPointerArrayIteratorImpl malloc_itr(const_cast<MemPointerArray*>(malloc_records));
+  MemPointerRecordEx* malloc_ptr = (MemPointerRecordEx*)malloc_itr.current();
+  MallocCallsitePointer malloc_callsite;
+
+  // initailize malloc callsite array
+  if (_malloc_cs == NULL) {
+    _malloc_cs = new (std::nothrow) MemPointerArrayImpl<MallocCallsitePointer>(64);
+    // out of native memory
+    if (_malloc_cs == NULL || _malloc_cs->out_of_memory()) {
+      return false;
+    }
+  } else {
+    _malloc_cs->clear();
+  }
+
+  MemPointerArray* malloc_data = const_cast<MemPointerArray*>(malloc_records);
+
+  // sort into callsite pc order. Details are aggregated by callsites
+  malloc_data->sort((FN_SORT)malloc_sort_by_pc);
+  bool ret = true;
+
+  // baseline memory that is totaled over 1 KB
+  while (malloc_ptr != NULL) {
+    if (!MemPointerRecord::is_arena_memory_record(malloc_ptr->flags())) {
+      // skip thread stacks
+      if (!IS_MEMORY_TYPE(malloc_ptr->flags(), mtThreadStack)) {
+        if (malloc_callsite.addr() != malloc_ptr->pc()) {
+          if ((malloc_callsite.amount()/K) > 0) {
+            if (!_malloc_cs->append(&malloc_callsite)) {
+              ret = false;
+              break;
+            }
+          }
+          malloc_callsite = MallocCallsitePointer(malloc_ptr->pc());
+        }
+        malloc_callsite.inc(malloc_ptr->size());
+      }
+    }
+    malloc_ptr = (MemPointerRecordEx*)malloc_itr.next();
+  }
+
+  // restore to address order. Snapshot malloc data is maintained in memory
+  // address order.
+  malloc_data->sort((FN_SORT)malloc_sort_by_addr);
+
+  if (!ret) {
+              return false;
+            }
+  // deal with last record
+  if (malloc_callsite.addr() != 0 && (malloc_callsite.amount()/K) > 0) {
+    if (!_malloc_cs->append(&malloc_callsite)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+// baseline mmap'd memory by callsites
+bool MemBaseline::baseline_vm_details(const MemPointerArray* vm_records) {
+  assert(MemTracker::track_callsite(), "detail tracking is off");
+
+  VMCallsitePointer  vm_callsite;
+  VMCallsitePointer* cur_callsite = NULL;
+  MemPointerArrayIteratorImpl vm_itr((MemPointerArray*)vm_records);
+  VMMemRegionEx* vm_ptr = (VMMemRegionEx*)vm_itr.current();
+
+  // initialize virtual memory map array
+  if (_vm_map == NULL) {
+    _vm_map = new (std::nothrow) MemPointerArrayImpl<VMMemRegionEx>(vm_records->length());
+   if (_vm_map == NULL || _vm_map->out_of_memory()) {
+     return false;
+   }
+  } else {
+    _vm_map->clear();
+  }
+
+  // initialize virtual memory callsite array
+  if (_vm_cs == NULL) {
+    _vm_cs = new (std::nothrow) MemPointerArrayImpl<VMCallsitePointer>(64);
+    if (_vm_cs == NULL || _vm_cs->out_of_memory()) {
+      return false;
+    }
+  } else {
+    _vm_cs->clear();
+  }
+
+  // consolidate virtual memory data
+  VMMemRegionEx*     reserved_rec = NULL;
+  VMMemRegionEx*     committed_rec = NULL;
+
+  // vm_ptr is coming in increasing base address order
+  while (vm_ptr != NULL) {
+    if (vm_ptr->is_reserved_region()) {
+      // consolidate reserved memory regions for virtual memory map.
+      // The criteria for consolidation is:
+      // 1. two adjacent reserved memory regions
+      // 2. belong to the same memory type
+      // 3. reserved from the same callsite
+      if (reserved_rec == NULL ||
+        reserved_rec->base() + reserved_rec->size() != vm_ptr->addr() ||
+        FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) != FLAGS_TO_MEMORY_TYPE(vm_ptr->flags()) ||
+        reserved_rec->pc() != vm_ptr->pc()) {
+        if (!_vm_map->append(vm_ptr)) {
+        return false;
+      }
+        // inserted reserved region, we need the pointer to the element in virtual
+        // memory map array.
+        reserved_rec = (VMMemRegionEx*)_vm_map->at(_vm_map->length() - 1);
+      } else {
+        reserved_rec->expand_region(vm_ptr->addr(), vm_ptr->size());
+    }
+
+      if (cur_callsite != NULL && !_vm_cs->append(cur_callsite)) {
+      return false;
+    }
+      vm_callsite = VMCallsitePointer(vm_ptr->pc());
+      cur_callsite = &vm_callsite;
+      vm_callsite.inc(vm_ptr->size(), 0);
+    } else {
+      // consolidate committed memory regions for virtual memory map
+      // The criterial is:
+      // 1. two adjacent committed memory regions
+      // 2. committed from the same callsite
+      if (committed_rec == NULL ||
+        committed_rec->base() + committed_rec->size() != vm_ptr->addr() ||
+        committed_rec->pc() != vm_ptr->pc()) {
+        if (!_vm_map->append(vm_ptr)) {
+          return false;
+  }
+        committed_rec = (VMMemRegionEx*)_vm_map->at(_vm_map->length() - 1);
+    } else {
+        committed_rec->expand_region(vm_ptr->addr(), vm_ptr->size());
+      }
+      vm_callsite.inc(0, vm_ptr->size());
+    }
+    vm_ptr = (VMMemRegionEx*)vm_itr.next();
+  }
+  // deal with last record
+  if (cur_callsite != NULL && !_vm_cs->append(cur_callsite)) {
+    return false;
+  }
+
+  // sort it into callsite pc order. Details are aggregated by callsites
+  _vm_cs->sort((FN_SORT)bl_vm_sort_by_pc);
+
+  // walk the array to consolidate record by pc
+  MemPointerArrayIteratorImpl itr(_vm_cs);
+  VMCallsitePointer* callsite_rec = (VMCallsitePointer*)itr.current();
+  VMCallsitePointer* next_rec = (VMCallsitePointer*)itr.next();
+  while (next_rec != NULL) {
+    assert(callsite_rec != NULL, "Sanity check");
+    if (next_rec->addr() == callsite_rec->addr()) {
+      callsite_rec->inc(next_rec->reserved_amount(), next_rec->committed_amount());
+      itr.remove();
+      next_rec = (VMCallsitePointer*)itr.current();
+    } else {
+      callsite_rec = next_rec;
+      next_rec = (VMCallsitePointer*)itr.next();
+    }
+  }
+
+  return true;
+}
+
+// baseline a snapshot. If summary_only = false, memory usages aggregated by
+// callsites are also baselined.
+bool MemBaseline::baseline(MemSnapshot& snapshot, bool summary_only) {
+  MutexLockerEx snapshot_locker(snapshot._lock, true);
+  reset();
+  _baselined = baseline_malloc_summary(snapshot._alloc_ptrs) &&
+               baseline_vm_summary(snapshot._vm_ptrs);
+  _number_of_classes = SystemDictionary::number_of_classes();
+
+  if (!summary_only && MemTracker::track_callsite() && _baselined) {
+    _baselined =  baseline_malloc_details(snapshot._alloc_ptrs) &&
+      baseline_vm_details(snapshot._vm_ptrs);
+  }
+  return _baselined;
+}
+
+
+int MemBaseline::flag2index(MEMFLAGS flag) const {
+  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+    if (MemType2NameMap[index]._flag == flag) {
+      return index;
+    }
+  }
+  assert(false, "no type");
+  return -1;
+}
+
+const char* MemBaseline::type2name(MEMFLAGS type) {
+  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+    if (MemType2NameMap[index]._flag == type) {
+      return MemType2NameMap[index]._name;
+    }
+  }
+  assert(false, err_msg("bad type %x", type));
+  return NULL;
+}
+
+
+MemBaseline& MemBaseline::operator=(const MemBaseline& other) {
+  _total_malloced = other._total_malloced;
+  _total_vm_reserved = other._total_vm_reserved;
+  _total_vm_committed = other._total_vm_committed;
+
+  _baselined = other._baselined;
+  _number_of_classes = other._number_of_classes;
+
+  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+    _malloc_data[index] = other._malloc_data[index];
+    _vm_data[index] = other._vm_data[index];
+    _arena_data[index] = other._arena_data[index];
+  }
+
+  if (MemTracker::track_callsite()) {
+    assert(_malloc_cs != NULL && _vm_cs != NULL, "out of memory");
+    assert(other._malloc_cs != NULL && other._vm_cs != NULL,
+           "not properly baselined");
+    _malloc_cs->clear();
+    _vm_cs->clear();
+    int index;
+    for (index = 0; index < other._malloc_cs->length(); index ++) {
+      _malloc_cs->append(other._malloc_cs->at(index));
+    }
+
+    for (index = 0; index < other._vm_cs->length(); index ++) {
+      _vm_cs->append(other._vm_cs->at(index));
+    }
+  }
+  return *this;
+}
+
+/* compare functions for sorting */
+
+// sort snapshot malloc'd records in callsite pc order
+int MemBaseline::malloc_sort_by_pc(const void* p1, const void* p2) {
+  assert(MemTracker::track_callsite(),"Just check");
+  const MemPointerRecordEx* mp1 = (const MemPointerRecordEx*)p1;
+  const MemPointerRecordEx* mp2 = (const MemPointerRecordEx*)p2;
+  return UNSIGNED_COMPARE(mp1->pc(), mp2->pc());
+}
+
+// sort baselined malloc'd records in size order
+int MemBaseline::bl_malloc_sort_by_size(const void* p1, const void* p2) {
+  assert(MemTracker::is_on(), "Just check");
+  const MallocCallsitePointer* mp1 = (const MallocCallsitePointer*)p1;
+  const MallocCallsitePointer* mp2 = (const MallocCallsitePointer*)p2;
+  return UNSIGNED_COMPARE(mp2->amount(), mp1->amount());
+}
+
+// sort baselined malloc'd records in callsite pc order
+int MemBaseline::bl_malloc_sort_by_pc(const void* p1, const void* p2) {
+  assert(MemTracker::is_on(), "Just check");
+  const MallocCallsitePointer* mp1 = (const MallocCallsitePointer*)p1;
+  const MallocCallsitePointer* mp2 = (const MallocCallsitePointer*)p2;
+  return UNSIGNED_COMPARE(mp1->addr(), mp2->addr());
+}
+
+
+// sort baselined mmap'd records in size (reserved size) order
+int MemBaseline::bl_vm_sort_by_size(const void* p1, const void* p2) {
+  assert(MemTracker::is_on(), "Just check");
+  const VMCallsitePointer* mp1 = (const VMCallsitePointer*)p1;
+  const VMCallsitePointer* mp2 = (const VMCallsitePointer*)p2;
+  return UNSIGNED_COMPARE(mp2->reserved_amount(), mp1->reserved_amount());
+}
+
+// sort baselined mmap'd records in callsite pc order
+int MemBaseline::bl_vm_sort_by_pc(const void* p1, const void* p2) {
+  assert(MemTracker::is_on(), "Just check");
+  const VMCallsitePointer* mp1 = (const VMCallsitePointer*)p1;
+  const VMCallsitePointer* mp2 = (const VMCallsitePointer*)p2;
+  return UNSIGNED_COMPARE(mp1->addr(), mp2->addr());
+}
+
+
+// sort snapshot malloc'd records in memory block address order
+int MemBaseline::malloc_sort_by_addr(const void* p1, const void* p2) {
+  assert(MemTracker::is_on(), "Just check");
+  const MemPointerRecord* mp1 = (const MemPointerRecord*)p1;
+  const MemPointerRecord* mp2 = (const MemPointerRecord*)p2;
+  int delta = UNSIGNED_COMPARE(mp1->addr(), mp2->addr());
+  assert(delta != 0, "dup pointer");
+  return delta;
+}
+
diff --git a/hotspot/src/share/vm/services/memBaseline.hpp b/hotspot/src/share/vm/services/memBaseline.hpp
new file mode 100644
index 0000000..5f98e30
--- /dev/null
+++ b/hotspot/src/share/vm/services/memBaseline.hpp
@@ -0,0 +1,446 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_MEM_BASELINE_HPP
+#define SHARE_VM_SERVICES_MEM_BASELINE_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/mutex.hpp"
+#include "services/memPtr.hpp"
+#include "services/memSnapshot.hpp"
+
+// compare unsigned number
+#define UNSIGNED_COMPARE(a, b)  ((a > b) ? 1 : ((a == b) ? 0 : -1))
+
+/*
+ * MallocCallsitePointer and VMCallsitePointer are used
+ * to baseline memory blocks with their callsite information.
+ * They are only available when detail tracking is turned
+ * on.
+ */
+
+/* baselined malloc record aggregated by callsite */
+class MallocCallsitePointer : public MemPointer {
+ private:
+  size_t    _count;   // number of malloc invocation from this callsite
+  size_t    _amount;  // total amount of memory malloc-ed from this callsite
+
+ public:
+  MallocCallsitePointer() {
+    _count = 0;
+    _amount = 0;
+  }
+
+  MallocCallsitePointer(address pc) : MemPointer(pc) {
+    _count = 0;
+    _amount = 0;
+  }
+
+  MallocCallsitePointer& operator=(const MallocCallsitePointer& p) {
+    MemPointer::operator=(p);
+    _count = p.count();
+    _amount = p.amount();
+    return *this;
+  }
+
+  inline void inc(size_t size) {
+    _count ++;
+    _amount += size;
+  };
+
+  inline size_t count() const {
+    return _count;
+  }
+
+  inline size_t amount() const {
+    return _amount;
+  }
+};
+
+// baselined virtual memory record aggregated by callsite
+class VMCallsitePointer : public MemPointer {
+ private:
+  size_t     _count;              // number of invocation from this callsite
+  size_t     _reserved_amount;    // total reserved amount
+  size_t     _committed_amount;   // total committed amount
+
+ public:
+  VMCallsitePointer() {
+    _count = 0;
+    _reserved_amount = 0;
+    _committed_amount = 0;
+  }
+
+  VMCallsitePointer(address pc) : MemPointer(pc) {
+    _count = 0;
+    _reserved_amount = 0;
+    _committed_amount = 0;
+  }
+
+  VMCallsitePointer& operator=(const VMCallsitePointer& p) {
+    MemPointer::operator=(p);
+    _count = p.count();
+    _reserved_amount = p.reserved_amount();
+    _committed_amount = p.committed_amount();
+    return *this;
+  }
+
+  inline void inc(size_t reserved, size_t committed) {
+    _count ++;
+    _reserved_amount += reserved;
+    _committed_amount += committed;
+  }
+
+  inline size_t count() const {
+    return _count;
+  }
+
+  inline size_t reserved_amount() const {
+    return _reserved_amount;
+  }
+
+  inline size_t committed_amount() const {
+    return _committed_amount;
+  }
+};
+
+// maps a memory type flag to readable name
+typedef struct _memType2Name {
+  MEMFLAGS     _flag;
+  const char*  _name;
+} MemType2Name;
+
+
+// This class aggregates malloc'd records by memory type
+class MallocMem : public _ValueObj {
+ private:
+  MEMFLAGS       _type;
+
+  size_t         _count;
+  size_t         _amount;
+
+ public:
+  MallocMem() {
+    _type = mtNone;
+    _count = 0;
+    _amount = 0;
+  }
+
+  MallocMem(MEMFLAGS flags) {
+    assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
+    _type = FLAGS_TO_MEMORY_TYPE(flags);
+    _count = 0;
+    _amount = 0;
+  }
+
+  inline void set_type(MEMFLAGS flag) {
+    _type = flag;
+  }
+
+  inline void clear() {
+    _count = 0;
+    _amount = 0;
+    _type = mtNone;
+  }
+
+  MallocMem& operator=(const MallocMem& m) {
+    assert(_type == m.type(), "different type");
+    _count = m.count();
+    _amount = m.amount();
+    return *this;
+  }
+
+  inline void inc(size_t amt) {
+    _amount += amt;
+    _count ++;
+  }
+
+  inline void reduce(size_t amt) {
+    assert(_amount >= amt, "Just check");
+    _amount -= amt;
+  }
+
+  inline void overwrite_counter(size_t count) {
+    _count = count;
+  }
+
+  inline MEMFLAGS type() const {
+    return _type;
+  }
+
+  inline bool is_type(MEMFLAGS flags) const {
+    return FLAGS_TO_MEMORY_TYPE(flags) == _type;
+  }
+
+  inline size_t count() const {
+    return _count;
+  }
+
+  inline size_t amount() const {
+    return _amount;
+  }
+};
+
+// This class records live arena's memory usage
+class ArenaMem : public MallocMem {
+ public:
+  ArenaMem(MEMFLAGS typeflag): MallocMem(typeflag) {
+  }
+  ArenaMem() { }
+};
+
+// This class aggregates virtual memory by its memory type
+class VMMem : public _ValueObj {
+ private:
+  MEMFLAGS       _type;
+
+  size_t         _count;
+  size_t         _reserved_amount;
+  size_t         _committed_amount;
+
+ public:
+  VMMem() {
+    _type = mtNone;
+    _count = 0;
+    _reserved_amount = 0;
+    _committed_amount = 0;
+  }
+
+  VMMem(MEMFLAGS flags) {
+    assert(HAS_VALID_MEMORY_TYPE(flags), "no type");
+    _type = FLAGS_TO_MEMORY_TYPE(flags);
+    _count = 0;
+    _reserved_amount = 0;
+    _committed_amount = 0;
+  }
+
+  inline void clear() {
+    _type = mtNone;
+    _count = 0;
+    _reserved_amount = 0;
+    _committed_amount = 0;
+  }
+
+  inline void set_type(MEMFLAGS flags) {
+    _type = FLAGS_TO_MEMORY_TYPE(flags);
+  }
+
+  VMMem& operator=(const VMMem& m) {
+    assert(_type == m.type(), "different type");
+
+    _count = m.count();
+    _reserved_amount = m.reserved_amount();
+    _committed_amount = m.committed_amount();
+    return *this;
+  }
+
+
+  inline MEMFLAGS type() const {
+    return _type;
+  }
+
+  inline bool is_type(MEMFLAGS flags) const {
+    return FLAGS_TO_MEMORY_TYPE(flags) == _type;
+  }
+
+  inline void inc(size_t reserved_amt, size_t committed_amt) {
+    _reserved_amount += reserved_amt;
+    _committed_amount += committed_amt;
+    _count ++;
+  }
+
+  inline size_t count() const {
+    return _count;
+  }
+
+  inline size_t reserved_amount() const {
+    return _reserved_amount;
+  }
+
+  inline size_t committed_amount() const {
+    return _committed_amount;
+  }
+};
+
+
+
+#define NUMBER_OF_MEMORY_TYPE    (mt_number_of_types + 1)
+
+class BaselineReporter;
+class BaselineComparisonReporter;
+
+/*
+ * This class baselines current memory snapshot.
+ * A memory baseline summarizes memory usage by memory type,
+ * aggregates memory usage by callsites when detail tracking
+ * is on.
+ */
+class MemBaseline : public _ValueObj {
+  friend class BaselineReporter;
+  friend class BaselineComparisonReporter;
+
+ private:
+  // overall summaries
+  size_t        _total_malloced;
+  size_t        _total_vm_reserved;
+  size_t        _total_vm_committed;
+  size_t        _number_of_classes;
+  size_t        _number_of_threads;
+
+  // if it has properly baselined
+  bool          _baselined;
+
+  // we categorize memory into three categories within the memory type
+  MallocMem     _malloc_data[NUMBER_OF_MEMORY_TYPE];
+  VMMem         _vm_data[NUMBER_OF_MEMORY_TYPE];
+  ArenaMem      _arena_data[NUMBER_OF_MEMORY_TYPE];
+
+  // memory records that aggregate memory usage by callsites.
+  // only available when detail tracking is on.
+  MemPointerArray*  _malloc_cs;
+  MemPointerArray*  _vm_cs;
+  // virtual memory map
+  MemPointerArray*  _vm_map;
+
+ private:
+  static MemType2Name  MemType2NameMap[NUMBER_OF_MEMORY_TYPE];
+
+ private:
+  // should not use copy constructor
+  MemBaseline(MemBaseline& copy) { ShouldNotReachHere(); }
+
+ public:
+  // create a memory baseline
+  MemBaseline();
+
+  virtual ~MemBaseline();
+
+  inline bool baselined() const {
+    return _baselined;
+  }
+
+  MemBaseline& operator=(const MemBaseline& other);
+
+  // reset the baseline for reuse
+  void clear();
+
+  // baseline the snapshot
+  bool baseline(MemSnapshot& snapshot, bool summary_only = true);
+
+  bool baseline(const MemPointerArray* malloc_records,
+                const MemPointerArray* vm_records,
+                bool summary_only = true);
+
+  // total malloc'd memory of specified memory type
+  inline size_t malloc_amount(MEMFLAGS flag) const {
+    return _malloc_data[flag2index(flag)].amount();
+  }
+  // number of malloc'd memory blocks of specified memory type
+  inline size_t malloc_count(MEMFLAGS flag) const {
+    return _malloc_data[flag2index(flag)].count();
+  }
+  // total memory used by arenas of specified memory type
+  inline size_t arena_amount(MEMFLAGS flag) const {
+    return _arena_data[flag2index(flag)].amount();
+  }
+  // number of arenas of specified memory type
+  inline size_t arena_count(MEMFLAGS flag) const {
+    return _arena_data[flag2index(flag)].count();
+  }
+  // total reserved memory of specified memory type
+  inline size_t reserved_amount(MEMFLAGS flag) const {
+    return _vm_data[flag2index(flag)].reserved_amount();
+  }
+  // total committed memory of specified memory type
+  inline size_t committed_amount(MEMFLAGS flag) const {
+    return _vm_data[flag2index(flag)].committed_amount();
+  }
+  // total memory (malloc'd + mmap'd + arena) of specified
+  // memory type
+  inline size_t total_amount(MEMFLAGS flag) const {
+    int index = flag2index(flag);
+    return _malloc_data[index].amount() +
+           _vm_data[index].reserved_amount() +
+           _arena_data[index].amount();
+  }
+
+  /* overall summaries */
+
+  // total malloc'd memory in snapshot
+  inline size_t total_malloc_amount() const {
+    return _total_malloced;
+  }
+  // total mmap'd memory in snapshot
+  inline size_t total_reserved_amount() const {
+    return _total_vm_reserved;
+  }
+  // total committed memory in snapshot
+  inline size_t total_committed_amount() const {
+    return _total_vm_committed;
+  }
+  // number of loaded classes
+  inline size_t number_of_classes() const {
+    return _number_of_classes;
+  }
+  // number of running threads
+  inline size_t number_of_threads() const {
+    return _number_of_threads;
+  }
+  // lookup human readable name of a memory type
+  static const char* type2name(MEMFLAGS type);
+
+ private:
+  // convert memory flag to the index to mapping table
+  int         flag2index(MEMFLAGS flag) const;
+
+  // reset baseline values
+  void reset();
+
+  // summarize the records in global snapshot
+  bool baseline_malloc_summary(const MemPointerArray* malloc_records);
+  bool baseline_vm_summary(const MemPointerArray* vm_records);
+  bool baseline_malloc_details(const MemPointerArray* malloc_records);
+  bool baseline_vm_details(const MemPointerArray* vm_records);
+
+  // print a line of malloc'd memory aggregated by callsite
+  void print_malloc_callsite(outputStream* st, address pc, size_t size,
+    size_t count, int diff_amt, int diff_count) const;
+  // print a line of mmap'd memory aggregated by callsite
+  void print_vm_callsite(outputStream* st, address pc, size_t rsz,
+    size_t csz, int diff_rsz, int diff_csz) const;
+
+  // sorting functions for raw records
+  static int malloc_sort_by_pc(const void* p1, const void* p2);
+  static int malloc_sort_by_addr(const void* p1, const void* p2);
+
+ private:
+  // sorting functions for baselined records
+  static int bl_malloc_sort_by_size(const void* p1, const void* p2);
+  static int bl_vm_sort_by_size(const void* p1, const void* p2);
+  static int bl_malloc_sort_by_pc(const void* p1, const void* p2);
+  static int bl_vm_sort_by_pc(const void* p1, const void* p2);
+};
+
+
+#endif // SHARE_VM_SERVICES_MEM_BASELINE_HPP
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/hotspot/src/share/vm/services/memPtr.cpp
similarity index 60%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to hotspot/src/share/vm/services/memPtr.cpp
index 077886f..5d0fbf5 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/hotspot/src/share/vm/services/memPtr.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -22,14 +22,21 @@
  *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+#include "precompiled.hpp"
+#include "services/memPtr.hpp"
+#include "services/memTracker.hpp"
 
-    public FileFormatException() {
-        super();
-    }
+volatile jint SequenceGenerator::_seq_number = 1;
+NOT_PRODUCT(jint SequenceGenerator::_max_seq_number = 1;)
+DEBUG_ONLY(volatile unsigned long SequenceGenerator::_generation = 0;)
 
-    public FileFormatException(String s) {
-        super(s);
-    }
+jint SequenceGenerator::next() {
+  jint seq = Atomic::add(1, &_seq_number);
+  if (seq < 0) {
+    MemTracker::shutdown(MemTracker::NMT_sequence_overflow);
+  }
+  assert(seq > 0, "counter overflow");
+  NOT_PRODUCT(_max_seq_number = (seq > _max_seq_number) ? seq : _max_seq_number;)
+  return seq;
 }
+
diff --git a/hotspot/src/share/vm/services/memPtr.hpp b/hotspot/src/share/vm/services/memPtr.hpp
new file mode 100644
index 0000000..a27c3eb
--- /dev/null
+++ b/hotspot/src/share/vm/services/memPtr.hpp
@@ -0,0 +1,511 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_MEM_PTR_HPP
+#define SHARE_VM_SERVICES_MEM_PTR_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/atomic.hpp"
+#include "runtime/os.hpp"
+#include "runtime/safepoint.hpp"
+
+/*
+ * global sequence generator that generates sequence numbers to serialize
+ * memory records.
+ */
+class SequenceGenerator : AllStatic {
+ public:
+  static jint next();
+
+  // peek last sequence number
+  static jint peek() {
+    return _seq_number;
+  }
+
+  // reset sequence number
+  static void reset() {
+    assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
+    _seq_number = 1;
+    DEBUG_ONLY(_generation ++;)
+  };
+
+  DEBUG_ONLY(static unsigned long current_generation() { return (unsigned long)_generation; })
+  NOT_PRODUCT(static jint max_seq_num() { return _max_seq_number; })
+
+ private:
+  static volatile jint _seq_number;
+  NOT_PRODUCT(static jint _max_seq_number; )
+  DEBUG_ONLY(static volatile unsigned long _generation; )
+};
+
+/*
+ * followings are the classes that are used to hold memory activity records in different stages.
+ *   MemPointer
+ *     |--------MemPointerRecord
+ *                     |
+ *                     |----MemPointerRecordEx
+ *                     |           |
+ *                     |           |-------SeqMemPointerRecordEx
+ *                     |
+ *                     |----SeqMemPointerRecord
+ *                     |
+ *                     |----VMMemRegion
+ *                               |
+ *                               |-----VMMemRegionEx
+ *
+ *
+ *  prefix 'Seq' - sequenced, the record contains a sequence number
+ *  surfix 'Ex'  - extension, the record contains a caller's pc
+ *
+ *  per-thread recorder : SeqMemPointerRecord(Ex)
+ *  snapshot staging    : SeqMemPointerRecord(Ex)
+ *  snapshot            : MemPointerRecord(Ex) and VMMemRegion(Ex)
+ *
+ */
+
+/*
+ * class that wraps an address to a memory block,
+ * the memory pointer either points to a malloc'd
+ * memory block, or a mmap'd memory block
+ */
+class MemPointer : public _ValueObj {
+ public:
+  MemPointer(): _addr(0) { }
+  MemPointer(address addr): _addr(addr) { }
+
+  MemPointer(const MemPointer& copy_from) {
+    _addr = copy_from.addr();
+  }
+
+  inline address addr() const {
+    return _addr;
+  }
+
+  inline operator address() const {
+    return addr();
+  }
+
+  inline bool operator == (const MemPointer& other) const {
+    return addr() == other.addr();
+  }
+
+  inline MemPointer& operator = (const MemPointer& other) {
+    _addr = other.addr();
+    return *this;
+  }
+
+ protected:
+  inline void set_addr(address addr) { _addr = addr; }
+
+ protected:
+  // memory address
+  address    _addr;
+};
+
+/* MemPointerRecord records an activityand associated
+ * attributes on a memory block.
+ */
+class MemPointerRecord : public MemPointer {
+ private:
+  MEMFLAGS       _flags;
+  size_t         _size;
+
+public:
+  /* extension of MemoryType enum
+   * see share/vm/memory/allocation.hpp for details.
+   *
+   * The tag values are associated to sorting orders, so be
+   * careful if changes are needed.
+   * The allocation records should be sorted ahead of tagging
+   * records, which in turn ahead of deallocation records
+   */
+  enum MemPointerTags {
+    tag_alloc            = 0x0001, // malloc or reserve record
+    tag_commit           = 0x0002, // commit record
+    tag_type             = 0x0003, // tag virtual memory to a memory type
+    tag_uncommit         = 0x0004, // uncommit record
+    tag_release          = 0x0005, // free or release record
+    tag_size             = 0x0006, // arena size
+    tag_masks            = 0x0007, // all tag bits
+    vmBit                = 0x0008
+  };
+
+  /* helper functions to interpret the tagging flags */
+
+  inline static bool is_allocation_record(MEMFLAGS flags) {
+    return (flags & tag_masks) == tag_alloc;
+  }
+
+  inline static bool is_deallocation_record(MEMFLAGS flags) {
+    return (flags & tag_masks) == tag_release;
+  }
+
+  inline static bool is_arena_record(MEMFLAGS flags) {
+    return (flags & (otArena | tag_size)) == otArena;
+  }
+
+  inline static bool is_arena_memory_record(MEMFLAGS flags) {
+    return (flags & (otArena | tag_size)) == (otArena | tag_size);
+  }
+
+  inline static bool is_virtual_memory_record(MEMFLAGS flags) {
+    return (flags & vmBit) != 0;
+  }
+
+  inline static bool is_virtual_memory_reserve_record(MEMFLAGS flags) {
+    return (flags & 0x0F) == (tag_alloc | vmBit);
+  }
+
+  inline static bool is_virtual_memory_commit_record(MEMFLAGS flags) {
+    return (flags & 0x0F) == (tag_commit | vmBit);
+  }
+
+  inline static bool is_virtual_memory_uncommit_record(MEMFLAGS flags) {
+    return (flags & 0x0F) == (tag_uncommit | vmBit);
+  }
+
+  inline static bool is_virtual_memory_release_record(MEMFLAGS flags) {
+    return (flags & 0x0F) == (tag_release | vmBit);
+  }
+
+  inline static bool is_virtual_memory_type_record(MEMFLAGS flags) {
+    return (flags & 0x0F) == (tag_type | vmBit);
+  }
+
+  /* tagging flags */
+  inline static MEMFLAGS malloc_tag()                 { return tag_alloc;   }
+  inline static MEMFLAGS free_tag()                   { return tag_release; }
+  inline static MEMFLAGS arena_size_tag()             { return tag_size | otArena; }
+  inline static MEMFLAGS virtual_memory_tag()         { return vmBit; }
+  inline static MEMFLAGS virtual_memory_reserve_tag() { return (tag_alloc | vmBit); }
+  inline static MEMFLAGS virtual_memory_commit_tag()  { return (tag_commit | vmBit); }
+  inline static MEMFLAGS virtual_memory_uncommit_tag(){ return (tag_uncommit | vmBit); }
+  inline static MEMFLAGS virtual_memory_release_tag() { return (tag_release | vmBit); }
+  inline static MEMFLAGS virtual_memory_type_tag()    { return (tag_type | vmBit); }
+
+ public:
+  MemPointerRecord(): _size(0), _flags(mtNone) { }
+
+  MemPointerRecord(address addr, MEMFLAGS memflags, size_t size = 0):
+      MemPointer(addr), _flags(memflags), _size(size) { }
+
+  MemPointerRecord(const MemPointerRecord& copy_from):
+    MemPointer(copy_from), _flags(copy_from.flags()),
+    _size(copy_from.size()) {
+  }
+
+  /* MemPointerRecord is not sequenced, it always return
+   * 0 to indicate non-sequenced
+   */
+  virtual jint seq() const               { return 0; }
+
+  inline size_t   size()  const          { return _size; }
+  inline void set_size(size_t size)      { _size = size; }
+
+  inline MEMFLAGS flags() const          { return _flags; }
+  inline void set_flags(MEMFLAGS flags)  { _flags = flags; }
+
+  MemPointerRecord& operator= (const MemPointerRecord& ptr) {
+    MemPointer::operator=(ptr);
+    _flags = ptr.flags();
+#ifdef ASSERT
+    if (IS_ARENA_OBJ(_flags)) {
+      assert(!is_vm_pointer(), "wrong flags");
+      assert((_flags & ot_masks) == otArena, "wrong flags");
+    }
+#endif
+    _size = ptr.size();
+    return *this;
+  }
+
+  // if the pointer represents a malloc-ed memory address
+  inline bool is_malloced_pointer() const {
+    return !is_vm_pointer();
+  }
+
+  // if the pointer represents a virtual memory address
+  inline bool is_vm_pointer() const {
+    return is_virtual_memory_record(_flags);
+  }
+
+  // if this record records a 'malloc' or virtual memory
+  // 'reserve' call
+  inline bool is_allocation_record() const {
+    return is_allocation_record(_flags);
+  }
+
+  // if this record records a size information of an arena
+  inline bool is_arena_memory_record() const {
+    return is_arena_memory_record(_flags);
+  }
+
+  // if this pointer represents an address to an arena object
+  inline bool is_arena_record() const {
+    return is_arena_record(_flags);
+  }
+
+  // if this record represents a size information of specific arena
+  inline bool is_memory_record_of_arena(const MemPointerRecord* arena_rc) {
+    assert(is_arena_memory_record(), "not size record");
+    assert(arena_rc->is_arena_record(), "not arena record");
+    return (arena_rc->addr() + sizeof(void*)) == addr();
+  }
+
+  // if this record records a 'free' or virtual memory 'free' call
+  inline bool is_deallocation_record() const {
+    return is_deallocation_record(_flags);
+  }
+
+  // if this record records a virtual memory 'commit' call
+  inline bool is_commit_record() const {
+    return is_virtual_memory_commit_record(_flags);
+  }
+
+  // if this record records a virtual memory 'uncommit' call
+  inline bool is_uncommit_record() const {
+    return is_virtual_memory_uncommit_record(_flags);
+  }
+
+  // if this record is a tagging record of a virtual memory block
+  inline bool is_type_tagging_record() const {
+    return is_virtual_memory_type_record(_flags);
+  }
+
+  // if the two memory pointer records actually represent the same
+  // memory block
+  inline bool is_same_region(const MemPointerRecord* other) const {
+    return (addr() == other->addr() && size() == other->size());
+  }
+
+  // if this memory region fully contains another one
+  inline bool contains_region(const MemPointerRecord* other) const {
+    return contains_region(other->addr(), other->size());
+  }
+
+  // if this memory region fully contains specified memory range
+  inline bool contains_region(address add, size_t sz) const {
+    return (addr() <= add && addr() + size() >= add + sz);
+  }
+
+  inline bool contains_address(address add) const {
+    return (addr() <= add && addr() + size() > add);
+  }
+
+  // if this memory region overlaps another region
+  inline bool overlaps_region(const MemPointerRecord* other) const {
+    assert(other != NULL, "Just check");
+    assert(size() > 0 && other->size() > 0, "empty range");
+    return contains_address(other->addr()) ||
+           contains_address(other->addr() + other->size() - 1) || // exclude end address
+           other->contains_address(addr()) ||
+           other->contains_address(addr() + size() - 1); // exclude end address
+  }
+
+};
+
+// MemPointerRecordEx also records callsite pc, from where
+// the memory block is allocated
+class MemPointerRecordEx : public MemPointerRecord {
+ private:
+  address      _pc;  // callsite pc
+
+ public:
+  MemPointerRecordEx(): _pc(0) { }
+
+  MemPointerRecordEx(address addr, MEMFLAGS memflags, size_t size = 0, address pc = 0):
+    MemPointerRecord(addr, memflags, size), _pc(pc) {}
+
+  MemPointerRecordEx(const MemPointerRecordEx& copy_from):
+    MemPointerRecord(copy_from), _pc(copy_from.pc()) {}
+
+  inline address pc() const { return _pc; }
+
+  void init(const MemPointerRecordEx* mpe) {
+    MemPointerRecord::operator=(*mpe);
+    _pc = mpe->pc();
+  }
+
+  void init(const MemPointerRecord* mp) {
+    MemPointerRecord::operator=(*mp);
+    _pc = 0;
+  }
+};
+
+// a virtual memory region. The region can represent a reserved
+// virtual memory region or a committed memory region
+class VMMemRegion : public MemPointerRecord {
+public:
+  VMMemRegion() { }
+
+  void init(const MemPointerRecord* mp) {
+    assert(mp->is_vm_pointer(), "Sanity check");
+    _addr = mp->addr();
+      set_size(mp->size());
+    set_flags(mp->flags());
+  }
+
+  VMMemRegion& operator=(const VMMemRegion& other) {
+    MemPointerRecord::operator=(other);
+    return *this;
+  }
+
+  inline bool is_reserved_region() const {
+    return is_allocation_record();
+  }
+
+  inline bool is_committed_region() const {
+    return is_commit_record();
+  }
+
+  /* base address of this virtual memory range */
+  inline address base() const {
+    return addr();
+  }
+
+  /* tag this virtual memory range to the specified memory type */
+  inline void tag(MEMFLAGS f) {
+    set_flags(flags() | (f & mt_masks));
+  }
+
+  // expand this region to also cover specified range.
+  // The range has to be on either end of the memory region.
+  void expand_region(address addr, size_t sz) {
+    if (addr < base()) {
+      assert(addr + sz == base(), "Sanity check");
+      _addr = addr;
+      set_size(size() + sz);
+    } else {
+      assert(base() + size() == addr, "Sanity check");
+      set_size(size() + sz);
+    }
+  }
+
+  // exclude the specified address range from this region.
+  // The excluded memory range has to be on either end of this memory
+  // region.
+  inline void exclude_region(address add, size_t sz) {
+    assert(is_reserved_region() || is_committed_region(), "Sanity check");
+    assert(addr() != NULL && size() != 0, "Sanity check");
+    assert(add >= addr() && add < addr() + size(), "Sanity check");
+    assert(add == addr() || (add + sz) == (addr() + size()),
+      "exclude in the middle");
+    if (add == addr()) {
+      set_addr(add + sz);
+      set_size(size() - sz);
+    } else {
+      set_size(size() - sz);
+    }
+  }
+};
+
+class VMMemRegionEx : public VMMemRegion {
+ private:
+  jint   _seq;  // sequence number
+
+ public:
+  VMMemRegionEx(): _pc(0) { }
+
+  void init(const MemPointerRecordEx* mpe) {
+    VMMemRegion::init(mpe);
+    _pc = mpe->pc();
+  }
+
+  void init(const MemPointerRecord* mpe) {
+    VMMemRegion::init(mpe);
+    _pc = 0;
+  }
+
+  VMMemRegionEx& operator=(const VMMemRegionEx& other) {
+    VMMemRegion::operator=(other);
+    _pc = other.pc();
+    return *this;
+  }
+
+  inline address pc() const { return _pc; }
+ private:
+  address   _pc;
+};
+
+/*
+ * Sequenced memory record
+ */
+class SeqMemPointerRecord : public MemPointerRecord {
+ private:
+   jint _seq;  // sequence number
+
+ public:
+  SeqMemPointerRecord(): _seq(0){ }
+
+  SeqMemPointerRecord(address addr, MEMFLAGS flags, size_t size)
+    : MemPointerRecord(addr, flags, size) {
+    _seq = SequenceGenerator::next();
+  }
+
+  SeqMemPointerRecord(const SeqMemPointerRecord& copy_from)
+    : MemPointerRecord(copy_from) {
+    _seq = copy_from.seq();
+  }
+
+  SeqMemPointerRecord& operator= (const SeqMemPointerRecord& ptr) {
+    MemPointerRecord::operator=(ptr);
+    _seq = ptr.seq();
+    return *this;
+  }
+
+  inline jint seq() const {
+    return _seq;
+  }
+};
+
+
+
+class SeqMemPointerRecordEx : public MemPointerRecordEx {
+ private:
+  jint    _seq;  // sequence number
+
+ public:
+  SeqMemPointerRecordEx(): _seq(0) { }
+
+  SeqMemPointerRecordEx(address addr, MEMFLAGS flags, size_t size,
+    address pc): MemPointerRecordEx(addr, flags, size, pc) {
+    _seq = SequenceGenerator::next();
+  }
+
+  SeqMemPointerRecordEx(const SeqMemPointerRecordEx& copy_from)
+    : MemPointerRecordEx(copy_from) {
+    _seq = copy_from.seq();
+  }
+
+  SeqMemPointerRecordEx& operator= (const SeqMemPointerRecordEx& ptr) {
+    MemPointerRecordEx::operator=(ptr);
+    _seq = ptr.seq();
+    return *this;
+  }
+
+  inline jint seq() const {
+    return _seq;
+  }
+};
+
+#endif // SHARE_VM_SERVICES_MEM_PTR_HPP
diff --git a/hotspot/src/share/vm/services/memPtrArray.hpp b/hotspot/src/share/vm/services/memPtrArray.hpp
new file mode 100644
index 0000000..b3e48f6
--- /dev/null
+++ b/hotspot/src/share/vm/services/memPtrArray.hpp
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+#ifndef SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
+#define SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
+
+#include "memory/allocation.hpp"
+#include "services/memPtr.hpp"
+
+class MemPtr;
+class MemRecorder;
+class ArenaInfo;
+class MemSnapshot;
+
+extern "C" {
+  typedef int (*FN_SORT)(const void *, const void *);
+}
+
+
+// Memory pointer array interface. This array is used by NMT to hold
+// various memory block information.
+// The memory pointer arrays are usually walked with their iterators.
+
+class MemPointerArray : public CHeapObj<mtNMT> {
+ public:
+  virtual ~MemPointerArray() { }
+
+  // return true if it can not allocate storage for the data
+  virtual bool out_of_memory() const = 0;
+  virtual bool is_empty() const = 0;
+  virtual bool is_full() = 0;
+  virtual int  length() const = 0;
+  virtual void clear() = 0;
+  virtual bool append(MemPointer* ptr) = 0;
+  virtual bool insert_at(MemPointer* ptr, int pos) = 0;
+  virtual bool remove_at(int pos) = 0;
+  virtual MemPointer* at(int index) const = 0;
+  virtual void sort(FN_SORT fn) = 0;
+  virtual size_t instance_size() const = 0;
+  virtual bool shrink() = 0;
+
+  NOT_PRODUCT(virtual int capacity() const = 0;)
+};
+
+// Iterator interface
+class MemPointerArrayIterator VALUE_OBJ_CLASS_SPEC {
+ public:
+  // return the pointer at current position
+  virtual MemPointer* current() const = 0;
+  // return the next pointer and advance current position
+  virtual MemPointer* next() = 0;
+  // return next pointer without advancing current position
+  virtual MemPointer* peek_next() const = 0;
+  // return previous pointer without changing current position
+  virtual MemPointer* peek_prev() const = 0;
+  // remove the pointer at current position
+  virtual void        remove() = 0;
+  // insert the pointer at current position
+  virtual bool        insert(MemPointer* ptr) = 0;
+  // insert specified element after current position and
+  // move current position to newly inserted position
+  virtual bool        insert_after(MemPointer* ptr) = 0;
+};
+
+// implementation class
+class MemPointerArrayIteratorImpl : public MemPointerArrayIterator {
+ protected:
+  MemPointerArray*  _array;
+  int               _pos;
+
+ public:
+  MemPointerArrayIteratorImpl(MemPointerArray* arr) {
+    assert(arr != NULL, "Parameter check");
+    _array = arr;
+    _pos = 0;
+  }
+
+  virtual MemPointer* current() const {
+    if (_pos < _array->length()) {
+      return _array->at(_pos);
+    }
+    return NULL;
+  }
+
+  virtual MemPointer* next() {
+    if (_pos + 1 < _array->length()) {
+      return _array->at(++_pos);
+    }
+    _pos = _array->length();
+    return NULL;
+  }
+
+  virtual MemPointer* peek_next() const {
+    if (_pos + 1 < _array->length()) {
+      return _array->at(_pos + 1);
+    }
+    return NULL;
+  }
+
+  virtual MemPointer* peek_prev() const {
+    if (_pos > 0) {
+      return _array->at(_pos - 1);
+    }
+    return NULL;
+  }
+
+  virtual void remove() {
+    if (_pos < _array->length()) {
+      _array->remove_at(_pos);
+    }
+  }
+
+  virtual bool insert(MemPointer* ptr) {
+    return _array->insert_at(ptr, _pos);
+  }
+
+  virtual bool insert_after(MemPointer* ptr) {
+    if (_array->insert_at(ptr, _pos + 1)) {
+      _pos ++;
+      return true;
+    }
+    return false;
+  }
+};
+
+
+
+// Memory pointer array implementation.
+// This implementation implements expandable array
+#define DEFAULT_PTR_ARRAY_SIZE 1024
+
+template <class E> class MemPointerArrayImpl : public MemPointerArray {
+ private:
+  int                   _max_size;
+  int                   _size;
+  bool                  _init_elements;
+  E*                    _data;
+
+ public:
+  MemPointerArrayImpl(int initial_size = DEFAULT_PTR_ARRAY_SIZE, bool init_elements = true):
+   _max_size(initial_size), _size(0), _init_elements(init_elements) {
+    _data = (E*)raw_allocate(sizeof(E), initial_size);
+    if (_init_elements) {
+      for (int index = 0; index < _max_size; index ++) {
+        ::new ((void*)&_data[index]) E();
+      }
+    }
+  }
+
+  virtual ~MemPointerArrayImpl() {
+    if (_data != NULL) {
+      raw_free(_data);
+    }
+  }
+
+ public:
+  bool out_of_memory() const {
+    return (_data == NULL);
+  }
+
+  size_t instance_size() const {
+    return sizeof(MemPointerArrayImpl<E>) + _max_size * sizeof(E);
+  }
+
+  bool is_empty() const {
+    assert(_data != NULL, "Just check");
+    return _size == 0;
+  }
+
+  bool is_full() {
+    assert(_data != NULL, "Just check");
+    if (_size < _max_size) {
+      return false;
+    } else {
+      return !expand_array();
+    }
+  }
+
+  int length() const {
+    assert(_data != NULL, "Just check");
+    return _size;
+  }
+
+  NOT_PRODUCT(int capacity() const { return _max_size; })
+
+  void clear() {
+    assert(_data != NULL, "Just check");
+    _size = 0;
+  }
+
+  bool append(MemPointer* ptr) {
+    assert(_data != NULL, "Just check");
+    if (is_full()) {
+      return false;
+    }
+    _data[_size ++] = *(E*)ptr;
+    return true;
+  }
+
+  bool insert_at(MemPointer* ptr, int pos) {
+    assert(_data != NULL, "Just check");
+    if (is_full()) {
+      return false;
+    }
+    for (int index = _size; index > pos; index --) {
+      _data[index] = _data[index - 1];
+    }
+    _data[pos] = *(E*)ptr;
+    _size ++;
+    return true;
+  }
+
+  bool remove_at(int pos) {
+    assert(_data != NULL, "Just check");
+    if (_size <= pos && pos >= 0) {
+      return false;
+    }
+    -- _size;
+
+    for (int index = pos; index < _size; index ++) {
+      _data[index] = _data[index + 1];
+    }
+    return true;
+  }
+
+  MemPointer* at(int index) const {
+    assert(_data != NULL, "Just check");
+    assert(index >= 0 && index < _size, "illegal index");
+    return &_data[index];
+  }
+
+  bool shrink() {
+    float used = ((float)_size) / ((float)_max_size);
+    if (used < 0.40) {
+      E* old_ptr = _data;
+      int new_size = ((_max_size) / (2 * DEFAULT_PTR_ARRAY_SIZE) + 1) * DEFAULT_PTR_ARRAY_SIZE;
+      _data = (E*)raw_reallocate(_data, sizeof(E), new_size);
+      if (_data == NULL) {
+        _data = old_ptr;
+        return false;
+      } else {
+        _max_size = new_size;
+        return true;
+      }
+    }
+    return false;
+  }
+
+  void sort(FN_SORT fn) {
+    assert(_data != NULL, "Just check");
+    qsort((void*)_data, _size, sizeof(E), fn);
+  }
+
+ private:
+  bool  expand_array() {
+    assert(_data != NULL, "Not yet allocated");
+    E* old_ptr = _data;
+    if ((_data = (E*)raw_reallocate((void*)_data, sizeof(E),
+      _max_size + DEFAULT_PTR_ARRAY_SIZE)) == NULL) {
+      _data = old_ptr;
+      return false;
+    } else {
+      _max_size += DEFAULT_PTR_ARRAY_SIZE;
+      if (_init_elements) {
+        for (int index = _size; index < _max_size; index ++) {
+          ::new ((void*)&_data[index]) E();
+        }
+      }
+      return true;
+    }
+  }
+
+  void* raw_allocate(size_t elementSize, int items) {
+    return os::malloc(elementSize * items, mtNMT);
+  }
+
+  void* raw_reallocate(void* ptr, size_t elementSize, int items) {
+    return os::realloc(ptr, elementSize * items, mtNMT);
+  }
+
+  void  raw_free(void* ptr) {
+    os::free(ptr, mtNMT);
+  }
+};
+
+#endif // SHARE_VM_UTILITIES_MEM_PTR_ARRAY_HPP
diff --git a/hotspot/src/share/vm/services/memRecorder.cpp b/hotspot/src/share/vm/services/memRecorder.cpp
new file mode 100644
index 0000000..5ec865a
--- /dev/null
+++ b/hotspot/src/share/vm/services/memRecorder.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+
+#include "runtime/atomic.hpp"
+#include "services/memBaseline.hpp"
+#include "services/memRecorder.hpp"
+#include "services/memPtr.hpp"
+#include "services/memTracker.hpp"
+
+MemPointer* SequencedRecordIterator::next_record() {
+  MemPointerRecord* itr_cur = (MemPointerRecord*)_itr.current();
+  if (itr_cur == NULL)  {
+    return itr_cur;
+  }
+
+  MemPointerRecord* itr_next = (MemPointerRecord*)_itr.next();
+
+  // don't collapse virtual memory records
+  while (itr_next != NULL && !itr_cur->is_vm_pointer() &&
+    !itr_next->is_vm_pointer() &&
+    same_kind(itr_cur, itr_next)) {
+    itr_cur = itr_next;
+    itr_next = (MemPointerRecord*)_itr.next();
+  }
+
+  return itr_cur;
+}
+
+
+volatile jint MemRecorder::_instance_count = 0;
+
+MemRecorder::MemRecorder() {
+  assert(MemTracker::is_on(), "Native memory tracking is off");
+  Atomic::inc(&_instance_count);
+  debug_only(set_generation();)
+
+  if (MemTracker::track_callsite()) {
+    _pointer_records = new (std::nothrow)FixedSizeMemPointerArray<SeqMemPointerRecordEx,
+        DEFAULT_RECORDER_PTR_ARRAY_SIZE>();
+  } else {
+    _pointer_records = new (std::nothrow)FixedSizeMemPointerArray<SeqMemPointerRecord,
+        DEFAULT_RECORDER_PTR_ARRAY_SIZE>();
+  }
+  _next = NULL;
+
+
+  if (_pointer_records != NULL) {
+    // recode itself
+    record((address)this, (MemPointerRecord::malloc_tag()|mtNMT|otNMTRecorder),
+        sizeof(MemRecorder), CALLER_PC);
+    record((address)_pointer_records, (MemPointerRecord::malloc_tag()|mtNMT|otNMTRecorder),
+        _pointer_records->instance_size(),CURRENT_PC);
+  }
+}
+
+MemRecorder::~MemRecorder() {
+  if (_pointer_records != NULL) {
+    if (MemTracker::is_on()) {
+      MemTracker::record_free((address)_pointer_records, mtNMT);
+      MemTracker::record_free((address)this, mtNMT);
+    }
+    delete _pointer_records;
+  }
+  if (_next != NULL) {
+    delete _next;
+  }
+
+  Atomic::dec(&_instance_count);
+}
+
+// Sorting order:
+//   1. memory block address
+//   2. mem pointer record tags
+//   3. sequence number
+int MemRecorder::sort_record_fn(const void* e1, const void* e2) {
+  const MemPointerRecord* p1 = (const MemPointerRecord*)e1;
+  const MemPointerRecord* p2 = (const MemPointerRecord*)e2;
+  int delta = UNSIGNED_COMPARE(p1->addr(), p2->addr());
+  if (delta == 0) {
+    int df = UNSIGNED_COMPARE((p1->flags() & MemPointerRecord::tag_masks),
+                              (p2->flags() & MemPointerRecord::tag_masks));
+    if (df == 0) {
+      assert(p1->seq() != p2->seq(), "dup seq");
+      return p1->seq() - p2->seq();
+    } else {
+      return df;
+    }
+  } else {
+    return delta;
+  }
+}
+
+bool MemRecorder::record(address p, MEMFLAGS flags, size_t size, address pc) {
+#ifdef ASSERT
+  if (MemPointerRecord::is_virtual_memory_record(flags)) {
+    assert((flags & MemPointerRecord::tag_masks) != 0, "bad virtual memory record");
+  } else {
+    assert((flags & MemPointerRecord::tag_masks) == MemPointerRecord::malloc_tag() ||
+           (flags & MemPointerRecord::tag_masks) == MemPointerRecord::free_tag() ||
+           IS_ARENA_OBJ(flags),
+           "bad malloc record");
+  }
+  // a recorder should only hold records within the same generation
+  unsigned long cur_generation = SequenceGenerator::current_generation();
+  assert(cur_generation == _generation,
+         "this thread did not enter sync point");
+#endif
+
+  if (MemTracker::track_callsite()) {
+    SeqMemPointerRecordEx ap(p, flags, size, pc);
+    debug_only(check_dup_seq(ap.seq());)
+    return _pointer_records->append(&ap);
+  } else {
+    SeqMemPointerRecord ap(p, flags, size);
+    debug_only(check_dup_seq(ap.seq());)
+    return _pointer_records->append(&ap);
+  }
+}
+
+  // iterator for alloc pointers
+SequencedRecordIterator MemRecorder::pointer_itr() {
+  assert(_pointer_records != NULL, "just check");
+  _pointer_records->sort((FN_SORT)sort_record_fn);
+  return SequencedRecordIterator(_pointer_records);
+}
+
+
+#ifdef ASSERT
+void MemRecorder::set_generation() {
+  _generation = SequenceGenerator::current_generation();
+}
+
+void MemRecorder::check_dup_seq(jint seq) const {
+  MemPointerArrayIteratorImpl itr(_pointer_records);
+  MemPointerRecord* rc = (MemPointerRecord*)itr.current();
+  while (rc != NULL) {
+    assert(rc->seq() != seq, "dup seq");
+    rc = (MemPointerRecord*)itr.next();
+  }
+}
+
+#endif
diff --git a/hotspot/src/share/vm/services/memRecorder.hpp b/hotspot/src/share/vm/services/memRecorder.hpp
new file mode 100644
index 0000000..2afeeb0
--- /dev/null
+++ b/hotspot/src/share/vm/services/memRecorder.hpp
@@ -0,0 +1,268 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_MEM_RECORDER_HPP
+#define SHARE_VM_SERVICES_MEM_RECORDER_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/os.hpp"
+#include "services/memPtrArray.hpp"
+
+class MemSnapshot;
+class MemTracker;
+class MemTrackWorker;
+
+// Fixed size memory pointer array implementation
+template <class E, int SIZE> class FixedSizeMemPointerArray :
+  public MemPointerArray {
+  // This implementation is for memory recorder only
+  friend class MemRecorder;
+
+ private:
+  E      _data[SIZE];
+  int    _size;
+
+ protected:
+  FixedSizeMemPointerArray(bool init_elements = false):
+   _size(0){
+    if (init_elements) {
+      for (int index = 0; index < SIZE; index ++) {
+        ::new ((void*)&_data[index]) E();
+      }
+    }
+  }
+
+  void* operator new(size_t size, const std::nothrow_t& nothrow_constant) {
+    // the instance is part of memRecorder, needs to be tagged with 'otNMTRecorder'
+    // to avoid recursion
+    return os::malloc(size, (mtNMT | otNMTRecorder));
+  }
+
+  void* operator new(size_t size) {
+    assert(false, "use nothrow version");
+    return NULL;
+  }
+
+  void operator delete(void* p) {
+    os::free(p, (mtNMT | otNMTRecorder));
+  }
+
+  // instance size
+  inline size_t instance_size() const {
+    return sizeof(FixedSizeMemPointerArray<E, SIZE>);
+  }
+
+  NOT_PRODUCT(int capacity() const { return SIZE; })
+
+ public:
+  // implementation of public interface
+  bool out_of_memory() const { return false; }
+  bool is_empty()      const { return _size == 0; }
+  bool is_full()             { return length() >= SIZE; }
+  int  length()        const { return _size; }
+
+  void clear() {
+    _size = 0;
+  }
+
+  bool append(MemPointer* ptr) {
+    if (is_full()) return false;
+    _data[_size ++] = *(E*)ptr;
+    return true;
+  }
+
+  virtual bool insert_at(MemPointer* p, int pos) {
+    assert(false, "append only");
+    return false;
+  }
+
+  virtual bool remove_at(int pos) {
+    assert(false, "not supported");
+    return false;
+  }
+
+  MemPointer* at(int index) const {
+    assert(index >= 0 && index < length(),
+      "parameter check");
+    return ((E*)&_data[index]);
+  }
+
+  void sort(FN_SORT fn) {
+    qsort((void*)_data, _size, sizeof(E), fn);
+  }
+
+  bool shrink() {
+    return false;
+  }
+};
+
+
+// This iterator requires pre-sorted MemPointerArray, which is sorted by:
+//  1. address
+//  2. allocation type
+//  3. sequence number
+// During the array walking, iterator collapses pointers with the same
+// address and allocation type, and only returns the one with highest
+// sequence number.
+//
+// This is read-only iterator, update methods are asserted.
+class SequencedRecordIterator : public MemPointerArrayIterator {
+ private:
+   MemPointerArrayIteratorImpl _itr;
+   MemPointer*                 _cur;
+
+ public:
+  SequencedRecordIterator(const MemPointerArray* arr):
+    _itr(const_cast<MemPointerArray*>(arr)) {
+    _cur = next_record();
+  }
+
+  SequencedRecordIterator(const SequencedRecordIterator& itr):
+    _itr(itr._itr) {
+    _cur = next_record();
+  }
+
+  // return the pointer at current position
+  virtual MemPointer* current() const {
+    return _cur;
+  };
+
+  // return the next pointer and advance current position
+  virtual MemPointer* next() {
+    _cur = next_record();
+    return _cur;
+  }
+
+  // return the next pointer without advancing current position
+  virtual MemPointer* peek_next() const {
+    assert(false, "not implemented");
+    return NULL;
+
+  }
+  // return the previous pointer without changing current position
+  virtual MemPointer* peek_prev() const {
+    assert(false, "not implemented");
+    return NULL;
+  }
+
+  // remove the pointer at current position
+  virtual void remove() {
+    assert(false, "read-only iterator");
+  };
+  // insert the pointer at current position
+  virtual bool insert(MemPointer* ptr) {
+    assert(false, "read-only iterator");
+    return false;
+  }
+
+  virtual bool insert_after(MemPointer* ptr) {
+    assert(false, "read-only iterator");
+    return false;
+  }
+ private:
+  // collapse the 'same kind' of records, and return this 'kind' of
+  // record with highest sequence number
+  MemPointer* next_record();
+
+  // Test if the two records are the same kind: the same memory block and allocation
+  // type.
+  inline bool same_kind(const MemPointerRecord* p1, const MemPointerRecord* p2) const {
+    assert(!p1->is_vm_pointer() && !p2->is_vm_pointer(), "malloc pointer only");
+    return (p1->addr() == p2->addr() &&
+      (p1->flags() &MemPointerRecord::tag_masks) ==
+      (p2->flags() & MemPointerRecord::tag_masks));
+  }
+};
+
+
+
+#define DEFAULT_RECORDER_PTR_ARRAY_SIZE 512
+
+class MemRecorder : public CHeapObj<mtNMT|otNMTRecorder> {
+  friend class MemSnapshot;
+  friend class MemTracker;
+  friend class MemTrackWorker;
+
+ protected:
+  // the array that holds memory records
+  MemPointerArray*         _pointer_records;
+
+ private:
+  // used for linked list
+  MemRecorder*             _next;
+  // active recorder can only record a certain generation data
+  debug_only(unsigned long _generation;)
+
+ protected:
+  _NOINLINE_ MemRecorder();
+  ~MemRecorder();
+
+  // record a memory operation
+  bool record(address addr, MEMFLAGS flags, size_t size, address caller_pc = 0);
+
+  // linked list support
+  inline void set_next(MemRecorder* rec) {
+    _next = rec;
+  }
+
+  inline MemRecorder* next() const {
+    return _next;
+  }
+
+  // if the recorder is full
+  inline bool is_full() const {
+    assert(_pointer_records != NULL, "just check");
+    return _pointer_records->is_full();
+  }
+
+  // if running out of memory when initializing recorder's internal
+  // data
+  inline bool out_of_memory() const {
+    return (_pointer_records == NULL ||
+      _pointer_records->out_of_memory());
+  }
+
+  inline void clear() {
+    assert(_pointer_records != NULL, "Just check");
+    _pointer_records->clear();
+  }
+
+  SequencedRecordIterator pointer_itr();
+
+ protected:
+  // number of MemRecorder instance
+  static volatile jint _instance_count;
+
+ private:
+  // sorting function, sort records into following order
+  // 1. memory address
+  // 2. allocation type
+  // 3. sequence number
+  static int sort_record_fn(const void* e1, const void* e2);
+
+  debug_only(void check_dup_seq(jint seq) const;)
+  debug_only(void set_generation();)
+};
+
+#endif // SHARE_VM_SERVICES_MEM_RECORDER_HPP
diff --git a/hotspot/src/share/vm/services/memReporter.cpp b/hotspot/src/share/vm/services/memReporter.cpp
new file mode 100644
index 0000000..602ac1c
--- /dev/null
+++ b/hotspot/src/share/vm/services/memReporter.cpp
@@ -0,0 +1,614 @@
+/*
+ * Copyright (c) 2012 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.
+ *
+ */
+#include "precompiled.hpp"
+#include "classfile/systemDictionary.hpp"
+#include "runtime/os.hpp"
+#include "services/memReporter.hpp"
+#include "services/memPtrArray.hpp"
+#include "services/memTracker.hpp"
+
+const char* BaselineOutputer::memory_unit(size_t scale) {
+  switch(scale) {
+    case K: return "KB";
+    case M: return "MB";
+    case G: return "GB";
+  }
+  ShouldNotReachHere();
+  return NULL;
+}
+
+
+void BaselineReporter::report_baseline(const MemBaseline& baseline, bool summary_only) {
+  assert(MemTracker::is_on(), "Native memory tracking is off");
+  _outputer.start(scale());
+  _outputer.total_usage(
+    amount_in_current_scale(baseline.total_malloc_amount() + baseline.total_reserved_amount()),
+    amount_in_current_scale(baseline.total_malloc_amount() + baseline.total_committed_amount()));
+
+  _outputer.num_of_classes(baseline.number_of_classes());
+  _outputer.num_of_threads(baseline.number_of_threads());
+
+  report_summaries(baseline);
+  if (!summary_only && MemTracker::track_callsite()) {
+    report_virtual_memory_map(baseline);
+    report_callsites(baseline);
+  }
+  _outputer.done();
+}
+
+void BaselineReporter::report_summaries(const MemBaseline& baseline) {
+  _outputer.start_category_summary();
+  MEMFLAGS type;
+
+  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+    type = MemBaseline::MemType2NameMap[index]._flag;
+    _outputer.category_summary(type,
+      amount_in_current_scale(baseline.reserved_amount(type)),
+      amount_in_current_scale(baseline.committed_amount(type)),
+      amount_in_current_scale(baseline.malloc_amount(type)),
+      baseline.malloc_count(type),
+      amount_in_current_scale(baseline.arena_amount(type)),
+      baseline.arena_count(type));
+  }
+
+  _outputer.done_category_summary();
+}
+
+void BaselineReporter::report_virtual_memory_map(const MemBaseline& baseline) {
+  _outputer.start_virtual_memory_map();
+  MemBaseline* pBL = const_cast<MemBaseline*>(&baseline);
+  MemPointerArrayIteratorImpl itr = MemPointerArrayIteratorImpl(pBL->_vm_map);
+  VMMemRegionEx* rgn = (VMMemRegionEx*)itr.current();
+  while (rgn != NULL) {
+    if (rgn->is_reserved_region()) {
+      _outputer.reserved_memory_region(FLAGS_TO_MEMORY_TYPE(rgn->flags()),
+        rgn->base(), rgn->base() + rgn->size(), amount_in_current_scale(rgn->size()), rgn->pc());
+    } else {
+      _outputer.committed_memory_region(rgn->base(), rgn->base() + rgn->size(),
+        amount_in_current_scale(rgn->size()), rgn->pc());
+    }
+    rgn = (VMMemRegionEx*)itr.next();
+  }
+
+  _outputer.done_virtual_memory_map();
+}
+
+void BaselineReporter::report_callsites(const MemBaseline& baseline) {
+  _outputer.start_callsite();
+  MemBaseline* pBL = const_cast<MemBaseline*>(&baseline);
+
+  pBL->_malloc_cs->sort((FN_SORT)MemBaseline::bl_malloc_sort_by_size);
+  pBL->_vm_cs->sort((FN_SORT)MemBaseline::bl_vm_sort_by_size);
+
+  // walk malloc callsites
+  MemPointerArrayIteratorImpl malloc_itr(pBL->_malloc_cs);
+  MallocCallsitePointer*      malloc_callsite =
+                  (MallocCallsitePointer*)malloc_itr.current();
+  while (malloc_callsite != NULL) {
+    _outputer.malloc_callsite(malloc_callsite->addr(),
+        amount_in_current_scale(malloc_callsite->amount()), malloc_callsite->count());
+    malloc_callsite = (MallocCallsitePointer*)malloc_itr.next();
+  }
+
+  // walk virtual memory callsite
+  MemPointerArrayIteratorImpl vm_itr(pBL->_vm_cs);
+  VMCallsitePointer*          vm_callsite = (VMCallsitePointer*)vm_itr.current();
+  while (vm_callsite != NULL) {
+    _outputer.virtual_memory_callsite(vm_callsite->addr(),
+      amount_in_current_scale(vm_callsite->reserved_amount()),
+      amount_in_current_scale(vm_callsite->committed_amount()));
+    vm_callsite = (VMCallsitePointer*)vm_itr.next();
+  }
+  pBL->_malloc_cs->sort((FN_SORT)MemBaseline::bl_malloc_sort_by_pc);
+  pBL->_vm_cs->sort((FN_SORT)MemBaseline::bl_vm_sort_by_pc);
+  _outputer.done_callsite();
+}
+
+void BaselineReporter::diff_baselines(const MemBaseline& cur, const MemBaseline& prev,
+  bool summary_only) {
+  assert(MemTracker::is_on(), "Native memory tracking is off");
+  _outputer.start(scale());
+  size_t total_reserved = cur.total_malloc_amount() + cur.total_reserved_amount();
+  size_t total_committed = cur.total_malloc_amount() + cur.total_committed_amount();
+
+  _outputer.diff_total_usage(
+    amount_in_current_scale(total_reserved), amount_in_current_scale(total_committed),
+    diff_in_current_scale(total_reserved,  (prev.total_malloc_amount() + prev.total_reserved_amount())),
+    diff_in_current_scale(total_committed, (prev.total_committed_amount() + prev.total_malloc_amount())));
+
+  _outputer.diff_num_of_classes(cur.number_of_classes(),
+       diff(cur.number_of_classes(), prev.number_of_classes()));
+  _outputer.diff_num_of_threads(cur.number_of_threads(),
+       diff(cur.number_of_threads(), prev.number_of_threads()));
+
+  diff_summaries(cur, prev);
+  if (!summary_only && MemTracker::track_callsite()) {
+    diff_callsites(cur, prev);
+  }
+  _outputer.done();
+}
+
+void BaselineReporter::diff_summaries(const MemBaseline& cur, const MemBaseline& prev) {
+  _outputer.start_category_summary();
+  MEMFLAGS type;
+
+  for (int index = 0; index < NUMBER_OF_MEMORY_TYPE; index ++) {
+    type = MemBaseline::MemType2NameMap[index]._flag;
+    _outputer.diff_category_summary(type,
+      amount_in_current_scale(cur.reserved_amount(type)),
+      amount_in_current_scale(cur.committed_amount(type)),
+      amount_in_current_scale(cur.malloc_amount(type)),
+      cur.malloc_count(type),
+      amount_in_current_scale(cur.arena_amount(type)),
+      cur.arena_count(type),
+      diff_in_current_scale(cur.reserved_amount(type), prev.reserved_amount(type)),
+      diff_in_current_scale(cur.committed_amount(type), prev.committed_amount(type)),
+      diff_in_current_scale(cur.malloc_amount(type), prev.malloc_amount(type)),
+      diff(cur.malloc_count(type), prev.malloc_count(type)),
+      diff_in_current_scale(cur.arena_amount(type), prev.arena_amount(type)),
+      diff(cur.arena_count(type), prev.arena_count(type)));
+  }
+
+  _outputer.done_category_summary();
+}
+
+void BaselineReporter::diff_callsites(const MemBaseline& cur, const MemBaseline& prev) {
+  _outputer.start_callsite();
+  MemBaseline* pBL_cur = const_cast<MemBaseline*>(&cur);
+  MemBaseline* pBL_prev = const_cast<MemBaseline*>(&prev);
+
+  // walk malloc callsites
+  MemPointerArrayIteratorImpl cur_malloc_itr(pBL_cur->_malloc_cs);
+  MemPointerArrayIteratorImpl prev_malloc_itr(pBL_prev->_malloc_cs);
+
+  MallocCallsitePointer*      cur_malloc_callsite =
+                  (MallocCallsitePointer*)cur_malloc_itr.current();
+  MallocCallsitePointer*      prev_malloc_callsite =
+                  (MallocCallsitePointer*)prev_malloc_itr.current();
+
+  while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) {
+    if (prev_malloc_callsite == NULL ||
+        cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) {
+      _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
+        amount_in_current_scale(cur_malloc_callsite->amount()),
+        cur_malloc_callsite->count(),
+        diff_in_current_scale(cur_malloc_callsite->amount(), 0),
+        diff(cur_malloc_callsite->count(), 0));
+      cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
+    } else if (prev_malloc_callsite == NULL ||
+               cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) {
+      _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
+        amount_in_current_scale(prev_malloc_callsite->amount()),
+        prev_malloc_callsite->count(),
+        diff_in_current_scale(0, prev_malloc_callsite->amount()),
+        diff(0, prev_malloc_callsite->count()));
+      prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
+    } else {  // the same callsite
+      _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(),
+        amount_in_current_scale(cur_malloc_callsite->amount()),
+        cur_malloc_callsite->count(),
+        diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()),
+        diff(cur_malloc_callsite->count(), prev_malloc_callsite->count()));
+      cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next();
+      prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next();
+    }
+  }
+
+  // walk virtual memory callsite
+  MemPointerArrayIteratorImpl cur_vm_itr(pBL_cur->_vm_cs);
+  MemPointerArrayIteratorImpl prev_vm_itr(pBL_prev->_vm_cs);
+  VMCallsitePointer*          cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.current();
+  VMCallsitePointer*          prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.current();
+  while (cur_vm_callsite != NULL || prev_vm_callsite != NULL) {
+    if (prev_vm_callsite == NULL || cur_vm_callsite->addr() < prev_vm_callsite->addr()) {
+      _outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(),
+        amount_in_current_scale(cur_vm_callsite->reserved_amount()),
+        amount_in_current_scale(cur_vm_callsite->committed_amount()),
+        diff_in_current_scale(cur_vm_callsite->reserved_amount(), 0),
+        diff_in_current_scale(cur_vm_callsite->committed_amount(), 0));
+      cur_vm_callsite = (VMCallsitePointer*)cur_vm_itr.next();
+    } else if (cur_vm_callsite == NULL || cur_vm_callsite->addr() > prev_vm_callsite->addr()) {
+      _outputer.diff_virtual_memory_callsite(prev_vm_callsite->addr(),
+        amount_in_current_scale(prev_vm_callsite->reserved_amount()),
+        amount_in_current_scale(prev_vm_callsite->committed_amount()),
+        diff_in_current_scale(0, prev_vm_callsite->reserved_amount()),
+        diff_in_current_scale(0, prev_vm_callsite->committed_amount()));
+      prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next();
+    } else { // the same callsite
+      _outputer.diff_virtual_memory_callsite(cur_vm_callsite->addr(),
+        amount_in_current_scale(cur_vm_callsite->reserved_amount()),
+        amount_in_current_scale(cur_vm_callsite->committed_amount()),
+        diff_in_current_scale(cur_vm_callsite->reserved_amount(), prev_vm_callsite->reserved_amount()),
+        diff_in_current_scale(cur_vm_callsite->committed_amount(), prev_vm_callsite->committed_amount()));
+      cur_vm_callsite  = (VMCallsitePointer*)cur_vm_itr.next();
+      prev_vm_callsite = (VMCallsitePointer*)prev_vm_itr.next();
+    }
+  }
+
+  _outputer.done_callsite();
+}
+
+size_t BaselineReporter::amount_in_current_scale(size_t amt) const {
+  return (size_t)(((float)amt/(float)_scale) + 0.5);
+}
+
+int BaselineReporter::diff_in_current_scale(size_t value1, size_t value2) const {
+  return (int)(((float)value1 - (float)value2)/((float)_scale) + 0.5);
+}
+
+int BaselineReporter::diff(size_t value1, size_t value2) const {
+  return ((int)value1 - (int)value2);
+}
+
+void BaselineTTYOutputer::start(size_t scale, bool report_diff) {
+  _scale = scale;
+  _output->print_cr(" ");
+  _output->print_cr("Native Memory Tracking:");
+  _output->print_cr(" ");
+}
+
+void BaselineTTYOutputer::done() {
+
+}
+
+void BaselineTTYOutputer::total_usage(size_t total_reserved, size_t total_committed) {
+  const char* unit = memory_unit(_scale);
+  _output->print_cr("Total:  reserved=%d%s,  committed=%d%s",
+    total_reserved, unit, total_committed, unit);
+}
+
+void BaselineTTYOutputer::start_category_summary() {
+  _output->print_cr(" ");
+}
+
+/**
+ * report a summary of memory type
+ */
+void BaselineTTYOutputer::category_summary(MEMFLAGS type,
+  size_t reserved_amt, size_t committed_amt, size_t malloc_amt,
+  size_t malloc_count, size_t arena_amt, size_t arena_count) {
+
+  // we report mtThreadStack under mtThread category
+  if (type == mtThreadStack) {
+    assert(malloc_amt == 0 && malloc_count == 0 && arena_amt == 0,
+      "Just check");
+    _thread_stack_reserved = reserved_amt;
+    _thread_stack_committed = committed_amt;
+  } else {
+    const char* unit = memory_unit(_scale);
+    size_t total_reserved = (reserved_amt + malloc_amt + arena_amt);
+    size_t total_committed = (committed_amt + malloc_amt + arena_amt);
+    if (type == mtThread) {
+      total_reserved += _thread_stack_reserved;
+      total_committed += _thread_stack_committed;
+    }
+
+    if (total_reserved > 0) {
+      _output->print_cr("-%26s (reserved=%d%s, committed=%d%s)",
+        MemBaseline::type2name(type), total_reserved, unit,
+        total_committed, unit);
+
+      if (type == mtClass) {
+        _output->print_cr("%27s (classes #%d)", " ", _num_of_classes);
+      } else if (type == mtThread) {
+        _output->print_cr("%27s (thread #%d)", " ", _num_of_threads);
+        _output->print_cr("%27s (stack: reserved=%d%s, committed=%d%s)", " ",
+          _thread_stack_reserved, unit, _thread_stack_committed, unit);
+      }
+
+      if (malloc_amt > 0) {
+        if (type != mtChunk) {
+          _output->print_cr("%27s (malloc=%d%s, #%d)", " ", malloc_amt, unit,
+            malloc_count);
+        } else {
+          _output->print_cr("%27s (malloc=%d%s)", " ", malloc_amt, unit);
+        }
+      }
+
+      if (reserved_amt > 0) {
+        _output->print_cr("%27s (mmap: reserved=%d%s, committed=%d%s)",
+          " ", reserved_amt, unit, committed_amt, unit);
+      }
+
+      if (arena_amt > 0) {
+        _output->print_cr("%27s (arena=%d%s, #%d)", " ", arena_amt, unit, arena_count);
+      }
+
+      _output->print_cr(" ");
+    }
+  }
+}
+
+void BaselineTTYOutputer::done_category_summary() {
+  _output->print_cr(" ");
+}
+
+
+void BaselineTTYOutputer::start_virtual_memory_map() {
+  _output->print_cr("Virtual memory map:");
+}
+
+void BaselineTTYOutputer::reserved_memory_region(MEMFLAGS type, address base, address end,
+                                                 size_t size, address pc) {
+  const char* unit = memory_unit(_scale);
+  char buf[128];
+  int  offset;
+  _output->print_cr(" ");
+  _output->print_cr("[" PTR_FORMAT " - " PTR_FORMAT "] reserved %d%s for %s", base, end, size, unit,
+            MemBaseline::type2name(type));
+  if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+      _output->print_cr("\t\tfrom [%s+0x%x]", buf, offset);
+  }
+}
+
+void BaselineTTYOutputer::committed_memory_region(address base, address end, size_t size, address pc) {
+  const char* unit = memory_unit(_scale);
+  char buf[128];
+  int  offset;
+  _output->print("\t[" PTR_FORMAT " - " PTR_FORMAT "] committed %d%s", base, end, size, unit);
+  if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+      _output->print_cr(" from [%s+0x%x]", buf, offset);
+  }
+}
+
+void BaselineTTYOutputer::done_virtual_memory_map() {
+  _output->print_cr(" ");
+}
+
+
+
+void BaselineTTYOutputer::start_callsite() {
+  _output->print_cr("Details:");
+  _output->print_cr(" ");
+}
+
+void BaselineTTYOutputer::done_callsite() {
+  _output->print_cr(" ");
+}
+
+void BaselineTTYOutputer::malloc_callsite(address pc, size_t malloc_amt,
+  size_t malloc_count) {
+  if (malloc_amt > 0) {
+    const char* unit = memory_unit(_scale);
+    char buf[128];
+    int  offset;
+    if (pc == 0) {
+      _output->print("[BOOTSTRAP]%18s", " ");
+    } else if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+      _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
+      _output->print("%28s", " ");
+    } else {
+      _output->print("[" PTR_FORMAT "]%18s", pc, " ");
+    }
+
+    _output->print_cr("(malloc=%d%s #%d)", malloc_amt, unit, malloc_count);
+    _output->print_cr(" ");
+  }
+}
+
+void BaselineTTYOutputer::virtual_memory_callsite(address pc, size_t reserved_amt,
+  size_t committed_amt) {
+  if (reserved_amt > 0) {
+    const char* unit = memory_unit(_scale);
+    char buf[128];
+    int  offset;
+    if (pc == 0) {
+      _output->print("[BOOTSTRAP]%18s", " ");
+    } else if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+      _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
+      _output->print("%28s", " ");
+    } else {
+      _output->print("[" PTR_FORMAT "]%18s", " ");
+    }
+
+    _output->print_cr("(mmap: reserved=%d%s, committed=%d%s)",
+      reserved_amt, unit, committed_amt, unit);
+    _output->print_cr(" ");
+  }
+}
+
+void BaselineTTYOutputer::diff_total_usage(size_t total_reserved,
+  size_t total_committed, int reserved_diff, int committed_diff) {
+  const char* unit = memory_unit(_scale);
+  _output->print_cr("Total:  reserved=%d%s  %+d%s, committed=%d%s %+d%s",
+    total_reserved, unit, reserved_diff, unit, total_committed, unit,
+    committed_diff, unit);
+}
+
+void BaselineTTYOutputer::diff_category_summary(MEMFLAGS type,
+  size_t cur_reserved_amt, size_t cur_committed_amt,
+  size_t cur_malloc_amt, size_t cur_malloc_count,
+  size_t cur_arena_amt, size_t cur_arena_count,
+  int reserved_diff, int committed_diff, int malloc_diff,
+  int malloc_count_diff, int arena_diff, int arena_count_diff) {
+
+  if (type == mtThreadStack) {
+    assert(cur_malloc_amt == 0 && cur_malloc_count == 0 &&
+      cur_arena_amt == 0, "Just check");
+    _thread_stack_reserved = cur_reserved_amt;
+    _thread_stack_committed = cur_committed_amt;
+    _thread_stack_reserved_diff = reserved_diff;
+    _thread_stack_committed_diff = committed_diff;
+  } else {
+    const char* unit = memory_unit(_scale);
+    size_t total_reserved = (cur_reserved_amt + cur_malloc_amt + cur_arena_amt);
+    // nothing to report in this category
+    if (total_reserved == 0) {
+      return;
+    }
+    int    diff_reserved = (reserved_diff + malloc_diff + arena_diff);
+
+    // category summary
+    _output->print("-%26s (reserved=%d%s", MemBaseline::type2name(type),
+      total_reserved, unit);
+
+    if (diff_reserved != 0) {
+      _output->print(" %+d%s", diff_reserved, unit);
+    }
+
+    size_t total_committed = cur_committed_amt + cur_malloc_amt + cur_arena_amt;
+    _output->print(", committed=%d%s", total_committed, unit);
+
+    int total_committed_diff = committed_diff + malloc_diff + arena_diff;
+    if (total_committed_diff != 0) {
+      _output->print(" %+d%s", total_committed_diff, unit);
+    }
+
+    _output->print_cr(")");
+
+    // special cases
+    if (type == mtClass) {
+      _output->print("%27s (classes #%d", " ", _num_of_classes);
+      if (_num_of_classes_diff != 0) {
+        _output->print(" %+d", _num_of_classes_diff);
+      }
+      _output->print_cr(")");
+    } else if (type == mtThread) {
+      // thread count
+      _output->print("%27s (thread #%d", " ", _num_of_threads);
+      if (_num_of_threads_diff != 0) {
+        _output->print_cr(" %+d)", _num_of_threads_diff);
+      } else {
+        _output->print_cr(")");
+      }
+      _output->print("%27s (stack: reserved=%d%s", " ", _thread_stack_reserved, unit);
+      if (_thread_stack_reserved_diff != 0) {
+        _output->print(" %+d%s", _thread_stack_reserved_diff, unit);
+      }
+
+      _output->print(", committed=%d%s", _thread_stack_committed, unit);
+      if (_thread_stack_committed_diff != 0) {
+        _output->print(" %+d%s",_thread_stack_committed_diff, unit);
+      }
+
+      _output->print_cr(")");
+    }
+
+    // malloc'd memory
+    if (cur_malloc_amt > 0) {
+      _output->print("%27s (malloc=%d%s", " ", cur_malloc_amt, unit);
+      if (malloc_diff != 0) {
+        _output->print(" %+d%s", malloc_diff, unit);
+      }
+      if (type != mtChunk) {
+        _output->print(", #%d", cur_malloc_count);
+        if (malloc_count_diff) {
+          _output->print(" %+d", malloc_count_diff);
+        }
+      }
+      _output->print_cr(")");
+    }
+
+    // mmap'd memory
+    if (cur_reserved_amt > 0) {
+      _output->print("%27s (mmap: reserved=%d%s", " ", cur_reserved_amt, unit);
+      if (reserved_diff != 0) {
+        _output->print(" %+d%s", reserved_diff, unit);
+      }
+
+      _output->print(", committed=%d%s", cur_committed_amt, unit);
+      if (committed_diff != 0) {
+        _output->print(" %+d%s", committed_diff, unit);
+      }
+      _output->print_cr(")");
+    }
+
+    // arena memory
+    if (cur_arena_amt > 0) {
+      _output->print("%27s (arena=%d%s", " ", cur_arena_amt, unit);
+      if (arena_diff != 0) {
+        _output->print(" %+d%s", arena_diff, unit);
+      }
+      _output->print(", #%d", cur_arena_count);
+      if (arena_count_diff != 0) {
+        _output->print(" %+d", arena_count_diff);
+      }
+      _output->print_cr(")");
+    }
+
+    _output->print_cr(" ");
+  }
+}
+
+void BaselineTTYOutputer::diff_malloc_callsite(address pc,
+    size_t cur_malloc_amt, size_t cur_malloc_count,
+    int malloc_diff, int malloc_count_diff) {
+  if (malloc_diff != 0) {
+    const char* unit = memory_unit(_scale);
+    char buf[128];
+    int  offset;
+    if (pc == 0) {
+      _output->print_cr("[BOOTSTRAP]%18s", " ");
+    } else {
+      if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+        _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
+        _output->print("%28s", " ");
+      } else {
+        _output->print("[" PTR_FORMAT "]%18s", pc, " ");
+      }
+    }
+
+    _output->print("(malloc=%d%s", cur_malloc_amt, unit);
+    if (malloc_diff != 0) {
+      _output->print(" %+d%s", malloc_diff, unit);
+    }
+    _output->print(", #%d", cur_malloc_count);
+    if (malloc_count_diff != 0) {
+      _output->print(" %+d", malloc_count_diff);
+    }
+    _output->print_cr(")");
+    _output->print_cr(" ");
+  }
+}
+
+void BaselineTTYOutputer::diff_virtual_memory_callsite(address pc,
+    size_t cur_reserved_amt, size_t cur_committed_amt,
+    int reserved_diff, int committed_diff) {
+  if (reserved_diff != 0 || committed_diff != 0) {
+    const char* unit = memory_unit(_scale);
+    char buf[64];
+    int  offset;
+    if (pc == 0) {
+      _output->print_cr("[BOOSTRAP]%18s", " ");
+    } else {
+      if (os::dll_address_to_function_name(pc, buf, sizeof(buf), &offset)) {
+        _output->print_cr("[" PTR_FORMAT "] %s+0x%x", pc, buf, offset);
+        _output->print("%28s", " ");
+      } else {
+        _output->print("[" PTR_FORMAT "]%18s", " ");
+      }
+    }
+
+    _output->print("(mmap: reserved=%d%s", cur_reserved_amt, unit);
+    if (reserved_diff != 0) {
+      _output->print(" %+d%s", reserved_diff, unit);
+    }
+    _output->print(", committed=%d%s", cur_committed_amt, unit);
+    if (committed_diff != 0) {
+      _output->print(" %+d%s", committed_diff, unit);
+    }
+    _output->print_cr(")");
+    _output->print_cr(" ");
+  }
+}
diff --git a/hotspot/src/share/vm/services/memReporter.hpp b/hotspot/src/share/vm/services/memReporter.hpp
new file mode 100644
index 0000000..537094f
--- /dev/null
+++ b/hotspot/src/share/vm/services/memReporter.hpp
@@ -0,0 +1,281 @@
+/*
+ * Copyright (c) 2012 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_MEM_REPORTER_HPP
+#define SHARE_VM_SERVICES_MEM_REPORTER_HPP
+
+#include "runtime/mutexLocker.hpp"
+#include "services/memBaseline.hpp"
+#include "services/memTracker.hpp"
+#include "utilities/ostream.hpp"
+
+/*
+ * MemBaselineReporter reports data to this outputer class,
+ * ReportOutputer is responsible for format, store and redirect
+ * the data to the final destination.
+ */
+class BaselineOutputer : public StackObj {
+ public:
+  // start to report memory usage in specified scale.
+  // if report_diff = true, the reporter reports baseline comparison
+  // information.
+
+  virtual void start(size_t scale, bool report_diff = false) = 0;
+  // Done reporting
+  virtual void done() = 0;
+
+  /* report baseline summary information */
+  virtual void total_usage(size_t total_reserved,
+                           size_t total_committed) = 0;
+  virtual void num_of_classes(size_t classes) = 0;
+  virtual void num_of_threads(size_t threads) = 0;
+
+  virtual void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) = 0;
+
+  /* report baseline summary comparison */
+  virtual void diff_total_usage(size_t total_reserved,
+                                size_t total_committed,
+                                int reserved_diff,
+                                int committed_diff) = 0;
+  virtual void diff_num_of_classes(size_t classes, int diff) = 0;
+  virtual void diff_num_of_threads(size_t threads, int diff) = 0;
+
+  virtual void diff_thread_info(size_t stack_reserved, size_t stack_committed,
+        int stack_reserved_diff, int stack_committed_diff) = 0;
+
+
+  /*
+   * memory summary by memory types.
+   * for each memory type, following summaries are reported:
+   *  - reserved amount, committed amount
+   *  - malloc'd amount, malloc count
+   *  - arena amount, arena count
+   */
+
+  // start reporting memory summary by memory type
+  virtual void start_category_summary() = 0;
+
+  virtual void category_summary(MEMFLAGS type, size_t reserved_amt,
+                                size_t committed_amt,
+                                size_t malloc_amt, size_t malloc_count,
+                                size_t arena_amt, size_t arena_count) = 0;
+
+  virtual void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt,
+                                size_t cur_committed_amt,
+                                size_t cur_malloc_amt, size_t cur_malloc_count,
+                                size_t cur_arena_amt, size_t cur_arena_count,
+                                int reserved_diff, int committed_diff, int malloc_diff,
+                                int malloc_count_diff, int arena_diff,
+                                int arena_count_diff) = 0;
+
+  virtual void done_category_summary() = 0;
+
+  virtual void start_virtual_memory_map() = 0;
+  virtual void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc) = 0;
+  virtual void committed_memory_region(address base, address end, size_t size, address pc) = 0;
+  virtual void done_virtual_memory_map() = 0;
+
+  /*
+   *  Report callsite information
+   */
+  virtual void start_callsite() = 0;
+  virtual void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count) = 0;
+  virtual void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt) = 0;
+
+  virtual void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count,
+              int malloc_diff, int malloc_count_diff) = 0;
+  virtual void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt,
+              int reserved_diff, int committed_diff) = 0;
+
+  virtual void done_callsite() = 0;
+
+  // return current scale in "KB", "MB" or "GB"
+  static const char* memory_unit(size_t scale);
+};
+
+/*
+ * This class reports processed data from a baseline or
+ * the changes between the two baseline.
+ */
+class BaselineReporter : public StackObj {
+ private:
+  BaselineOutputer&  _outputer;
+  size_t             _scale;
+
+ public:
+  // construct a reporter that reports memory usage
+  // in specified scale
+  BaselineReporter(BaselineOutputer& outputer, size_t scale = K):
+    _outputer(outputer) {
+    _scale = scale;
+  }
+  virtual void report_baseline(const MemBaseline& baseline, bool summary_only = false);
+  virtual void diff_baselines(const MemBaseline& cur, const MemBaseline& prev,
+                              bool summary_only = false);
+
+  void set_scale(size_t scale);
+  size_t scale() const { return _scale; }
+
+ private:
+  void report_summaries(const MemBaseline& baseline);
+  void report_virtual_memory_map(const MemBaseline& baseline);
+  void report_callsites(const MemBaseline& baseline);
+
+  void diff_summaries(const MemBaseline& cur, const MemBaseline& prev);
+  void diff_callsites(const MemBaseline& cur, const MemBaseline& prev);
+
+  // calculate memory size in current memory scale
+  size_t amount_in_current_scale(size_t amt) const;
+  // diff two unsigned values in current memory scale
+  int    diff_in_current_scale(size_t value1, size_t value2) const;
+  // diff two unsigned value
+  int    diff(size_t value1, size_t value2) const;
+};
+
+/*
+ * tty output implementation. Native memory tracking
+ * DCmd uses this outputer.
+ */
+class BaselineTTYOutputer : public BaselineOutputer {
+ private:
+  size_t         _scale;
+
+  size_t         _num_of_classes;
+  size_t         _num_of_threads;
+  size_t         _thread_stack_reserved;
+  size_t         _thread_stack_committed;
+
+  int            _num_of_classes_diff;
+  int            _num_of_threads_diff;
+  int            _thread_stack_reserved_diff;
+  int            _thread_stack_committed_diff;
+
+  outputStream*  _output;
+
+ public:
+  BaselineTTYOutputer(outputStream* st) {
+    _scale = K;
+    _num_of_classes = 0;
+    _num_of_threads = 0;
+    _thread_stack_reserved = 0;
+    _thread_stack_committed = 0;
+    _num_of_classes_diff = 0;
+    _num_of_threads_diff = 0;
+    _thread_stack_reserved_diff = 0;
+    _thread_stack_committed_diff = 0;
+    _output = st;
+  }
+
+  // begin reporting memory usage in specified scale
+  void start(size_t scale, bool report_diff = false);
+  // done reporting
+  void done();
+
+  // total memory usage
+  void total_usage(size_t total_reserved,
+                   size_t total_committed);
+  // report total loaded classes
+  void num_of_classes(size_t classes) {
+    _num_of_classes = classes;
+  }
+
+  void num_of_threads(size_t threads) {
+    _num_of_threads = threads;
+  }
+
+  void thread_info(size_t stack_reserved_amt, size_t stack_committed_amt) {
+    _thread_stack_reserved = stack_reserved_amt;
+    _thread_stack_committed = stack_committed_amt;
+  }
+
+  void diff_total_usage(size_t total_reserved,
+                        size_t total_committed,
+                        int reserved_diff,
+                        int committed_diff);
+
+  void diff_num_of_classes(size_t classes, int diff) {
+    _num_of_classes = classes;
+    _num_of_classes_diff = diff;
+  }
+
+  void diff_num_of_threads(size_t threads, int diff) {
+    _num_of_threads = threads;
+    _num_of_threads_diff = diff;
+  }
+
+  void diff_thread_info(size_t stack_reserved_amt, size_t stack_committed_amt,
+               int stack_reserved_diff, int stack_committed_diff) {
+    _thread_stack_reserved = stack_reserved_amt;
+    _thread_stack_committed = stack_committed_amt;
+    _thread_stack_reserved_diff = stack_reserved_diff;
+    _thread_stack_committed_diff = stack_committed_diff;
+  }
+
+  /*
+   * Report memory summary categoriuzed by memory types.
+   * For each memory type, following summaries are reported:
+   *  - reserved amount, committed amount
+   *  - malloc-ed amount, malloc count
+   *  - arena amount, arena count
+   */
+  // start reporting memory summary by memory type
+  void start_category_summary();
+  void category_summary(MEMFLAGS type, size_t reserved_amt, size_t committed_amt,
+                               size_t malloc_amt, size_t malloc_count,
+                               size_t arena_amt, size_t arena_count);
+
+  void diff_category_summary(MEMFLAGS type, size_t cur_reserved_amt,
+                          size_t cur_committed_amt,
+                          size_t cur_malloc_amt, size_t cur_malloc_count,
+                          size_t cur_arena_amt, size_t cur_arena_count,
+                          int reserved_diff, int committed_diff, int malloc_diff,
+                          int malloc_count_diff, int arena_diff,
+                          int arena_count_diff);
+
+  void done_category_summary();
+
+  // virtual memory map
+  void start_virtual_memory_map();
+  void reserved_memory_region(MEMFLAGS type, address base, address end, size_t size, address pc);
+  void committed_memory_region(address base, address end, size_t size, address pc);
+  void done_virtual_memory_map();
+
+
+  /*
+   *  Report callsite information
+   */
+  void start_callsite();
+  void malloc_callsite(address pc, size_t malloc_amt, size_t malloc_count);
+  void virtual_memory_callsite(address pc, size_t reserved_amt, size_t committed_amt);
+
+  void diff_malloc_callsite(address pc, size_t cur_malloc_amt, size_t cur_malloc_count,
+              int malloc_diff, int malloc_count_diff);
+  void diff_virtual_memory_callsite(address pc, size_t cur_reserved_amt, size_t cur_committed_amt,
+              int reserved_diff, int committed_diff);
+
+  void done_callsite();
+};
+
+
+#endif // SHARE_VM_SERVICES_MEM_REPORTER_HPP
diff --git a/hotspot/src/share/vm/services/memSnapshot.cpp b/hotspot/src/share/vm/services/memSnapshot.cpp
new file mode 100644
index 0000000..c293542
--- /dev/null
+++ b/hotspot/src/share/vm/services/memSnapshot.cpp
@@ -0,0 +1,728 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "utilities/decoder.hpp"
+#include "services/memBaseline.hpp"
+#include "services/memPtr.hpp"
+#include "services/memPtrArray.hpp"
+#include "services/memSnapshot.hpp"
+#include "services/memTracker.hpp"
+
+#ifdef ASSERT
+
+void decode_pointer_record(MemPointerRecord* rec) {
+  tty->print("Pointer: [" PTR_FORMAT " - " PTR_FORMAT  "] size = %d bytes", rec->addr(),
+    rec->addr() + rec->size(), (int)rec->size());
+  tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
+  if (rec->is_vm_pointer()) {
+    if (rec->is_allocation_record()) {
+      tty->print_cr(" (reserve)");
+    } else if (rec->is_commit_record()) {
+      tty->print_cr(" (commit)");
+    } else if (rec->is_uncommit_record()) {
+      tty->print_cr(" (uncommit)");
+    } else if (rec->is_deallocation_record()) {
+      tty->print_cr(" (release)");
+    } else {
+      tty->print_cr(" (tag)");
+    }
+  } else {
+    if (rec->is_arena_memory_record()) {
+      tty->print_cr(" (arena size)");
+    } else if (rec->is_allocation_record()) {
+      tty->print_cr(" (malloc)");
+    } else {
+      tty->print_cr(" (free)");
+    }
+  }
+  if (MemTracker::track_callsite()) {
+    char buf[1024];
+    address pc = ((MemPointerRecordEx*)rec)->pc();
+    if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
+      tty->print_cr("\tfrom %s", buf);
+    } else {
+      tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
+    }
+  }
+}
+
+void decode_vm_region_record(VMMemRegion* rec) {
+  tty->print("VM Region [" PTR_FORMAT " - " PTR_FORMAT "]", rec->addr(),
+    rec->addr() + rec->size());
+  tty->print(" type = %s", MemBaseline::type2name(FLAGS_TO_MEMORY_TYPE(rec->flags())));
+  if (rec->is_allocation_record()) {
+    tty->print_cr(" (reserved)");
+  } else if (rec->is_commit_record()) {
+    tty->print_cr(" (committed)");
+  } else {
+    ShouldNotReachHere();
+  }
+  if (MemTracker::track_callsite()) {
+    char buf[1024];
+    address pc = ((VMMemRegionEx*)rec)->pc();
+    if (pc != NULL && os::dll_address_to_function_name(pc, buf, sizeof(buf), NULL)) {
+      tty->print_cr("\tfrom %s", buf);
+    } else {
+      tty->print_cr("\tcould not decode pc = " PTR_FORMAT "", pc);
+    }
+
+  }
+}
+
+#endif
+
+
+bool VMMemPointerIterator::insert_record(MemPointerRecord* rec) {
+  VMMemRegionEx new_rec;
+  assert(rec->is_allocation_record() || rec->is_commit_record(),
+    "Sanity check");
+  if (MemTracker::track_callsite()) {
+    new_rec.init((MemPointerRecordEx*)rec);
+  } else {
+    new_rec.init(rec);
+  }
+  return insert(&new_rec);
+}
+
+bool VMMemPointerIterator::insert_record_after(MemPointerRecord* rec) {
+  VMMemRegionEx new_rec;
+  assert(rec->is_allocation_record() || rec->is_commit_record(),
+    "Sanity check");
+  if (MemTracker::track_callsite()) {
+    new_rec.init((MemPointerRecordEx*)rec);
+  } else {
+    new_rec.init(rec);
+  }
+  return insert_after(&new_rec);
+}
+
+// we don't consolidate reserved regions, since they may be categorized
+// in different types.
+bool VMMemPointerIterator::add_reserved_region(MemPointerRecord* rec) {
+  assert(rec->is_allocation_record(), "Sanity check");
+  VMMemRegion* reserved_region = (VMMemRegion*)current();
+
+  // we don't have anything yet
+  if (reserved_region == NULL) {
+    return insert_record(rec);
+  }
+
+  assert(reserved_region->is_reserved_region(), "Sanity check");
+  // duplicated records
+  if (reserved_region->is_same_region(rec)) {
+    return true;
+  }
+  // Overlapping stack regions indicate that a JNI thread failed to
+  // detach from the VM before exiting. This leaks the JavaThread object.
+  if (CheckJNICalls)  {
+      guarantee(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) != mtThreadStack ||
+         !reserved_region->overlaps_region(rec),
+         "Attached JNI thread exited without being detached");
+  }
+  // otherwise, we should not have overlapping reserved regions
+  assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
+    reserved_region->base() > rec->addr(), "Just check: locate()");
+  assert(FLAGS_TO_MEMORY_TYPE(reserved_region->flags()) == mtThreadStack ||
+    !reserved_region->overlaps_region(rec), "overlapping reserved regions");
+
+  return insert_record(rec);
+}
+
+// we do consolidate committed regions
+bool VMMemPointerIterator::add_committed_region(MemPointerRecord* rec) {
+  assert(rec->is_commit_record(), "Sanity check");
+  VMMemRegion* reserved_rgn = (VMMemRegion*)current();
+  assert(reserved_rgn->is_reserved_region() && reserved_rgn->contains_region(rec),
+    "Sanity check");
+
+  // thread's native stack is always marked as "committed", ignore
+  // the "commit" operation for creating stack guard pages
+  if (FLAGS_TO_MEMORY_TYPE(reserved_rgn->flags()) == mtThreadStack &&
+      FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
+    return true;
+  }
+
+  // if the reserved region has any committed regions
+  VMMemRegion* committed_rgn  = (VMMemRegion*)next();
+  while (committed_rgn != NULL && committed_rgn->is_committed_region()) {
+    // duplicated commit records
+    if(committed_rgn->contains_region(rec)) {
+      return true;
+    } else if (committed_rgn->overlaps_region(rec)) {
+      // overlaps front part
+      if (rec->addr() < committed_rgn->addr()) {
+        committed_rgn->expand_region(rec->addr(),
+          committed_rgn->addr() - rec->addr());
+      } else {
+        // overlaps tail part
+        address committed_rgn_end = committed_rgn->addr() +
+              committed_rgn->size();
+        assert(committed_rgn_end < rec->addr() + rec->size(),
+             "overlap tail part");
+        committed_rgn->expand_region(committed_rgn_end,
+          (rec->addr() + rec->size()) - committed_rgn_end);
+      }
+    } else if (committed_rgn->base() + committed_rgn->size() == rec->addr()) {
+      // adjunct each other
+      committed_rgn->expand_region(rec->addr(), rec->size());
+      VMMemRegion* next_reg = (VMMemRegion*)next();
+      // see if we can consolidate next committed region
+      if (next_reg != NULL && next_reg->is_committed_region() &&
+        next_reg->base() == committed_rgn->base() + committed_rgn->size()) {
+          committed_rgn->expand_region(next_reg->base(), next_reg->size());
+          // delete merged region
+          remove();
+      }
+      return true;
+    } else if (committed_rgn->base() > rec->addr()) {
+      // found the location, insert this committed region
+      return insert_record(rec);
+    }
+    committed_rgn = (VMMemRegion*)next();
+  }
+  return insert_record(rec);
+}
+
+bool VMMemPointerIterator::remove_uncommitted_region(MemPointerRecord* rec) {
+  assert(rec->is_uncommit_record(), "sanity check");
+  VMMemRegion* cur;
+  cur = (VMMemRegion*)current();
+  assert(cur->is_reserved_region() && cur->contains_region(rec),
+    "Sanity check");
+  // thread's native stack is always marked as "committed", ignore
+  // the "commit" operation for creating stack guard pages
+  if (FLAGS_TO_MEMORY_TYPE(cur->flags()) == mtThreadStack &&
+      FLAGS_TO_MEMORY_TYPE(rec->flags()) != mtThreadStack) {
+    return true;
+  }
+
+  cur = (VMMemRegion*)next();
+  while (cur != NULL && cur->is_committed_region()) {
+    // region already uncommitted, must be due to duplicated record
+    if (cur->addr() >= rec->addr() + rec->size()) {
+      break;
+    } else if (cur->contains_region(rec)) {
+      // uncommit whole region
+      if (cur->is_same_region(rec)) {
+        remove();
+        break;
+      } else if (rec->addr() == cur->addr() ||
+        rec->addr() + rec->size() == cur->addr() + cur->size()) {
+        // uncommitted from either end of current memory region.
+        cur->exclude_region(rec->addr(), rec->size());
+        break;
+      } else { // split the committed region and release the middle
+        address high_addr = cur->addr() + cur->size();
+        size_t sz = high_addr - rec->addr();
+        cur->exclude_region(rec->addr(), sz);
+        sz = high_addr - (rec->addr() + rec->size());
+        if (MemTracker::track_callsite()) {
+          MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
+             ((VMMemRegionEx*)cur)->pc());
+          return insert_record_after(&tmp);
+        } else {
+          MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
+          return insert_record_after(&tmp);
+        }
+      }
+    }
+    cur = (VMMemRegion*)next();
+  }
+
+  // we may not find committed record due to duplicated records
+  return true;
+}
+
+bool VMMemPointerIterator::remove_released_region(MemPointerRecord* rec) {
+  assert(rec->is_deallocation_record(), "Sanity check");
+  VMMemRegion* cur = (VMMemRegion*)current();
+  assert(cur->is_reserved_region() && cur->contains_region(rec),
+    "Sanity check");
+  if (rec->is_same_region(cur)) {
+    // release whole reserved region
+#ifdef ASSERT
+    VMMemRegion* next_region = (VMMemRegion*)peek_next();
+    // should not have any committed memory in this reserved region
+    assert(next_region == NULL || !next_region->is_committed_region(), "Sanity check");
+#endif
+    remove();
+  } else if (rec->addr() == cur->addr() ||
+    rec->addr() + rec->size() == cur->addr() + cur->size()) {
+    // released region is at either end of this region
+    cur->exclude_region(rec->addr(), rec->size());
+    assert(check_reserved_region(), "Integrity check");
+  } else { // split the reserved region and release the middle
+    address high_addr = cur->addr() + cur->size();
+    size_t sz = high_addr - rec->addr();
+    cur->exclude_region(rec->addr(), sz);
+    sz = high_addr - rec->addr() - rec->size();
+    if (MemTracker::track_callsite()) {
+      MemPointerRecordEx tmp(rec->addr() + rec->size(), cur->flags(), sz,
+        ((VMMemRegionEx*)cur)->pc());
+      bool ret = insert_reserved_region(&tmp);
+      assert(!ret || check_reserved_region(), "Integrity check");
+      return ret;
+    } else {
+      MemPointerRecord tmp(rec->addr() + rec->size(), cur->flags(), sz);
+      bool ret = insert_reserved_region(&tmp);
+      assert(!ret || check_reserved_region(), "Integrity check");
+      return ret;
+    }
+  }
+  return true;
+}
+
+bool VMMemPointerIterator::insert_reserved_region(MemPointerRecord* rec) {
+  // skip all 'commit' records associated with previous reserved region
+  VMMemRegion* p = (VMMemRegion*)next();
+  while (p != NULL && p->is_committed_region() &&
+         p->base() + p->size() < rec->addr()) {
+    p = (VMMemRegion*)next();
+  }
+  return insert_record(rec);
+}
+
+bool VMMemPointerIterator::split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size) {
+  assert(rgn->contains_region(new_rgn_addr, new_rgn_size), "Not fully contained");
+  address pc = (MemTracker::track_callsite() ? ((VMMemRegionEx*)rgn)->pc() : NULL);
+  if (rgn->base() == new_rgn_addr) { // new region is at the beginning of the region
+    size_t sz = rgn->size() - new_rgn_size;
+    // the original region becomes 'new' region
+    rgn->exclude_region(new_rgn_addr + new_rgn_size, sz);
+     // remaining becomes next region
+    MemPointerRecordEx next_rgn(new_rgn_addr + new_rgn_size, rgn->flags(), sz, pc);
+    return insert_reserved_region(&next_rgn);
+  } else if (rgn->base() + rgn->size() == new_rgn_addr + new_rgn_size) {
+    rgn->exclude_region(new_rgn_addr, new_rgn_size);
+    MemPointerRecordEx next_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc);
+    return insert_reserved_region(&next_rgn);
+  } else {
+    // the orginal region will be split into three
+    address rgn_high_addr = rgn->base() + rgn->size();
+    // first region
+    rgn->exclude_region(new_rgn_addr, (rgn_high_addr - new_rgn_addr));
+    // the second region is the new region
+    MemPointerRecordEx new_rgn(new_rgn_addr, rgn->flags(), new_rgn_size, pc);
+    if (!insert_reserved_region(&new_rgn)) return false;
+    // the remaining region
+    MemPointerRecordEx rem_rgn(new_rgn_addr + new_rgn_size, rgn->flags(),
+      rgn_high_addr - (new_rgn_addr + new_rgn_size), pc);
+    return insert_reserved_region(&rem_rgn);
+  }
+}
+
+static int sort_in_seq_order(const void* p1, const void* p2) {
+  assert(p1 != NULL && p2 != NULL, "Sanity check");
+  const MemPointerRecord* mp1 = (MemPointerRecord*)p1;
+  const MemPointerRecord* mp2 = (MemPointerRecord*)p2;
+  return (mp1->seq() - mp2->seq());
+}
+
+bool StagingArea::init() {
+  if (MemTracker::track_callsite()) {
+    _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>();
+    _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecordEx>();
+  } else {
+    _malloc_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
+    _vm_data = new (std::nothrow)MemPointerArrayImpl<SeqMemPointerRecord>();
+  }
+
+  if (_malloc_data != NULL && _vm_data != NULL &&
+      !_malloc_data->out_of_memory() &&
+      !_vm_data->out_of_memory()) {
+    return true;
+  } else {
+    if (_malloc_data != NULL) delete _malloc_data;
+    if (_vm_data != NULL) delete _vm_data;
+    _malloc_data = NULL;
+    _vm_data = NULL;
+    return false;
+  }
+}
+
+
+VMRecordIterator StagingArea::virtual_memory_record_walker() {
+  MemPointerArray* arr = vm_data();
+  // sort into seq number order
+  arr->sort((FN_SORT)sort_in_seq_order);
+  return VMRecordIterator(arr);
+}
+
+
+MemSnapshot::MemSnapshot() {
+  if (MemTracker::track_callsite()) {
+    _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecordEx>();
+    _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegionEx>(64, true);
+  } else {
+    _alloc_ptrs = new (std::nothrow) MemPointerArrayImpl<MemPointerRecord>();
+    _vm_ptrs = new (std::nothrow)MemPointerArrayImpl<VMMemRegion>(64, true);
+  }
+
+  _staging_area.init();
+  _lock = new (std::nothrow) Mutex(Monitor::max_nonleaf - 1, "memSnapshotLock");
+  NOT_PRODUCT(_untracked_count = 0;)
+}
+
+MemSnapshot::~MemSnapshot() {
+  assert(MemTracker::shutdown_in_progress(), "native memory tracking still on");
+  {
+    MutexLockerEx locker(_lock);
+    if (_alloc_ptrs != NULL) {
+      delete _alloc_ptrs;
+      _alloc_ptrs = NULL;
+    }
+
+    if (_vm_ptrs != NULL) {
+      delete _vm_ptrs;
+      _vm_ptrs = NULL;
+    }
+  }
+
+  if (_lock != NULL) {
+    delete _lock;
+    _lock = NULL;
+  }
+}
+
+
+void MemSnapshot::copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src) {
+  assert(dest != NULL && src != NULL, "Just check");
+  assert(dest->addr() == src->addr(), "Just check");
+  assert(dest->seq() > 0 && src->seq() > 0, "not sequenced");
+
+  if (MemTracker::track_callsite()) {
+    *(SeqMemPointerRecordEx*)dest = *(SeqMemPointerRecordEx*)src;
+  } else {
+    *(SeqMemPointerRecord*)dest = *(SeqMemPointerRecord*)src;
+  }
+}
+
+void MemSnapshot::assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src) {
+  assert(src != NULL && dest != NULL, "Just check");
+  assert(dest->seq() == 0 && src->seq() >0, "cast away sequence");
+
+  if (MemTracker::track_callsite()) {
+    *(MemPointerRecordEx*)dest = *(MemPointerRecordEx*)src;
+  } else {
+    *(MemPointerRecord*)dest = *(MemPointerRecord*)src;
+  }
+}
+
+// merge a recorder to the staging area
+bool MemSnapshot::merge(MemRecorder* rec) {
+  assert(rec != NULL && !rec->out_of_memory(), "Just check");
+
+  SequencedRecordIterator itr(rec->pointer_itr());
+
+  MutexLockerEx lock(_lock, true);
+  MemPointerIterator malloc_staging_itr(_staging_area.malloc_data());
+  MemPointerRecord* incoming_rec = (MemPointerRecord*) itr.current();
+  MemPointerRecord* matched_rec;
+
+  while (incoming_rec != NULL) {
+    if (incoming_rec->is_vm_pointer()) {
+      // we don't do anything with virtual memory records during merge
+      if (!_staging_area.vm_data()->append(incoming_rec)) {
+        return false;
+      }
+    } else {
+      // locate matched record and/or also position the iterator to proper
+      // location for this incoming record.
+      matched_rec = (MemPointerRecord*)malloc_staging_itr.locate(incoming_rec->addr());
+      // we have not seen this memory block in this generation,
+      // so just add to staging area
+      if (matched_rec == NULL) {
+        if (!malloc_staging_itr.insert(incoming_rec)) {
+          return false;
+        }
+      } else if (incoming_rec->addr() == matched_rec->addr()) {
+        // whoever has higher sequence number wins
+        if (incoming_rec->seq() > matched_rec->seq()) {
+          copy_seq_pointer(matched_rec, incoming_rec);
+        }
+      } else if (incoming_rec->addr() < matched_rec->addr()) {
+        if (!malloc_staging_itr.insert(incoming_rec)) {
+          return false;
+        }
+      } else {
+        ShouldNotReachHere();
+      }
+    }
+    incoming_rec = (MemPointerRecord*)itr.next();
+  }
+  NOT_PRODUCT(void check_staging_data();)
+  return true;
+}
+
+
+// promote data to next generation
+bool MemSnapshot::promote() {
+  assert(_alloc_ptrs != NULL && _vm_ptrs != NULL, "Just check");
+  assert(_staging_area.malloc_data() != NULL && _staging_area.vm_data() != NULL,
+         "Just check");
+  MutexLockerEx lock(_lock, true);
+
+  MallocRecordIterator  malloc_itr = _staging_area.malloc_record_walker();
+  bool promoted = false;
+  if (promote_malloc_records(&malloc_itr)) {
+    VMRecordIterator vm_itr = _staging_area.virtual_memory_record_walker();
+    if (promote_virtual_memory_records(&vm_itr)) {
+      promoted = true;
+    }
+  }
+
+  NOT_PRODUCT(check_malloc_pointers();)
+  _staging_area.clear();
+  return promoted;
+}
+
+bool MemSnapshot::promote_malloc_records(MemPointerArrayIterator* itr) {
+  MemPointerIterator malloc_snapshot_itr(_alloc_ptrs);
+  MemPointerRecord* new_rec = (MemPointerRecord*)itr->current();
+  MemPointerRecord* matched_rec;
+  while (new_rec != NULL) {
+    matched_rec = (MemPointerRecord*)malloc_snapshot_itr.locate(new_rec->addr());
+    // found matched memory block
+    if (matched_rec != NULL && new_rec->addr() == matched_rec->addr()) {
+      // snapshot already contains 'live' records
+      assert(matched_rec->is_allocation_record() || matched_rec->is_arena_memory_record(),
+             "Sanity check");
+      // update block states
+      if (new_rec->is_allocation_record()) {
+        assign_pointer(matched_rec, new_rec);
+      } else if (new_rec->is_arena_memory_record()) {
+        if (new_rec->size() == 0) {
+          // remove size record once size drops to 0
+          malloc_snapshot_itr.remove();
+        } else {
+          assign_pointer(matched_rec, new_rec);
+        }
+      } else {
+        // a deallocation record
+        assert(new_rec->is_deallocation_record(), "Sanity check");
+        // an arena record can be followed by a size record, we need to remove both
+        if (matched_rec->is_arena_record()) {
+          MemPointerRecord* next = (MemPointerRecord*)malloc_snapshot_itr.peek_next();
+          if (next->is_arena_memory_record() && next->is_memory_record_of_arena(matched_rec)) {
+            malloc_snapshot_itr.remove();
+          }
+        }
+        // the memory is deallocated, remove related record(s)
+        malloc_snapshot_itr.remove();
+      }
+    } else {
+      // don't insert size 0 record
+      if (new_rec->is_arena_memory_record() && new_rec->size() == 0) {
+        new_rec = NULL;
+      }
+
+      if (new_rec != NULL) {
+        if  (new_rec->is_allocation_record() || new_rec->is_arena_memory_record()) {
+          if (matched_rec != NULL && new_rec->addr() > matched_rec->addr()) {
+            if (!malloc_snapshot_itr.insert_after(new_rec)) {
+              return false;
+            }
+          } else {
+            if (!malloc_snapshot_itr.insert(new_rec)) {
+              return false;
+            }
+          }
+        }
+#ifndef PRODUCT
+        else if (!has_allocation_record(new_rec->addr())) {
+          // NMT can not track some startup memory, which is allocated before NMT is on
+          _untracked_count ++;
+        }
+#endif
+      }
+    }
+    new_rec = (MemPointerRecord*)itr->next();
+  }
+  return true;
+}
+
+bool MemSnapshot::promote_virtual_memory_records(MemPointerArrayIterator* itr) {
+  VMMemPointerIterator vm_snapshot_itr(_vm_ptrs);
+  MemPointerRecord* new_rec = (MemPointerRecord*)itr->current();
+  VMMemRegion*  reserved_rec;
+  while (new_rec != NULL) {
+    assert(new_rec->is_vm_pointer(), "Sanity check");
+
+    // locate a reserved region that contains the specified address, or
+    // the nearest reserved region has base address just above the specified
+    // address
+    reserved_rec = (VMMemRegion*)vm_snapshot_itr.locate(new_rec->addr());
+    if (reserved_rec != NULL && reserved_rec->contains_region(new_rec)) {
+      // snapshot can only have 'live' records
+      assert(reserved_rec->is_reserved_region(), "Sanity check");
+      if (new_rec->is_allocation_record()) {
+        if (!reserved_rec->is_same_region(new_rec)) {
+          // only deal with split a bigger reserved region into smaller regions.
+          // So far, CDS is the only use case.
+          if (!vm_snapshot_itr.split_reserved_region(reserved_rec, new_rec->addr(), new_rec->size())) {
+            return false;
+          }
+        }
+      } else if (new_rec->is_uncommit_record()) {
+        if (!vm_snapshot_itr.remove_uncommitted_region(new_rec)) {
+          return false;
+        }
+      } else if (new_rec->is_commit_record()) {
+        // insert or expand existing committed region to cover this
+        // newly committed region
+        if (!vm_snapshot_itr.add_committed_region(new_rec)) {
+          return false;
+        }
+      } else if (new_rec->is_deallocation_record()) {
+        // release part or all memory region
+        if (!vm_snapshot_itr.remove_released_region(new_rec)) {
+          return false;
+        }
+      } else if (new_rec->is_type_tagging_record()) {
+        // tag this reserved virtual memory range to a memory type. Can not re-tag a memory range
+        // to different type.
+        assert(FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == mtNone ||
+               FLAGS_TO_MEMORY_TYPE(reserved_rec->flags()) == FLAGS_TO_MEMORY_TYPE(new_rec->flags()),
+               "Sanity check");
+        reserved_rec->tag(new_rec->flags());
+    } else {
+        ShouldNotReachHere();
+          }
+        } else {
+      /*
+       * The assertion failure indicates mis-matched virtual memory records. The likely
+       * scenario is, that some virtual memory operations are not going through os::xxxx_memory()
+       * api, which have to be tracked manually. (perfMemory is an example).
+      */
+      assert(new_rec->is_allocation_record(), "Sanity check");
+      if (!vm_snapshot_itr.add_reserved_region(new_rec)) {
+            return false;
+          }
+  }
+    new_rec = (MemPointerRecord*)itr->next();
+  }
+  return true;
+}
+
+#ifndef PRODUCT
+void MemSnapshot::print_snapshot_stats(outputStream* st) {
+  st->print_cr("Snapshot:");
+  st->print_cr("\tMalloced: %d/%d [%5.2f%%]  %dKB", _alloc_ptrs->length(), _alloc_ptrs->capacity(),
+    (100.0 * (float)_alloc_ptrs->length()) / (float)_alloc_ptrs->capacity(), _alloc_ptrs->instance_size()/K);
+
+  st->print_cr("\tVM: %d/%d [%5.2f%%] %dKB", _vm_ptrs->length(), _vm_ptrs->capacity(),
+    (100.0 * (float)_vm_ptrs->length()) / (float)_vm_ptrs->capacity(), _vm_ptrs->instance_size()/K);
+
+  st->print_cr("\tMalloc staging Area:     %d/%d [%5.2f%%] %dKB", _staging_area.malloc_data()->length(),
+    _staging_area.malloc_data()->capacity(),
+    (100.0 * (float)_staging_area.malloc_data()->length()) / (float)_staging_area.malloc_data()->capacity(),
+    _staging_area.malloc_data()->instance_size()/K);
+
+  st->print_cr("\tVirtual memory staging Area:     %d/%d [%5.2f%%] %dKB", _staging_area.vm_data()->length(),
+    _staging_area.vm_data()->capacity(),
+    (100.0 * (float)_staging_area.vm_data()->length()) / (float)_staging_area.vm_data()->capacity(),
+    _staging_area.vm_data()->instance_size()/K);
+
+  st->print_cr("\tUntracked allocation: %d", _untracked_count);
+}
+
+void MemSnapshot::check_malloc_pointers() {
+  MemPointerArrayIteratorImpl mItr(_alloc_ptrs);
+  MemPointerRecord* p = (MemPointerRecord*)mItr.current();
+  MemPointerRecord* prev = NULL;
+  while (p != NULL) {
+    if (prev != NULL) {
+      assert(p->addr() >= prev->addr(), "sorting order");
+    }
+    prev = p;
+    p = (MemPointerRecord*)mItr.next();
+  }
+}
+
+bool MemSnapshot::has_allocation_record(address addr) {
+  MemPointerArrayIteratorImpl itr(_staging_area.malloc_data());
+  MemPointerRecord* cur = (MemPointerRecord*)itr.current();
+  while (cur != NULL) {
+    if (cur->addr() == addr && cur->is_allocation_record()) {
+      return true;
+    }
+    cur = (MemPointerRecord*)itr.next();
+  }
+  return false;
+}
+#endif // PRODUCT
+
+#ifdef ASSERT
+void MemSnapshot::check_staging_data() {
+  MemPointerArrayIteratorImpl itr(_staging_area.malloc_data());
+  MemPointerRecord* cur = (MemPointerRecord*)itr.current();
+  MemPointerRecord* next = (MemPointerRecord*)itr.next();
+  while (next != NULL) {
+    assert((next->addr() > cur->addr()) ||
+      ((next->flags() & MemPointerRecord::tag_masks) >
+       (cur->flags() & MemPointerRecord::tag_masks)),
+       "sorting order");
+    cur = next;
+    next = (MemPointerRecord*)itr.next();
+  }
+
+  MemPointerArrayIteratorImpl vm_itr(_staging_area.vm_data());
+  cur = (MemPointerRecord*)vm_itr.current();
+  while (cur != NULL) {
+    assert(cur->is_vm_pointer(), "virtual memory pointer only");
+    cur = (MemPointerRecord*)vm_itr.next();
+  }
+}
+
+void MemSnapshot::dump_all_vm_pointers() {
+  MemPointerArrayIteratorImpl itr(_vm_ptrs);
+  VMMemRegion* ptr = (VMMemRegion*)itr.current();
+  tty->print_cr("dump virtual memory pointers:");
+  while (ptr != NULL) {
+    if (ptr->is_committed_region()) {
+      tty->print("\t");
+    }
+    tty->print("[" PTR_FORMAT " - " PTR_FORMAT "] [%x]", ptr->addr(),
+      (ptr->addr() + ptr->size()), ptr->flags());
+
+    if (MemTracker::track_callsite()) {
+      VMMemRegionEx* ex = (VMMemRegionEx*)ptr;
+      if (ex->pc() != NULL) {
+        char buf[1024];
+        if (os::dll_address_to_function_name(ex->pc(), buf, sizeof(buf), NULL)) {
+          tty->print_cr("\t%s", buf);
+        } else {
+          tty->print_cr("");
+        }
+      }
+    }
+
+    ptr = (VMMemRegion*)itr.next();
+  }
+  tty->flush();
+}
+#endif // ASSERT
+
diff --git a/hotspot/src/share/vm/services/memSnapshot.hpp b/hotspot/src/share/vm/services/memSnapshot.hpp
new file mode 100644
index 0000000..5755108
--- /dev/null
+++ b/hotspot/src/share/vm/services/memSnapshot.hpp
@@ -0,0 +1,404 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP
+#define SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/mutex.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "services/memBaseline.hpp"
+#include "services/memPtrArray.hpp"
+
+// Snapshot pointer array iterator
+
+// The pointer array contains malloc-ed pointers
+class MemPointerIterator : public MemPointerArrayIteratorImpl {
+ public:
+  MemPointerIterator(MemPointerArray* arr):
+    MemPointerArrayIteratorImpl(arr) {
+    assert(arr != NULL, "null array");
+  }
+
+#ifdef ASSERT
+  virtual bool is_dup_pointer(const MemPointer* ptr1,
+    const MemPointer* ptr2) const {
+    MemPointerRecord* p1 = (MemPointerRecord*)ptr1;
+    MemPointerRecord* p2 = (MemPointerRecord*)ptr2;
+
+    if (p1->addr() != p2->addr()) return false;
+    if ((p1->flags() & MemPointerRecord::tag_masks) !=
+        (p2->flags() & MemPointerRecord::tag_masks)) {
+      return false;
+    }
+    // we do see multiple commit/uncommit on the same memory, it is ok
+    return (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_alloc ||
+           (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release;
+  }
+
+  virtual bool insert(MemPointer* ptr) {
+    if (_pos > 0) {
+      MemPointer* p1 = (MemPointer*)ptr;
+      MemPointer* p2 = (MemPointer*)_array->at(_pos - 1);
+      assert(!is_dup_pointer(p1, p2),
+        err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
+    }
+     if (_pos < _array->length() -1) {
+      MemPointer* p1 = (MemPointer*)ptr;
+      MemPointer* p2 = (MemPointer*)_array->at(_pos + 1);
+      assert(!is_dup_pointer(p1, p2),
+        err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
+     }
+    return _array->insert_at(ptr, _pos);
+  }
+
+  virtual bool insert_after(MemPointer* ptr) {
+    if (_pos > 0) {
+      MemPointer* p1 = (MemPointer*)ptr;
+      MemPointer* p2 = (MemPointer*)_array->at(_pos - 1);
+      assert(!is_dup_pointer(p1, p2),
+        err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
+    }
+    if (_pos < _array->length() - 1) {
+      MemPointer* p1 = (MemPointer*)ptr;
+      MemPointer* p2 = (MemPointer*)_array->at(_pos + 1);
+
+      assert(!is_dup_pointer(p1, p2),
+        err_msg("duplicated pointer, flag = [%x]", (unsigned int)((MemPointerRecord*)p1)->flags()));
+     }
+    if (_array->insert_at(ptr, _pos + 1)) {
+      _pos ++;
+      return true;
+    }
+    return false;
+  }
+#endif
+
+  virtual MemPointer* locate(address addr) {
+    MemPointer* cur = current();
+    while (cur != NULL && cur->addr() < addr) {
+      cur = next();
+    }
+    return cur;
+  }
+};
+
+class VMMemPointerIterator : public MemPointerIterator {
+ public:
+  VMMemPointerIterator(MemPointerArray* arr):
+      MemPointerIterator(arr) {
+  }
+
+  // locate an existing reserved memory region that contains specified address,
+  // or the reserved region just above this address, where the incoming
+  // reserved region should be inserted.
+  virtual MemPointer* locate(address addr) {
+    reset();
+    VMMemRegion* reg = (VMMemRegion*)current();
+    while (reg != NULL) {
+      if (reg->is_reserved_region()) {
+        if (reg->contains_address(addr) || addr < reg->base()) {
+          return reg;
+      }
+    }
+      reg = (VMMemRegion*)next();
+    }
+      return NULL;
+    }
+
+  // following methods update virtual memory in the context
+  // of 'current' position, which is properly positioned by
+  // callers via locate method.
+  bool add_reserved_region(MemPointerRecord* rec);
+  bool add_committed_region(MemPointerRecord* rec);
+  bool remove_uncommitted_region(MemPointerRecord* rec);
+  bool remove_released_region(MemPointerRecord* rec);
+
+  // split a reserved region to create a new memory region with specified base and size
+  bool split_reserved_region(VMMemRegion* rgn, address new_rgn_addr, size_t new_rgn_size);
+ private:
+  bool insert_record(MemPointerRecord* rec);
+  bool insert_record_after(MemPointerRecord* rec);
+
+  bool insert_reserved_region(MemPointerRecord* rec);
+
+  // reset current position
+  inline void reset() { _pos = 0; }
+#ifdef ASSERT
+  // check integrity of records on current reserved memory region.
+  bool check_reserved_region() {
+    VMMemRegion* reserved_region = (VMMemRegion*)current();
+    assert(reserved_region != NULL && reserved_region->is_reserved_region(),
+          "Sanity check");
+    // all committed regions that follow current reserved region, should all
+    // belong to the reserved region.
+    VMMemRegion* next_region = (VMMemRegion*)next();
+    for (; next_region != NULL && next_region->is_committed_region();
+         next_region = (VMMemRegion*)next() ) {
+      if(!reserved_region->contains_region(next_region)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  virtual bool is_dup_pointer(const MemPointer* ptr1,
+    const MemPointer* ptr2) const {
+    VMMemRegion* p1 = (VMMemRegion*)ptr1;
+    VMMemRegion* p2 = (VMMemRegion*)ptr2;
+
+    if (p1->addr() != p2->addr()) return false;
+    if ((p1->flags() & MemPointerRecord::tag_masks) !=
+        (p2->flags() & MemPointerRecord::tag_masks)) {
+      return false;
+    }
+    // we do see multiple commit/uncommit on the same memory, it is ok
+    return (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_alloc ||
+           (p1->flags() & MemPointerRecord::tag_masks) == MemPointerRecord::tag_release;
+  }
+#endif
+};
+
+class MallocRecordIterator : public MemPointerArrayIterator {
+ private:
+  MemPointerArrayIteratorImpl  _itr;
+
+
+
+ public:
+  MallocRecordIterator(MemPointerArray* arr) : _itr(arr) {
+  }
+
+  virtual MemPointer* current() const {
+#ifdef ASSERT
+    MemPointer* cur_rec = _itr.current();
+    if (cur_rec != NULL) {
+      MemPointer* prev_rec = _itr.peek_prev();
+      MemPointer* next_rec = _itr.peek_next();
+      assert(prev_rec == NULL || prev_rec->addr() < cur_rec->addr(), "Sorting order");
+      assert(next_rec == NULL || next_rec->addr() > cur_rec->addr(), "Sorting order");
+    }
+#endif
+    return _itr.current();
+  }
+  virtual MemPointer* next() {
+    MemPointerRecord* next_rec = (MemPointerRecord*)_itr.next();
+    // arena memory record is a special case, which we have to compare
+    // sequence number against its associated arena record.
+    if (next_rec != NULL && next_rec->is_arena_memory_record()) {
+      MemPointerRecord* prev_rec = (MemPointerRecord*)_itr.peek_prev();
+      // if there is an associated arena record, it has to be previous
+      // record because of sorting order (by address) - NMT generates a pseudo address
+      // for arena's size record by offsetting arena's address, that guarantees
+      // the order of arena record and it's size record.
+      if (prev_rec != NULL && prev_rec->is_arena_record() &&
+        next_rec->is_memory_record_of_arena(prev_rec)) {
+        if (prev_rec->seq() > next_rec->seq()) {
+          // Skip this arena memory record
+          // Two scenarios:
+          //   - if the arena record is an allocation record, this early
+          //     size record must be leftover by previous arena,
+          //     and the last size record should have size = 0.
+          //   - if the arena record is a deallocation record, this
+          //     size record should be its cleanup record, which should
+          //     also have size = 0. In other world, arena alway reset
+          //     its size before gone (see Arena's destructor)
+          assert(next_rec->size() == 0, "size not reset");
+          return _itr.next();
+        } else {
+          assert(prev_rec->is_allocation_record(),
+            "Arena size record ahead of allocation record");
+        }
+      }
+    }
+    return next_rec;
+  }
+
+  MemPointer* peek_next() const      { ShouldNotReachHere(); return NULL; }
+  MemPointer* peek_prev() const      { ShouldNotReachHere(); return NULL; }
+  void remove()                      { ShouldNotReachHere(); }
+  bool insert(MemPointer* ptr)       { ShouldNotReachHere(); return false; }
+  bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; }
+};
+
+// collapse duplicated records. Eliminating duplicated records here, is much
+// cheaper than during promotion phase. However, it does have limitation - it
+// can only eliminate duplicated records within the generation, there are
+// still chances seeing duplicated records during promotion.
+// We want to use the record with higher sequence number, because it has
+// more accurate callsite pc.
+class VMRecordIterator : public MemPointerArrayIterator {
+ private:
+  MemPointerArrayIteratorImpl  _itr;
+
+ public:
+  VMRecordIterator(MemPointerArray* arr) : _itr(arr) {
+    MemPointerRecord* cur = (MemPointerRecord*)_itr.current();
+    MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
+    while (next != NULL) {
+      assert(cur != NULL, "Sanity check");
+      assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(),
+        "pre-sort order");
+
+      if (is_duplicated_record(cur, next)) {
+        _itr.next();
+        next = (MemPointerRecord*)_itr.peek_next();
+      } else {
+        break;
+      }
+    }
+  }
+
+  virtual MemPointer* current() const {
+    return _itr.current();
+  }
+
+  // get next record, but skip the duplicated records
+  virtual MemPointer* next() {
+    MemPointerRecord* cur = (MemPointerRecord*)_itr.next();
+    MemPointerRecord* next = (MemPointerRecord*)_itr.peek_next();
+    while (next != NULL) {
+      assert(cur != NULL, "Sanity check");
+      assert(((SeqMemPointerRecord*)next)->seq() > ((SeqMemPointerRecord*)cur)->seq(),
+        "pre-sort order");
+
+      if (is_duplicated_record(cur, next)) {
+        _itr.next();
+        cur = next;
+        next = (MemPointerRecord*)_itr.peek_next();
+      } else {
+        break;
+      }
+    }
+    return cur;
+  }
+
+  MemPointer* peek_next() const      { ShouldNotReachHere(); return NULL; }
+  MemPointer* peek_prev() const      { ShouldNotReachHere(); return NULL; }
+  void remove()                      { ShouldNotReachHere(); }
+  bool insert(MemPointer* ptr)       { ShouldNotReachHere(); return false; }
+  bool insert_after(MemPointer* ptr) { ShouldNotReachHere(); return false; }
+
+ private:
+  bool is_duplicated_record(MemPointerRecord* p1, MemPointerRecord* p2) const {
+    bool ret = (p1->addr() == p2->addr() && p1->size() == p2->size() && p1->flags() == p2->flags());
+    assert(!(ret && FLAGS_TO_MEMORY_TYPE(p1->flags()) == mtThreadStack), "dup on stack record");
+    return ret;
+  }
+};
+
+class StagingArea : public _ValueObj {
+ private:
+  MemPointerArray*   _malloc_data;
+  MemPointerArray*   _vm_data;
+
+ public:
+  StagingArea() : _malloc_data(NULL), _vm_data(NULL) {
+    init();
+  }
+
+  ~StagingArea() {
+    if (_malloc_data != NULL) delete _malloc_data;
+    if (_vm_data != NULL) delete _vm_data;
+  }
+
+  MallocRecordIterator malloc_record_walker() {
+    return MallocRecordIterator(malloc_data());
+  }
+
+  VMRecordIterator virtual_memory_record_walker();
+
+  bool init();
+  void clear() {
+    assert(_malloc_data != NULL && _vm_data != NULL, "Just check");
+    _malloc_data->shrink();
+    _malloc_data->clear();
+    _vm_data->clear();
+  }
+
+  inline MemPointerArray* malloc_data() { return _malloc_data; }
+  inline MemPointerArray* vm_data()     { return _vm_data; }
+};
+
+class MemBaseline;
+class MemSnapshot : public CHeapObj<mtNMT> {
+ private:
+  // the following two arrays contain records of all known lived memory blocks
+  // live malloc-ed memory pointers
+  MemPointerArray*      _alloc_ptrs;
+  // live virtual memory pointers
+  MemPointerArray*      _vm_ptrs;
+
+  StagingArea           _staging_area;
+
+  // the lock to protect this snapshot
+  Monitor*              _lock;
+
+  NOT_PRODUCT(size_t    _untracked_count;)
+  friend class MemBaseline;
+
+ public:
+  MemSnapshot();
+  virtual ~MemSnapshot();
+
+  // if we are running out of native memory
+  bool out_of_memory() {
+    return (_alloc_ptrs == NULL ||
+      _staging_area.malloc_data() == NULL ||
+      _staging_area.vm_data() == NULL ||
+      _vm_ptrs == NULL || _lock == NULL ||
+      _alloc_ptrs->out_of_memory() ||
+      _vm_ptrs->out_of_memory());
+  }
+
+  // merge a per-thread memory recorder into staging area
+  bool merge(MemRecorder* rec);
+  // promote staged data to snapshot
+  bool promote();
+
+
+  void wait(long timeout) {
+    assert(_lock != NULL, "Just check");
+    MonitorLockerEx locker(_lock);
+    locker.wait(true, timeout);
+  }
+
+  NOT_PRODUCT(void print_snapshot_stats(outputStream* st);)
+  NOT_PRODUCT(void check_staging_data();)
+  NOT_PRODUCT(void check_malloc_pointers();)
+  NOT_PRODUCT(bool has_allocation_record(address addr);)
+  // dump all virtual memory pointers in snapshot
+  DEBUG_ONLY( void dump_all_vm_pointers();)
+
+ private:
+   // copy sequenced pointer from src to dest
+   void copy_seq_pointer(MemPointerRecord* dest, const MemPointerRecord* src);
+   // assign a sequenced pointer to non-sequenced pointer
+   void assign_pointer(MemPointerRecord*dest, const MemPointerRecord* src);
+
+   bool promote_malloc_records(MemPointerArrayIterator* itr);
+   bool promote_virtual_memory_records(MemPointerArrayIterator* itr);
+};
+
+#endif // SHARE_VM_SERVICES_MEM_SNAPSHOT_HPP
diff --git a/hotspot/src/share/vm/services/memTrackWorker.cpp b/hotspot/src/share/vm/services/memTrackWorker.cpp
new file mode 100644
index 0000000..9f0577a
--- /dev/null
+++ b/hotspot/src/share/vm/services/memTrackWorker.cpp
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#include "precompiled.hpp"
+#include "runtime/threadCritical.hpp"
+#include "services/memTracker.hpp"
+#include "services/memTrackWorker.hpp"
+#include "utilities/decoder.hpp"
+#include "utilities/vmError.hpp"
+
+MemTrackWorker::MemTrackWorker() {
+  // create thread uses cgc thread type for now. We should revisit
+  // the option, or create new thread type.
+  _has_error = !os::create_thread(this, os::cgc_thread);
+  set_name("MemTrackWorker", 0);
+
+  // initial generation circuit buffer
+  if (!has_error()) {
+    _head = _tail = 0;
+    for(int index = 0; index < MAX_GENERATIONS; index ++) {
+      _gen[index] = NULL;
+    }
+  }
+  NOT_PRODUCT(_sync_point_count = 0;)
+  NOT_PRODUCT(_merge_count = 0;)
+  NOT_PRODUCT(_last_gen_in_use = 0;)
+}
+
+MemTrackWorker::~MemTrackWorker() {
+  for (int index = 0; index < MAX_GENERATIONS; index ++) {
+    MemRecorder* rc = _gen[index];
+    if (rc != NULL) {
+      delete rc;
+    }
+  }
+}
+
+void* MemTrackWorker::operator new(size_t size) {
+  assert(false, "use nothrow version");
+  return NULL;
+}
+
+void* MemTrackWorker::operator new(size_t size, const std::nothrow_t& nothrow_constant) {
+  return allocate(size, false, mtNMT);
+}
+
+void MemTrackWorker::start() {
+  os::start_thread(this);
+}
+
+/*
+ * Native memory tracking worker thread loop:
+ *   1. merge one generation of memory recorders to staging area
+ *   2. promote staging data to memory snapshot
+ *
+ * This thread can run through safepoint.
+ */
+
+void MemTrackWorker::run() {
+  assert(MemTracker::is_on(), "native memory tracking is off");
+  this->initialize_thread_local_storage();
+  this->record_stack_base_and_size();
+  MemSnapshot* snapshot = MemTracker::get_snapshot();
+  assert(snapshot != NULL, "Worker should not be started");
+  MemRecorder* rec;
+
+  while (!MemTracker::shutdown_in_progress()) {
+    NOT_PRODUCT(_last_gen_in_use = generations_in_use();)
+    {
+      // take a recorder from earliest generation in buffer
+      ThreadCritical tc;
+      rec = _gen[_head];
+      if (rec != NULL) {
+        _gen[_head] = rec->next();
+      }
+      assert(count_recorder(_gen[_head]) <= MemRecorder::_instance_count,
+        "infinite loop after dequeue");
+    }
+    if (rec != NULL) {
+      // merge the recorder into staging area
+      if (!snapshot->merge(rec)) {
+        MemTracker::shutdown(MemTracker::NMT_out_of_memory);
+      } else {
+        NOT_PRODUCT(_merge_count ++;)
+      }
+      MemTracker::release_thread_recorder(rec);
+    } else {
+      // no more recorder to merge, promote staging area
+      // to snapshot
+      if (_head != _tail) {
+        {
+          ThreadCritical tc;
+          if (_gen[_head] != NULL || _head == _tail) {
+            continue;
+          }
+          // done with this generation, increment _head pointer
+          _head = (_head + 1) % MAX_GENERATIONS;
+        }
+        // promote this generation data to snapshot
+        if (!snapshot->promote()) {
+          // failed to promote, means out of memory
+          MemTracker::shutdown(MemTracker::NMT_out_of_memory);
+        }
+      } else {
+        snapshot->wait(1000);
+        ThreadCritical tc;
+        // check if more data arrived
+        if (_gen[_head] == NULL) {
+          _gen[_head] = MemTracker::get_pending_recorders();
+        }
+      }
+    }
+  }
+  assert(MemTracker::shutdown_in_progress(), "just check");
+
+  // transits to final shutdown
+  MemTracker::final_shutdown();
+}
+
+// at synchronization point, where 'safepoint visible' Java threads are blocked
+// at a safepoint, and the rest of threads are blocked on ThreadCritical lock.
+// The caller MemTracker::sync() already takes ThreadCritical before calling this
+// method.
+//
+// Following tasks are performed:
+//   1. add all recorders in pending queue to current generation
+//   2. increase generation
+
+void MemTrackWorker::at_sync_point(MemRecorder* rec) {
+  NOT_PRODUCT(_sync_point_count ++;)
+  assert(count_recorder(rec) <= MemRecorder::_instance_count,
+    "pending queue has infinite loop");
+
+  bool out_of_generation_buffer = false;
+  // check shutdown state inside ThreadCritical
+  if (MemTracker::shutdown_in_progress()) return;
+  // append the recorders to the end of the generation
+  if( rec != NULL) {
+    MemRecorder* cur_head = _gen[_tail];
+    if (cur_head == NULL) {
+      _gen[_tail] = rec;
+    } else {
+      while (cur_head->next() != NULL) {
+        cur_head = cur_head->next();
+      }
+      cur_head->set_next(rec);
+    }
+  }
+  assert(count_recorder(rec) <= MemRecorder::_instance_count,
+    "after add to current generation has infinite loop");
+  // we have collected all recorders for this generation. If there is data,
+  // we need to increment _tail to start a new generation.
+  if (_gen[_tail] != NULL || _head == _tail) {
+    _tail = (_tail + 1) % MAX_GENERATIONS;
+    out_of_generation_buffer = (_tail == _head);
+  }
+
+  if (out_of_generation_buffer) {
+    MemTracker::shutdown(MemTracker::NMT_out_of_generation);
+  }
+}
+
+#ifndef PRODUCT
+int MemTrackWorker::count_recorder(const MemRecorder* head) {
+  int count = 0;
+  while(head != NULL) {
+    count ++;
+    head = head->next();
+  }
+  return count;
+}
+
+int MemTrackWorker::count_pending_recorders() const {
+  int count = 0;
+  for (int index = 0; index < MAX_GENERATIONS; index ++) {
+    MemRecorder* head = _gen[index];
+    if (head != NULL) {
+      count += count_recorder(head);
+    }
+  }
+  return count;
+}
+#endif
diff --git a/hotspot/src/share/vm/services/memTrackWorker.hpp b/hotspot/src/share/vm/services/memTrackWorker.hpp
new file mode 100644
index 0000000..969828c
--- /dev/null
+++ b/hotspot/src/share/vm/services/memTrackWorker.hpp
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP
+#define SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/thread.hpp"
+#include "services/memRecorder.hpp"
+
+// Maximum MAX_GENERATIONS generation data can be tracked.
+#define MAX_GENERATIONS  512
+
+
+class MemTrackWorker : public NamedThread {
+ private:
+  // circular buffer. This buffer contains recorders to be merged into global
+  // snaphsot.
+  // Each slot holds a linked list of memory recorders, that contains one
+  // generation of memory data.
+  MemRecorder*  _gen[MAX_GENERATIONS];
+  int           _head, _tail; // head and tail pointers to above circular buffer
+
+  bool          _has_error;
+
+ public:
+  MemTrackWorker();
+  ~MemTrackWorker();
+  _NOINLINE_ void* operator new(size_t size);
+  _NOINLINE_ void* operator new(size_t size, const std::nothrow_t& nothrow_constant);
+
+  void start();
+  void run();
+
+  inline bool has_error() const { return _has_error; }
+
+  // task at synchronization point
+  void at_sync_point(MemRecorder* pending_recorders);
+
+  // for debugging purpose, they are not thread safe.
+  NOT_PRODUCT(static int count_recorder(const MemRecorder* head);)
+  NOT_PRODUCT(int count_pending_recorders() const;)
+
+  NOT_PRODUCT(int _sync_point_count;)
+  NOT_PRODUCT(int _merge_count;)
+  NOT_PRODUCT(int _last_gen_in_use;)
+
+  inline int generations_in_use() const {
+    return (_tail >= _head ? (_tail - _head + 1) : (MAX_GENERATIONS - (_head - _tail) + 1));
+  }
+};
+
+#endif // SHARE_VM_SERVICES_MEM_TRACK_WORKER_HPP
diff --git a/hotspot/src/share/vm/services/memTracker.cpp b/hotspot/src/share/vm/services/memTracker.cpp
new file mode 100644
index 0000000..ebb690a
--- /dev/null
+++ b/hotspot/src/share/vm/services/memTracker.cpp
@@ -0,0 +1,631 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+#include "precompiled.hpp"
+
+#include "runtime/atomic.hpp"
+#include "runtime/interfaceSupport.hpp"
+#include "runtime/mutexLocker.hpp"
+#include "runtime/safepoint.hpp"
+#include "runtime/threadCritical.hpp"
+#include "services/memPtr.hpp"
+#include "services/memReporter.hpp"
+#include "services/memTracker.hpp"
+#include "utilities/decoder.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+bool NMT_track_callsite = false;
+
+// walk all 'known' threads at NMT sync point, and collect their recorders
+void SyncThreadRecorderClosure::do_thread(Thread* thread) {
+  assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
+  if (thread->is_Java_thread()) {
+    JavaThread* javaThread = (JavaThread*)thread;
+    MemRecorder* recorder = javaThread->get_recorder();
+    if (recorder != NULL) {
+      MemTracker::enqueue_pending_recorder(recorder);
+      javaThread->set_recorder(NULL);
+    }
+  }
+  _thread_count ++;
+}
+
+
+MemRecorder*                    MemTracker::_global_recorder = NULL;
+MemSnapshot*                    MemTracker::_snapshot = NULL;
+MemBaseline                     MemTracker::_baseline;
+Mutex*                          MemTracker::_query_lock = NULL;
+volatile MemRecorder*           MemTracker::_merge_pending_queue = NULL;
+volatile MemRecorder*           MemTracker::_pooled_recorders = NULL;
+MemTrackWorker*                 MemTracker::_worker_thread = NULL;
+int                             MemTracker::_sync_point_skip_count = 0;
+MemTracker::NMTLevel            MemTracker::_tracking_level = MemTracker::NMT_off;
+volatile MemTracker::NMTStates  MemTracker::_state = NMT_uninited;
+MemTracker::ShutdownReason      MemTracker::_reason = NMT_shutdown_none;
+int                             MemTracker::_thread_count = 255;
+volatile jint                   MemTracker::_pooled_recorder_count = 0;
+debug_only(intx                 MemTracker::_main_thread_tid = 0;)
+NOT_PRODUCT(volatile jint       MemTracker::_pending_recorder_count = 0;)
+
+void MemTracker::init_tracking_options(const char* option_line) {
+  _tracking_level = NMT_off;
+  if (strcmp(option_line, "=summary") == 0) {
+    _tracking_level = NMT_summary;
+  } else if (strcmp(option_line, "=detail") == 0) {
+    _tracking_level = NMT_detail;
+  } else if (strcmp(option_line, "=off") != 0) {
+    vm_exit_during_initialization("Syntax error, expecting -XX:NativeMemoryTracking=[off|summary|detail]", NULL);
+  }
+}
+
+// first phase of bootstrapping, when VM is still in single-threaded mode.
+void MemTracker::bootstrap_single_thread() {
+  if (_tracking_level > NMT_off) {
+    assert(_state == NMT_uninited, "wrong state");
+
+    // NMT is not supported with UseMallocOnly is on. NMT can NOT
+    // handle the amount of malloc data without significantly impacting
+    // runtime performance when this flag is on.
+    if (UseMallocOnly) {
+      shutdown(NMT_use_malloc_only);
+      return;
+    }
+
+    _query_lock = new (std::nothrow) Mutex(Monitor::max_nonleaf, "NMT_queryLock");
+    if (_query_lock == NULL) {
+      shutdown(NMT_out_of_memory);
+      return;
+    }
+
+    debug_only(_main_thread_tid = os::current_thread_id();)
+    _state = NMT_bootstrapping_single_thread;
+    NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
+  }
+}
+
+// second phase of bootstrapping, when VM is about to or already entered multi-theaded mode.
+void MemTracker::bootstrap_multi_thread() {
+  if (_tracking_level > NMT_off && _state == NMT_bootstrapping_single_thread) {
+  // create nmt lock for multi-thread execution
+    assert(_main_thread_tid == os::current_thread_id(), "wrong thread");
+    _state = NMT_bootstrapping_multi_thread;
+    NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
+  }
+}
+
+// fully start nmt
+void MemTracker::start() {
+  // Native memory tracking is off from command line option
+  if (_tracking_level == NMT_off || shutdown_in_progress()) return;
+
+  assert(_main_thread_tid == os::current_thread_id(), "wrong thread");
+  assert(_state == NMT_bootstrapping_multi_thread, "wrong state");
+
+  _snapshot = new (std::nothrow)MemSnapshot();
+  if (_snapshot != NULL && !_snapshot->out_of_memory()) {
+    if (start_worker()) {
+      _state = NMT_started;
+      NMT_track_callsite = (_tracking_level == NMT_detail && can_walk_stack());
+      return;
+    }
+  }
+
+  // fail to start native memory tracking, shut it down
+  shutdown(NMT_initialization);
+}
+
+/**
+ * Shutting down native memory tracking.
+ * We can not shutdown native memory tracking immediately, so we just
+ * setup shutdown pending flag, every native memory tracking component
+ * should orderly shut itself down.
+ *
+ * The shutdown sequences:
+ *  1. MemTracker::shutdown() sets MemTracker to shutdown pending state
+ *  2. Worker thread calls MemTracker::final_shutdown(), which transites
+ *     MemTracker to final shutdown state.
+ *  3. At sync point, MemTracker does final cleanup, before sets memory
+ *     tracking level to off to complete shutdown.
+ */
+void MemTracker::shutdown(ShutdownReason reason) {
+  if (_tracking_level == NMT_off) return;
+
+  if (_state <= NMT_bootstrapping_single_thread) {
+    // we still in single thread mode, there is not contention
+    _state = NMT_shutdown_pending;
+    _reason = reason;
+  } else {
+    // we want to know who initialized shutdown
+    if ((jint)NMT_started == Atomic::cmpxchg((jint)NMT_shutdown_pending,
+                                       (jint*)&_state, (jint)NMT_started)) {
+        _reason = reason;
+    }
+  }
+}
+
+// final phase of shutdown
+void MemTracker::final_shutdown() {
+  // delete all pending recorders and pooled recorders
+  delete_all_pending_recorders();
+  delete_all_pooled_recorders();
+
+  {
+    // shared baseline and snapshot are the only objects needed to
+    // create query results
+    MutexLockerEx locker(_query_lock, true);
+    // cleanup baseline data and snapshot
+    _baseline.clear();
+    delete _snapshot;
+    _snapshot = NULL;
+  }
+
+  // shutdown shared decoder instance, since it is only
+  // used by native memory tracking so far.
+  Decoder::shutdown();
+
+  MemTrackWorker* worker = NULL;
+  {
+    ThreadCritical tc;
+    // can not delete worker inside the thread critical
+    if (_worker_thread != NULL && Thread::current() == _worker_thread) {
+      worker = _worker_thread;
+      _worker_thread = NULL;
+    }
+  }
+  if (worker != NULL) {
+    delete worker;
+  }
+  _state = NMT_final_shutdown;
+}
+
+// delete all pooled recorders
+void MemTracker::delete_all_pooled_recorders() {
+  // free all pooled recorders
+  volatile MemRecorder* cur_head = _pooled_recorders;
+  if (cur_head != NULL) {
+    MemRecorder* null_ptr = NULL;
+    while (cur_head != NULL && (void*)cur_head != Atomic::cmpxchg_ptr((void*)null_ptr,
+      (void*)&_pooled_recorders, (void*)cur_head)) {
+      cur_head = _pooled_recorders;
+    }
+    if (cur_head != NULL) {
+      delete cur_head;
+      _pooled_recorder_count = 0;
+    }
+  }
+}
+
+// delete all recorders in pending queue
+void MemTracker::delete_all_pending_recorders() {
+  // free all pending recorders
+  MemRecorder* pending_head = get_pending_recorders();
+  if (pending_head != NULL) {
+    delete pending_head;
+  }
+}
+
+/*
+ * retrieve per-thread recorder of specified thread.
+ * if thread == NULL, it means global recorder
+ */
+MemRecorder* MemTracker::get_thread_recorder(JavaThread* thread) {
+  if (shutdown_in_progress()) return NULL;
+
+  MemRecorder* rc;
+  if (thread == NULL) {
+    rc = _global_recorder;
+  } else {
+    rc = thread->get_recorder();
+  }
+
+  if (rc != NULL && rc->is_full()) {
+    enqueue_pending_recorder(rc);
+    rc = NULL;
+  }
+
+  if (rc == NULL) {
+    rc = get_new_or_pooled_instance();
+    if (thread == NULL) {
+      _global_recorder = rc;
+    } else {
+      thread->set_recorder(rc);
+    }
+  }
+  return rc;
+}
+
+/*
+ * get a per-thread recorder from pool, or create a new one if
+ * there is not one available.
+ */
+MemRecorder* MemTracker::get_new_or_pooled_instance() {
+   MemRecorder* cur_head = const_cast<MemRecorder*> (_pooled_recorders);
+   if (cur_head == NULL) {
+     MemRecorder* rec = new (std::nothrow)MemRecorder();
+     if (rec == NULL || rec->out_of_memory()) {
+       shutdown(NMT_out_of_memory);
+       if (rec != NULL) {
+         delete rec;
+         rec = NULL;
+       }
+     }
+     return rec;
+   } else {
+     MemRecorder* next_head = cur_head->next();
+     if ((void*)cur_head != Atomic::cmpxchg_ptr((void*)next_head, (void*)&_pooled_recorders,
+       (void*)cur_head)) {
+       return get_new_or_pooled_instance();
+     }
+     cur_head->set_next(NULL);
+     Atomic::dec(&_pooled_recorder_count);
+     debug_only(cur_head->set_generation();)
+     return cur_head;
+  }
+}
+
+/*
+ * retrieve all recorders in pending queue, and empty the queue
+ */
+MemRecorder* MemTracker::get_pending_recorders() {
+  MemRecorder* cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
+  MemRecorder* null_ptr = NULL;
+  while ((void*)cur_head != Atomic::cmpxchg_ptr((void*)null_ptr, (void*)&_merge_pending_queue,
+    (void*)cur_head)) {
+    cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
+  }
+  NOT_PRODUCT(Atomic::store(0, &_pending_recorder_count));
+  return cur_head;
+}
+
+/*
+ * release a recorder to recorder pool.
+ */
+void MemTracker::release_thread_recorder(MemRecorder* rec) {
+  assert(rec != NULL, "null recorder");
+  // we don't want to pool too many recorders
+  rec->set_next(NULL);
+  if (shutdown_in_progress() || _pooled_recorder_count > _thread_count * 2) {
+    delete rec;
+    return;
+  }
+
+  rec->clear();
+  MemRecorder* cur_head = const_cast<MemRecorder*>(_pooled_recorders);
+  rec->set_next(cur_head);
+  while ((void*)cur_head != Atomic::cmpxchg_ptr((void*)rec, (void*)&_pooled_recorders,
+    (void*)cur_head)) {
+    cur_head = const_cast<MemRecorder*>(_pooled_recorders);
+    rec->set_next(cur_head);
+  }
+  Atomic::inc(&_pooled_recorder_count);
+}
+
+/*
+ * This is the most important method in whole nmt implementation.
+ *
+ * Create a memory record.
+ * 1. When nmt is in single-threaded bootstrapping mode, no lock is needed as VM
+ *    still in single thread mode.
+ * 2. For all threads other than JavaThread, ThreadCritical is needed
+ *    to write to recorders to global recorder.
+ * 3. For JavaThreads that are not longer visible by safepoint, also
+ *    need to take ThreadCritical and records are written to global
+ *    recorders, since these threads are NOT walked by Threads.do_thread().
+ * 4. JavaThreads that are running in native state, have to transition
+ *    to VM state before writing to per-thread recorders.
+ * 5. JavaThreads that are running in VM state do not need any lock and
+ *    records are written to per-thread recorders.
+ * 6. For a thread has yet to attach VM 'Thread', they need to take
+ *    ThreadCritical to write to global recorder.
+ *
+ *    Important note:
+ *    NO LOCK should be taken inside ThreadCritical lock !!!
+ */
+void MemTracker::create_memory_record(address addr, MEMFLAGS flags,
+    size_t size, address pc, Thread* thread) {
+  assert(addr != NULL, "Sanity check");
+  if (!shutdown_in_progress()) {
+    // single thread, we just write records direct to global recorder,'
+    // with any lock
+    if (_state == NMT_bootstrapping_single_thread) {
+      assert(_main_thread_tid == os::current_thread_id(), "wrong thread");
+      thread = NULL;
+    } else {
+      if (thread == NULL) {
+          // don't use Thread::current(), since it is possible that
+          // the calling thread has yet to attach to VM 'Thread',
+          // which will result assertion failure
+          thread = ThreadLocalStorage::thread();
+      }
+    }
+
+    if (thread != NULL) {
+      if (thread->is_Java_thread() && ((JavaThread*)thread)->is_safepoint_visible()) {
+        JavaThread*      java_thread = (JavaThread*)thread;
+        JavaThreadState  state = java_thread->thread_state();
+        if (SafepointSynchronize::safepoint_safe(java_thread, state)) {
+          // JavaThreads that are safepoint safe, can run through safepoint,
+          // so ThreadCritical is needed to ensure no threads at safepoint create
+          // new records while the records are being gathered and the sequence number is changing
+          ThreadCritical tc;
+          create_record_in_recorder(addr, flags, size, pc, java_thread);
+        } else {
+          create_record_in_recorder(addr, flags, size, pc, java_thread);
+        }
+      } else {
+        // other threads, such as worker and watcher threads, etc. need to
+        // take ThreadCritical to write to global recorder
+        ThreadCritical tc;
+        create_record_in_recorder(addr, flags, size, pc, NULL);
+      }
+    } else {
+      if (_state == NMT_bootstrapping_single_thread) {
+        // single thread, no lock needed
+        create_record_in_recorder(addr, flags, size, pc, NULL);
+      } else {
+        // for thread has yet to attach VM 'Thread', we can not use VM mutex.
+        // use native thread critical instead
+        ThreadCritical tc;
+        create_record_in_recorder(addr, flags, size, pc, NULL);
+      }
+    }
+  }
+}
+
+// write a record to proper recorder. No lock can be taken from this method
+// down.
+void MemTracker::create_record_in_recorder(address addr, MEMFLAGS flags,
+    size_t size, address pc, JavaThread* thread) {
+
+    MemRecorder* rc = get_thread_recorder(thread);
+    if (rc != NULL) {
+      rc->record(addr, flags, size, pc);
+    }
+}
+
+/**
+ * enqueue a recorder to pending queue
+ */
+void MemTracker::enqueue_pending_recorder(MemRecorder* rec) {
+  assert(rec != NULL, "null recorder");
+
+  // we are shutting down, so just delete it
+  if (shutdown_in_progress()) {
+    rec->set_next(NULL);
+    delete rec;
+    return;
+  }
+
+  MemRecorder* cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
+  rec->set_next(cur_head);
+  while ((void*)cur_head != Atomic::cmpxchg_ptr((void*)rec, (void*)&_merge_pending_queue,
+    (void*)cur_head)) {
+    cur_head = const_cast<MemRecorder*>(_merge_pending_queue);
+    rec->set_next(cur_head);
+  }
+  NOT_PRODUCT(Atomic::inc(&_pending_recorder_count);)
+}
+
+/*
+ * The method is called at global safepoint
+ * during it synchronization process.
+ *   1. enqueue all JavaThreads' per-thread recorders
+ *   2. enqueue global recorder
+ *   3. retrieve all pending recorders
+ *   4. reset global sequence number generator
+ *   5. call worker's sync
+ */
+#define MAX_SAFEPOINTS_TO_SKIP     128
+#define SAFE_SEQUENCE_THRESHOLD    30
+#define HIGH_GENERATION_THRESHOLD  60
+
+void MemTracker::sync() {
+  assert(_tracking_level > NMT_off, "NMT is not enabled");
+  assert(SafepointSynchronize::is_at_safepoint(), "Safepoint required");
+
+  // Some GC tests hit large number of safepoints in short period of time
+  // without meaningful activities. We should prevent going to
+  // sync point in these cases, which can potentially exhaust generation buffer.
+  // Here is the factots to determine if we should go into sync point:
+  // 1. not to overflow sequence number
+  // 2. if we are in danger to overflow generation buffer
+  // 3. how many safepoints we already skipped sync point
+  if (_state == NMT_started) {
+    // worker thread is not ready, no one can manage generation
+    // buffer, so skip this safepoint
+    if (_worker_thread == NULL) return;
+
+    if (_sync_point_skip_count < MAX_SAFEPOINTS_TO_SKIP) {
+      int per_seq_in_use = SequenceGenerator::peek() * 100 / max_jint;
+      int per_gen_in_use = _worker_thread->generations_in_use() * 100 / MAX_GENERATIONS;
+      if (per_seq_in_use < SAFE_SEQUENCE_THRESHOLD && per_gen_in_use >= HIGH_GENERATION_THRESHOLD) {
+        _sync_point_skip_count ++;
+        return;
+      }
+    }
+    _sync_point_skip_count = 0;
+    {
+      // This method is running at safepoint, with ThreadCritical lock,
+      // it should guarantee that NMT is fully sync-ed.
+      ThreadCritical tc;
+
+      SequenceGenerator::reset();
+
+      // walk all JavaThreads to collect recorders
+      SyncThreadRecorderClosure stc;
+      Threads::threads_do(&stc);
+
+      _thread_count = stc.get_thread_count();
+      MemRecorder* pending_recorders = get_pending_recorders();
+
+      if (_global_recorder != NULL) {
+        _global_recorder->set_next(pending_recorders);
+        pending_recorders = _global_recorder;
+        _global_recorder = NULL;
+      }
+      // check _worker_thread with lock to avoid racing condition
+      if (_worker_thread != NULL) {
+        _worker_thread->at_sync_point(pending_recorders);
+      }
+
+      assert(SequenceGenerator::peek() == 1, "Should not have memory activities during sync-point");
+    }
+  }
+
+  // now, it is the time to shut whole things off
+  if (_state == NMT_final_shutdown) {
+    // walk all JavaThreads to delete all recorders
+    SyncThreadRecorderClosure stc;
+    Threads::threads_do(&stc);
+    // delete global recorder
+    {
+      ThreadCritical tc;
+      if (_global_recorder != NULL) {
+        delete _global_recorder;
+        _global_recorder = NULL;
+      }
+    }
+    MemRecorder* pending_recorders = get_pending_recorders();
+    if (pending_recorders != NULL) {
+      delete pending_recorders;
+    }
+    // try at a later sync point to ensure MemRecorder instance drops to zero to
+    // completely shutdown NMT
+    if (MemRecorder::_instance_count == 0) {
+      _state = NMT_shutdown;
+      _tracking_level = NMT_off;
+    }
+  }
+}
+
+/*
+ * Start worker thread.
+ */
+bool MemTracker::start_worker() {
+  assert(_worker_thread == NULL, "Just Check");
+  _worker_thread = new (std::nothrow) MemTrackWorker();
+  if (_worker_thread == NULL || _worker_thread->has_error()) {
+    shutdown(NMT_initialization);
+    return false;
+  }
+  _worker_thread->start();
+  return true;
+}
+
+/*
+ * We need to collect a JavaThread's per-thread recorder
+ * before it exits.
+ */
+void MemTracker::thread_exiting(JavaThread* thread) {
+  if (is_on()) {
+    MemRecorder* rec = thread->get_recorder();
+    if (rec != NULL) {
+      enqueue_pending_recorder(rec);
+      thread->set_recorder(NULL);
+    }
+  }
+}
+
+// baseline current memory snapshot
+bool MemTracker::baseline() {
+  MutexLockerEx lock(_query_lock, true);
+  MemSnapshot* snapshot = get_snapshot();
+  if (snapshot != NULL) {
+    return _baseline.baseline(*snapshot, false);
+  }
+  return false;
+}
+
+// print memory usage from current snapshot
+bool MemTracker::print_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
+  MemBaseline  baseline;
+  MutexLockerEx lock(_query_lock, true);
+  MemSnapshot* snapshot = get_snapshot();
+  if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
+    BaselineReporter reporter(out, unit);
+    reporter.report_baseline(baseline, summary_only);
+    return true;
+  }
+  return false;
+}
+
+// compare memory usage between current snapshot and baseline
+bool MemTracker::compare_memory_usage(BaselineOutputer& out, size_t unit, bool summary_only) {
+  MutexLockerEx lock(_query_lock, true);
+  if (_baseline.baselined()) {
+    MemBaseline baseline;
+    MemSnapshot* snapshot = get_snapshot();
+    if (snapshot != NULL && baseline.baseline(*snapshot, summary_only)) {
+      BaselineReporter reporter(out, unit);
+      reporter.diff_baselines(baseline, _baseline, summary_only);
+      return true;
+    }
+  }
+  return false;
+}
+
+#ifndef PRODUCT
+void MemTracker::walk_stack(int toSkip, char* buf, int len) {
+  int cur_len = 0;
+  char tmp[1024];
+  address pc;
+
+  while (cur_len < len) {
+    pc = os::get_caller_pc(toSkip + 1);
+    if (pc != NULL && os::dll_address_to_function_name(pc, tmp, sizeof(tmp), NULL)) {
+      jio_snprintf(&buf[cur_len], (len - cur_len), "%s\n", tmp);
+      cur_len = (int)strlen(buf);
+    } else {
+      buf[cur_len] = '\0';
+      break;
+    }
+    toSkip ++;
+  }
+}
+
+void MemTracker::print_tracker_stats(outputStream* st) {
+  st->print_cr("\nMemory Tracker Stats:");
+  st->print_cr("\tMax sequence number = %d", SequenceGenerator::max_seq_num());
+  st->print_cr("\tthead count = %d", _thread_count);
+  st->print_cr("\tArena instance = %d", Arena::_instance_count);
+  st->print_cr("\tpooled recorder count = %d", _pooled_recorder_count);
+  st->print_cr("\tqueued recorder count = %d", _pending_recorder_count);
+  st->print_cr("\tmemory recorder instance count = %d", MemRecorder::_instance_count);
+  if (_worker_thread != NULL) {
+    st->print_cr("\tWorker thread:");
+    st->print_cr("\t\tSync point count = %d", _worker_thread->_sync_point_count);
+    st->print_cr("\t\tpending recorder count = %d", _worker_thread->count_pending_recorders());
+    st->print_cr("\t\tmerge count = %d", _worker_thread->_merge_count);
+  } else {
+    st->print_cr("\tWorker thread is not started");
+  }
+  st->print_cr(" ");
+
+  if (_snapshot != NULL) {
+    _snapshot->print_snapshot_stats(st);
+  } else {
+    st->print_cr("No snapshot");
+  }
+}
+#endif
+
diff --git a/hotspot/src/share/vm/services/memTracker.hpp b/hotspot/src/share/vm/services/memTracker.hpp
new file mode 100644
index 0000000..ff89be3
--- /dev/null
+++ b/hotspot/src/share/vm/services/memTracker.hpp
@@ -0,0 +1,417 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_MEM_TRACKER_HPP
+#define SHARE_VM_SERVICES_MEM_TRACKER_HPP
+
+#include "memory/allocation.hpp"
+#include "runtime/globals.hpp"
+#include "runtime/mutex.hpp"
+#include "runtime/os.hpp"
+#include "runtime/thread.hpp"
+#include "services/memPtr.hpp"
+#include "services/memRecorder.hpp"
+#include "services/memSnapshot.hpp"
+#include "services/memTrackWorker.hpp"
+
+#ifdef SOLARIS
+#include "thread_solaris.inline.hpp"
+#endif
+
+extern bool NMT_track_callsite;
+
+#ifdef ASSERT
+  #define DEBUG_CALLER_PC  (NMT_track_callsite ? os::get_caller_pc(2) : 0)
+#else
+  #define DEBUG_CALLER_PC  0
+#endif
+
+// The thread closure walks threads to collect per-thread
+// memory recorders at NMT sync point
+class SyncThreadRecorderClosure : public ThreadClosure {
+ private:
+  int _thread_count;
+
+ public:
+  SyncThreadRecorderClosure() {
+    _thread_count =0;
+  }
+
+  void do_thread(Thread* thread);
+  int  get_thread_count() const {
+    return _thread_count;
+  }
+};
+
+class BaselineOutputer;
+class MemSnapshot;
+class MemTrackWorker;
+class Thread;
+/*
+ * MemTracker is the 'gate' class to native memory tracking runtime.
+ */
+class MemTracker : AllStatic {
+  friend class MemTrackWorker;
+  friend class MemSnapshot;
+  friend class SyncThreadRecorderClosure;
+
+  // NMT state
+  enum NMTStates {
+    NMT_uninited,                        // not yet initialized
+    NMT_bootstrapping_single_thread,     // bootstrapping, VM is in single thread mode
+    NMT_bootstrapping_multi_thread,      // bootstrapping, VM is about to enter multi-thread mode
+    NMT_started,                         // NMT fully started
+    NMT_shutdown_pending,                // shutdown pending
+    NMT_final_shutdown,                  // in final phase of shutdown
+    NMT_shutdown                         // shutdown
+  };
+
+ public:
+  // native memory tracking level
+  enum NMTLevel {
+    NMT_off,              // native memory tracking is off
+    NMT_summary,          // don't track callsite
+    NMT_detail            // track callsite also
+  };
+
+   enum ShutdownReason {
+     NMT_shutdown_none,     // no shutdown requested
+     NMT_shutdown_user,     // user requested shutdown
+     NMT_normal,            // normal shutdown, process exit
+     NMT_out_of_memory,     // shutdown due to out of memory
+     NMT_initialization,    // shutdown due to initialization failure
+     NMT_use_malloc_only,   // can not combine NMT with UseMallocOnly flag
+     NMT_error_reporting,   // shutdown by vmError::report_and_die()
+     NMT_out_of_generation, // running out of generation queue
+     NMT_sequence_overflow  // overflow the sequence number
+   };
+
+ public:
+  // initialize NMT tracking level from command line options, called
+   // from VM command line parsing code
+  static void init_tracking_options(const char* option_line);
+
+  // if NMT is enabled to record memory activities
+  static inline bool is_on() {
+    return (_tracking_level >= NMT_summary &&
+      _state >= NMT_bootstrapping_single_thread);
+  }
+
+  static inline enum NMTLevel tracking_level() {
+    return _tracking_level;
+  }
+
+  // user readable reason for shutting down NMT
+  static const char* reason() {
+    switch(_reason) {
+      case NMT_shutdown_none:
+        return "Native memory tracking is not enabled";
+      case NMT_shutdown_user:
+        return "Native memory tracking has been shutdown by user";
+      case NMT_normal:
+        return "Native memory tracking has been shutdown due to process exiting";
+      case NMT_out_of_memory:
+        return "Native memory tracking has been shutdown due to out of native memory";
+      case NMT_initialization:
+        return "Native memory tracking failed to initialize";
+      case NMT_error_reporting:
+        return "Native memory tracking has been shutdown due to error reporting";
+      case NMT_out_of_generation:
+        return "Native memory tracking has been shutdown due to running out of generation buffer";
+      case NMT_sequence_overflow:
+        return "Native memory tracking has been shutdown due to overflow the sequence number";
+      case NMT_use_malloc_only:
+        return "Native memory tracking is not supported when UseMallocOnly is on";
+      default:
+        ShouldNotReachHere();
+        return NULL;
+    }
+  }
+
+  // test if we can walk native stack
+  static bool can_walk_stack() {
+  // native stack is not walkable during bootstrapping on sparc
+#if defined(SPARC)
+    return (_state == NMT_started);
+#else
+    return (_state >= NMT_bootstrapping_single_thread && _state  <= NMT_started);
+#endif
+  }
+
+  // if native memory tracking tracks callsite
+  static inline bool track_callsite() { return _tracking_level == NMT_detail; }
+
+  // shutdown native memory tracking capability. Native memory tracking
+  // can be shutdown by VM when it encounters low memory scenarios.
+  // Memory tracker should gracefully shutdown itself, and preserve the
+  // latest memory statistics for post morten diagnosis.
+  static void shutdown(ShutdownReason reason);
+
+  // if there is shutdown requested
+  static inline bool shutdown_in_progress() {
+    return (_state >= NMT_shutdown_pending);
+  }
+
+  // bootstrap native memory tracking, so it can start to collect raw data
+  // before worker thread can start
+
+  // the first phase of bootstrapping, when VM still in single-threaded mode
+  static void bootstrap_single_thread();
+  // the second phase of bootstrapping, VM is about or already in multi-threaded mode
+  static void bootstrap_multi_thread();
+
+
+  // start() has to be called when VM still in single thread mode, but after
+  // command line option parsing is done.
+  static void start();
+
+  // record a 'malloc' call
+  static inline void record_malloc(address addr, size_t size, MEMFLAGS flags,
+                            address pc = 0, Thread* thread = NULL) {
+    if (is_on() && NMT_CAN_TRACK(flags)) {
+      assert(size > 0, "Sanity check");
+      create_memory_record(addr, (flags|MemPointerRecord::malloc_tag()), size, pc, thread);
+    }
+  }
+  // record a 'free' call
+  static inline void record_free(address addr, MEMFLAGS flags, Thread* thread = NULL) {
+    if (is_on() && NMT_CAN_TRACK(flags)) {
+      create_memory_record(addr, MemPointerRecord::free_tag(), 0, 0, thread);
+    }
+  }
+  // record a 'realloc' call
+  static inline void record_realloc(address old_addr, address new_addr, size_t size,
+       MEMFLAGS flags, address pc = 0, Thread* thread = NULL) {
+    if (is_on() && NMT_CAN_TRACK(flags)) {
+      assert(size > 0, "Sanity check");
+      record_free(old_addr, flags, thread);
+      record_malloc(new_addr, size, flags, pc, thread);
+    }
+  }
+
+  // record arena memory size
+  static inline void record_arena_size(address addr, size_t size) {
+    // we add a positive offset to arena address, so we can have arena memory record
+    // sorted after arena record
+    if (is_on() && !UseMallocOnly) {
+      assert(addr != NULL, "Sanity check");
+      create_memory_record((addr + sizeof(void*)), MemPointerRecord::arena_size_tag(), size,
+        DEBUG_CALLER_PC, NULL);
+    }
+  }
+
+  // record a virtual memory 'reserve' call
+  static inline void record_virtual_memory_reserve(address addr, size_t size,
+                            address pc = 0, Thread* thread = NULL) {
+    if (is_on()) {
+      assert(size > 0, "Sanity check");
+      create_memory_record(addr, MemPointerRecord::virtual_memory_reserve_tag(),
+                           size, pc, thread);
+    }
+  }
+
+  static inline void record_thread_stack(address addr, size_t size, Thread* thr,
+                           address pc = 0) {
+    if (is_on()) {
+      assert(size > 0 && thr != NULL, "Sanity check");
+      create_memory_record(addr, MemPointerRecord::virtual_memory_reserve_tag() | mtThreadStack,
+                          size, pc, thr);
+      create_memory_record(addr, MemPointerRecord::virtual_memory_commit_tag() | mtThreadStack,
+                          size, pc, thr);
+    }
+  }
+
+  static inline void release_thread_stack(address addr, size_t size, Thread* thr) {
+    if (is_on()) {
+      assert(size > 0 && thr != NULL, "Sanity check");
+      assert(!thr->is_Java_thread(), "too early");
+      create_memory_record(addr, MemPointerRecord::virtual_memory_uncommit_tag() | mtThreadStack,
+                          size, DEBUG_CALLER_PC, thr);
+      create_memory_record(addr, MemPointerRecord::virtual_memory_release_tag() | mtThreadStack,
+                          size, DEBUG_CALLER_PC, thr);
+    }
+  }
+
+  // record a virtual memory 'commit' call
+  static inline void record_virtual_memory_commit(address addr, size_t size,
+                            address pc, Thread* thread = NULL) {
+    if (is_on()) {
+      assert(size > 0, "Sanity check");
+      create_memory_record(addr, MemPointerRecord::virtual_memory_commit_tag(),
+                           size, pc, thread);
+    }
+  }
+
+  // record a virtual memory 'uncommit' call
+  static inline void record_virtual_memory_uncommit(address addr, size_t size,
+                            Thread* thread = NULL) {
+    if (is_on()) {
+      assert(size > 0, "Sanity check");
+      create_memory_record(addr, MemPointerRecord::virtual_memory_uncommit_tag(),
+                           size, DEBUG_CALLER_PC, thread);
+    }
+  }
+
+  // record a virtual memory 'release' call
+  static inline void record_virtual_memory_release(address addr, size_t size,
+                            Thread* thread = NULL) {
+    if (is_on()) {
+      assert(size > 0, "Sanity check");
+      create_memory_record(addr, MemPointerRecord::virtual_memory_release_tag(),
+                           size, DEBUG_CALLER_PC, thread);
+    }
+  }
+
+  // record memory type on virtual memory base address
+  static inline void record_virtual_memory_type(address base, MEMFLAGS flags,
+                            Thread* thread = NULL) {
+    if (is_on()) {
+      assert(base > 0, "wrong base address");
+      assert((flags & (~mt_masks)) == 0, "memory type only");
+      create_memory_record(base, (flags | MemPointerRecord::virtual_memory_type_tag()),
+                           0, DEBUG_CALLER_PC, thread);
+    }
+  }
+
+
+  // create memory baseline of current memory snapshot
+  static bool baseline();
+  // is there a memory baseline
+  static bool has_baseline() {
+    return _baseline.baselined();
+  }
+
+  // print memory usage from current snapshot
+  static bool print_memory_usage(BaselineOutputer& out, size_t unit,
+           bool summary_only = true);
+  // compare memory usage between current snapshot and baseline
+  static bool compare_memory_usage(BaselineOutputer& out, size_t unit,
+           bool summary_only = true);
+
+  // sync is called within global safepoint to synchronize nmt data
+  static void sync();
+
+  // called when a thread is about to exit
+  static void thread_exiting(JavaThread* thread);
+
+  // retrieve global snapshot
+  static MemSnapshot* get_snapshot() {
+    if (shutdown_in_progress()) {
+      return NULL;
+    }
+    return _snapshot;
+  }
+
+  // print tracker stats
+  NOT_PRODUCT(static void print_tracker_stats(outputStream* st);)
+  NOT_PRODUCT(static void walk_stack(int toSkip, char* buf, int len);)
+
+ private:
+  // start native memory tracking worker thread
+  static bool start_worker();
+
+  // called by worker thread to complete shutdown process
+  static void final_shutdown();
+
+ protected:
+  // retrieve per-thread recorder of the specified thread.
+  // if the recorder is full, it will be enqueued to overflow
+  // queue, a new recorder is acquired from recorder pool or a
+  // new instance is created.
+  // when thread == NULL, it means global recorder
+  static MemRecorder* get_thread_recorder(JavaThread* thread);
+
+  // per-thread recorder pool
+  static void release_thread_recorder(MemRecorder* rec);
+  static void delete_all_pooled_recorders();
+
+  // pending recorder queue. Recorders are queued to pending queue
+  // when they are overflowed or collected at nmt sync point.
+  static void enqueue_pending_recorder(MemRecorder* rec);
+  static MemRecorder* get_pending_recorders();
+  static void delete_all_pending_recorders();
+
+ private:
+  // retrieve a pooled memory record or create new one if there is not
+  // one available
+  static MemRecorder* get_new_or_pooled_instance();
+  static void create_memory_record(address addr, MEMFLAGS type,
+                   size_t size, address pc, Thread* thread);
+  static void create_record_in_recorder(address addr, MEMFLAGS type,
+                   size_t size, address pc, JavaThread* thread);
+
+ private:
+  // global memory snapshot
+  static MemSnapshot*     _snapshot;
+
+  // a memory baseline of snapshot
+  static MemBaseline      _baseline;
+
+  // query lock
+  static Mutex*           _query_lock;
+
+  // a thread can start to allocate memory before it is attached
+  // to VM 'Thread', those memory activities are recorded here.
+  // ThreadCritical is required to guard this global recorder.
+  static MemRecorder*     _global_recorder;
+
+  // main thread id
+  debug_only(static intx   _main_thread_tid;)
+
+  // pending recorders to be merged
+  static volatile MemRecorder*      _merge_pending_queue;
+
+  NOT_PRODUCT(static volatile jint   _pending_recorder_count;)
+
+  // pooled memory recorders
+  static volatile MemRecorder*      _pooled_recorders;
+
+  // memory recorder pool management, uses following
+  // counter to determine if a released memory recorder
+  // should be pooled
+
+  // latest thread count
+  static int               _thread_count;
+  // pooled recorder count
+  static volatile jint     _pooled_recorder_count;
+
+
+  // worker thread to merge pending recorders into snapshot
+  static MemTrackWorker*  _worker_thread;
+
+  // how many safepoints we skipped without entering sync point
+  static int              _sync_point_skip_count;
+
+  // if the tracker is properly intialized
+  static bool             _is_tracker_ready;
+  // tracking level (off, summary and detail)
+  static enum NMTLevel    _tracking_level;
+
+  // current nmt state
+  static volatile enum NMTStates   _state;
+  // the reason for shutting down nmt
+  static enum ShutdownReason       _reason;
+};
+
+#endif // SHARE_VM_SERVICES_MEM_TRACKER_HPP
diff --git a/hotspot/src/share/vm/services/memoryManager.cpp b/hotspot/src/share/vm/services/memoryManager.cpp
index 0666223..8852f9f 100644
--- a/hotspot/src/share/vm/services/memoryManager.cpp
+++ b/hotspot/src/share/vm/services/memoryManager.cpp
@@ -166,15 +166,15 @@
 
 GCStatInfo::GCStatInfo(int num_pools) {
   // initialize the arrays for memory usage
-  _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
-  _after_gc_usage_array  = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools);
+  _before_gc_usage_array = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools, mtInternal);
+  _after_gc_usage_array  = (MemoryUsage*) NEW_C_HEAP_ARRAY(MemoryUsage, num_pools, mtInternal);
   _usage_array_size = num_pools;
   clear();
 }
 
 GCStatInfo::~GCStatInfo() {
-  FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array);
-  FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array);
+  FREE_C_HEAP_ARRAY(MemoryUsage*, _before_gc_usage_array, mtInternal);
+  FREE_C_HEAP_ARRAY(MemoryUsage*, _after_gc_usage_array, mtInternal);
 }
 
 void GCStatInfo::set_gc_usage(int pool_index, MemoryUsage usage, bool before_gc) {
@@ -214,8 +214,8 @@
 
 void GCMemoryManager::initialize_gc_stat_info() {
   assert(MemoryService::num_memory_pools() > 0, "should have one or more memory pools");
-  _last_gc_stat = new(ResourceObj::C_HEAP) GCStatInfo(MemoryService::num_memory_pools());
-  _current_gc_stat = new(ResourceObj::C_HEAP) GCStatInfo(MemoryService::num_memory_pools());
+  _last_gc_stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(MemoryService::num_memory_pools());
+  _current_gc_stat = new(ResourceObj::C_HEAP, mtGC) GCStatInfo(MemoryService::num_memory_pools());
   // tracking concurrent collections we need two objects: one to update, and one to
   // hold the publicly available "last (completed) gc" information.
 }
diff --git a/hotspot/src/share/vm/services/memoryManager.hpp b/hotspot/src/share/vm/services/memoryManager.hpp
index eb0d969..bb6a811 100644
--- a/hotspot/src/share/vm/services/memoryManager.hpp
+++ b/hotspot/src/share/vm/services/memoryManager.hpp
@@ -40,7 +40,7 @@
 class GCMemoryManager;
 class OopClosure;
 
-class MemoryManager : public CHeapObj {
+class MemoryManager : public CHeapObj<mtInternal> {
 private:
   enum {
     max_num_pools = 10
diff --git a/hotspot/src/share/vm/services/memoryPool.hpp b/hotspot/src/share/vm/services/memoryPool.hpp
index 441df25..db560db 100644
--- a/hotspot/src/share/vm/services/memoryPool.hpp
+++ b/hotspot/src/share/vm/services/memoryPool.hpp
@@ -50,7 +50,7 @@
 class PermGen;
 class ThresholdSupport;
 
-class MemoryPool : public CHeapObj {
+class MemoryPool : public CHeapObj<mtInternal> {
   friend class MemoryManager;
  public:
   enum PoolType {
diff --git a/hotspot/src/share/vm/services/memoryService.cpp b/hotspot/src/share/vm/services/memoryService.cpp
index d1bb9c2..621cb7a 100644
--- a/hotspot/src/share/vm/services/memoryService.cpp
+++ b/hotspot/src/share/vm/services/memoryService.cpp
@@ -58,9 +58,9 @@
 #endif
 
 GrowableArray<MemoryPool*>* MemoryService::_pools_list =
-  new (ResourceObj::C_HEAP) GrowableArray<MemoryPool*>(init_pools_list_size, true);
+  new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryPool*>(init_pools_list_size, true);
 GrowableArray<MemoryManager*>* MemoryService::_managers_list =
-  new (ResourceObj::C_HEAP) GrowableArray<MemoryManager*>(init_managers_list_size, true);
+  new (ResourceObj::C_HEAP, mtInternal) GrowableArray<MemoryManager*>(init_managers_list_size, true);
 
 GCMemoryManager* MemoryService::_minor_gc_manager = NULL;
 GCMemoryManager* MemoryService::_major_gc_manager = NULL;
diff --git a/hotspot/src/share/vm/services/nmtDCmd.cpp b/hotspot/src/share/vm/services/nmtDCmd.cpp
new file mode 100644
index 0000000..83b7d7e
--- /dev/null
+++ b/hotspot/src/share/vm/services/nmtDCmd.cpp
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+#include "precompiled.hpp"
+#include "services/nmtDCmd.hpp"
+#include "services/memReporter.hpp"
+#include "services/memTracker.hpp"
+#include "utilities/globalDefinitions.hpp"
+
+NMTDCmd::NMTDCmd(outputStream* output,
+  bool heap): DCmdWithParser(output, heap),
+  _summary("summary", "request runtime to report current memory summary, " \
+           "which includes total reserved and committed memory, along " \
+           "with memory usage summary by each subsytem.",
+           "BOOLEAN", false, "false"),
+  _detail("detail", "request runtime to report memory allocation >= "
+           "1K by each callsite.",
+           "BOOLEAN", false, "false"),
+  _baseline("baseline", "request runtime to baseline current memory usage, " \
+            "so it can be compared against in later time.",
+            "BOOLEAN", false, "false"),
+  _summary_diff("summary.diff", "request runtime to report memory summary " \
+            "comparison against previous baseline.",
+            "BOOLEAN", false, "false"),
+  _detail_diff("detail.diff", "request runtime to report memory detail " \
+            "comparison against previous baseline, which shows the memory " \
+            "allocation activities at different callsites.",
+            "BOOLEAN", false, "false"),
+  _shutdown("shutdown", "request runtime to shutdown itself and free the " \
+            "memory used by runtime.",
+            "BOOLEAN", false, "false"),
+#ifndef PRODUCT
+  _debug("debug", "print tracker statistics. Debug only, not thread safe", \
+            "BOOLEAN", false, "false"),
+#endif
+  _scale("scale", "Memory usage in which scale, KB, MB or GB",
+       "STRING", false, "KB") {
+  _dcmdparser.add_dcmd_option(&_summary);
+  _dcmdparser.add_dcmd_option(&_detail);
+  _dcmdparser.add_dcmd_option(&_baseline);
+  _dcmdparser.add_dcmd_option(&_summary_diff);
+  _dcmdparser.add_dcmd_option(&_detail_diff);
+  _dcmdparser.add_dcmd_option(&_shutdown);
+#ifndef PRODUCT
+  _dcmdparser.add_dcmd_option(&_debug);
+#endif
+  _dcmdparser.add_dcmd_option(&_scale);
+}
+
+void NMTDCmd::execute(TRAPS) {
+  const char* scale_value = _scale.value();
+  size_t scale_unit;
+  if (strcmp(scale_value, "KB") == 0 || strcmp(scale_value, "kb") == 0) {
+    scale_unit = K;
+  } else if (strcmp(scale_value, "MB") == 0 ||
+             strcmp(scale_value, "mb") == 0) {
+    scale_unit = M;
+  } else if (strcmp(scale_value, "GB") == 0 ||
+             strcmp(scale_value, "gb") == 0) {
+    scale_unit = G;
+  } else {
+    output()->print_cr("Incorrect scale value: %s", scale_value);
+    return;
+  }
+
+  int nopt = 0;
+  if(_summary.is_set() && _summary.value()) { ++nopt; }
+  if(_detail.is_set() && _detail.value()) { ++nopt; }
+  if(_baseline.is_set() && _baseline.value()) { ++nopt; }
+  if(_summary_diff.is_set() && _summary_diff.value()) { ++nopt; }
+  if(_detail_diff.is_set() && _detail_diff.value()) { ++nopt; }
+  if(_shutdown.is_set() && _shutdown.value()) { ++nopt; }
+#ifndef PRODUCT
+  if(_debug.is_set() && _debug.value()) { ++nopt; }
+#endif
+
+  if(nopt > 1) {
+      output()->print_cr("At most one of the following option can be specified: " \
+        "summary, detail, baseline, summary.diff, detail.diff, shutdown"
+#ifndef PRODUCT
+        ", debug"
+#endif
+      );
+      return;
+  } else if (nopt == 0) {
+    if (_summary.is_set()) {
+      output()->print_cr("No command to execute");
+      return;
+    } else {
+      _summary.set_value(true);
+    }
+  }
+
+#ifndef PRODUCT
+  if (_debug.value()) {
+    output()->print_cr("debug command is NOT thread-safe, may cause crash");
+    MemTracker::print_tracker_stats(output());
+    return;
+  }
+#endif
+
+  // native memory tracking has to be on
+  if (!MemTracker::is_on() || MemTracker::shutdown_in_progress()) {
+    // if it is not on, what's the reason?
+    output()->print_cr(MemTracker::reason());
+    return;
+  }
+
+  if (_summary.value()) {
+    BaselineTTYOutputer outputer(output());
+    MemTracker::print_memory_usage(outputer, scale_unit, true);
+  } else if (_detail.value()) {
+    BaselineTTYOutputer outputer(output());
+    MemTracker::print_memory_usage(outputer, scale_unit, false);
+  } else if (_baseline.value()) {
+    if (MemTracker::baseline()) {
+      output()->print_cr("Successfully baselined.");
+    } else {
+      output()->print_cr("Baseline failed.");
+    }
+  } else if (_summary_diff.value()) {
+    if (MemTracker::has_baseline()) {
+      BaselineTTYOutputer outputer(output());
+      MemTracker::compare_memory_usage(outputer, scale_unit, true);
+    } else {
+      output()->print_cr("No baseline to compare, run 'baseline' command first");
+    }
+  } else if (_detail_diff.value()) {
+    if (MemTracker::has_baseline()) {
+      BaselineTTYOutputer outputer(output());
+      MemTracker::compare_memory_usage(outputer, scale_unit, false);
+    } else {
+      output()->print_cr("No baseline to compare to, run 'baseline' command first");
+    }
+  } else if (_shutdown.value()) {
+    MemTracker::shutdown(MemTracker::NMT_shutdown_user);
+    output()->print_cr("Shutdown is in progress, it will take a few moments to " \
+      "completely shutdown");
+  } else {
+    ShouldNotReachHere();
+    output()->print_cr("Unknown command");
+  }
+}
+
+int NMTDCmd::num_arguments() {
+  ResourceMark rm;
+  NMTDCmd* dcmd = new NMTDCmd(NULL, false);
+  if (dcmd != NULL) {
+    DCmdMark mark(dcmd);
+    return dcmd->_dcmdparser.num_arguments();
+  } else {
+    return 0;
+  }
+}
+
diff --git a/hotspot/src/share/vm/services/nmtDCmd.hpp b/hotspot/src/share/vm/services/nmtDCmd.hpp
new file mode 100644
index 0000000..0c8c865
--- /dev/null
+++ b/hotspot/src/share/vm/services/nmtDCmd.hpp
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+#ifndef SHARE_VM_SERVICES_NMT_DCMD_HPP
+#define SHARE_VM_SERVICES_NMT_DCMD_HPP
+
+#include "services/diagnosticArgument.hpp"
+#include "services/diagnosticFramework.hpp"
+
+/**
+ * Native memory tracking DCmd implementation
+ */
+class NMTDCmd: public DCmdWithParser {
+ protected:
+  DCmdArgument<bool>  _summary;
+  DCmdArgument<bool>  _detail;
+  DCmdArgument<bool>  _baseline;
+  DCmdArgument<bool>  _summary_diff;
+  DCmdArgument<bool>  _detail_diff;
+  DCmdArgument<bool>  _shutdown;
+#ifndef PRODUCT
+  DCmdArgument<bool>  _debug;
+#endif
+  DCmdArgument<char*> _scale;
+
+ public:
+  NMTDCmd(outputStream* output, bool heap);
+  static const char* name() { return "VM.native_memory"; }
+  static const char* description() {
+    return "Print native memory usage";
+  }
+  static const char* impact() {
+    return "Medium:";
+  }
+  static int num_arguments();
+  virtual void execute(TRAPS);
+};
+
+#endif // SHARE_VM_SERVICES_NMT_DCMD_HPP
diff --git a/hotspot/src/share/vm/services/threadService.cpp b/hotspot/src/share/vm/services/threadService.cpp
index 5c70fe9..325c236 100644
--- a/hotspot/src/share/vm/services/threadService.cpp
+++ b/hotspot/src/share/vm/services/threadService.cpp
@@ -437,7 +437,7 @@
     GrowableArray<MonitorInfo*>* list = jvf->locked_monitors();
     int length = list->length();
     if (length > 0) {
-      _locked_monitors = new (ResourceObj::C_HEAP) GrowableArray<oop>(length, true);
+      _locked_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(length, true);
       for (int i = 0; i < length; i++) {
         MonitorInfo* monitor = list->at(i);
         assert(monitor->owner(), "This monitor must have an owning object");
@@ -491,11 +491,11 @@
 
 ThreadStackTrace::ThreadStackTrace(JavaThread* t, bool with_locked_monitors) {
   _thread = t;
-  _frames = new (ResourceObj::C_HEAP) GrowableArray<StackFrameInfo*>(INITIAL_ARRAY_SIZE, true);
+  _frames = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<StackFrameInfo*>(INITIAL_ARRAY_SIZE, true);
   _depth = 0;
   _with_locked_monitors = with_locked_monitors;
   if (_with_locked_monitors) {
-    _jni_locked_monitors = new (ResourceObj::C_HEAP) GrowableArray<oop>(INITIAL_ARRAY_SIZE, true);
+    _jni_locked_monitors = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<oop>(INITIAL_ARRAY_SIZE, true);
   } else {
     _jni_locked_monitors = NULL;
   }
@@ -689,7 +689,7 @@
 
 ThreadConcurrentLocks::ThreadConcurrentLocks(JavaThread* thread) {
   _thread = thread;
-  _owned_locks = new (ResourceObj::C_HEAP) GrowableArray<instanceOop>(INITIAL_ARRAY_SIZE, true);
+  _owned_locks = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<instanceOop>(INITIAL_ARRAY_SIZE, true);
   _next = NULL;
 }
 
@@ -803,7 +803,7 @@
 
 DeadlockCycle::DeadlockCycle() {
   _is_deadlock = false;
-  _threads = new (ResourceObj::C_HEAP) GrowableArray<JavaThread*>(INITIAL_ARRAY_SIZE, true);
+  _threads = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<JavaThread*>(INITIAL_ARRAY_SIZE, true);
   _next = NULL;
 }
 
diff --git a/hotspot/src/share/vm/services/threadService.hpp b/hotspot/src/share/vm/services/threadService.hpp
index bd1395a..9f91edf 100644
--- a/hotspot/src/share/vm/services/threadService.hpp
+++ b/hotspot/src/share/vm/services/threadService.hpp
@@ -116,7 +116,7 @@
 };
 
 // Per-thread Statistics for synchronization
-class ThreadStatistics : public CHeapObj {
+class ThreadStatistics : public CHeapObj<mtInternal> {
 private:
   // The following contention statistics are only updated by
   // the thread owning these statistics when contention occurs.
@@ -186,7 +186,7 @@
 };
 
 // Thread snapshot to represent the thread state and statistics
-class ThreadSnapshot : public CHeapObj {
+class ThreadSnapshot : public CHeapObj<mtInternal> {
 private:
   JavaThread* _thread;
   oop         _threadObj;
@@ -244,7 +244,7 @@
   void        oops_do(OopClosure* f);
 };
 
-class ThreadStackTrace : public CHeapObj {
+class ThreadStackTrace : public CHeapObj<mtInternal> {
  private:
   JavaThread*                     _thread;
   int                             _depth;  // number of stack frames added
@@ -275,7 +275,7 @@
 // StackFrameInfo for keeping methodOop and bci during
 // stack walking for later construction of StackTraceElement[]
 // Java instances
-class StackFrameInfo : public CHeapObj {
+class StackFrameInfo : public CHeapObj<mtInternal> {
  private:
   methodOop           _method;
   int                 _bci;
@@ -299,7 +299,7 @@
   void      print_on(outputStream* st) const;
 };
 
-class ThreadConcurrentLocks : public CHeapObj {
+class ThreadConcurrentLocks : public CHeapObj<mtInternal> {
 private:
   GrowableArray<instanceOop>* _owned_locks;
   ThreadConcurrentLocks*      _next;
@@ -356,7 +356,7 @@
   void                 oops_do(OopClosure* f);
 };
 
-class DeadlockCycle : public CHeapObj {
+class DeadlockCycle : public CHeapObj<mtInternal> {
  private:
   bool _is_deadlock;
   GrowableArray<JavaThread*>* _threads;
diff --git a/hotspot/src/share/vm/trace/traceMacros.hpp b/hotspot/src/share/vm/trace/traceMacros.hpp
index 221f4d0..4410319 100644
--- a/hotspot/src/share/vm/trace/traceMacros.hpp
+++ b/hotspot/src/share/vm/trace/traceMacros.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -43,5 +43,9 @@
 #define TRACE_SET_KLASS_TRACE_ID(x1, x2) do { } while (0)
 #define TRACE_DEFINE_KLASS_METHODS typedef int ___IGNORED_hs_trace_type1
 #define TRACE_DEFINE_KLASS_TRACE_ID typedef int ___IGNORED_hs_trace_type2
+#define TRACE_DEFINE_OFFSET typedef int ___IGNORED_hs_trace_type3
+#define TRACE_ID_OFFSET in_ByteSize(0); ShouldNotReachHere()
+#define TRACE_TEMPLATES(template)
+#define TRACE_INTRINSICS(do_intrinsic, do_class, do_name, do_signature, do_alias)
 
 #endif
diff --git a/hotspot/src/share/vm/utilities/accessFlags.hpp b/hotspot/src/share/vm/utilities/accessFlags.hpp
index 484ce4f..ef1df6d 100644
--- a/hotspot/src/share/vm/utilities/accessFlags.hpp
+++ b/hotspot/src/share/vm/utilities/accessFlags.hpp
@@ -47,7 +47,7 @@
   JVM_ACC_QUEUED                  = 0x01000000,     // Queued for compilation
   JVM_ACC_NOT_C2_COMPILABLE       = 0x02000000,
   JVM_ACC_NOT_C1_COMPILABLE       = 0x04000000,
-  JVM_ACC_NOT_OSR_COMPILABLE      = 0x08000000,
+  JVM_ACC_NOT_C2_OSR_COMPILABLE   = 0x08000000,
   JVM_ACC_HAS_LINE_NUMBER_TABLE   = 0x00100000,
   JVM_ACC_HAS_CHECKED_EXCEPTIONS  = 0x00400000,
   JVM_ACC_HAS_JSRS                = 0x00800000,
@@ -55,9 +55,6 @@
   JVM_ACC_IS_OBSOLETE             = 0x00020000,     // RedefineClasses() has made method obsolete
   JVM_ACC_IS_PREFIXED_NATIVE      = 0x00040000,     // JVMTI has prefixed this native method
 
-  JVM_MH_INVOKE_BITS           // = 0x10001100      // MethodHandle.invoke quasi-native
-                                  = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_MONITOR_MATCH),
-
   // klassOop flags
   JVM_ACC_HAS_MIRANDA_METHODS     = 0x10000000,     // True if this class has miranda methods in it's vtable
   JVM_ACC_HAS_VANILLA_CONSTRUCTOR = 0x20000000,     // True if klass has a vanilla default constructor
@@ -80,10 +77,12 @@
   JVM_ACC_FIELD_ACCESS_WATCHED       = 0x00002000,  // field access is watched by JVMTI
   JVM_ACC_FIELD_MODIFICATION_WATCHED = 0x00008000,  // field modification is watched by JVMTI
   JVM_ACC_FIELD_INTERNAL             = 0x00000400,  // internal field, same as JVM_ACC_ABSTRACT
+  JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE = 0x00000800, // field has generic signature
 
   JVM_ACC_FIELD_INTERNAL_FLAGS       = JVM_ACC_FIELD_ACCESS_WATCHED |
                                        JVM_ACC_FIELD_MODIFICATION_WATCHED |
-                                       JVM_ACC_FIELD_INTERNAL,
+                                       JVM_ACC_FIELD_INTERNAL |
+                                       JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE,
 
                                                     // flags accepted by set_field_flags()
   JVM_ACC_FIELD_FLAGS                = JVM_RECOGNIZED_FIELD_MODIFIERS | JVM_ACC_FIELD_INTERNAL_FLAGS
@@ -121,9 +120,9 @@
   bool has_loops               () const { return (_flags & JVM_ACC_HAS_LOOPS              ) != 0; }
   bool loops_flag_init         () const { return (_flags & JVM_ACC_LOOPS_FLAG_INIT        ) != 0; }
   bool queued_for_compilation  () const { return (_flags & JVM_ACC_QUEUED                 ) != 0; }
-  bool is_not_c1_compilable () const    { return (_flags & JVM_ACC_NOT_C1_COMPILABLE      ) != 0; }
-  bool is_not_c2_compilable () const    { return (_flags & JVM_ACC_NOT_C2_COMPILABLE      ) != 0; }
-  bool is_not_osr_compilable   () const { return (_flags & JVM_ACC_NOT_OSR_COMPILABLE     ) != 0; }
+  bool is_not_c1_compilable    () const { return (_flags & JVM_ACC_NOT_C1_COMPILABLE      ) != 0; }
+  bool is_not_c2_compilable    () const { return (_flags & JVM_ACC_NOT_C2_COMPILABLE      ) != 0; }
+  bool is_not_c2_osr_compilable() const { return (_flags & JVM_ACC_NOT_C2_OSR_COMPILABLE  ) != 0; }
   bool has_linenumber_table    () const { return (_flags & JVM_ACC_HAS_LINE_NUMBER_TABLE  ) != 0; }
   bool has_checked_exceptions  () const { return (_flags & JVM_ACC_HAS_CHECKED_EXCEPTIONS ) != 0; }
   bool has_jsrs                () const { return (_flags & JVM_ACC_HAS_JSRS               ) != 0; }
@@ -131,15 +130,6 @@
   bool is_obsolete             () const { return (_flags & JVM_ACC_IS_OBSOLETE            ) != 0; }
   bool is_prefixed_native      () const { return (_flags & JVM_ACC_IS_PREFIXED_NATIVE     ) != 0; }
 
-  // JSR 292:  A method of the form MethodHandle.invoke(A...)R method is
-  // neither bytecoded nor a JNI native, but rather a fast call through
-  // a lightweight method handle object.  Because it is not bytecoded,
-  // it has the native bit set, but the monitor-match bit is also set
-  // to distinguish it from a JNI native (which never has the match bit set).
-  // The synthetic bit is also present, because such a method is never
-  // explicitly defined in Java code.
-  bool is_method_handle_invoke () const { return (_flags & JVM_MH_INVOKE_BITS) == JVM_MH_INVOKE_BITS; }
-
   // klassOop flags
   bool has_miranda_methods     () const { return (_flags & JVM_ACC_HAS_MIRANDA_METHODS    ) != 0; }
   bool has_vanilla_constructor () const { return (_flags & JVM_ACC_HAS_VANILLA_CONSTRUCTOR) != 0; }
@@ -156,6 +146,8 @@
   bool is_field_modification_watched() const
                                         { return (_flags & JVM_ACC_FIELD_MODIFICATION_WATCHED) != 0; }
   bool is_internal() const              { return (_flags & JVM_ACC_FIELD_INTERNAL) != 0; }
+  bool field_has_generic_signature() const
+                                        { return (_flags & JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE) != 0; }
 
   // get .class file flags
   jint get_flags               () const { return (_flags & JVM_ACC_WRITTEN_FLAGS); }
@@ -192,7 +184,7 @@
   void set_loops_flag_init()           { atomic_set_bits(JVM_ACC_LOOPS_FLAG_INIT);         }
   void set_not_c1_compilable()         { atomic_set_bits(JVM_ACC_NOT_C1_COMPILABLE);       }
   void set_not_c2_compilable()         { atomic_set_bits(JVM_ACC_NOT_C2_COMPILABLE);       }
-  void set_not_osr_compilable()        { atomic_set_bits(JVM_ACC_NOT_OSR_COMPILABLE);      }
+  void set_not_c2_osr_compilable()     { atomic_set_bits(JVM_ACC_NOT_C2_OSR_COMPILABLE);   }
   void set_has_linenumber_table()      { atomic_set_bits(JVM_ACC_HAS_LINE_NUMBER_TABLE);   }
   void set_has_checked_exceptions()    { atomic_set_bits(JVM_ACC_HAS_CHECKED_EXCEPTIONS);  }
   void set_has_jsrs()                  { atomic_set_bits(JVM_ACC_HAS_JSRS);                }
@@ -225,6 +217,10 @@
                                            atomic_clear_bits(JVM_ACC_FIELD_MODIFICATION_WATCHED);
                                          }
                                        }
+  void set_field_has_generic_signature()
+                                       {
+                                         atomic_set_bits(JVM_ACC_FIELD_HAS_GENERIC_SIGNATURE);
+                                       }
 
   // Conversion
   jshort as_short() const              { return (jshort)_flags; }
diff --git a/hotspot/src/share/vm/utilities/array.cpp b/hotspot/src/share/vm/utilities/array.cpp
index 44782ea..b1c7a61 100644
--- a/hotspot/src/share/vm/utilities/array.cpp
+++ b/hotspot/src/share/vm/utilities/array.cpp
@@ -49,7 +49,7 @@
 void ResourceArray::sort(size_t esize, ftype f) {
   if (!is_empty()) qsort(_data, length(), esize, f);
 }
-void CHeapArray::sort(size_t esize, ftype f) {
+template <MEMFLAGS F> void CHeapArray<F>::sort(size_t esize, ftype f) {
   if (!is_empty()) qsort(_data, length(), esize, f);
 }
 
@@ -70,14 +70,14 @@
 }
 
 
-void CHeapArray::expand(size_t esize, int i, int& size) {
+template <MEMFLAGS F> void CHeapArray<F>::expand(size_t esize, int i, int& size) {
   // determine new size
   if (size == 0) size = 4; // prevent endless loop
   while (i >= size) size *= 2;
   // allocate and initialize new data section
-  void* data = NEW_C_HEAP_ARRAY(char*, esize * size);
+  void* data = NEW_C_HEAP_ARRAY(char*, esize * size, F);
   memcpy(data, _data, esize * length());
-  FREE_C_HEAP_ARRAY(char*, _data);
+  FREE_C_HEAP_ARRAY(char*, _data, F);
   _data = data;
 }
 
@@ -91,7 +91,7 @@
   memmove(dst, src, cnt);
 }
 
-void CHeapArray::remove_at(size_t esize, int i) {
+template <MEMFLAGS F> void CHeapArray<F>::remove_at(size_t esize, int i) {
   assert(0 <= i && i < length(), "index out of bounds");
   _length--;
   void* dst = (char*)_data + i*esize;
diff --git a/hotspot/src/share/vm/utilities/array.hpp b/hotspot/src/share/vm/utilities/array.hpp
index cbc4161..c0fb592 100644
--- a/hotspot/src/share/vm/utilities/array.hpp
+++ b/hotspot/src/share/vm/utilities/array.hpp
@@ -79,7 +79,7 @@
 };
 
 
-class CHeapArray: public CHeapObj {
+template <MEMFLAGS F>class CHeapArray: public CHeapObj<F> {
  protected:
   int   _length;                                 // the number of array elements
   void* _data;                                   // the array memory
@@ -94,7 +94,7 @@
   CHeapArray(size_t esize, int length) {
     assert(length >= 0, "illegal length");
     _length  = length;
-    _data    = (void*) NEW_C_HEAP_ARRAY(char *, esize * length);
+    _data    = (void*) NEW_C_HEAP_ARRAY(char *, esize * length, F);
   }
 
 #ifdef ASSERT
diff --git a/hotspot/src/share/vm/utilities/bitMap.cpp b/hotspot/src/share/vm/utilities/bitMap.cpp
index 17231d3..0b12b11 100644
--- a/hotspot/src/share/vm/utilities/bitMap.cpp
+++ b/hotspot/src/share/vm/utilities/bitMap.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,8 +65,8 @@
   if (in_resource_area) {
     _map = NEW_RESOURCE_ARRAY(bm_word_t, new_size_in_words);
   } else {
-    if (old_map != NULL) FREE_C_HEAP_ARRAY(bm_word_t, _map);
-    _map = NEW_C_HEAP_ARRAY(bm_word_t, new_size_in_words);
+    if (old_map != NULL) FREE_C_HEAP_ARRAY(bm_word_t, _map, mtInternal);
+    _map = NEW_C_HEAP_ARRAY(bm_word_t, new_size_in_words, mtInternal);
   }
   Copy::disjoint_words((HeapWord*)old_map, (HeapWord*) _map,
                        MIN2(old_size_in_words, new_size_in_words));
@@ -179,64 +179,6 @@
   clear_range_within_word(bit_index(end_full_word), end);
 }
 
-void BitMap::mostly_disjoint_range_union(BitMap* from_bitmap,
-                                         idx_t   from_start_index,
-                                         idx_t   to_start_index,
-                                         size_t  word_num) {
-  // Ensure that the parameters are correct.
-  // These shouldn't be that expensive to check, hence I left them as
-  // guarantees.
-  guarantee(from_bitmap->bit_in_word(from_start_index) == 0,
-            "it should be aligned on a word boundary");
-  guarantee(bit_in_word(to_start_index) == 0,
-            "it should be aligned on a word boundary");
-  guarantee(word_num >= 2, "word_num should be at least 2");
-
-  intptr_t* from = (intptr_t*) from_bitmap->word_addr(from_start_index);
-  intptr_t* to   = (intptr_t*) word_addr(to_start_index);
-
-  if (*from != 0) {
-    // if it's 0, then there's no point in doing the CAS
-    while (true) {
-      intptr_t old_value = *to;
-      intptr_t new_value = old_value | *from;
-      intptr_t res       = Atomic::cmpxchg_ptr(new_value, to, old_value);
-      if (res == old_value) break;
-    }
-  }
-  ++from;
-  ++to;
-
-  for (size_t i = 0; i < word_num - 2; ++i) {
-    if (*from != 0) {
-      // if it's 0, then there's no point in doing the CAS
-      assert(*to == 0, "nobody else should be writing here");
-      intptr_t new_value = *from;
-      *to = new_value;
-    }
-
-    ++from;
-    ++to;
-  }
-
-  if (*from != 0) {
-    // if it's 0, then there's no point in doing the CAS
-    while (true) {
-      intptr_t old_value = *to;
-      intptr_t new_value = old_value | *from;
-      intptr_t res       = Atomic::cmpxchg_ptr(new_value, to, old_value);
-      if (res == old_value) break;
-    }
-  }
-
-  // the -1 is because we didn't advance them after the final CAS
-  assert(from ==
-           (intptr_t*) from_bitmap->word_addr(from_start_index) + word_num - 1,
-            "invariant");
-  assert(to == (intptr_t*) word_addr(to_start_index) + word_num - 1,
-            "invariant");
-}
-
 void BitMap::at_put(idx_t offset, bool value) {
   if (value) {
     set_bit(offset);
@@ -527,7 +469,7 @@
 
 void BitMap::init_pop_count_table() {
   if (_pop_count_table == NULL) {
-    BitMap::idx_t *table = NEW_C_HEAP_ARRAY(idx_t, 256);
+    BitMap::idx_t *table = NEW_C_HEAP_ARRAY(idx_t, 256, mtInternal);
     for (uint i = 0; i < 256; i++) {
       table[i] = num_set_bits(i);
     }
@@ -537,7 +479,7 @@
                                        (intptr_t)  NULL_WORD);
     if (res != NULL_WORD) {
       guarantee( _pop_count_table == (void*) res, "invariant" );
-      FREE_C_HEAP_ARRAY(bm_word_t, table);
+      FREE_C_HEAP_ARRAY(bm_word_t, table, mtInternal);
     }
   }
 }
diff --git a/hotspot/src/share/vm/utilities/bitMap.hpp b/hotspot/src/share/vm/utilities/bitMap.hpp
index 7577877..2c0975f 100644
--- a/hotspot/src/share/vm/utilities/bitMap.hpp
+++ b/hotspot/src/share/vm/utilities/bitMap.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -192,31 +192,6 @@
   void par_set_range(idx_t beg, idx_t end, RangeSizeHint hint);
   void par_clear_range  (idx_t beg, idx_t end, RangeSizeHint hint);
 
-  // It performs the union operation between subsets of equal length
-  // of two bitmaps (the target bitmap of the method and the
-  // from_bitmap) and stores the result to the target bitmap.  The
-  // from_start_index represents the first bit index of the subrange
-  // of the from_bitmap.  The to_start_index is the equivalent of the
-  // target bitmap. Both indexes should be word-aligned, i.e. they
-  // should correspond to the first bit on a bitmap word (it's up to
-  // the caller to ensure this; the method does check it).  The length
-  // of the subset is specified with word_num and it is in number of
-  // bitmap words. The caller should ensure that this is at least 2
-  // (smaller ranges are not support to save extra checks).  Again,
-  // this is checked in the method.
-  //
-  // Atomicity concerns: it is assumed that any contention on the
-  // target bitmap with other threads will happen on the first and
-  // last words; the ones in between will be "owned" exclusively by
-  // the calling thread and, in fact, they will already be 0. So, the
-  // method performs a CAS on the first word, copies the next
-  // word_num-2 words, and finally performs a CAS on the last word.
-  void mostly_disjoint_range_union(BitMap* from_bitmap,
-                                   idx_t   from_start_index,
-                                   idx_t   to_start_index,
-                                   size_t  word_num);
-
-
   // Clearing
   void clear_large();
   inline void clear();
diff --git a/hotspot/src/share/vm/utilities/debug.cpp b/hotspot/src/share/vm/utilities/debug.cpp
index b7e7a27..8f7f182 100644
--- a/hotspot/src/share/vm/utilities/debug.cpp
+++ b/hotspot/src/share/vm/utilities/debug.cpp
@@ -91,6 +91,13 @@
 #  endif
 #endif // PRODUCT
 
+FormatBufferResource::FormatBufferResource(const char * format, ...)
+  : FormatBufferBase((char*)resource_allocate_bytes(RES_BUFSZ)) {
+  va_list argp;
+  va_start(argp, format);
+  jio_vsnprintf(_buf, RES_BUFSZ, format, argp);
+  va_end(argp);
+}
 
 void warning(const char* format, ...) {
   if (PrintWarnings) {
@@ -467,7 +474,7 @@
   }
   // Ensure Eden top is correct before verification
   Universe::heap()->prepare_for_verify();
-  Universe::verify(true);
+  Universe::verify();
   if (!safe) SafepointSynchronize::set_is_not_at_safepoint();
 }
 
diff --git a/hotspot/src/share/vm/utilities/debug.hpp b/hotspot/src/share/vm/utilities/debug.hpp
index 0ba6442..0c718a2 100644
--- a/hotspot/src/share/vm/utilities/debug.hpp
+++ b/hotspot/src/share/vm/utilities/debug.hpp
@@ -31,29 +31,43 @@
 #include <stdarg.h>
 
 // Simple class to format the ctor arguments into a fixed-sized buffer.
+class FormatBufferBase {
+ protected:
+  char* _buf;
+  inline FormatBufferBase(char* buf) : _buf(buf) {}
+ public:
+  operator const char *() const { return _buf; }
+};
+
+// Use resource area for buffer
+#define RES_BUFSZ 256
+class FormatBufferResource : public FormatBufferBase {
+ public:
+  FormatBufferResource(const char * format, ...);
+};
+
+// Use stack for buffer
 template <size_t bufsz = 256>
-class FormatBuffer {
+class FormatBuffer : public FormatBufferBase {
  public:
   inline FormatBuffer(const char * format, ...);
   inline void append(const char* format, ...);
   inline void print(const char* format, ...);
   inline void printv(const char* format, va_list ap);
-  operator const char *() const { return _buf; }
 
   char* buffer() { return _buf; }
   int size() { return bufsz; }
 
  private:
   FormatBuffer(const FormatBuffer &); // prevent copies
+  char _buffer[bufsz];
 
  protected:
-  char _buf[bufsz];
-
   inline FormatBuffer();
 };
 
 template <size_t bufsz>
-FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) {
+FormatBuffer<bufsz>::FormatBuffer(const char * format, ...) : FormatBufferBase(_buffer) {
   va_list argp;
   va_start(argp, format);
   jio_vsnprintf(_buf, bufsz, format, argp);
@@ -61,7 +75,7 @@
 }
 
 template <size_t bufsz>
-FormatBuffer<bufsz>::FormatBuffer() {
+FormatBuffer<bufsz>::FormatBuffer() : FormatBufferBase(_buffer) {
   _buf[0] = '\0';
 }
 
@@ -93,6 +107,7 @@
 
 // Used to format messages for assert(), guarantee(), fatal(), etc.
 typedef FormatBuffer<> err_msg;
+typedef FormatBufferResource err_msg_res;
 
 // assertions
 #ifdef ASSERT
diff --git a/hotspot/src/share/vm/utilities/decoder.cpp b/hotspot/src/share/vm/utilities/decoder.cpp
index cf7be32..4a9266f 100644
--- a/hotspot/src/share/vm/utilities/decoder.cpp
+++ b/hotspot/src/share/vm/utilities/decoder.cpp
@@ -91,6 +91,18 @@
   return decoder->decode(addr, buf, buflen, offset, modulepath);
 }
 
+bool Decoder::decode(address addr, char* buf, int buflen, int* offset, const void* base) {
+  assert(_shared_decoder_lock != NULL, "Just check");
+  bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
+  MutexLockerEx locker(error_handling_thread ? NULL : _shared_decoder_lock, true);
+  AbstractDecoder* decoder = error_handling_thread ?
+    get_error_handler_instance(): get_shared_instance();
+  assert(decoder != NULL, "null decoder");
+
+  return decoder->decode(addr, buf, buflen, offset, base);
+}
+
+
 bool Decoder::demangle(const char* symbol, char* buf, int buflen) {
   assert(_shared_decoder_lock != NULL, "Just check");
   bool error_handling_thread = os::current_thread_id() == VMError::first_error_tid;
diff --git a/hotspot/src/share/vm/utilities/decoder.hpp b/hotspot/src/share/vm/utilities/decoder.hpp
index 56ff919..0d2af80 100644
--- a/hotspot/src/share/vm/utilities/decoder.hpp
+++ b/hotspot/src/share/vm/utilities/decoder.hpp
@@ -29,7 +29,7 @@
 #include "memory/allocation.hpp"
 #include "runtime/mutex.hpp"
 
-class AbstractDecoder : public CHeapObj {
+class AbstractDecoder : public CHeapObj<mtInternal> {
 public:
   // status code for decoding native C frame
   enum decoder_status {
@@ -47,6 +47,8 @@
   // the function
   virtual bool decode(address pc, char* buf, int buflen, int* offset,
     const char* modulepath = NULL) = 0;
+  virtual bool decode(address pc, char* buf, int buflen, int* offset, const void* base) = 0;
+
   // demangle a C++ symbol
   virtual bool demangle(const char* symbol, char* buf, int buflen) = 0;
   // if the decoder can decode symbols in vm
@@ -82,6 +84,10 @@
     return false;
   }
 
+  virtual bool decode(address pc, char* buf, int buflen, int* offset, const void* base) {
+    return false;
+  }
+
   virtual bool demangle(const char* symbol, char* buf, int buflen) {
     return false;
   }
@@ -95,6 +101,7 @@
 class Decoder : AllStatic {
 public:
   static bool decode(address pc, char* buf, int buflen, int* offset, const char* modulepath = NULL);
+  static bool decode(address pc, char* buf, int buflen, int* offset, const void* base);
   static bool demangle(const char* symbol, char* buf, int buflen);
   static bool can_decode_C_frame_in_vm();
 
diff --git a/hotspot/src/share/vm/utilities/decoder_elf.hpp b/hotspot/src/share/vm/utilities/decoder_elf.hpp
index 971cd3c..79652ae 100644
--- a/hotspot/src/share/vm/utilities/decoder_elf.hpp
+++ b/hotspot/src/share/vm/utilities/decoder_elf.hpp
@@ -43,6 +43,10 @@
 
   bool demangle(const char* symbol, char *buf, int buflen);
   bool decode(address addr, char *buf, int buflen, int* offset, const char* filepath = NULL);
+  bool decode(address addr, char *buf, int buflen, int* offset, const void *base) {
+    ShouldNotReachHere();
+    return false;
+  }
 
 private:
   ElfFile*         get_elf_file(const char* filepath);
diff --git a/hotspot/src/share/vm/utilities/dtrace.hpp b/hotspot/src/share/vm/utilities/dtrace.hpp
index 799cd72..0e260fe 100644
--- a/hotspot/src/share/vm/utilities/dtrace.hpp
+++ b/hotspot/src/share/vm/utilities/dtrace.hpp
@@ -1,5 +1,6 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012 Red Hat, Inc.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -32,13 +33,17 @@
 #define DTRACE_ONLY(x) x
 #define NOT_DTRACE(x)
 
+#if defined(SOLARIS)
 // Work around dtrace tail call bug 6672627 until it is fixed in solaris 10.
 #define HS_DTRACE_WORKAROUND_TAIL_CALL_BUG() \
   do { volatile size_t dtrace_workaround_tail_call_bug = 1; } while (0)
 
-#if defined(SOLARIS)
+#define USDT1 1
+#elif defined(LINUX)
+#define HS_DTRACE_WORKAROUND_TAIL_CALL_BUG()
 #define USDT1 1
 #elif defined(__APPLE__)
+#define HS_DTRACE_WORKAROUND_TAIL_CALL_BUG()
 #define USDT2 1
 #include <sys/types.h>
 #include "dtracefiles/hotspot.h"
@@ -63,6 +68,11 @@
 #define DTRACE_PROBE3(a,b,c,d,e) {;}
 #define DTRACE_PROBE4(a,b,c,d,e,f) {;}
 #define DTRACE_PROBE5(a,b,c,d,e,f,g) {;}
+#define DTRACE_PROBE6(a,b,c,d,e,f,g,h) {;}
+#define DTRACE_PROBE7(a,b,c,d,e,f,g,h,i) {;}
+#define DTRACE_PROBE8(a,b,c,d,e,f,g,h,i,j) {;}
+#define DTRACE_PROBE9(a,b,c,d,e,f,g,h,i,j,k) {;}
+#define DTRACE_PROBE10(a,b,c,d,e,f,g,h,i,j,k,l) {;}
 
 #else /* USDT2 */
 
@@ -76,10 +86,18 @@
 #define HS_DTRACE_PROBE_FN(provider,name)\
   __dtrace_##provider##___##name
 
+#ifdef SOLARIS
+// Solaris dtrace needs actual extern function decls.
 #define HS_DTRACE_PROBE_DECL_N(provider,name,args) \
   DTRACE_ONLY(extern "C" void HS_DTRACE_PROBE_FN(provider,name) args)
 #define HS_DTRACE_PROBE_CDECL_N(provider,name,args) \
   DTRACE_ONLY(extern void HS_DTRACE_PROBE_FN(provider,name) args)
+#else
+// Systemtap dtrace compatible probes on GNU/Linux don't.
+// If dtrace is disabled this macro becomes NULL
+#define HS_DTRACE_PROBE_DECL_N(provider,name,args)
+#define HS_DTRACE_PROBE_CDECL_N(provider,name,args)
+#endif
 
 /* Dtrace probe declarations */
 #define HS_DTRACE_PROBE_DECL(provider,name) \
@@ -118,6 +136,8 @@
     uintptr_t,uintptr_t,uintptr_t))
 
 /* Dtrace probe definitions */
+#if defined(SOLARIS)
+// Solaris dtrace uses actual function calls.
 #define HS_DTRACE_PROBE_N(provider,name, args) \
   DTRACE_ONLY(HS_DTRACE_PROBE_FN(provider,name) args)
 
@@ -153,6 +173,33 @@
   HS_DTRACE_PROBE_N(provider,name,((uintptr_t)a0,(uintptr_t)a1,(uintptr_t)a2,\
     (uintptr_t)a3,(uintptr_t)a4,(uintptr_t)a5,(uintptr_t)a6,(uintptr_t)a7,\
     (uintptr_t)a8,(uintptr_t)a9))
+#else
+// Systemtap dtrace compatible probes on GNU/Linux use direct macros.
+// If dtrace is disabled this macro becomes NULL
+#define HS_DTRACE_PROBE(provider,name) HS_DTRACE_PROBE0(provider,name)
+#define HS_DTRACE_PROBE0(provider,name)\
+  DTRACE_PROBE(provider,name)
+#define HS_DTRACE_PROBE1(provider,name,a0)\
+  DTRACE_PROBE1(provider,name,a0)
+#define HS_DTRACE_PROBE2(provider,name,a0,a1)\
+  DTRACE_PROBE2(provider,name,a0,a1)
+#define HS_DTRACE_PROBE3(provider,name,a0,a1,a2)\
+  DTRACE_PROBE3(provider,name,a0,a1,a2)
+#define HS_DTRACE_PROBE4(provider,name,a0,a1,a2,a3)\
+  DTRACE_PROBE4(provider,name,a0,a1,a2,a3)
+#define HS_DTRACE_PROBE5(provider,name,a0,a1,a2,a3,a4)\
+  DTRACE_PROBE5(provider,name,a0,a1,a2,a3,a4)
+#define HS_DTRACE_PROBE6(provider,name,a0,a1,a2,a3,a4,a5)\
+  DTRACE_PROBE6(provider,name,a0,a1,a2,a3,a4,a5)
+#define HS_DTRACE_PROBE7(provider,name,a0,a1,a2,a3,a4,a5,a6)\
+  DTRACE_PROBE7(provider,name,a0,a1,a2,a3,a4,a5,a6)
+#define HS_DTRACE_PROBE8(provider,name,a0,a1,a2,a3,a4,a5,a6,a7)\
+  DTRACE_PROBE8(provider,name,a0,a1,a2,a3,a4,a5,a6,a7)
+#define HS_DTRACE_PROBE9(provider,name,a0,a1,a2,a3,a4,a5,a6,a7,a8)\
+  DTRACE_PROBE9(provider,name,a0,a1,a2,a3,a4,a5,a6,a7,a8)
+#define HS_DTRACE_PROBE10(provider,name,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9)\
+  DTRACE_PROBE10(provider,name,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9)
+#endif
 
 #endif /* !USDT2 */
 
diff --git a/hotspot/src/share/vm/utilities/elfFile.cpp b/hotspot/src/share/vm/utilities/elfFile.cpp
index 2e4b683..5faaf83 100644
--- a/hotspot/src/share/vm/utilities/elfFile.cpp
+++ b/hotspot/src/share/vm/utilities/elfFile.cpp
@@ -47,7 +47,7 @@
   m_status = NullDecoder::no_error;
 
   int len = strlen(filepath) + 1;
-  m_filepath = (const char*)os::malloc(len * sizeof(char));
+  m_filepath = (const char*)os::malloc(len * sizeof(char), mtInternal);
   if (m_filepath != NULL) {
     strcpy((char*)m_filepath, filepath);
     m_file = fopen(filepath, "r");
diff --git a/hotspot/src/share/vm/utilities/elfFile.hpp b/hotspot/src/share/vm/utilities/elfFile.hpp
index e6f4ce2..f0cba8b 100644
--- a/hotspot/src/share/vm/utilities/elfFile.hpp
+++ b/hotspot/src/share/vm/utilities/elfFile.hpp
@@ -82,7 +82,7 @@
 // in "error" state, so there are scenarios, lookup will fail. We want this
 // part of code to be very defensive, and bait out if anything went wrong.
 
-class ElfFile: public CHeapObj {
+class ElfFile: public CHeapObj<mtInternal> {
   friend class ElfDecoder;
  public:
   ElfFile(const char* filepath);
diff --git a/hotspot/src/share/vm/utilities/elfStringTable.cpp b/hotspot/src/share/vm/utilities/elfStringTable.cpp
index 89286cb..cba67dd 100644
--- a/hotspot/src/share/vm/utilities/elfStringTable.cpp
+++ b/hotspot/src/share/vm/utilities/elfStringTable.cpp
@@ -42,7 +42,7 @@
 
   // try to load the string table
   long cur_offset = ftell(file);
-  m_table = (char*)os::malloc(sizeof(char) * shdr.sh_size);
+  m_table = (char*)os::malloc(sizeof(char) * shdr.sh_size, mtInternal);
   if (m_table != NULL) {
     // if there is an error, mark the error
     if (fseek(file, shdr.sh_offset, SEEK_SET) ||
diff --git a/hotspot/src/share/vm/utilities/elfStringTable.hpp b/hotspot/src/share/vm/utilities/elfStringTable.hpp
index 96f30b1..a4cdfc0 100644
--- a/hotspot/src/share/vm/utilities/elfStringTable.hpp
+++ b/hotspot/src/share/vm/utilities/elfStringTable.hpp
@@ -35,7 +35,7 @@
 // The string table represents a string table section in an elf file.
 // Whenever there is enough memory, it will load whole string table as
 // one blob. Otherwise, it will load string from file when requested.
-class ElfStringTable: CHeapObj {
+class ElfStringTable: CHeapObj<mtInternal> {
   friend class ElfFile;
  public:
   ElfStringTable(FILE* file, Elf_Shdr shdr, int index);
diff --git a/hotspot/src/share/vm/utilities/elfSymbolTable.cpp b/hotspot/src/share/vm/utilities/elfSymbolTable.cpp
index 3ac9b92..5301d5a 100644
--- a/hotspot/src/share/vm/utilities/elfSymbolTable.cpp
+++ b/hotspot/src/share/vm/utilities/elfSymbolTable.cpp
@@ -40,7 +40,7 @@
   long cur_offset = ftell(file);
   if (cur_offset != -1) {
     // call malloc so we can back up if memory allocation fails.
-    m_symbols = (Elf_Sym*)os::malloc(shdr.sh_size);
+    m_symbols = (Elf_Sym*)os::malloc(shdr.sh_size, mtInternal);
     if (m_symbols) {
       if (fseek(file, shdr.sh_offset, SEEK_SET) ||
         fread((void*)m_symbols, shdr.sh_size, 1, file) != 1 ||
diff --git a/hotspot/src/share/vm/utilities/elfSymbolTable.hpp b/hotspot/src/share/vm/utilities/elfSymbolTable.hpp
index a149b99..4a23cfd 100644
--- a/hotspot/src/share/vm/utilities/elfSymbolTable.hpp
+++ b/hotspot/src/share/vm/utilities/elfSymbolTable.hpp
@@ -38,7 +38,7 @@
  * of the elf file into memory. Otherwise, it will walk the section in file
  * to look up the symbol that nearest the given address.
  */
-class ElfSymbolTable: public CHeapObj {
+class ElfSymbolTable: public CHeapObj<mtInternal> {
   friend class ElfFile;
  public:
   ElfSymbolTable(FILE* file, Elf_Shdr shdr);
diff --git a/hotspot/src/share/vm/utilities/events.hpp b/hotspot/src/share/vm/utilities/events.hpp
index 5b64e0c..74a8042 100644
--- a/hotspot/src/share/vm/utilities/events.hpp
+++ b/hotspot/src/share/vm/utilities/events.hpp
@@ -46,7 +46,7 @@
 // crash time.  This is a very generic interface that is mainly here
 // for completeness.  Normally the templated EventLogBase would be
 // subclassed to provide different log types.
-class EventLog : public CHeapObj {
+class EventLog : public CHeapObj<mtInternal> {
   friend class Events;
 
  private:
diff --git a/hotspot/src/share/vm/utilities/exceptions.cpp b/hotspot/src/share/vm/utilities/exceptions.cpp
index 874d8e5..03f254d 100644
--- a/hotspot/src/share/vm/utilities/exceptions.cpp
+++ b/hotspot/src/share/vm/utilities/exceptions.cpp
@@ -164,52 +164,58 @@
 }
 
 
-void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_loader, Handle h_protection_domain) {
+void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message,
+                            Handle h_loader, Handle h_protection_domain) {
   // Check for special boot-strapping/vm-thread handling
-  if (special_exception(thread, file, line, h_name, message)) return;
+  if (special_exception(thread, file, line, name, message)) return;
   // Create and throw exception
   Handle h_cause(thread, NULL);
-  Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain);
+  Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain);
   _throw(thread, file, line, h_exception, message);
 }
 
-// Throw an exception with a message and a cause
-void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* h_name, const char* message, Handle h_cause, Handle h_loader, Handle h_protection_domain) {
+void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,
+                                  Handle h_loader, Handle h_protection_domain) {
   // Check for special boot-strapping/vm-thread handling
-  if (special_exception(thread, file, line, h_name, message)) return;
+  if (special_exception(thread, file, line, name, message)) return;
   // Create and throw exception and init cause
-  Handle h_exception = new_exception(thread, h_name, message, h_cause, h_loader, h_protection_domain);
+  Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain);
   _throw(thread, file, line, h_exception, message);
 }
 
-// This version already has a handle for name
-void Exceptions::_throw_msg(Thread* thread, const char* file, int line,
-                            Symbol* name, const char* message) {
-  Handle       h_loader(thread, NULL);
-  Handle       h_protection_domain(thread, NULL);
-  Exceptions::_throw_msg(thread, file, line, name, message, h_loader, h_protection_domain);
-}
-
-// This version already has a handle for name
-void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line,
-                            Symbol* name, const char* message, Handle cause) {
-  Handle       h_loader(thread, NULL);
-  Handle       h_protection_domain(thread, NULL);
-  Exceptions::_throw_msg_cause(thread, file, line, name, message, cause, h_loader, h_protection_domain);
-}
-
-void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* h_name, Symbol* h_signature, JavaCallArguments *args) {
+void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause,
+                              Handle h_loader, Handle h_protection_domain) {
   // Check for special boot-strapping/vm-thread handling
-  if (special_exception(thread, file, line, h_name, NULL)) return;
+  if (special_exception(thread, file, line, h_cause)) return;
+  // Create and throw exception
+  Handle h_exception = new_exception(thread, name, h_cause, h_loader, h_protection_domain);
+  _throw(thread, file, line, h_exception, NULL);
+}
+
+void Exceptions::_throw_args(Thread* thread, const char* file, int line, Symbol* name, Symbol* signature, JavaCallArguments *args) {
+  // Check for special boot-strapping/vm-thread handling
+  if (special_exception(thread, file, line, name, NULL)) return;
   // Create and throw exception
   Handle h_loader(thread, NULL);
   Handle h_prot(thread, NULL);
-  Handle h_cause(thread, NULL);
-  Handle exception = new_exception(thread, h_name, h_signature, args, h_cause, h_loader, h_prot);
+  Handle exception = new_exception(thread, name, signature, args, h_loader, h_prot);
   _throw(thread, file, line, exception);
 }
 
 
+// Methods for default parameters.
+// NOTE: These must be here (and not in the header file) because of include circularities.
+void Exceptions::_throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause) {
+  _throw_msg_cause(thread, file, line, name, message, h_cause, Handle(thread, NULL), Handle(thread, NULL));
+}
+void Exceptions::_throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message) {
+  _throw_msg(thread, file, line, name, message, Handle(thread, NULL), Handle(thread, NULL));
+}
+void Exceptions::_throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause) {
+  _throw_cause(thread, file, line, name, h_cause, Handle(thread, NULL), Handle(thread, NULL));
+}
+
+
 void Exceptions::throw_stack_overflow_exception(Thread* THREAD, const char* file, int line, methodHandle method) {
   Handle exception;
   if (!THREAD->has_pending_exception()) {
@@ -240,12 +246,9 @@
 
 // Creates an exception oop, calls the <init> method with the given signature.
 // and returns a Handle
-// Initializes the cause if cause non-null
-Handle Exceptions::new_exception(Thread *thread, Symbol* h_name,
-                                 Symbol* signature,
-                                 JavaCallArguments *args,
-                                 Handle h_cause, Handle h_loader,
-                                 Handle h_protection_domain) {
+Handle Exceptions::new_exception(Thread *thread, Symbol* name,
+                                 Symbol* signature, JavaCallArguments *args,
+                                 Handle h_loader, Handle h_protection_domain) {
   assert(Universe::is_fully_initialized(),
     "cannot be called during initialization");
   assert(thread->is_Java_thread(), "can only be called by a Java thread");
@@ -254,8 +257,8 @@
   Handle h_exception;
 
   // Resolve exception klass
-  klassOop ik = SystemDictionary::resolve_or_fail(h_name, h_loader, h_protection_domain, true, thread);
-  instanceKlassHandle klass (thread, ik);
+  klassOop ik = SystemDictionary::resolve_or_fail(name, h_loader, h_protection_domain, true, thread);
+  instanceKlassHandle klass(thread, ik);
 
   if (!thread->has_pending_exception()) {
     assert(klass.not_null(), "klass must exist");
@@ -273,24 +276,8 @@
                                          signature,
                                          args,
                                          thread);
-
       }
     }
-
-    // Future: object initializer should take a cause argument
-    if (h_cause() != NULL) {
-      assert(h_cause->is_a(SystemDictionary::Throwable_klass()),
-          "exception cause is not a subclass of java/lang/Throwable");
-      JavaValue result1(T_OBJECT);
-      JavaCallArguments args1;
-      args1.set_receiver(h_exception);
-      args1.push_oop(h_cause);
-      JavaCalls::call_virtual(&result1, klass,
-                                     vmSymbols::initCause_name(),
-                                     vmSymbols::throwable_throwable_signature(),
-                                     &args1,
-                                     thread);
-    }
   }
 
   // Check if another exception was thrown in the process, if so rethrow that one
@@ -301,12 +288,60 @@
   return h_exception;
 }
 
+// Creates an exception oop, calls the <init> method with the given signature.
+// and returns a Handle
+// Initializes the cause if cause non-null
+Handle Exceptions::new_exception(Thread *thread, Symbol* name,
+                                 Symbol* signature, JavaCallArguments *args,
+                                 Handle h_cause,
+                                 Handle h_loader, Handle h_protection_domain) {
+  Handle h_exception = new_exception(thread, name, signature, args, h_loader, h_protection_domain);
+
+  // Future: object initializer should take a cause argument
+  if (h_cause.not_null()) {
+    assert(h_cause->is_a(SystemDictionary::Throwable_klass()),
+        "exception cause is not a subclass of java/lang/Throwable");
+    JavaValue result1(T_OBJECT);
+    JavaCallArguments args1;
+    args1.set_receiver(h_exception);
+    args1.push_oop(h_cause);
+    JavaCalls::call_virtual(&result1, h_exception->klass(),
+                                      vmSymbols::initCause_name(),
+                                      vmSymbols::throwable_throwable_signature(),
+                                      &args1,
+                                      thread);
+  }
+
+  // Check if another exception was thrown in the process, if so rethrow that one
+  if (thread->has_pending_exception()) {
+    h_exception = Handle(thread, thread->pending_exception());
+    thread->clear_pending_exception();
+  }
+  return h_exception;
+}
+
+// Convenience method. Calls either the <init>() or <init>(Throwable) method when
+// creating a new exception
+Handle Exceptions::new_exception(Thread* thread, Symbol* name,
+                                 Handle h_cause,
+                                 Handle h_loader, Handle h_protection_domain,
+                                 ExceptionMsgToUtf8Mode to_utf8_safe) {
+  JavaCallArguments args;
+  Symbol* signature = NULL;
+  if (h_cause.is_null()) {
+    signature = vmSymbols::void_method_signature();
+  } else {
+    signature = vmSymbols::throwable_void_signature();
+    args.push_oop(h_cause);
+  }
+  return new_exception(thread, name, signature, &args, h_loader, h_protection_domain);
+}
+
 // Convenience method. Calls either the <init>() or <init>(String) method when
 // creating a new exception
-Handle Exceptions::new_exception(Thread* thread, Symbol* h_name,
+Handle Exceptions::new_exception(Thread* thread, Symbol* name,
                                  const char* message, Handle h_cause,
-                                 Handle h_loader,
-                                 Handle h_protection_domain,
+                                 Handle h_loader, Handle h_protection_domain,
                                  ExceptionMsgToUtf8Mode to_utf8_safe) {
   JavaCallArguments args;
   Symbol* signature = NULL;
@@ -320,7 +355,7 @@
     // the exception we are trying to build, or the pending exception.
     // This is sort of like what PRESERVE_EXCEPTION_MARK does, except
     // for the preferencing and the early returns.
-    Handle incoming_exception (thread, NULL);
+    Handle incoming_exception(thread, NULL);
     if (thread->has_pending_exception()) {
       incoming_exception = Handle(thread, thread->pending_exception());
       thread->clear_pending_exception();
@@ -344,7 +379,7 @@
     args.push_oop(msg);
     signature = vmSymbols::string_void_signature();
   }
-  return new_exception(thread, h_name, signature, &args, h_cause, h_loader, h_protection_domain);
+  return new_exception(thread, name, signature, &args, h_cause, h_loader, h_protection_domain);
 }
 
 // Another convenience method that creates handles for null class loaders and
@@ -355,8 +390,7 @@
 // encoding scheme of the string into account. One thing we should do at some
 // point is to push this flag down to class java_lang_String since other
 // classes may need similar functionalities.
-Handle Exceptions::new_exception(Thread* thread,
-                                 Symbol* name,
+Handle Exceptions::new_exception(Thread* thread, Symbol* name,
                                  const char* message,
                                  ExceptionMsgToUtf8Mode to_utf8_safe) {
 
diff --git a/hotspot/src/share/vm/utilities/exceptions.hpp b/hotspot/src/share/vm/utilities/exceptions.hpp
index f7fece1..0244d75 100644
--- a/hotspot/src/share/vm/utilities/exceptions.hpp
+++ b/hotspot/src/share/vm/utilities/exceptions.hpp
@@ -57,7 +57,7 @@
 // field of the Thread class w/o having access to the Thread's interface (for
 // include hierachy reasons).
 
-class ThreadShadow: public CHeapObj {
+class ThreadShadow: public CHeapObj<mtThread> {
   friend class VMStructs;
 
  protected:
@@ -112,19 +112,22 @@
   // Throw exceptions: w/o message, w/ message & with formatted message.
   static void _throw_oop(Thread* thread, const char* file, int line, oop exception);
   static void _throw(Thread* thread, const char* file, int line, Handle exception, const char* msg = NULL);
-  static void _throw_msg(Thread* thread, const char* file, int line,
-                         Symbol* name, const char* message, Handle loader,
-                         Handle protection_domain);
-  static void _throw_msg(Thread* thread, const char* file, int line,
-                         Symbol* name, const char* message);
+
+  static void _throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message);
+  static void _throw_msg(Thread* thread, const char* file, int line, Symbol* name, const char* message,
+                         Handle loader, Handle protection_domain);
+
+  static void _throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause);
+  static void _throw_msg_cause(Thread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause,
+                               Handle h_loader, Handle h_protection_domain);
+
+  static void _throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause);
+  static void _throw_cause(Thread* thread, const char* file, int line, Symbol* name, Handle h_cause,
+                           Handle h_loader, Handle h_protection_domain);
+
   static void _throw_args(Thread* thread, const char* file, int line,
                           Symbol* name, Symbol* signature,
                           JavaCallArguments* args);
-  static void _throw_msg_cause(Thread* thread, const char* file,
-                         int line, Symbol* h_name, const char* message,
-                         Handle h_cause, Handle h_loader, Handle h_protection_domain);
-  static void _throw_msg_cause(Thread* thread, const char* file, int line,
-                            Symbol* name, const char* message, Handle cause);
 
   // There is no THROW... macro for this method. Caller should remember
   // to do a return after calling it.
@@ -134,17 +137,26 @@
   // Create and initialize a new exception
   static Handle new_exception(Thread* thread, Symbol* name,
                               Symbol* signature, JavaCallArguments* args,
-                              Handle cause, Handle loader,
-                              Handle protection_domain);
+                              Handle loader, Handle protection_domain);
 
   static Handle new_exception(Thread* thread, Symbol* name,
-                              const char* message, Handle cause, Handle loader,
-                              Handle protection_domain,
+                              Symbol* signature, JavaCallArguments* args,
+                              Handle cause,
+                              Handle loader, Handle protection_domain);
+
+  static Handle new_exception(Thread* thread, Symbol* name,
+                              Handle cause,
+                              Handle loader, Handle protection_domain,
                               ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
 
- static Handle new_exception(Thread* thread, Symbol* name,
-                             const char* message,
-                             ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
+  static Handle new_exception(Thread* thread, Symbol* name,
+                              const char* message, Handle cause,
+                              Handle loader, Handle protection_domain,
+                              ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
+
+  static Handle new_exception(Thread* thread, Symbol* name,
+                              const char* message,
+                              ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8);
 
   static void throw_stack_overflow_exception(Thread* thread, const char* file, int line, methodHandle method);
 
@@ -214,6 +226,9 @@
 #define THROW_MSG(name, message)                    \
   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return;  }
 
+#define THROW_CAUSE(name, cause)   \
+  { Exceptions::_throw_cause(THREAD_AND_LOCATION, name, cause); return; }
+
 #define THROW_MSG_LOADER(name, message, loader, protection_domain) \
   { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return;  }
 
@@ -238,6 +253,9 @@
 #define THROW_ARG_(name, signature, args, result) \
   { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return result; }
 
+#define THROW_MSG_CAUSE(name, message, cause)   \
+  { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return; }
+
 #define THROW_MSG_CAUSE_(name, message, cause, result)   \
   { Exceptions::_throw_msg_cause(THREAD_AND_LOCATION, name, message, cause); return result; }
 
diff --git a/hotspot/src/share/vm/utilities/globalDefinitions.hpp b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
index 89201f6..19dcec1 100644
--- a/hotspot/src/share/vm/utilities/globalDefinitions.hpp
+++ b/hotspot/src/share/vm/utilities/globalDefinitions.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -161,10 +161,6 @@
 const size_t G                  = M*K;
 const size_t HWperKB            = K / sizeof(HeapWord);
 
-const size_t LOG_K              = 10;
-const size_t LOG_M              = 2 * LOG_K;
-const size_t LOG_G              = 2 * LOG_M;
-
 const jint min_jint = (jint)1 << (sizeof(jint)*BitsPerByte-1); // 0x80000000 == smallest jint
 const jint max_jint = (juint)min_jint - 1;                     // 0x7FFFFFFF == largest jint
 
@@ -179,6 +175,11 @@
 const jint  NANOSECS_PER_MILLISEC = 1000000;
 
 inline const char* proper_unit_for_byte_size(size_t s) {
+#ifdef _LP64
+  if (s >= 10*G) {
+    return "G";
+  }
+#endif
   if (s >= 10*M) {
     return "M";
   } else if (s >= 10*K) {
@@ -188,17 +189,22 @@
   }
 }
 
-inline size_t byte_size_in_proper_unit(size_t s) {
+template <class T>
+inline T byte_size_in_proper_unit(T s) {
+#ifdef _LP64
+  if (s >= 10*G) {
+    return (T)(s/G);
+  }
+#endif
   if (s >= 10*M) {
-    return s/M;
+    return (T)(s/M);
   } else if (s >= 10*K) {
-    return s/K;
+    return (T)(s/K);
   } else {
     return s;
   }
 }
 
-
 //----------------------------------------------------------------------------------------------------
 // VM type definitions
 
diff --git a/hotspot/src/share/vm/utilities/growableArray.cpp b/hotspot/src/share/vm/utilities/growableArray.cpp
index a6ad8f3..7da659e 100644
--- a/hotspot/src/share/vm/utilities/growableArray.cpp
+++ b/hotspot/src/share/vm/utilities/growableArray.cpp
@@ -61,7 +61,7 @@
   if (on_stack()) {
     return (void*)resource_allocate_bytes(byte_size);
   } else if (on_C_heap()) {
-    return (void*)AllocateHeap(byte_size, "GrET in " __FILE__);
+    return (void*)AllocateHeap(byte_size, _memflags);
   } else {
     return _arena->Amalloc(byte_size);
   }
diff --git a/hotspot/src/share/vm/utilities/growableArray.hpp b/hotspot/src/share/vm/utilities/growableArray.hpp
index 34972be..2a6d6b8 100644
--- a/hotspot/src/share/vm/utilities/growableArray.hpp
+++ b/hotspot/src/share/vm/utilities/growableArray.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -86,6 +86,9 @@
                         //   0 means default ResourceArea
                         //   1 means on C heap
                         //   otherwise, allocate in _arena
+
+  MEMFLAGS   _memflags;   // memory type if allocation in C heap
+
 #ifdef ASSERT
   int    _nesting;      // resource area nesting at creation
   void   set_nesting();
@@ -102,9 +105,14 @@
 
   // This GA will use the resource stack for storage if c_heap==false,
   // Else it will use the C heap.  Use clear_and_deallocate to avoid leaks.
-  GenericGrowableArray(int initial_size, int initial_len, bool c_heap) {
+  GenericGrowableArray(int initial_size, int initial_len, bool c_heap, MEMFLAGS flags = mtNone) {
     _len = initial_len;
     _max = initial_size;
+    _memflags = flags;
+
+    // memory type has to be specified for C heap allocation
+    assert(!(c_heap && flags == mtNone), "memory type not specified for C heap object");
+
     assert(_len >= 0 && _len <= _max, "initial_len too big");
     _arena = (c_heap ? (Arena*)1 : NULL);
     set_nesting();
@@ -121,6 +129,8 @@
     _max = initial_size;
     assert(_len >= 0 && _len <= _max, "initial_len too big");
     _arena = arena;
+    _memflags = mtNone;
+
     assert(on_arena(), "arena has taken on reserved value 0 or 1");
     // Relax next assert to allow object allocation on resource area,
     // on stack or embedded into an other object.
@@ -152,12 +162,14 @@
     for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
   }
 
-  GrowableArray(int initial_size, bool C_heap = false) : GenericGrowableArray(initial_size, 0, C_heap) {
+  GrowableArray(int initial_size, bool C_heap = false, MEMFLAGS F = mtInternal)
+    : GenericGrowableArray(initial_size, 0, C_heap, F) {
     _data = (E*)raw_allocate(sizeof(E));
     for (int i = 0; i < _max; i++) ::new ((void*)&_data[i]) E();
   }
 
-  GrowableArray(int initial_size, int initial_len, const E& filler, bool C_heap = false) : GenericGrowableArray(initial_size, initial_len, C_heap) {
+  GrowableArray(int initial_size, int initial_len, const E& filler, bool C_heap = false, MEMFLAGS memflags = mtInternal)
+    : GenericGrowableArray(initial_size, initial_len, C_heap, memflags) {
     _data = (E*)raw_allocate(sizeof(E));
     int i = 0;
     for (; i < _len; i++) ::new ((void*)&_data[i]) E(filler);
@@ -198,8 +210,11 @@
     return idx;
   }
 
-  void append_if_missing(const E& elem) {
-    if (!contains(elem)) append(elem);
+  bool append_if_missing(const E& elem) {
+    // Returns TRUE if elem is added.
+    bool missed = !contains(elem);
+    if (missed) append(elem);
+    return missed;
   }
 
   E at(int i) const {
@@ -292,12 +307,22 @@
     ShouldNotReachHere();
   }
 
+  // The order is preserved.
   void remove_at(int index) {
     assert(0 <= index && index < _len, "illegal index");
     for (int j = index + 1; j < _len; j++) _data[j-1] = _data[j];
     _len--;
   }
 
+  // The order is changed.
+  void delete_at(int index) {
+    assert(0 <= index && index < _len, "illegal index");
+    if (index < --_len) {
+      // Replace removed element with last one.
+      _data[index] = _data[_len];
+    }
+  }
+
   // inserts the given element before the element at index i
   void insert_before(const int idx, const E& elem) {
     check_nesting();
diff --git a/hotspot/src/share/vm/utilities/hashtable.cpp b/hotspot/src/share/vm/utilities/hashtable.cpp
index d62b1d3..68b433c 100644
--- a/hotspot/src/share/vm/utilities/hashtable.cpp
+++ b/hotspot/src/share/vm/utilities/hashtable.cpp
@@ -35,11 +35,6 @@
 #include "utilities/hashtable.inline.hpp"
 
 
-#ifndef USDT2
-HS_DTRACE_PROBE_DECL4(hs_private, hashtable__new_entry,
-  void*, unsigned int, void*, void*);
-#endif /* !USDT2 */
-
 // This is a generic hashtable, designed to be used for the symbol
 // and string tables.
 //
@@ -48,8 +43,8 @@
 // %note:
 //  - HashtableEntrys are allocated in blocks to reduce the space overhead.
 
-BasicHashtableEntry* BasicHashtable::new_entry(unsigned int hashValue) {
-  BasicHashtableEntry* entry;
+template <MEMFLAGS F> BasicHashtableEntry<F>* BasicHashtable<F>::new_entry(unsigned int hashValue) {
+  BasicHashtableEntry<F>* entry;
 
   if (_free_list) {
     entry = _free_list;
@@ -60,10 +55,10 @@
       int len = _entry_size * block_size;
       len = 1 << log2_intptr(len); // round down to power of 2
       assert(len >= _entry_size, "");
-      _first_free_entry = NEW_C_HEAP_ARRAY(char, len);
+      _first_free_entry = NEW_C_HEAP_ARRAY2(char, len, F, CURRENT_PC);
       _end_block = _first_free_entry + len;
     }
-    entry = (BasicHashtableEntry*)_first_free_entry;
+    entry = (BasicHashtableEntry<F>*)_first_free_entry;
     _first_free_entry += _entry_size;
   }
 
@@ -73,29 +68,21 @@
 }
 
 
-template <class T> HashtableEntry<T>* Hashtable<T>::new_entry(unsigned int hashValue, T obj) {
-  HashtableEntry<T>* entry;
+template <class T, MEMFLAGS F> HashtableEntry<T, F>* Hashtable<T, F>::new_entry(unsigned int hashValue, T obj) {
+  HashtableEntry<T, F>* entry;
 
-  entry = (HashtableEntry<T>*)BasicHashtable::new_entry(hashValue);
+  entry = (HashtableEntry<T, F>*)BasicHashtable<F>::new_entry(hashValue);
   entry->set_literal(obj);
-#ifndef USDT2
-  HS_DTRACE_PROBE4(hs_private, hashtable__new_entry,
-    this, hashValue, obj, entry);
-#else /* USDT2 */
-  HS_PRIVATE_HASHTABLE_NEW_ENTRY(
-    this, hashValue, (uintptr_t) obj, entry);
-#endif /* USDT2 */
   return entry;
 }
 
-
 // Check to see if the hashtable is unbalanced.  The caller set a flag to
 // rehash at the next safepoint.  If this bucket is 60 times greater than the
 // expected average bucket length, it's an unbalanced hashtable.
 // This is somewhat an arbitrary heuristic but if one bucket gets to
 // rehash_count which is currently 100, there's probably something wrong.
 
-bool BasicHashtable::check_rehash_table(int count) {
+template <MEMFLAGS F> bool BasicHashtable<F>::check_rehash_table(int count) {
   assert(table_size() != 0, "underflow");
   if (count > (((double)number_of_entries()/(double)table_size())*rehash_multiple)) {
     // Set a flag for the next safepoint, which should be at some guaranteed
@@ -105,15 +92,15 @@
   return false;
 }
 
-template <class T> jint Hashtable<T>::_seed = 0;
+template <class T, MEMFLAGS F> jint Hashtable<T, F>::_seed = 0;
 
-template <class T> unsigned int Hashtable<T>::new_hash(Symbol* sym) {
+template <class T, MEMFLAGS F> unsigned int Hashtable<T, F>::new_hash(Symbol* sym) {
   ResourceMark rm;
   // Use alternate hashing algorithm on this symbol.
   return AltHashing::murmur3_32(seed(), (const jbyte*)sym->as_C_string(), sym->utf8_length());
 }
 
-template <class T> unsigned int Hashtable<T>::new_hash(oop string) {
+template <class T, MEMFLAGS F> unsigned int Hashtable<T, F>::new_hash(oop string) {
   ResourceMark rm;
   int length;
   jchar* chars = java_lang_String::as_unicode_string(string, length);
@@ -125,7 +112,7 @@
 // with the existing elements.   This can be used to change the hash code
 // and could in the future change the size of the table.
 
-template <class T> void Hashtable<T>::move_to(Hashtable<T>* new_table) {
+template <class T, MEMFLAGS F> void Hashtable<T, F>::move_to(Hashtable<T, F>* new_table) {
 
   // Initialize the global seed for hashing.
   _seed = AltHashing::compute_seed();
@@ -135,8 +122,8 @@
 
   // Iterate through the table and create a new entry for the new table
   for (int i = 0; i < new_table->table_size(); ++i) {
-    for (HashtableEntry<T>* p = bucket(i); p != NULL; ) {
-      HashtableEntry<T>* next = p->next();
+    for (HashtableEntry<T, F>* p = bucket(i); p != NULL; ) {
+      HashtableEntry<T, F>* next = p->next();
       T string = p->literal();
       // Use alternate hashing algorithm on the symbol in the first table
       unsigned int hashValue = new_hash(string);
@@ -148,7 +135,7 @@
       // walking the hashtable past these entries requires
       // BasicHashtableEntry::make_ptr() call.
       bool keep_shared = p->is_shared();
-      unlink_entry(p);
+      this->unlink_entry(p);
       new_table->add_entry(index, p);
       if (keep_shared) {
         p->set_shared();
@@ -164,16 +151,16 @@
   // for the elements has been used in a new table and is not
   // destroyed.  The memory reuse will benefit resizing the SystemDictionary
   // to avoid a memory allocation spike at safepoint.
-  free_buckets();
+  BasicHashtable<F>::free_buckets();
 }
 
-void BasicHashtable::free_buckets() {
+template <MEMFLAGS F> void BasicHashtable<F>::free_buckets() {
   if (NULL != _buckets) {
     // Don't delete the buckets in the shared space.  They aren't
     // allocated by os::malloc
     if (!UseSharedSpaces ||
         !FileMapInfo::current_info()->is_in_shared_space(_buckets)) {
-       FREE_C_HEAP_ARRAY(HashtableBucket, _buckets);
+       FREE_C_HEAP_ARRAY(HashtableBucket, _buckets, F);
     }
     _buckets = NULL;
   }
@@ -182,13 +169,13 @@
 
 // Reverse the order of elements in the hash buckets.
 
-void BasicHashtable::reverse() {
+template <MEMFLAGS F> void BasicHashtable<F>::reverse() {
 
   for (int i = 0; i < _table_size; ++i) {
-    BasicHashtableEntry* new_list = NULL;
-    BasicHashtableEntry* p = bucket(i);
+    BasicHashtableEntry<F>* new_list = NULL;
+    BasicHashtableEntry<F>* p = bucket(i);
     while (p != NULL) {
-      BasicHashtableEntry* next = p->next();
+      BasicHashtableEntry<F>* next = p->next();
       p->set_next(new_list);
       new_list = p;
       p = next;
@@ -200,7 +187,7 @@
 
 // Copy the table to the shared space.
 
-void BasicHashtable::copy_table(char** top, char* end) {
+template <MEMFLAGS F> void BasicHashtable<F>::copy_table(char** top, char* end) {
 
   // Dump the hash table entries.
 
@@ -209,13 +196,13 @@
 
   int i;
   for (i = 0; i < _table_size; ++i) {
-    for (BasicHashtableEntry** p = _buckets[i].entry_addr();
+    for (BasicHashtableEntry<F>** p = _buckets[i].entry_addr();
                               *p != NULL;
                                p = (*p)->next_addr()) {
       if (*top + entry_size() > end) {
         report_out_of_shared_space(SharedMiscData);
       }
-      *p = (BasicHashtableEntry*)memcpy(*top, *p, entry_size());
+      *p = (BasicHashtableEntry<F>*)memcpy(*top, *p, entry_size());
       *top += entry_size();
     }
   }
@@ -224,7 +211,7 @@
   // Set the shared bit.
 
   for (i = 0; i < _table_size; ++i) {
-    for (BasicHashtableEntry* p = bucket(i); p != NULL; p = p->next()) {
+    for (BasicHashtableEntry<F>* p = bucket(i); p != NULL; p = p->next()) {
       p->set_shared();
     }
   }
@@ -234,15 +221,15 @@
 
 // Reverse the order of elements in the hash buckets.
 
-template <class T> void Hashtable<T>::reverse(void* boundary) {
+template <class T, MEMFLAGS F> void Hashtable<T, F>::reverse(void* boundary) {
 
-  for (int i = 0; i < table_size(); ++i) {
-    HashtableEntry<T>* high_list = NULL;
-    HashtableEntry<T>* low_list = NULL;
-    HashtableEntry<T>* last_low_entry = NULL;
-    HashtableEntry<T>* p = bucket(i);
+  for (int i = 0; i < this->table_size(); ++i) {
+    HashtableEntry<T, F>* high_list = NULL;
+    HashtableEntry<T, F>* low_list = NULL;
+    HashtableEntry<T, F>* last_low_entry = NULL;
+    HashtableEntry<T, F>* p = bucket(i);
     while (p != NULL) {
-      HashtableEntry<T>* next = p->next();
+      HashtableEntry<T, F>* next = p->next();
       if ((void*)p->literal() >= boundary) {
         p->set_next(high_list);
         high_list = p;
@@ -267,8 +254,8 @@
 
 // Dump the hash table buckets.
 
-void BasicHashtable::copy_buckets(char** top, char* end) {
-  intptr_t len = _table_size * sizeof(HashtableBucket);
+template <MEMFLAGS F> void BasicHashtable<F>::copy_buckets(char** top, char* end) {
+  intptr_t len = _table_size * sizeof(HashtableBucket<F>);
   *(intptr_t*)(*top) = len;
   *top += sizeof(intptr_t);
 
@@ -278,18 +265,18 @@
   if (*top + len > end) {
     report_out_of_shared_space(SharedMiscData);
   }
-  _buckets = (HashtableBucket*)memcpy(*top, _buckets, len);
+  _buckets = (HashtableBucket<F>*)memcpy(*top, _buckets, len);
   *top += len;
 }
 
 
 #ifndef PRODUCT
 
-template <class T> void Hashtable<T>::print() {
+template <class T, MEMFLAGS F> void Hashtable<T, F>::print() {
   ResourceMark rm;
 
-  for (int i = 0; i < table_size(); i++) {
-    HashtableEntry<T>* entry = bucket(i);
+  for (int i = 0; i < BasicHashtable<F>::table_size(); i++) {
+    HashtableEntry<T, F>* entry = bucket(i);
     while(entry != NULL) {
       tty->print("%d : ", i);
       entry->literal()->print();
@@ -300,10 +287,10 @@
 }
 
 
-void BasicHashtable::verify() {
+template <MEMFLAGS F> void BasicHashtable<F>::verify() {
   int count = 0;
   for (int i = 0; i < table_size(); i++) {
-    for (BasicHashtableEntry* p = bucket(i); p != NULL; p = p->next()) {
+    for (BasicHashtableEntry<F>* p = bucket(i); p != NULL; p = p->next()) {
       ++count;
     }
   }
@@ -316,7 +303,7 @@
 
 #ifdef ASSERT
 
-void BasicHashtable::verify_lookup_length(double load) {
+template <MEMFLAGS F> void BasicHashtable<F>::verify_lookup_length(double load) {
   if ((double)_lookup_length / (double)_lookup_count > load * 2.0) {
     warning("Performance bug: SystemDictionary lookup_count=%d "
             "lookup_length=%d average=%lf load=%f",
@@ -326,10 +313,22 @@
 }
 
 #endif
-
 // Explicitly instantiate these types
-template class Hashtable<constantPoolOop>;
-template class Hashtable<Symbol*>;
-template class Hashtable<klassOop>;
-template class Hashtable<oop>;
-
+template class Hashtable<constantPoolOop, mtClass>;
+template class Hashtable<Symbol*, mtSymbol>;
+template class Hashtable<klassOop, mtClass>;
+template class Hashtable<oop, mtClass>;
+#ifdef SOLARIS
+template class Hashtable<oop, mtSymbol>;
+#endif
+template class Hashtable<oopDesc*, mtSymbol>;
+template class Hashtable<Symbol*, mtClass>;
+template class HashtableEntry<Symbol*, mtSymbol>;
+template class HashtableEntry<Symbol*, mtClass>;
+template class HashtableEntry<oop, mtSymbol>;
+template class BasicHashtableEntry<mtSymbol>;
+template class BasicHashtableEntry<mtCode>;
+template class BasicHashtable<mtClass>;
+template class BasicHashtable<mtSymbol>;
+template class BasicHashtable<mtCode>;
+template class BasicHashtable<mtInternal>;
diff --git a/hotspot/src/share/vm/utilities/hashtable.hpp b/hotspot/src/share/vm/utilities/hashtable.hpp
index 2926f54..24347c2 100644
--- a/hotspot/src/share/vm/utilities/hashtable.hpp
+++ b/hotspot/src/share/vm/utilities/hashtable.hpp
@@ -40,7 +40,7 @@
 
 
 
-class BasicHashtableEntry : public CHeapObj {
+template <MEMFLAGS F> class BasicHashtableEntry : public CHeapObj<F> {
   friend class VMStructs;
 private:
   unsigned int         _hash;           // 32-bit hash for item
@@ -52,7 +52,7 @@
   // shared entries will not change.  New entries will always be
   // unshared and since pointers are align, bit 0 will always remain 0
   // with no extra effort.
-  BasicHashtableEntry* _next;
+  BasicHashtableEntry<F>* _next;
 
   // Windows IA64 compiler requires subclasses to be able to access these
 protected:
@@ -69,19 +69,19 @@
   void set_hash(unsigned int hash)      { _hash = hash; }
   unsigned int* hash_addr()             { return &_hash; }
 
-  static BasicHashtableEntry* make_ptr(BasicHashtableEntry* p) {
+  static BasicHashtableEntry<F>* make_ptr(BasicHashtableEntry<F>* p) {
     return (BasicHashtableEntry*)((intptr_t)p & -2);
   }
 
-  BasicHashtableEntry* next() const {
+  BasicHashtableEntry<F>* next() const {
     return make_ptr(_next);
   }
 
-  void set_next(BasicHashtableEntry* next) {
+  void set_next(BasicHashtableEntry<F>* next) {
     _next = next;
   }
 
-  BasicHashtableEntry** next_addr() {
+  BasicHashtableEntry<F>** next_addr() {
     return &_next;
   }
 
@@ -90,13 +90,13 @@
   }
 
   void set_shared() {
-    _next = (BasicHashtableEntry*)((intptr_t)_next | 1);
+    _next = (BasicHashtableEntry<F>*)((intptr_t)_next | 1);
   }
 };
 
 
 
-template <class T> class HashtableEntry : public BasicHashtableEntry {
+template <class T, MEMFLAGS F> class HashtableEntry : public BasicHashtableEntry<F> {
   friend class VMStructs;
 private:
   T               _literal;          // ref to item in table.
@@ -108,20 +108,20 @@
   void set_literal(T s)               { _literal = s; }
 
   HashtableEntry* next() const {
-    return (HashtableEntry*)BasicHashtableEntry::next();
+    return (HashtableEntry*)BasicHashtableEntry<F>::next();
   }
   HashtableEntry** next_addr() {
-    return (HashtableEntry**)BasicHashtableEntry::next_addr();
+    return (HashtableEntry**)BasicHashtableEntry<F>::next_addr();
   }
 };
 
 
 
-class HashtableBucket : public CHeapObj {
+template <MEMFLAGS F> class HashtableBucket : public CHeapObj<F> {
   friend class VMStructs;
 private:
   // Instance variable
-  BasicHashtableEntry*       _entry;
+  BasicHashtableEntry<F>*       _entry;
 
 public:
   // Accessing
@@ -129,21 +129,21 @@
 
   // The following methods use order access methods to avoid race
   // conditions in multiprocessor systems.
-  BasicHashtableEntry* get_entry() const;
-  void set_entry(BasicHashtableEntry* l);
+  BasicHashtableEntry<F>* get_entry() const;
+  void set_entry(BasicHashtableEntry<F>* l);
 
   // The following method is not MT-safe and must be done under lock.
-  BasicHashtableEntry** entry_addr()  { return &_entry; }
+  BasicHashtableEntry<F>** entry_addr()  { return &_entry; }
 };
 
 
-class BasicHashtable : public CHeapObj {
+template <MEMFLAGS F> class BasicHashtable : public CHeapObj<F> {
   friend class VMStructs;
 
 public:
   BasicHashtable(int table_size, int entry_size);
   BasicHashtable(int table_size, int entry_size,
-                 HashtableBucket* buckets, int number_of_entries);
+                 HashtableBucket<F>* buckets, int number_of_entries);
 
   // Sharing support.
   void copy_buckets(char** top, char* end);
@@ -162,8 +162,8 @@
 private:
   // Instance variables
   int               _table_size;
-  HashtableBucket*  _buckets;
-  BasicHashtableEntry* _free_list;
+  HashtableBucket<F>*     _buckets;
+  BasicHashtableEntry<F>* _free_list;
   char*             _first_free_entry;
   char*             _end_block;
   int               _entry_size;
@@ -188,20 +188,20 @@
   int entry_size() const { return _entry_size; }
 
   // The following method is MT-safe and may be used with caution.
-  BasicHashtableEntry* bucket(int i);
+  BasicHashtableEntry<F>* bucket(int i);
 
   // The following method is not MT-safe and must be done under lock.
-  BasicHashtableEntry** bucket_addr(int i) { return _buckets[i].entry_addr(); }
+  BasicHashtableEntry<F>** bucket_addr(int i) { return _buckets[i].entry_addr(); }
 
   // Table entry management
-  BasicHashtableEntry* new_entry(unsigned int hashValue);
+  BasicHashtableEntry<F>* new_entry(unsigned int hashValue);
 
   // Check that the table is unbalanced
   bool check_rehash_table(int count);
 
   // Used when moving the entry to another table
   // Clean up links, but do not add to free_list
-  void unlink_entry(BasicHashtableEntry* entry) {
+  void unlink_entry(BasicHashtableEntry<F>* entry) {
     entry->set_next(NULL);
     --_number_of_entries;
   }
@@ -221,11 +221,11 @@
 
 public:
   int table_size() { return _table_size; }
-  void set_entry(int index, BasicHashtableEntry* entry);
+  void set_entry(int index, BasicHashtableEntry<F>* entry);
 
-  void add_entry(int index, BasicHashtableEntry* entry);
+  void add_entry(int index, BasicHashtableEntry<F>* entry);
 
-  void free_entry(BasicHashtableEntry* entry);
+  void free_entry(BasicHashtableEntry<F>* entry);
 
   int number_of_entries() { return _number_of_entries; }
 
@@ -233,16 +233,16 @@
 };
 
 
-template <class T> class Hashtable : public BasicHashtable {
+template <class T, MEMFLAGS F> class Hashtable : public BasicHashtable<F> {
   friend class VMStructs;
 
 public:
   Hashtable(int table_size, int entry_size)
-    : BasicHashtable(table_size, entry_size) { }
+    : BasicHashtable<F>(table_size, entry_size) { }
 
   Hashtable(int table_size, int entry_size,
-                   HashtableBucket* buckets, int number_of_entries)
-    : BasicHashtable(table_size, entry_size, buckets, number_of_entries) { }
+                   HashtableBucket<F>* buckets, int number_of_entries)
+    : BasicHashtable<F>(table_size, entry_size, buckets, number_of_entries) { }
 
   // Debugging
   void print()               PRODUCT_RETURN;
@@ -260,24 +260,24 @@
   }
 
   int index_for(Symbol* name) {
-    return hash_to_index(compute_hash(name));
+    return this->hash_to_index(compute_hash(name));
   }
 
   // Table entry management
-  HashtableEntry<T>* new_entry(unsigned int hashValue, T obj);
+  HashtableEntry<T, F>* new_entry(unsigned int hashValue, T obj);
 
   // The following method is MT-safe and may be used with caution.
-  HashtableEntry<T>* bucket(int i) {
-    return (HashtableEntry<T>*)BasicHashtable::bucket(i);
+  HashtableEntry<T, F>* bucket(int i) {
+    return (HashtableEntry<T, F>*)BasicHashtable<F>::bucket(i);
   }
 
   // The following method is not MT-safe and must be done under lock.
-  HashtableEntry<T>** bucket_addr(int i) {
-    return (HashtableEntry<T>**)BasicHashtable::bucket_addr(i);
+  HashtableEntry<T, F>** bucket_addr(int i) {
+    return (HashtableEntry<T, F>**)BasicHashtable<F>::bucket_addr(i);
   }
 
   // Function to move these elements into the new table.
-  void move_to(Hashtable<T>* new_table);
+  void move_to(Hashtable<T, F>* new_table);
   static bool use_alternate_hashcode()  { return _seed != 0; }
   static jint seed()                    { return _seed; }
 
@@ -291,15 +291,15 @@
 
 //  Verions of hashtable where two handles are used to compute the index.
 
-template <class T> class TwoOopHashtable : public Hashtable<T> {
+template <class T, MEMFLAGS F> class TwoOopHashtable : public Hashtable<T, F> {
   friend class VMStructs;
 protected:
   TwoOopHashtable(int table_size, int entry_size)
-    : Hashtable<T>(table_size, entry_size) {}
+    : Hashtable<T, F>(table_size, entry_size) {}
 
-  TwoOopHashtable(int table_size, int entry_size, HashtableBucket* t,
+  TwoOopHashtable(int table_size, int entry_size, HashtableBucket<F>* t,
                   int number_of_entries)
-    : Hashtable<T>(table_size, entry_size, t, number_of_entries) {}
+    : Hashtable<T, F>(table_size, entry_size, t, number_of_entries) {}
 
 public:
   unsigned int compute_hash(Symbol* name, Handle loader) {
diff --git a/hotspot/src/share/vm/utilities/hashtable.inline.hpp b/hotspot/src/share/vm/utilities/hashtable.inline.hpp
index 6874142..237fa5f 100644
--- a/hotspot/src/share/vm/utilities/hashtable.inline.hpp
+++ b/hotspot/src/share/vm/utilities/hashtable.inline.hpp
@@ -27,6 +27,7 @@
 
 #include "memory/allocation.inline.hpp"
 #include "utilities/hashtable.hpp"
+#include "utilities/dtrace.hpp"
 
 // Inline function definitions for hashtable.hpp.
 
@@ -34,18 +35,18 @@
 
 // Initialize a table.
 
-inline BasicHashtable::BasicHashtable(int table_size, int entry_size) {
+template <MEMFLAGS F> inline BasicHashtable<F>::BasicHashtable(int table_size, int entry_size) {
   // Called on startup, no locking needed
   initialize(table_size, entry_size, 0);
-  _buckets = NEW_C_HEAP_ARRAY(HashtableBucket, table_size);
+  _buckets = NEW_C_HEAP_ARRAY2(HashtableBucket<F>, table_size, F, CURRENT_PC);
   for (int index = 0; index < _table_size; index++) {
     _buckets[index].clear();
   }
 }
 
 
-inline BasicHashtable::BasicHashtable(int table_size, int entry_size,
-                                      HashtableBucket* buckets,
+template <MEMFLAGS F> inline BasicHashtable<F>::BasicHashtable(int table_size, int entry_size,
+                                      HashtableBucket<F>* buckets,
                                       int number_of_entries) {
   // Called on startup, no locking needed
   initialize(table_size, entry_size, number_of_entries);
@@ -53,7 +54,7 @@
 }
 
 
-inline void BasicHashtable::initialize(int table_size, int entry_size,
+template <MEMFLAGS F> inline void BasicHashtable<F>::initialize(int table_size, int entry_size,
                                        int number_of_entries) {
   // Called on startup, no locking needed
   _table_size = table_size;
@@ -70,12 +71,12 @@
 
 
 // The following method is MT-safe and may be used with caution.
-inline BasicHashtableEntry* BasicHashtable::bucket(int i) {
+template <MEMFLAGS F> inline BasicHashtableEntry<F>* BasicHashtable<F>::bucket(int i) {
   return _buckets[i].get_entry();
 }
 
 
-inline void HashtableBucket::set_entry(BasicHashtableEntry* l) {
+template <MEMFLAGS F> inline void HashtableBucket<F>::set_entry(BasicHashtableEntry<F>* l) {
   // Warning: Preserve store ordering.  The SystemDictionary is read
   //          without locks.  The new SystemDictionaryEntry must be
   //          complete before other threads can be allowed to see it
@@ -84,27 +85,27 @@
 }
 
 
-inline BasicHashtableEntry* HashtableBucket::get_entry() const {
+template <MEMFLAGS F> inline BasicHashtableEntry<F>* HashtableBucket<F>::get_entry() const {
   // Warning: Preserve load ordering.  The SystemDictionary is read
   //          without locks.  The new SystemDictionaryEntry must be
   //          complete before other threads can be allowed to see it
   //          via a store to _buckets[index].
-  return (BasicHashtableEntry*) OrderAccess::load_ptr_acquire(&_entry);
+  return (BasicHashtableEntry<F>*) OrderAccess::load_ptr_acquire(&_entry);
 }
 
 
-inline void BasicHashtable::set_entry(int index, BasicHashtableEntry* entry) {
+template <MEMFLAGS F> inline void BasicHashtable<F>::set_entry(int index, BasicHashtableEntry<F>* entry) {
   _buckets[index].set_entry(entry);
 }
 
 
-inline void BasicHashtable::add_entry(int index, BasicHashtableEntry* entry) {
+template <MEMFLAGS F> inline void BasicHashtable<F>::add_entry(int index, BasicHashtableEntry<F>* entry) {
   entry->set_next(bucket(index));
   _buckets[index].set_entry(entry);
   ++_number_of_entries;
 }
 
-inline void BasicHashtable::free_entry(BasicHashtableEntry* entry) {
+template <MEMFLAGS F> inline void BasicHashtable<F>::free_entry(BasicHashtableEntry<F>* entry) {
   entry->set_next(_free_list);
   _free_list = entry;
   --_number_of_entries;
diff --git a/hotspot/src/share/vm/utilities/histogram.cpp b/hotspot/src/share/vm/utilities/histogram.cpp
index ede6817..114d4ac 100644
--- a/hotspot/src/share/vm/utilities/histogram.cpp
+++ b/hotspot/src/share/vm/utilities/histogram.cpp
@@ -69,7 +69,7 @@
 
 Histogram::Histogram(const char* title,int estimatedCount) {
   _title = title;
-  _elements = new (ResourceObj::C_HEAP) GrowableArray<HistogramElement*>(estimatedCount,true);
+  _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<HistogramElement*>(estimatedCount,true);
 }
 
 void Histogram::add_element(HistogramElement* element) {
diff --git a/hotspot/src/share/vm/utilities/histogram.hpp b/hotspot/src/share/vm/utilities/histogram.hpp
index 4eaa3d4..5090aa0 100644
--- a/hotspot/src/share/vm/utilities/histogram.hpp
+++ b/hotspot/src/share/vm/utilities/histogram.hpp
@@ -77,7 +77,7 @@
 
 #ifdef ASSERT
 
-class HistogramElement : public CHeapObj {
+class HistogramElement : public CHeapObj<mtInternal> {
  protected:
   jint _count;
   const char* _name;
@@ -91,7 +91,7 @@
   virtual int compare(HistogramElement* e1,HistogramElement* e2);
 };
 
-class Histogram : public CHeapObj {
+class Histogram : public CHeapObj<mtInternal> {
  protected:
   GrowableArray<HistogramElement*>* _elements;
   GrowableArray<HistogramElement*>* elements() { return _elements; }
diff --git a/hotspot/src/share/vm/utilities/intHisto.cpp b/hotspot/src/share/vm/utilities/intHisto.cpp
index 8476c29..a8508c9 100644
--- a/hotspot/src/share/vm/utilities/intHisto.cpp
+++ b/hotspot/src/share/vm/utilities/intHisto.cpp
@@ -27,7 +27,7 @@
 
 IntHistogram::IntHistogram(int est, int max) : _max(max), _tot(0) {
   assert(0 <= est && est <= max, "Preconditions");
-  _elements = new (ResourceObj::C_HEAP) GrowableArray<int>(est, true);
+  _elements = new (ResourceObj::C_HEAP, mtInternal) GrowableArray<int>(est, true);
   guarantee(_elements != NULL, "alloc failure");
 }
 
diff --git a/hotspot/src/share/vm/utilities/intHisto.hpp b/hotspot/src/share/vm/utilities/intHisto.hpp
index 7c2f4ea..2d5d283 100644
--- a/hotspot/src/share/vm/utilities/intHisto.hpp
+++ b/hotspot/src/share/vm/utilities/intHisto.hpp
@@ -47,7 +47,7 @@
 // relation) to a count.
 
 
-class IntHistogram : public CHeapObj {
+class IntHistogram : public CHeapObj<mtInternal> {
  protected:
   int _max;
   int _tot;
diff --git a/hotspot/src/share/vm/utilities/numberSeq.cpp b/hotspot/src/share/vm/utilities/numberSeq.cpp
index 2cc4185..907c3a1 100644
--- a/hotspot/src/share/vm/utilities/numberSeq.cpp
+++ b/hotspot/src/share/vm/utilities/numberSeq.cpp
@@ -115,24 +115,6 @@
   return true;
 }
 
-NumberSeq::NumberSeq(NumberSeq *total, int n, NumberSeq **parts) {
-  guarantee(check_nums(total, n, parts), "all seq lengths should match");
-  double sum = total->sum();
-  for (int i = 0; i < n; ++i) {
-    if (parts[i] != NULL)
-      sum -= parts[i]->sum();
-  }
-
-  _num = total->num();
-  _sum = sum;
-
-  // we do not calculate these...
-  _sum_of_squares = -1.0;
-  _maximum = -1.0;
-  _davg = -1.0;
-  _dvariance = -1.0;
-}
-
 void NumberSeq::add(double val) {
   AbsSeq::add(val);
 
@@ -151,13 +133,13 @@
 
 TruncatedSeq::TruncatedSeq(int length, double alpha):
   AbsSeq(alpha), _length(length), _next(0) {
-  _sequence = NEW_C_HEAP_ARRAY(double, _length);
+  _sequence = NEW_C_HEAP_ARRAY(double, _length, mtInternal);
   for (int i = 0; i < _length; ++i)
     _sequence[i] = 0.0;
 }
 
 TruncatedSeq::~TruncatedSeq() {
-  FREE_C_HEAP_ARRAY(double, _sequence);
+  FREE_C_HEAP_ARRAY(double, _sequence, mtGC);
 }
 
 void TruncatedSeq::add(double val) {
diff --git a/hotspot/src/share/vm/utilities/numberSeq.hpp b/hotspot/src/share/vm/utilities/numberSeq.hpp
index 358448e..f8f2bc1 100644
--- a/hotspot/src/share/vm/utilities/numberSeq.hpp
+++ b/hotspot/src/share/vm/utilities/numberSeq.hpp
@@ -25,6 +25,8 @@
 #ifndef SHARE_VM_UTILITIES_NUMBERSEQ_HPP
 #define SHARE_VM_UTILITIES_NUMBERSEQ_HPP
 
+#include "memory/allocation.hpp"
+
 /**
  **  This file contains a few classes that represent number sequence,
  **  x1, x2, x3, ..., xN, and can calculate their avg, max, and sd.
@@ -40,7 +42,7 @@
 
 #define DEFAULT_ALPHA_VALUE 0.7
 
-class AbsSeq {
+class AbsSeq: public CHeapObj<mtInternal> {
 private:
   void init(double alpha);
 
@@ -93,7 +95,6 @@
 
 public:
   NumberSeq(double alpha = DEFAULT_ALPHA_VALUE);
-  NumberSeq(NumberSeq* total, int n_parts, NumberSeq** parts);
 
   virtual void add(double val);
   virtual double maximum() const { return _maximum; }
diff --git a/hotspot/src/share/vm/utilities/ostream.cpp b/hotspot/src/share/vm/utilities/ostream.cpp
index 2dc63d0..2b6e2ee 100644
--- a/hotspot/src/share/vm/utilities/ostream.cpp
+++ b/hotspot/src/share/vm/utilities/ostream.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -237,8 +237,9 @@
   return;
 }
 
-void outputStream::indent() {
+outputStream& outputStream::indent() {
   while (_position < _indentation) sp();
+  return *this;
 }
 
 void outputStream::print_jlong(jlong value) {
@@ -251,6 +252,47 @@
   print(os::julong_format_specifier(), value);
 }
 
+/**
+ * This prints out hex data in a 'windbg' or 'xxd' form, where each line is:
+ *   <hex-address>: 8 * <hex-halfword> <ascii translation (optional)>
+ * example:
+ * 0000000: 7f44 4f46 0102 0102 0000 0000 0000 0000  .DOF............
+ * 0000010: 0000 0000 0000 0040 0000 0020 0000 0005  .......@... ....
+ * 0000020: 0000 0000 0000 0040 0000 0000 0000 015d  .......@.......]
+ * ...
+ *
+ * indent is applied to each line.  Ends with a CR.
+ */
+void outputStream::print_data(void* data, size_t len, bool with_ascii) {
+  size_t limit = (len + 16) / 16 * 16;
+  for (size_t i = 0; i < limit; ++i) {
+    if (i % 16 == 0) {
+      indent().print("%07x:", i);
+    }
+    if (i % 2 == 0) {
+      print(" ");
+    }
+    if (i < len) {
+      print("%02x", ((unsigned char*)data)[i]);
+    } else {
+      print("  ");
+    }
+    if ((i + 1) % 16 == 0) {
+      if (with_ascii) {
+        print("  ");
+        for (size_t j = 0; j < 16; ++j) {
+          size_t idx = i + j - 15;
+          if (idx < len) {
+            char c = ((char*)data)[idx];
+            print("%c", c >= 32 && c <= 126 ? c : '.');
+          }
+        }
+      }
+      print_cr("");
+    }
+  }
+}
+
 stringStream::stringStream(size_t initial_size) : outputStream() {
   buffer_length = initial_size;
   buffer        = NEW_RESOURCE_ARRAY(char, buffer_length);
@@ -384,7 +426,7 @@
   if (_file != NULL) {
     if (_need_close) fclose(_file);
     _file      = NULL;
-    FREE_C_HEAP_ARRAY(char, _file_name);
+    FREE_C_HEAP_ARRAY(char, _file_name, mtInternal);
     _file_name = NULL;
   }
 }
@@ -392,7 +434,7 @@
 rotatingFileStream::rotatingFileStream(const char* file_name) {
   _cur_file_num = 0;
   _bytes_writen = 0L;
-  _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10);
+  _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
   jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
   _file = fopen(_file_name, "w");
   _need_close = true;
@@ -401,7 +443,7 @@
 rotatingFileStream::rotatingFileStream(const char* file_name, const char* opentype) {
   _cur_file_num = 0;
   _bytes_writen = 0L;
-  _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10);
+  _file_name = NEW_C_HEAP_ARRAY(char, strlen(file_name)+10, mtInternal);
   jio_snprintf(_file_name, strlen(file_name)+10, "%s.%d", file_name, _cur_file_num);
   _file = fopen(_file_name, opentype);
   _need_close = true;
@@ -524,7 +566,7 @@
   }
 
   // Create big enough buffer.
-  char *buf = NEW_C_HEAP_ARRAY(char, buffer_length);
+  char *buf = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
 
   strcpy(buf, "");
   if (force_directory != NULL) {
@@ -549,7 +591,7 @@
   // %%% Need a MutexLocker?
   const char* log_name = LogFile != NULL ? LogFile : "hotspot.log";
   const char* try_name = make_log_name(log_name, NULL);
-  fileStream* file = new(ResourceObj::C_HEAP) fileStream(try_name);
+  fileStream* file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
   if (!file->is_open()) {
     // Try again to open the file.
     char warnbuf[O_BUFLEN*2];
@@ -557,18 +599,18 @@
                  "Warning:  Cannot open log file: %s\n", try_name);
     // Note:  This feature is for maintainer use only.  No need for L10N.
     jio_print(warnbuf);
-    FREE_C_HEAP_ARRAY(char, try_name);
+    FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
     try_name = make_log_name("hs_pid%p.log", os::get_temp_directory());
     jio_snprintf(warnbuf, sizeof(warnbuf),
                  "Warning:  Forcing option -XX:LogFile=%s\n", try_name);
     jio_print(warnbuf);
     delete file;
-    file = new(ResourceObj::C_HEAP) fileStream(try_name);
-    FREE_C_HEAP_ARRAY(char, try_name);
+    file = new(ResourceObj::C_HEAP, mtInternal) fileStream(try_name);
+    FREE_C_HEAP_ARRAY(char, try_name, mtInternal);
   }
   if (file->is_open()) {
     _log_file = file;
-    xmlStream* xs = new(ResourceObj::C_HEAP) xmlStream(file);
+    xmlStream* xs = new(ResourceObj::C_HEAP, mtInternal) xmlStream(file);
     _outer_xmlStream = xs;
     if (this == tty)  xtty = xs;
     // Write XML header.
@@ -717,7 +759,7 @@
     if (has_log) {
       _log_file->bol();
       // output a hint where this output is coming from:
-      _log_file->print_cr("<writer thread='"INTX_FORMAT"'/>", writer_id);
+      _log_file->print_cr("<writer thread='" UINTX_FORMAT "'/>", writer_id);
     }
     _last_writer = writer_id;
   }
@@ -815,7 +857,7 @@
 
 void ostream_init() {
   if (defaultStream::instance == NULL) {
-    defaultStream::instance = new(ResourceObj::C_HEAP) defaultStream();
+    defaultStream::instance = new(ResourceObj::C_HEAP, mtInternal) defaultStream();
     tty = defaultStream::instance;
 
     // We want to ensure that time stamps in GC logs consider time 0
@@ -833,9 +875,9 @@
   gclog_or_tty = tty; // default to tty
   if (Arguments::gc_log_filename() != NULL) {
     fileStream * gclog  = UseGCLogFileRotation ?
-                          new(ResourceObj::C_HEAP)
+                          new(ResourceObj::C_HEAP, mtInternal)
                              rotatingFileStream(Arguments::gc_log_filename()) :
-                          new(ResourceObj::C_HEAP)
+                          new(ResourceObj::C_HEAP, mtInternal)
                              fileStream(Arguments::gc_log_filename());
     if (gclog->is_open()) {
       // now we update the time stamp of the GC log to be synced up
@@ -940,7 +982,7 @@
 
 bufferedStream::bufferedStream(size_t initial_size, size_t bufmax) : outputStream() {
   buffer_length = initial_size;
-  buffer        = NEW_C_HEAP_ARRAY(char, buffer_length);
+  buffer        = NEW_C_HEAP_ARRAY(char, buffer_length, mtInternal);
   buffer_pos    = 0;
   buffer_fixed  = false;
   buffer_max    = bufmax;
@@ -971,7 +1013,7 @@
       if (end < buffer_length * 2) {
         end = buffer_length * 2;
       }
-      buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end);
+      buffer = REALLOC_C_HEAP_ARRAY(char, buffer, end, mtInternal);
       buffer_length = end;
     }
   }
@@ -989,7 +1031,7 @@
 
 bufferedStream::~bufferedStream() {
   if (!buffer_fixed) {
-    FREE_C_HEAP_ARRAY(char, buffer);
+    FREE_C_HEAP_ARRAY(char, buffer, mtInternal);
   }
 }
 
diff --git a/hotspot/src/share/vm/utilities/ostream.hpp b/hotspot/src/share/vm/utilities/ostream.hpp
index e95f9a1..d6aa904 100644
--- a/hotspot/src/share/vm/utilities/ostream.hpp
+++ b/hotspot/src/share/vm/utilities/ostream.hpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -59,9 +59,11 @@
    outputStream(int width, bool has_time_stamps);
 
    // indentation
-   void indent();
+   outputStream& indent();
    void inc() { _indentation++; };
    void dec() { _indentation--; };
+   void inc(int n) { _indentation += n; };
+   void dec(int n) { _indentation -= n; };
    int  indentation() const    { return _indentation; }
    void set_indentation(int i) { _indentation = i;    }
    void fill_to(int col);
@@ -84,6 +86,7 @@
    void print_raw(const char* str, int len)   { write(str,         len); }
    void print_raw_cr(const char* str)         { write(str, strlen(str)); cr(); }
    void print_raw_cr(const char* str, int len){ write(str,         len); cr(); }
+   void print_data(void* data, size_t len, bool with_ascii);
    void put(char ch);
    void sp(int count = 1);
    void cr();
@@ -122,6 +125,19 @@
 extern outputStream* tty;           // tty output
 extern outputStream* gclog_or_tty;  // stream for gc log if -Xloggc:<f>, or tty
 
+class streamIndentor : public StackObj {
+ private:
+  outputStream* _str;
+  int _amount;
+
+ public:
+  streamIndentor(outputStream* str, int amt = 2) : _str(str), _amount(amt) {
+    _str->inc(_amount);
+  }
+  ~streamIndentor() { _str->dec(_amount); }
+};
+
+
 // advisory locking for the shared tty stream:
 class ttyLocker: StackObj {
   friend class ttyUnlocker;
diff --git a/hotspot/src/share/vm/utilities/stack.hpp b/hotspot/src/share/vm/utilities/stack.hpp
index eedaa72..1cf85a5 100644
--- a/hotspot/src/share/vm/utilities/stack.hpp
+++ b/hotspot/src/share/vm/utilities/stack.hpp
@@ -25,6 +25,7 @@
 #ifndef SHARE_VM_UTILITIES_STACK_HPP
 #define SHARE_VM_UTILITIES_STACK_HPP
 
+#include "memory/allocation.hpp"
 #include "memory/allocation.inline.hpp"
 
 // Class Stack (below) grows and shrinks by linking together "segments" which
@@ -51,11 +52,11 @@
 // implementation in class Stack assumes that alloc() will terminate the process
 // if the allocation fails.
 
-template <class E> class StackIterator;
+template <class E, MEMFLAGS F> class StackIterator;
 
 // StackBase holds common data/methods that don't depend on the element type,
 // factored out to reduce template code duplication.
-class StackBase
+template <MEMFLAGS F> class StackBase
 {
 public:
   size_t segment_size()   const { return _seg_size; } // Elements per segment.
@@ -89,11 +90,11 @@
 #define inline
 #endif // __GNUC__
 
-template <class E>
-class Stack:  public StackBase
+template <class E, MEMFLAGS F>
+class Stack:  public StackBase<F>
 {
 public:
-  friend class StackIterator<E>;
+  friend class StackIterator<E, F>;
 
   // segment_size:    number of items per segment
   // max_cache_size:  maxmium number of *segments* to cache
@@ -103,15 +104,15 @@
                size_t max_cache_size = 4, size_t max_size = 0);
   inline ~Stack() { clear(true); }
 
-  inline bool is_empty() const { return _cur_seg == NULL; }
-  inline bool is_full()  const { return _full_seg_size >= max_size(); }
+  inline bool is_empty() const { return this->_cur_seg == NULL; }
+  inline bool is_full()  const { return this->_full_seg_size >= this->max_size(); }
 
   // Performance sensitive code should use is_empty() instead of size() == 0 and
   // is_full() instead of size() == max_size().  Using a conditional here allows
   // just one var to be updated when pushing/popping elements instead of two;
   // _full_seg_size is updated only when pushing/popping segments.
   inline size_t size() const {
-    return is_empty() ? 0 : _full_seg_size + _cur_seg_size;
+    return is_empty() ? 0 : this->_full_seg_size + this->_cur_seg_size;
   }
 
   inline void push(E elem);
@@ -161,18 +162,18 @@
   E* _cache;      // Segment cache to avoid ping-ponging.
 };
 
-template <class E> class ResourceStack:  public Stack<E>, public ResourceObj
+template <class E, MEMFLAGS F> class ResourceStack:  public Stack<E, F>, public ResourceObj
 {
 public:
   // If this class becomes widely used, it may make sense to save the Thread
   // and use it when allocating segments.
-  ResourceStack(size_t segment_size = Stack<E>::default_segment_size()):
-    Stack<E>(segment_size, max_uintx)
+//  ResourceStack(size_t segment_size = Stack<E, F>::default_segment_size()):
+  ResourceStack(size_t segment_size): Stack<E, F>(segment_size, max_uintx)
     { }
 
   // Set the segment pointers to NULL so the parent dtor does not free them;
   // that must be done by the ResourceMark code.
-  ~ResourceStack() { Stack<E>::reset(true); }
+  ~ResourceStack() { Stack<E, F>::reset(true); }
 
 protected:
   virtual E*   alloc(size_t bytes);
@@ -182,13 +183,13 @@
   void clear(bool clear_cache = false);
 };
 
-template <class E>
+template <class E, MEMFLAGS F>
 class StackIterator: public StackObj
 {
 public:
-  StackIterator(Stack<E>& stack): _stack(stack) { sync(); }
+  StackIterator(Stack<E, F>& stack): _stack(stack) { sync(); }
 
-  Stack<E>& stack() const { return _stack; }
+  Stack<E, F>& stack() const { return _stack; }
 
   bool is_empty() const { return _cur_seg == NULL; }
 
@@ -198,7 +199,7 @@
   void sync(); // Sync the iterator's state to the stack's current state.
 
 private:
-  Stack<E>& _stack;
+  Stack<E, F>& _stack;
   size_t    _cur_seg_size;
   E*        _cur_seg;
   size_t    _full_seg_size;
diff --git a/hotspot/src/share/vm/utilities/stack.inline.hpp b/hotspot/src/share/vm/utilities/stack.inline.hpp
index bb97fc9..f53fd3c 100644
--- a/hotspot/src/share/vm/utilities/stack.inline.hpp
+++ b/hotspot/src/share/vm/utilities/stack.inline.hpp
@@ -27,7 +27,7 @@
 
 #include "utilities/stack.hpp"
 
-StackBase::StackBase(size_t segment_size, size_t max_cache_size,
+template <MEMFLAGS F> StackBase<F>::StackBase(size_t segment_size, size_t max_cache_size,
                      size_t max_size):
   _seg_size(segment_size),
   _max_cache_size(max_cache_size),
@@ -36,7 +36,7 @@
   assert(_max_size % _seg_size == 0, "not a multiple");
 }
 
-size_t StackBase::adjust_max_size(size_t max_size, size_t seg_size)
+template <MEMFLAGS F> size_t StackBase<F>::adjust_max_size(size_t max_size, size_t seg_size)
 {
   assert(seg_size > 0, "cannot be 0");
   assert(max_size >= seg_size || max_size == 0, "max_size too small");
@@ -47,54 +47,54 @@
   return (max_size + seg_size - 1) / seg_size * seg_size;
 }
 
-template <class E>
-Stack<E>::Stack(size_t segment_size, size_t max_cache_size, size_t max_size):
-  StackBase(adjust_segment_size(segment_size), max_cache_size, max_size)
+template <class E, MEMFLAGS F>
+Stack<E, F>::Stack(size_t segment_size, size_t max_cache_size, size_t max_size):
+  StackBase<F>(adjust_segment_size(segment_size), max_cache_size, max_size)
 {
   reset(true);
 }
 
-template <class E>
-void Stack<E>::push(E item)
+template <class E, MEMFLAGS F>
+void Stack<E, F>::push(E item)
 {
   assert(!is_full(), "pushing onto a full stack");
-  if (_cur_seg_size == _seg_size) {
+  if (this->_cur_seg_size == this->_seg_size) {
     push_segment();
   }
-  _cur_seg[_cur_seg_size] = item;
-  ++_cur_seg_size;
+  this->_cur_seg[this->_cur_seg_size] = item;
+  ++this->_cur_seg_size;
 }
 
-template <class E>
-E Stack<E>::pop()
+template <class E, MEMFLAGS F>
+E Stack<E, F>::pop()
 {
   assert(!is_empty(), "popping from an empty stack");
-  if (_cur_seg_size == 1) {
-    E tmp = _cur_seg[--_cur_seg_size];
+  if (this->_cur_seg_size == 1) {
+    E tmp = _cur_seg[--this->_cur_seg_size];
     pop_segment();
     return tmp;
   }
-  return _cur_seg[--_cur_seg_size];
+  return this->_cur_seg[--this->_cur_seg_size];
 }
 
-template <class E>
-void Stack<E>::clear(bool clear_cache)
+template <class E, MEMFLAGS F>
+void Stack<E, F>::clear(bool clear_cache)
 {
   free_segments(_cur_seg);
   if (clear_cache) free_segments(_cache);
   reset(clear_cache);
 }
 
-template <class E>
-size_t Stack<E>::default_segment_size()
+template <class E, MEMFLAGS F>
+size_t Stack<E, F>::default_segment_size()
 {
   // Number of elements that fit in 4K bytes minus the size of two pointers
   // (link field and malloc header).
   return (4096 - 2 * sizeof(E*)) / sizeof(E);
 }
 
-template <class E>
-size_t Stack<E>::adjust_segment_size(size_t seg_size)
+template <class E, MEMFLAGS F>
+size_t Stack<E, F>::adjust_segment_size(size_t seg_size)
 {
   const size_t elem_sz = sizeof(E);
   const size_t ptr_sz = sizeof(E*);
@@ -105,93 +105,93 @@
   return seg_size;
 }
 
-template <class E>
-size_t Stack<E>::link_offset() const
+template <class E, MEMFLAGS F>
+size_t Stack<E, F>::link_offset() const
 {
-  return align_size_up(_seg_size * sizeof(E), sizeof(E*));
+  return align_size_up(this->_seg_size * sizeof(E), sizeof(E*));
 }
 
-template <class E>
-size_t Stack<E>::segment_bytes() const
+template <class E, MEMFLAGS F>
+size_t Stack<E, F>::segment_bytes() const
 {
   return link_offset() + sizeof(E*);
 }
 
-template <class E>
-E** Stack<E>::link_addr(E* seg) const
+template <class E, MEMFLAGS F>
+E** Stack<E, F>::link_addr(E* seg) const
 {
   return (E**) ((char*)seg + link_offset());
 }
 
-template <class E>
-E* Stack<E>::get_link(E* seg) const
+template <class E, MEMFLAGS F>
+E* Stack<E, F>::get_link(E* seg) const
 {
   return *link_addr(seg);
 }
 
-template <class E>
-E* Stack<E>::set_link(E* new_seg, E* old_seg)
+template <class E, MEMFLAGS F>
+E* Stack<E, F>::set_link(E* new_seg, E* old_seg)
 {
   *link_addr(new_seg) = old_seg;
   return new_seg;
 }
 
-template <class E>
-E* Stack<E>::alloc(size_t bytes)
+template <class E, MEMFLAGS F>
+E* Stack<E, F>::alloc(size_t bytes)
 {
-  return (E*) NEW_C_HEAP_ARRAY(char, bytes);
+  return (E*) NEW_C_HEAP_ARRAY(char, bytes, F);
 }
 
-template <class E>
-void Stack<E>::free(E* addr, size_t bytes)
+template <class E, MEMFLAGS F>
+void Stack<E, F>::free(E* addr, size_t bytes)
 {
-  FREE_C_HEAP_ARRAY(char, (char*) addr);
+  FREE_C_HEAP_ARRAY(char, (char*) addr, F);
 }
 
-template <class E>
-void Stack<E>::push_segment()
+template <class E, MEMFLAGS F>
+void Stack<E, F>::push_segment()
 {
-  assert(_cur_seg_size == _seg_size, "current segment is not full");
+  assert(this->_cur_seg_size == this->_seg_size, "current segment is not full");
   E* next;
-  if (_cache_size > 0) {
+  if (this->_cache_size > 0) {
     // Use a cached segment.
     next = _cache;
     _cache = get_link(_cache);
-    --_cache_size;
+    --this->_cache_size;
   } else {
     next = alloc(segment_bytes());
     DEBUG_ONLY(zap_segment(next, true);)
   }
   const bool at_empty_transition = is_empty();
-  _cur_seg = set_link(next, _cur_seg);
-  _cur_seg_size = 0;
-  _full_seg_size += at_empty_transition ? 0 : _seg_size;
+  this->_cur_seg = set_link(next, _cur_seg);
+  this->_cur_seg_size = 0;
+  this->_full_seg_size += at_empty_transition ? 0 : this->_seg_size;
   DEBUG_ONLY(verify(at_empty_transition);)
 }
 
-template <class E>
-void Stack<E>::pop_segment()
+template <class E, MEMFLAGS F>
+void Stack<E, F>::pop_segment()
 {
-  assert(_cur_seg_size == 0, "current segment is not empty");
+  assert(this->_cur_seg_size == 0, "current segment is not empty");
   E* const prev = get_link(_cur_seg);
-  if (_cache_size < _max_cache_size) {
+  if (this->_cache_size < this->_max_cache_size) {
     // Add the current segment to the cache.
     DEBUG_ONLY(zap_segment(_cur_seg, false);)
     _cache = set_link(_cur_seg, _cache);
-    ++_cache_size;
+    ++this->_cache_size;
   } else {
     DEBUG_ONLY(zap_segment(_cur_seg, true);)
     free(_cur_seg, segment_bytes());
   }
   const bool at_empty_transition = prev == NULL;
-  _cur_seg = prev;
-  _cur_seg_size = _seg_size;
-  _full_seg_size -= at_empty_transition ? 0 : _seg_size;
+  this->_cur_seg = prev;
+  this->_cur_seg_size = this->_seg_size;
+  this->_full_seg_size -= at_empty_transition ? 0 : this->_seg_size;
   DEBUG_ONLY(verify(at_empty_transition);)
 }
 
-template <class E>
-void Stack<E>::free_segments(E* seg)
+template <class E, MEMFLAGS F>
+void Stack<E, F>::free_segments(E* seg)
 {
   const size_t bytes = segment_bytes();
   while (seg != NULL) {
@@ -201,37 +201,37 @@
   }
 }
 
-template <class E>
-void Stack<E>::reset(bool reset_cache)
+template <class E, MEMFLAGS F>
+void Stack<E, F>::reset(bool reset_cache)
 {
-  _cur_seg_size = _seg_size; // So push() will alloc a new segment.
-  _full_seg_size = 0;
+  this->_cur_seg_size = this->_seg_size; // So push() will alloc a new segment.
+  this->_full_seg_size = 0;
   _cur_seg = NULL;
   if (reset_cache) {
-    _cache_size = 0;
+    this->_cache_size = 0;
     _cache = NULL;
   }
 }
 
 #ifdef ASSERT
-template <class E>
-void Stack<E>::verify(bool at_empty_transition) const
+template <class E, MEMFLAGS F>
+void Stack<E, F>::verify(bool at_empty_transition) const
 {
-  assert(size() <= max_size(), "stack exceeded bounds");
-  assert(cache_size() <= max_cache_size(), "cache exceeded bounds");
-  assert(_cur_seg_size <= segment_size(), "segment index exceeded bounds");
+  assert(size() <= this->max_size(), "stack exceeded bounds");
+  assert(this->cache_size() <= this->max_cache_size(), "cache exceeded bounds");
+  assert(this->_cur_seg_size <= this->segment_size(), "segment index exceeded bounds");
 
-  assert(_full_seg_size % _seg_size == 0, "not a multiple");
+  assert(this->_full_seg_size % this->_seg_size == 0, "not a multiple");
   assert(at_empty_transition || is_empty() == (size() == 0), "mismatch");
-  assert((_cache == NULL) == (cache_size() == 0), "mismatch");
+  assert((_cache == NULL) == (this->cache_size() == 0), "mismatch");
 
   if (is_empty()) {
-    assert(_cur_seg_size == segment_size(), "sanity");
+    assert(this->_cur_seg_size == this->segment_size(), "sanity");
   }
 }
 
-template <class E>
-void Stack<E>::zap_segment(E* seg, bool zap_link_field) const
+template <class E, MEMFLAGS F>
+void Stack<E, F>::zap_segment(E* seg, bool zap_link_field) const
 {
   if (!ZapStackSegments) return;
   const size_t zap_bytes = segment_bytes() - (zap_link_field ? 0 : sizeof(E*));
@@ -243,28 +243,28 @@
 }
 #endif
 
-template <class E>
-E* ResourceStack<E>::alloc(size_t bytes)
+template <class E, MEMFLAGS F>
+E* ResourceStack<E, F>::alloc(size_t bytes)
 {
   return (E*) resource_allocate_bytes(bytes);
 }
 
-template <class E>
-void ResourceStack<E>::free(E* addr, size_t bytes)
+template <class E, MEMFLAGS F>
+void ResourceStack<E, F>::free(E* addr, size_t bytes)
 {
   resource_free_bytes((char*) addr, bytes);
 }
 
-template <class E>
-void StackIterator<E>::sync()
+template <class E, MEMFLAGS F>
+void StackIterator<E, F>::sync()
 {
   _full_seg_size = _stack._full_seg_size;
   _cur_seg_size = _stack._cur_seg_size;
   _cur_seg = _stack._cur_seg;
 }
 
-template <class E>
-E* StackIterator<E>::next_addr()
+template <class E, MEMFLAGS F>
+E* StackIterator<E, F>::next_addr()
 {
   assert(!is_empty(), "no items left");
   if (_cur_seg_size == 1) {
diff --git a/hotspot/src/share/vm/utilities/taskqueue.hpp b/hotspot/src/share/vm/utilities/taskqueue.hpp
index 545c6db..9d67af4 100644
--- a/hotspot/src/share/vm/utilities/taskqueue.hpp
+++ b/hotspot/src/share/vm/utilities/taskqueue.hpp
@@ -132,8 +132,8 @@
 }
 #endif // TASKQUEUE_STATS
 
-template <unsigned int N>
-class TaskQueueSuper: public CHeapObj {
+template <unsigned int N, MEMFLAGS F>
+class TaskQueueSuper: public CHeapObj<F> {
 protected:
   // Internal type for indexing the queue; also used for the tag.
   typedef NOT_LP64(uint16_t) LP64_ONLY(uint32_t) idx_t;
@@ -249,22 +249,27 @@
   TASKQUEUE_STATS_ONLY(TaskQueueStats stats;)
 };
 
-template<class E, unsigned int N = TASKQUEUE_SIZE>
-class GenericTaskQueue: public TaskQueueSuper<N> {
-protected:
-  typedef typename TaskQueueSuper<N>::Age Age;
-  typedef typename TaskQueueSuper<N>::idx_t idx_t;
 
-  using TaskQueueSuper<N>::_bottom;
-  using TaskQueueSuper<N>::_age;
-  using TaskQueueSuper<N>::increment_index;
-  using TaskQueueSuper<N>::decrement_index;
-  using TaskQueueSuper<N>::dirty_size;
+
+template <class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
+class GenericTaskQueue: public TaskQueueSuper<N, F> {
+protected:
+  typedef typename TaskQueueSuper<N, F>::Age Age;
+  typedef typename TaskQueueSuper<N, F>::idx_t idx_t;
+
+  using TaskQueueSuper<N, F>::_bottom;
+  using TaskQueueSuper<N, F>::_age;
+  using TaskQueueSuper<N, F>::increment_index;
+  using TaskQueueSuper<N, F>::decrement_index;
+  using TaskQueueSuper<N, F>::dirty_size;
 
 public:
-  using TaskQueueSuper<N>::max_elems;
-  using TaskQueueSuper<N>::size;
-  TASKQUEUE_STATS_ONLY(using TaskQueueSuper<N>::stats;)
+  using TaskQueueSuper<N, F>::max_elems;
+  using TaskQueueSuper<N, F>::size;
+
+#if  TASKQUEUE_STATS
+  using TaskQueueSuper<N, F>::stats;
+#endif
 
 private:
   // Slow paths for push, pop_local.  (pop_global has no fast path.)
@@ -302,18 +307,18 @@
   volatile E* _elems;
 };
 
-template<class E, unsigned int N>
-GenericTaskQueue<E, N>::GenericTaskQueue() {
+template<class E, MEMFLAGS F, unsigned int N>
+GenericTaskQueue<E, F, N>::GenericTaskQueue() {
   assert(sizeof(Age) == sizeof(size_t), "Depends on this.");
 }
 
-template<class E, unsigned int N>
-void GenericTaskQueue<E, N>::initialize() {
-  _elems = NEW_C_HEAP_ARRAY(E, N);
+template<class E, MEMFLAGS F, unsigned int N>
+void GenericTaskQueue<E, F, N>::initialize() {
+  _elems = NEW_C_HEAP_ARRAY(E, N, F);
 }
 
-template<class E, unsigned int N>
-void GenericTaskQueue<E, N>::oops_do(OopClosure* f) {
+template<class E, MEMFLAGS F, unsigned int N>
+void GenericTaskQueue<E, F, N>::oops_do(OopClosure* f) {
   // tty->print_cr("START OopTaskQueue::oops_do");
   uint iters = size();
   uint index = _bottom;
@@ -329,8 +334,8 @@
   // tty->print_cr("END OopTaskQueue::oops_do");
 }
 
-template<class E, unsigned int N>
-bool GenericTaskQueue<E, N>::push_slow(E t, uint dirty_n_elems) {
+template<class E, MEMFLAGS F, unsigned int N>
+bool GenericTaskQueue<E, F, N>::push_slow(E t, uint dirty_n_elems) {
   if (dirty_n_elems == N - 1) {
     // Actually means 0, so do the push.
     uint localBot = _bottom;
@@ -349,8 +354,8 @@
 // whenever the queue goes empty which it will do here if this thread
 // gets the last task or in pop_global() if the queue wraps (top == 0
 // and pop_global() succeeds, see pop_global()).
-template<class E, unsigned int N>
-bool GenericTaskQueue<E, N>::pop_local_slow(uint localBot, Age oldAge) {
+template<class E, MEMFLAGS F, unsigned int N>
+bool GenericTaskQueue<E, F, N>::pop_local_slow(uint localBot, Age oldAge) {
   // This queue was observed to contain exactly one element; either this
   // thread will claim it, or a competing "pop_global".  In either case,
   // the queue will be logically empty afterwards.  Create a new Age value
@@ -382,8 +387,8 @@
   return false;
 }
 
-template<class E, unsigned int N>
-bool GenericTaskQueue<E, N>::pop_global(E& t) {
+template<class E, MEMFLAGS F, unsigned int N>
+bool GenericTaskQueue<E, F, N>::pop_global(E& t) {
   Age oldAge = _age.get();
   uint localBot = _bottom;
   uint n_elems = size(localBot, oldAge.top());
@@ -402,9 +407,9 @@
   return resAge == oldAge;
 }
 
-template<class E, unsigned int N>
-GenericTaskQueue<E, N>::~GenericTaskQueue() {
-  FREE_C_HEAP_ARRAY(E, _elems);
+template<class E, MEMFLAGS F, unsigned int N>
+GenericTaskQueue<E, F, N>::~GenericTaskQueue() {
+  FREE_C_HEAP_ARRAY(E, _elems, F);
 }
 
 // OverflowTaskQueue is a TaskQueue that also includes an overflow stack for
@@ -418,12 +423,12 @@
 // Note that size() is not hidden--it returns the number of elements in the
 // TaskQueue, and does not include the size of the overflow stack.  This
 // simplifies replacement of GenericTaskQueues with OverflowTaskQueues.
-template<class E, unsigned int N = TASKQUEUE_SIZE>
-class OverflowTaskQueue: public GenericTaskQueue<E, N>
+template<class E, MEMFLAGS F, unsigned int N = TASKQUEUE_SIZE>
+class OverflowTaskQueue: public GenericTaskQueue<E, F, N>
 {
 public:
-  typedef Stack<E>               overflow_t;
-  typedef GenericTaskQueue<E, N> taskqueue_t;
+  typedef Stack<E, F>               overflow_t;
+  typedef GenericTaskQueue<E, F, N> taskqueue_t;
 
   TASKQUEUE_STATS_ONLY(using taskqueue_t::stats;)
 
@@ -445,8 +450,8 @@
   overflow_t _overflow_stack;
 };
 
-template <class E, unsigned int N>
-bool OverflowTaskQueue<E, N>::push(E t)
+template <class E, MEMFLAGS F, unsigned int N>
+bool OverflowTaskQueue<E, F, N>::push(E t)
 {
   if (!taskqueue_t::push(t)) {
     overflow_stack()->push(t);
@@ -455,15 +460,15 @@
   return true;
 }
 
-template <class E, unsigned int N>
-bool OverflowTaskQueue<E, N>::pop_overflow(E& t)
+template <class E, MEMFLAGS F, unsigned int N>
+bool OverflowTaskQueue<E, F, N>::pop_overflow(E& t)
 {
   if (overflow_empty()) return false;
   t = overflow_stack()->pop();
   return true;
 }
 
-class TaskQueueSetSuper: public CHeapObj {
+class TaskQueueSetSuper {
 protected:
   static int randomParkAndMiller(int* seed0);
 public:
@@ -471,8 +476,11 @@
   virtual bool peek() = 0;
 };
 
-template<class T>
-class GenericTaskQueueSet: public TaskQueueSetSuper {
+template <MEMFLAGS F> class TaskQueueSetSuperImpl: public CHeapObj<F>, public TaskQueueSetSuper {
+};
+
+template<class T, MEMFLAGS F>
+class GenericTaskQueueSet: public TaskQueueSetSuperImpl<F> {
 private:
   uint _n;
   T** _queues;
@@ -482,7 +490,7 @@
 
   GenericTaskQueueSet(int n) : _n(n) {
     typedef T* GenericTaskQueuePtr;
-    _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n);
+    _queues = NEW_C_HEAP_ARRAY(GenericTaskQueuePtr, n, F);
     for (int i = 0; i < n; i++) {
       _queues[i] = NULL;
     }
@@ -506,19 +514,19 @@
   bool peek();
 };
 
-template<class T> void
-GenericTaskQueueSet<T>::register_queue(uint i, T* q) {
+template<class T, MEMFLAGS F> void
+GenericTaskQueueSet<T, F>::register_queue(uint i, T* q) {
   assert(i < _n, "index out of range.");
   _queues[i] = q;
 }
 
-template<class T> T*
-GenericTaskQueueSet<T>::queue(uint i) {
+template<class T, MEMFLAGS F> T*
+GenericTaskQueueSet<T, F>::queue(uint i) {
   return _queues[i];
 }
 
-template<class T> bool
-GenericTaskQueueSet<T>::steal(uint queue_num, int* seed, E& t) {
+template<class T, MEMFLAGS F> bool
+GenericTaskQueueSet<T, F>::steal(uint queue_num, int* seed, E& t) {
   for (uint i = 0; i < 2 * _n; i++) {
     if (steal_best_of_2(queue_num, seed, t)) {
       TASKQUEUE_STATS_ONLY(queue(queue_num)->stats.record_steal(true));
@@ -529,8 +537,8 @@
   return false;
 }
 
-template<class T> bool
-GenericTaskQueueSet<T>::steal_best_of_all(uint queue_num, int* seed, E& t) {
+template<class T, MEMFLAGS F> bool
+GenericTaskQueueSet<T, F>::steal_best_of_all(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
     int best_k;
     uint best_sz = 0;
@@ -553,11 +561,11 @@
   }
 }
 
-template<class T> bool
-GenericTaskQueueSet<T>::steal_1_random(uint queue_num, int* seed, E& t) {
+template<class T, MEMFLAGS F> bool
+GenericTaskQueueSet<T, F>::steal_1_random(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
     uint k = queue_num;
-    while (k == queue_num) k = randomParkAndMiller(seed) % _n;
+    while (k == queue_num) k = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
     return _queues[2]->pop_global(t);
   } else if (_n == 2) {
     // Just try the other one.
@@ -569,13 +577,13 @@
   }
 }
 
-template<class T> bool
-GenericTaskQueueSet<T>::steal_best_of_2(uint queue_num, int* seed, E& t) {
+template<class T, MEMFLAGS F> bool
+GenericTaskQueueSet<T, F>::steal_best_of_2(uint queue_num, int* seed, E& t) {
   if (_n > 2) {
     uint k1 = queue_num;
-    while (k1 == queue_num) k1 = randomParkAndMiller(seed) % _n;
+    while (k1 == queue_num) k1 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
     uint k2 = queue_num;
-    while (k2 == queue_num || k2 == k1) k2 = randomParkAndMiller(seed) % _n;
+    while (k2 == queue_num || k2 == k1) k2 = TaskQueueSetSuper::randomParkAndMiller(seed) % _n;
     // Sample both and try the larger.
     uint sz1 = _queues[k1]->size();
     uint sz2 = _queues[k2]->size();
@@ -591,8 +599,8 @@
   }
 }
 
-template<class T>
-bool GenericTaskQueueSet<T>::peek() {
+template<class T, MEMFLAGS F>
+bool GenericTaskQueueSet<T, F>::peek() {
   // Try all the queues.
   for (uint j = 0; j < _n; j++) {
     if (_queues[j]->peek())
@@ -602,7 +610,7 @@
 }
 
 // When to terminate from the termination protocol.
-class TerminatorTerminator: public CHeapObj {
+class TerminatorTerminator: public CHeapObj<mtInternal> {
 public:
   virtual bool should_exit_termination() = 0;
 };
@@ -665,8 +673,8 @@
 #endif
 };
 
-template<class E, unsigned int N> inline bool
-GenericTaskQueue<E, N>::push(E t) {
+template<class E, MEMFLAGS F, unsigned int N> inline bool
+GenericTaskQueue<E, F, N>::push(E t) {
   uint localBot = _bottom;
   assert((localBot >= 0) && (localBot < N), "_bottom out of range.");
   idx_t top = _age.top();
@@ -683,8 +691,8 @@
   }
 }
 
-template<class E, unsigned int N> inline bool
-GenericTaskQueue<E, N>::pop_local(E& t) {
+template<class E, MEMFLAGS F, unsigned int N> inline bool
+GenericTaskQueue<E, F, N>::pop_local(E& t) {
   uint localBot = _bottom;
   // This value cannot be N-1.  That can only occur as a result of
   // the assignment to bottom in this method.  If it does, this method
@@ -715,8 +723,8 @@
   }
 }
 
-typedef GenericTaskQueue<oop>             OopTaskQueue;
-typedef GenericTaskQueueSet<OopTaskQueue> OopTaskQueueSet;
+typedef GenericTaskQueue<oop, mtGC>             OopTaskQueue;
+typedef GenericTaskQueueSet<OopTaskQueue, mtGC> OopTaskQueueSet;
 
 #ifdef _MSC_VER
 #pragma warning(push)
@@ -796,11 +804,11 @@
 #pragma warning(pop)
 #endif
 
-typedef OverflowTaskQueue<StarTask>           OopStarTaskQueue;
-typedef GenericTaskQueueSet<OopStarTaskQueue> OopStarTaskQueueSet;
+typedef OverflowTaskQueue<StarTask, mtClass>           OopStarTaskQueue;
+typedef GenericTaskQueueSet<OopStarTaskQueue, mtClass> OopStarTaskQueueSet;
 
-typedef OverflowTaskQueue<size_t>             RegionTaskQueue;
-typedef GenericTaskQueueSet<RegionTaskQueue>  RegionTaskQueueSet;
+typedef OverflowTaskQueue<size_t, mtInternal>             RegionTaskQueue;
+typedef GenericTaskQueueSet<RegionTaskQueue, mtClass>     RegionTaskQueueSet;
 
 
 #endif // SHARE_VM_UTILITIES_TASKQUEUE_HPP
diff --git a/hotspot/src/share/vm/utilities/vmError.cpp b/hotspot/src/share/vm/utilities/vmError.cpp
index c90e02f..175fe38 100644
--- a/hotspot/src/share/vm/utilities/vmError.cpp
+++ b/hotspot/src/share/vm/utilities/vmError.cpp
@@ -25,6 +25,7 @@
 #include "precompiled.hpp"
 #include "compiler/compileBroker.hpp"
 #include "gc_interface/collectedHeap.hpp"
+#include "prims/whitebox.hpp"
 #include "runtime/arguments.hpp"
 #include "runtime/frame.inline.hpp"
 #include "runtime/init.hpp"
@@ -32,6 +33,7 @@
 #include "runtime/thread.hpp"
 #include "runtime/vmThread.hpp"
 #include "runtime/vm_operations.hpp"
+#include "services/memTracker.hpp"
 #include "utilities/debug.hpp"
 #include "utilities/decoder.hpp"
 #include "utilities/defaultStream.hpp"
@@ -449,7 +451,11 @@
      // VM version
      st->print_cr("#");
      JDK_Version::current().to_string(buf, sizeof(buf));
-     st->print_cr("# JRE version: %s", buf);
+     const char* runtime_name = JDK_Version::runtime_name() != NULL ?
+                                  JDK_Version::runtime_name() : "";
+     const char* runtime_version = JDK_Version::runtime_version() != NULL ?
+                                  JDK_Version::runtime_version() : "";
+     st->print_cr("# JRE version: %s (%s) (build %s)", runtime_name, buf, runtime_version);
      st->print_cr("# Java VM: %s (%s %s %s %s)",
                    Abstract_VM_Version::vm_name(),
                    Abstract_VM_Version::vm_release(),
@@ -723,6 +729,13 @@
        st->cr();
      }
 
+  STEP(215, "(printing warning if internal testing API used)" )
+
+     if (WhiteBox::used()) {
+       st->print_cr("Unsupported internal testing APIs have been used.");
+       st->cr();
+     }
+
   STEP(220, "(printing environment variables)" )
 
      if (_verbose) {
@@ -810,6 +823,9 @@
   static bool transmit_report_done = false; // done error reporting
   static fdStream log;                  // error log
 
+  // disble NMT to avoid further exception
+  MemTracker::shutdown(MemTracker::NMT_error_reporting);
+
   if (SuppressFatalErrorMessage) {
       os::abort();
   }
diff --git a/hotspot/src/share/vm/utilities/workgroup.cpp b/hotspot/src/share/vm/utilities/workgroup.cpp
index 0ef1f83..4952058 100644
--- a/hotspot/src/share/vm/utilities/workgroup.cpp
+++ b/hotspot/src/share/vm/utilities/workgroup.cpp
@@ -77,7 +77,7 @@
                   name(),
                   total_workers());
   }
-  _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, total_workers());
+  _gang_workers = NEW_C_HEAP_ARRAY(GangWorker*, total_workers(), mtInternal);
   if (gang_workers() == NULL) {
     vm_exit_out_of_memory(0, "Cannot create GangWorker array.");
     return false;
@@ -241,6 +241,7 @@
 
 void GangWorker::initialize() {
   this->initialize_thread_local_storage();
+  this->record_stack_base_and_size();
   assert(_gang != NULL, "No gang to run in");
   os::set_priority(this, NearMaxPriority);
   if (TraceWorkGang) {
@@ -421,7 +422,7 @@
 
 SubTasksDone::SubTasksDone(uint n) :
   _n_tasks(n), _n_threads(1), _tasks(NULL) {
-  _tasks = NEW_C_HEAP_ARRAY(uint, n);
+  _tasks = NEW_C_HEAP_ARRAY(uint, n, mtInternal);
   guarantee(_tasks != NULL, "alloc failure");
   clear();
 }
@@ -476,7 +477,7 @@
 
 
 SubTasksDone::~SubTasksDone() {
-  if (_tasks != NULL) FREE_C_HEAP_ARRAY(jint, _tasks);
+  if (_tasks != NULL) FREE_C_HEAP_ARRAY(jint, _tasks, mtInternal);
 }
 
 // *** SequentialSubTasksDone
diff --git a/hotspot/src/share/vm/utilities/workgroup.hpp b/hotspot/src/share/vm/utilities/workgroup.hpp
index 7fc0ddf..9bd34e6b 100644
--- a/hotspot/src/share/vm/utilities/workgroup.hpp
+++ b/hotspot/src/share/vm/utilities/workgroup.hpp
@@ -123,7 +123,7 @@
 // Class AbstractWorkGang:
 // An abstract class representing a gang of workers.
 // You subclass this to supply an implementation of run_task().
-class AbstractWorkGang: public CHeapObj {
+class AbstractWorkGang: public CHeapObj<mtInternal> {
   // Here's the public interface to this class.
 public:
   // Constructor and destructor.
@@ -402,7 +402,7 @@
 // subtasks will be identified by integer indices, usually elements of an
 // enumeration type.
 
-class SubTasksDone : public CHeapObj {
+class SubTasksDone: public CHeapObj<mtInternal> {
   uint* _tasks;
   uint _n_tasks;
   // _n_threads is used to determine when a sub task is done.
diff --git a/hotspot/src/share/vm/utilities/xmlstream.cpp b/hotspot/src/share/vm/utilities/xmlstream.cpp
index 8646c30..2753b85 100644
--- a/hotspot/src/share/vm/utilities/xmlstream.cpp
+++ b/hotspot/src/share/vm/utilities/xmlstream.cpp
@@ -43,7 +43,7 @@
 #ifdef ASSERT
   _element_depth = 0;
   int   init_len = 100;
-  char* init_buf = NEW_C_HEAP_ARRAY(char, init_len);
+  char* init_buf = NEW_C_HEAP_ARRAY(char, init_len, mtInternal);
   _element_close_stack_low  = init_buf;
   _element_close_stack_high = init_buf + init_len;
   _element_close_stack_ptr  = init_buf + init_len - 1;
@@ -58,7 +58,7 @@
 
 #ifdef ASSERT
 xmlStream::~xmlStream() {
-  FREE_C_HEAP_ARRAY(char, _element_close_stack_low);
+  FREE_C_HEAP_ARRAY(char, _element_close_stack_low, mtInternal);
 }
 #endif
 
@@ -155,14 +155,14 @@
     int old_len = _element_close_stack_high - old_ptr;
     int new_len = old_len * 2;
     if (new_len < 100)  new_len = 100;
-    char* new_low  = NEW_C_HEAP_ARRAY(char, new_len);
+    char* new_low  = NEW_C_HEAP_ARRAY(char, new_len, mtInternal);
     char* new_high = new_low + new_len;
     char* new_ptr  = new_high - old_len;
     memcpy(new_ptr, old_ptr, old_len);
     _element_close_stack_high = new_high;
     _element_close_stack_low  = new_low;
     _element_close_stack_ptr  = new_ptr;
-    FREE_C_HEAP_ARRAY(char, old_low);
+    FREE_C_HEAP_ARRAY(char, old_low, mtInternal);
     push_ptr = new_ptr - (tag_len+1);
   }
   assert(push_ptr >= _element_close_stack_low, "in range");
diff --git a/hotspot/test/Makefile b/hotspot/test/Makefile
index f536592..c8efce4 100644
--- a/hotspot/test/Makefile
+++ b/hotspot/test/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 1995, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -26,6 +26,8 @@
 # Makefile to run various jdk tests
 #
 
+GETMIXEDPATH=echo
+
 # Get OS/ARCH specifics
 OSNAME = $(shell uname -s)
 ifeq ($(OSNAME), SunOS)
@@ -60,7 +62,14 @@
     ARCH = i586
   endif
 endif
-ifeq ($(OSNAME), Windows_NT)
+ifeq ($(PLATFORM),)
+  # detect wether we're running in MKS or cygwin
+  ifeq ($(OSNAME), Windows_NT) # MKS
+    GETMIXEDPATH=dosname -s
+  endif
+  ifeq ($(findstring CYGWIN,$(OSNAME)), CYGWIN)
+    GETMIXEDPATH=cygpath -m -s
+  endif
   PLATFORM = windows
   SLASH_JAVA = J:
   ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64)
@@ -228,6 +237,24 @@
 
 ################################################################
 
+# wbapitest (make sure the whitebox testing api classes work
+
+wbapitest: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
+	$(JTREG) -a -v:fail,error               \
+          $(JTREG_KEY_OPTION)                   \
+          $(EXTRA_JTREG_OPTIONS)                \
+          -r:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTreport    \
+          -w:$(shell $(GETMIXEDPATH) "$(ABS_TEST_OUTPUT_DIR)")/JTwork      \
+          -jdk:$(shell $(GETMIXEDPATH) "$(PRODUCT_HOME)")                  \
+          $(JAVA_OPTIONS:%=-vmoption:%)         \
+          $(shell $(GETMIXEDPATH) "$(TEST_ROOT)")/sanity                   \
+	  || $(BUNDLE_UP_FAILED)
+	$(BUNDLE_UP)
+
+PHONY_LIST += wbapitest
+
+################################################################
+
 # packtest
 
 # Expect JPRT to set JPRT_PACKTEST_HOME.
diff --git a/hotspot/test/compiler/6340864/TestByteVect.java b/hotspot/test/compiler/6340864/TestByteVect.java
new file mode 100644
index 0000000..5db3687
--- /dev/null
+++ b/hotspot/test/compiler/6340864/TestByteVect.java
@@ -0,0 +1,1487 @@
+/*
+ * Copyright (c) 2012, 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 6340864
+ * @summary Implement vectorization optimizations in hotspot-server
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestByteVect
+ */
+
+public class TestByteVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int ADD_INIT = 63;
+  private static final int BIT_MASK = 0xB7;
+  private static final int VALUE = 3;
+  private static final int SHIFT = 8;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Byte vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    byte[] a0 = new byte[ARRLEN];
+    byte[] a1 = new byte[ARRLEN];
+    byte[] a2 = new byte[ARRLEN];
+    byte[] a3 = new byte[ARRLEN];
+    byte[] a4 = new byte[ARRLEN];
+    short[] p2 = new short[ARRLEN/2];
+      int[] p4 = new   int[ARRLEN/4];
+     long[] p8 = new  long[ARRLEN/8];
+    // Initialize
+    int gold_sum = 0;
+    for (int i=0; i<ARRLEN; i++) {
+      byte val = (byte)(ADD_INIT+i);
+      gold_sum += val;
+      a1[i] = val;
+      a2[i] = (byte)VALUE;
+      a3[i] = (byte)-VALUE;
+      a4[i] = (byte)BIT_MASK;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+      test_addc(a0, a1);
+      test_addv(a0, a1, (byte)VALUE);
+      test_adda(a0, a1, a2);
+      test_subc(a0, a1);
+      test_subv(a0, a1, (byte)VALUE);
+      test_suba(a0, a1, a2);
+
+      test_mulc(a0, a1);
+      test_mulv(a0, a1, (byte)VALUE);
+      test_mula(a0, a1, a2);
+      test_divc(a0, a1);
+      test_divv(a0, a1, (byte)VALUE);
+      test_diva(a0, a1, a2);
+      test_mulc_n(a0, a1);
+      test_mulv(a0, a1, (byte)-VALUE);
+      test_mula(a0, a1, a3);
+      test_divc_n(a0, a1);
+      test_divv(a0, a1, (byte)-VALUE);
+      test_diva(a0, a1, a3);
+
+      test_andc(a0, a1);
+      test_andv(a0, a1, (byte)BIT_MASK);
+      test_anda(a0, a1, a4);
+      test_orc(a0, a1);
+      test_orv(a0, a1, (byte)BIT_MASK);
+      test_ora(a0, a1, a4);
+      test_xorc(a0, a1);
+      test_xorv(a0, a1, (byte)BIT_MASK);
+      test_xora(a0, a1, a4);
+
+      test_sllc(a0, a1);
+      test_sllv(a0, a1, VALUE);
+      test_srlc(a0, a1);
+      test_srlv(a0, a1, VALUE);
+      test_srac(a0, a1);
+      test_srav(a0, a1, VALUE);
+
+      test_sllc_n(a0, a1);
+      test_sllv(a0, a1, -VALUE);
+      test_srlc_n(a0, a1);
+      test_srlv(a0, a1, -VALUE);
+      test_srac_n(a0, a1);
+      test_srav(a0, a1, -VALUE);
+
+      test_sllc_o(a0, a1);
+      test_sllv(a0, a1, SHIFT);
+      test_srlc_o(a0, a1);
+      test_srlv(a0, a1, SHIFT);
+      test_srac_o(a0, a1);
+      test_srav(a0, a1, SHIFT);
+
+      test_sllc_on(a0, a1);
+      test_sllv(a0, a1, -SHIFT);
+      test_srlc_on(a0, a1);
+      test_srlv(a0, a1, -SHIFT);
+      test_srac_on(a0, a1);
+      test_srav(a0, a1, -SHIFT);
+
+      test_sllc_add(a0, a1);
+      test_sllv_add(a0, a1, ADD_INIT);
+      test_srlc_add(a0, a1);
+      test_srlv_add(a0, a1, ADD_INIT);
+      test_srac_add(a0, a1);
+      test_srav_add(a0, a1, ADD_INIT);
+
+      test_sllc_and(a0, a1);
+      test_sllv_and(a0, a1, BIT_MASK);
+      test_srlc_and(a0, a1);
+      test_srlv_and(a0, a1, BIT_MASK);
+      test_srac_and(a0, a1);
+      test_srav_and(a0, a1, BIT_MASK);
+
+      test_pack2(p2, a1);
+      test_unpack2(a0, p2);
+      test_pack2_swap(p2, a1);
+      test_unpack2_swap(a0, p2);
+      test_pack4(p4, a1);
+      test_unpack4(a0, p4);
+      test_pack4_swap(p4, a1);
+      test_unpack4_swap(a0, p4);
+      test_pack8(p8, a1);
+      test_unpack8(a0, p8);
+      test_pack8_swap(p8, a1);
+      test_unpack8_swap(a0, p8);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      int sum = test_sum(a1);
+      if (sum != gold_sum) {
+        System.err.println("test_sum:  " + sum + " != " + gold_sum);
+        errn++;
+      }
+
+      test_addc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)+VALUE));
+      }
+      test_addv(a0, a1, (byte)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)+VALUE));
+      }
+      test_adda(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_adda: ", i, a0[i], (byte)((byte)(ADD_INIT+i)+VALUE));
+      }
+
+      test_subc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)-VALUE));
+      }
+      test_subv(a0, a1, (byte)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)-VALUE));
+      }
+      test_suba(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_suba: ", i, a0[i], (byte)((byte)(ADD_INIT+i)-VALUE));
+      }
+
+      test_mulc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)*VALUE));
+      }
+      test_mulv(a0, a1, (byte)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)*VALUE));
+      }
+      test_mula(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula: ", i, a0[i], (byte)((byte)(ADD_INIT+i)*VALUE));
+      }
+
+      test_divc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)/VALUE));
+      }
+      test_divv(a0, a1, (byte)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)/VALUE));
+      }
+      test_diva(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva: ", i, a0[i], (byte)((byte)(ADD_INIT+i)/VALUE));
+      }
+
+      test_mulc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mulv(a0, a1, (byte)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mula(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)*(-VALUE)));
+      }
+
+      test_divc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_divv(a0, a1, (byte)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_diva(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)/(-VALUE)));
+      }
+
+      test_andc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_andv(a0, a1, (byte)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_anda(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_anda: ", i, a0[i], (byte)((byte)(ADD_INIT+i)&BIT_MASK));
+      }
+
+      test_orc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_orv(a0, a1, (byte)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_ora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ora: ", i, a0[i], (byte)((byte)(ADD_INIT+i)|BIT_MASK));
+      }
+
+      test_xorc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xorv(a0, a1, (byte)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xora: ", i, a0[i], (byte)((byte)(ADD_INIT+i)^BIT_MASK));
+      }
+
+      test_sllc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)<<VALUE));
+      }
+      test_sllv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)<<VALUE));
+      }
+
+      test_srlc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>>VALUE));
+      }
+      test_srlv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>>VALUE));
+      }
+
+      test_srac(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>VALUE));
+      }
+      test_srav(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>VALUE));
+      }
+
+      test_sllc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)<<(-VALUE)));
+      }
+      test_sllv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)<<(-VALUE)));
+      }
+
+      test_srlc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>>(-VALUE)));
+      }
+      test_srlv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>>(-VALUE)));
+      }
+
+      test_srac_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>(-VALUE)));
+      }
+      test_srav(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_n: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>(-VALUE)));
+      }
+
+      test_sllc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_o: ", i, a0[i], (byte)((byte)(ADD_INIT+i)<<SHIFT));
+      }
+      test_sllv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_o: ", i, a0[i], (byte)((byte)(ADD_INIT+i)<<SHIFT));
+      }
+
+      test_srlc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_o: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>>SHIFT));
+      }
+      test_srlv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_o: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>>SHIFT));
+      }
+
+      test_srac_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_o: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>SHIFT));
+      }
+      test_srav(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_o: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>SHIFT));
+      }
+
+      test_sllc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_on: ", i, a0[i], (byte)((byte)(ADD_INIT+i)<<(-SHIFT)));
+      }
+      test_sllv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_on: ", i, a0[i], (byte)((byte)(ADD_INIT+i)<<(-SHIFT)));
+      }
+
+      test_srlc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_on: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+      test_srlv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_on: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+
+      test_srac_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_on: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>(-SHIFT)));
+      }
+      test_srav(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_on: ", i, a0[i], (byte)((byte)(ADD_INIT+i)>>(-SHIFT)));
+      }
+
+      test_sllc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_add: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+      test_sllv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_add: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+
+      test_srlc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_add: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+      test_srlv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_add: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+
+      test_srac_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_add: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+      test_srav_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_add: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+
+      test_sllc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_and: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+      test_sllv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_and: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+
+      test_srlc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_and: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+      test_srlv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_and: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+
+      test_srac_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_and: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+      test_srav_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_and: ", i, a0[i], (byte)(((byte)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+
+      test_pack2(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2: ", i, p2[i], (short)(((short)(ADD_INIT+2*i) & 0xFF) | ((short)(ADD_INIT+2*i+1) << 8)));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack2(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2: ", i, a0[i], (byte)(ADD_INIT+i));
+      }
+
+      test_pack2_swap(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2_swap: ", i, p2[i], (short)(((short)(ADD_INIT+2*i+1) & 0xFF) | ((short)(ADD_INIT+2*i) << 8)));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack2_swap(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2_swap: ", i, a0[i], (byte)(ADD_INIT+i));
+      }
+
+      test_pack4(p4, a1);
+      for (int i=0; i<ARRLEN/4; i++) {
+        errn += verify("test_pack4: ", i, p4[i],  ((int)(ADD_INIT+4*i+0) & 0xFF) |
+                                                 (((int)(ADD_INIT+4*i+1) & 0xFF) <<  8)  |
+                                                 (((int)(ADD_INIT+4*i+2) & 0xFF) << 16)  |
+                                                 (((int)(ADD_INIT+4*i+3) & 0xFF) << 24));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack4(a0, p4);
+      for (int i=0; i<(ARRLEN&(-4)); i++) {
+        errn += verify("test_unpack4: ", i, a0[i], (byte)(ADD_INIT+i));
+      }
+
+      test_pack4_swap(p4, a1);
+      for (int i=0; i<ARRLEN/4; i++) {
+        errn += verify("test_pack4_swap: ", i, p4[i],  ((int)(ADD_INIT+4*i+3) & 0xFF) |
+                                                      (((int)(ADD_INIT+4*i+2) & 0xFF) <<  8)  |
+                                                      (((int)(ADD_INIT+4*i+1) & 0xFF) << 16)  |
+                                                      (((int)(ADD_INIT+4*i+0) & 0xFF) << 24));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack4_swap(a0, p4);
+      for (int i=0; i<(ARRLEN&(-4)); i++) {
+        errn += verify("test_unpack4_swap: ", i, a0[i], (byte)(ADD_INIT+i));
+      }
+
+      test_pack8(p8, a1);
+      for (int i=0; i<ARRLEN/8; i++) {
+        errn += verify("test_pack8: ", i, p8[i],  ((long)(ADD_INIT+8*i+0) & 0xFFl) |
+                                                 (((long)(ADD_INIT+8*i+1) & 0xFFl) <<  8)  |
+                                                 (((long)(ADD_INIT+8*i+2) & 0xFFl) << 16)  |
+                                                 (((long)(ADD_INIT+8*i+3) & 0xFFl) << 24)  |
+                                                 (((long)(ADD_INIT+8*i+4) & 0xFFl) << 32)  |
+                                                 (((long)(ADD_INIT+8*i+5) & 0xFFl) << 40)  |
+                                                 (((long)(ADD_INIT+8*i+6) & 0xFFl) << 48)  |
+                                                 (((long)(ADD_INIT+8*i+7) & 0xFFl) << 56));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack8(a0, p8);
+      for (int i=0; i<(ARRLEN&(-8)); i++) {
+        errn += verify("test_unpack8: ", i, a0[i], (byte)(ADD_INIT+i));
+      }
+
+      test_pack8_swap(p8, a1);
+      for (int i=0; i<ARRLEN/8; i++) {
+        errn += verify("test_pack8_swap: ", i, p8[i],  ((long)(ADD_INIT+8*i+7) & 0xFFl) |
+                                                      (((long)(ADD_INIT+8*i+6) & 0xFFl) <<  8)  |
+                                                      (((long)(ADD_INIT+8*i+5) & 0xFFl) << 16)  |
+                                                      (((long)(ADD_INIT+8*i+4) & 0xFFl) << 24)  |
+                                                      (((long)(ADD_INIT+8*i+3) & 0xFFl) << 32)  |
+                                                      (((long)(ADD_INIT+8*i+2) & 0xFFl) << 40)  |
+                                                      (((long)(ADD_INIT+8*i+1) & 0xFFl) << 48)  |
+                                                      (((long)(ADD_INIT+8*i+0) & 0xFFl) << 56));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack8_swap(a0, p8);
+      for (int i=0; i<(ARRLEN&(-8)); i++) {
+        errn += verify("test_unpack8_swap: ", i, a0[i], (byte)(ADD_INIT+i));
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sum: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addv(a0, a1, (byte)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_adda(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_adda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subv(a0, a1, (byte)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_suba(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_suba: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (byte)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, (byte)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (byte)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, (byte)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andv(a0, a1, (byte)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_anda(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_anda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orv(a0, a1, (byte)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorv(a0, a1, (byte)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack2(p2, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack2: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack2(a0, p2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack2: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack2_swap(p2, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack2_swap: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack2_swap(a0, p2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack2_swap: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack4(p4, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack4: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack4(a0, p4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack4: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack4_swap(p4, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack4_swap: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack4_swap(a0, p4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack4_swap: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack8(p8, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack8: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack8(a0, p8);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack8: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack8_swap(p8, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack8_swap: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack8_swap(a0, p8);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack8_swap: " + (end - start));
+
+    return errn;
+  }
+
+  static int test_sum(byte[] a1) {
+    int sum = 0;
+    for (int i = 0; i < a1.length; i+=1) {
+      sum += a1[i];
+    }
+    return sum;
+  }
+
+  static void test_addc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]+VALUE);
+    }
+  }
+  static void test_addv(byte[] a0, byte[] a1, byte b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]+b);
+    }
+  }
+  static void test_adda(byte[] a0, byte[] a1, byte[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]+a2[i]);
+    }
+  }
+
+  static void test_subc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]-VALUE);
+    }
+  }
+  static void test_subv(byte[] a0, byte[] a1, byte b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]-b);
+    }
+  }
+  static void test_suba(byte[] a0, byte[] a1, byte[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]-a2[i]);
+    }
+  }
+
+  static void test_mulc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]*VALUE);
+    }
+  }
+  static void test_mulc_n(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]*(-VALUE));
+    }
+  }
+  static void test_mulv(byte[] a0, byte[] a1, byte b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]*b);
+    }
+  }
+  static void test_mula(byte[] a0, byte[] a1, byte[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]*a2[i]);
+    }
+  }
+
+  static void test_divc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]/VALUE);
+    }
+  }
+  static void test_divc_n(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]/(-VALUE));
+    }
+  }
+  static void test_divv(byte[] a0, byte[] a1, byte b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]/b);
+    }
+  }
+  static void test_diva(byte[] a0, byte[] a1, byte[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]/a2[i]);
+    }
+  }
+
+  static void test_andc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]&BIT_MASK);
+    }
+  }
+  static void test_andv(byte[] a0, byte[] a1, byte b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]&b);
+    }
+  }
+  static void test_anda(byte[] a0, byte[] a1, byte[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]&a2[i]);
+    }
+  }
+
+  static void test_orc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]|BIT_MASK);
+    }
+  }
+  static void test_orv(byte[] a0, byte[] a1, byte b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]|b);
+    }
+  }
+  static void test_ora(byte[] a0, byte[] a1, byte[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]|a2[i]);
+    }
+  }
+
+  static void test_xorc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]^BIT_MASK);
+    }
+  }
+  static void test_xorv(byte[] a0, byte[] a1, byte b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]^b);
+    }
+  }
+  static void test_xora(byte[] a0, byte[] a1, byte[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]^a2[i]);
+    }
+  }
+
+  static void test_sllc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]<<VALUE);
+    }
+  }
+  static void test_sllc_n(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]<<(-VALUE));
+    }
+  }
+  static void test_sllc_o(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]<<SHIFT);
+    }
+  }
+  static void test_sllc_on(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]<<(-SHIFT));
+    }
+  }
+  static void test_sllv(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]<<b);
+    }
+  }
+  static void test_sllc_add(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] + ADD_INIT)<<VALUE);
+    }
+  }
+  static void test_sllv_add(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] + b)<<VALUE);
+    }
+  }
+  static void test_sllc_and(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] & BIT_MASK)<<VALUE);
+    }
+  }
+  static void test_sllv_and(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] & b)<<VALUE);
+    }
+  }
+
+  static void test_srlc(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>>VALUE);
+    }
+  }
+  static void test_srlc_n(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>>(-VALUE));
+    }
+  }
+  static void test_srlc_o(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>>SHIFT);
+    }
+  }
+  static void test_srlc_on(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>>(-SHIFT));
+    }
+  }
+  static void test_srlv(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>>b);
+    }
+  }
+  static void test_srlc_add(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] + ADD_INIT)>>>VALUE);
+    }
+  }
+  static void test_srlv_add(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] + b)>>>VALUE);
+    }
+  }
+  static void test_srlc_and(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] & BIT_MASK)>>>VALUE);
+    }
+  }
+  static void test_srlv_and(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] & b)>>>VALUE);
+    }
+  }
+
+  static void test_srac(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>VALUE);
+    }
+  }
+  static void test_srac_n(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>(-VALUE));
+    }
+  }
+  static void test_srac_o(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>SHIFT);
+    }
+  }
+  static void test_srac_on(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>(-SHIFT));
+    }
+  }
+  static void test_srav(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]>>b);
+    }
+  }
+  static void test_srac_add(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] + ADD_INIT)>>VALUE);
+    }
+  }
+  static void test_srav_add(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] + b)>>VALUE);
+    }
+  }
+  static void test_srac_and(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] & BIT_MASK)>>VALUE);
+    }
+  }
+  static void test_srav_and(byte[] a0, byte[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)((a1[i] & b)>>VALUE);
+    }
+  }
+
+  static void test_pack2(short[] p2, byte[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      short l0 = (short)a1[i*2+0];
+      short l1 = (short)a1[i*2+1];
+      p2[i] = (short)((l1 << 8) | (l0 & 0xFF));
+    }
+  }
+  static void test_unpack2(byte[] a0, short[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      short l = p2[i];
+      a0[i*2+0] = (byte)(l & 0xFF);
+      a0[i*2+1] = (byte)(l >> 8);
+    }
+  }
+  static void test_pack2_swap(short[] p2, byte[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      short l0 = (short)a1[i*2+0];
+      short l1 = (short)a1[i*2+1];
+      p2[i] = (short)((l0 << 8) | (l1 & 0xFF));
+    }
+  }
+  static void test_unpack2_swap(byte[] a0, short[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      short l = p2[i];
+      a0[i*2+0] = (byte)(l >> 8);
+      a0[i*2+1] = (byte)(l & 0xFF);
+    }
+  }
+
+  static void test_pack4(int[] p4, byte[] a1) {
+    if (p4.length*4 > a1.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      int l0 = (int)a1[i*4+0];
+      int l1 = (int)a1[i*4+1];
+      int l2 = (int)a1[i*4+2];
+      int l3 = (int)a1[i*4+3];
+      p4[i] = (l0 & 0xFF) |
+             ((l1 & 0xFF) <<  8) |
+             ((l2 & 0xFF) << 16) |
+             ((l3 & 0xFF) << 24);
+    }
+  }
+  static void test_unpack4(byte[] a0, int[] p4) {
+    if (p4.length*4 > a0.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      int l = p4[i];
+      a0[i*4+0] = (byte)(l & 0xFF);
+      a0[i*4+1] = (byte)(l >>  8);
+      a0[i*4+2] = (byte)(l >> 16);
+      a0[i*4+3] = (byte)(l >> 24);
+    }
+  }
+  static void test_pack4_swap(int[] p4, byte[] a1) {
+    if (p4.length*4 > a1.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      int l0 = (int)a1[i*4+0];
+      int l1 = (int)a1[i*4+1];
+      int l2 = (int)a1[i*4+2];
+      int l3 = (int)a1[i*4+3];
+      p4[i] = (l3 & 0xFF) |
+             ((l2 & 0xFF) <<  8) |
+             ((l1 & 0xFF) << 16) |
+             ((l0 & 0xFF) << 24);
+    }
+  }
+  static void test_unpack4_swap(byte[] a0, int[] p4) {
+    if (p4.length*4 > a0.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      int l = p4[i];
+      a0[i*4+0] = (byte)(l >> 24);
+      a0[i*4+1] = (byte)(l >> 16);
+      a0[i*4+2] = (byte)(l >>  8);
+      a0[i*4+3] = (byte)(l & 0xFF);
+    }
+  }
+
+  static void test_pack8(long[] p8, byte[] a1) {
+    if (p8.length*8 > a1.length) return;
+    for (int i = 0; i < p8.length; i+=1) {
+      long l0 = (long)a1[i*8+0];
+      long l1 = (long)a1[i*8+1];
+      long l2 = (long)a1[i*8+2];
+      long l3 = (long)a1[i*8+3];
+      long l4 = (long)a1[i*8+4];
+      long l5 = (long)a1[i*8+5];
+      long l6 = (long)a1[i*8+6];
+      long l7 = (long)a1[i*8+7];
+      p8[i] = (l0 & 0xFFl) |
+             ((l1 & 0xFFl) <<  8) |
+             ((l2 & 0xFFl) << 16) |
+             ((l3 & 0xFFl) << 24) |
+             ((l4 & 0xFFl) << 32) |
+             ((l5 & 0xFFl) << 40) |
+             ((l6 & 0xFFl) << 48) |
+             ((l7 & 0xFFl) << 56);
+    }
+  }
+  static void test_unpack8(byte[] a0, long[] p8) {
+    if (p8.length*8 > a0.length) return;
+    for (int i = 0; i < p8.length; i+=1) {
+      long l = p8[i];
+      a0[i*8+0] = (byte)(l & 0xFFl);
+      a0[i*8+1] = (byte)(l >>  8);
+      a0[i*8+2] = (byte)(l >> 16);
+      a0[i*8+3] = (byte)(l >> 24);
+      a0[i*8+4] = (byte)(l >> 32);
+      a0[i*8+5] = (byte)(l >> 40);
+      a0[i*8+6] = (byte)(l >> 48);
+      a0[i*8+7] = (byte)(l >> 56);
+    }
+  }
+  static void test_pack8_swap(long[] p8, byte[] a1) {
+    if (p8.length*8 > a1.length) return;
+    for (int i = 0; i < p8.length; i+=1) {
+      long l0 = (long)a1[i*8+0];
+      long l1 = (long)a1[i*8+1];
+      long l2 = (long)a1[i*8+2];
+      long l3 = (long)a1[i*8+3];
+      long l4 = (long)a1[i*8+4];
+      long l5 = (long)a1[i*8+5];
+      long l6 = (long)a1[i*8+6];
+      long l7 = (long)a1[i*8+7];
+      p8[i] = (l7 & 0xFFl) |
+             ((l6 & 0xFFl) <<  8) |
+             ((l5 & 0xFFl) << 16) |
+             ((l4 & 0xFFl) << 24) |
+             ((l3 & 0xFFl) << 32) |
+             ((l2 & 0xFFl) << 40) |
+             ((l1 & 0xFFl) << 48) |
+             ((l0 & 0xFFl) << 56);
+    }
+  }
+  static void test_unpack8_swap(byte[] a0, long[] p8) {
+    if (p8.length*8 > a0.length) return;
+    for (int i = 0; i < p8.length; i+=1) {
+      long l = p8[i];
+      a0[i*8+0] = (byte)(l >> 56);
+      a0[i*8+1] = (byte)(l >> 48);
+      a0[i*8+2] = (byte)(l >> 40);
+      a0[i*8+3] = (byte)(l >> 32);
+      a0[i*8+4] = (byte)(l >> 24);
+      a0[i*8+5] = (byte)(l >> 16);
+      a0[i*8+6] = (byte)(l >>  8);
+      a0[i*8+7] = (byte)(l & 0xFFl);
+    }
+  }
+
+  static int verify(String text, int i, byte elem, byte val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + Integer.toHexString(elem) + " != " + Integer.toHexString(val));
+      return 1;
+    }
+    return 0;
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + Long.toHexString(elem) + " != " + Long.toHexString(val));
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/6340864/TestDoubleVect.java b/hotspot/test/compiler/6340864/TestDoubleVect.java
new file mode 100644
index 0000000..db0f460
--- /dev/null
+++ b/hotspot/test/compiler/6340864/TestDoubleVect.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2012, 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 6340864
+ * @summary Implement vectorization optimizations in hotspot-server
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestDoubleVect
+ */
+
+public class TestDoubleVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final double ADD_INIT = -7500.;
+  private static final double VALUE = 15.;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Double vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    double[] a0 = new double[ARRLEN];
+    double[] a1 = new double[ARRLEN];
+    double[] a2 = new double[ARRLEN];
+    double[] a3 = new double[ARRLEN];
+    // Initialize
+    double gold_sum = 0;
+    for (int i=0; i<ARRLEN; i++) {
+      double val = ADD_INIT+(double)i;
+      gold_sum += val;
+      a1[i] = val;
+      a2[i] = VALUE;
+      a3[i] = -VALUE;
+    }
+
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+      test_addc(a0, a1);
+      test_addv(a0, a1, VALUE);
+      test_adda(a0, a1, a2);
+      test_subc(a0, a1);
+      test_subv(a0, a1, VALUE);
+      test_suba(a0, a1, a2);
+      test_mulc(a0, a1);
+      test_mulv(a0, a1, VALUE);
+      test_mula(a0, a1, a2);
+      test_divc(a0, a1);
+      test_divv(a0, a1, VALUE);
+      test_diva(a0, a1, a2);
+      test_mulc_n(a0, a1);
+      test_mulv(a0, a1, -VALUE);
+      test_mula(a0, a1, a3);
+      test_divc_n(a0, a1);
+      test_divv(a0, a1, -VALUE);
+      test_diva(a0, a1, a3);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      double sum = test_sum(a1);
+      if (sum != gold_sum) {
+        System.err.println("test_sum:  " + sum + " != " + gold_sum);
+        errn++;
+      }
+      // Overwrite with NaN values
+      a1[0] = Double.NaN;
+      a1[1] = Double.POSITIVE_INFINITY;
+      a1[2] = Double.NEGATIVE_INFINITY;
+      a1[3] = Double.MAX_VALUE;
+      a1[4] = Double.MIN_VALUE;
+      a1[5] = Double.MIN_NORMAL;
+
+      a2[6] = a1[0];
+      a2[7] = a1[1];
+      a2[8] = a1[2];
+      a2[9] = a1[3];
+      a2[10] = a1[4];
+      a2[11] = a1[5];
+
+      a3[6] = -a2[6];
+      a3[7] = -a2[7];
+      a3[8] = -a2[8];
+      a3[9] = -a2[9];
+      a3[10] = -a2[10];
+      a3[11] = -a2[11];
+
+      test_addc(a0, a1);
+      errn += verify("test_addc: ", 0, a0[0], (Double.NaN+VALUE));
+      errn += verify("test_addc: ", 1, a0[1], (Double.POSITIVE_INFINITY+VALUE));
+      errn += verify("test_addc: ", 2, a0[2], (Double.NEGATIVE_INFINITY+VALUE));
+      errn += verify("test_addc: ", 3, a0[3], (Double.MAX_VALUE+VALUE));
+      errn += verify("test_addc: ", 4, a0[4], (Double.MIN_VALUE+VALUE));
+      errn += verify("test_addc: ", 5, a0[5], (Double.MIN_NORMAL+VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], ((ADD_INIT+i)+VALUE));
+      }
+      test_addv(a0, a1, VALUE);
+      errn += verify("test_addv: ", 0, a0[0], (Double.NaN+VALUE));
+      errn += verify("test_addv: ", 1, a0[1], (Double.POSITIVE_INFINITY+VALUE));
+      errn += verify("test_addv: ", 2, a0[2], (Double.NEGATIVE_INFINITY+VALUE));
+      errn += verify("test_addv: ", 3, a0[3], (Double.MAX_VALUE+VALUE));
+      errn += verify("test_addv: ", 4, a0[4], (Double.MIN_VALUE+VALUE));
+      errn += verify("test_addv: ", 5, a0[5], (Double.MIN_NORMAL+VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], ((ADD_INIT+i)+VALUE));
+      }
+      test_adda(a0, a1, a2);
+      errn += verify("test_adda: ", 0, a0[0], (Double.NaN+VALUE));
+      errn += verify("test_adda: ", 1, a0[1], (Double.POSITIVE_INFINITY+VALUE));
+      errn += verify("test_adda: ", 2, a0[2], (Double.NEGATIVE_INFINITY+VALUE));
+      errn += verify("test_adda: ", 3, a0[3], (Double.MAX_VALUE+VALUE));
+      errn += verify("test_adda: ", 4, a0[4], (Double.MIN_VALUE+VALUE));
+      errn += verify("test_adda: ", 5, a0[5], (Double.MIN_NORMAL+VALUE));
+      errn += verify("test_adda: ", 6, a0[6], ((ADD_INIT+6)+Double.NaN));
+      errn += verify("test_adda: ", 7, a0[7], ((ADD_INIT+7)+Double.POSITIVE_INFINITY));
+      errn += verify("test_adda: ", 8, a0[8], ((ADD_INIT+8)+Double.NEGATIVE_INFINITY));
+      errn += verify("test_adda: ", 9, a0[9], ((ADD_INIT+9)+Double.MAX_VALUE));
+      errn += verify("test_adda: ", 10, a0[10], ((ADD_INIT+10)+Double.MIN_VALUE));
+      errn += verify("test_adda: ", 11, a0[11], ((ADD_INIT+11)+Double.MIN_NORMAL));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_adda: ", i, a0[i], ((ADD_INIT+i)+VALUE));
+      }
+
+      test_subc(a0, a1);
+      errn += verify("test_subc: ", 0, a0[0], (Double.NaN-VALUE));
+      errn += verify("test_subc: ", 1, a0[1], (Double.POSITIVE_INFINITY-VALUE));
+      errn += verify("test_subc: ", 2, a0[2], (Double.NEGATIVE_INFINITY-VALUE));
+      errn += verify("test_subc: ", 3, a0[3], (Double.MAX_VALUE-VALUE));
+      errn += verify("test_subc: ", 4, a0[4], (Double.MIN_VALUE-VALUE));
+      errn += verify("test_subc: ", 5, a0[5], (Double.MIN_NORMAL-VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_subc: ", i, a0[i], ((ADD_INIT+i)-VALUE));
+      }
+      test_subv(a0, a1, VALUE);
+      errn += verify("test_subv: ", 0, a0[0], (Double.NaN-VALUE));
+      errn += verify("test_subv: ", 1, a0[1], (Double.POSITIVE_INFINITY-VALUE));
+      errn += verify("test_subv: ", 2, a0[2], (Double.NEGATIVE_INFINITY-VALUE));
+      errn += verify("test_subv: ", 3, a0[3], (Double.MAX_VALUE-VALUE));
+      errn += verify("test_subv: ", 4, a0[4], (Double.MIN_VALUE-VALUE));
+      errn += verify("test_subv: ", 5, a0[5], (Double.MIN_NORMAL-VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_subv: ", i, a0[i], ((ADD_INIT+i)-VALUE));
+      }
+      test_suba(a0, a1, a2);
+      errn += verify("test_suba: ", 0, a0[0], (Double.NaN-VALUE));
+      errn += verify("test_suba: ", 1, a0[1], (Double.POSITIVE_INFINITY-VALUE));
+      errn += verify("test_suba: ", 2, a0[2], (Double.NEGATIVE_INFINITY-VALUE));
+      errn += verify("test_suba: ", 3, a0[3], (Double.MAX_VALUE-VALUE));
+      errn += verify("test_suba: ", 4, a0[4], (Double.MIN_VALUE-VALUE));
+      errn += verify("test_suba: ", 5, a0[5], (Double.MIN_NORMAL-VALUE));
+      errn += verify("test_suba: ", 6, a0[6], ((ADD_INIT+6)-Double.NaN));
+      errn += verify("test_suba: ", 7, a0[7], ((ADD_INIT+7)-Double.POSITIVE_INFINITY));
+      errn += verify("test_suba: ", 8, a0[8], ((ADD_INIT+8)-Double.NEGATIVE_INFINITY));
+      errn += verify("test_suba: ", 9, a0[9], ((ADD_INIT+9)-Double.MAX_VALUE));
+      errn += verify("test_suba: ", 10, a0[10], ((ADD_INIT+10)-Double.MIN_VALUE));
+      errn += verify("test_suba: ", 11, a0[11], ((ADD_INIT+11)-Double.MIN_NORMAL));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_suba: ", i, a0[i], ((ADD_INIT+i)-VALUE));
+      }
+
+      test_mulc(a0, a1);
+      errn += verify("test_mulc: ", 0, a0[0], (Double.NaN*VALUE));
+      errn += verify("test_mulc: ", 1, a0[1], (Double.POSITIVE_INFINITY*VALUE));
+      errn += verify("test_mulc: ", 2, a0[2], (Double.NEGATIVE_INFINITY*VALUE));
+      errn += verify("test_mulc: ", 3, a0[3], (Double.MAX_VALUE*VALUE));
+      errn += verify("test_mulc: ", 4, a0[4], (Double.MIN_VALUE*VALUE));
+      errn += verify("test_mulc: ", 5, a0[5], (Double.MIN_NORMAL*VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_mulc: ", i, a0[i], ((ADD_INIT+i)*VALUE));
+      }
+      test_mulv(a0, a1, VALUE);
+      errn += verify("test_mulv: ", 0, a0[0], (Double.NaN*VALUE));
+      errn += verify("test_mulv: ", 1, a0[1], (Double.POSITIVE_INFINITY*VALUE));
+      errn += verify("test_mulv: ", 2, a0[2], (Double.NEGATIVE_INFINITY*VALUE));
+      errn += verify("test_mulv: ", 3, a0[3], (Double.MAX_VALUE*VALUE));
+      errn += verify("test_mulv: ", 4, a0[4], (Double.MIN_VALUE*VALUE));
+      errn += verify("test_mulv: ", 5, a0[5], (Double.MIN_NORMAL*VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_mulv: ", i, a0[i], ((ADD_INIT+i)*VALUE));
+      }
+      test_mula(a0, a1, a2);
+      errn += verify("test_mula: ", 0, a0[0], (Double.NaN*VALUE));
+      errn += verify("test_mula: ", 1, a0[1], (Double.POSITIVE_INFINITY*VALUE));
+      errn += verify("test_mula: ", 2, a0[2], (Double.NEGATIVE_INFINITY*VALUE));
+      errn += verify("test_mula: ", 3, a0[3], (Double.MAX_VALUE*VALUE));
+      errn += verify("test_mula: ", 4, a0[4], (Double.MIN_VALUE*VALUE));
+      errn += verify("test_mula: ", 5, a0[5], (Double.MIN_NORMAL*VALUE));
+      errn += verify("test_mula: ", 6, a0[6], ((ADD_INIT+6)*Double.NaN));
+      errn += verify("test_mula: ", 7, a0[7], ((ADD_INIT+7)*Double.POSITIVE_INFINITY));
+      errn += verify("test_mula: ", 8, a0[8], ((ADD_INIT+8)*Double.NEGATIVE_INFINITY));
+      errn += verify("test_mula: ", 9, a0[9], ((ADD_INIT+9)*Double.MAX_VALUE));
+      errn += verify("test_mula: ", 10, a0[10], ((ADD_INIT+10)*Double.MIN_VALUE));
+      errn += verify("test_mula: ", 11, a0[11], ((ADD_INIT+11)*Double.MIN_NORMAL));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_mula: ", i, a0[i], ((ADD_INIT+i)*VALUE));
+      }
+
+      test_divc(a0, a1);
+      errn += verify("test_divc: ", 0, a0[0], (Double.NaN/VALUE));
+      errn += verify("test_divc: ", 1, a0[1], (Double.POSITIVE_INFINITY/VALUE));
+      errn += verify("test_divc: ", 2, a0[2], (Double.NEGATIVE_INFINITY/VALUE));
+      errn += verify("test_divc: ", 3, a0[3], (Double.MAX_VALUE/VALUE));
+      errn += verify("test_divc: ", 4, a0[4], (Double.MIN_VALUE/VALUE));
+      errn += verify("test_divc: ", 5, a0[5], (Double.MIN_NORMAL/VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_divc: ", i, a0[i], ((ADD_INIT+i)/VALUE));
+      }
+      test_divv(a0, a1, VALUE);
+      errn += verify("test_divv: ", 0, a0[0], (Double.NaN/VALUE));
+      errn += verify("test_divv: ", 1, a0[1], (Double.POSITIVE_INFINITY/VALUE));
+      errn += verify("test_divv: ", 2, a0[2], (Double.NEGATIVE_INFINITY/VALUE));
+      errn += verify("test_divv: ", 3, a0[3], (Double.MAX_VALUE/VALUE));
+      errn += verify("test_divv: ", 4, a0[4], (Double.MIN_VALUE/VALUE));
+      errn += verify("test_divv: ", 5, a0[5], (Double.MIN_NORMAL/VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_divv: ", i, a0[i], ((ADD_INIT+i)/VALUE));
+      }
+      test_diva(a0, a1, a2);
+      errn += verify("test_diva: ", 0, a0[0], (Double.NaN/VALUE));
+      errn += verify("test_diva: ", 1, a0[1], (Double.POSITIVE_INFINITY/VALUE));
+      errn += verify("test_diva: ", 2, a0[2], (Double.NEGATIVE_INFINITY/VALUE));
+      errn += verify("test_diva: ", 3, a0[3], (Double.MAX_VALUE/VALUE));
+      errn += verify("test_diva: ", 4, a0[4], (Double.MIN_VALUE/VALUE));
+      errn += verify("test_diva: ", 5, a0[5], (Double.MIN_NORMAL/VALUE));
+      errn += verify("test_diva: ", 6, a0[6], ((ADD_INIT+6)/Double.NaN));
+      errn += verify("test_diva: ", 7, a0[7], ((ADD_INIT+7)/Double.POSITIVE_INFINITY));
+      errn += verify("test_diva: ", 8, a0[8], ((ADD_INIT+8)/Double.NEGATIVE_INFINITY));
+      errn += verify("test_diva: ", 9, a0[9], ((ADD_INIT+9)/Double.MAX_VALUE));
+      errn += verify("test_diva: ", 10, a0[10], ((ADD_INIT+10)/Double.MIN_VALUE));
+      errn += verify("test_diva: ", 11, a0[11], ((ADD_INIT+11)/Double.MIN_NORMAL));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_diva: ", i, a0[i], ((ADD_INIT+i)/VALUE));
+      }
+
+      test_mulc_n(a0, a1);
+      errn += verify("test_mulc_n: ", 0, a0[0], (Double.NaN*(-VALUE)));
+      errn += verify("test_mulc_n: ", 1, a0[1], (Double.POSITIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mulc_n: ", 2, a0[2], (Double.NEGATIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mulc_n: ", 3, a0[3], (Double.MAX_VALUE*(-VALUE)));
+      errn += verify("test_mulc_n: ", 4, a0[4], (Double.MIN_VALUE*(-VALUE)));
+      errn += verify("test_mulc_n: ", 5, a0[5], (Double.MIN_NORMAL*(-VALUE)));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_mulc_n: ", i, a0[i], ((ADD_INIT+i)*(-VALUE)));
+      }
+      test_mulv(a0, a1, -VALUE);
+      errn += verify("test_mulv_n: ", 0, a0[0], (Double.NaN*(-VALUE)));
+      errn += verify("test_mulv_n: ", 1, a0[1], (Double.POSITIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mulv_n: ", 2, a0[2], (Double.NEGATIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mulv_n: ", 3, a0[3], (Double.MAX_VALUE*(-VALUE)));
+      errn += verify("test_mulv_n: ", 4, a0[4], (Double.MIN_VALUE*(-VALUE)));
+      errn += verify("test_mulv_n: ", 5, a0[5], (Double.MIN_NORMAL*(-VALUE)));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_mulv_n: ", i, a0[i], ((ADD_INIT+i)*(-VALUE)));
+      }
+      test_mula(a0, a1, a3);
+      errn += verify("test_mula_n: ", 0, a0[0], (Double.NaN*(-VALUE)));
+      errn += verify("test_mula_n: ", 1, a0[1], (Double.POSITIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mula_n: ", 2, a0[2], (Double.NEGATIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mula_n: ", 3, a0[3], (Double.MAX_VALUE*(-VALUE)));
+      errn += verify("test_mula_n: ", 4, a0[4], (Double.MIN_VALUE*(-VALUE)));
+      errn += verify("test_mula_n: ", 5, a0[5], (Double.MIN_NORMAL*(-VALUE)));
+      errn += verify("test_mula_n: ", 6, a0[6], ((ADD_INIT+6)*(-Double.NaN)));
+      errn += verify("test_mula_n: ", 7, a0[7], ((ADD_INIT+7)*(-Double.POSITIVE_INFINITY)));
+      errn += verify("test_mula_n: ", 8, a0[8], ((ADD_INIT+8)*(-Double.NEGATIVE_INFINITY)));
+      errn += verify("test_mula_n: ", 9, a0[9], ((ADD_INIT+9)*(-Double.MAX_VALUE)));
+      errn += verify("test_mula_n: ", 10, a0[10], ((ADD_INIT+10)*(-Double.MIN_VALUE)));
+      errn += verify("test_mula_n: ", 11, a0[11], ((ADD_INIT+11)*(-Double.MIN_NORMAL)));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_mula_n: ", i, a0[i], ((ADD_INIT+i)*(-VALUE)));
+      }
+
+      test_divc_n(a0, a1);
+      errn += verify("test_divc_n: ", 0, a0[0], (Double.NaN/(-VALUE)));
+      errn += verify("test_divc_n: ", 1, a0[1], (Double.POSITIVE_INFINITY/(-VALUE)));
+      errn += verify("test_divc_n: ", 2, a0[2], (Double.NEGATIVE_INFINITY/(-VALUE)));
+      errn += verify("test_divc_n: ", 3, a0[3], (Double.MAX_VALUE/(-VALUE)));
+      errn += verify("test_divc_n: ", 4, a0[4], (Double.MIN_VALUE/(-VALUE)));
+      errn += verify("test_divc_n: ", 5, a0[5], (Double.MIN_NORMAL/(-VALUE)));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_divc_n: ", i, a0[i], ((ADD_INIT+i)/(-VALUE)));
+      }
+      test_divv(a0, a1, -VALUE);
+      errn += verify("test_divv_n: ", 0, a0[0], (Double.NaN/(-VALUE)));
+      errn += verify("test_divv_n: ", 1, a0[1], (Double.POSITIVE_INFINITY/(-VALUE)));
+      errn += verify("test_divv_n: ", 2, a0[2], (Double.NEGATIVE_INFINITY/(-VALUE)));
+      errn += verify("test_divv_n: ", 3, a0[3], (Double.MAX_VALUE/(-VALUE)));
+      errn += verify("test_divv_n: ", 4, a0[4], (Double.MIN_VALUE/(-VALUE)));
+      errn += verify("test_divv_n: ", 5, a0[5], (Double.MIN_NORMAL/(-VALUE)));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_divv_n: ", i, a0[i], ((ADD_INIT+i)/(-VALUE)));
+      }
+      test_diva(a0, a1, a3);
+      errn += verify("test_diva_n: ", 0, a0[0], (Double.NaN/(-VALUE)));
+      errn += verify("test_diva_n: ", 1, a0[1], (Double.POSITIVE_INFINITY/(-VALUE)));
+      errn += verify("test_diva_n: ", 2, a0[2], (Double.NEGATIVE_INFINITY/(-VALUE)));
+      errn += verify("test_diva_n: ", 3, a0[3], (Double.MAX_VALUE/(-VALUE)));
+      errn += verify("test_diva_n: ", 4, a0[4], (Double.MIN_VALUE/(-VALUE)));
+      errn += verify("test_diva_n: ", 5, a0[5], (Double.MIN_NORMAL/(-VALUE)));
+      errn += verify("test_diva_n: ", 6, a0[6], ((ADD_INIT+6)/(-Double.NaN)));
+      errn += verify("test_diva_n: ", 7, a0[7], ((ADD_INIT+7)/(-Double.POSITIVE_INFINITY)));
+      errn += verify("test_diva_n: ", 8, a0[8], ((ADD_INIT+8)/(-Double.NEGATIVE_INFINITY)));
+      errn += verify("test_diva_n: ", 9, a0[9], ((ADD_INIT+9)/(-Double.MAX_VALUE)));
+      errn += verify("test_diva_n: ", 10, a0[10], ((ADD_INIT+10)/(-Double.MIN_VALUE)));
+      errn += verify("test_diva_n: ", 11, a0[11], ((ADD_INIT+11)/(-Double.MIN_NORMAL)));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_diva_n: ", i, a0[i], ((ADD_INIT+i)/(-VALUE)));
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sum: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_adda(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_adda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_suba(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_suba: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva_n: " + (end - start));
+
+    return errn;
+  }
+
+  static double test_sum(double[] a1) {
+    double sum = 0;
+    for (int i = 0; i < a1.length; i+=1) {
+      sum += a1[i];
+    }
+    return sum;
+  }
+
+  static void test_addc(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]+VALUE);
+    }
+  }
+  static void test_addv(double[] a0, double[] a1, double b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]+b);
+    }
+  }
+  static void test_adda(double[] a0, double[] a1, double[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]+a2[i]);
+    }
+  }
+
+  static void test_subc(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]-VALUE);
+    }
+  }
+  static void test_subv(double[] a0, double[] a1, double b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]-b);
+    }
+  }
+  static void test_suba(double[] a0, double[] a1, double[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]-a2[i]);
+    }
+  }
+
+  static void test_mulc(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]*VALUE);
+    }
+  }
+  static void test_mulc_n(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]*(-VALUE));
+    }
+  }
+  static void test_mulv(double[] a0, double[] a1, double b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]*b);
+    }
+  }
+  static void test_mula(double[] a0, double[] a1, double[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]*a2[i]);
+    }
+  }
+
+  static void test_divc(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]/VALUE);
+    }
+  }
+  static void test_divc_n(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]/(-VALUE));
+    }
+  }
+  static void test_divv(double[] a0, double[] a1, double b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]/b);
+    }
+  }
+  static void test_diva(double[] a0, double[] a1, double[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]/a2[i]);
+    }
+  }
+
+  static int verify(String text, int i, double elem, double val) {
+    if (elem != val && !(Double.isNaN(elem) && Double.isNaN(val))) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/6340864/TestFloatVect.java b/hotspot/test/compiler/6340864/TestFloatVect.java
new file mode 100644
index 0000000..63f517c
--- /dev/null
+++ b/hotspot/test/compiler/6340864/TestFloatVect.java
@@ -0,0 +1,560 @@
+/*
+ * Copyright (c) 2012, 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 6340864
+ * @summary Implement vectorization optimizations in hotspot-server
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestFloatVect
+ */
+
+public class TestFloatVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final float ADD_INIT = -7500.f;
+  private static final float VALUE = 15.f;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Float vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    float[] a0 = new float[ARRLEN];
+    float[] a1 = new float[ARRLEN];
+    float[] a2 = new float[ARRLEN];
+    float[] a3 = new float[ARRLEN];
+    // Initialize
+    float gold_sum = 0;
+    for (int i=0; i<ARRLEN; i++) {
+      float val = ADD_INIT+(float)i;
+      gold_sum += val;
+      a1[i] = val;
+      a2[i] = VALUE;
+      a3[i] = -VALUE;
+    }
+
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+      test_addc(a0, a1);
+      test_addv(a0, a1, VALUE);
+      test_adda(a0, a1, a2);
+      test_subc(a0, a1);
+      test_subv(a0, a1, VALUE);
+      test_suba(a0, a1, a2);
+      test_mulc(a0, a1);
+      test_mulv(a0, a1, VALUE);
+      test_mula(a0, a1, a2);
+      test_divc(a0, a1);
+      test_divv(a0, a1, VALUE);
+      test_diva(a0, a1, a2);
+      test_mulc_n(a0, a1);
+      test_mulv(a0, a1, -VALUE);
+      test_mula(a0, a1, a3);
+      test_divc_n(a0, a1);
+      test_divv(a0, a1, -VALUE);
+      test_diva(a0, a1, a3);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      float sum = test_sum(a1);
+      if (sum != gold_sum) {
+        System.err.println("test_sum:  " + sum + " != " + gold_sum);
+        errn++;
+      }
+      // Overwrite with NaN values
+      a1[0] = Float.NaN;
+      a1[1] = Float.POSITIVE_INFINITY;
+      a1[2] = Float.NEGATIVE_INFINITY;
+      a1[3] = Float.MAX_VALUE;
+      a1[4] = Float.MIN_VALUE;
+      a1[5] = Float.MIN_NORMAL;
+
+      a2[6] = a1[0];
+      a2[7] = a1[1];
+      a2[8] = a1[2];
+      a2[9] = a1[3];
+      a2[10] = a1[4];
+      a2[11] = a1[5];
+
+      a3[6] = -a2[6];
+      a3[7] = -a2[7];
+      a3[8] = -a2[8];
+      a3[9] = -a2[9];
+      a3[10] = -a2[10];
+      a3[11] = -a2[11];
+
+      test_addc(a0, a1);
+      errn += verify("test_addc: ", 0, a0[0], (Float.NaN+VALUE));
+      errn += verify("test_addc: ", 1, a0[1], (Float.POSITIVE_INFINITY+VALUE));
+      errn += verify("test_addc: ", 2, a0[2], (Float.NEGATIVE_INFINITY+VALUE));
+      errn += verify("test_addc: ", 3, a0[3], (Float.MAX_VALUE+VALUE));
+      errn += verify("test_addc: ", 4, a0[4], (Float.MIN_VALUE+VALUE));
+      errn += verify("test_addc: ", 5, a0[5], (Float.MIN_NORMAL+VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], ((ADD_INIT+i)+VALUE));
+      }
+      test_addv(a0, a1, VALUE);
+      errn += verify("test_addv: ", 0, a0[0], (Float.NaN+VALUE));
+      errn += verify("test_addv: ", 1, a0[1], (Float.POSITIVE_INFINITY+VALUE));
+      errn += verify("test_addv: ", 2, a0[2], (Float.NEGATIVE_INFINITY+VALUE));
+      errn += verify("test_addv: ", 3, a0[3], (Float.MAX_VALUE+VALUE));
+      errn += verify("test_addv: ", 4, a0[4], (Float.MIN_VALUE+VALUE));
+      errn += verify("test_addv: ", 5, a0[5], (Float.MIN_NORMAL+VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], ((ADD_INIT+i)+VALUE));
+      }
+      test_adda(a0, a1, a2);
+      errn += verify("test_adda: ", 0, a0[0], (Float.NaN+VALUE));
+      errn += verify("test_adda: ", 1, a0[1], (Float.POSITIVE_INFINITY+VALUE));
+      errn += verify("test_adda: ", 2, a0[2], (Float.NEGATIVE_INFINITY+VALUE));
+      errn += verify("test_adda: ", 3, a0[3], (Float.MAX_VALUE+VALUE));
+      errn += verify("test_adda: ", 4, a0[4], (Float.MIN_VALUE+VALUE));
+      errn += verify("test_adda: ", 5, a0[5], (Float.MIN_NORMAL+VALUE));
+      errn += verify("test_adda: ", 6, a0[6], ((ADD_INIT+6)+Float.NaN));
+      errn += verify("test_adda: ", 7, a0[7], ((ADD_INIT+7)+Float.POSITIVE_INFINITY));
+      errn += verify("test_adda: ", 8, a0[8], ((ADD_INIT+8)+Float.NEGATIVE_INFINITY));
+      errn += verify("test_adda: ", 9, a0[9], ((ADD_INIT+9)+Float.MAX_VALUE));
+      errn += verify("test_adda: ", 10, a0[10], ((ADD_INIT+10)+Float.MIN_VALUE));
+      errn += verify("test_adda: ", 11, a0[11], ((ADD_INIT+11)+Float.MIN_NORMAL));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_adda: ", i, a0[i], ((ADD_INIT+i)+VALUE));
+      }
+
+      test_subc(a0, a1);
+      errn += verify("test_subc: ", 0, a0[0], (Float.NaN-VALUE));
+      errn += verify("test_subc: ", 1, a0[1], (Float.POSITIVE_INFINITY-VALUE));
+      errn += verify("test_subc: ", 2, a0[2], (Float.NEGATIVE_INFINITY-VALUE));
+      errn += verify("test_subc: ", 3, a0[3], (Float.MAX_VALUE-VALUE));
+      errn += verify("test_subc: ", 4, a0[4], (Float.MIN_VALUE-VALUE));
+      errn += verify("test_subc: ", 5, a0[5], (Float.MIN_NORMAL-VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_subc: ", i, a0[i], ((ADD_INIT+i)-VALUE));
+      }
+      test_subv(a0, a1, VALUE);
+      errn += verify("test_subv: ", 0, a0[0], (Float.NaN-VALUE));
+      errn += verify("test_subv: ", 1, a0[1], (Float.POSITIVE_INFINITY-VALUE));
+      errn += verify("test_subv: ", 2, a0[2], (Float.NEGATIVE_INFINITY-VALUE));
+      errn += verify("test_subv: ", 3, a0[3], (Float.MAX_VALUE-VALUE));
+      errn += verify("test_subv: ", 4, a0[4], (Float.MIN_VALUE-VALUE));
+      errn += verify("test_subv: ", 5, a0[5], (Float.MIN_NORMAL-VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_subv: ", i, a0[i], ((ADD_INIT+i)-VALUE));
+      }
+      test_suba(a0, a1, a2);
+      errn += verify("test_suba: ", 0, a0[0], (Float.NaN-VALUE));
+      errn += verify("test_suba: ", 1, a0[1], (Float.POSITIVE_INFINITY-VALUE));
+      errn += verify("test_suba: ", 2, a0[2], (Float.NEGATIVE_INFINITY-VALUE));
+      errn += verify("test_suba: ", 3, a0[3], (Float.MAX_VALUE-VALUE));
+      errn += verify("test_suba: ", 4, a0[4], (Float.MIN_VALUE-VALUE));
+      errn += verify("test_suba: ", 5, a0[5], (Float.MIN_NORMAL-VALUE));
+      errn += verify("test_suba: ", 6, a0[6], ((ADD_INIT+6)-Float.NaN));
+      errn += verify("test_suba: ", 7, a0[7], ((ADD_INIT+7)-Float.POSITIVE_INFINITY));
+      errn += verify("test_suba: ", 8, a0[8], ((ADD_INIT+8)-Float.NEGATIVE_INFINITY));
+      errn += verify("test_suba: ", 9, a0[9], ((ADD_INIT+9)-Float.MAX_VALUE));
+      errn += verify("test_suba: ", 10, a0[10], ((ADD_INIT+10)-Float.MIN_VALUE));
+      errn += verify("test_suba: ", 11, a0[11], ((ADD_INIT+11)-Float.MIN_NORMAL));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_suba: ", i, a0[i], ((ADD_INIT+i)-VALUE));
+      }
+
+      test_mulc(a0, a1);
+      errn += verify("test_mulc: ", 0, a0[0], (Float.NaN*VALUE));
+      errn += verify("test_mulc: ", 1, a0[1], (Float.POSITIVE_INFINITY*VALUE));
+      errn += verify("test_mulc: ", 2, a0[2], (Float.NEGATIVE_INFINITY*VALUE));
+      errn += verify("test_mulc: ", 3, a0[3], (Float.MAX_VALUE*VALUE));
+      errn += verify("test_mulc: ", 4, a0[4], (Float.MIN_VALUE*VALUE));
+      errn += verify("test_mulc: ", 5, a0[5], (Float.MIN_NORMAL*VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_mulc: ", i, a0[i], ((ADD_INIT+i)*VALUE));
+      }
+      test_mulv(a0, a1, VALUE);
+      errn += verify("test_mulv: ", 0, a0[0], (Float.NaN*VALUE));
+      errn += verify("test_mulv: ", 1, a0[1], (Float.POSITIVE_INFINITY*VALUE));
+      errn += verify("test_mulv: ", 2, a0[2], (Float.NEGATIVE_INFINITY*VALUE));
+      errn += verify("test_mulv: ", 3, a0[3], (Float.MAX_VALUE*VALUE));
+      errn += verify("test_mulv: ", 4, a0[4], (Float.MIN_VALUE*VALUE));
+      errn += verify("test_mulv: ", 5, a0[5], (Float.MIN_NORMAL*VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_mulv: ", i, a0[i], ((ADD_INIT+i)*VALUE));
+      }
+      test_mula(a0, a1, a2);
+      errn += verify("test_mula: ", 0, a0[0], (Float.NaN*VALUE));
+      errn += verify("test_mula: ", 1, a0[1], (Float.POSITIVE_INFINITY*VALUE));
+      errn += verify("test_mula: ", 2, a0[2], (Float.NEGATIVE_INFINITY*VALUE));
+      errn += verify("test_mula: ", 3, a0[3], (Float.MAX_VALUE*VALUE));
+      errn += verify("test_mula: ", 4, a0[4], (Float.MIN_VALUE*VALUE));
+      errn += verify("test_mula: ", 5, a0[5], (Float.MIN_NORMAL*VALUE));
+      errn += verify("test_mula: ", 6, a0[6], ((ADD_INIT+6)*Float.NaN));
+      errn += verify("test_mula: ", 7, a0[7], ((ADD_INIT+7)*Float.POSITIVE_INFINITY));
+      errn += verify("test_mula: ", 8, a0[8], ((ADD_INIT+8)*Float.NEGATIVE_INFINITY));
+      errn += verify("test_mula: ", 9, a0[9], ((ADD_INIT+9)*Float.MAX_VALUE));
+      errn += verify("test_mula: ", 10, a0[10], ((ADD_INIT+10)*Float.MIN_VALUE));
+      errn += verify("test_mula: ", 11, a0[11], ((ADD_INIT+11)*Float.MIN_NORMAL));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_mula: ", i, a0[i], ((ADD_INIT+i)*VALUE));
+      }
+
+      test_divc(a0, a1);
+      errn += verify("test_divc: ", 0, a0[0], (Float.NaN/VALUE));
+      errn += verify("test_divc: ", 1, a0[1], (Float.POSITIVE_INFINITY/VALUE));
+      errn += verify("test_divc: ", 2, a0[2], (Float.NEGATIVE_INFINITY/VALUE));
+      errn += verify("test_divc: ", 3, a0[3], (Float.MAX_VALUE/VALUE));
+      errn += verify("test_divc: ", 4, a0[4], (Float.MIN_VALUE/VALUE));
+      errn += verify("test_divc: ", 5, a0[5], (Float.MIN_NORMAL/VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_divc: ", i, a0[i], ((ADD_INIT+i)/VALUE));
+      }
+      test_divv(a0, a1, VALUE);
+      errn += verify("test_divv: ", 0, a0[0], (Float.NaN/VALUE));
+      errn += verify("test_divv: ", 1, a0[1], (Float.POSITIVE_INFINITY/VALUE));
+      errn += verify("test_divv: ", 2, a0[2], (Float.NEGATIVE_INFINITY/VALUE));
+      errn += verify("test_divv: ", 3, a0[3], (Float.MAX_VALUE/VALUE));
+      errn += verify("test_divv: ", 4, a0[4], (Float.MIN_VALUE/VALUE));
+      errn += verify("test_divv: ", 5, a0[5], (Float.MIN_NORMAL/VALUE));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_divv: ", i, a0[i], ((ADD_INIT+i)/VALUE));
+      }
+      test_diva(a0, a1, a2);
+      errn += verify("test_diva: ", 0, a0[0], (Float.NaN/VALUE));
+      errn += verify("test_diva: ", 1, a0[1], (Float.POSITIVE_INFINITY/VALUE));
+      errn += verify("test_diva: ", 2, a0[2], (Float.NEGATIVE_INFINITY/VALUE));
+      errn += verify("test_diva: ", 3, a0[3], (Float.MAX_VALUE/VALUE));
+      errn += verify("test_diva: ", 4, a0[4], (Float.MIN_VALUE/VALUE));
+      errn += verify("test_diva: ", 5, a0[5], (Float.MIN_NORMAL/VALUE));
+      errn += verify("test_diva: ", 6, a0[6], ((ADD_INIT+6)/Float.NaN));
+      errn += verify("test_diva: ", 7, a0[7], ((ADD_INIT+7)/Float.POSITIVE_INFINITY));
+      errn += verify("test_diva: ", 8, a0[8], ((ADD_INIT+8)/Float.NEGATIVE_INFINITY));
+      errn += verify("test_diva: ", 9, a0[9], ((ADD_INIT+9)/Float.MAX_VALUE));
+      errn += verify("test_diva: ", 10, a0[10], ((ADD_INIT+10)/Float.MIN_VALUE));
+      errn += verify("test_diva: ", 11, a0[11], ((ADD_INIT+11)/Float.MIN_NORMAL));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_diva: ", i, a0[i], ((ADD_INIT+i)/VALUE));
+      }
+
+      test_mulc_n(a0, a1);
+      errn += verify("test_mulc_n: ", 0, a0[0], (Float.NaN*(-VALUE)));
+      errn += verify("test_mulc_n: ", 1, a0[1], (Float.POSITIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mulc_n: ", 2, a0[2], (Float.NEGATIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mulc_n: ", 3, a0[3], (Float.MAX_VALUE*(-VALUE)));
+      errn += verify("test_mulc_n: ", 4, a0[4], (Float.MIN_VALUE*(-VALUE)));
+      errn += verify("test_mulc_n: ", 5, a0[5], (Float.MIN_NORMAL*(-VALUE)));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_mulc_n: ", i, a0[i], ((ADD_INIT+i)*(-VALUE)));
+      }
+      test_mulv(a0, a1, -VALUE);
+      errn += verify("test_mulv_n: ", 0, a0[0], (Float.NaN*(-VALUE)));
+      errn += verify("test_mulv_n: ", 1, a0[1], (Float.POSITIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mulv_n: ", 2, a0[2], (Float.NEGATIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mulv_n: ", 3, a0[3], (Float.MAX_VALUE*(-VALUE)));
+      errn += verify("test_mulv_n: ", 4, a0[4], (Float.MIN_VALUE*(-VALUE)));
+      errn += verify("test_mulv_n: ", 5, a0[5], (Float.MIN_NORMAL*(-VALUE)));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_mulv_n: ", i, a0[i], ((ADD_INIT+i)*(-VALUE)));
+      }
+      test_mula(a0, a1, a3);
+      errn += verify("test_mula_n: ", 0, a0[0], (Float.NaN*(-VALUE)));
+      errn += verify("test_mula_n: ", 1, a0[1], (Float.POSITIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mula_n: ", 2, a0[2], (Float.NEGATIVE_INFINITY*(-VALUE)));
+      errn += verify("test_mula_n: ", 3, a0[3], (Float.MAX_VALUE*(-VALUE)));
+      errn += verify("test_mula_n: ", 4, a0[4], (Float.MIN_VALUE*(-VALUE)));
+      errn += verify("test_mula_n: ", 5, a0[5], (Float.MIN_NORMAL*(-VALUE)));
+      errn += verify("test_mula_n: ", 6, a0[6], ((ADD_INIT+6)*(-Float.NaN)));
+      errn += verify("test_mula_n: ", 7, a0[7], ((ADD_INIT+7)*(-Float.POSITIVE_INFINITY)));
+      errn += verify("test_mula_n: ", 8, a0[8], ((ADD_INIT+8)*(-Float.NEGATIVE_INFINITY)));
+      errn += verify("test_mula_n: ", 9, a0[9], ((ADD_INIT+9)*(-Float.MAX_VALUE)));
+      errn += verify("test_mula_n: ", 10, a0[10], ((ADD_INIT+10)*(-Float.MIN_VALUE)));
+      errn += verify("test_mula_n: ", 11, a0[11], ((ADD_INIT+11)*(-Float.MIN_NORMAL)));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_mula_n: ", i, a0[i], ((ADD_INIT+i)*(-VALUE)));
+      }
+
+      test_divc_n(a0, a1);
+      errn += verify("test_divc_n: ", 0, a0[0], (Float.NaN/(-VALUE)));
+      errn += verify("test_divc_n: ", 1, a0[1], (Float.POSITIVE_INFINITY/(-VALUE)));
+      errn += verify("test_divc_n: ", 2, a0[2], (Float.NEGATIVE_INFINITY/(-VALUE)));
+      errn += verify("test_divc_n: ", 3, a0[3], (Float.MAX_VALUE/(-VALUE)));
+      errn += verify("test_divc_n: ", 4, a0[4], (Float.MIN_VALUE/(-VALUE)));
+      errn += verify("test_divc_n: ", 5, a0[5], (Float.MIN_NORMAL/(-VALUE)));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_divc_n: ", i, a0[i], ((ADD_INIT+i)/(-VALUE)));
+      }
+      test_divv(a0, a1, -VALUE);
+      errn += verify("test_divv_n: ", 0, a0[0], (Float.NaN/(-VALUE)));
+      errn += verify("test_divv_n: ", 1, a0[1], (Float.POSITIVE_INFINITY/(-VALUE)));
+      errn += verify("test_divv_n: ", 2, a0[2], (Float.NEGATIVE_INFINITY/(-VALUE)));
+      errn += verify("test_divv_n: ", 3, a0[3], (Float.MAX_VALUE/(-VALUE)));
+      errn += verify("test_divv_n: ", 4, a0[4], (Float.MIN_VALUE/(-VALUE)));
+      errn += verify("test_divv_n: ", 5, a0[5], (Float.MIN_NORMAL/(-VALUE)));
+      for (int i=6; i<ARRLEN; i++) {
+        errn += verify("test_divv_n: ", i, a0[i], ((ADD_INIT+i)/(-VALUE)));
+      }
+      test_diva(a0, a1, a3);
+      errn += verify("test_diva_n: ", 0, a0[0], (Float.NaN/(-VALUE)));
+      errn += verify("test_diva_n: ", 1, a0[1], (Float.POSITIVE_INFINITY/(-VALUE)));
+      errn += verify("test_diva_n: ", 2, a0[2], (Float.NEGATIVE_INFINITY/(-VALUE)));
+      errn += verify("test_diva_n: ", 3, a0[3], (Float.MAX_VALUE/(-VALUE)));
+      errn += verify("test_diva_n: ", 4, a0[4], (Float.MIN_VALUE/(-VALUE)));
+      errn += verify("test_diva_n: ", 5, a0[5], (Float.MIN_NORMAL/(-VALUE)));
+      errn += verify("test_diva_n: ", 6, a0[6], ((ADD_INIT+6)/(-Float.NaN)));
+      errn += verify("test_diva_n: ", 7, a0[7], ((ADD_INIT+7)/(-Float.POSITIVE_INFINITY)));
+      errn += verify("test_diva_n: ", 8, a0[8], ((ADD_INIT+8)/(-Float.NEGATIVE_INFINITY)));
+      errn += verify("test_diva_n: ", 9, a0[9], ((ADD_INIT+9)/(-Float.MAX_VALUE)));
+      errn += verify("test_diva_n: ", 10, a0[10], ((ADD_INIT+10)/(-Float.MIN_VALUE)));
+      errn += verify("test_diva_n: ", 11, a0[11], ((ADD_INIT+11)/(-Float.MIN_NORMAL)));
+      for (int i=12; i<ARRLEN; i++) {
+        errn += verify("test_diva_n: ", i, a0[i], ((ADD_INIT+i)/(-VALUE)));
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sum: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_adda(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_adda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_suba(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_suba: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva_n: " + (end - start));
+
+    return errn;
+  }
+
+  static float test_sum(float[] a1) {
+    float sum = 0;
+    for (int i = 0; i < a1.length; i+=1) {
+      sum += a1[i];
+    }
+    return sum;
+  }
+
+  static void test_addc(float[] a0, float[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]+VALUE);
+    }
+  }
+  static void test_addv(float[] a0, float[] a1, float b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]+b);
+    }
+  }
+  static void test_adda(float[] a0, float[] a1, float[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]+a2[i]);
+    }
+  }
+
+  static void test_subc(float[] a0, float[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]-VALUE);
+    }
+  }
+  static void test_subv(float[] a0, float[] a1, float b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]-b);
+    }
+  }
+  static void test_suba(float[] a0, float[] a1, float[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]-a2[i]);
+    }
+  }
+
+  static void test_mulc(float[] a0, float[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]*VALUE);
+    }
+  }
+  static void test_mulc_n(float[] a0, float[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]*(-VALUE));
+    }
+  }
+  static void test_mulv(float[] a0, float[] a1, float b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]*b);
+    }
+  }
+  static void test_mula(float[] a0, float[] a1, float[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]*a2[i]);
+    }
+  }
+
+  static void test_divc(float[] a0, float[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]/VALUE);
+    }
+  }
+  static void test_divc_n(float[] a0, float[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]/(-VALUE));
+    }
+  }
+  static void test_divv(float[] a0, float[] a1, float b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]/b);
+    }
+  }
+  static void test_diva(float[] a0, float[] a1, float[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (a1[i]/a2[i]);
+    }
+  }
+
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val && !(Float.isNaN(elem) && Float.isNaN(val))) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/6340864/TestIntVect.java b/hotspot/test/compiler/6340864/TestIntVect.java
new file mode 100644
index 0000000..5866b34
--- /dev/null
+++ b/hotspot/test/compiler/6340864/TestIntVect.java
@@ -0,0 +1,1225 @@
+/*
+ * Copyright (c) 2012, 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 6340864
+ * @summary Implement vectorization optimizations in hotspot-server
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestIntVect
+ */
+
+public class TestIntVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int ADD_INIT = Integer.MAX_VALUE-500;
+  private static final int BIT_MASK = 0xEC80F731;
+  private static final int VALUE = 15;
+  private static final int SHIFT = 32;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Integer vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    int[] a0 = new int[ARRLEN];
+    int[] a1 = new int[ARRLEN];
+    int[] a2 = new int[ARRLEN];
+    int[] a3 = new int[ARRLEN];
+    int[] a4 = new int[ARRLEN];
+    long[] p2 = new long[ARRLEN/2];
+    // Initialize
+    int gold_sum = 0;
+    for (int i=0; i<ARRLEN; i++) {
+      int val = (int)(ADD_INIT+i);
+      gold_sum += val;
+      a1[i] = val;
+      a2[i] = (int)VALUE;
+      a3[i] = (int)-VALUE;
+      a4[i] = (int)BIT_MASK;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+      test_addc(a0, a1);
+      test_addv(a0, a1, (int)VALUE);
+      test_adda(a0, a1, a2);
+      test_subc(a0, a1);
+      test_subv(a0, a1, (int)VALUE);
+      test_suba(a0, a1, a2);
+
+      test_mulc(a0, a1);
+      test_mulv(a0, a1, (int)VALUE);
+      test_mula(a0, a1, a2);
+      test_divc(a0, a1);
+      test_divv(a0, a1, (int)VALUE);
+      test_diva(a0, a1, a2);
+      test_mulc_n(a0, a1);
+      test_mulv(a0, a1, (int)-VALUE);
+      test_mula(a0, a1, a3);
+      test_divc_n(a0, a1);
+      test_divv(a0, a1, (int)-VALUE);
+      test_diva(a0, a1, a3);
+
+      test_andc(a0, a1);
+      test_andv(a0, a1, (int)BIT_MASK);
+      test_anda(a0, a1, a4);
+      test_orc(a0, a1);
+      test_orv(a0, a1, (int)BIT_MASK);
+      test_ora(a0, a1, a4);
+      test_xorc(a0, a1);
+      test_xorv(a0, a1, (int)BIT_MASK);
+      test_xora(a0, a1, a4);
+
+      test_sllc(a0, a1);
+      test_sllv(a0, a1, VALUE);
+      test_srlc(a0, a1);
+      test_srlv(a0, a1, VALUE);
+      test_srac(a0, a1);
+      test_srav(a0, a1, VALUE);
+
+      test_sllc_n(a0, a1);
+      test_sllv(a0, a1, -VALUE);
+      test_srlc_n(a0, a1);
+      test_srlv(a0, a1, -VALUE);
+      test_srac_n(a0, a1);
+      test_srav(a0, a1, -VALUE);
+
+      test_sllc_o(a0, a1);
+      test_sllv(a0, a1, SHIFT);
+      test_srlc_o(a0, a1);
+      test_srlv(a0, a1, SHIFT);
+      test_srac_o(a0, a1);
+      test_srav(a0, a1, SHIFT);
+
+      test_sllc_on(a0, a1);
+      test_sllv(a0, a1, -SHIFT);
+      test_srlc_on(a0, a1);
+      test_srlv(a0, a1, -SHIFT);
+      test_srac_on(a0, a1);
+      test_srav(a0, a1, -SHIFT);
+
+      test_sllc_add(a0, a1);
+      test_sllv_add(a0, a1, ADD_INIT);
+      test_srlc_add(a0, a1);
+      test_srlv_add(a0, a1, ADD_INIT);
+      test_srac_add(a0, a1);
+      test_srav_add(a0, a1, ADD_INIT);
+
+      test_sllc_and(a0, a1);
+      test_sllv_and(a0, a1, BIT_MASK);
+      test_srlc_and(a0, a1);
+      test_srlv_and(a0, a1, BIT_MASK);
+      test_srac_and(a0, a1);
+      test_srav_and(a0, a1, BIT_MASK);
+
+      test_pack2(p2, a1);
+      test_unpack2(a0, p2);
+      test_pack2_swap(p2, a1);
+      test_unpack2_swap(a0, p2);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      int sum = test_sum(a1);
+      if (sum != gold_sum) {
+        System.err.println("test_sum:  " + sum + " != " + gold_sum);
+        errn++;
+      }
+
+      test_addc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], (int)((int)(ADD_INIT+i)+VALUE));
+      }
+      test_addv(a0, a1, (int)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], (int)((int)(ADD_INIT+i)+VALUE));
+      }
+      test_adda(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_adda: ", i, a0[i], (int)((int)(ADD_INIT+i)+VALUE));
+      }
+
+      test_subc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subc: ", i, a0[i], (int)((int)(ADD_INIT+i)-VALUE));
+      }
+      test_subv(a0, a1, (int)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subv: ", i, a0[i], (int)((int)(ADD_INIT+i)-VALUE));
+      }
+      test_suba(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_suba: ", i, a0[i], (int)((int)(ADD_INIT+i)-VALUE));
+      }
+
+      test_mulc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc: ", i, a0[i], (int)((int)(ADD_INIT+i)*VALUE));
+      }
+      test_mulv(a0, a1, (int)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv: ", i, a0[i], (int)((int)(ADD_INIT+i)*VALUE));
+      }
+      test_mula(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula: ", i, a0[i], (int)((int)(ADD_INIT+i)*VALUE));
+      }
+
+      test_divc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc: ", i, a0[i], (int)((int)(ADD_INIT+i)/VALUE));
+      }
+      test_divv(a0, a1, (int)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv: ", i, a0[i], (int)((int)(ADD_INIT+i)/VALUE));
+      }
+      test_diva(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva: ", i, a0[i], (int)((int)(ADD_INIT+i)/VALUE));
+      }
+
+      test_mulc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc_n: ", i, a0[i], (int)((int)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mulv(a0, a1, (int)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv_n: ", i, a0[i], (int)((int)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mula(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula_n: ", i, a0[i], (int)((int)(ADD_INIT+i)*(-VALUE)));
+      }
+
+      test_divc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc_n: ", i, a0[i], (int)((int)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_divv(a0, a1, (int)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv_n: ", i, a0[i], (int)((int)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_diva(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva_n: ", i, a0[i], (int)((int)(ADD_INIT+i)/(-VALUE)));
+      }
+
+      test_andc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andc: ", i, a0[i], (int)((int)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_andv(a0, a1, (int)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andv: ", i, a0[i], (int)((int)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_anda(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_anda: ", i, a0[i], (int)((int)(ADD_INIT+i)&BIT_MASK));
+      }
+
+      test_orc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orc: ", i, a0[i], (int)((int)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_orv(a0, a1, (int)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orv: ", i, a0[i], (int)((int)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_ora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ora: ", i, a0[i], (int)((int)(ADD_INIT+i)|BIT_MASK));
+      }
+
+      test_xorc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorc: ", i, a0[i], (int)((int)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xorv(a0, a1, (int)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorv: ", i, a0[i], (int)((int)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xora: ", i, a0[i], (int)((int)(ADD_INIT+i)^BIT_MASK));
+      }
+
+      test_sllc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc: ", i, a0[i], (int)((int)(ADD_INIT+i)<<VALUE));
+      }
+      test_sllv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv: ", i, a0[i], (int)((int)(ADD_INIT+i)<<VALUE));
+      }
+
+      test_srlc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>VALUE));
+      }
+      test_srlv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>VALUE));
+      }
+
+      test_srac(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac: ", i, a0[i], (int)((int)(ADD_INIT+i)>>VALUE));
+      }
+      test_srav(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav: ", i, a0[i], (int)((int)(ADD_INIT+i)>>VALUE));
+      }
+
+      test_sllc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_n: ", i, a0[i], (int)((int)(ADD_INIT+i)<<(-VALUE)));
+      }
+      test_sllv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_n: ", i, a0[i], (int)((int)(ADD_INIT+i)<<(-VALUE)));
+      }
+
+      test_srlc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_n: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>(-VALUE)));
+      }
+      test_srlv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_n: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>(-VALUE)));
+      }
+
+      test_srac_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_n: ", i, a0[i], (int)((int)(ADD_INIT+i)>>(-VALUE)));
+      }
+      test_srav(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_n: ", i, a0[i], (int)((int)(ADD_INIT+i)>>(-VALUE)));
+      }
+
+      test_sllc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_o: ", i, a0[i], (int)((int)(ADD_INIT+i)<<SHIFT));
+      }
+      test_sllv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_o: ", i, a0[i], (int)((int)(ADD_INIT+i)<<SHIFT));
+      }
+
+      test_srlc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_o: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>SHIFT));
+      }
+      test_srlv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_o: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>SHIFT));
+      }
+
+      test_srac_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_o: ", i, a0[i], (int)((int)(ADD_INIT+i)>>SHIFT));
+      }
+      test_srav(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_o: ", i, a0[i], (int)((int)(ADD_INIT+i)>>SHIFT));
+      }
+
+      test_sllc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_on: ", i, a0[i], (int)((int)(ADD_INIT+i)<<(-SHIFT)));
+      }
+      test_sllv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_on: ", i, a0[i], (int)((int)(ADD_INIT+i)<<(-SHIFT)));
+      }
+
+      test_srlc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_on: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+      test_srlv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_on: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+
+      test_srac_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_on: ", i, a0[i], (int)((int)(ADD_INIT+i)>>(-SHIFT)));
+      }
+      test_srav(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_on: ", i, a0[i], (int)((int)(ADD_INIT+i)>>(-SHIFT)));
+      }
+
+      test_sllc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_add: ", i, a0[i], (int)(((int)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+      test_sllv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_add: ", i, a0[i], (int)(((int)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+
+      test_srlc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_add: ", i, a0[i], (int)(((int)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+      test_srlv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_add: ", i, a0[i], (int)(((int)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+
+      test_srac_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_add: ", i, a0[i], (int)(((int)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+      test_srav_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_add: ", i, a0[i], (int)(((int)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+
+      test_sllc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_and: ", i, a0[i], (int)(((int)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+      test_sllv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_and: ", i, a0[i], (int)(((int)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+
+      test_srlc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_and: ", i, a0[i], (int)(((int)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+      test_srlv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_and: ", i, a0[i], (int)(((int)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+
+      test_srac_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_and: ", i, a0[i], (int)(((int)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+      test_srav_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_and: ", i, a0[i], (int)(((int)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+
+      test_pack2(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2: ", i, p2[i], ((long)(ADD_INIT+2*i) & 0xFFFFFFFFl) | ((long)(ADD_INIT+2*i+1) << 32));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack2(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2: ", i, a0[i], (ADD_INIT+i));
+      }
+
+      test_pack2_swap(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2_swap: ", i, p2[i], ((long)(ADD_INIT+2*i+1) & 0xFFFFFFFFl) | ((long)(ADD_INIT+2*i) << 32));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack2_swap(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2_swap: ", i, a0[i], (ADD_INIT+i));
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sum: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addv(a0, a1, (int)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_adda(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_adda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subv(a0, a1, (int)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_suba(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_suba: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (int)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, (int)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (int)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, (int)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andv(a0, a1, (int)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_anda(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_anda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orv(a0, a1, (int)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorv(a0, a1, (int)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack2(p2, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack2: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack2(a0, p2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack2: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack2_swap(p2, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack2_swap: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack2_swap(a0, p2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack2_swap: " + (end - start));
+
+    return errn;
+  }
+
+  static int test_sum(int[] a1) {
+    int sum = 0;
+    for (int i = 0; i < a1.length; i+=1) {
+      sum += a1[i];
+    }
+    return sum;
+  }
+
+  static void test_addc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]+VALUE);
+    }
+  }
+  static void test_addv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]+b);
+    }
+  }
+  static void test_adda(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]+a2[i]);
+    }
+  }
+
+  static void test_subc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]-VALUE);
+    }
+  }
+  static void test_subv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]-b);
+    }
+  }
+  static void test_suba(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]-a2[i]);
+    }
+  }
+
+  static void test_mulc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]*VALUE);
+    }
+  }
+  static void test_mulc_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]*(-VALUE));
+    }
+  }
+  static void test_mulv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]*b);
+    }
+  }
+  static void test_mula(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]*a2[i]);
+    }
+  }
+
+  static void test_divc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]/VALUE);
+    }
+  }
+  static void test_divc_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]/(-VALUE));
+    }
+  }
+  static void test_divv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]/b);
+    }
+  }
+  static void test_diva(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]/a2[i]);
+    }
+  }
+
+  static void test_andc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]&BIT_MASK);
+    }
+  }
+  static void test_andv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]&b);
+    }
+  }
+  static void test_anda(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]&a2[i]);
+    }
+  }
+
+  static void test_orc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]|BIT_MASK);
+    }
+  }
+  static void test_orv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]|b);
+    }
+  }
+  static void test_ora(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]|a2[i]);
+    }
+  }
+
+  static void test_xorc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]^BIT_MASK);
+    }
+  }
+  static void test_xorv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]^b);
+    }
+  }
+  static void test_xora(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]^a2[i]);
+    }
+  }
+
+  static void test_sllc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<VALUE);
+    }
+  }
+  static void test_sllc_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<(-VALUE));
+    }
+  }
+  static void test_sllc_o(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<SHIFT);
+    }
+  }
+  static void test_sllc_on(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<(-SHIFT));
+    }
+  }
+  static void test_sllv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<b);
+    }
+  }
+  static void test_sllc_add(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] + ADD_INIT)<<VALUE);
+    }
+  }
+  static void test_sllv_add(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] + b)<<VALUE);
+    }
+  }
+  static void test_sllc_and(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] & BIT_MASK)<<VALUE);
+    }
+  }
+  static void test_sllv_and(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] & b)<<VALUE);
+    }
+  }
+
+  static void test_srlc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>VALUE);
+    }
+  }
+  static void test_srlc_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>(-VALUE));
+    }
+  }
+  static void test_srlc_o(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>SHIFT);
+    }
+  }
+  static void test_srlc_on(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>(-SHIFT));
+    }
+  }
+  static void test_srlv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>b);
+    }
+  }
+  static void test_srlc_add(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] + ADD_INIT)>>>VALUE);
+    }
+  }
+  static void test_srlv_add(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] + b)>>>VALUE);
+    }
+  }
+  static void test_srlc_and(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] & BIT_MASK)>>>VALUE);
+    }
+  }
+  static void test_srlv_and(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] & b)>>>VALUE);
+    }
+  }
+
+  static void test_srac(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>VALUE);
+    }
+  }
+  static void test_srac_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>(-VALUE));
+    }
+  }
+  static void test_srac_o(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>SHIFT);
+    }
+  }
+  static void test_srac_on(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>(-SHIFT));
+    }
+  }
+  static void test_srav(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>b);
+    }
+  }
+  static void test_srac_add(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] + ADD_INIT)>>VALUE);
+    }
+  }
+  static void test_srav_add(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] + b)>>VALUE);
+    }
+  }
+  static void test_srac_and(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] & BIT_MASK)>>VALUE);
+    }
+  }
+  static void test_srav_and(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)((a1[i] & b)>>VALUE);
+    }
+  }
+
+  static void test_pack2(long[] p2, int[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      long l0 = (long)a1[i*2+0];
+      long l1 = (long)a1[i*2+1];
+      p2[i] = (l1 << 32) | (l0 & 0xFFFFFFFFl);
+    }
+  }
+  static void test_unpack2(int[] a0, long[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      long l = p2[i];
+      a0[i*2+0] = (int)(l & 0xFFFFFFFFl);
+      a0[i*2+1] = (int)(l >> 32);
+    }
+  }
+  static void test_pack2_swap(long[] p2, int[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      long l0 = (long)a1[i*2+0];
+      long l1 = (long)a1[i*2+1];
+      p2[i] = (l0 << 32) | (l1 & 0xFFFFFFFFl);
+    }
+  }
+  static void test_unpack2_swap(int[] a0, long[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      long l = p2[i];
+      a0[i*2+0] = (int)(l >> 32);
+      a0[i*2+1] = (int)(l & 0xFFFFFFFFl);
+    }
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + Long.toHexString(elem) + " != " + Long.toHexString(val));
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/6340864/TestLongVect.java b/hotspot/test/compiler/6340864/TestLongVect.java
new file mode 100644
index 0000000..436a847
--- /dev/null
+++ b/hotspot/test/compiler/6340864/TestLongVect.java
@@ -0,0 +1,1129 @@
+/*
+ * Copyright (c) 2012, 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 6340864
+ * @summary Implement vectorization optimizations in hotspot-server
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestLongVect
+ */
+
+public class TestLongVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final long ADD_INIT = Long.MAX_VALUE-500;
+  private static final long BIT_MASK = 0xEC80F731EC80F731L;
+  private static final int VALUE = 31;
+  private static final int SHIFT = 64;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Long vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    long[] a0 = new long[ARRLEN];
+    long[] a1 = new long[ARRLEN];
+    long[] a2 = new long[ARRLEN];
+    long[] a3 = new long[ARRLEN];
+    long[] a4 = new long[ARRLEN];
+    // Initialize
+    long gold_sum = 0;
+    for (int i=0; i<ARRLEN; i++) {
+      long val = (long)(ADD_INIT+i);
+      gold_sum += val;
+      a1[i] = val;
+      a2[i] = (long)VALUE;
+      a3[i] = (long)-VALUE;
+      a4[i] = (long)BIT_MASK;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+      test_addc(a0, a1);
+      test_addv(a0, a1, (long)VALUE);
+      test_adda(a0, a1, a2);
+      test_subc(a0, a1);
+      test_subv(a0, a1, (long)VALUE);
+      test_suba(a0, a1, a2);
+
+      test_mulc(a0, a1);
+      test_mulv(a0, a1, (long)VALUE);
+      test_mula(a0, a1, a2);
+      test_divc(a0, a1);
+      test_divv(a0, a1, (long)VALUE);
+      test_diva(a0, a1, a2);
+      test_mulc_n(a0, a1);
+      test_mulv(a0, a1, (long)-VALUE);
+      test_mula(a0, a1, a3);
+      test_divc_n(a0, a1);
+      test_divv(a0, a1, (long)-VALUE);
+      test_diva(a0, a1, a3);
+
+      test_andc(a0, a1);
+      test_andv(a0, a1, (long)BIT_MASK);
+      test_anda(a0, a1, a4);
+      test_orc(a0, a1);
+      test_orv(a0, a1, (long)BIT_MASK);
+      test_ora(a0, a1, a4);
+      test_xorc(a0, a1);
+      test_xorv(a0, a1, (long)BIT_MASK);
+      test_xora(a0, a1, a4);
+
+      test_sllc(a0, a1);
+      test_sllv(a0, a1, VALUE);
+      test_srlc(a0, a1);
+      test_srlv(a0, a1, VALUE);
+      test_srac(a0, a1);
+      test_srav(a0, a1, VALUE);
+
+      test_sllc_n(a0, a1);
+      test_sllv(a0, a1, -VALUE);
+      test_srlc_n(a0, a1);
+      test_srlv(a0, a1, -VALUE);
+      test_srac_n(a0, a1);
+      test_srav(a0, a1, -VALUE);
+
+      test_sllc_o(a0, a1);
+      test_sllv(a0, a1, SHIFT);
+      test_srlc_o(a0, a1);
+      test_srlv(a0, a1, SHIFT);
+      test_srac_o(a0, a1);
+      test_srav(a0, a1, SHIFT);
+
+      test_sllc_on(a0, a1);
+      test_sllv(a0, a1, -SHIFT);
+      test_srlc_on(a0, a1);
+      test_srlv(a0, a1, -SHIFT);
+      test_srac_on(a0, a1);
+      test_srav(a0, a1, -SHIFT);
+
+      test_sllc_add(a0, a1);
+      test_sllv_add(a0, a1, ADD_INIT);
+      test_srlc_add(a0, a1);
+      test_srlv_add(a0, a1, ADD_INIT);
+      test_srac_add(a0, a1);
+      test_srav_add(a0, a1, ADD_INIT);
+
+      test_sllc_and(a0, a1);
+      test_sllv_and(a0, a1, BIT_MASK);
+      test_srlc_and(a0, a1);
+      test_srlv_and(a0, a1, BIT_MASK);
+      test_srac_and(a0, a1);
+      test_srav_and(a0, a1, BIT_MASK);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      long sum = test_sum(a1);
+      if (sum != gold_sum) {
+        System.err.println("test_sum:  " + sum + " != " + gold_sum);
+        errn++;
+      }
+
+      test_addc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], (long)((long)(ADD_INIT+i)+VALUE));
+      }
+      test_addv(a0, a1, (long)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], (long)((long)(ADD_INIT+i)+VALUE));
+      }
+      test_adda(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_adda: ", i, a0[i], (long)((long)(ADD_INIT+i)+VALUE));
+      }
+
+      test_subc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subc: ", i, a0[i], (long)((long)(ADD_INIT+i)-VALUE));
+      }
+      test_subv(a0, a1, (long)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subv: ", i, a0[i], (long)((long)(ADD_INIT+i)-VALUE));
+      }
+      test_suba(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_suba: ", i, a0[i], (long)((long)(ADD_INIT+i)-VALUE));
+      }
+
+      test_mulc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc: ", i, a0[i], (long)((long)(ADD_INIT+i)*VALUE));
+      }
+      test_mulv(a0, a1, (long)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv: ", i, a0[i], (long)((long)(ADD_INIT+i)*VALUE));
+      }
+      test_mula(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula: ", i, a0[i], (long)((long)(ADD_INIT+i)*VALUE));
+      }
+
+      test_divc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc: ", i, a0[i], (long)((long)(ADD_INIT+i)/VALUE));
+      }
+      test_divv(a0, a1, (long)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv: ", i, a0[i], (long)((long)(ADD_INIT+i)/VALUE));
+      }
+      test_diva(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva: ", i, a0[i], (long)((long)(ADD_INIT+i)/VALUE));
+      }
+
+      test_mulc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc_n: ", i, a0[i], (long)((long)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mulv(a0, a1, (long)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv_n: ", i, a0[i], (long)((long)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mula(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula_n: ", i, a0[i], (long)((long)(ADD_INIT+i)*(-VALUE)));
+      }
+
+      test_divc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc_n: ", i, a0[i], (long)((long)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_divv(a0, a1, (long)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv_n: ", i, a0[i], (long)((long)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_diva(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva_n: ", i, a0[i], (long)((long)(ADD_INIT+i)/(-VALUE)));
+      }
+
+      test_andc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andc: ", i, a0[i], (long)((long)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_andv(a0, a1, (long)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andv: ", i, a0[i], (long)((long)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_anda(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_anda: ", i, a0[i], (long)((long)(ADD_INIT+i)&BIT_MASK));
+      }
+
+      test_orc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orc: ", i, a0[i], (long)((long)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_orv(a0, a1, (long)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orv: ", i, a0[i], (long)((long)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_ora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ora: ", i, a0[i], (long)((long)(ADD_INIT+i)|BIT_MASK));
+      }
+
+      test_xorc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorc: ", i, a0[i], (long)((long)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xorv(a0, a1, (long)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorv: ", i, a0[i], (long)((long)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xora: ", i, a0[i], (long)((long)(ADD_INIT+i)^BIT_MASK));
+      }
+
+      test_sllc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc: ", i, a0[i], (long)((long)(ADD_INIT+i)<<VALUE));
+      }
+      test_sllv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv: ", i, a0[i], (long)((long)(ADD_INIT+i)<<VALUE));
+      }
+
+      test_srlc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc: ", i, a0[i], (long)((long)(ADD_INIT+i)>>>VALUE));
+      }
+      test_srlv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv: ", i, a0[i], (long)((long)(ADD_INIT+i)>>>VALUE));
+      }
+
+      test_srac(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac: ", i, a0[i], (long)((long)(ADD_INIT+i)>>VALUE));
+      }
+      test_srav(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav: ", i, a0[i], (long)((long)(ADD_INIT+i)>>VALUE));
+      }
+
+      test_sllc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_n: ", i, a0[i], (long)((long)(ADD_INIT+i)<<(-VALUE)));
+      }
+      test_sllv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_n: ", i, a0[i], (long)((long)(ADD_INIT+i)<<(-VALUE)));
+      }
+
+      test_srlc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_n: ", i, a0[i], (long)((long)(ADD_INIT+i)>>>(-VALUE)));
+      }
+      test_srlv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_n: ", i, a0[i], (long)((long)(ADD_INIT+i)>>>(-VALUE)));
+      }
+
+      test_srac_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_n: ", i, a0[i], (long)((long)(ADD_INIT+i)>>(-VALUE)));
+      }
+      test_srav(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_n: ", i, a0[i], (long)((long)(ADD_INIT+i)>>(-VALUE)));
+      }
+
+      test_sllc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_o: ", i, a0[i], (long)((long)(ADD_INIT+i)<<SHIFT));
+      }
+      test_sllv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_o: ", i, a0[i], (long)((long)(ADD_INIT+i)<<SHIFT));
+      }
+
+      test_srlc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_o: ", i, a0[i], (long)((long)(ADD_INIT+i)>>>SHIFT));
+      }
+      test_srlv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_o: ", i, a0[i], (long)((long)(ADD_INIT+i)>>>SHIFT));
+      }
+
+      test_srac_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_o: ", i, a0[i], (long)((long)(ADD_INIT+i)>>SHIFT));
+      }
+      test_srav(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_o: ", i, a0[i], (long)((long)(ADD_INIT+i)>>SHIFT));
+      }
+
+      test_sllc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_on: ", i, a0[i], (long)((long)(ADD_INIT+i)<<(-SHIFT)));
+      }
+      test_sllv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_on: ", i, a0[i], (long)((long)(ADD_INIT+i)<<(-SHIFT)));
+      }
+
+      test_srlc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_on: ", i, a0[i], (long)((long)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+      test_srlv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_on: ", i, a0[i], (long)((long)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+
+      test_srac_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_on: ", i, a0[i], (long)((long)(ADD_INIT+i)>>(-SHIFT)));
+      }
+      test_srav(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_on: ", i, a0[i], (long)((long)(ADD_INIT+i)>>(-SHIFT)));
+      }
+
+      test_sllc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_add: ", i, a0[i], (long)(((long)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+      test_sllv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_add: ", i, a0[i], (long)(((long)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+
+      test_srlc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_add: ", i, a0[i], (long)(((long)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+      test_srlv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_add: ", i, a0[i], (long)(((long)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+
+      test_srac_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_add: ", i, a0[i], (long)(((long)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+      test_srav_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_add: ", i, a0[i], (long)(((long)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+
+      test_sllc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_and: ", i, a0[i], (long)(((long)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+      test_sllv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_and: ", i, a0[i], (long)(((long)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+
+      test_srlc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_and: ", i, a0[i], (long)(((long)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+      test_srlv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_and: ", i, a0[i], (long)(((long)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+
+      test_srac_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_and: ", i, a0[i], (long)(((long)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+      test_srav_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_and: ", i, a0[i], (long)(((long)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sum: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addv(a0, a1, (long)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_adda(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_adda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subv(a0, a1, (long)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_suba(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_suba: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (long)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, (long)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (long)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, (long)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andv(a0, a1, (long)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_anda(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_anda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orv(a0, a1, (long)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorv(a0, a1, (long)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_and: " + (end - start));
+
+    return errn;
+  }
+
+  static long test_sum(long[] a1) {
+    long sum = 0;
+    for (int i = 0; i < a1.length; i+=1) {
+      sum += a1[i];
+    }
+    return sum;
+  }
+
+  static void test_addc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]+VALUE);
+    }
+  }
+  static void test_addv(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]+b);
+    }
+  }
+  static void test_adda(long[] a0, long[] a1, long[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]+a2[i]);
+    }
+  }
+
+  static void test_subc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]-VALUE);
+    }
+  }
+  static void test_subv(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]-b);
+    }
+  }
+  static void test_suba(long[] a0, long[] a1, long[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]-a2[i]);
+    }
+  }
+
+  static void test_mulc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]*VALUE);
+    }
+  }
+  static void test_mulc_n(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]*(-VALUE));
+    }
+  }
+  static void test_mulv(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]*b);
+    }
+  }
+  static void test_mula(long[] a0, long[] a1, long[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]*a2[i]);
+    }
+  }
+
+  static void test_divc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]/VALUE);
+    }
+  }
+  static void test_divc_n(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]/(-VALUE));
+    }
+  }
+  static void test_divv(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]/b);
+    }
+  }
+  static void test_diva(long[] a0, long[] a1, long[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]/a2[i]);
+    }
+  }
+
+  static void test_andc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]&BIT_MASK);
+    }
+  }
+  static void test_andv(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]&b);
+    }
+  }
+  static void test_anda(long[] a0, long[] a1, long[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]&a2[i]);
+    }
+  }
+
+  static void test_orc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]|BIT_MASK);
+    }
+  }
+  static void test_orv(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]|b);
+    }
+  }
+  static void test_ora(long[] a0, long[] a1, long[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]|a2[i]);
+    }
+  }
+
+  static void test_xorc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]^BIT_MASK);
+    }
+  }
+  static void test_xorv(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]^b);
+    }
+  }
+  static void test_xora(long[] a0, long[] a1, long[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]^a2[i]);
+    }
+  }
+
+  static void test_sllc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]<<VALUE);
+    }
+  }
+  static void test_sllc_n(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]<<(-VALUE));
+    }
+  }
+  static void test_sllc_o(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]<<SHIFT);
+    }
+  }
+  static void test_sllc_on(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]<<(-SHIFT));
+    }
+  }
+  static void test_sllv(long[] a0, long[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]<<b);
+    }
+  }
+  static void test_sllc_add(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] + ADD_INIT)<<VALUE);
+    }
+  }
+  static void test_sllv_add(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] + b)<<VALUE);
+    }
+  }
+  static void test_sllc_and(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] & BIT_MASK)<<VALUE);
+    }
+  }
+  static void test_sllv_and(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] & b)<<VALUE);
+    }
+  }
+
+  static void test_srlc(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>>VALUE);
+    }
+  }
+  static void test_srlc_n(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>>(-VALUE));
+    }
+  }
+  static void test_srlc_o(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>>SHIFT);
+    }
+  }
+  static void test_srlc_on(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>>(-SHIFT));
+    }
+  }
+  static void test_srlv(long[] a0, long[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>>b);
+    }
+  }
+  static void test_srlc_add(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] + ADD_INIT)>>>VALUE);
+    }
+  }
+  static void test_srlv_add(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] + b)>>>VALUE);
+    }
+  }
+  static void test_srlc_and(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] & BIT_MASK)>>>VALUE);
+    }
+  }
+  static void test_srlv_and(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] & b)>>>VALUE);
+    }
+  }
+
+  static void test_srac(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>VALUE);
+    }
+  }
+  static void test_srac_n(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>(-VALUE));
+    }
+  }
+  static void test_srac_o(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>SHIFT);
+    }
+  }
+  static void test_srac_on(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>(-SHIFT));
+    }
+  }
+  static void test_srav(long[] a0, long[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]>>b);
+    }
+  }
+  static void test_srac_add(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] + ADD_INIT)>>VALUE);
+    }
+  }
+  static void test_srav_add(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] + b)>>VALUE);
+    }
+  }
+  static void test_srac_and(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] & BIT_MASK)>>VALUE);
+    }
+  }
+  static void test_srav_and(long[] a0, long[] a1, long b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)((a1[i] & b)>>VALUE);
+    }
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/6340864/TestShortVect.java b/hotspot/test/compiler/6340864/TestShortVect.java
new file mode 100644
index 0000000..9f59c8f
--- /dev/null
+++ b/hotspot/test/compiler/6340864/TestShortVect.java
@@ -0,0 +1,1340 @@
+/*
+ * Copyright (c) 2012, 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 6340864
+ * @summary Implement vectorization optimizations in hotspot-server
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestShortVect
+ */
+
+public class TestShortVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int ADD_INIT = Short.MAX_VALUE-500;
+  private static final int BIT_MASK = 0xB731;
+  private static final int VALUE = 7;
+  private static final int SHIFT = 16;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Short vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    short[] a0 = new short[ARRLEN];
+    short[] a1 = new short[ARRLEN];
+    short[] a2 = new short[ARRLEN];
+    short[] a3 = new short[ARRLEN];
+    short[] a4 = new short[ARRLEN];
+     int[] p2 = new  int[ARRLEN/2];
+    long[] p4 = new long[ARRLEN/4];
+    // Initialize
+    int gold_sum = 0;
+    for (int i=0; i<ARRLEN; i++) {
+      short val = (short)(ADD_INIT+i);
+      gold_sum += val;
+      a1[i] = val;
+      a2[i] = (short)VALUE;
+      a3[i] = (short)-VALUE;
+      a4[i] = (short)BIT_MASK;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+      test_addc(a0, a1);
+      test_addv(a0, a1, (short)VALUE);
+      test_adda(a0, a1, a2);
+      test_subc(a0, a1);
+      test_subv(a0, a1, (short)VALUE);
+      test_suba(a0, a1, a2);
+
+      test_mulc(a0, a1);
+      test_mulv(a0, a1, (short)VALUE);
+      test_mula(a0, a1, a2);
+      test_divc(a0, a1);
+      test_divv(a0, a1, (short)VALUE);
+      test_diva(a0, a1, a2);
+      test_mulc_n(a0, a1);
+      test_mulv(a0, a1, (short)-VALUE);
+      test_mula(a0, a1, a3);
+      test_divc_n(a0, a1);
+      test_divv(a0, a1, (short)-VALUE);
+      test_diva(a0, a1, a3);
+
+      test_andc(a0, a1);
+      test_andv(a0, a1, (short)BIT_MASK);
+      test_anda(a0, a1, a4);
+      test_orc(a0, a1);
+      test_orv(a0, a1, (short)BIT_MASK);
+      test_ora(a0, a1, a4);
+      test_xorc(a0, a1);
+      test_xorv(a0, a1, (short)BIT_MASK);
+      test_xora(a0, a1, a4);
+
+      test_sllc(a0, a1);
+      test_sllv(a0, a1, VALUE);
+      test_srlc(a0, a1);
+      test_srlv(a0, a1, VALUE);
+      test_srac(a0, a1);
+      test_srav(a0, a1, VALUE);
+
+      test_sllc_n(a0, a1);
+      test_sllv(a0, a1, -VALUE);
+      test_srlc_n(a0, a1);
+      test_srlv(a0, a1, -VALUE);
+      test_srac_n(a0, a1);
+      test_srav(a0, a1, -VALUE);
+
+      test_sllc_o(a0, a1);
+      test_sllv(a0, a1, SHIFT);
+      test_srlc_o(a0, a1);
+      test_srlv(a0, a1, SHIFT);
+      test_srac_o(a0, a1);
+      test_srav(a0, a1, SHIFT);
+
+      test_sllc_on(a0, a1);
+      test_sllv(a0, a1, -SHIFT);
+      test_srlc_on(a0, a1);
+      test_srlv(a0, a1, -SHIFT);
+      test_srac_on(a0, a1);
+      test_srav(a0, a1, -SHIFT);
+
+      test_sllc_add(a0, a1);
+      test_sllv_add(a0, a1, ADD_INIT);
+      test_srlc_add(a0, a1);
+      test_srlv_add(a0, a1, ADD_INIT);
+      test_srac_add(a0, a1);
+      test_srav_add(a0, a1, ADD_INIT);
+
+      test_sllc_and(a0, a1);
+      test_sllv_and(a0, a1, BIT_MASK);
+      test_srlc_and(a0, a1);
+      test_srlv_and(a0, a1, BIT_MASK);
+      test_srac_and(a0, a1);
+      test_srav_and(a0, a1, BIT_MASK);
+
+      test_pack2(p2, a1);
+      test_unpack2(a0, p2);
+      test_pack2_swap(p2, a1);
+      test_unpack2_swap(a0, p2);
+      test_pack4(p4, a1);
+      test_unpack4(a0, p4);
+      test_pack4_swap(p4, a1);
+      test_unpack4_swap(a0, p4);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      int sum = test_sum(a1);
+      if (sum != gold_sum) {
+        System.err.println("test_sum:  " + sum + " != " + gold_sum);
+        errn++;
+      }
+
+      test_addc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], (short)((short)(ADD_INIT+i)+VALUE));
+      }
+      test_addv(a0, a1, (short)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], (short)((short)(ADD_INIT+i)+VALUE));
+      }
+      test_adda(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_adda: ", i, a0[i], (short)((short)(ADD_INIT+i)+VALUE));
+      }
+
+      test_subc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subc: ", i, a0[i], (short)((short)(ADD_INIT+i)-VALUE));
+      }
+      test_subv(a0, a1, (short)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subv: ", i, a0[i], (short)((short)(ADD_INIT+i)-VALUE));
+      }
+      test_suba(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_suba: ", i, a0[i], (short)((short)(ADD_INIT+i)-VALUE));
+      }
+
+      test_mulc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc: ", i, a0[i], (short)((short)(ADD_INIT+i)*VALUE));
+      }
+      test_mulv(a0, a1, (short)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv: ", i, a0[i], (short)((short)(ADD_INIT+i)*VALUE));
+      }
+      test_mula(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula: ", i, a0[i], (short)((short)(ADD_INIT+i)*VALUE));
+      }
+
+      test_divc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc: ", i, a0[i], (short)((short)(ADD_INIT+i)/VALUE));
+      }
+      test_divv(a0, a1, (short)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv: ", i, a0[i], (short)((short)(ADD_INIT+i)/VALUE));
+      }
+      test_diva(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva: ", i, a0[i], (short)((short)(ADD_INIT+i)/VALUE));
+      }
+
+      test_mulc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc_n: ", i, a0[i], (short)((short)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mulv(a0, a1, (short)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv_n: ", i, a0[i], (short)((short)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mula(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula_n: ", i, a0[i], (short)((short)(ADD_INIT+i)*(-VALUE)));
+      }
+
+      test_divc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc_n: ", i, a0[i], (short)((short)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_divv(a0, a1, (short)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv_n: ", i, a0[i], (short)((short)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_diva(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva_n: ", i, a0[i], (short)((short)(ADD_INIT+i)/(-VALUE)));
+      }
+
+      test_andc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andc: ", i, a0[i], (short)((short)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_andv(a0, a1, (short)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andv: ", i, a0[i], (short)((short)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_anda(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_anda: ", i, a0[i], (short)((short)(ADD_INIT+i)&BIT_MASK));
+      }
+
+      test_orc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orc: ", i, a0[i], (short)((short)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_orv(a0, a1, (short)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orv: ", i, a0[i], (short)((short)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_ora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ora: ", i, a0[i], (short)((short)(ADD_INIT+i)|BIT_MASK));
+      }
+
+      test_xorc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorc: ", i, a0[i], (short)((short)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xorv(a0, a1, (short)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorv: ", i, a0[i], (short)((short)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xora: ", i, a0[i], (short)((short)(ADD_INIT+i)^BIT_MASK));
+      }
+
+      test_sllc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc: ", i, a0[i], (short)((short)(ADD_INIT+i)<<VALUE));
+      }
+      test_sllv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv: ", i, a0[i], (short)((short)(ADD_INIT+i)<<VALUE));
+      }
+
+      test_srlc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc: ", i, a0[i], (short)((short)(ADD_INIT+i)>>>VALUE));
+      }
+      test_srlv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv: ", i, a0[i], (short)((short)(ADD_INIT+i)>>>VALUE));
+      }
+
+      test_srac(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac: ", i, a0[i], (short)((short)(ADD_INIT+i)>>VALUE));
+      }
+      test_srav(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav: ", i, a0[i], (short)((short)(ADD_INIT+i)>>VALUE));
+      }
+
+      test_sllc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_n: ", i, a0[i], (short)((short)(ADD_INIT+i)<<(-VALUE)));
+      }
+      test_sllv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_n: ", i, a0[i], (short)((short)(ADD_INIT+i)<<(-VALUE)));
+      }
+
+      test_srlc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_n: ", i, a0[i], (short)((short)(ADD_INIT+i)>>>(-VALUE)));
+      }
+      test_srlv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_n: ", i, a0[i], (short)((short)(ADD_INIT+i)>>>(-VALUE)));
+      }
+
+      test_srac_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_n: ", i, a0[i], (short)((short)(ADD_INIT+i)>>(-VALUE)));
+      }
+      test_srav(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_n: ", i, a0[i], (short)((short)(ADD_INIT+i)>>(-VALUE)));
+      }
+
+      test_sllc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_o: ", i, a0[i], (short)((short)(ADD_INIT+i)<<SHIFT));
+      }
+      test_sllv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_o: ", i, a0[i], (short)((short)(ADD_INIT+i)<<SHIFT));
+      }
+
+      test_srlc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_o: ", i, a0[i], (short)((short)(ADD_INIT+i)>>>SHIFT));
+      }
+      test_srlv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_o: ", i, a0[i], (short)((short)(ADD_INIT+i)>>>SHIFT));
+      }
+
+      test_srac_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_o: ", i, a0[i], (short)((short)(ADD_INIT+i)>>SHIFT));
+      }
+      test_srav(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_o: ", i, a0[i], (short)((short)(ADD_INIT+i)>>SHIFT));
+      }
+
+      test_sllc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_on: ", i, a0[i], (short)((short)(ADD_INIT+i)<<(-SHIFT)));
+      }
+      test_sllv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_on: ", i, a0[i], (short)((short)(ADD_INIT+i)<<(-SHIFT)));
+      }
+
+      test_srlc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_on: ", i, a0[i], (short)((short)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+      test_srlv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_on: ", i, a0[i], (short)((short)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+
+      test_srac_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_on: ", i, a0[i], (short)((short)(ADD_INIT+i)>>(-SHIFT)));
+      }
+      test_srav(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_on: ", i, a0[i], (short)((short)(ADD_INIT+i)>>(-SHIFT)));
+      }
+
+      test_sllc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_add: ", i, a0[i], (short)(((short)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+      test_sllv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_add: ", i, a0[i], (short)(((short)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+
+      test_srlc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_add: ", i, a0[i], (short)(((short)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+      test_srlv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_add: ", i, a0[i], (short)(((short)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+
+      test_srac_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_add: ", i, a0[i], (short)(((short)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+      test_srav_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_add: ", i, a0[i], (short)(((short)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+
+      test_sllc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_and: ", i, a0[i], (short)(((short)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+      test_sllv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_and: ", i, a0[i], (short)(((short)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+
+      test_srlc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_and: ", i, a0[i], (short)(((short)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+      test_srlv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_and: ", i, a0[i], (short)(((short)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+
+      test_srac_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_and: ", i, a0[i], (short)(((short)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+      test_srav_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_and: ", i, a0[i], (short)(((short)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+
+      test_pack2(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2: ", i, p2[i], ((int)(ADD_INIT+2*i) & 0xFFFF) | ((int)(ADD_INIT+2*i+1) << 16));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack2(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2: ", i, a0[i], (short)(ADD_INIT+i));
+      }
+
+      test_pack2_swap(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2_swap: ", i, p2[i], ((int)(ADD_INIT+2*i+1) & 0xFFFF) | ((int)(ADD_INIT+2*i) << 16));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack2_swap(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2_swap: ", i, a0[i], (short)(ADD_INIT+i));
+      }
+
+      test_pack4(p4, a1);
+      for (int i=0; i<ARRLEN/4; i++) {
+        errn += verify("test_pack4: ", i, p4[i],  ((long)(ADD_INIT+4*i+0) & 0xFFFFl) |
+                                                 (((long)(ADD_INIT+4*i+1) & 0xFFFFl) << 16)  |
+                                                 (((long)(ADD_INIT+4*i+2) & 0xFFFFl) << 32)  |
+                                                 (((long)(ADD_INIT+4*i+3) & 0xFFFFl) << 48));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack4(a0, p4);
+      for (int i=0; i<(ARRLEN&(-4)); i++) {
+        errn += verify("test_unpack4: ", i, a0[i], (short)(ADD_INIT+i));
+      }
+
+      test_pack4_swap(p4, a1);
+      for (int i=0; i<ARRLEN/4; i++) {
+        errn += verify("test_pack4_swap: ", i, p4[i],  ((long)(ADD_INIT+4*i+3) & 0xFFFFl) |
+                                                      (((long)(ADD_INIT+4*i+2) & 0xFFFFl) << 16)  |
+                                                      (((long)(ADD_INIT+4*i+1) & 0xFFFFl) << 32)  |
+                                                      (((long)(ADD_INIT+4*i+0) & 0xFFFFl) << 48));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack4_swap(a0, p4);
+      for (int i=0; i<(ARRLEN&(-4)); i++) {
+        errn += verify("test_unpack4_swap: ", i, a0[i], (short)(ADD_INIT+i));
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sum: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addv(a0, a1, (short)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_adda(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_adda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subv(a0, a1, (short)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_suba(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_suba: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (short)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, (short)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (short)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, (short)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andv(a0, a1, (short)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_anda(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_anda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orv(a0, a1, (short)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorv(a0, a1, (short)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack2(p2, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack2: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack2(a0, p2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack2: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack2_swap(p2, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack2_swap: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack2_swap(a0, p2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack2_swap: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack4(p4, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack4: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack4(a0, p4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack4: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack4_swap(p4, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack4_swap: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack4_swap(a0, p4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack4_swap: " + (end - start));
+
+    return errn;
+  }
+
+  static int test_sum(short[] a1) {
+    int sum = 0;
+    for (int i = 0; i < a1.length; i+=1) {
+      sum += a1[i];
+    }
+    return sum;
+  }
+
+  static void test_addc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]+VALUE);
+    }
+  }
+  static void test_addv(short[] a0, short[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]+b);
+    }
+  }
+  static void test_adda(short[] a0, short[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]+a2[i]);
+    }
+  }
+
+  static void test_subc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]-VALUE);
+    }
+  }
+  static void test_subv(short[] a0, short[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]-b);
+    }
+  }
+  static void test_suba(short[] a0, short[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]-a2[i]);
+    }
+  }
+
+  static void test_mulc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]*VALUE);
+    }
+  }
+  static void test_mulc_n(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]*(-VALUE));
+    }
+  }
+  static void test_mulv(short[] a0, short[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]*b);
+    }
+  }
+  static void test_mula(short[] a0, short[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]*a2[i]);
+    }
+  }
+
+  static void test_divc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]/VALUE);
+    }
+  }
+  static void test_divc_n(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]/(-VALUE));
+    }
+  }
+  static void test_divv(short[] a0, short[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]/b);
+    }
+  }
+  static void test_diva(short[] a0, short[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]/a2[i]);
+    }
+  }
+
+  static void test_andc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]&BIT_MASK);
+    }
+  }
+  static void test_andv(short[] a0, short[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]&b);
+    }
+  }
+  static void test_anda(short[] a0, short[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]&a2[i]);
+    }
+  }
+
+  static void test_orc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]|BIT_MASK);
+    }
+  }
+  static void test_orv(short[] a0, short[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]|b);
+    }
+  }
+  static void test_ora(short[] a0, short[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]|a2[i]);
+    }
+  }
+
+  static void test_xorc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]^BIT_MASK);
+    }
+  }
+  static void test_xorv(short[] a0, short[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]^b);
+    }
+  }
+  static void test_xora(short[] a0, short[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]^a2[i]);
+    }
+  }
+
+  static void test_sllc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]<<VALUE);
+    }
+  }
+  static void test_sllc_n(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]<<(-VALUE));
+    }
+  }
+  static void test_sllc_o(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]<<SHIFT);
+    }
+  }
+  static void test_sllc_on(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]<<(-SHIFT));
+    }
+  }
+  static void test_sllv(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]<<b);
+    }
+  }
+  static void test_sllc_add(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] + ADD_INIT)<<VALUE);
+    }
+  }
+  static void test_sllv_add(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] + b)<<VALUE);
+    }
+  }
+  static void test_sllc_and(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] & BIT_MASK)<<VALUE);
+    }
+  }
+  static void test_sllv_and(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] & b)<<VALUE);
+    }
+  }
+
+  static void test_srlc(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>>VALUE);
+    }
+  }
+  static void test_srlc_n(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>>(-VALUE));
+    }
+  }
+  static void test_srlc_o(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>>SHIFT);
+    }
+  }
+  static void test_srlc_on(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>>(-SHIFT));
+    }
+  }
+  static void test_srlv(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>>b);
+    }
+  }
+  static void test_srlc_add(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] + ADD_INIT)>>>VALUE);
+    }
+  }
+  static void test_srlv_add(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] + b)>>>VALUE);
+    }
+  }
+  static void test_srlc_and(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] & BIT_MASK)>>>VALUE);
+    }
+  }
+  static void test_srlv_and(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] & b)>>>VALUE);
+    }
+  }
+
+  static void test_srac(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>VALUE);
+    }
+  }
+  static void test_srac_n(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>(-VALUE));
+    }
+  }
+  static void test_srac_o(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>SHIFT);
+    }
+  }
+  static void test_srac_on(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>(-SHIFT));
+    }
+  }
+  static void test_srav(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]>>b);
+    }
+  }
+  static void test_srac_add(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] + ADD_INIT)>>VALUE);
+    }
+  }
+  static void test_srav_add(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] + b)>>VALUE);
+    }
+  }
+  static void test_srac_and(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] & BIT_MASK)>>VALUE);
+    }
+  }
+  static void test_srav_and(short[] a0, short[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)((a1[i] & b)>>VALUE);
+    }
+  }
+
+  static void test_pack2(int[] p2, short[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      int l0 = (int)a1[i*2+0];
+      int l1 = (int)a1[i*2+1];
+      p2[i] = (l1 << 16) | (l0 & 0xFFFF);
+    }
+  }
+  static void test_unpack2(short[] a0, int[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      int l = p2[i];
+      a0[i*2+0] = (short)(l & 0xFFFF);
+      a0[i*2+1] = (short)(l >> 16);
+    }
+  }
+  static void test_pack2_swap(int[] p2, short[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      int l0 = (int)a1[i*2+0];
+      int l1 = (int)a1[i*2+1];
+      p2[i] = (l0 << 16) | (l1 & 0xFFFF);
+    }
+  }
+  static void test_unpack2_swap(short[] a0, int[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      int l = p2[i];
+      a0[i*2+0] = (short)(l >> 16);
+      a0[i*2+1] = (short)(l & 0xFFFF);
+    }
+  }
+
+  static void test_pack4(long[] p4, short[] a1) {
+    if (p4.length*4 > a1.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      long l0 = (long)a1[i*4+0];
+      long l1 = (long)a1[i*4+1];
+      long l2 = (long)a1[i*4+2];
+      long l3 = (long)a1[i*4+3];
+      p4[i] = (l0 & 0xFFFFl) |
+             ((l1 & 0xFFFFl) << 16) |
+             ((l2 & 0xFFFFl) << 32) |
+             ((l3 & 0xFFFFl) << 48);
+    }
+  }
+  static void test_unpack4(short[] a0, long[] p4) {
+    if (p4.length*4 > a0.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      long l = p4[i];
+      a0[i*4+0] = (short)(l & 0xFFFFl);
+      a0[i*4+1] = (short)(l >> 16);
+      a0[i*4+2] = (short)(l >> 32);
+      a0[i*4+3] = (short)(l >> 48);
+    }
+  }
+  static void test_pack4_swap(long[] p4, short[] a1) {
+    if (p4.length*4 > a1.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      long l0 = (long)a1[i*4+0];
+      long l1 = (long)a1[i*4+1];
+      long l2 = (long)a1[i*4+2];
+      long l3 = (long)a1[i*4+3];
+      p4[i] = (l3 & 0xFFFFl) |
+             ((l2 & 0xFFFFl) << 16) |
+             ((l1 & 0xFFFFl) << 32) |
+             ((l0 & 0xFFFFl) << 48);
+    }
+  }
+  static void test_unpack4_swap(short[] a0, long[] p4) {
+    if (p4.length*4 > a0.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      long l = p4[i];
+      a0[i*4+0] = (short)(l >> 48);
+      a0[i*4+1] = (short)(l >> 32);
+      a0[i*4+2] = (short)(l >> 16);
+      a0[i*4+3] = (short)(l & 0xFFFFl);
+    }
+  }
+
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + Integer.toHexString(elem) + " != " + Integer.toHexString(val));
+      return 1;
+    }
+    return 0;
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + Long.toHexString(elem) + " != " + Long.toHexString(val));
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/6894807/Test6894807.sh b/hotspot/test/compiler/6894807/Test6894807.sh
index da435cc..229fb54 100644
--- a/hotspot/test/compiler/6894807/Test6894807.sh
+++ b/hotspot/test/compiler/6894807/Test6894807.sh
@@ -18,27 +18,24 @@
   exit 1
 fi
 
-BIT_FLAG=""
-
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     NULL=/dev/null
     PS=":"
     FS="/"
-    ## for solaris, linux it's HOME
-    FILE_LOCATION=$HOME
-    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ]
-    then
-        BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT | grep -v '^#'`
-    fi
     ;;
   Windows_* )
     NULL=NUL
     PS=";"
     FS="\\"
     ;;
+  CYGWIN_* )
+    NULL=/dev/null
+    PS=";"
+    FS="/"
+    ;;
   * )
     echo "Unrecognized system!"
     exit 1;
@@ -50,9 +47,9 @@
 
 THIS_DIR=`pwd`
 
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -version
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version
 
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -server IsInstanceTest > test.out 2>&1
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} IsInstanceTest > test.out 2>&1
 
 cat test.out
 
diff --git a/hotspot/test/compiler/7119644/TestBooleanVect.java b/hotspot/test/compiler/7119644/TestBooleanVect.java
new file mode 100644
index 0000000..d4e3ad6
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestBooleanVect.java
@@ -0,0 +1,952 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestBooleanVect
+ */
+
+public class TestBooleanVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Boolean vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    boolean[] a1 = new boolean[ARRLEN];
+    boolean[] a2 = new boolean[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+      test_vi(a2, true);
+      test_cp(a1, a2);
+      test_2ci(a1, a2);
+      test_2vi(a1, a2, true, true);
+      test_ci_neg(a1);
+      test_vi_neg(a2, true);
+      test_cp_neg(a1, a2);
+      test_2ci_neg(a1, a2);
+      test_2vi_neg(a1, a2, true, true);
+      test_ci_oppos(a1);
+      test_vi_oppos(a2, true);
+      test_cp_oppos(a1, a2);
+      test_2ci_oppos(a1, a2);
+      test_2vi_oppos(a1, a2, true, true);
+      test_ci_off(a1);
+      test_vi_off(a2, true);
+      test_cp_off(a1, a2);
+      test_2ci_off(a1, a2);
+      test_2vi_off(a1, a2, true, true);
+      test_ci_inv(a1, OFFSET);
+      test_vi_inv(a2, true, OFFSET);
+      test_cp_inv(a1, a2, OFFSET);
+      test_2ci_inv(a1, a2, OFFSET);
+      test_2vi_inv(a1, a2, true, true, OFFSET);
+      test_ci_scl(a1);
+      test_vi_scl(a2, true);
+      test_cp_scl(a1, a2);
+      test_2ci_scl(a1, a2);
+      test_2vi_scl(a1, a2, true, true);
+      test_cp_alndst(a1, a2);
+      test_cp_alnsrc(a1, a2);
+      test_2ci_aln(a1, a2);
+      test_2vi_aln(a1, a2, true, true);
+      test_cp_unalndst(a1, a2);
+      test_cp_unalnsrc(a1, a2);
+      test_2ci_unaln(a1, a2);
+      test_2vi_unaln(a1, a2, true, true);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = false;
+      a2[i] = false;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], false);
+      }
+      test_vi(a2, true);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], true);
+      }
+      test_cp(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], true);
+      }
+      test_2ci(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci: a1", i, a1[i], false);
+        errn += verify("test_2ci: a2", i, a2[i], false);
+      }
+      test_2vi(a1, a2, true, true);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi: a1", i, a1[i], true);
+        errn += verify("test_2vi: a2", i, a2[i], true);
+      }
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_ci_neg(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], false);
+      }
+      test_vi_neg(a2, true);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], true);
+      }
+      test_cp_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], true);
+      }
+      test_2ci_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_neg: a1", i, a1[i], false);
+        errn += verify("test_2ci_neg: a2", i, a2[i], false);
+      }
+      test_2vi_neg(a1, a2, true, true);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_neg: a1", i, a1[i], true);
+        errn += verify("test_2vi_neg: a2", i, a2[i], true);
+      }
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_ci_oppos(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], false);
+      }
+      test_vi_oppos(a2, true);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], true);
+      }
+      test_cp_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], true);
+      }
+      test_2ci_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_oppos: a1", i, a1[i], false);
+        errn += verify("test_2ci_oppos: a2", i, a2[i], false);
+      }
+      test_2vi_oppos(a1, a2, true, true);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_oppos: a1", i, a1[i], true);
+        errn += verify("test_2vi_oppos: a2", i, a2[i], true);
+      }
+      // Reset for indexing with offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_ci_off(a1);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_off: a1", i, a1[i], false);
+      }
+      test_vi_off(a2, true);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_off: a2", i, a2[i], true);
+      }
+      test_cp_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_off: a1", i, a1[i], true);
+      }
+      test_2ci_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_off: a1", i, a1[i], false);
+        errn += verify("test_2ci_off: a2", i, a2[i], false);
+      }
+      test_2vi_off(a1, a2, true, true);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], true);
+        errn += verify("test_2vi_off: a2", i, a2[i], true);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], false);
+        errn += verify("test_2vi_off: a2", i, a2[i], false);
+      }
+      // Reset for indexing with invariant offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_ci_inv(a1, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_inv: a1", i, a1[i], false);
+      }
+      test_vi_inv(a2, true, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_inv: a2", i, a2[i], true);
+      }
+      test_cp_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_inv: a1", i, a1[i], true);
+      }
+      test_2ci_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_inv: a1", i, a1[i], false);
+        errn += verify("test_2ci_inv: a2", i, a2[i], false);
+      }
+      test_2vi_inv(a1, a2, true, true, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], true);
+        errn += verify("test_2vi_inv: a2", i, a2[i], true);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], false);
+        errn += verify("test_2vi_inv: a2", i, a2[i], false);
+      }
+      // Reset for indexing with scale
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = true;
+        a2[i] = false;
+      }
+      test_ci_scl(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        boolean val = (i%SCALE != 0);
+        errn += verify("test_ci_scl: a1", i, a1[i], val);
+      }
+      test_vi_scl(a2, true);
+      for (int i=0; i<ARRLEN; i++) {
+        boolean val = (i%SCALE == 0);
+        errn += verify("test_vi_scl: a2", i, a2[i], val);
+      }
+      test_cp_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_scl: a1", i, a1[i], true);
+      }
+      test_2ci_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a1", i, a1[i], true);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], false);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a2", i, a2[i], false);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], false);
+        }
+      }
+      test_2vi_scl(a1, a2, false, true);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a1", i, a1[i], true);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], false);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a2", i, a2[i], false);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], true);
+        }
+      }
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_vi(a2, true);
+      test_cp_alndst(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], false);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], true);
+      }
+      test_vi(a2, false);
+      test_cp_alnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], false);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], true);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_2ci_aln(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], false);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], false);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], false);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], false);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_2vi_aln(a1, a2, true, true);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], true);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], false);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], false);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], true);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_vi(a2, true);
+      test_cp_unalndst(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], false);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], true);
+      }
+      test_vi(a2, false);
+      test_cp_unalnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], false);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], true);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_2ci_unaln(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], false);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], false);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], false);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], false);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+        a2[i] = false;
+      }
+      test_2vi_unaln(a1, a2, true, true);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], true);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], false);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], false);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], true);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (i > 0);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = false;
+      }
+      test_cp_alndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        boolean v = (i%ALIGN_OFF > 0);
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = false;
+      }
+      test_cp_alnsrc(a1, a1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], false);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        boolean v = (i%ALIGN_OFF > 0);
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+      }
+      test_2ci_aln(a1, a1);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], false);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], false);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+      }
+      test_2vi_aln(a1, a1, true, true);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], true);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], true);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (i > 0);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = false;
+      }
+      test_cp_unalndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        boolean v = (i%UNALIGN_OFF > 0);
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = false;
+      }
+      test_cp_unalnsrc(a1, a1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], false);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        boolean v = (i%UNALIGN_OFF > 0);
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+      }
+      test_2ci_unaln(a1, a1);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], false);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], false);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = false;
+      }
+      test_2vi_unaln(a1, a1, true, true);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], true);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], true);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi(a1, a2, true, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a2, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_neg(a1, a2, true, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_neg: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a2, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_oppos(a1, a2, true, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_oppos: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_off(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_off(a2, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_off(a1, a2, true, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_off: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_inv(a1, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_inv(a2, true, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_inv(a1, a2, true, true, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_inv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_scl(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_scl(a2, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_scl(a1, a2, true, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_scl: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_aln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_aln(a1, a2, true, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_aln: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_unaln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_unaln(a1, a2, true, true);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_unaln: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_ci(boolean[] a) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = false;
+    }
+  }
+  static void test_vi(boolean[] a, boolean b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = false;
+      b[i] = false;
+    }
+  }
+  static void test_2vi(boolean[] a, boolean[] b, boolean c, boolean d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_neg(boolean[] a) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = false;
+    }
+  }
+  static void test_vi_neg(boolean[] a, boolean b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp_neg(boolean[] a, boolean[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci_neg(boolean[] a, boolean[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = false;
+      b[i] = false;
+    }
+  }
+  static void test_2vi_neg(boolean[] a, boolean[] b, boolean c, boolean d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_oppos(boolean[] a) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = false;
+    }
+  }
+  static void test_vi_oppos(boolean[] a, boolean b) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[limit-i] = b;
+    }
+  }
+  static void test_cp_oppos(boolean[] a, boolean[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+    }
+  }
+  static void test_2ci_oppos(boolean[] a, boolean[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = false;
+      b[i] = false;
+    }
+  }
+  static void test_2vi_oppos(boolean[] a, boolean[] b, boolean c, boolean d) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_ci_off(boolean[] a) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = false;
+    }
+  }
+  static void test_vi_off(boolean[] a, boolean b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b;
+    }
+  }
+  static void test_cp_off(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b[i+OFFSET];
+    }
+  }
+  static void test_2ci_off(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = false;
+      b[i+OFFSET] = false;
+    }
+  }
+  static void test_2vi_off(boolean[] a, boolean[] b, boolean c, boolean d) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = c;
+      b[i+OFFSET] = d;
+    }
+  }
+  static void test_ci_inv(boolean[] a, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = false;
+    }
+  }
+  static void test_vi_inv(boolean[] a, boolean b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b;
+    }
+  }
+  static void test_cp_inv(boolean[] a, boolean[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b[i+k];
+    }
+  }
+  static void test_2ci_inv(boolean[] a, boolean[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = false;
+      b[i+k] = false;
+    }
+  }
+  static void test_2vi_inv(boolean[] a, boolean[] b, boolean c, boolean d, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = c;
+      b[i+k] = d;
+    }
+  }
+  static void test_ci_scl(boolean[] a) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = false;
+    }
+  }
+  static void test_vi_scl(boolean[] a, boolean b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b;
+    }
+  }
+  static void test_cp_scl(boolean[] a, boolean[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b[i*SCALE];
+    }
+  }
+  static void test_2ci_scl(boolean[] a, boolean[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = false;
+      b[i*SCALE] = false;
+    }
+  }
+  static void test_2vi_scl(boolean[] a, boolean[] b, boolean c, boolean d) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = c;
+      b[i*SCALE] = d;
+    }
+  }
+  static void test_cp_alndst(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_alnsrc(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+    }
+  }
+  static void test_2ci_aln(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = false;
+      b[i] = false;
+    }
+  }
+  static void test_2vi_aln(boolean[] a, boolean[] b, boolean c, boolean d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_unalnsrc(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+    }
+  }
+  static void test_2ci_unaln(boolean[] a, boolean[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = false;
+      b[i] = false;
+    }
+  }
+  static void test_2vi_unaln(boolean[] a, boolean[] b, boolean c, boolean d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+
+  static int verify(String text, int i, boolean elem, boolean val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestByteDoubleVect.java b/hotspot/test/compiler/7119644/TestByteDoubleVect.java
new file mode 100644
index 0000000..acf71bf
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestByteDoubleVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestByteDoubleVect
+ */
+
+public class TestByteDoubleVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Byte + Double vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    byte[] a1 = new byte[ARRLEN];
+    byte[] a2 = new byte[ARRLEN];
+    double[] b1 = new double[ARRLEN];
+    double[] b2 = new double[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (byte)123, 103.);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (byte)123, 103.);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (byte)123, 103.);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (byte)123, 103.);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (byte)123, 103.);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.;
+      b2[i] = -1.;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci: b1", i, b1[i], -103.);
+      }
+      test_vi(a2, b2, (byte)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi: b2", i, b2[i], 103.);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp: b1", i, b1[i], 103.);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.);
+      }
+      test_vi_neg(a2, b2, (byte)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.);
+      }
+      test_vi_oppos(a2, b2, (byte)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_vi_aln(a1, b1, (byte)123, 103.);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (byte)123, 103.);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (double)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (double)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (byte)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (byte)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (byte)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (byte)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (byte)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(byte[] a, double[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi(byte[] a, double[] b, byte c, double d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(byte[] a, byte[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(byte[] a, double[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_neg(byte[] a, double[] b, byte c, double d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(byte[] a, byte[] b, double[] c, double[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(byte[] a, double[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_oppos(byte[] a, double[] b, byte c, double d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(byte[] a, byte[] b, double[] c, double[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(byte[] a, double[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_aln(byte[] a, double[] b, byte c, double d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(byte[] a, byte[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(byte[] a, byte[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(byte[] a, double[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_unaln(byte[] a, double[] b, byte c, double d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(byte[] a, byte[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(byte[] a, byte[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, byte elem, byte val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, double elem, double val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestByteFloatVect.java b/hotspot/test/compiler/7119644/TestByteFloatVect.java
new file mode 100644
index 0000000..45fe34e
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestByteFloatVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestByteFloatVect
+ */
+
+public class TestByteFloatVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Byte + Float vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    byte[] a1 = new byte[ARRLEN];
+    byte[] a2 = new byte[ARRLEN];
+    float[] b1 = new float[ARRLEN];
+    float[] b2 = new float[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (byte)123, 103.f);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (byte)123, 103.f);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (byte)123, 103.f);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (byte)123, 103.f);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (byte)123, 103.f);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.f;
+      b2[i] = -1.f;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci: b1", i, b1[i], -103.f);
+      }
+      test_vi(a2, b2, (byte)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi: b2", i, b2[i], 103.f);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.f;
+        b2[i] = -1.f;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.f);
+      }
+      test_vi_neg(a2, b2, (byte)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.f);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.f;
+        b2[i] = -1.f;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.f);
+      }
+      test_vi_oppos(a2, b2, (byte)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.f);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.f;
+        b2[i] = 123.f;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.f;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.f);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.f);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_vi_aln(a1, b1, (byte)123, 103.f);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.f;
+        b2[i] = 123.f;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.f;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (byte)123, 103.f);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (float)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (float)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.f;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (float)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (float)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (float)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.f;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (float)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (byte)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (byte)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (byte)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (byte)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (byte)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(byte[] a, float[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi(byte[] a, float[] b, byte c, float d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(byte[] a, byte[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(byte[] a, float[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_neg(byte[] a, float[] b, byte c, float d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(byte[] a, byte[] b, float[] c, float[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(byte[] a, float[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_oppos(byte[] a, float[] b, byte c, float d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(byte[] a, byte[] b, float[] c, float[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(byte[] a, float[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_aln(byte[] a, float[] b, byte c, float d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(byte[] a, byte[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(byte[] a, byte[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(byte[] a, float[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_unaln(byte[] a, float[] b, byte c, float d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(byte[] a, byte[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(byte[] a, byte[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, byte elem, byte val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestByteIntVect.java b/hotspot/test/compiler/7119644/TestByteIntVect.java
new file mode 100644
index 0000000..8d9aa6a
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestByteIntVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestByteIntVect
+ */
+
+public class TestByteIntVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Byte + Integer vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    byte[] a1 = new byte[ARRLEN];
+    byte[] a2 = new byte[ARRLEN];
+    int[] b1 = new int[ARRLEN];
+    int[] b2 = new int[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (byte)123, (int)103);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (byte)123, (int)103);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (byte)123, (int)103);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (byte)123, (int)103);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (byte)123, (int)103);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1;
+      b2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci: b1", i, b1[i], (int)-103);
+      }
+      test_vi(a2, b2, (byte)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi: b2", i, b2[i], (int)103);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], (int)-103);
+      }
+      test_vi_neg(a2, b2, (byte)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], (int)103);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], (int)-103);
+      }
+      test_vi_oppos(a2, b2, (byte)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], (int)103);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (int)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (int)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (int)123);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (int)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (int)-1);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_aln(a1, b1, (byte)123, (int)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (int)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (int)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (int)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (int)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (int)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (byte)123, (int)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (int)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (int)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (int)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (int)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (int)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (int)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (byte)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (byte)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (byte)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (byte)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (byte)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(byte[] a, int[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi(byte[] a, int[] b, byte c, int d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(byte[] a, byte[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(byte[] a, int[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_neg(byte[] a, int[] b, byte c, int d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(byte[] a, byte[] b, int[] c, int[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(byte[] a, int[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_oppos(byte[] a, int[] b, byte c, int d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(byte[] a, byte[] b, int[] c, int[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(byte[] a, int[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_aln(byte[] a, int[] b, byte c, int d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(byte[] a, byte[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(byte[] a, byte[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(byte[] a, int[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_unaln(byte[] a, int[] b, byte c, int d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(byte[] a, byte[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(byte[] a, byte[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, byte elem, byte val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestByteLongVect.java b/hotspot/test/compiler/7119644/TestByteLongVect.java
new file mode 100644
index 0000000..c2d4390
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestByteLongVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestByteLongVect
+ */
+
+public class TestByteLongVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Byte + Long vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    byte[] a1 = new byte[ARRLEN];
+    byte[] a2 = new byte[ARRLEN];
+    long[] b1 = new long[ARRLEN];
+    long[] b2 = new long[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (byte)123, (long)103);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (byte)123, (long)103);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (byte)123, (long)103);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (byte)123, (long)103);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (byte)123, (long)103);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1;
+      b2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci: b1", i, b1[i], (long)-103);
+      }
+      test_vi(a2, b2, (byte)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi: b2", i, b2[i], (long)103);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], (long)-103);
+      }
+      test_vi_neg(a2, b2, (byte)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], (long)103);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], (long)-103);
+      }
+      test_vi_oppos(a2, b2, (byte)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], (long)103);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (long)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (long)123);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (long)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (long)-1);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_aln(a1, b1, (byte)123, (long)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (long)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (long)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (byte)123, (long)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (long)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (long)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (long)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (long)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (long)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (long)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (byte)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (byte)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (byte)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (byte)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (byte)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(byte[] a, long[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi(byte[] a, long[] b, byte c, long d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(byte[] a, byte[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(byte[] a, long[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_neg(byte[] a, long[] b, byte c, long d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(byte[] a, byte[] b, long[] c, long[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(byte[] a, long[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_oppos(byte[] a, long[] b, byte c, long d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(byte[] a, byte[] b, long[] c, long[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(byte[] a, long[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_aln(byte[] a, long[] b, byte c, long d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(byte[] a, byte[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(byte[] a, byte[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(byte[] a, long[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_unaln(byte[] a, long[] b, byte c, long d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(byte[] a, byte[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(byte[] a, byte[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, byte elem, byte val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestByteShortVect.java b/hotspot/test/compiler/7119644/TestByteShortVect.java
new file mode 100644
index 0000000..ee1a206
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestByteShortVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestByteShortVect
+ */
+
+public class TestByteShortVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Byte + Short vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    byte[] a1 = new byte[ARRLEN];
+    byte[] a2 = new byte[ARRLEN];
+    short[] b1 = new short[ARRLEN];
+    short[] b2 = new short[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (byte)123, (short)103);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (byte)123, (short)103);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (byte)123, (short)103);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (byte)123, (short)103);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (byte)123, (short)103);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1;
+      b2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci: b1", i, b1[i], (short)-103);
+      }
+      test_vi(a2, b2, (byte)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi: b2", i, b2[i], (short)103);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], (short)-103);
+      }
+      test_vi_neg(a2, b2, (byte)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], (short)103);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (byte)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], (short)-103);
+      }
+      test_vi_oppos(a2, b2, (byte)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (byte)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], (short)103);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (short)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (short)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (short)123);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (short)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (short)-1);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_aln(a1, b1, (byte)123, (short)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (short)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (short)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (short)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (short)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (short)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (byte)123, (short)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (short)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (short)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (short)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+        b1[i] = (short)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (short)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (short)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (byte)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (byte)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (byte)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (byte)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (byte)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(byte[] a, short[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi(byte[] a, short[] b, byte c, short d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(byte[] a, byte[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(byte[] a, short[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_neg(byte[] a, short[] b, byte c, short d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(byte[] a, byte[] b, short[] c, short[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(byte[] a, short[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_oppos(byte[] a, short[] b, byte c, short d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(byte[] a, byte[] b, short[] c, short[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(byte[] a, short[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_aln(byte[] a, short[] b, byte c, short d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(byte[] a, byte[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(byte[] a, byte[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(byte[] a, short[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_unaln(byte[] a, short[] b, byte c, short d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(byte[] a, byte[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(byte[] a, byte[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, byte elem, byte val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestByteVect.java b/hotspot/test/compiler/7119644/TestByteVect.java
new file mode 100644
index 0000000..6167678
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestByteVect.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestByteVect
+ */
+
+public class TestByteVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Byte vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    byte[] a1 = new byte[ARRLEN];
+    byte[] a2 = new byte[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+      test_vi(a2, (byte)123);
+      test_cp(a1, a2);
+      test_2ci(a1, a2);
+      test_2vi(a1, a2, (byte)123, (byte)103);
+      test_ci_neg(a1);
+      test_vi_neg(a2, (byte)123);
+      test_cp_neg(a1, a2);
+      test_2ci_neg(a1, a2);
+      test_2vi_neg(a1, a2, (byte)123, (byte)103);
+      test_ci_oppos(a1);
+      test_vi_oppos(a2, (byte)123);
+      test_cp_oppos(a1, a2);
+      test_2ci_oppos(a1, a2);
+      test_2vi_oppos(a1, a2, (byte)123, (byte)103);
+      test_ci_off(a1);
+      test_vi_off(a2, (byte)123);
+      test_cp_off(a1, a2);
+      test_2ci_off(a1, a2);
+      test_2vi_off(a1, a2, (byte)123, (byte)103);
+      test_ci_inv(a1, OFFSET);
+      test_vi_inv(a2, (byte)123, OFFSET);
+      test_cp_inv(a1, a2, OFFSET);
+      test_2ci_inv(a1, a2, OFFSET);
+      test_2vi_inv(a1, a2, (byte)123, (byte)103, OFFSET);
+      test_ci_scl(a1);
+      test_vi_scl(a2, (byte)123);
+      test_cp_scl(a1, a2);
+      test_2ci_scl(a1, a2);
+      test_2vi_scl(a1, a2, (byte)123, (byte)103);
+      test_cp_alndst(a1, a2);
+      test_cp_alnsrc(a1, a2);
+      test_2ci_aln(a1, a2);
+      test_2vi_aln(a1, a2, (byte)123, (byte)103);
+      test_cp_unalndst(a1, a2);
+      test_cp_unalnsrc(a1, a2);
+      test_2ci_unaln(a1, a2);
+      test_2vi_unaln(a1, a2, (byte)123, (byte)103);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (byte)-123);
+      }
+      test_vi(a2, (byte)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (byte)123);
+      }
+      test_cp(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (byte)123);
+      }
+      test_2ci(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci: a1", i, a1[i], (byte)-123);
+        errn += verify("test_2ci: a2", i, a2[i], (byte)-103);
+      }
+      test_2vi(a1, a2, (byte)123, (byte)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi: a1", i, a1[i], (byte)123);
+        errn += verify("test_2vi: a2", i, a2[i], (byte)103);
+      }
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_neg(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (byte)-123);
+      }
+      test_vi_neg(a2, (byte)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (byte)123);
+      }
+      test_cp_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (byte)123);
+      }
+      test_2ci_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_neg: a1", i, a1[i], (byte)-123);
+        errn += verify("test_2ci_neg: a2", i, a2[i], (byte)-103);
+      }
+      test_2vi_neg(a1, a2, (byte)123, (byte)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_neg: a1", i, a1[i], (byte)123);
+        errn += verify("test_2vi_neg: a2", i, a2[i], (byte)103);
+      }
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_oppos(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (byte)-123);
+      }
+      test_vi_oppos(a2, (byte)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (byte)123);
+      }
+      test_cp_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (byte)123);
+      }
+      test_2ci_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_oppos: a1", i, a1[i], (byte)-123);
+        errn += verify("test_2ci_oppos: a2", i, a2[i], (byte)-103);
+      }
+      test_2vi_oppos(a1, a2, (byte)123, (byte)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_oppos: a1", i, a1[i], (byte)123);
+        errn += verify("test_2vi_oppos: a2", i, a2[i], (byte)103);
+      }
+      // Reset for indexing with offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_off(a1);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_off: a1", i, a1[i], (byte)-123);
+      }
+      test_vi_off(a2, (byte)123);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_off: a2", i, a2[i], (byte)123);
+      }
+      test_cp_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_off: a1", i, a1[i], (byte)123);
+      }
+      test_2ci_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_off: a1", i, a1[i], (byte)-123);
+        errn += verify("test_2ci_off: a2", i, a2[i], (byte)-103);
+      }
+      test_2vi_off(a1, a2, (byte)123, (byte)103);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (byte)123);
+        errn += verify("test_2vi_off: a2", i, a2[i], (byte)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (byte)-1);
+        errn += verify("test_2vi_off: a2", i, a2[i], (byte)-1);
+      }
+      // Reset for indexing with invariant offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_inv(a1, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_inv: a1", i, a1[i], (byte)-123);
+      }
+      test_vi_inv(a2, (byte)123, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_inv: a2", i, a2[i], (byte)123);
+      }
+      test_cp_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_inv: a1", i, a1[i], (byte)123);
+      }
+      test_2ci_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_inv: a1", i, a1[i], (byte)-123);
+        errn += verify("test_2ci_inv: a2", i, a2[i], (byte)-103);
+      }
+      test_2vi_inv(a1, a2, (byte)123, (byte)103, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (byte)123);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (byte)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (byte)-1);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (byte)-1);
+      }
+      // Reset for indexing with scale
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_scl(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : -123;
+        errn += verify("test_ci_scl: a1", i, a1[i], (byte)val);
+      }
+      test_vi_scl(a2, (byte)123);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_vi_scl: a2", i, a2[i], (byte)val);
+      }
+      test_cp_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_cp_scl: a1", i, a1[i], (byte)val);
+      }
+      test_2ci_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a1", i, a1[i], (byte)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], (byte)-123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a2", i, a2[i], (byte)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], (byte)-103);
+        }
+      }
+      test_2vi_scl(a1, a2, (byte)123, (byte)103);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a1", i, a1[i], (byte)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], (byte)123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a2", i, a2[i], (byte)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], (byte)103);
+        }
+      }
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, (byte)123);
+      test_cp_alndst(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (byte)123);
+      }
+      test_vi(a2, (byte)-123);
+      test_cp_alnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (byte)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_aln(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (byte)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (byte)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_aln(a1, a2, (byte)123, (byte)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (byte)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, (byte)123);
+      test_cp_unalndst(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (byte)123);
+      }
+      test_vi(a2, (byte)-123);
+      test_cp_unalnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (byte)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_unaln(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (byte)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (byte)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_unaln(a1, a2, (byte)123, (byte)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (byte)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_alndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (byte)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (byte)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_aln(a1, a1);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (byte)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_aln(a1, a1, (byte)123, (byte)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (byte)103);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (byte)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (byte)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (byte)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_unaln(a1, a1);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (byte)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (byte)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_unaln(a1, a1, (byte)123, (byte)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (byte)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (byte)103);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, (byte)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi(a1, a2, (byte)123, (byte)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a2, (byte)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_neg(a1, a2, (byte)123, (byte)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_neg: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a2, (byte)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_oppos(a1, a2, (byte)123, (byte)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_oppos: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_off(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_off(a2, (byte)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_off(a1, a2, (byte)123, (byte)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_off: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_inv(a1, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_inv(a2, (byte)123, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_inv(a1, a2, (byte)123, (byte)103, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_inv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_scl(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_scl(a2, (byte)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_scl(a1, a2, (byte)123, (byte)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_scl: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_aln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_aln(a1, a2, (byte)123, (byte)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_aln: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_unaln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_unaln(a1, a2, (byte)123, (byte)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_unaln: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_ci(byte[] a) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+    }
+  }
+  static void test_vi(byte[] a, byte b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi(byte[] a, byte[] b, byte c, byte d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_neg(byte[] a) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+    }
+  }
+  static void test_vi_neg(byte[] a, byte b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp_neg(byte[] a, byte[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci_neg(byte[] a, byte[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_neg(byte[] a, byte[] b, byte c, byte d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_oppos(byte[] a) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+    }
+  }
+  static void test_vi_oppos(byte[] a, byte b) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[limit-i] = b;
+    }
+  }
+  static void test_cp_oppos(byte[] a, byte[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+    }
+  }
+  static void test_2ci_oppos(byte[] a, byte[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_oppos(byte[] a, byte[] b, byte c, byte d) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_ci_off(byte[] a) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123;
+    }
+  }
+  static void test_vi_off(byte[] a, byte b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b;
+    }
+  }
+  static void test_cp_off(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b[i+OFFSET];
+    }
+  }
+  static void test_2ci_off(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123;
+      b[i+OFFSET] = -103;
+    }
+  }
+  static void test_2vi_off(byte[] a, byte[] b, byte c, byte d) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = c;
+      b[i+OFFSET] = d;
+    }
+  }
+  static void test_ci_inv(byte[] a, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123;
+    }
+  }
+  static void test_vi_inv(byte[] a, byte b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b;
+    }
+  }
+  static void test_cp_inv(byte[] a, byte[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b[i+k];
+    }
+  }
+  static void test_2ci_inv(byte[] a, byte[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123;
+      b[i+k] = -103;
+    }
+  }
+  static void test_2vi_inv(byte[] a, byte[] b, byte c, byte d, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = c;
+      b[i+k] = d;
+    }
+  }
+  static void test_ci_scl(byte[] a) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123;
+    }
+  }
+  static void test_vi_scl(byte[] a, byte b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b;
+    }
+  }
+  static void test_cp_scl(byte[] a, byte[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b[i*SCALE];
+    }
+  }
+  static void test_2ci_scl(byte[] a, byte[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123;
+      b[i*SCALE] = -103;
+    }
+  }
+  static void test_2vi_scl(byte[] a, byte[] b, byte c, byte d) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = c;
+      b[i*SCALE] = d;
+    }
+  }
+  static void test_cp_alndst(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_alnsrc(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+    }
+  }
+  static void test_2ci_aln(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_aln(byte[] a, byte[] b, byte c, byte d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_unalnsrc(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+    }
+  }
+  static void test_2ci_unaln(byte[] a, byte[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_unaln(byte[] a, byte[] b, byte c, byte d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+
+  static int verify(String text, int i, byte elem, byte val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestCharShortVect.java b/hotspot/test/compiler/7119644/TestCharShortVect.java
new file mode 100644
index 0000000..55f8e03
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestCharShortVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestCharShortVect
+ */
+
+public class TestCharShortVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Char + Short vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    char[] a1 = new char[ARRLEN];
+    char[] a2 = new char[ARRLEN];
+    short[] b1 = new short[ARRLEN];
+    short[] b2 = new short[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (char)123, (short)103);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (char)123, (short)103);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (char)123, (short)103);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (char)123, (short)103);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (char)123, (short)103);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = (char)-1;
+      a2[i] = (char)-1;
+      b1[i] = (short)-1;
+      b2[i] = (short)-1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (char)-123);
+        errn += verify("test_ci: b1", i, b1[i], (short)-103);
+      }
+      test_vi(a2, b2, (char)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (char)123);
+        errn += verify("test_vi: b2", i, b2[i], (short)103);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (char)123);
+        errn += verify("test_cp: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+        b1[i] = (short)-1;
+        b2[i] = (short)-1;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (char)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], (short)-103);
+      }
+      test_vi_neg(a2, b2, (char)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (char)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], (short)103);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (char)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+        b1[i] = (short)-1;
+        b2[i] = (short)-1;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (char)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], (short)-103);
+      }
+      test_vi_oppos(a2, b2, (char)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (char)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], (short)103);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (char)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)123;
+        b1[i] = (short)-1;
+        b2[i] = (short)123;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (char)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (char)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (short)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = (char)-123;
+        b2[i] = (short)-123;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (char)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (short)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (char)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (short)123);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        b1[i] = (short)-1;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (char)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (char)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (short)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (short)-1);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        b1[i] = (short)-1;
+      }
+      test_vi_aln(a1, b1, (char)123, (short)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (char)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (char)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)123;
+        b1[i] = (short)-1;
+        b2[i] = (short)123;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (char)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (char)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (short)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = (char)-123;
+        b2[i] = (short)-123;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (char)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (short)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (char)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (short)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        b1[i] = (short)-1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (char)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (char)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (short)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (short)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        b1[i] = (short)-1;
+      }
+      test_vi_unaln(a1, b1, (char)123, (short)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (char)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (char)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (short)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (char)i;
+        b1[i] = (short)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        b1[i] = (short)-1;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (char)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (short)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = (char)-1;
+        b1[i+ALIGN_OFF] = (short)-1;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (char)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (char)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (short)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (char)i;
+        b1[i] = (short)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        b1[i] = (short)-1;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (char)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (short)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = (char)-1;
+        b1[i+UNALIGN_OFF] = (short)-1;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (char)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (char)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (short)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (char)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (char)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (char)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (char)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (char)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(char[] a, short[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = (char)-123;
+      b[i] = (short)-103;
+    }
+  }
+  static void test_vi(char[] a, short[] b, char c, short d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(char[] a, char[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(char[] a, short[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = (char)-123;
+      b[i] = (short)-103;
+    }
+  }
+  static void test_vi_neg(char[] a, short[] b, char c, short d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(char[] a, char[] b, short[] c, short[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(char[] a, short[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = (char)-123;
+      b[i] = (short)-103;
+    }
+  }
+  static void test_vi_oppos(char[] a, short[] b, char c, short d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(char[] a, char[] b, short[] c, short[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(char[] a, short[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = (char)-123;
+      b[i] = (short)-103;
+    }
+  }
+  static void test_vi_aln(char[] a, short[] b, char c, short d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(char[] a, char[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(char[] a, char[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(char[] a, short[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = (char)-123;
+      b[i] = (short)-103;
+    }
+  }
+  static void test_vi_unaln(char[] a, short[] b, char c, short d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(char[] a, char[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(char[] a, char[] b, short[] c, short[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, char elem, char val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestCharVect.java b/hotspot/test/compiler/7119644/TestCharVect.java
new file mode 100644
index 0000000..d05ed4d
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestCharVect.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestCharVect
+ */
+
+public class TestCharVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Char vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    char[] a1 = new char[ARRLEN];
+    char[] a2 = new char[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+      test_vi(a2, (char)123);
+      test_cp(a1, a2);
+      test_2ci(a1, a2);
+      test_2vi(a1, a2, (char)123, (char)103);
+      test_ci_neg(a1);
+      test_vi_neg(a2, (char)123);
+      test_cp_neg(a1, a2);
+      test_2ci_neg(a1, a2);
+      test_2vi_neg(a1, a2, (char)123, (char)103);
+      test_ci_oppos(a1);
+      test_vi_oppos(a2, (char)123);
+      test_cp_oppos(a1, a2);
+      test_2ci_oppos(a1, a2);
+      test_2vi_oppos(a1, a2, (char)123, (char)103);
+      test_ci_off(a1);
+      test_vi_off(a2, (char)123);
+      test_cp_off(a1, a2);
+      test_2ci_off(a1, a2);
+      test_2vi_off(a1, a2, (char)123, (char)103);
+      test_ci_inv(a1, OFFSET);
+      test_vi_inv(a2, (char)123, OFFSET);
+      test_cp_inv(a1, a2, OFFSET);
+      test_2ci_inv(a1, a2, OFFSET);
+      test_2vi_inv(a1, a2, (char)123, (char)103, OFFSET);
+      test_ci_scl(a1);
+      test_vi_scl(a2, (char)123);
+      test_cp_scl(a1, a2);
+      test_2ci_scl(a1, a2);
+      test_2vi_scl(a1, a2, (char)123, (char)103);
+      test_cp_alndst(a1, a2);
+      test_cp_alnsrc(a1, a2);
+      test_2ci_aln(a1, a2);
+      test_2vi_aln(a1, a2, (char)123, (char)103);
+      test_cp_unalndst(a1, a2);
+      test_cp_unalnsrc(a1, a2);
+      test_2ci_unaln(a1, a2);
+      test_2vi_unaln(a1, a2, (char)123, (char)103);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = (char)-1;
+      a2[i] = (char)-1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (char)-123);
+      }
+      test_vi(a2, (char)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (char)123);
+      }
+      test_cp(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (char)123);
+      }
+      test_2ci(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci: a1", i, a1[i], (char)-123);
+        errn += verify("test_2ci: a2", i, a2[i], (char)-103);
+      }
+      test_2vi(a1, a2, (char)123, (char)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi: a1", i, a1[i], (char)123);
+        errn += verify("test_2vi: a2", i, a2[i], (char)103);
+      }
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_ci_neg(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (char)-123);
+      }
+      test_vi_neg(a2, (char)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (char)123);
+      }
+      test_cp_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (char)123);
+      }
+      test_2ci_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_neg: a1", i, a1[i], (char)-123);
+        errn += verify("test_2ci_neg: a2", i, a2[i], (char)-103);
+      }
+      test_2vi_neg(a1, a2, (char)123, (char)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_neg: a1", i, a1[i], (char)123);
+        errn += verify("test_2vi_neg: a2", i, a2[i], (char)103);
+      }
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_ci_oppos(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (char)-123);
+      }
+      test_vi_oppos(a2, (char)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (char)123);
+      }
+      test_cp_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (char)123);
+      }
+      test_2ci_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_oppos: a1", i, a1[i], (char)-123);
+        errn += verify("test_2ci_oppos: a2", i, a2[i], (char)-103);
+      }
+      test_2vi_oppos(a1, a2, (char)123, (char)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_oppos: a1", i, a1[i], (char)123);
+        errn += verify("test_2vi_oppos: a2", i, a2[i], (char)103);
+      }
+      // Reset for indexing with offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_ci_off(a1);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_off: a1", i, a1[i], (char)-123);
+      }
+      test_vi_off(a2, (char)123);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_off: a2", i, a2[i], (char)123);
+      }
+      test_cp_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_off: a1", i, a1[i], (char)123);
+      }
+      test_2ci_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_off: a1", i, a1[i], (char)-123);
+        errn += verify("test_2ci_off: a2", i, a2[i], (char)-103);
+      }
+      test_2vi_off(a1, a2, (char)123, (char)103);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (char)123);
+        errn += verify("test_2vi_off: a2", i, a2[i], (char)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (char)-1);
+        errn += verify("test_2vi_off: a2", i, a2[i], (char)-1);
+      }
+      // Reset for indexing with invariant offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_ci_inv(a1, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_inv: a1", i, a1[i], (char)-123);
+      }
+      test_vi_inv(a2, (char)123, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_inv: a2", i, a2[i], (char)123);
+      }
+      test_cp_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_inv: a1", i, a1[i], (char)123);
+      }
+      test_2ci_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_inv: a1", i, a1[i], (char)-123);
+        errn += verify("test_2ci_inv: a2", i, a2[i], (char)-103);
+      }
+      test_2vi_inv(a1, a2, (char)123, (char)103, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (char)123);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (char)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (char)-1);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (char)-1);
+      }
+      // Reset for indexing with scale
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_ci_scl(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : -123;
+        errn += verify("test_ci_scl: a1", i, a1[i], (char)val);
+      }
+      test_vi_scl(a2, (char)123);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_vi_scl: a2", i, a2[i], (char)val);
+      }
+      test_cp_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_cp_scl: a1", i, a1[i], (char)val);
+      }
+      test_2ci_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a1", i, a1[i], (char)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], (char)-123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a2", i, a2[i], (char)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], (char)-103);
+        }
+      }
+      test_2vi_scl(a1, a2, (char)123, (char)103);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a1", i, a1[i], (char)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], (char)123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a2", i, a2[i], (char)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], (char)103);
+        }
+      }
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_vi(a2, (char)123);
+      test_cp_alndst(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (char)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (char)123);
+      }
+      test_vi(a2, (char)-123);
+      test_cp_alnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (char)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (char)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_2ci_aln(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (char)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (char)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (char)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (char)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_2vi_aln(a1, a2, (char)123, (char)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (char)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (char)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (char)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (char)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_vi(a2, (char)123);
+      test_cp_unalndst(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (char)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (char)123);
+      }
+      test_vi(a2, (char)-123);
+      test_cp_unalnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (char)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (char)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_2ci_unaln(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (char)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (char)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (char)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (char)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+        a2[i] = (char)-1;
+      }
+      test_2vi_unaln(a1, a2, (char)123, (char)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (char)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (char)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (char)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (char)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (char)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+      }
+      test_cp_alndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (char)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = (char)-1;
+      }
+      test_cp_alnsrc(a1, a1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (char)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (char)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+      }
+      test_2ci_aln(a1, a1);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (char)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (char)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+      }
+      test_2vi_aln(a1, a1, (char)123, (char)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (char)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (char)103);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (char)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+      }
+      test_cp_unalndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (char)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = (char)-1;
+      }
+      test_cp_unalnsrc(a1, a1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (char)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (char)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+      }
+      test_2ci_unaln(a1, a1);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (char)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (char)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = (char)-1;
+      }
+      test_2vi_unaln(a1, a1, (char)123, (char)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (char)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (char)103);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, (char)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi(a1, a2, (char)123, (char)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a2, (char)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_neg(a1, a2, (char)123, (char)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_neg: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a2, (char)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_oppos(a1, a2, (char)123, (char)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_oppos: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_off(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_off(a2, (char)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_off(a1, a2, (char)123, (char)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_off: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_inv(a1, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_inv(a2, (char)123, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_inv(a1, a2, (char)123, (char)103, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_inv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_scl(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_scl(a2, (char)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_scl(a1, a2, (char)123, (char)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_scl: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_aln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_aln(a1, a2, (char)123, (char)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_aln: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_unaln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_unaln(a1, a2, (char)123, (char)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_unaln: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_ci(char[] a) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = (char)-123;
+    }
+  }
+  static void test_vi(char[] a, char b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp(char[] a, char[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci(char[] a, char[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = (char)-123;
+      b[i] = (char)-103;
+    }
+  }
+  static void test_2vi(char[] a, char[] b, char c, char d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_neg(char[] a) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = (char)-123;
+    }
+  }
+  static void test_vi_neg(char[] a, char b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp_neg(char[] a, char[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci_neg(char[] a, char[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = (char)-123;
+      b[i] = (char)-103;
+    }
+  }
+  static void test_2vi_neg(char[] a, char[] b, char c, char d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_oppos(char[] a) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = (char)-123;
+    }
+  }
+  static void test_vi_oppos(char[] a, char b) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[limit-i] = b;
+    }
+  }
+  static void test_cp_oppos(char[] a, char[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+    }
+  }
+  static void test_2ci_oppos(char[] a, char[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = (char)-123;
+      b[i] = (char)-103;
+    }
+  }
+  static void test_2vi_oppos(char[] a, char[] b, char c, char d) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_ci_off(char[] a) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = (char)-123;
+    }
+  }
+  static void test_vi_off(char[] a, char b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b;
+    }
+  }
+  static void test_cp_off(char[] a, char[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b[i+OFFSET];
+    }
+  }
+  static void test_2ci_off(char[] a, char[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = (char)-123;
+      b[i+OFFSET] = (char)-103;
+    }
+  }
+  static void test_2vi_off(char[] a, char[] b, char c, char d) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = c;
+      b[i+OFFSET] = d;
+    }
+  }
+  static void test_ci_inv(char[] a, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = (char)-123;
+    }
+  }
+  static void test_vi_inv(char[] a, char b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b;
+    }
+  }
+  static void test_cp_inv(char[] a, char[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b[i+k];
+    }
+  }
+  static void test_2ci_inv(char[] a, char[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = (char)-123;
+      b[i+k] = (char)-103;
+    }
+  }
+  static void test_2vi_inv(char[] a, char[] b, char c, char d, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = c;
+      b[i+k] = d;
+    }
+  }
+  static void test_ci_scl(char[] a) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = (char)-123;
+    }
+  }
+  static void test_vi_scl(char[] a, char b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b;
+    }
+  }
+  static void test_cp_scl(char[] a, char[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b[i*SCALE];
+    }
+  }
+  static void test_2ci_scl(char[] a, char[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = (char)-123;
+      b[i*SCALE] = (char)-103;
+    }
+  }
+  static void test_2vi_scl(char[] a, char[] b, char c, char d) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = c;
+      b[i*SCALE] = d;
+    }
+  }
+  static void test_cp_alndst(char[] a, char[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_alnsrc(char[] a, char[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+    }
+  }
+  static void test_2ci_aln(char[] a, char[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = (char)-123;
+      b[i] = (char)-103;
+    }
+  }
+  static void test_2vi_aln(char[] a, char[] b, char c, char d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(char[] a, char[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_unalnsrc(char[] a, char[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+    }
+  }
+  static void test_2ci_unaln(char[] a, char[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = (char)-123;
+      b[i] = (char)-103;
+    }
+  }
+  static void test_2vi_unaln(char[] a, char[] b, char c, char d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+
+  static int verify(String text, int i, char elem, char val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestDoubleVect.java b/hotspot/test/compiler/7119644/TestDoubleVect.java
new file mode 100644
index 0000000..385a64d
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestDoubleVect.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestDoubleVect
+ */
+
+public class TestDoubleVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Double vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    double[] a1 = new double[ARRLEN];
+    double[] a2 = new double[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+      test_vi(a2, 123.);
+      test_cp(a1, a2);
+      test_2ci(a1, a2);
+      test_2vi(a1, a2, 123., 103.);
+      test_ci_neg(a1);
+      test_vi_neg(a2, 123.);
+      test_cp_neg(a1, a2);
+      test_2ci_neg(a1, a2);
+      test_2vi_neg(a1, a2, 123., 103.);
+      test_ci_oppos(a1);
+      test_vi_oppos(a2, 123.);
+      test_cp_oppos(a1, a2);
+      test_2ci_oppos(a1, a2);
+      test_2vi_oppos(a1, a2, 123., 103.);
+      test_ci_off(a1);
+      test_vi_off(a2, 123.);
+      test_cp_off(a1, a2);
+      test_2ci_off(a1, a2);
+      test_2vi_off(a1, a2, 123., 103.);
+      test_ci_inv(a1, OFFSET);
+      test_vi_inv(a2, 123., OFFSET);
+      test_cp_inv(a1, a2, OFFSET);
+      test_2ci_inv(a1, a2, OFFSET);
+      test_2vi_inv(a1, a2, 123., 103., OFFSET);
+      test_ci_scl(a1);
+      test_vi_scl(a2, 123.);
+      test_cp_scl(a1, a2);
+      test_2ci_scl(a1, a2);
+      test_2vi_scl(a1, a2, 123., 103.);
+      test_cp_alndst(a1, a2);
+      test_cp_alnsrc(a1, a2);
+      test_2ci_aln(a1, a2);
+      test_2vi_aln(a1, a2, 123., 103.);
+      test_cp_unalndst(a1, a2);
+      test_cp_unalnsrc(a1, a2);
+      test_2ci_unaln(a1, a2);
+      test_2vi_unaln(a1, a2, 123., 103.);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], -123.);
+      }
+      test_vi(a2, 123.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], 123.);
+      }
+      test_cp(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], 123.);
+      }
+      test_2ci(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci: a1", i, a1[i], -123.);
+        errn += verify("test_2ci: a2", i, a2[i], -103.);
+      }
+      test_2vi(a1, a2, 123., 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi: a1", i, a1[i], 123.);
+        errn += verify("test_2vi: a2", i, a2[i], 103.);
+      }
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_neg(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], -123.);
+      }
+      test_vi_neg(a2, 123.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], 123.);
+      }
+      test_cp_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], 123.);
+      }
+      test_2ci_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_neg: a1", i, a1[i], -123.);
+        errn += verify("test_2ci_neg: a2", i, a2[i], -103.);
+      }
+      test_2vi_neg(a1, a2, 123., 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_neg: a1", i, a1[i], 123.);
+        errn += verify("test_2vi_neg: a2", i, a2[i], 103.);
+      }
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_oppos(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], -123.);
+      }
+      test_vi_oppos(a2, 123.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], 123.);
+      }
+      test_cp_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], 123.);
+      }
+      test_2ci_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_oppos: a1", i, a1[i], -123.);
+        errn += verify("test_2ci_oppos: a2", i, a2[i], -103.);
+      }
+      test_2vi_oppos(a1, a2, 123., 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_oppos: a1", i, a1[i], 123.);
+        errn += verify("test_2vi_oppos: a2", i, a2[i], 103.);
+      }
+      // Reset for indexing with offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_off(a1);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_off: a1", i, a1[i], -123.);
+      }
+      test_vi_off(a2, 123.);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_off: a2", i, a2[i], 123.);
+      }
+      test_cp_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_off: a1", i, a1[i], 123.);
+      }
+      test_2ci_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_off: a1", i, a1[i], -123.);
+        errn += verify("test_2ci_off: a2", i, a2[i], -103.);
+      }
+      test_2vi_off(a1, a2, 123., 103.);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], 123.);
+        errn += verify("test_2vi_off: a2", i, a2[i], 103.);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], -1.);
+        errn += verify("test_2vi_off: a2", i, a2[i], -1.);
+      }
+      // Reset for indexing with invariant offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_inv(a1, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_inv: a1", i, a1[i], -123.);
+      }
+      test_vi_inv(a2, 123., OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_inv: a2", i, a2[i], 123.);
+      }
+      test_cp_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_inv: a1", i, a1[i], 123.);
+      }
+      test_2ci_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_inv: a1", i, a1[i], -123.);
+        errn += verify("test_2ci_inv: a2", i, a2[i], -103.);
+      }
+      test_2vi_inv(a1, a2, 123., 103., OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], 123.);
+        errn += verify("test_2vi_inv: a2", i, a2[i], 103.);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], -1.);
+        errn += verify("test_2vi_inv: a2", i, a2[i], -1.);
+      }
+      // Reset for indexing with scale
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_scl(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : -123;
+        errn += verify("test_ci_scl: a1", i, a1[i], (double)val);
+      }
+      test_vi_scl(a2, 123.);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_vi_scl: a2", i, a2[i], (double)val);
+      }
+      test_cp_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_cp_scl: a1", i, a1[i], (double)val);
+      }
+      test_2ci_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a1", i, a1[i], -1.);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], -123.);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a2", i, a2[i], -1.);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], -103.);
+        }
+      }
+      test_2vi_scl(a1, a2, 123., 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a1", i, a1[i], -1.);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], 123.);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a2", i, a2[i], -1.);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], 103.);
+        }
+      }
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, 123.);
+      test_cp_alndst(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], 123.);
+      }
+      test_vi(a2, -123.);
+      test_cp_alnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], -123.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_aln(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], -123.);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], -103.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], -1.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_aln(a1, a2, 123., 103.);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], 123.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], -1.);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, 123.);
+      test_cp_unalndst(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], 123.);
+      }
+      test_vi(a2, -123.);
+      test_cp_unalnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], -123.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_unaln(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], -123.);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], -103.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], -1.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_unaln(a1, a2, 123., 103.);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], 123.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], -1.);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], 103.);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (double)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_alndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (double)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (double)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_aln(a1, a1);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -103.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_aln(a1, a1, 123., 103.);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 123.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 103.);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (double)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (double)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (double)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_unaln(a1, a1);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -103.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_unaln(a1, a1, 123., 103.);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 123.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 103.);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, 123.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi(a1, a2, 123., 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a2, 123.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_neg(a1, a2, 123., 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_neg: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a2, 123.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_oppos(a1, a2, 123., 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_oppos: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_off(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_off(a2, 123.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_off(a1, a2, 123., 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_off: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_inv(a1, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_inv(a2, 123., OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_inv(a1, a2, 123., 103., OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_inv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_scl(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_scl(a2, 123.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_scl(a1, a2, 123., 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_scl: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_aln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_aln(a1, a2, 123., 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_aln: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_unaln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_unaln(a1, a2, 123., 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_unaln: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_ci(double[] a) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123.;
+    }
+  }
+  static void test_vi(double[] a, double b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp(double[] a, double[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci(double[] a, double[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123.;
+      b[i] = -103.;
+    }
+  }
+  static void test_2vi(double[] a, double[] b, double c, double d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_neg(double[] a) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123.;
+    }
+  }
+  static void test_vi_neg(double[] a, double b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp_neg(double[] a, double[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci_neg(double[] a, double[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123.;
+      b[i] = -103.;
+    }
+  }
+  static void test_2vi_neg(double[] a, double[] b, double c, double d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_oppos(double[] a) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123.;
+    }
+  }
+  static void test_vi_oppos(double[] a, double b) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[limit-i] = b;
+    }
+  }
+  static void test_cp_oppos(double[] a, double[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+    }
+  }
+  static void test_2ci_oppos(double[] a, double[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123.;
+      b[i] = -103.;
+    }
+  }
+  static void test_2vi_oppos(double[] a, double[] b, double c, double d) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_ci_off(double[] a) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123.;
+    }
+  }
+  static void test_vi_off(double[] a, double b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b;
+    }
+  }
+  static void test_cp_off(double[] a, double[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b[i+OFFSET];
+    }
+  }
+  static void test_2ci_off(double[] a, double[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123.;
+      b[i+OFFSET] = -103.;
+    }
+  }
+  static void test_2vi_off(double[] a, double[] b, double c, double d) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = c;
+      b[i+OFFSET] = d;
+    }
+  }
+  static void test_ci_inv(double[] a, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123.;
+    }
+  }
+  static void test_vi_inv(double[] a, double b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b;
+    }
+  }
+  static void test_cp_inv(double[] a, double[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b[i+k];
+    }
+  }
+  static void test_2ci_inv(double[] a, double[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123.;
+      b[i+k] = -103.;
+    }
+  }
+  static void test_2vi_inv(double[] a, double[] b, double c, double d, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = c;
+      b[i+k] = d;
+    }
+  }
+  static void test_ci_scl(double[] a) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123.;
+    }
+  }
+  static void test_vi_scl(double[] a, double b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b;
+    }
+  }
+  static void test_cp_scl(double[] a, double[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b[i*SCALE];
+    }
+  }
+  static void test_2ci_scl(double[] a, double[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123.;
+      b[i*SCALE] = -103.;
+    }
+  }
+  static void test_2vi_scl(double[] a, double[] b, double c, double d) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = c;
+      b[i*SCALE] = d;
+    }
+  }
+  static void test_cp_alndst(double[] a, double[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_alnsrc(double[] a, double[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+    }
+  }
+  static void test_2ci_aln(double[] a, double[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123.;
+      b[i] = -103.;
+    }
+  }
+  static void test_2vi_aln(double[] a, double[] b, double c, double d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(double[] a, double[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_unalnsrc(double[] a, double[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+    }
+  }
+  static void test_2ci_unaln(double[] a, double[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123.;
+      b[i] = -103.;
+    }
+  }
+  static void test_2vi_unaln(double[] a, double[] b, double c, double d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+
+  static int verify(String text, int i, double elem, double val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestFloatDoubleVect.java b/hotspot/test/compiler/7119644/TestFloatDoubleVect.java
new file mode 100644
index 0000000..827ecdb
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestFloatDoubleVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestFloatDoubleVect
+ */
+
+public class TestFloatDoubleVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Float + Double vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    float[] a1 = new float[ARRLEN];
+    float[] a2 = new float[ARRLEN];
+    double[] b1 = new double[ARRLEN];
+    double[] b2 = new double[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, 123.f, 103.);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, 123.f, 103.);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, 123.f, 103.);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, 123.f, 103.);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, 123.f, 103.);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.;
+      b2[i] = -1.;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], -123.f);
+        errn += verify("test_ci: b1", i, b1[i], -103.);
+      }
+      test_vi(a2, b2, 123.f, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], 123.f);
+        errn += verify("test_vi: b2", i, b2[i], 103.);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], 123.f);
+        errn += verify("test_cp: b1", i, b1[i], 103.);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], -123.f);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.);
+      }
+      test_vi_neg(a2, b2, 123.f, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], 123.f);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], 123.f);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], -123.f);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.);
+      }
+      test_vi_oppos(a2, b2, 123.f, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], 123.f);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], 123.f);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], -1.f);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], 123.f);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], -123.f);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], 123.f);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], -123.f);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_vi_aln(a1, b1, 123.f, 103.);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], 123.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], -1.f);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], -1.f);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], 123.f);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], -123.f);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], 123.f);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], -123.f);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, 123.f, 103.);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], 123.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], -1.f);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (float)i;
+        b1[i] = (double)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (float)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], -1.f);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (float)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (float)i;
+        b1[i] = (double)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (float)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], -1.f);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (float)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, 123.f, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, 123.f, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, 123.f, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, 123.f, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, 123.f, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(float[] a, double[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123.f;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi(float[] a, double[] b, float c, double d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(float[] a, float[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(float[] a, double[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123.f;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_neg(float[] a, double[] b, float c, double d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(float[] a, float[] b, double[] c, double[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(float[] a, double[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123.f;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_oppos(float[] a, double[] b, float c, double d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(float[] a, float[] b, double[] c, double[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(float[] a, double[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123.f;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_aln(float[] a, double[] b, float c, double d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(float[] a, float[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(float[] a, float[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(float[] a, double[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123.f;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_unaln(float[] a, double[] b, float c, double d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(float[] a, float[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(float[] a, float[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, double elem, double val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestFloatVect.java b/hotspot/test/compiler/7119644/TestFloatVect.java
new file mode 100644
index 0000000..825fffe
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestFloatVect.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestFloatVect
+ */
+
+public class TestFloatVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Float vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    float[] a1 = new float[ARRLEN];
+    float[] a2 = new float[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+      test_vi(a2, 123.f);
+      test_cp(a1, a2);
+      test_2ci(a1, a2);
+      test_2vi(a1, a2, 123.f, 103.f);
+      test_ci_neg(a1);
+      test_vi_neg(a2, 123.f);
+      test_cp_neg(a1, a2);
+      test_2ci_neg(a1, a2);
+      test_2vi_neg(a1, a2, 123.f, 103.f);
+      test_ci_oppos(a1);
+      test_vi_oppos(a2, 123.f);
+      test_cp_oppos(a1, a2);
+      test_2ci_oppos(a1, a2);
+      test_2vi_oppos(a1, a2, 123.f, 103.f);
+      test_ci_off(a1);
+      test_vi_off(a2, 123.f);
+      test_cp_off(a1, a2);
+      test_2ci_off(a1, a2);
+      test_2vi_off(a1, a2, 123.f, 103.f);
+      test_ci_inv(a1, OFFSET);
+      test_vi_inv(a2, 123.f, OFFSET);
+      test_cp_inv(a1, a2, OFFSET);
+      test_2ci_inv(a1, a2, OFFSET);
+      test_2vi_inv(a1, a2, 123.f, 103.f, OFFSET);
+      test_ci_scl(a1);
+      test_vi_scl(a2, 123.f);
+      test_cp_scl(a1, a2);
+      test_2ci_scl(a1, a2);
+      test_2vi_scl(a1, a2, 123.f, 103.f);
+      test_cp_alndst(a1, a2);
+      test_cp_alnsrc(a1, a2);
+      test_2ci_aln(a1, a2);
+      test_2vi_aln(a1, a2, 123.f, 103.f);
+      test_cp_unalndst(a1, a2);
+      test_cp_unalnsrc(a1, a2);
+      test_2ci_unaln(a1, a2);
+      test_2vi_unaln(a1, a2, 123.f, 103.f);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], -123.f);
+      }
+      test_vi(a2, 123.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], 123.f);
+      }
+      test_cp(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], 123.f);
+      }
+      test_2ci(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci: a1", i, a1[i], -123.f);
+        errn += verify("test_2ci: a2", i, a2[i], -103.f);
+      }
+      test_2vi(a1, a2, 123.f, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi: a1", i, a1[i], 123.f);
+        errn += verify("test_2vi: a2", i, a2[i], 103.f);
+      }
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_neg(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], -123.f);
+      }
+      test_vi_neg(a2, 123.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], 123.f);
+      }
+      test_cp_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], 123.f);
+      }
+      test_2ci_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_neg: a1", i, a1[i], -123.f);
+        errn += verify("test_2ci_neg: a2", i, a2[i], -103.f);
+      }
+      test_2vi_neg(a1, a2, 123.f, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_neg: a1", i, a1[i], 123.f);
+        errn += verify("test_2vi_neg: a2", i, a2[i], 103.f);
+      }
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_oppos(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], -123.f);
+      }
+      test_vi_oppos(a2, 123.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], 123.f);
+      }
+      test_cp_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], 123.f);
+      }
+      test_2ci_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_oppos: a1", i, a1[i], -123.f);
+        errn += verify("test_2ci_oppos: a2", i, a2[i], -103.f);
+      }
+      test_2vi_oppos(a1, a2, 123.f, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_oppos: a1", i, a1[i], 123.f);
+        errn += verify("test_2vi_oppos: a2", i, a2[i], 103.f);
+      }
+      // Reset for indexing with offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_off(a1);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_off: a1", i, a1[i], -123.f);
+      }
+      test_vi_off(a2, 123.f);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_off: a2", i, a2[i], 123.f);
+      }
+      test_cp_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_off: a1", i, a1[i], 123.f);
+      }
+      test_2ci_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_off: a1", i, a1[i], -123.f);
+        errn += verify("test_2ci_off: a2", i, a2[i], -103.f);
+      }
+      test_2vi_off(a1, a2, 123.f, 103.f);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], 123.f);
+        errn += verify("test_2vi_off: a2", i, a2[i], 103.f);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], -1.f);
+        errn += verify("test_2vi_off: a2", i, a2[i], -1.f);
+      }
+      // Reset for indexing with invariant offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_inv(a1, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_inv: a1", i, a1[i], -123.f);
+      }
+      test_vi_inv(a2, 123.f, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_inv: a2", i, a2[i], 123.f);
+      }
+      test_cp_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_inv: a1", i, a1[i], 123.f);
+      }
+      test_2ci_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_inv: a1", i, a1[i], -123.f);
+        errn += verify("test_2ci_inv: a2", i, a2[i], -103.f);
+      }
+      test_2vi_inv(a1, a2, 123.f, 103.f, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], 123.f);
+        errn += verify("test_2vi_inv: a2", i, a2[i], 103.f);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], -1.f);
+        errn += verify("test_2vi_inv: a2", i, a2[i], -1.f);
+      }
+      // Reset for indexing with scale
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_scl(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : -123;
+        errn += verify("test_ci_scl: a1", i, a1[i], (float)val);
+      }
+      test_vi_scl(a2, 123.f);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_vi_scl: a2", i, a2[i], (float)val);
+      }
+      test_cp_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_cp_scl: a1", i, a1[i], (float)val);
+      }
+      test_2ci_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a1", i, a1[i], -1.f);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], -123.f);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a2", i, a2[i], -1.f);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], -103.f);
+        }
+      }
+      test_2vi_scl(a1, a2, 123.f, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a1", i, a1[i], -1.f);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], 123.f);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a2", i, a2[i], -1.f);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], 103.f);
+        }
+      }
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, 123.f);
+      test_cp_alndst(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], 123.f);
+      }
+      test_vi(a2, -123.f);
+      test_cp_alnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], -123.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_aln(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], -123.f);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], -103.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], -1.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_aln(a1, a2, 123.f, 103.f);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], 123.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], -1.f);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, 123.f);
+      test_cp_unalndst(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], 123.f);
+      }
+      test_vi(a2, -123.f);
+      test_cp_unalnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], -123.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_unaln(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], -123.f);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], -103.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], -1.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_unaln(a1, a2, 123.f, 103.f);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], 123.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], -1.f);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], 103.f);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (float)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_alndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (float)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (float)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_aln(a1, a1);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -103.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], -123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_aln(a1, a1, 123.f, 103.f);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 123.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], 103.f);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (float)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (float)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (float)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_unaln(a1, a1);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -103.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], -123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_unaln(a1, a1, 123.f, 103.f);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 123.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], 103.f);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, 123.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi(a1, a2, 123.f, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a2, 123.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_neg(a1, a2, 123.f, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_neg: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a2, 123.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_oppos(a1, a2, 123.f, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_oppos: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_off(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_off(a2, 123.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_off(a1, a2, 123.f, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_off: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_inv(a1, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_inv(a2, 123.f, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_inv(a1, a2, 123.f, 103.f, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_inv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_scl(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_scl(a2, 123.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_scl(a1, a2, 123.f, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_scl: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_aln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_aln(a1, a2, 123.f, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_aln: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_unaln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_unaln(a1, a2, 123.f, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_unaln: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_ci(float[] a) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123.f;
+    }
+  }
+  static void test_vi(float[] a, float b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp(float[] a, float[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci(float[] a, float[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123.f;
+      b[i] = -103.f;
+    }
+  }
+  static void test_2vi(float[] a, float[] b, float c, float d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_neg(float[] a) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123.f;
+    }
+  }
+  static void test_vi_neg(float[] a, float b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp_neg(float[] a, float[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci_neg(float[] a, float[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123.f;
+      b[i] = -103.f;
+    }
+  }
+  static void test_2vi_neg(float[] a, float[] b, float c, float d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_oppos(float[] a) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123.f;
+    }
+  }
+  static void test_vi_oppos(float[] a, float b) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[limit-i] = b;
+    }
+  }
+  static void test_cp_oppos(float[] a, float[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+    }
+  }
+  static void test_2ci_oppos(float[] a, float[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123.f;
+      b[i] = -103.f;
+    }
+  }
+  static void test_2vi_oppos(float[] a, float[] b, float c, float d) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_ci_off(float[] a) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123.f;
+    }
+  }
+  static void test_vi_off(float[] a, float b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b;
+    }
+  }
+  static void test_cp_off(float[] a, float[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b[i+OFFSET];
+    }
+  }
+  static void test_2ci_off(float[] a, float[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123.f;
+      b[i+OFFSET] = -103.f;
+    }
+  }
+  static void test_2vi_off(float[] a, float[] b, float c, float d) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = c;
+      b[i+OFFSET] = d;
+    }
+  }
+  static void test_ci_inv(float[] a, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123.f;
+    }
+  }
+  static void test_vi_inv(float[] a, float b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b;
+    }
+  }
+  static void test_cp_inv(float[] a, float[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b[i+k];
+    }
+  }
+  static void test_2ci_inv(float[] a, float[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123.f;
+      b[i+k] = -103.f;
+    }
+  }
+  static void test_2vi_inv(float[] a, float[] b, float c, float d, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = c;
+      b[i+k] = d;
+    }
+  }
+  static void test_ci_scl(float[] a) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123.f;
+    }
+  }
+  static void test_vi_scl(float[] a, float b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b;
+    }
+  }
+  static void test_cp_scl(float[] a, float[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b[i*SCALE];
+    }
+  }
+  static void test_2ci_scl(float[] a, float[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123.f;
+      b[i*SCALE] = -103.f;
+    }
+  }
+  static void test_2vi_scl(float[] a, float[] b, float c, float d) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = c;
+      b[i*SCALE] = d;
+    }
+  }
+  static void test_cp_alndst(float[] a, float[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_alnsrc(float[] a, float[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+    }
+  }
+  static void test_2ci_aln(float[] a, float[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123.f;
+      b[i] = -103.f;
+    }
+  }
+  static void test_2vi_aln(float[] a, float[] b, float c, float d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(float[] a, float[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_unalnsrc(float[] a, float[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+    }
+  }
+  static void test_2ci_unaln(float[] a, float[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123.f;
+      b[i] = -103.f;
+    }
+  }
+  static void test_2vi_unaln(float[] a, float[] b, float c, float d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestIntDoubleVect.java b/hotspot/test/compiler/7119644/TestIntDoubleVect.java
new file mode 100644
index 0000000..fc6e32d
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestIntDoubleVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntDoubleVect
+ */
+
+public class TestIntDoubleVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Integer + Double vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    int[] a1 = new int[ARRLEN];
+    int[] a2 = new int[ARRLEN];
+    double[] b1 = new double[ARRLEN];
+    double[] b2 = new double[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (int)123, 103.);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (int)123, 103.);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (int)123, 103.);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (int)123, 103.);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (int)123, 103.);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.;
+      b2[i] = -1.;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci: b1", i, b1[i], -103.);
+      }
+      test_vi(a2, b2, (int)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (int)123);
+        errn += verify("test_vi: b2", i, b2[i], 103.);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (int)123);
+        errn += verify("test_cp: b1", i, b1[i], 103.);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.);
+      }
+      test_vi_neg(a2, b2, (int)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (int)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.);
+      }
+      test_vi_oppos(a2, b2, (int)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (int)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (int)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_vi_aln(a1, b1, (int)123, 103.);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (int)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (int)123, 103.);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (int)i;
+        b1[i] = (double)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (int)i;
+        b1[i] = (double)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (int)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (int)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (int)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (int)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (int)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(int[] a, double[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi(int[] a, double[] b, int c, double d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(int[] a, int[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(int[] a, double[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_neg(int[] a, double[] b, int c, double d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(int[] a, int[] b, double[] c, double[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(int[] a, double[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_oppos(int[] a, double[] b, int c, double d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(int[] a, int[] b, double[] c, double[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(int[] a, double[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_aln(int[] a, double[] b, int c, double d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(int[] a, int[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(int[] a, int[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(int[] a, double[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_unaln(int[] a, double[] b, int c, double d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(int[] a, int[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(int[] a, int[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, double elem, double val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestIntFloatVect.java b/hotspot/test/compiler/7119644/TestIntFloatVect.java
new file mode 100644
index 0000000..e698c89
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestIntFloatVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntFloatVect
+ */
+
+public class TestIntFloatVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Integer + Float vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    int[] a1 = new int[ARRLEN];
+    int[] a2 = new int[ARRLEN];
+    float[] b1 = new float[ARRLEN];
+    float[] b2 = new float[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (int)123, 103.f);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (int)123, 103.f);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (int)123, 103.f);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (int)123, 103.f);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (int)123, 103.f);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.f;
+      b2[i] = -1.f;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci: b1", i, b1[i], -103.f);
+      }
+      test_vi(a2, b2, (int)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (int)123);
+        errn += verify("test_vi: b2", i, b2[i], 103.f);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (int)123);
+        errn += verify("test_cp: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.f;
+        b2[i] = -1.f;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.f);
+      }
+      test_vi_neg(a2, b2, (int)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (int)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.f);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.f;
+        b2[i] = -1.f;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.f);
+      }
+      test_vi_oppos(a2, b2, (int)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (int)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.f);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.f;
+        b2[i] = 123.f;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.f;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (int)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.f);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.f);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_vi_aln(a1, b1, (int)123, 103.f);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.f;
+        b2[i] = 123.f;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.f;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (int)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (int)123, 103.f);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (int)i;
+        b1[i] = (float)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (float)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.f;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (float)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (int)i;
+        b1[i] = (float)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (float)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.f;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (float)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (int)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (int)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (int)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (int)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (int)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(int[] a, float[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi(int[] a, float[] b, int c, float d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(int[] a, int[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(int[] a, float[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_neg(int[] a, float[] b, int c, float d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(int[] a, int[] b, float[] c, float[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(int[] a, float[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_oppos(int[] a, float[] b, int c, float d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(int[] a, int[] b, float[] c, float[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(int[] a, float[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_aln(int[] a, float[] b, int c, float d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(int[] a, int[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(int[] a, int[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(int[] a, float[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_unaln(int[] a, float[] b, int c, float d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(int[] a, int[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(int[] a, int[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestIntLongVect.java b/hotspot/test/compiler/7119644/TestIntLongVect.java
new file mode 100644
index 0000000..def0d9b
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestIntLongVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntLongVect
+ */
+
+public class TestIntLongVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Integer + Long vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    int[] a1 = new int[ARRLEN];
+    int[] a2 = new int[ARRLEN];
+    long[] b1 = new long[ARRLEN];
+    long[] b2 = new long[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (int)123, (long)103);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (int)123, (long)103);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (int)123, (long)103);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (int)123, (long)103);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (int)123, (long)103);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1;
+      b2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci: b1", i, b1[i], (long)-103);
+      }
+      test_vi(a2, b2, (int)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (int)123);
+        errn += verify("test_vi: b2", i, b2[i], (long)103);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (int)123);
+        errn += verify("test_cp: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], (long)-103);
+      }
+      test_vi_neg(a2, b2, (int)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (int)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], (long)103);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (int)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], (long)-103);
+      }
+      test_vi_oppos(a2, b2, (int)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (int)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], (long)103);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (int)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (long)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (long)123);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (long)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (long)-1);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_aln(a1, b1, (int)123, (long)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (int)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (long)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (int)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (long)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (int)123, (long)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (int)i;
+        b1[i] = (long)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (long)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (long)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (int)i;
+        b1[i] = (long)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (long)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (long)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (int)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (int)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (int)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (int)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (int)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(int[] a, long[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi(int[] a, long[] b, int c, long d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(int[] a, int[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(int[] a, long[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_neg(int[] a, long[] b, int c, long d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(int[] a, int[] b, long[] c, long[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(int[] a, long[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_oppos(int[] a, long[] b, int c, long d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(int[] a, int[] b, long[] c, long[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(int[] a, long[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_aln(int[] a, long[] b, int c, long d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(int[] a, int[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(int[] a, int[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(int[] a, long[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_unaln(int[] a, long[] b, int c, long d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(int[] a, int[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(int[] a, int[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestIntVect.java b/hotspot/test/compiler/7119644/TestIntVect.java
new file mode 100644
index 0000000..9d3f4e5
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestIntVect.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestIntVect
+ */
+
+public class TestIntVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Integer vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    int[] a1 = new int[ARRLEN];
+    int[] a2 = new int[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+      test_vi(a2, (int)123);
+      test_cp(a1, a2);
+      test_2ci(a1, a2);
+      test_2vi(a1, a2, (int)123, (int)103);
+      test_ci_neg(a1);
+      test_vi_neg(a2, (int)123);
+      test_cp_neg(a1, a2);
+      test_2ci_neg(a1, a2);
+      test_2vi_neg(a1, a2, (int)123, (int)103);
+      test_ci_oppos(a1);
+      test_vi_oppos(a2, (int)123);
+      test_cp_oppos(a1, a2);
+      test_2ci_oppos(a1, a2);
+      test_2vi_oppos(a1, a2, (int)123, (int)103);
+      test_ci_off(a1);
+      test_vi_off(a2, (int)123);
+      test_cp_off(a1, a2);
+      test_2ci_off(a1, a2);
+      test_2vi_off(a1, a2, (int)123, (int)103);
+      test_ci_inv(a1, OFFSET);
+      test_vi_inv(a2, (int)123, OFFSET);
+      test_cp_inv(a1, a2, OFFSET);
+      test_2ci_inv(a1, a2, OFFSET);
+      test_2vi_inv(a1, a2, (int)123, (int)103, OFFSET);
+      test_ci_scl(a1);
+      test_vi_scl(a2, (int)123);
+      test_cp_scl(a1, a2);
+      test_2ci_scl(a1, a2);
+      test_2vi_scl(a1, a2, (int)123, (int)103);
+      test_cp_alndst(a1, a2);
+      test_cp_alnsrc(a1, a2);
+      test_2ci_aln(a1, a2);
+      test_2vi_aln(a1, a2, (int)123, (int)103);
+      test_cp_unalndst(a1, a2);
+      test_cp_unalnsrc(a1, a2);
+      test_2ci_unaln(a1, a2);
+      test_2vi_unaln(a1, a2, (int)123, (int)103);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (int)-123);
+      }
+      test_vi(a2, (int)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (int)123);
+      }
+      test_cp(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (int)123);
+      }
+      test_2ci(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci: a1", i, a1[i], (int)-123);
+        errn += verify("test_2ci: a2", i, a2[i], (int)-103);
+      }
+      test_2vi(a1, a2, (int)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi: a1", i, a1[i], (int)123);
+        errn += verify("test_2vi: a2", i, a2[i], (int)103);
+      }
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_neg(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (int)-123);
+      }
+      test_vi_neg(a2, (int)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (int)123);
+      }
+      test_cp_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (int)123);
+      }
+      test_2ci_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_neg: a1", i, a1[i], (int)-123);
+        errn += verify("test_2ci_neg: a2", i, a2[i], (int)-103);
+      }
+      test_2vi_neg(a1, a2, (int)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_neg: a1", i, a1[i], (int)123);
+        errn += verify("test_2vi_neg: a2", i, a2[i], (int)103);
+      }
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_oppos(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (int)-123);
+      }
+      test_vi_oppos(a2, (int)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (int)123);
+      }
+      test_cp_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (int)123);
+      }
+      test_2ci_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_oppos: a1", i, a1[i], (int)-123);
+        errn += verify("test_2ci_oppos: a2", i, a2[i], (int)-103);
+      }
+      test_2vi_oppos(a1, a2, (int)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_oppos: a1", i, a1[i], (int)123);
+        errn += verify("test_2vi_oppos: a2", i, a2[i], (int)103);
+      }
+      // Reset for indexing with offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_off(a1);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_off: a1", i, a1[i], (int)-123);
+      }
+      test_vi_off(a2, (int)123);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_off: a2", i, a2[i], (int)123);
+      }
+      test_cp_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_off: a1", i, a1[i], (int)123);
+      }
+      test_2ci_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_off: a1", i, a1[i], (int)-123);
+        errn += verify("test_2ci_off: a2", i, a2[i], (int)-103);
+      }
+      test_2vi_off(a1, a2, (int)123, (int)103);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (int)123);
+        errn += verify("test_2vi_off: a2", i, a2[i], (int)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (int)-1);
+        errn += verify("test_2vi_off: a2", i, a2[i], (int)-1);
+      }
+      // Reset for indexing with invariant offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_inv(a1, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_inv: a1", i, a1[i], (int)-123);
+      }
+      test_vi_inv(a2, (int)123, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_inv: a2", i, a2[i], (int)123);
+      }
+      test_cp_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_inv: a1", i, a1[i], (int)123);
+      }
+      test_2ci_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_inv: a1", i, a1[i], (int)-123);
+        errn += verify("test_2ci_inv: a2", i, a2[i], (int)-103);
+      }
+      test_2vi_inv(a1, a2, (int)123, (int)103, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (int)123);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (int)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (int)-1);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (int)-1);
+      }
+      // Reset for indexing with scale
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_scl(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : -123;
+        errn += verify("test_ci_scl: a1", i, a1[i], (int)val);
+      }
+      test_vi_scl(a2, (int)123);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_vi_scl: a2", i, a2[i], (int)val);
+      }
+      test_cp_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_cp_scl: a1", i, a1[i], (int)val);
+      }
+      test_2ci_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a1", i, a1[i], (int)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], (int)-123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a2", i, a2[i], (int)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], (int)-103);
+        }
+      }
+      test_2vi_scl(a1, a2, (int)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a1", i, a1[i], (int)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], (int)123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a2", i, a2[i], (int)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], (int)103);
+        }
+      }
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, (int)123);
+      test_cp_alndst(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (int)123);
+      }
+      test_vi(a2, (int)-123);
+      test_cp_alnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (int)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (int)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_aln(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (int)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (int)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_aln(a1, a2, (int)123, (int)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (int)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, (int)123);
+      test_cp_unalndst(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (int)123);
+      }
+      test_vi(a2, (int)-123);
+      test_cp_unalnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (int)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (int)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_unaln(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (int)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (int)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_unaln(a1, a2, (int)123, (int)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (int)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (int)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (int)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_alndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (int)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (int)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_aln(a1, a1);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (int)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_aln(a1, a1, (int)123, (int)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (int)103);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (int)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (int)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (int)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_unaln(a1, a1);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (int)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (int)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_unaln(a1, a1, (int)123, (int)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (int)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (int)103);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, (int)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi(a1, a2, (int)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a2, (int)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_neg(a1, a2, (int)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_neg: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a2, (int)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_oppos(a1, a2, (int)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_oppos: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_off(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_off(a2, (int)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_off(a1, a2, (int)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_off: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_inv(a1, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_inv(a2, (int)123, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_inv(a1, a2, (int)123, (int)103, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_inv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_scl(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_scl(a2, (int)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_scl(a1, a2, (int)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_scl: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_aln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_aln(a1, a2, (int)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_aln: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_unaln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_unaln(a1, a2, (int)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_unaln: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_ci(int[] a) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+    }
+  }
+  static void test_vi(int[] a, int b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp(int[] a, int[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci(int[] a, int[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi(int[] a, int[] b, int c, int d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_neg(int[] a) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+    }
+  }
+  static void test_vi_neg(int[] a, int b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp_neg(int[] a, int[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci_neg(int[] a, int[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_neg(int[] a, int[] b, int c, int d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_oppos(int[] a) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+    }
+  }
+  static void test_vi_oppos(int[] a, int b) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[limit-i] = b;
+    }
+  }
+  static void test_cp_oppos(int[] a, int[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+    }
+  }
+  static void test_2ci_oppos(int[] a, int[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_oppos(int[] a, int[] b, int c, int d) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_ci_off(int[] a) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123;
+    }
+  }
+  static void test_vi_off(int[] a, int b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b;
+    }
+  }
+  static void test_cp_off(int[] a, int[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b[i+OFFSET];
+    }
+  }
+  static void test_2ci_off(int[] a, int[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123;
+      b[i+OFFSET] = -103;
+    }
+  }
+  static void test_2vi_off(int[] a, int[] b, int c, int d) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = c;
+      b[i+OFFSET] = d;
+    }
+  }
+  static void test_ci_inv(int[] a, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123;
+    }
+  }
+  static void test_vi_inv(int[] a, int b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b;
+    }
+  }
+  static void test_cp_inv(int[] a, int[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b[i+k];
+    }
+  }
+  static void test_2ci_inv(int[] a, int[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123;
+      b[i+k] = -103;
+    }
+  }
+  static void test_2vi_inv(int[] a, int[] b, int c, int d, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = c;
+      b[i+k] = d;
+    }
+  }
+  static void test_ci_scl(int[] a) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123;
+    }
+  }
+  static void test_vi_scl(int[] a, int b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b;
+    }
+  }
+  static void test_cp_scl(int[] a, int[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b[i*SCALE];
+    }
+  }
+  static void test_2ci_scl(int[] a, int[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123;
+      b[i*SCALE] = -103;
+    }
+  }
+  static void test_2vi_scl(int[] a, int[] b, int c, int d) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = c;
+      b[i*SCALE] = d;
+    }
+  }
+  static void test_cp_alndst(int[] a, int[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_alnsrc(int[] a, int[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+    }
+  }
+  static void test_2ci_aln(int[] a, int[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_aln(int[] a, int[] b, int c, int d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(int[] a, int[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_unalnsrc(int[] a, int[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+    }
+  }
+  static void test_2ci_unaln(int[] a, int[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_unaln(int[] a, int[] b, int c, int d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestLongDoubleVect.java b/hotspot/test/compiler/7119644/TestLongDoubleVect.java
new file mode 100644
index 0000000..344e3a9
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestLongDoubleVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestLongDoubleVect
+ */
+
+public class TestLongDoubleVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Long + Double vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    long[] a1 = new long[ARRLEN];
+    long[] a2 = new long[ARRLEN];
+    double[] b1 = new double[ARRLEN];
+    double[] b2 = new double[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (long)123, 103.);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (long)123, 103.);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (long)123, 103.);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (long)123, 103.);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (long)123, 103.);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.;
+      b2[i] = -1.;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (long)-123);
+        errn += verify("test_ci: b1", i, b1[i], -103.);
+      }
+      test_vi(a2, b2, (long)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (long)123);
+        errn += verify("test_vi: b2", i, b2[i], 103.);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (long)123);
+        errn += verify("test_cp: b1", i, b1[i], 103.);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (long)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.);
+      }
+      test_vi_neg(a2, b2, (long)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (long)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (long)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.);
+      }
+      test_vi_oppos(a2, b2, (long)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (long)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (long)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (long)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (long)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_vi_aln(a1, b1, (long)123, 103.);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (long)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (long)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (long)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (long)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (long)123, 103.);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (long)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (long)i;
+        b1[i] = (double)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (long)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (long)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (long)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (long)i;
+        b1[i] = (double)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (long)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (long)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (long)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (long)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (long)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (long)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(long[] a, double[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi(long[] a, double[] b, long c, double d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(long[] a, long[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(long[] a, double[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_neg(long[] a, double[] b, long c, double d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(long[] a, long[] b, double[] c, double[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(long[] a, double[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_oppos(long[] a, double[] b, long c, double d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(long[] a, long[] b, double[] c, double[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(long[] a, double[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_aln(long[] a, double[] b, long c, double d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(long[] a, long[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(long[] a, long[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(long[] a, double[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_unaln(long[] a, double[] b, long c, double d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(long[] a, long[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(long[] a, long[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, double elem, double val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestLongFloatVect.java b/hotspot/test/compiler/7119644/TestLongFloatVect.java
new file mode 100644
index 0000000..714f6c8
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestLongFloatVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestLongFloatVect
+ */
+
+public class TestLongFloatVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Long + Float vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    long[] a1 = new long[ARRLEN];
+    long[] a2 = new long[ARRLEN];
+    float[] b1 = new float[ARRLEN];
+    float[] b2 = new float[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (long)123, 103.f);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (long)123, 103.f);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (long)123, 103.f);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (long)123, 103.f);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (long)123, 103.f);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.f;
+      b2[i] = -1.f;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (long)-123);
+        errn += verify("test_ci: b1", i, b1[i], -103.f);
+      }
+      test_vi(a2, b2, (long)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (long)123);
+        errn += verify("test_vi: b2", i, b2[i], 103.f);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (long)123);
+        errn += verify("test_cp: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.f;
+        b2[i] = -1.f;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (long)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.f);
+      }
+      test_vi_neg(a2, b2, (long)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (long)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.f);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.f;
+        b2[i] = -1.f;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (long)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.f);
+      }
+      test_vi_oppos(a2, b2, (long)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (long)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.f);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.f;
+        b2[i] = 123.f;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (long)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.f;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (long)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.f);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (long)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.f);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_vi_aln(a1, b1, (long)123, 103.f);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (long)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.f;
+        b2[i] = 123.f;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (long)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.f;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (long)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (long)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (long)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (long)123, 103.f);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (long)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (long)i;
+        b1[i] = (float)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (long)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (float)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.f;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (long)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (long)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (float)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (long)i;
+        b1[i] = (float)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (long)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (float)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.f;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (float)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (long)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (long)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (long)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (long)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (long)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(long[] a, float[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi(long[] a, float[] b, long c, float d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(long[] a, long[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(long[] a, float[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_neg(long[] a, float[] b, long c, float d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(long[] a, long[] b, float[] c, float[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(long[] a, float[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_oppos(long[] a, float[] b, long c, float d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(long[] a, long[] b, float[] c, float[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(long[] a, float[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_aln(long[] a, float[] b, long c, float d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(long[] a, long[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(long[] a, long[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(long[] a, float[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_unaln(long[] a, float[] b, long c, float d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(long[] a, long[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(long[] a, long[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestLongVect.java b/hotspot/test/compiler/7119644/TestLongVect.java
new file mode 100644
index 0000000..6f0365b
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestLongVect.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestLongVect
+ */
+
+public class TestLongVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Long vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    long[] a1 = new long[ARRLEN];
+    long[] a2 = new long[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+      test_vi(a2, (long)123);
+      test_cp(a1, a2);
+      test_2ci(a1, a2);
+      test_2vi(a1, a2, (long)123, (long)103);
+      test_ci_neg(a1);
+      test_vi_neg(a2, (long)123);
+      test_cp_neg(a1, a2);
+      test_2ci_neg(a1, a2);
+      test_2vi_neg(a1, a2, (long)123, (long)103);
+      test_ci_oppos(a1);
+      test_vi_oppos(a2, (long)123);
+      test_cp_oppos(a1, a2);
+      test_2ci_oppos(a1, a2);
+      test_2vi_oppos(a1, a2, (long)123, (long)103);
+      test_ci_off(a1);
+      test_vi_off(a2, (long)123);
+      test_cp_off(a1, a2);
+      test_2ci_off(a1, a2);
+      test_2vi_off(a1, a2, (long)123, (long)103);
+      test_ci_inv(a1, OFFSET);
+      test_vi_inv(a2, (long)123, OFFSET);
+      test_cp_inv(a1, a2, OFFSET);
+      test_2ci_inv(a1, a2, OFFSET);
+      test_2vi_inv(a1, a2, (long)123, (long)103, OFFSET);
+      test_ci_scl(a1);
+      test_vi_scl(a2, (long)123);
+      test_cp_scl(a1, a2);
+      test_2ci_scl(a1, a2);
+      test_2vi_scl(a1, a2, (long)123, (long)103);
+      test_cp_alndst(a1, a2);
+      test_cp_alnsrc(a1, a2);
+      test_2ci_aln(a1, a2);
+      test_2vi_aln(a1, a2, (long)123, (long)103);
+      test_cp_unalndst(a1, a2);
+      test_cp_unalnsrc(a1, a2);
+      test_2ci_unaln(a1, a2);
+      test_2vi_unaln(a1, a2, (long)123, (long)103);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (long)-123);
+      }
+      test_vi(a2, (long)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (long)123);
+      }
+      test_cp(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (long)123);
+      }
+      test_2ci(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci: a1", i, a1[i], (long)-123);
+        errn += verify("test_2ci: a2", i, a2[i], (long)-103);
+      }
+      test_2vi(a1, a2, (long)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi: a1", i, a1[i], (long)123);
+        errn += verify("test_2vi: a2", i, a2[i], (long)103);
+      }
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_neg(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (long)-123);
+      }
+      test_vi_neg(a2, (long)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (long)123);
+      }
+      test_cp_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (long)123);
+      }
+      test_2ci_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_neg: a1", i, a1[i], (long)-123);
+        errn += verify("test_2ci_neg: a2", i, a2[i], (long)-103);
+      }
+      test_2vi_neg(a1, a2, (long)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_neg: a1", i, a1[i], (long)123);
+        errn += verify("test_2vi_neg: a2", i, a2[i], (long)103);
+      }
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_oppos(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (long)-123);
+      }
+      test_vi_oppos(a2, (long)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (long)123);
+      }
+      test_cp_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (long)123);
+      }
+      test_2ci_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_oppos: a1", i, a1[i], (long)-123);
+        errn += verify("test_2ci_oppos: a2", i, a2[i], (long)-103);
+      }
+      test_2vi_oppos(a1, a2, (long)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_oppos: a1", i, a1[i], (long)123);
+        errn += verify("test_2vi_oppos: a2", i, a2[i], (long)103);
+      }
+      // Reset for indexing with offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_off(a1);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_off: a1", i, a1[i], (long)-123);
+      }
+      test_vi_off(a2, (long)123);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_off: a2", i, a2[i], (long)123);
+      }
+      test_cp_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_off: a1", i, a1[i], (long)123);
+      }
+      test_2ci_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_off: a1", i, a1[i], (long)-123);
+        errn += verify("test_2ci_off: a2", i, a2[i], (long)-103);
+      }
+      test_2vi_off(a1, a2, (long)123, (long)103);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (long)123);
+        errn += verify("test_2vi_off: a2", i, a2[i], (long)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (long)-1);
+        errn += verify("test_2vi_off: a2", i, a2[i], (long)-1);
+      }
+      // Reset for indexing with invariant offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_inv(a1, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_inv: a1", i, a1[i], (long)-123);
+      }
+      test_vi_inv(a2, (long)123, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_inv: a2", i, a2[i], (long)123);
+      }
+      test_cp_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_inv: a1", i, a1[i], (long)123);
+      }
+      test_2ci_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_inv: a1", i, a1[i], (long)-123);
+        errn += verify("test_2ci_inv: a2", i, a2[i], (long)-103);
+      }
+      test_2vi_inv(a1, a2, (long)123, (long)103, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (long)123);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (long)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (long)-1);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (long)-1);
+      }
+      // Reset for indexing with scale
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_scl(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : -123;
+        errn += verify("test_ci_scl: a1", i, a1[i], (long)val);
+      }
+      test_vi_scl(a2, (long)123);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_vi_scl: a2", i, a2[i], (long)val);
+      }
+      test_cp_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_cp_scl: a1", i, a1[i], (long)val);
+      }
+      test_2ci_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a1", i, a1[i], (long)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], (long)-123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a2", i, a2[i], (long)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], (long)-103);
+        }
+      }
+      test_2vi_scl(a1, a2, (long)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a1", i, a1[i], (long)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], (long)123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a2", i, a2[i], (long)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], (long)103);
+        }
+      }
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, (long)123);
+      test_cp_alndst(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (long)123);
+      }
+      test_vi(a2, (long)-123);
+      test_cp_alnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (long)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_aln(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (long)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (long)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (long)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_aln(a1, a2, (long)123, (long)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (long)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (long)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, (long)123);
+      test_cp_unalndst(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (long)123);
+      }
+      test_vi(a2, (long)-123);
+      test_cp_unalnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (long)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_unaln(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (long)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (long)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (long)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_unaln(a1, a2, (long)123, (long)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (long)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (long)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (long)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (long)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_alndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (long)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (long)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_aln(a1, a1);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (long)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (long)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_aln(a1, a1, (long)123, (long)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (long)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (long)103);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (long)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (long)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (long)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_unaln(a1, a1);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (long)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (long)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_unaln(a1, a1, (long)123, (long)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (long)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (long)103);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, (long)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi(a1, a2, (long)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a2, (long)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_neg(a1, a2, (long)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_neg: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a2, (long)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_oppos(a1, a2, (long)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_oppos: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_off(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_off(a2, (long)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_off(a1, a2, (long)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_off: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_inv(a1, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_inv(a2, (long)123, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_inv(a1, a2, (long)123, (long)103, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_inv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_scl(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_scl(a2, (long)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_scl(a1, a2, (long)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_scl: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_aln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_aln(a1, a2, (long)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_aln: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_unaln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_unaln(a1, a2, (long)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_unaln: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_ci(long[] a) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+    }
+  }
+  static void test_vi(long[] a, long b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp(long[] a, long[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci(long[] a, long[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi(long[] a, long[] b, long c, long d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_neg(long[] a) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+    }
+  }
+  static void test_vi_neg(long[] a, long b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp_neg(long[] a, long[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci_neg(long[] a, long[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_neg(long[] a, long[] b, long c, long d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_oppos(long[] a) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+    }
+  }
+  static void test_vi_oppos(long[] a, long b) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[limit-i] = b;
+    }
+  }
+  static void test_cp_oppos(long[] a, long[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+    }
+  }
+  static void test_2ci_oppos(long[] a, long[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_oppos(long[] a, long[] b, long c, long d) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_ci_off(long[] a) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123;
+    }
+  }
+  static void test_vi_off(long[] a, long b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b;
+    }
+  }
+  static void test_cp_off(long[] a, long[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b[i+OFFSET];
+    }
+  }
+  static void test_2ci_off(long[] a, long[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123;
+      b[i+OFFSET] = -103;
+    }
+  }
+  static void test_2vi_off(long[] a, long[] b, long c, long d) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = c;
+      b[i+OFFSET] = d;
+    }
+  }
+  static void test_ci_inv(long[] a, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123;
+    }
+  }
+  static void test_vi_inv(long[] a, long b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b;
+    }
+  }
+  static void test_cp_inv(long[] a, long[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b[i+k];
+    }
+  }
+  static void test_2ci_inv(long[] a, long[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123;
+      b[i+k] = -103;
+    }
+  }
+  static void test_2vi_inv(long[] a, long[] b, long c, long d, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = c;
+      b[i+k] = d;
+    }
+  }
+  static void test_ci_scl(long[] a) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123;
+    }
+  }
+  static void test_vi_scl(long[] a, long b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b;
+    }
+  }
+  static void test_cp_scl(long[] a, long[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b[i*SCALE];
+    }
+  }
+  static void test_2ci_scl(long[] a, long[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123;
+      b[i*SCALE] = -103;
+    }
+  }
+  static void test_2vi_scl(long[] a, long[] b, long c, long d) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = c;
+      b[i*SCALE] = d;
+    }
+  }
+  static void test_cp_alndst(long[] a, long[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_alnsrc(long[] a, long[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+    }
+  }
+  static void test_2ci_aln(long[] a, long[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_aln(long[] a, long[] b, long c, long d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(long[] a, long[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_unalnsrc(long[] a, long[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+    }
+  }
+  static void test_2ci_unaln(long[] a, long[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_unaln(long[] a, long[] b, long c, long d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestShortDoubleVect.java b/hotspot/test/compiler/7119644/TestShortDoubleVect.java
new file mode 100644
index 0000000..c21037e
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestShortDoubleVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestShortDoubleVect
+ */
+
+public class TestShortDoubleVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Short + Double vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    short[] a1 = new short[ARRLEN];
+    short[] a2 = new short[ARRLEN];
+    double[] b1 = new double[ARRLEN];
+    double[] b2 = new double[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (short)123, 103.);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (short)123, 103.);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (short)123, 103.);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (short)123, 103.);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (short)123, 103.);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.;
+      b2[i] = -1.;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci: b1", i, b1[i], -103.);
+      }
+      test_vi(a2, b2, (short)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (short)123);
+        errn += verify("test_vi: b2", i, b2[i], 103.);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (short)123);
+        errn += verify("test_cp: b1", i, b1[i], 103.);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.);
+      }
+      test_vi_neg(a2, b2, (short)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (short)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.;
+        b2[i] = -1.;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.);
+      }
+      test_vi_oppos(a2, b2, (short)123, 103.);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (short)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_vi_aln(a1, b1, (short)123, 103.);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.;
+        b2[i] = 123.;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (short)123, 103.);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (short)i;
+        b1[i] = (double)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (short)i;
+        b1[i] = (double)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (double)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (double)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (short)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (short)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (short)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (short)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (short)123, 103.);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(short[] a, double[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi(short[] a, double[] b, short c, double d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(short[] a, short[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(short[] a, double[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_neg(short[] a, double[] b, short c, double d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(short[] a, short[] b, double[] c, double[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(short[] a, double[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_oppos(short[] a, double[] b, short c, double d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(short[] a, short[] b, double[] c, double[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(short[] a, double[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_aln(short[] a, double[] b, short c, double d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(short[] a, short[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(short[] a, short[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(short[] a, double[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103.;
+    }
+  }
+  static void test_vi_unaln(short[] a, double[] b, short c, double d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(short[] a, short[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(short[] a, short[] b, double[] c, double[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, double elem, double val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestShortFloatVect.java b/hotspot/test/compiler/7119644/TestShortFloatVect.java
new file mode 100644
index 0000000..05b4ddd
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestShortFloatVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestShortFloatVect
+ */
+
+public class TestShortFloatVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Short + Float vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    short[] a1 = new short[ARRLEN];
+    short[] a2 = new short[ARRLEN];
+    float[] b1 = new float[ARRLEN];
+    float[] b2 = new float[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (short)123, 103.f);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (short)123, 103.f);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (short)123, 103.f);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (short)123, 103.f);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (short)123, 103.f);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1.f;
+      b2[i] = -1.f;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci: b1", i, b1[i], -103.f);
+      }
+      test_vi(a2, b2, (short)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (short)123);
+        errn += verify("test_vi: b2", i, b2[i], 103.f);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (short)123);
+        errn += verify("test_cp: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.f;
+        b2[i] = -1.f;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], -103.f);
+      }
+      test_vi_neg(a2, b2, (short)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (short)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], 103.f);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1.f;
+        b2[i] = -1.f;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], -103.f);
+      }
+      test_vi_oppos(a2, b2, (short)123, 103.f);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (short)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], 103.f);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.f;
+        b2[i] = 123.f;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.f;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], -123.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], 123.f);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -103.f);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], -1.f);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_vi_aln(a1, b1, (short)123, 103.f);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1.f;
+        b2[i] = 123.f;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123.f;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], -123.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], 123.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -103.f);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], -1.f);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (short)123, 103.f);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], 103.f);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (short)i;
+        b1[i] = (float)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (float)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1.f;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], -1.f);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (float)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (short)i;
+        b1[i] = (float)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1.f;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (float)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1.f;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], -1.f);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (float)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (short)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (short)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (short)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (short)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (short)123, 103.f);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(short[] a, float[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi(short[] a, float[] b, short c, float d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(short[] a, short[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(short[] a, float[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_neg(short[] a, float[] b, short c, float d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(short[] a, short[] b, float[] c, float[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(short[] a, float[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_oppos(short[] a, float[] b, short c, float d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(short[] a, short[] b, float[] c, float[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(short[] a, float[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_aln(short[] a, float[] b, short c, float d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(short[] a, short[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(short[] a, short[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(short[] a, float[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103.f;
+    }
+  }
+  static void test_vi_unaln(short[] a, float[] b, short c, float d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(short[] a, short[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(short[] a, short[] b, float[] c, float[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestShortIntVect.java b/hotspot/test/compiler/7119644/TestShortIntVect.java
new file mode 100644
index 0000000..bf18094
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestShortIntVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestShortIntVect
+ */
+
+public class TestShortIntVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Short + Integer vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    short[] a1 = new short[ARRLEN];
+    short[] a2 = new short[ARRLEN];
+    int[] b1 = new int[ARRLEN];
+    int[] b2 = new int[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (short)123, (int)103);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (short)123, (int)103);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (short)123, (int)103);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (short)123, (int)103);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (short)123, (int)103);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1;
+      b2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci: b1", i, b1[i], (int)-103);
+      }
+      test_vi(a2, b2, (short)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (short)123);
+        errn += verify("test_vi: b2", i, b2[i], (int)103);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (short)123);
+        errn += verify("test_cp: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], (int)-103);
+      }
+      test_vi_neg(a2, b2, (short)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (short)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], (int)103);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], (int)-103);
+      }
+      test_vi_oppos(a2, b2, (short)123, (int)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (short)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], (int)103);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (int)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (int)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (int)123);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (int)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (int)-1);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_aln(a1, b1, (short)123, (int)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (int)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (int)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (int)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (int)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (int)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (short)123, (int)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (int)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (short)i;
+        b1[i] = (int)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (int)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (int)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (int)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (short)i;
+        b1[i] = (int)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (int)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (int)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (int)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (short)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (short)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (short)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (short)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (short)123, (int)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(short[] a, int[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi(short[] a, int[] b, short c, int d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(short[] a, short[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(short[] a, int[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_neg(short[] a, int[] b, short c, int d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(short[] a, short[] b, int[] c, int[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(short[] a, int[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_oppos(short[] a, int[] b, short c, int d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(short[] a, short[] b, int[] c, int[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(short[] a, int[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_aln(short[] a, int[] b, short c, int d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(short[] a, short[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(short[] a, short[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(short[] a, int[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_unaln(short[] a, int[] b, short c, int d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(short[] a, short[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(short[] a, short[] b, int[] c, int[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestShortLongVect.java b/hotspot/test/compiler/7119644/TestShortLongVect.java
new file mode 100644
index 0000000..d4c121f
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestShortLongVect.java
@@ -0,0 +1,571 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestShortLongVect
+ */
+
+public class TestShortLongVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Short + Long vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    short[] a1 = new short[ARRLEN];
+    short[] a2 = new short[ARRLEN];
+    long[] b1 = new long[ARRLEN];
+    long[] b2 = new long[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+      test_vi(a2, b2, (short)123, (long)103);
+      test_cp(a1, a2, b1, b2);
+      test_ci_neg(a1, b1);
+      test_vi_neg(a1, b1, (short)123, (long)103);
+      test_cp_neg(a1, a2, b1, b2);
+      test_ci_oppos(a1, b1);
+      test_vi_oppos(a1, b1, (short)123, (long)103);
+      test_cp_oppos(a1, a2, b1, b2);
+      test_ci_aln(a1, b1);
+      test_vi_aln(a1, b1, (short)123, (long)103);
+      test_cp_alndst(a1, a2, b1, b2);
+      test_cp_alnsrc(a1, a2, b1, b2);
+      test_ci_unaln(a1, b1);
+      test_vi_unaln(a1, b1, (short)123, (long)103);
+      test_cp_unalndst(a1, a2, b1, b2);
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+      b1[i] = -1;
+      b2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci: b1", i, b1[i], (long)-103);
+      }
+      test_vi(a2, b2, (short)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (short)123);
+        errn += verify("test_vi: b2", i, b2[i], (long)103);
+      }
+      test_cp(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (short)123);
+        errn += verify("test_cp: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_neg(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci_neg: b1", i, b1[i], (long)-103);
+      }
+      test_vi_neg(a2, b2, (short)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (short)123);
+        errn += verify("test_vi_neg: b2", i, b2[i], (long)103);
+      }
+      test_cp_neg(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_neg: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+        b1[i] = -1;
+        b2[i] = -1;
+      }
+      test_ci_oppos(a1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (short)-123);
+        errn += verify("test_ci_oppos: b1", i, b1[i], (long)-103);
+      }
+      test_vi_oppos(a2, b2, (short)123, (long)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (short)123);
+        errn += verify("test_vi_oppos: b2", i, b2[i], (long)103);
+      }
+      test_cp_oppos(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_oppos: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_alndst(a1, a2, b1, b2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_alndst: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_alnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)-123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (long)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_alnsrc: b1", i, b1[i], (long)123);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_aln(a1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (long)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_aln: b1", i, b1[i], (long)-1);
+      }
+
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_aln(a1, b1, (short)123, (long)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_aln: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = 123;
+        b1[i] = -1;
+        b2[i] = 123;
+      }
+      test_cp_unalndst(a1, a2, b1, b2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_unalndst: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a2[i] = -123;
+        b2[i] = -123;
+      }
+      test_cp_unalnsrc(a1, a2, b1, b2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)-123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (long)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)123);
+        errn += verify("test_cp_unalnsrc: b1", i, b1[i], (long)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_ci_unaln(a1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (long)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_ci_unaln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_vi_unaln(a1, b1, (short)123, (long)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_vi_unaln: b1", i, b1[i], (long)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (short)i;
+        b1[i] = (long)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_alndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_alndst_overlap: b1", i, b1[i], (long)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+        b1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1, b1, b1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (long)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_alnsrc_overlap: b1", i, b1[i], (long)v);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (short)i;
+        b1[i] = (long)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+        b1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1, b1, b1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_unalndst_overlap: b1", i, b1[i], (long)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+        b1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1, b1, b1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)-1);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (long)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)v);
+        errn += verify("test_cp_unalnsrc_overlap: b1", i, b1[i], (long)v);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, b2, (short)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a1, b1, (short)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a1, b1, (short)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_aln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_aln(a1, b1, (short)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_unaln(a1, b1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_unaln(a1, b1, (short)123, (long)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2, b1, b2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    return errn;
+  }
+
+  static void test_ci(short[] a, long[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi(short[] a, long[] b, short c, long d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp(short[] a, short[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_neg(short[] a, long[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_neg(short[] a, long[] b, short c, long d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_cp_neg(short[] a, short[] b, long[] c, long[] d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+      c[i] = d[i];
+    }
+  }
+  static void test_ci_oppos(short[] a, long[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_oppos(short[] a, long[] b, short c, long d) {
+    int limit = a.length-1;
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_cp_oppos(short[] a, short[] b, long[] c, long[] d) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+      c[limit-i] = d[i];
+    }
+  }
+  static void test_ci_aln(short[] a, long[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_aln(short[] a, long[] b, short c, long d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_alndst(short[] a, short[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+      c[i+ALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_alnsrc(short[] a, short[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+      c[i] = d[i+ALIGN_OFF];
+    }
+  }
+  static void test_ci_unaln(short[] a, long[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_vi_unaln(short[] a, long[] b, short c, long d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(short[] a, short[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+      c[i+UNALIGN_OFF] = d[i];
+    }
+  }
+  static void test_cp_unalnsrc(short[] a, short[] b, long[] c, long[] d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+      c[i] = d[i+UNALIGN_OFF];
+    }
+  }
+
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7119644/TestShortVect.java b/hotspot/test/compiler/7119644/TestShortVect.java
new file mode 100644
index 0000000..d458383
--- /dev/null
+++ b/hotspot/test/compiler/7119644/TestShortVect.java
@@ -0,0 +1,953 @@
+/*
+ * Copyright (c) 2012, 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 7119644
+ * @summary Increase superword's vector size up to 256 bits
+ *
+ * @run main/othervm/timeout=300 -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:-OptimizeFill TestShortVect
+ */
+
+public class TestShortVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int OFFSET = 3;
+  private static final int SCALE = 2;
+  private static final int ALIGN_OFF = 8;
+  private static final int UNALIGN_OFF = 5;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Short vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    short[] a1 = new short[ARRLEN];
+    short[] a2 = new short[ARRLEN];
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+      test_vi(a2, (short)123);
+      test_cp(a1, a2);
+      test_2ci(a1, a2);
+      test_2vi(a1, a2, (short)123, (short)103);
+      test_ci_neg(a1);
+      test_vi_neg(a2, (short)123);
+      test_cp_neg(a1, a2);
+      test_2ci_neg(a1, a2);
+      test_2vi_neg(a1, a2, (short)123, (short)103);
+      test_ci_oppos(a1);
+      test_vi_oppos(a2, (short)123);
+      test_cp_oppos(a1, a2);
+      test_2ci_oppos(a1, a2);
+      test_2vi_oppos(a1, a2, (short)123, (short)103);
+      test_ci_off(a1);
+      test_vi_off(a2, (short)123);
+      test_cp_off(a1, a2);
+      test_2ci_off(a1, a2);
+      test_2vi_off(a1, a2, (short)123, (short)103);
+      test_ci_inv(a1, OFFSET);
+      test_vi_inv(a2, (short)123, OFFSET);
+      test_cp_inv(a1, a2, OFFSET);
+      test_2ci_inv(a1, a2, OFFSET);
+      test_2vi_inv(a1, a2, (short)123, (short)103, OFFSET);
+      test_ci_scl(a1);
+      test_vi_scl(a2, (short)123);
+      test_cp_scl(a1, a2);
+      test_2ci_scl(a1, a2);
+      test_2vi_scl(a1, a2, (short)123, (short)103);
+      test_cp_alndst(a1, a2);
+      test_cp_alnsrc(a1, a2);
+      test_2ci_aln(a1, a2);
+      test_2vi_aln(a1, a2, (short)123, (short)103);
+      test_cp_unalndst(a1, a2);
+      test_cp_unalnsrc(a1, a2);
+      test_2ci_unaln(a1, a2);
+      test_2vi_unaln(a1, a2, (short)123, (short)103);
+    }
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = -1;
+      a2[i] = -1;
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_ci(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci: a1", i, a1[i], (short)-123);
+      }
+      test_vi(a2, (short)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi: a2", i, a2[i], (short)123);
+      }
+      test_cp(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp: a1", i, a1[i], (short)123);
+      }
+      test_2ci(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci: a1", i, a1[i], (short)-123);
+        errn += verify("test_2ci: a2", i, a2[i], (short)-103);
+      }
+      test_2vi(a1, a2, (short)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi: a1", i, a1[i], (short)123);
+        errn += verify("test_2vi: a2", i, a2[i], (short)103);
+      }
+      // Reset for negative stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_neg(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_neg: a1", i, a1[i], (short)-123);
+      }
+      test_vi_neg(a2, (short)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_neg: a2", i, a2[i], (short)123);
+      }
+      test_cp_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_neg: a1", i, a1[i], (short)123);
+      }
+      test_2ci_neg(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_neg: a1", i, a1[i], (short)-123);
+        errn += verify("test_2ci_neg: a2", i, a2[i], (short)-103);
+      }
+      test_2vi_neg(a1, a2, (short)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_neg: a1", i, a1[i], (short)123);
+        errn += verify("test_2vi_neg: a2", i, a2[i], (short)103);
+      }
+      // Reset for opposite stride
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_oppos(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ci_oppos: a1", i, a1[i], (short)-123);
+      }
+      test_vi_oppos(a2, (short)123);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_vi_oppos: a2", i, a2[i], (short)123);
+      }
+      test_cp_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_cp_oppos: a1", i, a1[i], (short)123);
+      }
+      test_2ci_oppos(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2ci_oppos: a1", i, a1[i], (short)-123);
+        errn += verify("test_2ci_oppos: a2", i, a2[i], (short)-103);
+      }
+      test_2vi_oppos(a1, a2, (short)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_2vi_oppos: a1", i, a1[i], (short)123);
+        errn += verify("test_2vi_oppos: a2", i, a2[i], (short)103);
+      }
+      // Reset for indexing with offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_off(a1);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_off: a1", i, a1[i], (short)-123);
+      }
+      test_vi_off(a2, (short)123);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_off: a2", i, a2[i], (short)123);
+      }
+      test_cp_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_off: a1", i, a1[i], (short)123);
+      }
+      test_2ci_off(a1, a2);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_off: a1", i, a1[i], (short)-123);
+        errn += verify("test_2ci_off: a2", i, a2[i], (short)-103);
+      }
+      test_2vi_off(a1, a2, (short)123, (short)103);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (short)123);
+        errn += verify("test_2vi_off: a2", i, a2[i], (short)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_off: a1", i, a1[i], (short)-1);
+        errn += verify("test_2vi_off: a2", i, a2[i], (short)-1);
+      }
+      // Reset for indexing with invariant offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_inv(a1, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_ci_inv: a1", i, a1[i], (short)-123);
+      }
+      test_vi_inv(a2, (short)123, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_vi_inv: a2", i, a2[i], (short)123);
+      }
+      test_cp_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_cp_inv: a1", i, a1[i], (short)123);
+      }
+      test_2ci_inv(a1, a2, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2ci_inv: a1", i, a1[i], (short)-123);
+        errn += verify("test_2ci_inv: a2", i, a2[i], (short)-103);
+      }
+      test_2vi_inv(a1, a2, (short)123, (short)103, OFFSET);
+      for (int i=OFFSET; i<ARRLEN; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (short)123);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (short)103);
+      }
+      for (int i=0; i<OFFSET; i++) {
+        errn += verify("test_2vi_inv: a1", i, a1[i], (short)-1);
+        errn += verify("test_2vi_inv: a2", i, a2[i], (short)-1);
+      }
+      // Reset for indexing with scale
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_ci_scl(a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : -123;
+        errn += verify("test_ci_scl: a1", i, a1[i], (short)val);
+      }
+      test_vi_scl(a2, (short)123);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_vi_scl: a2", i, a2[i], (short)val);
+      }
+      test_cp_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        int val = (i%SCALE != 0) ? -1 : 123;
+        errn += verify("test_cp_scl: a1", i, a1[i], (short)val);
+      }
+      test_2ci_scl(a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a1", i, a1[i], (short)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a1", i*SCALE, a1[i*SCALE], (short)-123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2ci_scl: a2", i, a2[i], (short)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2ci_scl: a2", i*SCALE, a2[i*SCALE], (short)-103);
+        }
+      }
+      test_2vi_scl(a1, a2, (short)123, (short)103);
+      for (int i=0; i<ARRLEN; i++) {
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a1", i, a1[i], (short)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a1", i*SCALE, a1[i*SCALE], (short)123);
+        }
+        if (i%SCALE != 0) {
+          errn += verify("test_2vi_scl: a2", i, a2[i], (short)-1);
+        } else if (i*SCALE < ARRLEN) {
+          errn += verify("test_2vi_scl: a2", i*SCALE, a2[i*SCALE], (short)103);
+        }
+      }
+      // Reset for 2 arrays with relative aligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, (short)123);
+      test_cp_alndst(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alndst: a1", i, a1[i], (short)123);
+      }
+      test_vi(a2, (short)-123);
+      test_cp_alnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)-123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_alnsrc: a1", i, a1[i], (short)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_aln(a1, a2);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (short)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln: a2", i, a2[i], (short)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_aln(a1, a2, (short)123, (short)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln: a2", i, a2[i], (short)103);
+      }
+
+      // Reset for 2 arrays with relative unaligned offset
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_vi(a2, (short)123);
+      test_cp_unalndst(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalndst: a1", i, a1[i], (short)123);
+      }
+      test_vi(a2, (short)-123);
+      test_cp_unalnsrc(a1, a2);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)-123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_cp_unalnsrc: a1", i, a1[i], (short)123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2ci_unaln(a1, a2);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (short)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln: a2", i, a2[i], (short)-1);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+        a2[i] = -1;
+      }
+      test_2vi_unaln(a1, a2, (short)123, (short)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a1", i, a1[i], (short)-1);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln: a2", i, a2[i], (short)103);
+      }
+
+      // Reset for aligned overlap initialization
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i] = (short)i;
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_alndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alndst_overlap: a1", i, a1[i], (short)v);
+      }
+      for (int i=0; i<ALIGN_OFF; i++) {
+        a1[i+ALIGN_OFF] = -1;
+      }
+      test_cp_alnsrc(a1, a1);
+      for (int i=0; i<ALIGN_OFF; i++) {
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)-1);
+      }
+      for (int i=ALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%ALIGN_OFF;
+        errn += verify("test_cp_alnsrc_overlap: a1", i, a1[i], (short)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_aln(a1, a1);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (short)-103);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_aln_overlap: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_aln(a1, a1, (short)123, (short)103);
+      for (int i=0; i<ARRLEN-ALIGN_OFF; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-ALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_aln_overlap: a1", i, a1[i], (short)103);
+      }
+
+      // Reset for unaligned overlap initialization
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i] = (short)i;
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_cp_unalndst(a1, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalndst_overlap: a1", i, a1[i], (short)v);
+      }
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        a1[i+UNALIGN_OFF] = -1;
+      }
+      test_cp_unalnsrc(a1, a1);
+      for (int i=0; i<UNALIGN_OFF; i++) {
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)-1);
+      }
+      for (int i=UNALIGN_OFF; i<ARRLEN; i++) {
+        int v = i%UNALIGN_OFF;
+        errn += verify("test_cp_unalnsrc_overlap: a1", i, a1[i], (short)v);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2ci_unaln(a1, a1);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (short)-103);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2ci_unaln_overlap: a1", i, a1[i], (short)-123);
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a1[i] = -1;
+      }
+      test_2vi_unaln(a1, a1, (short)123, (short)103);
+      for (int i=0; i<ARRLEN-UNALIGN_OFF; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (short)123);
+      }
+      for (int i=ARRLEN-UNALIGN_OFF; i<ARRLEN; i++) {
+        errn += verify("test_2vi_unaln_overlap: a1", i, a1[i], (short)103);
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi(a2, (short)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi(a1, a2, (short)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_neg(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_neg(a2, (short)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_neg(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_neg: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_neg(a1, a2, (short)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_neg: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_oppos(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_oppos(a2, (short)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_oppos(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_oppos: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_oppos(a1, a2, (short)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_oppos: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_off(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_off(a2, (short)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_off(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_off: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_off(a1, a2, (short)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_off: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_inv(a1, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_inv(a2, (short)123, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_inv(a1, a2, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_inv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_inv(a1, a2, (short)123, (short)103, OFFSET);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_inv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ci_scl(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_vi_scl(a2, (short)123);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_vi_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_scl(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_scl: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_scl(a1, a2, (short)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_scl: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_alnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_alnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_aln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_aln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_aln(a1, a2, (short)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_aln: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalndst(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalndst: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_cp_unalnsrc(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_cp_unalnsrc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2ci_unaln(a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2ci_unaln: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_2vi_unaln(a1, a2, (short)123, (short)103);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_2vi_unaln: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_ci(short[] a) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+    }
+  }
+  static void test_vi(short[] a, short b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp(short[] a, short[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci(short[] a, short[] b) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi(short[] a, short[] b, short c, short d) {
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_neg(short[] a) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+    }
+  }
+  static void test_vi_neg(short[] a, short b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b;
+    }
+  }
+  static void test_cp_neg(short[] a, short[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = b[i];
+    }
+  }
+  static void test_2ci_neg(short[] a, short[] b) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_neg(short[] a, short[] b, short c, short d) {
+    for (int i = a.length-1; i >= 0; i-=1) {
+      a[i] = c;
+      b[i] = d;
+    }
+  }
+  static void test_ci_oppos(short[] a) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+    }
+  }
+  static void test_vi_oppos(short[] a, short b) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[limit-i] = b;
+    }
+  }
+  static void test_cp_oppos(short[] a, short[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[i] = b[limit-i];
+    }
+  }
+  static void test_2ci_oppos(short[] a, short[] b) {
+    int limit = a.length-1;
+    for (int i = 0; i < a.length; i+=1) {
+      a[limit-i] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_oppos(short[] a, short[] b, short c, short d) {
+    int limit = a.length-1;
+    for (int i = limit; i >= 0; i-=1) {
+      a[i] = c;
+      b[limit-i] = d;
+    }
+  }
+  static void test_ci_off(short[] a) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123;
+    }
+  }
+  static void test_vi_off(short[] a, short b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b;
+    }
+  }
+  static void test_cp_off(short[] a, short[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = b[i+OFFSET];
+    }
+  }
+  static void test_2ci_off(short[] a, short[] b) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = -123;
+      b[i+OFFSET] = -103;
+    }
+  }
+  static void test_2vi_off(short[] a, short[] b, short c, short d) {
+    for (int i = 0; i < a.length-OFFSET; i+=1) {
+      a[i+OFFSET] = c;
+      b[i+OFFSET] = d;
+    }
+  }
+  static void test_ci_inv(short[] a, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123;
+    }
+  }
+  static void test_vi_inv(short[] a, short b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b;
+    }
+  }
+  static void test_cp_inv(short[] a, short[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = b[i+k];
+    }
+  }
+  static void test_2ci_inv(short[] a, short[] b, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = -123;
+      b[i+k] = -103;
+    }
+  }
+  static void test_2vi_inv(short[] a, short[] b, short c, short d, int k) {
+    for (int i = 0; i < a.length-k; i+=1) {
+      a[i+k] = c;
+      b[i+k] = d;
+    }
+  }
+  static void test_ci_scl(short[] a) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123;
+    }
+  }
+  static void test_vi_scl(short[] a, short b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b;
+    }
+  }
+  static void test_cp_scl(short[] a, short[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = b[i*SCALE];
+    }
+  }
+  static void test_2ci_scl(short[] a, short[] b) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = -123;
+      b[i*SCALE] = -103;
+    }
+  }
+  static void test_2vi_scl(short[] a, short[] b, short c, short d) {
+    for (int i = 0; i*SCALE < a.length; i+=1) {
+      a[i*SCALE] = c;
+      b[i*SCALE] = d;
+    }
+  }
+  static void test_cp_alndst(short[] a, short[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_alnsrc(short[] a, short[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = b[i+ALIGN_OFF];
+    }
+  }
+  static void test_2ci_aln(short[] a, short[] b) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i+ALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_aln(short[] a, short[] b, short c, short d) {
+    for (int i = 0; i < a.length-ALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+ALIGN_OFF] = d;
+    }
+  }
+  static void test_cp_unalndst(short[] a, short[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = b[i];
+    }
+  }
+  static void test_cp_unalnsrc(short[] a, short[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = b[i+UNALIGN_OFF];
+    }
+  }
+  static void test_2ci_unaln(short[] a, short[] b) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i+UNALIGN_OFF] = -123;
+      b[i] = -103;
+    }
+  }
+  static void test_2vi_unaln(short[] a, short[] b, short c, short d) {
+    for (int i = 0; i < a.length-UNALIGN_OFF; i+=1) {
+      a[i] = c;
+      b[i+UNALIGN_OFF] = d;
+    }
+  }
+
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/7160610/Test7160610.java b/hotspot/test/compiler/7160610/Test7160610.java
new file mode 100644
index 0000000..62b2e6e
--- /dev/null
+++ b/hotspot/test/compiler/7160610/Test7160610.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 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 7160610
+ * @summary Unknown Native Code compilation issue.
+ *
+ * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-OptimizeFill Test7160610
+ */
+
+public class Test7160610 {
+  private static final byte[] BYTE_ARRAY = new byte[7];
+  private static int[] anIntArray1190 = new int[32768];
+  private static int[] anIntArray1191 = new int[32768];
+
+  public static void main(String arg[]) {
+    int i = 256;
+    for(int j = BYTE_ARRAY[2]; j < anIntArray1190.length; j++) {
+      anIntArray1190[j] = BYTE_ARRAY[2];
+    }
+
+    for(int k = BYTE_ARRAY[2]; (k ^ BYTE_ARRAY[1]) > -5001; k++) {
+      int i1 = (int)(Math.random() * 128D * (double)i);
+      anIntArray1190[i1] = (int)(Math.random() * 256D);
+    }
+
+    for(int l = BYTE_ARRAY[2]; (l ^ BYTE_ARRAY[1]) > -21; l++) {
+      for(int j1 = BYTE_ARRAY[0]; j1 < i + -BYTE_ARRAY[0]; j1++) {
+        for(int k1 = BYTE_ARRAY[0]; (k1 ^ BYTE_ARRAY[1]) > -128; k1++) {
+          int l1 = k1 - -(j1 << 0x26cb6487);
+          anIntArray1191[l1] = (anIntArray1190[l1 + -BYTE_ARRAY[0]] - -anIntArray1190[l1 - -BYTE_ARRAY[0]] - -anIntArray1190[-128 + l1] - -anIntArray1190[128 + l1]) / BYTE_ARRAY[6];
+        }
+      }
+      int ai[] = anIntArray1190;
+      anIntArray1190 = anIntArray1191;
+      anIntArray1191 = ai;
+    }
+  }
+
+  static {
+    BYTE_ARRAY[6] = 4;
+    BYTE_ARRAY[5] = 5;
+    BYTE_ARRAY[4] = 3;
+    BYTE_ARRAY[3] = 2;
+    BYTE_ARRAY[2] = 0;
+    BYTE_ARRAY[1] = -1;
+    BYTE_ARRAY[0] = 1;
+  }
+}
diff --git a/hotspot/test/compiler/7177917/Test7177917.java b/hotspot/test/compiler/7177917/Test7177917.java
new file mode 100644
index 0000000..7d2c764
--- /dev/null
+++ b/hotspot/test/compiler/7177917/Test7177917.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+/*
+ * Micro-benchmark for Math.pow() and Math.exp()
+ */
+
+import java.util.*;
+
+public class Test7177917 {
+
+  static double d;
+
+  static Random r = new Random(0);
+
+  static long  m_pow(double[][] values) {
+    double res = 0;
+    long start = System.nanoTime();
+    for (int i = 0; i < values.length; i++) {
+      res += Math.pow(values[i][0], values[i][1]);
+    }
+    long stop = System.nanoTime();
+    d = res;
+    return (stop - start) / 1000;
+  }
+
+  static long  m_exp(double[] values) {
+    double res = 0;
+    long start = System.nanoTime();
+    for (int i = 0; i < values.length; i++) {
+      res += Math.exp(values[i]);
+    }
+    long stop = System.nanoTime();
+    d = res;
+    return (stop - start) / 1000;
+  }
+
+  static double[][] pow_values(int nb) {
+    double[][] res = new double[nb][2];
+    for (int i = 0; i < nb; i++) {
+      double ylogx = (1 + (r.nextDouble() * 2045)) - 1023; // 2045 rather than 2046 as a safety margin
+      double x = Math.abs(Double.longBitsToDouble(r.nextLong()));
+      while (x != x) {
+        x = Math.abs(Double.longBitsToDouble(r.nextLong()));
+      }
+      double logx = Math.log(x) / Math.log(2);
+      double y = ylogx / logx;
+
+      res[i][0] = x;
+      res[i][1] = y;
+    }
+    return res;
+  }
+
+  static double[] exp_values(int nb) {
+    double[] res = new double[nb];
+    for (int i = 0; i < nb; i++) {
+      double ylogx = (1 + (r.nextDouble() * 2045)) - 1023; // 2045 rather than 2046 as a safety margin
+      double x = Math.E;
+      double logx = Math.log(x) / Math.log(2);
+      double y = ylogx / logx;
+      res[i] = y;
+    }
+    return res;
+  }
+
+  static public void main(String[] args) {
+    {
+      // warmup
+      double[][] warmup_values = pow_values(10);
+      m_pow(warmup_values);
+
+      for (int i = 0; i < 20000; i++) {
+        m_pow(warmup_values);
+      }
+      // test pow perf
+      double[][] values = pow_values(1000000);
+      System.out.println("==> POW " + m_pow(values));
+
+      // force uncommon trap
+      double[][] nan_values = new double[1][2];
+      nan_values[0][0] = Double.NaN;
+      nan_values[0][1] = Double.NaN;
+      m_pow(nan_values);
+
+      // force recompilation
+      for (int i = 0; i < 20000; i++) {
+        m_pow(warmup_values);
+      }
+
+      // test pow perf again
+      System.out.println("==> POW " + m_pow(values));
+    }
+    {
+      // warmup
+      double[] warmup_values = exp_values(10);
+      m_exp(warmup_values);
+
+      for (int i = 0; i < 20000; i++) {
+        m_exp(warmup_values);
+      }
+
+      // test pow perf
+      double[] values = exp_values(1000000);
+      System.out.println("==> EXP " + m_exp(values));
+
+      // force uncommon trap
+      double[] nan_values = new double[1];
+      nan_values[0] = Double.NaN;
+      m_exp(nan_values);
+
+      // force recompilation
+      for (int i = 0; i < 20000; i++) {
+        m_exp(warmup_values);
+      }
+
+      // test pow perf again
+      System.out.println("==> EXP " + m_exp(values));
+    }
+  }
+}
diff --git a/hotspot/test/compiler/7184394/TestAESBase.java b/hotspot/test/compiler/7184394/TestAESBase.java
new file mode 100644
index 0000000..ad6c835
--- /dev/null
+++ b/hotspot/test/compiler/7184394/TestAESBase.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+/**
+ * @author Tom Deneau
+ */
+
+import javax.crypto.Cipher;
+import javax.crypto.KeyGenerator;
+import javax.crypto.SecretKey;
+import javax.crypto.spec.IvParameterSpec;
+import javax.crypto.spec.SecretKeySpec;
+import java.security.AlgorithmParameters;
+
+import java.util.Random;
+import java.util.Arrays;
+
+abstract public class TestAESBase {
+  int msgSize = Integer.getInteger("msgSize", 646);
+  boolean checkOutput = Boolean.getBoolean("checkOutput");
+  boolean noReinit = Boolean.getBoolean("noReinit");
+  int keySize = Integer.getInteger("keySize", 128);
+  String algorithm = System.getProperty("algorithm", "AES");
+  String mode = System.getProperty("mode", "CBC");
+  byte[] input;
+  byte[] encode;
+  byte[] expectedEncode;
+  byte[] decode;
+  byte[] expectedDecode;
+  Random random = new Random(0);
+  Cipher cipher;
+  Cipher dCipher;
+  String paddingStr = "PKCS5Padding";
+  AlgorithmParameters algParams;
+  SecretKey key;
+  int ivLen;
+
+  static int numThreads = 0;
+  int  threadId;
+  static synchronized int getThreadId() {
+    int id = numThreads;
+    numThreads++;
+    return id;
+  }
+
+  abstract public void run();
+
+  public void prepare() {
+    try {
+    System.out.println("\nmsgSize=" + msgSize + ", key size=" + keySize + ", reInit=" + !noReinit + ", checkOutput=" + checkOutput);
+
+      int keyLenBytes = (keySize == 0 ? 16 : keySize/8);
+      byte keyBytes[] = new byte[keyLenBytes];
+      if (keySize == 128)
+        keyBytes = new byte[] {-8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7};
+      else
+        random.nextBytes(keyBytes);
+
+      key = new SecretKeySpec(keyBytes, algorithm);
+      if (threadId == 0) {
+        System.out.println("Algorithm: " + key.getAlgorithm() + "("
+                           + key.getEncoded().length * 8 + "bit)");
+      }
+      input = new byte[msgSize];
+      for (int i=0; i<input.length; i++) {
+        input[i] = (byte) (i & 0xff);
+      }
+
+      cipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
+      dCipher = Cipher.getInstance(algorithm + "/" + mode + "/" + paddingStr, "SunJCE");
+
+      ivLen = (algorithm.equals("AES") ? 16 : algorithm.equals("DES") ? 8 : 0);
+      IvParameterSpec initVector = new IvParameterSpec(new byte[ivLen]);
+
+      cipher.init(Cipher.ENCRYPT_MODE, key, initVector);
+      algParams = cipher.getParameters();
+      dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
+      if (threadId == 0) {
+        childShowCipher();
+      }
+
+      // do one encode and decode in preparation
+      // this will also create the encode buffer and decode buffer
+      encode = cipher.doFinal(input);
+      decode = dCipher.doFinal(encode);
+      if (checkOutput) {
+        expectedEncode = (byte[]) encode.clone();
+        expectedDecode = (byte[]) decode.clone();
+        showArray(key.getEncoded()  ,  "key:    ");
+        showArray(input,  "input:  ");
+        showArray(encode, "encode: ");
+        showArray(decode, "decode: ");
+      }
+    }
+    catch (Exception e) {
+      e.printStackTrace();
+      System.exit(1);
+    }
+  }
+
+  void showArray(byte b[], String name) {
+    System.out.format("%s [%d]: ", name, b.length);
+    for (int i=0; i<Math.min(b.length, 32); i++) {
+      System.out.format("%02x ", b[i] & 0xff);
+    }
+    System.out.println();
+  }
+
+  void compareArrays(byte b[], byte exp[]) {
+    if (b.length != exp.length) {
+      System.out.format("different lengths for actual and expected output arrays\n");
+      showArray(b, "test: ");
+      showArray(exp, "exp : ");
+      System.exit(1);
+    }
+    for (int i=0; i< exp.length; i++) {
+      if (b[i] != exp[i]) {
+        System.out.format("output error at index %d: got %02x, expected %02x\n", i, b[i] & 0xff, exp[i] & 0xff);
+        showArray(b, "test: ");
+        showArray(exp, "exp : ");
+        System.exit(1);
+      }
+    }
+  }
+
+
+  void showCipher(Cipher c, String kind) {
+    System.out.println(kind + " cipher provider: " + cipher.getProvider());
+    System.out.println(kind + " cipher algorithm: " + cipher.getAlgorithm());
+  }
+
+  abstract void childShowCipher();
+}
diff --git a/hotspot/test/compiler/7184394/TestAESDecode.java b/hotspot/test/compiler/7184394/TestAESDecode.java
new file mode 100644
index 0000000..f9ec02d
--- /dev/null
+++ b/hotspot/test/compiler/7184394/TestAESDecode.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+/**
+ * @author Tom Deneau
+ */
+
+import javax.crypto.Cipher;
+
+public class TestAESDecode extends TestAESBase {
+  @Override
+  public void run() {
+    try {
+      if (!noReinit) dCipher.init(Cipher.DECRYPT_MODE, key, algParams);
+      if (checkOutput) {
+        // checked version creates new output buffer each time
+        decode = dCipher.doFinal(encode, 0, encode.length);
+        compareArrays(decode, expectedDecode);
+      } else {
+        // non-checked version outputs to existing encode buffer for maximum speed
+        decode = new byte[dCipher.getOutputSize(encode.length)];
+        dCipher.doFinal(encode, 0, encode.length, decode);
+      }
+    }
+    catch (Exception e) {
+      e.printStackTrace();
+      System.exit(1);
+    }
+  }
+
+  @Override
+  void childShowCipher() {
+    showCipher(dCipher, "Decryption");
+  }
+
+}
diff --git a/hotspot/test/compiler/7184394/TestAESEncode.java b/hotspot/test/compiler/7184394/TestAESEncode.java
new file mode 100644
index 0000000..1d6bf7f
--- /dev/null
+++ b/hotspot/test/compiler/7184394/TestAESEncode.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+/**
+ * @author Tom Deneau
+ */
+
+import javax.crypto.Cipher;
+
+public class TestAESEncode extends TestAESBase {
+  @Override
+  public void run() {
+    try {
+      if (!noReinit) cipher.init(Cipher.ENCRYPT_MODE, key, algParams);
+      if (checkOutput) {
+        // checked version creates new output buffer each time
+        encode = cipher.doFinal(input, 0, msgSize);
+        compareArrays(encode, expectedEncode);
+      } else {
+        // non-checked version outputs to existing encode buffer for maximum speed
+        encode = new byte[cipher.getOutputSize(msgSize)];
+        cipher.doFinal(input, 0, msgSize, encode);
+      }
+    }
+    catch (Exception e) {
+      e.printStackTrace();
+      System.exit(1);
+    }
+  }
+
+  @Override
+  void childShowCipher() {
+    showCipher(cipher, "Encryption");
+  }
+
+}
diff --git a/hotspot/test/compiler/7184394/TestAESMain.java b/hotspot/test/compiler/7184394/TestAESMain.java
new file mode 100644
index 0000000..ca2cb43
--- /dev/null
+++ b/hotspot/test/compiler/7184394/TestAESMain.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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 7184394
+ * @summary add intrinsics to use AES instructions
+ *
+ * @run main/othervm/timeout=600 -Xbatch -DcheckOutput=true TestAESMain
+ *
+ * @author Tom Deneau
+ */
+
+public class TestAESMain {
+  public static void main(String[] args) {
+    int iters = (args.length > 0 ? Integer.valueOf(args[0]) : 1000000);
+    System.out.println(iters + " iterations");
+    TestAESEncode etest = new TestAESEncode();
+    etest.prepare();
+    long start = System.nanoTime();
+    for (int i=0; i<iters; i++) {
+      etest.run();
+    }
+    long end = System.nanoTime();
+    System.out.println("TestAESEncode runtime was " + (double)((end - start)/1000000000.0) + " ms");
+
+    TestAESDecode dtest = new TestAESDecode();
+    dtest.prepare();
+    start = System.nanoTime();
+    for (int i=0; i<iters; i++) {
+      dtest.run();
+    }
+    end = System.nanoTime();
+    System.out.println("TestAESDecode runtime was " + (double)((end - start)/1000000000.0) + " ms");
+  }
+}
diff --git a/hotspot/test/compiler/7190310/Test7190310.java b/hotspot/test/compiler/7190310/Test7190310.java
new file mode 100644
index 0000000..57a89b9
--- /dev/null
+++ b/hotspot/test/compiler/7190310/Test7190310.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+/*
+ * Manual test
+ */
+
+import java.lang.ref.*;
+
+public class Test7190310 {
+  private static Object str = new Object() {
+    public String toString() {
+      return "The Object";
+    }
+
+    protected void finalize() throws Throwable {
+      System.out.println("The Object is being finalized");
+      super.finalize();
+    }
+  };
+  private final static ReferenceQueue<Object> rq =
+      new ReferenceQueue<Object>();
+  private final static WeakReference<Object> wr =
+      new WeakReference<Object>(str, rq);
+
+  public static void main(String[] args)
+      throws InterruptedException {
+    Thread reader = new Thread() {
+      public void run() {
+        while (wr.get() != null) {
+        }
+        System.out.println("wr.get() returned null");
+      }
+    };
+
+    Thread queueReader = new Thread() {
+      public void run() {
+        try {
+          Reference<? extends Object> ref = rq.remove();
+          System.out.println(ref);
+          System.out.println("queueReader returned, ref==wr is "
+              + (ref == wr));
+        } catch (InterruptedException e) {
+          System.err.println("Sleep interrupted - exiting");
+        }
+      }
+    };
+
+    reader.start();
+    queueReader.start();
+
+    Thread.sleep(1000);
+    str = null;
+    System.gc();
+  }
+}
+
diff --git a/hotspot/test/compiler/7190310/Test7190310_unsafe.java b/hotspot/test/compiler/7190310/Test7190310_unsafe.java
new file mode 100644
index 0000000..3f97f28
--- /dev/null
+++ b/hotspot/test/compiler/7190310/Test7190310_unsafe.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (c) 2012, 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 7190310
+ * @summary Inlining WeakReference.get(), and hoisting $referent may lead to non-terminating loops
+ * @run main/othervm -Xbatch Test7190310_unsafe
+ */
+
+import java.lang.ref.*;
+import java.lang.reflect.*;
+import sun.misc.Unsafe;
+
+public class Test7190310_unsafe {
+
+  static class TestObject {
+    public String toString() {
+      return "TestObject";
+    }
+  };
+
+  private static TestObject str = new TestObject();
+  private static final WeakReference ref = new WeakReference(str);
+
+  private TestObject obj;
+
+  public static void main(String[] args) throws Exception {
+    Class c = Test7190310_unsafe.class.getClassLoader().loadClass("sun.misc.Unsafe");
+    Field f = c.getDeclaredField("theUnsafe");
+    f.setAccessible(true);
+    Unsafe unsafe = (Unsafe)f.get(c);
+
+    f = Reference.class.getDeclaredField("referent");
+    f.setAccessible(true);
+    long referent_offset = unsafe.objectFieldOffset(f);
+
+    Test7190310_unsafe t = new Test7190310_unsafe();
+    TestObject o = new TestObject();
+    t.obj = o;
+
+    // Warmup (compile methods)
+    System.err.println("Warmup");
+    Object obj = null;
+    for (int i = 0; i < 11000; i++) {
+      obj = getRef0(ref);
+    }
+    for (int i = 0; i < 11000; i++) {
+      obj = getRef1(unsafe, ref, referent_offset);
+    }
+    for (int i = 0; i < 11000; i++) {
+      obj = getRef2(unsafe, ref, referent_offset);
+    }
+    for (int i = 0; i < 11000; i++) {
+      obj = getRef3(unsafe, ref, referent_offset);
+    }
+    for (int i = 0; i < 11000; i++) {
+      obj = getRef4(unsafe, t, referent_offset);
+    }
+
+    // Access verification
+    System.err.println("Verification");
+    if (!verifyGet(referent_offset, unsafe)) {
+      System.exit(97);
+    }
+
+    obj = getRef3(unsafe, t, referent_offset);
+    if (obj != o) {
+      System.out.println("FAILED: unsafe.getObject(Object, " + referent_offset + ") " + obj + " != " + o);
+      System.exit(97);
+    }
+    obj = getRef4(unsafe, t, referent_offset);
+    if (obj != o) {
+      System.out.println("FAILED: unsafe.getObject(Test7190310, " + referent_offset + ") " + obj + " != " + o);
+      System.exit(97);
+    }
+  }
+
+  static boolean verifyGet(long referent_offset, Unsafe unsafe) throws Exception {
+    // Access verification
+    System.out.println("referent: " + str);
+    Object obj = getRef0(ref);
+    if (obj != str) {
+      System.out.println("FAILED: weakRef.get() " + obj + " != " + str);
+      return false;
+    }
+    obj = getRef1(unsafe, ref, referent_offset);
+    if (obj != str) {
+      System.out.println("FAILED: unsafe.getObject(weakRef, " + referent_offset + ") " + obj + " != " + str);
+      return false;
+    }
+    obj = getRef2(unsafe, ref, referent_offset);
+    if (obj != str) {
+      System.out.println("FAILED: unsafe.getObject(abstRef, " + referent_offset + ") " + obj + " != " + str);
+      return false;
+    }
+    obj = getRef3(unsafe, ref, referent_offset);
+    if (obj != str) {
+      System.out.println("FAILED: unsafe.getObject(Object, " + referent_offset + ") " + obj + " != " + str);
+      return false;
+    }
+    return true;
+  }
+
+  static Object getRef0(WeakReference ref) throws Exception {
+    return ref.get();
+  }
+  static Object getRef1(Unsafe unsafe, WeakReference ref, long referent_offset) throws Exception {
+    return unsafe.getObject(ref, referent_offset);
+  }
+  static Object getRef2(Unsafe unsafe, Reference ref, long referent_offset) throws Exception {
+    return unsafe.getObject(ref, referent_offset);
+  }
+  static Object getRef3(Unsafe unsafe, Object ref, long referent_offset) throws Exception {
+    return unsafe.getObject(ref, referent_offset);
+  }
+  static Object getRef4(Unsafe unsafe, Test7190310_unsafe ref, long referent_offset) throws Exception {
+    return unsafe.getObject(ref, referent_offset);
+  }
+}
+
diff --git a/hotspot/test/compiler/7192963/TestByteVect.java b/hotspot/test/compiler/7192963/TestByteVect.java
new file mode 100644
index 0000000..fd466ff
--- /dev/null
+++ b/hotspot/test/compiler/7192963/TestByteVect.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012, 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 7192963
+ * @summary assert(_in[req-1] == this) failed: Must pass arg count to 'new'
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestByteVect
+ */
+
+public class TestByteVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  public static void main(String args[]) {
+    System.out.println("Testing Byte vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    byte[] a0 = new byte[ARRLEN];
+    byte[] a1 = new byte[ARRLEN];
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = (byte)i;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+      test_addi(a0, a1);
+      test_lsai(a0, a1);
+      test_unrl_init(a0);
+      test_unrl_addi(a0, a1);
+      test_unrl_lsai(a0, a1);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_init: ", i, a0[i], (byte)(i&3));
+      }
+      test_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addi: ", i, a0[i], (byte)(i+(i&3)));
+      }
+      test_lsai(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_lsai: ", i, a0[i], (byte)(i<<(i&3)));
+      }
+      test_unrl_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_init: ", i, a0[i], (byte)(i&3));
+      }
+      test_unrl_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_addi: ", i, a0[i], (byte)(i+(i&3)));
+      }
+      test_unrl_lsai(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_lsai: ", i, a0[i], (byte)(i<<(i&3)));
+      }
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_lsai(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_lsai: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_lsai(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_lsai: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_init(byte[] a0) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(i&3);
+    }
+  }
+  static void test_addi(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]+(i&3));
+    }
+  }
+  static void test_lsai(byte[] a0, byte[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (byte)(a1[i]<<(i&3));
+    }
+  }
+  static void test_unrl_init(byte[] a0) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = 0;
+      a0[i+1] = 1;
+      a0[i+2] = 2;
+      a0[i+3] = 3;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (byte)(i&3);
+    }
+  }
+  static void test_unrl_addi(byte[] a0, byte[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = (byte)(a1[i+0]+0);
+      a0[i+1] = (byte)(a1[i+1]+1);
+      a0[i+2] = (byte)(a1[i+2]+2);
+      a0[i+3] = (byte)(a1[i+3]+3);
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (byte)(a1[i]+(i&3));
+    }
+  }
+  static void test_unrl_lsai(byte[] a0, byte[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = (byte)(a1[i+0]<<0);
+      a0[i+1] = (byte)(a1[i+1]<<1);
+      a0[i+2] = (byte)(a1[i+2]<<2);
+      a0[i+3] = (byte)(a1[i+3]<<3);
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (byte)(a1[i]<<(i&3));
+    }
+  }
+
+  static int verify(String text, int i, byte elem, byte val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
+
diff --git a/hotspot/test/compiler/7192963/TestDoubleVect.java b/hotspot/test/compiler/7192963/TestDoubleVect.java
new file mode 100644
index 0000000..872eb42
--- /dev/null
+++ b/hotspot/test/compiler/7192963/TestDoubleVect.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012, 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 7192963
+ * @summary assert(_in[req-1] == this) failed: Must pass arg count to 'new'
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestDoubleVect
+ */
+
+public class TestDoubleVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  public static void main(String args[]) {
+    System.out.println("Testing Double vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    double[] a0 = new double[ARRLEN];
+    double[] a1 = new double[ARRLEN];
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = (double)i;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+      test_addi(a0, a1);
+      test_divi(a0, a1);
+      test_unrl_init(a0);
+      test_unrl_addi(a0, a1);
+      test_unrl_divi(a0, a1);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_init: ", i, a0[i], (double)(i&3));
+      }
+      test_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addi: ", i, a0[i], (double)(i+(i&3)));
+      }
+      test_divi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divi: ", i, a0[i], (double)i/(double)((i&3)+1));
+      }
+      test_unrl_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_init: ", i, a0[i], (double)(i&3));
+      }
+      test_unrl_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_addi: ", i, a0[i], (double)(i+(i&3)));
+      }
+      test_unrl_divi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_divi: ", i, a0[i], (double)i/(double)((i&3)+1));
+      }
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_divi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_divi: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_init(double[] a0) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (double)(i&3);
+    }
+  }
+  static void test_addi(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = a1[i]+(double)(i&3);
+    }
+  }
+  static void test_divi(double[] a0, double[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = a1[i]/(double)((i&3)+1);
+    }
+  }
+  static void test_unrl_init(double[] a0) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = 0.;
+      a0[i+1] = 1.;
+      a0[i+2] = 2.;
+      a0[i+3] = 3.;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (double)(i&3);
+    }
+  }
+  static void test_unrl_addi(double[] a0, double[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = a1[i+0]+0.;
+      a0[i+1] = a1[i+1]+1.;
+      a0[i+2] = a1[i+2]+2.;
+      a0[i+3] = a1[i+3]+3.;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = a1[i]+(double)(i&3);
+    }
+  }
+  static void test_unrl_divi(double[] a0, double[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = a1[i+0]/1.;
+      a0[i+1] = a1[i+1]/2.;
+      a0[i+2] = a1[i+2]/3.;
+      a0[i+3] = a1[i+3]/4.;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = a1[i]/(double)((i&3)+1);
+    }
+  }
+
+  static int verify(String text, int i, double elem, double val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
+
diff --git a/hotspot/test/compiler/7192963/TestFloatVect.java b/hotspot/test/compiler/7192963/TestFloatVect.java
new file mode 100644
index 0000000..399e68e
--- /dev/null
+++ b/hotspot/test/compiler/7192963/TestFloatVect.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012, 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 7192963
+ * @summary assert(_in[req-1] == this) failed: Must pass arg count to 'new'
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestFloatVect
+ */
+
+public class TestFloatVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  public static void main(String args[]) {
+    System.out.println("Testing Float vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    float[] a0 = new float[ARRLEN];
+    float[] a1 = new float[ARRLEN];
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = (float)i;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+      test_addi(a0, a1);
+      test_divi(a0, a1);
+      test_unrl_init(a0);
+      test_unrl_addi(a0, a1);
+      test_unrl_divi(a0, a1);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_init: ", i, a0[i], (float)(i&3));
+      }
+      test_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addi: ", i, a0[i], (float)(i+(i&3)));
+      }
+      test_divi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divi: ", i, a0[i], (float)i/(float)((i&3)+1));
+      }
+      test_unrl_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_init: ", i, a0[i], (float)(i&3));
+      }
+      test_unrl_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_addi: ", i, a0[i], (float)(i+(i&3)));
+      }
+      test_unrl_divi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_divi: ", i, a0[i], (float)i/(float)((i&3)+1));
+      }
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_divi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_divi: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_init(float[] a0) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (float)(i&3);
+    }
+  }
+  static void test_addi(float[] a0, float[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = a1[i]+(float)(i&3);
+    }
+  }
+  static void test_divi(float[] a0, float[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = a1[i]/(float)((i&3)+1);
+    }
+  }
+  static void test_unrl_init(float[] a0) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = 0.f;
+      a0[i+1] = 1.f;
+      a0[i+2] = 2.f;
+      a0[i+3] = 3.f;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (float)(i&3);
+    }
+  }
+  static void test_unrl_addi(float[] a0, float[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = a1[i+0]+0.f;
+      a0[i+1] = a1[i+1]+1.f;
+      a0[i+2] = a1[i+2]+2.f;
+      a0[i+3] = a1[i+3]+3.f;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = a1[i]+(float)(i&3);
+    }
+  }
+  static void test_unrl_divi(float[] a0, float[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = a1[i+0]/1.f;
+      a0[i+1] = a1[i+1]/2.f;
+      a0[i+2] = a1[i+2]/3.f;
+      a0[i+3] = a1[i+3]/4.f;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = a1[i]/(float)((i&3)+1);
+    }
+  }
+
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
+
diff --git a/hotspot/test/compiler/7192963/TestIntVect.java b/hotspot/test/compiler/7192963/TestIntVect.java
new file mode 100644
index 0000000..b1bb147
--- /dev/null
+++ b/hotspot/test/compiler/7192963/TestIntVect.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012, 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 7192963
+ * @summary assert(_in[req-1] == this) failed: Must pass arg count to 'new'
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestIntVect
+ */
+
+public class TestIntVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  public static void main(String args[]) {
+    System.out.println("Testing Integer vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    int[] a0 = new int[ARRLEN];
+    int[] a1 = new int[ARRLEN];
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = i;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+      test_addi(a0, a1);
+      test_lsai(a0, a1);
+      test_unrl_init(a0);
+      test_unrl_addi(a0, a1);
+      test_unrl_lsai(a0, a1);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_init: ", i, a0[i], (i&3));
+      }
+      test_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addi: ", i, a0[i], (i+(i&3)));
+      }
+      test_lsai(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_lsai: ", i, a0[i], (i<<(i&3)));
+      }
+      test_unrl_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_init: ", i, a0[i], (i&3));
+      }
+      test_unrl_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_addi: ", i, a0[i], (i+(i&3)));
+      }
+      test_unrl_lsai(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_lsai: ", i, a0[i], (i<<(i&3)));
+      }
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_lsai(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_lsai: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_lsai(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_lsai: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_init(int[] a0) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (i&3);
+    }
+  }
+  static void test_addi(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = a1[i]+(i&3);
+    }
+  }
+  static void test_lsai(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = a1[i]<<(i&3);
+    }
+  }
+  static void test_unrl_init(int[] a0) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = 0;
+      a0[i+1] = 1;
+      a0[i+2] = 2;
+      a0[i+3] = 3;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (i&3);
+    }
+  }
+  static void test_unrl_addi(int[] a0, int[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = a1[i+0]+0;
+      a0[i+1] = a1[i+1]+1;
+      a0[i+2] = a1[i+2]+2;
+      a0[i+3] = a1[i+3]+3;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = a1[i]+(i&3);
+    }
+  }
+  static void test_unrl_lsai(int[] a0, int[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = a1[i+0]<<0;
+      a0[i+1] = a1[i+1]<<1;
+      a0[i+2] = a1[i+2]<<2;
+      a0[i+3] = a1[i+3]<<3;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = a1[i]<<(i&3);
+    }
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
+
diff --git a/hotspot/test/compiler/7192963/TestLongVect.java b/hotspot/test/compiler/7192963/TestLongVect.java
new file mode 100644
index 0000000..7266352
--- /dev/null
+++ b/hotspot/test/compiler/7192963/TestLongVect.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012, 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 7192963
+ * @summary assert(_in[req-1] == this) failed: Must pass arg count to 'new'
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestLongVect
+ */
+
+public class TestLongVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  public static void main(String args[]) {
+    System.out.println("Testing Long vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    long[] a0 = new long[ARRLEN];
+    long[] a1 = new long[ARRLEN];
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = (long)i;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+      test_addi(a0, a1);
+      test_lsai(a0, a1);
+      test_unrl_init(a0);
+      test_unrl_addi(a0, a1);
+      test_unrl_lsai(a0, a1);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_init: ", i, a0[i], (long)(i&3));
+      }
+      test_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addi: ", i, a0[i], (long)(i+(i&3)));
+      }
+      test_lsai(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_lsai: ", i, a0[i], (long)(i<<(i&3)));
+      }
+      test_unrl_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_init: ", i, a0[i], (long)(i&3));
+      }
+      test_unrl_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_addi: ", i, a0[i], (long)(i+(i&3)));
+      }
+      test_unrl_lsai(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_lsai: ", i, a0[i], (long)(i<<(i&3)));
+      }
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_lsai(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_lsai: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_lsai(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_lsai: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_init(long[] a0) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(i&3);
+    }
+  }
+  static void test_addi(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]+(i&3));
+    }
+  }
+  static void test_lsai(long[] a0, long[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (long)(a1[i]<<(i&3));
+    }
+  }
+  static void test_unrl_init(long[] a0) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = 0;
+      a0[i+1] = 1;
+      a0[i+2] = 2;
+      a0[i+3] = 3;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (long)(i&3);
+    }
+  }
+  static void test_unrl_addi(long[] a0, long[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = (long)(a1[i+0]+0);
+      a0[i+1] = (long)(a1[i+1]+1);
+      a0[i+2] = (long)(a1[i+2]+2);
+      a0[i+3] = (long)(a1[i+3]+3);
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (long)(a1[i]+(i&3));
+    }
+  }
+  static void test_unrl_lsai(long[] a0, long[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = (long)(a1[i+0]<<0);
+      a0[i+1] = (long)(a1[i+1]<<1);
+      a0[i+2] = (long)(a1[i+2]<<2);
+      a0[i+3] = (long)(a1[i+3]<<3);
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (long)(a1[i]<<(i&3));
+    }
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
+
diff --git a/hotspot/test/compiler/7192963/TestShortVect.java b/hotspot/test/compiler/7192963/TestShortVect.java
new file mode 100644
index 0000000..f83e5ff
--- /dev/null
+++ b/hotspot/test/compiler/7192963/TestShortVect.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright (c) 2012, 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 7192963
+ * @summary assert(_in[req-1] == this) failed: Must pass arg count to 'new'
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestShortVect
+ */
+
+public class TestShortVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  public static void main(String args[]) {
+    System.out.println("Testing Short vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    short[] a0 = new short[ARRLEN];
+    short[] a1 = new short[ARRLEN];
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a1[i] = (short)i;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+      test_addi(a0, a1);
+      test_lsai(a0, a1);
+      test_unrl_init(a0);
+      test_unrl_addi(a0, a1);
+      test_unrl_lsai(a0, a1);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      test_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_init: ", i, a0[i], (short)(i&3));
+      }
+      test_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addi: ", i, a0[i], (short)(i+(i&3)));
+      }
+      test_lsai(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_lsai: ", i, a0[i], (short)(i<<(i&3)));
+      }
+      test_unrl_init(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_init: ", i, a0[i], (short)(i&3));
+      }
+      test_unrl_addi(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_addi: ", i, a0[i], (short)(i+(i&3)));
+      }
+      test_unrl_lsai(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_unrl_lsai: ", i, a0[i], (short)(i<<(i&3)));
+      }
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_lsai(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_lsai: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_init(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_init: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_addi(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_addi: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unrl_lsai(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unrl_lsai: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_init(short[] a0) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(i&3);
+    }
+  }
+  static void test_addi(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]+(i&3));
+    }
+  }
+  static void test_lsai(short[] a0, short[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (short)(a1[i]<<(i&3));
+    }
+  }
+  static void test_unrl_init(short[] a0) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = 0;
+      a0[i+1] = 1;
+      a0[i+2] = 2;
+      a0[i+3] = 3;
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (short)(i&3);
+    }
+  }
+  static void test_unrl_addi(short[] a0, short[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = (short)(a1[i+0]+0);
+      a0[i+1] = (short)(a1[i+1]+1);
+      a0[i+2] = (short)(a1[i+2]+2);
+      a0[i+3] = (short)(a1[i+3]+3);
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (short)(a1[i]+(i&3));
+    }
+  }
+  static void test_unrl_lsai(short[] a0, short[] a1) {
+    int i = 0;
+    for (; i < a0.length-4; i+=4) {
+      a0[i+0] = (short)(a1[i+0]<<0);
+      a0[i+1] = (short)(a1[i+1]<<1);
+      a0[i+2] = (short)(a1[i+2]<<2);
+      a0[i+3] = (short)(a1[i+3]<<3);
+    }
+    for (; i < a0.length; i++) {
+      a0[i] = (short)(a1[i]<<(i&3));
+    }
+  }
+
+  static int verify(String text, int i, short elem, short val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
+
diff --git a/hotspot/test/compiler/7196199/Test7196199.java b/hotspot/test/compiler/7196199/Test7196199.java
new file mode 100644
index 0000000..6aa3536
--- /dev/null
+++ b/hotspot/test/compiler/7196199/Test7196199.java
@@ -0,0 +1,189 @@
+/*
+ * Copyright (c) 2012, 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 7196199
+ * @summary java/text/Bidi/Bug6665028.java failed: Bidi run count incorrect
+ *
+ * @run main/othervm/timeout=400 -Xmx32m -Xbatch -XX:+IgnoreUnrecognizedVMOptions -XX:-TieredCompilation -XX:CompileCommand=exclude,Test7196199.test -XX:+SafepointALot -XX:GuaranteedSafepointInterval=100 Test7196199
+ */
+
+
+public class Test7196199 {
+  private static final int ARRLEN = 97;
+  private static final int ITERS  = 5000;
+  private static final int INI_ITERS  = 1000;
+  private static final int SFP_ITERS  = 10000;
+  private static final float SFP_ITERS_F  = 10000.f;
+  private static final float VALUE = 15.f;
+  public static void main(String args[]) {
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    float[] a0 = new float[ARRLEN];
+    float[] a1 = new float[ARRLEN];
+    // Initialize
+    for (int i=0; i<ARRLEN; i++) {
+      a0[i] = 0.f;
+      a1[i] = (float)i;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<INI_ITERS; i++) {
+      test_incrc(a0);
+      test_incrv(a0, VALUE);
+      test_addc(a0, a1);
+      test_addv(a0, a1, VALUE);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    for (int i=0; i<ARRLEN; i++)
+      a0[i] = 0.f;
+
+    System.out.println("  test_incrc");
+    for (int j=0; j<ITERS; j++) {
+      test_incrc(a0);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_incrc: ", i, a0[i], VALUE*SFP_ITERS_F);
+        a0[i] = 0.f; // Reset
+      }
+    }
+
+    System.out.println("  test_incrv");
+    for (int j=0; j<ITERS; j++) {
+      test_incrv(a0, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_incrv: ", i, a0[i], VALUE*SFP_ITERS_F);
+        a0[i] = 0.f; // Reset
+      }
+    }
+
+    System.out.println("  test_addc");
+    for (int j=0; j<ITERS; j++) {
+      test_addc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], ((float)i + VALUE)*SFP_ITERS_F);
+        a0[i] = 0.f; // Reset
+      }
+    }
+
+    System.out.println("  test_addv");
+    for (int j=0; j<ITERS; j++) {
+      test_addv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], ((float)i + VALUE)*SFP_ITERS_F);
+        a0[i] = 0.f; // Reset
+      }
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<INI_ITERS; i++) {
+      test_incrc(a0);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_incrc: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<INI_ITERS; i++) {
+      test_incrv(a0, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_incrv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<INI_ITERS; i++) {
+      test_addc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addc: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<INI_ITERS; i++) {
+      test_addv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addv: " + (end - start));
+
+    return errn;
+  }
+
+  static void test_incrc(float[] a0) {
+    // Non-counted loop with safepoint.
+    for (long l = 0; l < SFP_ITERS; l++) {
+      // Counted and vectorized loop.
+      for (int i = 0; i < a0.length; i+=1) {
+        a0[i] += VALUE;
+      }
+    }
+  }
+  static void test_incrv(float[] a0, float b) {
+    // Non-counted loop with safepoint.
+    for (long l = 0; l < SFP_ITERS; l++) {
+      // Counted and vectorized loop.
+      for (int i = 0; i < a0.length; i+=1) {
+        a0[i] += b;
+      }
+    }
+  }
+  static void test_addc(float[] a0, float[] a1) {
+    // Non-counted loop with safepoint.
+    for (long l = 0; l < SFP_ITERS; l++) {
+      // Counted and vectorized loop.
+      for (int i = 0; i < a0.length; i+=1) {
+        a0[i] += a1[i]+VALUE;
+      }
+    }
+  }
+  static void test_addv(float[] a0, float[] a1, float b) {
+    // Non-counted loop with safepoint.
+    for (long l = 0; l < SFP_ITERS; l++) {
+      // Counted and vectorized loop.
+      for (int i = 0; i < a0.length; i+=1) {
+        a0[i] += a1[i]+b;
+      }
+    }
+  }
+
+  static int verify(String text, int i, float elem, float val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+}
+
diff --git a/hotspot/test/compiler/7199742/Test7199742.java b/hotspot/test/compiler/7199742/Test7199742.java
new file mode 100644
index 0000000..7f29e96
--- /dev/null
+++ b/hotspot/test/compiler/7199742/Test7199742.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2012, 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 7199742
+ * @summary A lot of C2 OSR compilations of the same method's bci
+ *
+ * @run main/othervm -Xmx32m -Xbatch Test7199742
+ */
+
+public class Test7199742 {
+  private static final int ITERS  = 10000000;
+  public static void main(String args[]) {
+    Test7199742 t = new Test7199742();
+    for (int i=0; i<10; i++) {
+      test(t, 7);
+    }
+  }
+  static Test7199742 test(Test7199742 t, int m) {
+    int i = -(ITERS/2);
+    if (i == 0) return null;
+    Test7199742 v = null;
+    while(i < ITERS) {
+      if ((i&m) == 0) {
+        v = t;
+      }
+      i++;
+    }
+    return v;
+  }
+}
+
diff --git a/hotspot/test/compiler/7200264/Test7200264.sh b/hotspot/test/compiler/7200264/Test7200264.sh
new file mode 100644
index 0000000..4276a8f
--- /dev/null
+++ b/hotspot/test/compiler/7200264/Test7200264.sh
@@ -0,0 +1,164 @@
+#!/bin/sh
+# 
+# Copyright (c) 2012, 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.
+# 
+# 
+
+if [ "${TESTSRC}" = "" ]
+then
+  echo "TESTSRC not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTSRC=${TESTSRC}"
+if [ "${TESTJAVA}" = "" ]
+then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTJAVA=${TESTJAVA}"
+if [ "${TESTCLASSES}" = "" ]
+then
+  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+echo "TESTCLASSES=${TESTCLASSES}"
+echo "CLASSPATH=${CLASSPATH}"
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin )
+    NULL=/dev/null
+    PS=":"
+    FS="/"
+    ;;
+  Windows_* )
+    NULL=NUL
+    PS=";"
+    FS="\\"
+    ;;
+  CYGWIN_* )
+    NULL=/dev/null
+    PS=";"
+    FS="/"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xinternalversion | sed 's/amd64/x86/' | grep "x86" | grep "Server VM" | grep "debug"
+
+# Only test fastdebug Server VM on x86
+if [ $? != 0 ]
+then
+    echo "Test Passed"
+    exit 0
+fi
+
+# grep for support integer multiply vectors (cpu with SSE4.1)
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -XX:+PrintMiscellaneous -XX:+Verbose -version | grep "cores per cpu" | grep "sse4.1"
+
+if [ $? != 0 ]
+then
+    SSE=2
+else
+    SSE=4
+fi
+
+cp ${TESTSRC}${FS}TestIntVect.java .
+${TESTJAVA}${FS}bin${FS}javac -d . TestIntVect.java
+
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 -XX:+PrintCompilation -XX:+TraceNewVectors TestIntVect > test.out 2>&1
+
+COUNT=`grep AddVI test.out | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 4 ]
+then
+    echo "Test Failed: AddVI $COUNT < 4"
+    exit 1
+fi
+
+# AddVI is generated for test_subc
+COUNT=`grep SubVI test.out | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 4 ]
+then
+    echo "Test Failed: SubVI $COUNT < 4"
+    exit 1
+fi
+
+# MulVI is only supported with SSE4.1.
+if [ $SSE -gt 3 ]
+then
+# LShiftVI+SubVI is generated for test_mulc
+COUNT=`grep MulVI test.out | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 2 ]
+then
+    echo "Test Failed: MulVI $COUNT < 2"
+    exit 1
+fi
+fi
+
+COUNT=`grep AndV test.out | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 3 ]
+then
+    echo "Test Failed: AndV $COUNT < 3"
+    exit 1
+fi
+
+COUNT=`grep OrV test.out | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 3 ]
+then
+    echo "Test Failed: OrV $COUNT < 3"
+    exit 1
+fi
+
+COUNT=`grep XorV test.out | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 3 ]
+then
+    echo "Test Failed: XorV $COUNT < 3"
+    exit 1
+fi
+
+# LShiftVI+SubVI is generated for test_mulc
+COUNT=`grep LShiftVI test.out | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 5 ]
+then
+    echo "Test Failed: LShiftVI $COUNT < 5"
+    exit 1
+fi
+
+COUNT=`grep RShiftVI test.out | sed '/URShiftVI/d' | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 3 ]
+then
+    echo "Test Failed: RShiftVI $COUNT < 3"
+    exit 1
+fi
+
+COUNT=`grep URShiftVI test.out | wc -l | awk '{print $1}'`
+if [ $COUNT -lt 3 ]
+then
+    echo "Test Failed: URShiftVI $COUNT < 3"
+    exit 1
+fi
+
diff --git a/hotspot/test/compiler/7200264/TestIntVect.java b/hotspot/test/compiler/7200264/TestIntVect.java
new file mode 100644
index 0000000..f85d4ff
--- /dev/null
+++ b/hotspot/test/compiler/7200264/TestIntVect.java
@@ -0,0 +1,650 @@
+/*
+ * Copyright (c) 2012, 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 7200264
+ * @summary 7192963 changes disabled shift vectors
+ *
+ * @run shell Test7200264.sh
+ */
+
+/*
+ * Copy of test/compiler/6340864/TestIntVect.java without performance tests.
+ */
+public class TestIntVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int ADD_INIT = Integer.MAX_VALUE-500;
+  private static final int BIT_MASK = 0xEC80F731;
+  private static final int VALUE = 15;
+  private static final int SHIFT = 32;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Integer vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    int[] a0 = new int[ARRLEN];
+    int[] a1 = new int[ARRLEN];
+    int[] a2 = new int[ARRLEN];
+    int[] a3 = new int[ARRLEN];
+    int[] a4 = new int[ARRLEN];
+    long[] p2 = new long[ARRLEN/2];
+    // Initialize
+    int gold_sum = 0;
+    for (int i=0; i<ARRLEN; i++) {
+      int val = (int)(ADD_INIT+i);
+      gold_sum += val;
+      a1[i] = val;
+      a2[i] = (int)VALUE;
+      a3[i] = (int)-VALUE;
+      a4[i] = (int)BIT_MASK;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+      test_addc(a0, a1);
+      test_addv(a0, a1, (int)VALUE);
+      test_adda(a0, a1, a2);
+      test_subc(a0, a1);
+      test_subv(a0, a1, (int)VALUE);
+      test_suba(a0, a1, a2);
+      test_mulc(a0, a1);
+      test_mulv(a0, a1, (int)VALUE);
+      test_mula(a0, a1, a2);
+      test_divc(a0, a1);
+      test_divv(a0, a1, (int)VALUE);
+      test_diva(a0, a1, a2);
+      test_mulc_n(a0, a1);
+      test_mulv(a0, a1, (int)-VALUE);
+      test_mula(a0, a1, a3);
+      test_divc_n(a0, a1);
+      test_divv(a0, a1, (int)-VALUE);
+      test_diva(a0, a1, a3);
+      test_andc(a0, a1);
+      test_andv(a0, a1, (int)BIT_MASK);
+      test_anda(a0, a1, a4);
+      test_orc(a0, a1);
+      test_orv(a0, a1, (int)BIT_MASK);
+      test_ora(a0, a1, a4);
+      test_xorc(a0, a1);
+      test_xorv(a0, a1, (int)BIT_MASK);
+      test_xora(a0, a1, a4);
+      test_sllc(a0, a1);
+      test_sllv(a0, a1, VALUE);
+      test_srlc(a0, a1);
+      test_srlv(a0, a1, VALUE);
+      test_srac(a0, a1);
+      test_srav(a0, a1, VALUE);
+      test_sllc_n(a0, a1);
+      test_sllv(a0, a1, -VALUE);
+      test_srlc_n(a0, a1);
+      test_srlv(a0, a1, -VALUE);
+      test_srac_n(a0, a1);
+      test_srav(a0, a1, -VALUE);
+      test_sllc_o(a0, a1);
+      test_sllv(a0, a1, SHIFT);
+      test_srlc_o(a0, a1);
+      test_srlv(a0, a1, SHIFT);
+      test_srac_o(a0, a1);
+      test_srav(a0, a1, SHIFT);
+      test_sllc_on(a0, a1);
+      test_sllv(a0, a1, -SHIFT);
+      test_srlc_on(a0, a1);
+      test_srlv(a0, a1, -SHIFT);
+      test_srac_on(a0, a1);
+      test_srav(a0, a1, -SHIFT);
+      test_pack2(p2, a1);
+      test_unpack2(a0, p2);
+      test_pack2_swap(p2, a1);
+      test_unpack2_swap(a0, p2);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      int sum = test_sum(a1);
+      if (sum != gold_sum) {
+        System.err.println("test_sum:  " + sum + " != " + gold_sum);
+        errn++;
+      }
+
+      test_addc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], (int)((int)(ADD_INIT+i)+VALUE));
+      }
+      test_addv(a0, a1, (int)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], (int)((int)(ADD_INIT+i)+VALUE));
+      }
+      test_adda(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_adda: ", i, a0[i], (int)((int)(ADD_INIT+i)+VALUE));
+      }
+
+      test_subc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subc: ", i, a0[i], (int)((int)(ADD_INIT+i)-VALUE));
+      }
+      test_subv(a0, a1, (int)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subv: ", i, a0[i], (int)((int)(ADD_INIT+i)-VALUE));
+      }
+      test_suba(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_suba: ", i, a0[i], (int)((int)(ADD_INIT+i)-VALUE));
+      }
+
+      test_mulc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc: ", i, a0[i], (int)((int)(ADD_INIT+i)*VALUE));
+      }
+      test_mulv(a0, a1, (int)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv: ", i, a0[i], (int)((int)(ADD_INIT+i)*VALUE));
+      }
+      test_mula(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula: ", i, a0[i], (int)((int)(ADD_INIT+i)*VALUE));
+      }
+
+      test_divc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc: ", i, a0[i], (int)((int)(ADD_INIT+i)/VALUE));
+      }
+      test_divv(a0, a1, (int)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv: ", i, a0[i], (int)((int)(ADD_INIT+i)/VALUE));
+      }
+      test_diva(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva: ", i, a0[i], (int)((int)(ADD_INIT+i)/VALUE));
+      }
+
+      test_mulc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc_n: ", i, a0[i], (int)((int)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mulv(a0, a1, (int)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv_n: ", i, a0[i], (int)((int)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mula(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula_n: ", i, a0[i], (int)((int)(ADD_INIT+i)*(-VALUE)));
+      }
+
+      test_divc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc_n: ", i, a0[i], (int)((int)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_divv(a0, a1, (int)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv_n: ", i, a0[i], (int)((int)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_diva(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva_n: ", i, a0[i], (int)((int)(ADD_INIT+i)/(-VALUE)));
+      }
+
+      test_andc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andc: ", i, a0[i], (int)((int)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_andv(a0, a1, (int)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andv: ", i, a0[i], (int)((int)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_anda(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_anda: ", i, a0[i], (int)((int)(ADD_INIT+i)&BIT_MASK));
+      }
+
+      test_orc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orc: ", i, a0[i], (int)((int)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_orv(a0, a1, (int)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orv: ", i, a0[i], (int)((int)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_ora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ora: ", i, a0[i], (int)((int)(ADD_INIT+i)|BIT_MASK));
+      }
+
+      test_xorc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorc: ", i, a0[i], (int)((int)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xorv(a0, a1, (int)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorv: ", i, a0[i], (int)((int)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xora: ", i, a0[i], (int)((int)(ADD_INIT+i)^BIT_MASK));
+      }
+
+      test_sllc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc: ", i, a0[i], (int)((int)(ADD_INIT+i)<<VALUE));
+      }
+      test_sllv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv: ", i, a0[i], (int)((int)(ADD_INIT+i)<<VALUE));
+      }
+
+      test_srlc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>VALUE));
+      }
+      test_srlv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>VALUE));
+      }
+
+      test_srac(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac: ", i, a0[i], (int)((int)(ADD_INIT+i)>>VALUE));
+      }
+      test_srav(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav: ", i, a0[i], (int)((int)(ADD_INIT+i)>>VALUE));
+      }
+
+      test_sllc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_n: ", i, a0[i], (int)((int)(ADD_INIT+i)<<(-VALUE)));
+      }
+      test_sllv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_n: ", i, a0[i], (int)((int)(ADD_INIT+i)<<(-VALUE)));
+      }
+
+      test_srlc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_n: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>(-VALUE)));
+      }
+      test_srlv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_n: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>(-VALUE)));
+      }
+
+      test_srac_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_n: ", i, a0[i], (int)((int)(ADD_INIT+i)>>(-VALUE)));
+      }
+      test_srav(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_n: ", i, a0[i], (int)((int)(ADD_INIT+i)>>(-VALUE)));
+      }
+
+      test_sllc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_o: ", i, a0[i], (int)((int)(ADD_INIT+i)<<SHIFT));
+      }
+      test_sllv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_o: ", i, a0[i], (int)((int)(ADD_INIT+i)<<SHIFT));
+      }
+
+      test_srlc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_o: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>SHIFT));
+      }
+      test_srlv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_o: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>SHIFT));
+      }
+
+      test_srac_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_o: ", i, a0[i], (int)((int)(ADD_INIT+i)>>SHIFT));
+      }
+      test_srav(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_o: ", i, a0[i], (int)((int)(ADD_INIT+i)>>SHIFT));
+      }
+
+      test_sllc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_on: ", i, a0[i], (int)((int)(ADD_INIT+i)<<(-SHIFT)));
+      }
+      test_sllv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_on: ", i, a0[i], (int)((int)(ADD_INIT+i)<<(-SHIFT)));
+      }
+
+      test_srlc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_on: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+      test_srlv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_on: ", i, a0[i], (int)((int)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+
+      test_srac_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_on: ", i, a0[i], (int)((int)(ADD_INIT+i)>>(-SHIFT)));
+      }
+      test_srav(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_on: ", i, a0[i], (int)((int)(ADD_INIT+i)>>(-SHIFT)));
+      }
+
+      test_pack2(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2: ", i, p2[i], ((long)(ADD_INIT+2*i) & 0xFFFFFFFFl) | ((long)(ADD_INIT+2*i+1) << 32));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack2(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2: ", i, a0[i], (ADD_INIT+i));
+      }
+
+      test_pack2_swap(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2_swap: ", i, p2[i], ((long)(ADD_INIT+2*i+1) & 0xFFFFFFFFl) | ((long)(ADD_INIT+2*i) << 32));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = -1;
+      }
+      test_unpack2_swap(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2_swap: ", i, a0[i], (ADD_INIT+i));
+      }
+
+    }
+
+    return errn;
+  }
+
+  static int test_sum(int[] a1) {
+    int sum = 0;
+    for (int i = 0; i < a1.length; i+=1) {
+      sum += a1[i];
+    }
+    return sum;
+  }
+
+  static void test_addc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]+VALUE);
+    }
+  }
+  static void test_addv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]+b);
+    }
+  }
+  static void test_adda(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]+a2[i]);
+    }
+  }
+
+  static void test_subc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]-VALUE);
+    }
+  }
+  static void test_subv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]-b);
+    }
+  }
+  static void test_suba(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]-a2[i]);
+    }
+  }
+
+  static void test_mulc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]*VALUE);
+    }
+  }
+  static void test_mulc_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]*(-VALUE));
+    }
+  }
+  static void test_mulv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]*b);
+    }
+  }
+  static void test_mula(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]*a2[i]);
+    }
+  }
+
+  static void test_divc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]/VALUE);
+    }
+  }
+  static void test_divc_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]/(-VALUE));
+    }
+  }
+  static void test_divv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]/b);
+    }
+  }
+  static void test_diva(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]/a2[i]);
+    }
+  }
+
+  static void test_andc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]&BIT_MASK);
+    }
+  }
+  static void test_andv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]&b);
+    }
+  }
+  static void test_anda(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]&a2[i]);
+    }
+  }
+
+  static void test_orc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]|BIT_MASK);
+    }
+  }
+  static void test_orv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]|b);
+    }
+  }
+  static void test_ora(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]|a2[i]);
+    }
+  }
+
+  static void test_xorc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]^BIT_MASK);
+    }
+  }
+  static void test_xorv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]^b);
+    }
+  }
+  static void test_xora(int[] a0, int[] a1, int[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]^a2[i]);
+    }
+  }
+
+  static void test_sllc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<VALUE);
+    }
+  }
+  static void test_sllc_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<(-VALUE));
+    }
+  }
+  static void test_sllc_o(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<SHIFT);
+    }
+  }
+  static void test_sllc_on(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<(-SHIFT));
+    }
+  }
+  static void test_sllv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]<<b);
+    }
+  }
+
+  static void test_srlc(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>VALUE);
+    }
+  }
+  static void test_srlc_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>(-VALUE));
+    }
+  }
+  static void test_srlc_o(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>SHIFT);
+    }
+  }
+  static void test_srlc_on(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>(-SHIFT));
+    }
+  }
+  static void test_srlv(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>>b);
+    }
+  }
+
+  static void test_srac(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>VALUE);
+    }
+  }
+  static void test_srac_n(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>(-VALUE));
+    }
+  }
+  static void test_srac_o(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>SHIFT);
+    }
+  }
+  static void test_srac_on(int[] a0, int[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>(-SHIFT));
+    }
+  }
+  static void test_srav(int[] a0, int[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (int)(a1[i]>>b);
+    }
+  }
+
+  static void test_pack2(long[] p2, int[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      long l0 = (long)a1[i*2+0];
+      long l1 = (long)a1[i*2+1];
+      p2[i] = (l1 << 32) | (l0 & 0xFFFFFFFFl);
+    }
+  }
+  static void test_unpack2(int[] a0, long[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      long l = p2[i];
+      a0[i*2+0] = (int)(l & 0xFFFFFFFFl);
+      a0[i*2+1] = (int)(l >> 32);
+    }
+  }
+  static void test_pack2_swap(long[] p2, int[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      long l0 = (long)a1[i*2+0];
+      long l1 = (long)a1[i*2+1];
+      p2[i] = (l0 << 32) | (l1 & 0xFFFFFFFFl);
+    }
+  }
+  static void test_unpack2_swap(int[] a0, long[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      long l = p2[i];
+      a0[i*2+0] = (int)(l >> 32);
+      a0[i*2+1] = (int)(l & 0xFFFFFFFFl);
+    }
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + Long.toHexString(elem) + " != " + Long.toHexString(val));
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/8000805/Test8000805.java b/hotspot/test/compiler/8000805/Test8000805.java
new file mode 100644
index 0000000..bd0b7b4
--- /dev/null
+++ b/hotspot/test/compiler/8000805/Test8000805.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright (c) 2012, 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 8000805
+ * @summary JMM issue: short loads are non-atomic
+ *
+ * @run main/othervm -server -XX:-TieredCompilation -Xcomp -XX:+PrintCompilation -XX:CompileOnly=Test8000805.loadS2LmaskFF,Test8000805.loadS2Lmask16,Test8000805.loadS2Lmask13,Test8000805.loadUS_signExt,Test8000805.loadB2L_mask8 Test8000805
+ */
+
+public class Test8000805 {
+    static long loadS2LmaskFF   (short[] sa) { return sa[0] & 0xFF; }
+    static long loadS2LmaskFF_1 (short[] sa) { return sa[0] & 0xFF; }
+
+    static long loadS2Lmask16   (short[] sa) { return sa[0] & 0xFFFE; }
+    static long loadS2Lmask16_1 (short[] sa) { return sa[0] & 0xFFFE; }
+
+    static long loadS2Lmask13   (short[] sa) { return sa[0] & 0x0FFF; }
+    static long loadS2Lmask13_1 (short[] sa) { return sa[0] & 0x0FFF; }
+
+    static int loadUS_signExt   (char[] ca) { return (ca[0] << 16) >> 16; }
+    static int loadUS_signExt_1 (char[] ca) { return (ca[0] << 16) >> 16; }
+
+    static long loadB2L_mask8   (byte[] ba) { return ba[0] & 0x55; }
+    static long loadB2L_mask8_1 (byte[] ba) { return ba[0] & 0x55; }
+
+    public static void main(String[] args) {
+        for (int i = Byte.MIN_VALUE; i < Byte.MAX_VALUE; i++) {
+            byte[] ba = new byte[]  { (byte) i};
+
+            { long v1 = loadB2L_mask8(ba);
+              long v2 = loadB2L_mask8_1(ba);
+              if (v1 != v2)
+              throw new InternalError(String.format("loadB2L_mask8 failed: %x != %x", v1, v2)); }
+        }
+
+        for (int i = Short.MIN_VALUE; i < Short.MAX_VALUE; i++) {
+            short[] sa = new short[] { (short)i };
+            char[] ca = new char[] { (char)i };
+
+            { long v1 = loadS2LmaskFF(sa);
+              long v2 = loadS2LmaskFF_1(sa);
+              if (v1 != v2)
+              throw new InternalError(String.format("loadS2LmaskFF failed: %x != %x", v1, v2)); }
+
+            { long v1 = loadS2Lmask16(sa);
+              long v2 = loadS2Lmask16_1(sa);
+              if (v1 != v2)
+              throw new InternalError(String.format("loadS2Lmask16 failed: %x != %x", v1, v2)); }
+
+            { long v1 = loadS2Lmask13(sa);
+              long v2 = loadS2Lmask13_1(sa);
+              if (v1 != v2)
+              throw new InternalError(String.format("loadS2Lmask13 failed: %x != %x", v1, v2)); }
+
+            { int v1 = loadUS_signExt(ca);
+              int v2 = loadUS_signExt_1(ca);
+              if (v1 != v2)
+                throw new InternalError(String.format("loadUS_signExt failed: %x != %x", v1, v2)); }
+        }
+
+        System.out.println("TEST PASSED.");
+    }
+}
diff --git a/hotspot/test/compiler/8001183/TestCharVect.java b/hotspot/test/compiler/8001183/TestCharVect.java
new file mode 100644
index 0000000..a6ff1e2
--- /dev/null
+++ b/hotspot/test/compiler/8001183/TestCharVect.java
@@ -0,0 +1,1332 @@
+/*
+ * Copyright (c) 2012, 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 8001183
+ * @summary incorrect results of char vectors right shift operaiton
+ *
+ * @run main/othervm/timeout=400 -Xbatch -Xmx64m TestCharVect
+ */
+
+public class TestCharVect {
+  private static final int ARRLEN = 997;
+  private static final int ITERS  = 11000;
+  private static final int ADD_INIT = Character.MAX_VALUE-500;
+  private static final int BIT_MASK = 0xB731;
+  private static final int VALUE = 7;
+  private static final int SHIFT = 16;
+
+  public static void main(String args[]) {
+    System.out.println("Testing Char vectors");
+    int errn = test();
+    if (errn > 0) {
+      System.err.println("FAILED: " + errn + " errors");
+      System.exit(97);
+    }
+    System.out.println("PASSED");
+  }
+
+  static int test() {
+    char[] a0 = new char[ARRLEN];
+    char[] a1 = new char[ARRLEN];
+    short[] a2 = new short[ARRLEN];
+    short[] a3 = new short[ARRLEN];
+    short[] a4 = new short[ARRLEN];
+     int[] p2 = new  int[ARRLEN/2];
+    long[] p4 = new long[ARRLEN/4];
+    // Initialize
+    int gold_sum = 0;
+    for (int i=0; i<ARRLEN; i++) {
+      char val = (char)(ADD_INIT+i);
+      gold_sum += val;
+      a1[i] = val;
+      a2[i] = VALUE;
+      a3[i] = -VALUE;
+      a4[i] = (short)BIT_MASK;
+    }
+    System.out.println("Warmup");
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+      test_addc(a0, a1);
+      test_addv(a0, a1, (char)VALUE);
+      test_adda(a0, a1, a2);
+      test_subc(a0, a1);
+      test_subv(a0, a1, (char)VALUE);
+      test_suba(a0, a1, a2);
+
+      test_mulc(a0, a1);
+      test_mulv(a0, a1, (char)VALUE);
+      test_mula(a0, a1, a2);
+      test_divc(a0, a1);
+      test_divv(a0, a1, VALUE);
+      test_diva(a0, a1, a2);
+      test_mulc_n(a0, a1);
+      test_mulv(a0, a1, (char)-VALUE);
+      test_mula(a0, a1, a3);
+      test_divc_n(a0, a1);
+      test_divv(a0, a1, -VALUE);
+      test_diva(a0, a1, a3);
+
+      test_andc(a0, a1);
+      test_andv(a0, a1, (short)BIT_MASK);
+      test_anda(a0, a1, a4);
+      test_orc(a0, a1);
+      test_orv(a0, a1, (short)BIT_MASK);
+      test_ora(a0, a1, a4);
+      test_xorc(a0, a1);
+      test_xorv(a0, a1, (short)BIT_MASK);
+      test_xora(a0, a1, a4);
+
+      test_sllc(a0, a1);
+      test_sllv(a0, a1, VALUE);
+      test_srlc(a0, a1);
+      test_srlv(a0, a1, VALUE);
+      test_srac(a0, a1);
+      test_srav(a0, a1, VALUE);
+
+      test_sllc_n(a0, a1);
+      test_sllv(a0, a1, -VALUE);
+      test_srlc_n(a0, a1);
+      test_srlv(a0, a1, -VALUE);
+      test_srac_n(a0, a1);
+      test_srav(a0, a1, -VALUE);
+
+      test_sllc_o(a0, a1);
+      test_sllv(a0, a1, SHIFT);
+      test_srlc_o(a0, a1);
+      test_srlv(a0, a1, SHIFT);
+      test_srac_o(a0, a1);
+      test_srav(a0, a1, SHIFT);
+
+      test_sllc_on(a0, a1);
+      test_sllv(a0, a1, -SHIFT);
+      test_srlc_on(a0, a1);
+      test_srlv(a0, a1, -SHIFT);
+      test_srac_on(a0, a1);
+      test_srav(a0, a1, -SHIFT);
+
+      test_sllc_add(a0, a1);
+      test_sllv_add(a0, a1, ADD_INIT);
+      test_srlc_add(a0, a1);
+      test_srlv_add(a0, a1, ADD_INIT);
+      test_srac_add(a0, a1);
+      test_srav_add(a0, a1, ADD_INIT);
+
+      test_sllc_and(a0, a1);
+      test_sllv_and(a0, a1, BIT_MASK);
+      test_srlc_and(a0, a1);
+      test_srlv_and(a0, a1, BIT_MASK);
+      test_srac_and(a0, a1);
+      test_srav_and(a0, a1, BIT_MASK);
+
+      test_pack2(p2, a1);
+      test_unpack2(a0, p2);
+      test_pack2_swap(p2, a1);
+      test_unpack2_swap(a0, p2);
+      test_pack4(p4, a1);
+      test_unpack4(a0, p4);
+      test_pack4_swap(p4, a1);
+      test_unpack4_swap(a0, p4);
+    }
+    // Test and verify results
+    System.out.println("Verification");
+    int errn = 0;
+    {
+      int sum = test_sum(a1);
+      if (sum != gold_sum) {
+        System.err.println("test_sum:  " + sum + " != " + gold_sum);
+        errn++;
+      }
+
+      test_addc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addc: ", i, a0[i], (char)((char)(ADD_INIT+i)+VALUE));
+      }
+      test_addv(a0, a1, (char)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_addv: ", i, a0[i], (char)((char)(ADD_INIT+i)+VALUE));
+      }
+      test_adda(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_adda: ", i, a0[i], (char)((char)(ADD_INIT+i)+VALUE));
+      }
+
+      test_subc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subc: ", i, a0[i], (char)((char)(ADD_INIT+i)-VALUE));
+      }
+      test_subv(a0, a1, (char)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_subv: ", i, a0[i], (char)((char)(ADD_INIT+i)-VALUE));
+      }
+      test_suba(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_suba: ", i, a0[i], (char)((char)(ADD_INIT+i)-VALUE));
+      }
+
+      test_mulc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc: ", i, a0[i], (char)((char)(ADD_INIT+i)*VALUE));
+      }
+      test_mulv(a0, a1, (char)VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv: ", i, a0[i], (char)((char)(ADD_INIT+i)*VALUE));
+      }
+      test_mula(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula: ", i, a0[i], (char)((char)(ADD_INIT+i)*VALUE));
+      }
+
+      test_divc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc: ", i, a0[i], (char)((char)(ADD_INIT+i)/VALUE));
+      }
+      test_divv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv: ", i, a0[i], (char)((char)(ADD_INIT+i)/VALUE));
+      }
+      test_diva(a0, a1, a2);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva: ", i, a0[i], (char)((char)(ADD_INIT+i)/VALUE));
+      }
+
+      test_mulc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulc_n: ", i, a0[i], (char)((char)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mulv(a0, a1, (char)-VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mulv_n: ", i, a0[i], (char)((char)(ADD_INIT+i)*(-VALUE)));
+      }
+      test_mula(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_mula_n: ", i, a0[i], (char)((char)(ADD_INIT+i)*(-VALUE)));
+      }
+
+      test_divc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divc_n: ", i, a0[i], (char)((char)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_divv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_divv_n: ", i, a0[i], (char)((char)(ADD_INIT+i)/(-VALUE)));
+      }
+      test_diva(a0, a1, a3);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_diva_n: ", i, a0[i], (char)((char)(ADD_INIT+i)/(-VALUE)));
+      }
+
+      test_andc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andc: ", i, a0[i], (char)((char)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_andv(a0, a1, (short)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_andv: ", i, a0[i], (char)((char)(ADD_INIT+i)&BIT_MASK));
+      }
+      test_anda(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_anda: ", i, a0[i], (char)((char)(ADD_INIT+i)&BIT_MASK));
+      }
+
+      test_orc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orc: ", i, a0[i], (char)((char)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_orv(a0, a1, (short)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_orv: ", i, a0[i], (char)((char)(ADD_INIT+i)|BIT_MASK));
+      }
+      test_ora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_ora: ", i, a0[i], (char)((char)(ADD_INIT+i)|BIT_MASK));
+      }
+
+      test_xorc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorc: ", i, a0[i], (char)((char)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xorv(a0, a1, (short)BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xorv: ", i, a0[i], (char)((char)(ADD_INIT+i)^BIT_MASK));
+      }
+      test_xora(a0, a1, a4);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_xora: ", i, a0[i], (char)((char)(ADD_INIT+i)^BIT_MASK));
+      }
+
+      test_sllc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc: ", i, a0[i], (char)((char)(ADD_INIT+i)<<VALUE));
+      }
+      test_sllv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv: ", i, a0[i], (char)((char)(ADD_INIT+i)<<VALUE));
+      }
+
+      test_srlc(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc: ", i, a0[i], (char)((char)(ADD_INIT+i)>>>VALUE));
+      }
+      test_srlv(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv: ", i, a0[i], (char)((char)(ADD_INIT+i)>>>VALUE));
+      }
+
+      test_srac(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac: ", i, a0[i], (char)((char)(ADD_INIT+i)>>VALUE));
+      }
+      test_srav(a0, a1, VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav: ", i, a0[i], (char)((char)(ADD_INIT+i)>>VALUE));
+      }
+
+      test_sllc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_n: ", i, a0[i], (char)((char)(ADD_INIT+i)<<(-VALUE)));
+      }
+      test_sllv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_n: ", i, a0[i], (char)((char)(ADD_INIT+i)<<(-VALUE)));
+      }
+
+      test_srlc_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_n: ", i, a0[i], (char)((char)(ADD_INIT+i)>>>(-VALUE)));
+      }
+      test_srlv(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_n: ", i, a0[i], (char)((char)(ADD_INIT+i)>>>(-VALUE)));
+      }
+
+      test_srac_n(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_n: ", i, a0[i], (char)((char)(ADD_INIT+i)>>(-VALUE)));
+      }
+      test_srav(a0, a1, -VALUE);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_n: ", i, a0[i], (char)((char)(ADD_INIT+i)>>(-VALUE)));
+      }
+
+      test_sllc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_o: ", i, a0[i], (char)((char)(ADD_INIT+i)<<SHIFT));
+      }
+      test_sllv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_o: ", i, a0[i], (char)((char)(ADD_INIT+i)<<SHIFT));
+      }
+
+      test_srlc_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_o: ", i, a0[i], (char)((char)(ADD_INIT+i)>>>SHIFT));
+      }
+      test_srlv(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_o: ", i, a0[i], (char)((char)(ADD_INIT+i)>>>SHIFT));
+      }
+
+      test_srac_o(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_o: ", i, a0[i], (char)((char)(ADD_INIT+i)>>SHIFT));
+      }
+      test_srav(a0, a1, SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_o: ", i, a0[i], (char)((char)(ADD_INIT+i)>>SHIFT));
+      }
+
+      test_sllc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_on: ", i, a0[i], (char)((char)(ADD_INIT+i)<<(-SHIFT)));
+      }
+      test_sllv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_on: ", i, a0[i], (char)((char)(ADD_INIT+i)<<(-SHIFT)));
+      }
+
+      test_srlc_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_on: ", i, a0[i], (char)((char)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+      test_srlv(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_on: ", i, a0[i], (char)((char)(ADD_INIT+i)>>>(-SHIFT)));
+      }
+
+      test_srac_on(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_on: ", i, a0[i], (char)((char)(ADD_INIT+i)>>(-SHIFT)));
+      }
+      test_srav(a0, a1, -SHIFT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_on: ", i, a0[i], (char)((char)(ADD_INIT+i)>>(-SHIFT)));
+      }
+
+      test_sllc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_add: ", i, a0[i], (char)(((char)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+      test_sllv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_add: ", i, a0[i], (char)(((char)(ADD_INIT+i) + ADD_INIT)<<VALUE));
+      }
+
+      test_srlc_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_add: ", i, a0[i], (char)(((char)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+      test_srlv_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_add: ", i, a0[i], (char)(((char)(ADD_INIT+i) + ADD_INIT)>>>VALUE));
+      }
+
+      test_srac_add(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_add: ", i, a0[i], (char)(((char)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+      test_srav_add(a0, a1, ADD_INIT);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_add: ", i, a0[i], (char)(((char)(ADD_INIT+i) + ADD_INIT)>>VALUE));
+      }
+
+      test_sllc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllc_and: ", i, a0[i], (char)(((char)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+      test_sllv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_sllv_and: ", i, a0[i], (char)(((char)(ADD_INIT+i) & BIT_MASK)<<VALUE));
+      }
+
+      test_srlc_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlc_and: ", i, a0[i], (char)(((char)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+      test_srlv_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srlv_and: ", i, a0[i], (char)(((char)(ADD_INIT+i) & BIT_MASK)>>>VALUE));
+      }
+
+      test_srac_and(a0, a1);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srac_and: ", i, a0[i], (char)(((char)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+      test_srav_and(a0, a1, BIT_MASK);
+      for (int i=0; i<ARRLEN; i++) {
+        errn += verify("test_srav_and: ", i, a0[i], (char)(((char)(ADD_INIT+i) & BIT_MASK)>>VALUE));
+      }
+
+      test_pack2(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2: ", i, p2[i], ((int)(ADD_INIT+2*i) & 0xFFFF) | ((int)(ADD_INIT+2*i+1) << 16));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = (char)-1;
+      }
+      test_unpack2(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2: ", i, a0[i], (char)(ADD_INIT+i));
+      }
+
+      test_pack2_swap(p2, a1);
+      for (int i=0; i<ARRLEN/2; i++) {
+        errn += verify("test_pack2_swap: ", i, p2[i], ((int)(ADD_INIT+2*i+1) & 0xFFFF) | ((int)(ADD_INIT+2*i) << 16));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = (char)-1;
+      }
+      test_unpack2_swap(a0, p2);
+      for (int i=0; i<(ARRLEN&(-2)); i++) {
+        errn += verify("test_unpack2_swap: ", i, a0[i], (char)(ADD_INIT+i));
+      }
+
+      test_pack4(p4, a1);
+      for (int i=0; i<ARRLEN/4; i++) {
+        errn += verify("test_pack4: ", i, p4[i],  ((long)(ADD_INIT+4*i+0) & 0xFFFFl) |
+                                                 (((long)(ADD_INIT+4*i+1) & 0xFFFFl) << 16)  |
+                                                 (((long)(ADD_INIT+4*i+2) & 0xFFFFl) << 32)  |
+                                                 (((long)(ADD_INIT+4*i+3) & 0xFFFFl) << 48));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = (char)-1;
+      }
+      test_unpack4(a0, p4);
+      for (int i=0; i<(ARRLEN&(-4)); i++) {
+        errn += verify("test_unpack4: ", i, a0[i], (char)(ADD_INIT+i));
+      }
+
+      test_pack4_swap(p4, a1);
+      for (int i=0; i<ARRLEN/4; i++) {
+        errn += verify("test_pack4_swap: ", i, p4[i],  ((long)(ADD_INIT+4*i+3) & 0xFFFFl) |
+                                                      (((long)(ADD_INIT+4*i+2) & 0xFFFFl) << 16)  |
+                                                      (((long)(ADD_INIT+4*i+1) & 0xFFFFl) << 32)  |
+                                                      (((long)(ADD_INIT+4*i+0) & 0xFFFFl) << 48));
+      }
+      for (int i=0; i<ARRLEN; i++) {
+        a0[i] = (char)-1;
+      }
+      test_unpack4_swap(a0, p4);
+      for (int i=0; i<(ARRLEN&(-4)); i++) {
+        errn += verify("test_unpack4_swap: ", i, a0[i], (char)(ADD_INIT+i));
+      }
+
+    }
+
+    if (errn > 0)
+      return errn;
+
+    System.out.println("Time");
+    long start, end;
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sum(a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sum: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_addv(a0, a1, (char)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_addv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_adda(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_adda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_subv(a0, a1, (char)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_subv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_suba(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_suba: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (char)VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mulv(a0, a1, (char)-VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mulv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_mula(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_mula_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_divv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_divv_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_diva(a0, a1, a3);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_diva_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_andv(a0, a1, (short)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_andv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_anda(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_anda: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_orv(a0, a1, (short)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_orv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_ora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_ora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xorv(a0, a1, (short)BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xorv: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_xora(a0, a1, a4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_xora: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_n(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_n: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -VALUE);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_n: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_o(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_o: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_o: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_on(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_on: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav(a0, a1, -SHIFT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_on: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_add(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_add: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_add(a0, a1, ADD_INIT);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_add: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_sllv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_sllv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlc_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlc_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srlv_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srlv_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srac_and(a0, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srac_and: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_srav_and(a0, a1, BIT_MASK);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_srav_and: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack2(p2, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack2: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack2(a0, p2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack2: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack2_swap(p2, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack2_swap: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack2_swap(a0, p2);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack2_swap: " + (end - start));
+
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack4(p4, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack4: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack4(a0, p4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack4: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_pack4_swap(p4, a1);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_pack4_swap: " + (end - start));
+    start = System.currentTimeMillis();
+    for (int i=0; i<ITERS; i++) {
+      test_unpack4_swap(a0, p4);
+    }
+    end = System.currentTimeMillis();
+    System.out.println("test_unpack4_swap: " + (end - start));
+
+    return errn;
+  }
+
+  static int test_sum(char[] a1) {
+    int sum = 0;
+    for (int i = 0; i < a1.length; i+=1) {
+      sum += a1[i];
+    }
+    return sum;
+  }
+
+  static void test_addc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]+VALUE);
+    }
+  }
+  static void test_addv(char[] a0, char[] a1, char b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]+b);
+    }
+  }
+  static void test_adda(char[] a0, char[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]+a2[i]);
+    }
+  }
+
+  static void test_subc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]-VALUE);
+    }
+  }
+  static void test_subv(char[] a0, char[] a1, char b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]-b);
+    }
+  }
+  static void test_suba(char[] a0, char[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]-a2[i]);
+    }
+  }
+
+  static void test_mulc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]*VALUE);
+    }
+  }
+  static void test_mulc_n(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]*(-VALUE));
+    }
+  }
+  static void test_mulv(char[] a0, char[] a1, char b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]*b);
+    }
+  }
+  static void test_mula(char[] a0, char[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]*a2[i]);
+    }
+  }
+
+  static void test_divc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]/VALUE);
+    }
+  }
+  static void test_divc_n(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]/(-VALUE));
+    }
+  }
+  static void test_divv(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]/b);
+    }
+  }
+  static void test_diva(char[] a0, char[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]/a2[i]);
+    }
+  }
+
+  static void test_andc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]&BIT_MASK);
+    }
+  }
+  static void test_andv(char[] a0, char[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]&b);
+    }
+  }
+  static void test_anda(char[] a0, char[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]&a2[i]);
+    }
+  }
+
+  static void test_orc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]|BIT_MASK);
+    }
+  }
+  static void test_orv(char[] a0, char[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]|b);
+    }
+  }
+  static void test_ora(char[] a0, char[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]|a2[i]);
+    }
+  }
+
+  static void test_xorc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]^BIT_MASK);
+    }
+  }
+  static void test_xorv(char[] a0, char[] a1, short b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]^b);
+    }
+  }
+  static void test_xora(char[] a0, char[] a1, short[] a2) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]^a2[i]);
+    }
+  }
+
+  static void test_sllc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]<<VALUE);
+    }
+  }
+  static void test_sllc_n(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]<<(-VALUE));
+    }
+  }
+  static void test_sllc_o(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]<<SHIFT);
+    }
+  }
+  static void test_sllc_on(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]<<(-SHIFT));
+    }
+  }
+  static void test_sllv(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]<<b);
+    }
+  }
+  static void test_sllc_add(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] + ADD_INIT)<<VALUE);
+    }
+  }
+  static void test_sllv_add(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] + b)<<VALUE);
+    }
+  }
+  static void test_sllc_and(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] & BIT_MASK)<<VALUE);
+    }
+  }
+  static void test_sllv_and(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] & b)<<VALUE);
+    }
+  }
+
+  static void test_srlc(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>>VALUE);
+    }
+  }
+  static void test_srlc_n(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>>(-VALUE));
+    }
+  }
+  static void test_srlc_o(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>>SHIFT);
+    }
+  }
+  static void test_srlc_on(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>>(-SHIFT));
+    }
+  }
+  static void test_srlv(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>>b);
+    }
+  }
+  static void test_srlc_add(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] + ADD_INIT)>>>VALUE);
+    }
+  }
+  static void test_srlv_add(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] + b)>>>VALUE);
+    }
+  }
+  static void test_srlc_and(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] & BIT_MASK)>>>VALUE);
+    }
+  }
+  static void test_srlv_and(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] & b)>>>VALUE);
+    }
+  }
+
+  static void test_srac(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>VALUE);
+    }
+  }
+  static void test_srac_n(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>(-VALUE));
+    }
+  }
+  static void test_srac_o(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>SHIFT);
+    }
+  }
+  static void test_srac_on(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>(-SHIFT));
+    }
+  }
+  static void test_srav(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)(a1[i]>>b);
+    }
+  }
+  static void test_srac_add(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] + ADD_INIT)>>VALUE);
+    }
+  }
+  static void test_srav_add(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] + b)>>VALUE);
+    }
+  }
+  static void test_srac_and(char[] a0, char[] a1) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] & BIT_MASK)>>VALUE);
+    }
+  }
+  static void test_srav_and(char[] a0, char[] a1, int b) {
+    for (int i = 0; i < a0.length; i+=1) {
+      a0[i] = (char)((a1[i] & b)>>VALUE);
+    }
+  }
+
+  static void test_pack2(int[] p2, char[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      int l0 = (int)a1[i*2+0];
+      int l1 = (int)a1[i*2+1];
+      p2[i] = (l1 << 16) | (l0 & 0xFFFF);
+    }
+  }
+  static void test_unpack2(char[] a0, int[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      int l = p2[i];
+      a0[i*2+0] = (char)(l & 0xFFFF);
+      a0[i*2+1] = (char)(l >> 16);
+    }
+  }
+  static void test_pack2_swap(int[] p2, char[] a1) {
+    if (p2.length*2 > a1.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      int l0 = (int)a1[i*2+0];
+      int l1 = (int)a1[i*2+1];
+      p2[i] = (l0 << 16) | (l1 & 0xFFFF);
+    }
+  }
+  static void test_unpack2_swap(char[] a0, int[] p2) {
+    if (p2.length*2 > a0.length) return;
+    for (int i = 0; i < p2.length; i+=1) {
+      int l = p2[i];
+      a0[i*2+0] = (char)(l >> 16);
+      a0[i*2+1] = (char)(l & 0xFFFF);
+    }
+  }
+
+  static void test_pack4(long[] p4, char[] a1) {
+    if (p4.length*4 > a1.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      long l0 = (long)a1[i*4+0];
+      long l1 = (long)a1[i*4+1];
+      long l2 = (long)a1[i*4+2];
+      long l3 = (long)a1[i*4+3];
+      p4[i] = (l0 & 0xFFFFl) |
+             ((l1 & 0xFFFFl) << 16) |
+             ((l2 & 0xFFFFl) << 32) |
+             ((l3 & 0xFFFFl) << 48);
+    }
+  }
+  static void test_unpack4(char[] a0, long[] p4) {
+    if (p4.length*4 > a0.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      long l = p4[i];
+      a0[i*4+0] = (char)(l & 0xFFFFl);
+      a0[i*4+1] = (char)(l >> 16);
+      a0[i*4+2] = (char)(l >> 32);
+      a0[i*4+3] = (char)(l >> 48);
+    }
+  }
+  static void test_pack4_swap(long[] p4, char[] a1) {
+    if (p4.length*4 > a1.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      long l0 = (long)a1[i*4+0];
+      long l1 = (long)a1[i*4+1];
+      long l2 = (long)a1[i*4+2];
+      long l3 = (long)a1[i*4+3];
+      p4[i] = (l3 & 0xFFFFl) |
+             ((l2 & 0xFFFFl) << 16) |
+             ((l1 & 0xFFFFl) << 32) |
+             ((l0 & 0xFFFFl) << 48);
+    }
+  }
+  static void test_unpack4_swap(char[] a0, long[] p4) {
+    if (p4.length*4 > a0.length) return;
+    for (int i = 0; i < p4.length; i+=1) {
+      long l = p4[i];
+      a0[i*4+0] = (char)(l >> 48);
+      a0[i*4+1] = (char)(l >> 32);
+      a0[i*4+2] = (char)(l >> 16);
+      a0[i*4+3] = (char)(l & 0xFFFFl);
+    }
+  }
+
+  static int verify(String text, int i, int elem, int val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + elem + " != " + val);
+      return 1;
+    }
+    return 0;
+  }
+
+  static int verify(String text, int i, long elem, long val) {
+    if (elem != val) {
+      System.err.println(text + "[" + i + "] = " + Long.toHexString(elem) + " != " + Long.toHexString(val));
+      return 1;
+    }
+    return 0;
+  }
+}
diff --git a/hotspot/test/compiler/8002069/Test8002069.java b/hotspot/test/compiler/8002069/Test8002069.java
new file mode 100644
index 0000000..9d11c25
--- /dev/null
+++ b/hotspot/test/compiler/8002069/Test8002069.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 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 8002069
+ * @summary Assert failed in C2: assert(field->edge_count() > 0) failed: sanity
+ *
+ * @run main/othervm -Xmx32m -XX:+IgnoreUnrecognizedVMOptions -Xbatch -XX:CompileCommand=exclude,Test8002069.dummy Test8002069
+ */
+
+abstract class O {
+  int f;
+  public O() { f = 5; }
+  abstract void put(int i);
+  public int foo(int i) {
+    put(i);
+    return i;
+  }
+};
+
+class A extends O {
+  int[] a;
+  public A(int s) {
+    a = new int[s];
+  }
+  public void put(int i) {
+    a[i%a.length] = i;
+  }
+}
+
+class B extends O {
+  int sz;
+  int[] a;
+  public B(int s) {
+    sz = s;
+    a = new int[s];
+  }
+  public void put(int i) {
+    a[i%sz] = i;
+  }
+}
+
+public class Test8002069 {
+  public static void main(String args[]) {
+    int sum = 0;
+    for (int i=0; i<8000; i++) {
+      sum += test1(i);
+    }
+    for (int i=0; i<100000; i++) {
+      sum += test2(i);
+    }
+    System.out.println("PASSED. sum = " + sum);
+  }
+
+  private O o;
+
+  private int foo(int i) {
+    return o.foo(i);
+  }
+  static int test1(int i) {
+    Test8002069 t = new Test8002069();
+    t.o = new A(5);
+    return t.foo(i);
+  }
+  static int test2(int i) {
+    Test8002069 t = new Test8002069();
+    t.o = new B(5);
+    dummy(i);
+    return t.foo(i);
+  }
+
+  static int dummy(int i) {
+    return i*2;
+  }
+}
+
diff --git a/hotspot/test/gc/6941923/test6941923.sh b/hotspot/test/gc/6941923/test6941923.sh
index a9b7721..0c751de 100644
--- a/hotspot/test/gc/6941923/test6941923.sh
+++ b/hotspot/test/gc/6941923/test6941923.sh
@@ -9,12 +9,12 @@
 ## skip on windows
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     NULL=/dev/null
     PS=":"
     FS="/"
     ;;
-  Windows_* )
+  Windows_* | CYGWIN_* )
     echo "Test skipped for Windows"
     exit 0 
     ;;
@@ -30,7 +30,7 @@
   exit 0
 fi
 
-$JAVA_HOME/bin/java -version > $NULL 2>&1
+$JAVA_HOME/bin/java ${TESTVMOPTS} -version > $NULL 2>&1
 
 if [ $? != 0 ]; then
   echo "Wrong JAVA_HOME? JAVA_HOME: $JAVA_HOME"
@@ -119,7 +119,7 @@
 
 options="-Xloggc:$logfile -XX:+UseConcMarkSweepGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseGCLogFileRotation  -XX:NumberOfGCLogFiles=1 -XX:GCLogFileSize=$gclogsize"
 echo "Test gc log rotation in same file, wait for $tts minutes ...."
-$JAVA_HOME/bin/java $options $testname $tts
+$JAVA_HOME/bin/java ${TESTVMOPTS} $options $testname $tts
 if [ $? != 0 ]; then
   echo "$msgfail"
   exit -1
@@ -148,7 +148,7 @@
 numoffiles=3
 options="-Xloggc:$logfile -XX:+UseConcMarkSweepGC -XX:+PrintGC -XX:+PrintGCDetails -XX:+UseGCLogFileRotation  -XX:NumberOfGCLogFiles=$numoffiles -XX:GCLogFileSize=$gclogsize"
 echo "Test gc log rotation in $numoffiles files, wait for $tts minutes ...."
-$JAVA_HOME/bin/java $options $testname $tts
+$JAVA_HOME/bin/java ${TESTVMOPTS} $options $testname $tts
 if [ $? != 0 ]; then
   echo "$msgfail"
   exit -1
diff --git a/hotspot/test/gc/7168848/HumongousAlloc.java b/hotspot/test/gc/7168848/HumongousAlloc.java
new file mode 100644
index 0000000..7ac6074
--- /dev/null
+++ b/hotspot/test/gc/7168848/HumongousAlloc.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2012, 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 Humongous.java
+ * @bug 7168848
+ * @summary G1: humongous object allocations should initiate marking cycles when necessary
+ * @run main/othervm -Xms100m -Xmx100m -XX:+PrintGC -XX:G1HeapRegionSize=1m -XX:+UseG1GC  HumongousAlloc
+ *
+ */
+import java.lang.management.GarbageCollectorMXBean;
+import java.lang.management.ManagementFactory;
+import java.util.List;
+
+public class HumongousAlloc {
+
+    public static byte[] dummy;
+    private static int sleepFreq = 40;
+    private static int sleepTime = 1000;
+    private static double size = 0.75;
+    private static int iterations = 50;
+    private static int MB = 1024 * 1024;
+
+    public static void allocate(int size, int sleepTime, int sleepFreq) throws InterruptedException {
+        System.out.println("Will allocate objects of size: " + size
+                + " bytes and sleep for " + sleepTime
+                + " ms after every " + sleepFreq + "th allocation.");
+        int count = 0;
+        while (count < iterations) {
+            for (int i = 0; i < sleepFreq; i++) {
+                dummy = new byte[size - 16];
+            }
+            Thread.sleep(sleepTime);
+            count++;
+        }
+    }
+
+    public static void main(String[] args) throws InterruptedException {
+        allocate((int) (size * MB), sleepTime, sleepFreq);
+        List<GarbageCollectorMXBean> collectors = ManagementFactory.getGarbageCollectorMXBeans();
+        for (GarbageCollectorMXBean collector : collectors) {
+            if (collector.getName().contains("G1 Old")) {
+               long count = collector.getCollectionCount();
+                if (count > 0) {
+                    throw new RuntimeException("Failed: FullGCs should not have happened. The number of FullGC run is " + count);
+                }
+                else {
+                    System.out.println("Passed.");
+                }
+            }
+        }
+    }
+}
+
diff --git a/hotspot/test/runtime/6294277/SourceDebugExtension.java b/hotspot/test/runtime/6294277/SourceDebugExtension.java
new file mode 100644
index 0000000..e8cc8a8
--- /dev/null
+++ b/hotspot/test/runtime/6294277/SourceDebugExtension.java
@@ -0,0 +1,136 @@
+/*
+ * Copyright (c) 2012, 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 6294277
+ * @summary java -Xdebug crashes on SourceDebugExtension attribute larger than 64K
+ * @run main/othervm -Xdebug -Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n SourceDebugExtension
+ */
+import java.io.*;
+
+public class SourceDebugExtension extends ClassLoader
+{
+    static final int attrSize = 68000;
+    static byte[] header = {
+(byte)0xca, (byte)0xfe, (byte)0xba, (byte)0xbe, (byte)0x00, (byte)0x00, (byte)0x00,
+(byte)0x32, (byte)0x00, (byte)0x1e, (byte)0x0a, (byte)0x00, (byte)0x06, (byte)0x00,
+(byte)0x0f, (byte)0x09, (byte)0x00, (byte)0x10, (byte)0x00, (byte)0x11, (byte)0x08,
+(byte)0x00, (byte)0x12, (byte)0x0a, (byte)0x00, (byte)0x13, (byte)0x00, (byte)0x14,
+(byte)0x07, (byte)0x00, (byte)0x15, (byte)0x07, (byte)0x00, (byte)0x16, (byte)0x01,
+(byte)0x00, (byte)0x06, (byte)0x3c, (byte)0x69, (byte)0x6e, (byte)0x69, (byte)0x74,
+(byte)0x3e, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x28, (byte)0x29, (byte)0x56,
+(byte)0x01, (byte)0x00, (byte)0x04, (byte)0x43, (byte)0x6f, (byte)0x64, (byte)0x65,
+(byte)0x01, (byte)0x00, (byte)0x0f, (byte)0x4c, (byte)0x69, (byte)0x6e, (byte)0x65,
+(byte)0x4e, (byte)0x75, (byte)0x6d, (byte)0x62, (byte)0x65, (byte)0x72, (byte)0x54,
+(byte)0x61, (byte)0x62, (byte)0x6c, (byte)0x65, (byte)0x01, (byte)0x00, (byte)0x04,
+(byte)0x6d, (byte)0x61, (byte)0x69, (byte)0x6e, (byte)0x01, (byte)0x00, (byte)0x16,
+(byte)0x28, (byte)0x5b, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61,
+(byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x53,
+(byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67, (byte)0x3b, (byte)0x29,
+(byte)0x56, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x53, (byte)0x6f, (byte)0x75,
+(byte)0x72, (byte)0x63, (byte)0x65, (byte)0x46, (byte)0x69, (byte)0x6c, (byte)0x65,
+(byte)0x01, (byte)0x00, (byte)0x0d, (byte)0x54, (byte)0x65, (byte)0x73, (byte)0x74,
+(byte)0x50, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x2e, (byte)0x6a, (byte)0x61,
+(byte)0x76, (byte)0x61, (byte)0x0c, (byte)0x00, (byte)0x07, (byte)0x00, (byte)0x08,
+(byte)0x07, (byte)0x00, (byte)0x17, (byte)0x0c, (byte)0x00, (byte)0x18, (byte)0x00,
+(byte)0x19, (byte)0x01, (byte)0x00, (byte)0x34, (byte)0x54, (byte)0x65, (byte)0x73,
+(byte)0x74, (byte)0x20, (byte)0x70, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x72,
+(byte)0x61, (byte)0x6d, (byte)0x20, (byte)0x66, (byte)0x6f, (byte)0x72, (byte)0x20,
+(byte)0x62, (byte)0x69, (byte)0x67, (byte)0x20, (byte)0x53, (byte)0x6f, (byte)0x75,
+(byte)0x72, (byte)0x63, (byte)0x65, (byte)0x44, (byte)0x65, (byte)0x62, (byte)0x75,
+(byte)0x67, (byte)0x45, (byte)0x78, (byte)0x74, (byte)0x65, (byte)0x6e, (byte)0x73,
+(byte)0x69, (byte)0x6f, (byte)0x6e, (byte)0x20, (byte)0x61, (byte)0x74, (byte)0x74,
+(byte)0x72, (byte)0x69, (byte)0x62, (byte)0x75, (byte)0x74, (byte)0x65, (byte)0x73,
+(byte)0x07, (byte)0x00, (byte)0x1a, (byte)0x0c, (byte)0x00, (byte)0x1b, (byte)0x00,
+(byte)0x1c, (byte)0x01, (byte)0x00, (byte)0x08, (byte)0x54, (byte)0x65, (byte)0x73,
+(byte)0x74, (byte)0x50, (byte)0x72, (byte)0x6f, (byte)0x67, (byte)0x01, (byte)0x00,
+(byte)0x10, (byte)0x6a, (byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c,
+(byte)0x61, (byte)0x6e, (byte)0x67, (byte)0x2f, (byte)0x4f, (byte)0x62, (byte)0x6a,
+(byte)0x65, (byte)0x63, (byte)0x74, (byte)0x01, (byte)0x00, (byte)0x10, (byte)0x6a,
+(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e,
+(byte)0x67, (byte)0x2f, (byte)0x53, (byte)0x79, (byte)0x73, (byte)0x74, (byte)0x65,
+(byte)0x6d, (byte)0x01, (byte)0x00, (byte)0x03, (byte)0x6f, (byte)0x75, (byte)0x74,
+(byte)0x01, (byte)0x00, (byte)0x15, (byte)0x4c, (byte)0x6a, (byte)0x61, (byte)0x76,
+(byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, (byte)0x2f, (byte)0x50, (byte)0x72,
+(byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x65,
+(byte)0x61, (byte)0x6d, (byte)0x3b, (byte)0x01, (byte)0x00, (byte)0x13, (byte)0x6a,
+(byte)0x61, (byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x69, (byte)0x6f, (byte)0x2f,
+(byte)0x50, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x53, (byte)0x74,
+(byte)0x72, (byte)0x65, (byte)0x61, (byte)0x6d, (byte)0x01, (byte)0x00, (byte)0x07,
+(byte)0x70, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x74, (byte)0x6c, (byte)0x6e,
+(byte)0x01, (byte)0x00, (byte)0x15, (byte)0x28, (byte)0x4c, (byte)0x6a, (byte)0x61,
+(byte)0x76, (byte)0x61, (byte)0x2f, (byte)0x6c, (byte)0x61, (byte)0x6e, (byte)0x67,
+(byte)0x2f, (byte)0x53, (byte)0x74, (byte)0x72, (byte)0x69, (byte)0x6e, (byte)0x67,
+(byte)0x3b, (byte)0x29, (byte)0x56, (byte)0x01, (byte)0x00, (byte)0x14, (byte)0x53,
+(byte)0x6f, (byte)0x75, (byte)0x72, (byte)0x63, (byte)0x65, (byte)0x44, (byte)0x65,
+(byte)0x62, (byte)0x75, (byte)0x67, (byte)0x45, (byte)0x78, (byte)0x74, (byte)0x65,
+(byte)0x6e, (byte)0x73, (byte)0x69, (byte)0x6f, (byte)0x6e, (byte)0x00, (byte)0x21,
+(byte)0x00, (byte)0x05, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x07,
+(byte)0x00, (byte)0x08, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x01,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x05, (byte)0x2a, (byte)0xb7, (byte)0x00,
+(byte)0x01, (byte)0xb1, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00,
+(byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x06, (byte)0x00, (byte)0x01,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09, (byte)0x00,
+(byte)0x0b, (byte)0x00, (byte)0x0c, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x09,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x25, (byte)0x00, (byte)0x02, (byte)0x00,
+(byte)0x01, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x09, (byte)0xb2, (byte)0x00,
+(byte)0x02, (byte)0x12, (byte)0x03, (byte)0xb6, (byte)0x00, (byte)0x04, (byte)0xb1,
+(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x01, (byte)0x00, (byte)0x0a, (byte)0x00,
+(byte)0x00, (byte)0x00, (byte)0x0a, (byte)0x00, (byte)0x02, (byte)0x00, (byte)0x00,
+(byte)0x00, (byte)0x03, (byte)0x00, (byte)0x08, (byte)0x00, (byte)0x04, (byte)0x00,
+(byte)0x02, (byte)0x00, (byte)0x0d, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x02,
+(byte)0x00, (byte)0x0e, (byte)0x00, (byte)0x1d, (byte)0x00, (byte)0x01, (byte)0x09,
+(byte)0xa0
+  };
+
+    public static void main(String[] args) throws Exception
+    {
+        try {
+            SourceDebugExtension loader = new SourceDebugExtension();
+            /* The test program creates a class file from the header
+             * stored above and adding the content of a SourceDebugExtension
+             * attribute made of the character 0x02 repeated 68000 times.
+             * This attribute doesn't follow the syntax specified in JSR 45
+             * but it's fine because this test just checks that the JVM is
+             * able to load a class file with a SourceDebugExtension
+             * attribute bigger than 64KB. The JVM doesn't try to
+             * parse the content of the attribute, this work is performed
+             * by the SA or external tools.
+             */
+            byte[] buf = new byte[header.length + attrSize];
+            for(int i=0; i<header.length; i++) {
+                buf[i] = header[i];
+            }
+            for(int i=0; i<attrSize; i++) {
+                buf[header.length+i] = (byte)0x02;
+            }
+            Class c = loader.defineClass("TestProg", buf, 0, buf.length);
+            System.out.println("Test PASSES");
+        } catch(Exception e) {
+            System.out.println("Test FAILS");
+        }
+    }
+}
diff --git a/hotspot/test/runtime/6626217/Test6626217.sh b/hotspot/test/runtime/6626217/Test6626217.sh
index 88c3c5b..a8c8a23 100644
--- a/hotspot/test/runtime/6626217/Test6626217.sh
+++ b/hotspot/test/runtime/6626217/Test6626217.sh
@@ -1,5 +1,5 @@
 # 
-#  Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+#  Copyright (c) 1998, 2012, 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,24 +46,16 @@
   exit 1
 fi
 
-BIT_FLAG=""
-
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     NULL=/dev/null
     PS=":"
     FS="/"
     RM=/bin/rm
     CP=/bin/cp
     MV=/bin/mv
-    ## for solaris, linux it's HOME
-    FILE_LOCATION=$HOME
-    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ]
-    then
-        BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT`
-    fi
     ;;
   Windows_* )
     NULL=NUL
@@ -73,6 +65,14 @@
     CP=cp
     MV=mv
     ;;
+  CYGWIN_* )
+    NULL=/dev/null
+    PS=";"
+    FS="/"
+    RM=rm
+    CP=cp
+    MV=mv
+    ;;
   * )
     echo "Unrecognized system!"
     exit 1;
@@ -87,7 +87,7 @@
 JAVA=${TESTJAVA}${FS}bin${FS}java
 JAVAC=${TESTJAVA}${FS}bin${FS}javac
 
-${JAVA} ${BIT_FLAG} -version
+${JAVA} ${TESTVMOPTS} -version
 
 # Current directory is scratch directory, copy all the test source there
 # (for the subsequent moves to work).
@@ -113,7 +113,7 @@
 ${MV} many_loader.impl1 many_loader.class
 ${RM} many_loader.java
 
-${JAVA} ${BIT_FLAG} -Xverify -Xint -cp . bug_21227 >test.out 2>&1
+${JAVA} ${TESTVMOPTS} -Xverify -Xint -cp . bug_21227 >test.out 2>&1
 grep "loader constraint" test.out
 exit $?
 
diff --git a/hotspot/test/runtime/6878713/Test6878713.sh b/hotspot/test/runtime/6878713/Test6878713.sh
index 54b0114..a452ad5 100644
--- a/hotspot/test/runtime/6878713/Test6878713.sh
+++ b/hotspot/test/runtime/6878713/Test6878713.sh
@@ -25,27 +25,24 @@
   exit 1
 fi
 
-BIT_FLAG=""
-
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     NULL=/dev/null
     PS=":"
     FS="/"
-    ## for solaris, linux it's HOME
-    FILE_LOCATION=$HOME
-    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ]
-    then
-        BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT | grep -v '^#'`
-    fi
     ;;
   Windows_* )
     NULL=NUL
     PS=";"
     FS="\\"
     ;;
+  CYGWIN_* )
+    NULL=/dev/null
+    PS=";"
+    FS="/"
+    ;;
   * )
     echo "Unrecognized system!"
     exit 1;
@@ -57,11 +54,11 @@
 
 THIS_DIR=`pwd`
 
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -version
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version
 
 ${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar
 
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} OOMCrashClass1960_2 > test.out 2>&1
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass1960_2 > test.out 2>&1
 
 if [ -s core -o -s "hs_*.log" ]
 then
diff --git a/hotspot/test/runtime/6929067/Test6929067.sh b/hotspot/test/runtime/6929067/Test6929067.sh
index 8f9e13a..c08aa6b 100644
--- a/hotspot/test/runtime/6929067/Test6929067.sh
+++ b/hotspot/test/runtime/6929067/Test6929067.sh
@@ -19,8 +19,6 @@
   echo "If this is incorrect, try setting the variable manually."
 fi
 
-BIT_FLAG=""
-
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
@@ -29,20 +27,25 @@
     PS=":"
     FS="/"
     ;;
-  SunOS | Windows_* | *BSD)
-    NULL=NUL
-    PS=";"
-    FS="\\"
+  * )
     echo "Test passed; only valid for Linux"
     exit 0;
     ;;
-  * )
-    echo "Unrecognized system!"
-    exit 1;
-    ;;
 esac
 
-LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/i386/client:/usr/openwin/lib:/usr/dt/lib:/usr/lib:$LD_LIBRARY_PATH
+# Choose arch: i386 or amd64 (test is Linux-specific)
+# Cannot simply look at TESTVMOPTS as -d64 is not
+# passed if there is only a 64-bit JVM available.
+
+${TESTJAVA}/bin/java ${TESTVMOPTS} -version 2>1 | grep "64-Bit" >/dev/null
+if [ "$?" = "0" ]
+then
+  ARCH=amd64
+else
+  ARCH=i386
+fi
+
+LD_LIBRARY_PATH=.:${TESTJAVA}/jre/lib/${ARCH}/client:/usr/openwin/lib:/usr/dt/lib:/usr/lib:$LD_LIBRARY_PATH
 export LD_LIBRARY_PATH
 
 THIS_DIR=`pwd`
@@ -51,10 +54,10 @@
 cp ${TESTSRC}${FS}T.java ${THIS_DIR}
 
 
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -fullversion
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion
 
 ${TESTJAVA}${FS}bin${FS}javac T.java
 
-gcc -o invoke -I${TESTJAVA}/include -I${TESTJAVA}/include/linux invoke.c ${TESTJAVA}/jre/lib/i386/client/libjvm.so
+gcc -o invoke -I${TESTJAVA}/include -I${TESTJAVA}/include/linux invoke.c ${TESTJAVA}/jre/lib/${ARCH}/client/libjvm.so
 ./invoke
 exit $?
diff --git a/hotspot/test/runtime/7020373/Test7020373.sh b/hotspot/test/runtime/7020373/Test7020373.sh
index 7f6b03c..83e7f4c 100644
--- a/hotspot/test/runtime/7020373/Test7020373.sh
+++ b/hotspot/test/runtime/7020373/Test7020373.sh
@@ -2,10 +2,10 @@
 
 ##
 ## @test
-## @bug 7020373 7055247
+## @bug 7020373 7055247 7053586 7185550
 ## @key cte_test
 ## @summary JSR rewriting can overflow memory address size variables
-## @ignore Ignore it until 7053586 fixed
+## @ignore Ignore it as 7053586 test uses lots of memory. See bug report for detail.
 ## @run shell Test7020373.sh
 ##
 
@@ -27,27 +27,24 @@
   exit 1
 fi
 
-BIT_FLAG=""
-
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     NULL=/dev/null
     PS=":"
     FS="/"
-    ## for solaris, linux it's HOME
-    FILE_LOCATION=$HOME
-    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ]
-    then
-        BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT | grep -v '^#'`
-    fi
     ;;
   Windows_* )
     NULL=NUL
     PS=";"
     FS="\\"
     ;;
+  CYGWIN_* )
+    NULL=/dev/null
+    PS=";"
+    FS="/"
+    ;;
   * )
     echo "Unrecognized system!"
     exit 1;
@@ -59,11 +56,11 @@
 
 THIS_DIR=`pwd`
 
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} -version
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -version
 
 ${TESTJAVA}${FS}bin${FS}jar xvf ${TESTSRC}${FS}testcase.jar
 
-${TESTJAVA}${FS}bin${FS}java ${BIT_FLAG} OOMCrashClass4000_1 > test.out 2>&1
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} OOMCrashClass4000_1 > test.out 2>&1
 
 cat test.out
 
@@ -74,7 +71,7 @@
     echo "Test Failed"
     exit 1
 else
-    grep "java.lang.LinkageError" test.out
+    egrep "java.lang.LinkageError|java.lang.NoSuchMethodError|Main method not found in class OOMCrashClass4000_1|insufficient memory" test.out
     if [ $? = 0 ]
     then
         echo "Test Passed"
diff --git a/hotspot/test/runtime/7051189/Xchecksig.sh b/hotspot/test/runtime/7051189/Xchecksig.sh
index 410cdb9..f3eabce 100644
--- a/hotspot/test/runtime/7051189/Xchecksig.sh
+++ b/hotspot/test/runtime/7051189/Xchecksig.sh
@@ -1,5 +1,5 @@
 # 
-#  Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+#  Copyright (c) 2011, 2012, 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
@@ -41,20 +41,12 @@
 fi
 
 
-BIT_FLAG=""
-
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     FS="/"
-    ## for solaris, linux it's HOME
-    FILE_LOCATION=$HOME
-    if [ -f ${FILE_LOCATION}${FS}JDK64BIT -a ${OS} = "SunOS" ]
-    then
-        BIT_FLAG=`cat ${FILE_LOCATION}${FS}JDK64BIT`
-    fi
     ;;
-  Windows_* )
+  Windows_* | CYGWIN_* )
     printf "Not testing libjsig.so on Windows. PASSED.\n "
     exit 0
     ;;
@@ -69,20 +61,16 @@
 
 # LD_PRELOAD arch needs to match the binary we run, so run the java
 # 64-bit binary directly if we are testing 64-bit (bin/ARCH/java).
-
-# However JPRT runs: .../solaris_x64_5.10-debug/bin/java
-# ..which is 32-bit, when it has built the 64-bit version to test.
-#
-# How does this script know we are meant to run the 64-bit version?
-# Can check for the path of the binary containing "x64" on Solaris.
+# Check if TESTVMOPS contains -d64, but cannot use 
+# java ${TESTVMOPS} to run "java -d64"  with LD_PRELOAD.
 
 if [ ${OS} -eq "SunOS" ]
 then
-  printf  "SunOS test JAVA=${JAVA}"
-  printf ${JAVA} | grep x64 > /dev/null
+  printf  "SunOS test TESTVMOPTS = ${TESTVMOPTS}"
+  printf ${TESTVMOPTS} | grep d64 > /dev/null
   if [ $? -eq 0 ]
   then
-    printf "SunOS x64 test, forcing -d64\n"
+    printf "SunOS 64-bit test\n"
     BIT_FLAG=-d64
   fi
 fi
@@ -127,20 +115,19 @@
   printf "Skipping test: libjsig missing for given architecture: ${LIBJSIG}\n"
   exit 0
 fi
-# Use java -version to test, java version info appeas on stderr,
+# Use java -version to test, java version info appears on stderr,
 # the libjsig message we are removing appears on stdout.
 
 # grep returns zero meaning found, non-zero means not found:
 
-LD_PRELOAD=${LIBJSIG} ${JAVA} ${BIT_FLAG} -Xcheck:jni -version 2>&1  | grep "libjsig is activated"
-
+LD_PRELOAD=${LIBJSIG} ${JAVA} ${TESTVMOPTS} -Xcheck:jni -version 2>&1  | grep "libjsig is activated"
 if [ $? -eq 0 ]; then
   printf "Failed: -Xcheck:jni prints message when libjsig.so is loaded.\n"
   exit 1
 fi
 
 
-LD_PRELOAD=${LIBJSIG} ${JAVA} ${BIT_FLAG} -Xcheck:jni -verbose:jni -version 2>&1 | grep "libjsig is activated"
+LD_PRELOAD=${LIBJSIG} ${JAVA} ${TESTVMOPTS} -Xcheck:jni -verbose:jni -version 2>&1 | grep "libjsig is activated"
 if [ $? != 0 ]; then
   printf "Failed: -Xcheck:jni does not print message when libjsig.so is loaded and -verbose:jni is set.\n"
   exit 1
diff --git a/hotspot/test/runtime/7110720/Test7110720.sh b/hotspot/test/runtime/7110720/Test7110720.sh
index c90c054..0788cb5 100644
--- a/hotspot/test/runtime/7110720/Test7110720.sh
+++ b/hotspot/test/runtime/7110720/Test7110720.sh
@@ -37,7 +37,7 @@
 # set platform-dependent variables
 OS=`uname -s`
 case "$OS" in
-  SunOS | Linux )
+  SunOS | Linux | Darwin )
     FS="/"
     RM=/bin/rm
     CP=/bin/cp
@@ -55,6 +55,12 @@
     CP=cp
     MV=mv
     ;;
+  CYGWIN_* )
+    FS="/"
+    RM=rm
+    CP=cp
+    MV=mv
+    ;;
   * )
     echo "Unrecognized system!"
     exit 1;
diff --git a/hotspot/test/runtime/7116786/Test7116786.java b/hotspot/test/runtime/7116786/Test7116786.java
new file mode 100644
index 0000000..8c137ec
--- /dev/null
+++ b/hotspot/test/runtime/7116786/Test7116786.java
@@ -0,0 +1,486 @@
+/*
+ * Copyright (c) 2012, 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 Test7116786
+ * @summary verify that VerifyError messages are as expected
+ * @library testcases.jar
+ * @run main/othervm -Xverify:all Test7116786
+ */
+
+
+/**
+ * This class contains information regarding when a VerifyError is thrown
+ * in the verifier.  Most of the data is informational-only, and can be
+ * used to track down where and why VerifyErrors are thrown.  As such it
+ * is possible the information may go out-of-date.
+ *
+ * The only fields used for the purpose of testing is the 'caseName' and
+ * the 'message'.  The 'caseName' corresponds to a classfile which exhibits
+ * the VerifyError, and the 'message' is a regular expression which we expect
+ * to match the verify error message.  If the 'message' doesn't match what
+ * we expect, it warrents investigation to see if we are still triggering
+ * the VerifyError that we expect.  It could simply just be that the message
+ * changed, which is fine.
+ *
+ * Some cases are not testable, either because the code is probably unreachable
+ * or the test classfile would be too onerous to create.  These cases are
+ * marked with 'testable' == false, and the test runner will skip them.
+ */
+class Case {
+    private String caseName;    // Name of the case
+    private String file;        // Source file where VerifyError is thrown
+    private String location;    // enclosing function or switch case
+    private String description; // What causes this VerifyError
+    private String message;     // The VerifyError message used.
+
+    private boolean testable;   // Whether this case is testable or not.
+
+    public Case(String caseName, String file, boolean testable,
+                String location, String description, String message) {
+        this.caseName = caseName;
+        this.file = file;
+        this.testable = testable;
+        this.location = location;
+        this.description = description;
+        this.message = message;
+    }
+
+    String getCaseName() { return this.caseName; }
+    String getFile() { return this.file; }
+    String getLocation() { return this.location; }
+    String getDescription() { return this.description; }
+    String getMessage() { return this.message; }
+
+    boolean isTestable() { return this.testable; }
+}
+
+/**
+ * These are the locations in the source code where VerifyErrors are thrown
+ * as of today, 2012/07/18.  These may change as the verification code is
+ * modified, which is ok.  This test is trying to provide coverage for all
+ * VerifyErrors (just to make sure there are no crashes) and it's probably
+ * not necessary to update it every time the VM changes.
+ */
+class VerifyErrorCases {
+    public static final Case[] cases = {
+
+        new Case("case00", "stackMapFrame.cpp", true, "pop_stack_ex",
+                 "stack underflow",
+                 "Operand stack underflow"),
+
+        new Case("case01", "stackMapFrame.cpp", true, "pop_stack_ex",
+                 "stack pop not assignable to expected",
+                 "Bad type on operand stack"),
+
+        new Case("case02", "stackMapFrame.cpp", true, "get_local",
+                 "local index out-of-bounds",
+                 "Local variable table overflow"),
+
+        new Case("case03", "stackMapFrame.cpp", true, "get_local",
+                 "local not assignable to expected",
+                 "Bad local variable type"),
+
+        new Case("case04", "stackMapFrame.cpp", true, "get_local_2",
+                 "local index out-of-bounds [type2]",
+                 "get long/double overflows locals"),
+
+        new Case("case05", "stackMapFrame.cpp", true, "get_local_2",
+                 "local not assignabled to expected [type2]",
+                 "Bad local variable type"),
+
+        /* Unreachable: Can't split long/double on stack */
+        new Case("case06", "stackMapFrame.cpp", false, "get_local_2",
+                 "local second-word not assignabled to expected",
+                 "Bad local variable type"),
+
+        new Case("case07", "stackMapFrame.cpp", true, "set_local",
+                 "local index out-of-bounds",
+                 "Local variable table overflow"),
+
+        new Case("case08", "stackMapFrame.cpp", true, "set_local_2",
+                 "local index out-of-bounds [type2]",
+                 "Local variable table overflow"),
+
+        new Case("case09", "stackMapFrame.hpp", true, "push_stack",
+                 "stack overflow",
+                 "Operand stack overflow"),
+
+        new Case("case10", "stackMapFrame.hpp", true, "push_stack_2",
+                 "stack overflow [type2]",
+                 "Operand stack overflow"),
+
+        new Case("case11", "stackMapFrame.hpp", true, "pop_stack",
+                 "stack underflow",
+                 "Operand stack underflow"),
+
+        new Case("case12", "stackMapTable.cpp", true, "StackMapTable ctor",
+                 "stackmap offset beyond code size",
+                 "StackMapTable error: bad offset"),
+
+        new Case("case13", "stackMapTable.cpp", true, "match_stackmap",
+                 "no stackmap frame at expected location",
+                 "Expecting a stackmap frame at branch target "),
+
+        new Case("case14", "stackMapTable.cpp", true, "check_jump_target",
+                 "no stackmap frame at jump location or bad jump",
+                 "Inconsistent stackmap frames at branch target "),
+
+        new Case("case15", "stackMapTable.cpp", true, "check_new_object",
+                 "backward jump with uninit",
+                 "Uninitialized object exists on backward branch "),
+
+        /* Unreachable: wide instructions verified during bytecode analysis */
+        new Case("case16", "verifier.cpp", false, "loop header",
+                 "bad op in wide instruction",
+                 "Bad wide instruction"),
+
+        new Case("case17", "verifier.cpp", true, "case iaload",
+                 "TOS not X array",
+                 "Bad type on operand stack in iaload"),
+
+        new Case("case18", "verifier.cpp", true, "case baload",
+                 "TOS not X array",
+                 "Bad type on operand stack in baload"),
+
+        new Case("case19", "verifier.cpp", true, "case caload",
+                 "TOS not X array",
+                 "Bad type on operand stack in caload"),
+
+        new Case("case20", "verifier.cpp", true, "case saload",
+                 "TOS not X array",
+                 "Bad type on operand stack in saload"),
+
+        new Case("case21", "verifier.cpp", true, "case laload",
+                 "TOS not X array",
+                 "Bad type on operand stack in laload"),
+
+        new Case("case22", "verifier.cpp", true, "case faload",
+                 "TOS not X array",
+                 "Bad type on operand stack in faload"),
+
+        new Case("case23", "verifier.cpp", true, "case daload",
+                 "TOS not X array",
+                 "Bad type on operand stack in daload"),
+
+        new Case("case24", "verifier.cpp", true, "case aaload",
+                 "TOS not X array",
+                 "Bad type on operand stack in aaload"),
+
+        new Case("case25", "verifier.cpp", true, "case iastore",
+                 "TOS not int array",
+                 "Bad type on operand stack in iastore"),
+
+        new Case("case26", "verifier.cpp", true, "case bastore",
+                 "TOS not byte array",
+                 "Bad type on operand stack in bastore"),
+
+        new Case("case27", "verifier.cpp", true, "case castore",
+                 "TOS not char array",
+                 "Bad type on operand stack in castore"),
+
+        new Case("case28", "verifier.cpp", true, "case sastore",
+                 "TOS not short array",
+                 "Bad type on operand stack in sastore"),
+
+        new Case("case29", "verifier.cpp", true, "case lastore",
+                 "TOS not long array",
+                 "Bad type on operand stack in lastore"),
+
+        new Case("case30", "verifier.cpp", true, "case fastore",
+                 "TOS not float array",
+                 "Bad type on operand stack in fastore"),
+
+        new Case("case31", "verifier.cpp", true, "case dastore",
+                 "TOS not double array",
+                 "Bad type on operand stack in dastore"),
+
+        new Case("case32", "verifier.cpp", true, "case aastore",
+                 "TOS not object array",
+                 "Bad type on operand stack in aastore"),
+
+        /* Unreachable: In order to hit this case, we would need a
+         * category2_1st at TOS which is not possible. */
+        new Case("case33", "verifier.cpp", false, "case pop2",
+                 "TOS is category2_1st (would split)",
+                 "Bad type on operand stack in pop2"),
+
+        /* Unreachable: In order to hit this case, we would need a
+         * category2_1st at stack depth 2 with category_1 on TOS which is not
+         * possible. */
+        new Case("case34", "verifier.cpp", false, "case dup_x2",
+                 "TOS-1 is category2_1st (would split)",
+                 "Bad type on operand stack in dup_x2"),
+
+        /* Unreachable: In order to hit this case, we would need a
+         * category2_1st at TOS which is not possible. */
+        new Case("case35", "verifier.cpp", false, "case dup2",
+                 "TOS-1 is category2_1st (would split)",
+                 "Bad type on operand stack in dup2"),
+
+        /* Unreachable: In order to hit this case, we would need a
+         * category2_1st at TOS which is not possible. */
+        new Case("case36", "verifier.cpp", false, "case dup2_x1",
+                 "TOS-1 is category2_1st (would split)",
+                 "Bad type on operand stack in dup2_x1"),
+
+        /* Unreachable: In order to hit this case, we would need a
+         * category2_1st at TOS which is not possible. */
+        new Case("case37", "verifier.cpp", false, "case dup2_x2",
+                 "TOS-1 is category2_1st (would split)",
+                 "Bad type on operand stack in dup2_x2"),
+
+        /* Unreachable: In order to hit this case, we would need a
+         * category2_1st at stack depth 3 with either 2 category_1 or 1
+         * category_2 on TOS, which is not possible. */
+        new Case("case38", "verifier.cpp", false, "case dup2_x2",
+                 "TOS-3 is category2_1st (would split)",
+                 "Bad type on operand stack in dup2_x2"),
+
+        new Case("case39", "verifier.cpp", true, "case return",
+                 "return type of method is not void",
+                 "Method expects a return value"),
+
+        new Case("case40", "verifier.cpp", true, "case return",
+                 "return with uninitialized this ",
+                 "Constructor must call super() or this() before return"),
+
+        new Case("case41", "verifier.cpp", true, "case new",
+                 "cp index not a class type",
+                 "Illegal new instruction"),
+
+        new Case("case42", "verifier.cpp", true, "case arraylength",
+                 "TOS is not an array",
+                 "Bad type on operand stack in arraylength"),
+
+        new Case("case43", "verifier.cpp", true, "case multianewarray",
+                 "CP index does not refer to array type",
+                 "Illegal constant pool index in multianewarray instruction"),
+
+        new Case("case44", "verifier.cpp", true, "case multianewarray",
+                 "Bad dimension (<1) or does not match CP signature",
+                 "Illegal dimension in multianewarray instruction: "),
+
+        new Case("case45", "verifier.cpp", true, "case default",
+                 "Unrecognized bytecode",
+                 "Bad instruction: "),
+
+        new Case("case46", "verifier.cpp", true, "loop end",
+                 "control flow falls off method",
+                 "Control flow falls through code end"),
+
+        new Case("case47", "verifier.cpp", true, "generate_code_data",
+                 "illegal bytecode via RawBytecodeStream (breakpoint)",
+                 "Bad instruction"),
+
+        new Case("case48", "verifier.cpp", true, "generate_code_data",
+                 "illegal bytecode via RawBytecodeStream (other illegal)",
+                 "Bad instruction"),
+
+        new Case("case49", "verifier.cpp", true,
+                 "verify_exception_handler_table",
+                 "catch_type is not throwable",
+                 "Catch type is not a subclass of Throwable in " +
+                 "exception handler "),
+
+        new Case("case50", "verifier.cpp", true, "verify_stackmap_table",
+                 "missing a stack map frame @ target location (mid table)",
+                 "Expecting a stack map frame"),
+
+        new Case("case51", "verifier.cpp", true, "verify_stackmap_table",
+                 "stack map does not match?",
+                 "Instruction type does not match stack map"),
+
+        new Case("case52", "verifier.cpp", true, "verify_stackmap_table",
+                 "missing a stack map frame @ target location (end of table)",
+                 "Expecting a stack map frame"),
+
+        new Case("case53", "verifier.cpp", true,
+                 "verify_exception_handler_targets",
+                 "stackmap mismatch at exception handler",
+                 "Stack map does not match the one at exception handler "),
+
+        new Case("case54", "verifier.cpp", true, "verify_cp_index",
+                 "constant pool index is out-of-bounds",
+                 "Illegal constant pool index "),
+
+        new Case("case55", "verifier.cpp", true, "verify_cp_type",
+                 "constant pool entry is not expected type",
+                 "Illegal type at constant pool entry "),
+
+        new Case("case56", "verifier.cpp", true, "verify_cp_class_type",
+                 "constant pool entry is not an object type",
+                 "Illegal type at constant pool entry "),
+
+        /* Unreachable: verify_cp_type gates this case */
+        new Case("case57", "verifier.cpp", false, "verify_ldc",
+                 "invalid constant pool index in ldc",
+                 "Invalid index in ldc"),
+
+        new Case("case58", "verifier.cpp", true, "verify_switch",
+                 "bad switch padding",
+                 "Nonzero padding byte in lookswitch or tableswitch"),
+
+        new Case("case59", "verifier.cpp", true, "verify_switch",
+                 "tableswitch low is greater than high",
+                 "low must be less than or equal to high in tableswitch"),
+
+        /* Unreachable on 64-bit?  Only way to get here is to overflow
+         * the 'keys' variable which can't happen on 64-bit since we're dealing
+         * with 32-bit values.  Perhaps reachable on 32-bit but the
+         * triggering class would be quite large */
+        new Case("case60", "verifier.cpp", false, "verify_switch",
+                 "high - low + 1 < 0 (overflow?)",
+                 "too many keys in tableswitch"),
+
+        /* Would have to create a 16G classfile to trip this.  Possible but
+         * not reasonable to do in a test.  */
+        new Case("case61", "verifier.cpp", false, "verify_switch",
+                 "lookupswitch keys < 0",
+                 "number of keys in lookupswitch less than 0"),
+
+        new Case("case62", "verifier.cpp", true, "verify_switch",
+                 "lookupswitch keys out-of-order",
+                 "Bad lookupswitch instruction"),
+
+        /* Unreachable: Class file parser verifies Fieldref contents */
+        new Case("case63", "verifier.cpp", false, "verify_field_instructions",
+                 "referenced class is not an CP object",
+                 "Expecting reference to class in class "),
+
+        new Case("case64", "verifier.cpp", true, "verify_field_instructions",
+                 "TOS not assignable to field type in putfield",
+                 "Bad type on operand stack in putfield"),
+
+        new Case("case65", "verifier.cpp", true, "verify_field_instructions",
+                 "TOS not assignable to class when accessing protected field",
+                 "Bad access to protected data in getfield"),
+
+        new Case("case66", "verifier.cpp", true, "verify_invoke_init",
+                 "Uninit_this is not of the current type or it's supertype",
+                 "Bad <init> method call"),
+
+        /* Unreachable:  Stack map parsing ensures valid type and new
+         * instructions have a valid BCI. */
+        new Case("case67", "verifier.cpp", false, "verify_invoke_init",
+                 "Uninit type with bad new instruction index",
+                 "Expecting new instruction"),
+
+        new Case("case68", "verifier.cpp", true, "verify_invoke_init",
+                 "calling other class's <init> method",
+                 "Call to wrong <init> method"),
+
+        new Case("case69", "verifier.cpp", true, "verify_invoke_init",
+                 "Calling protected <init> and type unassignable from current",
+                 "Bad access to protected <init> method"),
+
+        new Case("case70", "verifier.cpp", true, "verify_invoke_init",
+                 "TOS is not an uninitialized (or Uninit_this) type",
+                 "Bad operand type when invoking <init>"),
+
+        new Case("case71", "verifier.cpp", true, "verify_invoke_instructions",
+                 "Arg count in instruction doesn't match signature",
+                 "Inconsistent args count operand in invokeinterface"),
+
+        new Case("case72", "verifier.cpp", true, "verify_invoke_instructions",
+                 "Non-zero pad in invokeinterface",
+                 "Fourth operand byte of invokeinterface must be zero"),
+
+        new Case("case73", "verifier.cpp", true, "verify_invoke_instructions",
+                 "Non-zero pad in invokedynamic",
+                 "Third and fourth operand bytes of " +
+                 "invokedynamic must be zero"),
+
+        new Case("case74", "verifier.cpp", true, "verify_invoke_instructions",
+                 "Non-invokespecial trying to invoke a '<' method",
+                 "Illegal call to internal method"),
+
+        new Case("case75", "verifier.cpp", true, "verify_invoke_instructions",
+                 "invokespecial and current unassignable from referenced type",
+                 "Bad invokespecial instruction: current class isn't " +
+                 "assignable to reference class."),
+
+        new Case("case76", "verifier.cpp", true, "verify_invoke_instructions",
+                 "TOS not assignable to current when calling protected method",
+                 "Bad access to protected data in invokevirtual"),
+
+        /* Unreachable:  class file parser enforces void signature */
+        new Case("case77", "verifier.cpp", false, "verify_invoke_instructions",
+                 "<init> method is not void return",
+                 "Return type must be void in <init> method"),
+
+        new Case("case78", "verifier.cpp", true, "get_newarray_type",
+                 "newarray type invalid",
+                 "Illegal newarray instruction"),
+
+        new Case("case79", "verifier.cpp", true, "verify_return_value",
+                 "void return from method which has a return value",
+                 "Method expects a return value"),
+
+        new Case("case80", "verifier.cpp", true, "verify_return_value",
+                 "TOS type does not match signature",
+                 "Bad return type"),
+
+        new Case("case81", "verifier.cpp", true, "verify_stackmap_table",
+                 "stack map does not match (flags)",
+                 "Instruction type does not match stack map")
+    };
+}
+
+public class Test7116786 {
+    public static void main(String argv[]) throws Exception {
+        for (Case c : VerifyErrorCases.cases) {
+            System.out.println("******** " + c.getCaseName() + " ********");
+            if (c.isTestable()) {
+                try {
+                    ClassLoader cl = Test7116786.class.getClassLoader();
+                    Class<?> cls = Class.forName(c.getCaseName(), true, cl);
+                    throw new RuntimeException(
+                        "++ FAIL: No verify error encountered");
+                } catch (VerifyError ve) {
+                    String message = c.getMessage();
+                    String veMessage = ve.getMessage();
+                    System.out.print(veMessage);
+                    if (!veMessage.startsWith(message)) {
+                        // We're not seeing the message we expect.  Could be
+                        // that we've gotten the wrong VerifyError case, or
+                        // maybe the message changed.
+                        System.out.println("++ FAIL? " +
+                            "Message does not match what was expected: " +
+                            message);
+                        continue;
+                    }
+                    if (!veMessage.contains("Exception Details:") &&
+                        !veMessage.contains("Reason:")) {
+                        System.out.println("++ FAIL: No details found");
+                        throw new RuntimeException("FAIL: No details found");
+                    }
+                    System.out.println("++ PASS");
+                }
+            } else {
+               System.out.println("++ SKIPPED");
+            }
+        }
+    }
+}
diff --git a/hotspot/test/runtime/7116786/testcases.jar b/hotspot/test/runtime/7116786/testcases.jar
new file mode 100644
index 0000000..5996133
--- /dev/null
+++ b/hotspot/test/runtime/7116786/testcases.jar
Binary files differ
diff --git a/hotspot/test/runtime/7158988/FieldMonitor.java b/hotspot/test/runtime/7158988/FieldMonitor.java
new file mode 100644
index 0000000..584d39d2
--- /dev/null
+++ b/hotspot/test/runtime/7158988/FieldMonitor.java
@@ -0,0 +1,249 @@
+/*
+ * Copyright 2012 SAP AG.  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 FieldMonitor.java
+ * @bug 7158988
+ * @summary verify jvm does not crash while debugging
+ * @run shell TestFieldMonitor.sh
+ * @author axel.siebenborn@sap.com
+ */
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.Reader;
+import java.io.Writer;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import com.sun.jdi.Bootstrap;
+import com.sun.jdi.Field;
+import com.sun.jdi.ReferenceType;
+import com.sun.jdi.VirtualMachine;
+import com.sun.jdi.connect.Connector;
+import com.sun.jdi.connect.IllegalConnectorArgumentsException;
+import com.sun.jdi.connect.LaunchingConnector;
+import com.sun.jdi.connect.VMStartException;
+import com.sun.jdi.event.ClassPrepareEvent;
+import com.sun.jdi.event.Event;
+import com.sun.jdi.event.EventQueue;
+import com.sun.jdi.event.EventSet;
+import com.sun.jdi.event.ModificationWatchpointEvent;
+import com.sun.jdi.event.VMDeathEvent;
+import com.sun.jdi.event.VMDisconnectEvent;
+import com.sun.jdi.request.ClassPrepareRequest;
+import com.sun.jdi.request.EventRequest;
+import com.sun.jdi.request.EventRequestManager;
+import com.sun.jdi.request.ModificationWatchpointRequest;
+
+public class FieldMonitor {
+
+  public static final String CLASS_NAME = "TestPostFieldModification";
+  public static final String FIELD_NAME = "value";
+  public static final String ARGUMENTS = "-Xshare:off -XX:+PrintGC";
+
+  public static void main(String[] args)
+      throws IOException, InterruptedException {
+
+    StringBuffer sb = new StringBuffer();
+
+    for (int i=0; i < args.length; i++) {
+        sb.append(' ');
+        sb.append(args[i]);
+    }
+    //VirtualMachine vm = launchTarget(sb.toString());
+    VirtualMachine vm = launchTarget(CLASS_NAME);
+
+    System.out.println("Vm launched");
+    // set watch field on already loaded classes
+    List<ReferenceType> referenceTypes = vm
+        .classesByName(CLASS_NAME);
+    for (ReferenceType refType : referenceTypes) {
+      addFieldWatch(vm, refType);
+    }
+    // watch for loaded classes
+    addClassWatch(vm);
+
+    // process events
+    EventQueue eventQueue = vm.eventQueue();
+    // resume the vm
+
+    Process process = vm.process();
+
+
+    // Copy target's output and error to our output and error.
+    Thread outThread = new StreamRedirectThread("out reader", process.getInputStream());
+    Thread errThread = new StreamRedirectThread("error reader", process.getErrorStream());
+
+    errThread.start();
+    outThread.start();
+
+
+    vm.resume();
+    boolean connected = true;
+    while (connected) {
+      EventSet eventSet = eventQueue.remove();
+      for (Event event : eventSet) {
+        if (event instanceof VMDeathEvent
+            || event instanceof VMDisconnectEvent) {
+          // exit
+          connected = false;
+        } else if (event instanceof ClassPrepareEvent) {
+          // watch field on loaded class
+          System.out.println("ClassPrepareEvent");
+          ClassPrepareEvent classPrepEvent = (ClassPrepareEvent) event;
+          ReferenceType refType = classPrepEvent
+              .referenceType();
+          addFieldWatch(vm, refType);
+        } else if (event instanceof ModificationWatchpointEvent) {
+          System.out.println("sleep for 500 ms");
+          Thread.sleep(500);
+          System.out.println("resume...");
+
+          ModificationWatchpointEvent modEvent = (ModificationWatchpointEvent) event;
+          System.out.println("old="
+              + modEvent.valueCurrent());
+          System.out.println("new=" + modEvent.valueToBe());
+          System.out.println();
+        }
+      }
+      eventSet.resume();
+    }
+    // Shutdown begins when event thread terminates
+    try {
+        errThread.join(); // Make sure output is forwarded
+        outThread.join();
+    } catch (InterruptedException exc) {
+        // we don't interrupt
+    }
+  }
+
+  /**
+   * Find a com.sun.jdi.CommandLineLaunch connector
+   */
+  static LaunchingConnector findLaunchingConnector() {
+    List <Connector> connectors = Bootstrap.virtualMachineManager().allConnectors();
+    Iterator <Connector> iter = connectors.iterator();
+    while (iter.hasNext()) {
+      Connector connector = iter.next();
+      if (connector.name().equals("com.sun.jdi.CommandLineLaunch")) {
+        return (LaunchingConnector)connector;
+      }
+    }
+    throw new Error("No launching connector");
+  }
+  /**
+   * Return the launching connector's arguments.
+   */
+ static Map <String,Connector.Argument> connectorArguments(LaunchingConnector connector, String mainArgs) {
+      Map<String,Connector.Argument> arguments = connector.defaultArguments();
+      for (String key : arguments.keySet()) {
+        System.out.println(key);
+      }
+
+      Connector.Argument mainArg = (Connector.Argument)arguments.get("main");
+      if (mainArg == null) {
+          throw new Error("Bad launching connector");
+      }
+      mainArg.setValue(mainArgs);
+
+      Connector.Argument optionsArg = (Connector.Argument)arguments.get("options");
+      if (optionsArg == null) {
+        throw new Error("Bad launching connector");
+      }
+      optionsArg.setValue(ARGUMENTS);
+      return arguments;
+  }
+
+ static VirtualMachine launchTarget(String mainArgs) {
+    LaunchingConnector connector = findLaunchingConnector();
+    Map  arguments = connectorArguments(connector, mainArgs);
+    try {
+        return (VirtualMachine) connector.launch(arguments);
+    } catch (IOException exc) {
+        throw new Error("Unable to launch target VM: " + exc);
+    } catch (IllegalConnectorArgumentsException exc) {
+        throw new Error("Internal error: " + exc);
+    } catch (VMStartException exc) {
+        throw new Error("Target VM failed to initialize: " +
+                        exc.getMessage());
+    }
+}
+
+
+  private static void addClassWatch(VirtualMachine vm) {
+    EventRequestManager erm = vm.eventRequestManager();
+    ClassPrepareRequest classPrepareRequest = erm
+        .createClassPrepareRequest();
+    classPrepareRequest.addClassFilter(CLASS_NAME);
+    classPrepareRequest.setEnabled(true);
+  }
+
+
+  private static void addFieldWatch(VirtualMachine vm,
+      ReferenceType refType) {
+    EventRequestManager erm = vm.eventRequestManager();
+    Field field = refType.fieldByName(FIELD_NAME);
+    ModificationWatchpointRequest modificationWatchpointRequest = erm
+        .createModificationWatchpointRequest(field);
+    modificationWatchpointRequest.setSuspendPolicy(EventRequest.SUSPEND_EVENT_THREAD);
+    modificationWatchpointRequest.setEnabled(true);
+  }
+}
+
+class StreamRedirectThread extends Thread {
+
+  private final BufferedReader in;
+
+  private static final int BUFFER_SIZE = 2048;
+
+  /**
+   * Set up for copy.
+   * @param name  Name of the thread
+   * @param in    Stream to copy from
+   * @param out   Stream to copy to
+   */
+  StreamRedirectThread(String name, InputStream in) {
+    super(name);
+    this.in = new BufferedReader(new InputStreamReader(in));
+  }
+
+  /**
+   * Copy.
+   */
+  public void run() {
+    try {
+      String line;
+        while ((line = in.readLine ()) != null) {
+          System.out.println ("testvm: " + line);
+      }
+     System.out.flush();
+    } catch(IOException exc) {
+      System.err.println("Child I/O Transfer - " + exc);
+    }
+  }
+}
diff --git a/hotspot/test/runtime/7158988/TestFieldMonitor.sh b/hotspot/test/runtime/7158988/TestFieldMonitor.sh
new file mode 100644
index 0000000..aa18c16
--- /dev/null
+++ b/hotspot/test/runtime/7158988/TestFieldMonitor.sh
@@ -0,0 +1,75 @@
+#!/bin/sh
+
+if [ "${TESTSRC}" = "" ]
+then TESTSRC=.
+fi
+
+if [ "${TESTJAVA}" = "" ]
+then
+  PARENT=`dirname \`which java\``
+  TESTJAVA=`dirname ${PARENT}`
+  echo "TESTJAVA not set, selecting " ${TESTJAVA}
+  echo "If this is incorrect, try setting the variable manually."
+fi
+
+if [ "${TESTCLASSES}" = "" ]
+then
+  echo "TESTCLASSES not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+# set platform-dependent variables
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin)
+    NULL=/dev/null
+    PS=":"
+    FS="/"
+    ;;
+  Windows_95 | Windows_98 | Windows_ME )
+    NULL=NUL
+    PS=";"
+    FS="\\"
+    echo "Test skipped, only for WinNT"
+    exit 0
+    ;;
+  Windows_NT )
+    NULL=NUL
+    PS=";"
+    FS="\\"
+    ;;
+  CYGWIN_NT* )
+    NULL=/dev/null
+    PS=";"
+    FS="/"
+    ;;
+  CYGWIN_* )
+    NULL=/dev/null
+    PS=";"
+    FS="/"
+    echo "Test skipped, only for WinNT"
+    exit 0
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+#CLASSPATH=.${PS}${TESTCLASSES} ; export CLASSPATH
+
+cp ${TESTSRC}${FS}*.java .
+
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -fullversion
+
+${TESTJAVA}${FS}bin${FS}javac -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar *.java
+
+${TESTJAVA}${FS}bin${FS}java ${TESTVMOPTS} -classpath .${PS}$TESTJAVA${FS}lib${FS}tools.jar FieldMonitor > test.out
+
+grep "A fatal error has been detected" test.out > ${NULL}
+if [ $? = 0 ]; then
+    cat test.out
+    STATUS=1
+fi
+
+exit $STATUS
diff --git a/hotspot/test/runtime/7158988/TestPostFieldModification.java b/hotspot/test/runtime/7158988/TestPostFieldModification.java
new file mode 100644
index 0000000..d730003
--- /dev/null
+++ b/hotspot/test/runtime/7158988/TestPostFieldModification.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2012 SAP AG.  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.
+ */
+
+public class TestPostFieldModification {
+
+  public String value;  // watch modification of value
+
+  public static void main(String[] args){
+
+    System.out.println("Start threads");
+    // this thread modifies the field 'value'
+    new Thread() {
+      TestPostFieldModification test = new TestPostFieldModification();
+      public void run() {
+        test.value="test";
+        for(int i = 0; i < 10; i++) {
+          test.value += new String("_test");
+        }
+      }
+    }.start();
+
+    // this thread is used to trigger a gc
+    Thread d = new Thread() {
+      public void run() {
+        while(true) {
+          try {
+            Thread.sleep(100);
+          } catch (InterruptedException e) {
+
+          }
+          System.gc();
+        }
+      }
+    };
+    d.setDaemon(true);
+    d.start();
+  }
+}
diff --git a/hotspot/test/runtime/7167069/PrintAsFlag.java b/hotspot/test/runtime/7167069/PrintAsFlag.java
new file mode 100644
index 0000000..bf8747e
--- /dev/null
+++ b/hotspot/test/runtime/7167069/PrintAsFlag.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+/*
+ * Note that in the run command below the only important flag is PrintCommandLineFlags.
+ * The others are just flags of all types; bool, intx, uintx, uint64_t, double and ccstr.
+ *
+ * @test PrintAsFlag
+ * @summary verify that Flag::print_as_flag() works correctly. This is used by "jinfo -flag" and -XX:+PrintCommandLineFlags.
+ * @run main/othervm -XX:+PrintCommandLineFlags -XX:-ShowMessageBoxOnError -XX:BiasedLockingStartupDelay=4000 -XX:ParallelGCThreads=4 -XX:MaxRAM=1G -XX:CMSSmallCoalSurplusPercent=1.05 -XX:ErrorFile="file" PrintAsFlag
+ */
+
+public class PrintAsFlag {
+  public static void main(String... args) {
+    System.out.printf("Done");
+  }
+}
diff --git a/hotspot/test/runtime/7196045/Test7196045.java b/hotspot/test/runtime/7196045/Test7196045.java
new file mode 100644
index 0000000..59704f7
--- /dev/null
+++ b/hotspot/test/runtime/7196045/Test7196045.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2012, 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 7196045
+ * @summary Possible JVM deadlock in ThreadTimesClosure when using HotspotInternal non-public API.
+ * @run main/othervm Test7196045
+ */
+
+import java.lang.management.ManagementFactory;
+import javax.management.JMException;
+import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
+import javax.management.ObjectName;
+
+public class Test7196045 {
+
+    public static long duration = 1000 * 60 * 2;
+    private static final String HOTSPOT_INTERNAL = "sun.management:type=HotspotInternal";
+
+    public static void main(String[] args) {
+
+        MBeanServer server = ManagementFactory.getPlatformMBeanServer();
+        ObjectName objName= null;
+        try {
+            ObjectName hotspotInternal = new ObjectName(HOTSPOT_INTERNAL);
+            try {
+                server.registerMBean(new sun.management.HotspotInternal(), hotspotInternal);
+            } catch (JMException e) {
+                throw new RuntimeException("HotSpotWatcher: Failed to register the HotspotInternal MBean" + e);
+            }
+            objName= new ObjectName("sun.management:type=HotspotThreading");
+
+        } catch (MalformedObjectNameException e1) {
+            throw new RuntimeException("Bad object name" + e1);
+        }
+
+        long endTime = System.currentTimeMillis() + duration;
+        long i = 0;
+        while (true) {
+            try {
+                server.getAttribute(objName, "InternalThreadCpuTimes");
+            } catch (Exception ex) {
+                System.err.println("Exception while getting attribute: " + ex);
+            }
+            i++;
+            if (i % 10000 == 0) {
+                System.out.println("Successful iterations: " + i);
+            }
+            if (System.currentTimeMillis() > endTime) {
+                break;
+            }
+        }
+        System.out.println("PASSED.");
+    }
+}
diff --git a/hotspot/test/sanity/WBApi.java b/hotspot/test/sanity/WBApi.java
new file mode 100644
index 0000000..79a5164
--- /dev/null
+++ b/hotspot/test/sanity/WBApi.java
@@ -0,0 +1,13 @@
+/*
+ * @test WBApi
+ * @summary verify that whitebox functions can be linked and executed
+ * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI WBApi.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI WBApi
+ */
+
+import sun.hotspot.WhiteBox;
+public class WBApi {
+    public static void main(String... args) {
+        System.out.printf("args at: %x\n",WhiteBox.getWhiteBox().getObjectAddress(args));
+    }
+}
diff --git a/hotspot/test/serviceability/7170638/SDTProbesGNULinuxTest.sh b/hotspot/test/serviceability/7170638/SDTProbesGNULinuxTest.sh
new file mode 100644
index 0000000..1fd79d6
--- /dev/null
+++ b/hotspot/test/serviceability/7170638/SDTProbesGNULinuxTest.sh
@@ -0,0 +1,68 @@
+# 
+#  Copyright (c) 2012, Red Hat, Inc.
+#  DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+# 
+#  This code is free software; you can redistribute it and/or modify it
+#  under the terms of the GNU General Public License version 2 only, as
+#  published by the Free Software Foundation.
+# 
+#  This code is distributed in the hope that it will be useful, but WITHOUT
+#  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+#  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+#  version 2 for more details (a copy is included in the LICENSE file that
+#  accompanied this code).
+# 
+#  You should have received a copy of the GNU General Public License version
+#  2 along with this work; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+# 
+#  Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+#  or visit www.oracle.com if you need additional information or have any
+#  questions.
+# 
+
+# @test SDTProbesGNULinuxTest.sh
+# @bug 7170638
+# @summary Test SDT probes available on GNU/Linux when DTRACE_ENABLED
+# @run shell SDTProbesGNULinuxTest.sh
+
+# This test only matters on GNU/Linux, others trivially PASS.
+OS=`uname -s`
+case "$OS" in
+  Linux )
+    ;;
+  *)
+    echo "Not testing on anything but GNU/Linux. PASSED"
+    exit 0;
+    ;;
+esac
+
+# Where is our java (parent) directory? 
+if [ "${TESTJAVA}" = "" ]; then
+  PARENT=$(dirname $(readlink -f $(which java)))
+  TESTJAVA=`dirname ${PARENT}`
+  echo "TESTJAVA directory not set, using " ${TESTJAVA}
+fi
+
+# This test only matters when build with DTRACE_ENABLED. 
+${TESTJAVA}/bin/java -XX:+ExtendedDTraceProbes -version
+if [ "$?" != "0" ]; then
+  echo "Not build using DTRACE_ENABLED. PASSED"
+  exit 0
+fi
+
+# Test all available libjvm.so variants
+for libjvm in $(find ${TESTJAVA} -name libjvm.so); do
+  echo "Testing ${libjvm}"
+  # Check whether the SDT probes are compiled in.
+  readelf -S ${libjvm} | grep '.note.stapsdt'
+  if [ "$?" != "0" ]; then
+    echo "Failed: ${libjvm} doesn't contain SDT probes."
+    exit 1
+  fi
+  # We could iterate over all SDT probes and test them individually
+  # with readelf -n, but older readelf versions don't understand them.
+done
+
+echo "Passed."
+exit 0
diff --git a/hotspot/test/serviceability/ParserTest.java b/hotspot/test/serviceability/ParserTest.java
new file mode 100644
index 0000000..b70d235
--- /dev/null
+++ b/hotspot/test/serviceability/ParserTest.java
@@ -0,0 +1,180 @@
+/*
+ * @test ParserTest
+ * @summary verify that whitebox functions can be linked and executed
+ * @run compile -J-XX:+UnlockDiagnosticVMOptions -J-XX:+WhiteBoxAPI ParserTest.java
+ * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI ParserTest
+ */
+
+import java.math.BigInteger;
+
+import sun.hotspot.parser.DiagnosticCommand;
+import sun.hotspot.parser.DiagnosticCommand.DiagnosticArgumentType;
+import sun.hotspot.WhiteBox;
+
+public class ParserTest {
+    WhiteBox wb;
+
+    public ParserTest() throws Exception {
+        wb = WhiteBox.getWhiteBox();
+
+        testNanoTime();
+        testJLong();
+        testBool();
+        testQuotes();
+        testMemorySize();
+    }
+
+    public static void main(String... args) throws Exception  {
+         new ParserTest();
+    }
+
+    public void testNanoTime() throws Exception {
+        String name = "name";
+        DiagnosticCommand arg = new DiagnosticCommand(name,
+                "desc", DiagnosticArgumentType.NANOTIME,
+                false, "0");
+        DiagnosticCommand[] args = {arg};
+
+        BigInteger bi = new BigInteger("7");
+        //These should work
+        parse(name, bi.toString(), name + "=7ns", args);
+
+        bi = bi.multiply(BigInteger.valueOf(1000));
+        parse(name, bi.toString(), name + "=7us", args);
+
+        bi = bi.multiply(BigInteger.valueOf(1000));
+        parse(name, bi.toString(), name + "=7ms", args);
+
+        bi = bi.multiply(BigInteger.valueOf(1000));
+        parse(name, bi.toString(), name + "=7s", args);
+
+        bi = bi.multiply(BigInteger.valueOf(60));
+        parse(name, bi.toString() , name + "=7m", args);
+
+        bi = bi.multiply(BigInteger.valueOf(60));
+        parse(name, bi.toString() , name + "=7h", args);
+
+        bi = bi.multiply(BigInteger.valueOf(24));
+        parse(name, bi.toString() , name + "=7d", args);
+
+        parse(name, "0", name + "=0", args);
+
+        shouldFail(name + "=7xs", args);
+        shouldFail(name + "=7mms", args);
+        shouldFail(name + "=7f", args);
+        //Currently, only value 0 is allowed without unit
+        shouldFail(name + "=7", args);
+    }
+
+    public void testJLong() throws Exception {
+        String name = "name";
+        DiagnosticCommand arg = new DiagnosticCommand(name,
+                "desc", DiagnosticArgumentType.JLONG,
+                false, "0");
+        DiagnosticCommand[] args = {arg};
+
+        wb.parseCommandLine(name + "=10", args);
+        parse(name, "10", name + "=10", args);
+        parse(name, "-5", name + "=-5", args);
+
+        //shouldFail(name + "=12m", args); <-- should fail, doesn't
+    }
+
+    public void testBool() throws Exception {
+        String name = "name";
+        DiagnosticCommand arg = new DiagnosticCommand(name,
+                "desc", DiagnosticArgumentType.BOOLEAN,
+                false, "false");
+        DiagnosticCommand[] args = {arg};
+
+        parse(name, "true", name + "=true", args);
+        parse(name, "false", name + "=false", args);
+        parse(name, "true", name, args);
+
+        //Empty commandline to parse, tests default value
+        //of the parameter "name"
+        parse(name, "false", "", args);
+    }
+
+    public void testQuotes() throws Exception {
+        String name = "name";
+        DiagnosticCommand arg1 = new DiagnosticCommand(name,
+                "desc", DiagnosticArgumentType.STRING,
+                false, null);
+        DiagnosticCommand arg2 = new DiagnosticCommand("arg",
+                "desc", DiagnosticArgumentType.STRING,
+                false, null);
+        DiagnosticCommand[] args = {arg1, arg2};
+
+        // try with a quoted value
+        parse(name, "Recording 1", name + "=\"Recording 1\"", args);
+        // try with a quoted argument
+        parse(name, "myrec", "\"" + name + "\"" + "=myrec", args);
+        // try with both a quoted value and a quoted argument
+        parse(name, "Recording 1", "\"" + name + "\"" + "=\"Recording 1\"", args);
+
+        // now the same thing but with other arguments after
+
+        // try with a quoted value
+        parse(name, "Recording 1", name + "=\"Recording 1\",arg=value", args);
+        // try with a quoted argument
+        parse(name, "myrec", "\"" + name + "\"" + "=myrec,arg=value", args);
+        // try with both a quoted value and a quoted argument
+        parse(name, "Recording 1", "\"" + name + "\"" + "=\"Recording 1\",arg=value", args);
+    }
+
+    public void testMemorySize() throws Exception {
+        String name = "name";
+        String defaultValue = "1024";
+        DiagnosticCommand arg = new DiagnosticCommand(name,
+                "desc", DiagnosticArgumentType.MEMORYSIZE,
+                false, defaultValue);
+        DiagnosticCommand[] args = {arg};
+
+        BigInteger bi = new BigInteger("7");
+        parse(name, bi.toString(), name + "=7b", args);
+
+        bi = bi.multiply(BigInteger.valueOf(1024));
+        parse(name, bi.toString(), name + "=7k", args);
+
+        bi = bi.multiply(BigInteger.valueOf(1024));
+        parse(name, bi.toString(), name + "=7m", args);
+
+        bi = bi.multiply(BigInteger.valueOf(1024));
+        parse(name, bi.toString(), name + "=7g", args);
+        parse(name, defaultValue, "", args);
+
+        //shouldFail(name + "=7gg", args); <---- should fail, doesn't
+        //shouldFail(name + "=7t", args);  <----- should fail, doesn't
+    }
+
+    public void parse(String searchName, String expectedValue,
+            String cmdLine, DiagnosticCommand[] argumentTypes) throws Exception {
+        //parseCommandLine will return an object array that looks like
+        //{<name of parsed object>, <of parsed object> ... }
+        Object[] res = wb.parseCommandLine(cmdLine, argumentTypes);
+        for (int i = 0; i < res.length-1; i+=2) {
+            String parsedName = (String) res[i];
+            if (searchName.equals(parsedName)) {
+                String parsedValue = (String) res[i+1];
+                if (expectedValue.equals(parsedValue)) {
+                    return;
+                } else {
+                    throw new Exception("Parsing of cmdline '" + cmdLine + "' failed!\n"
+                            + searchName + " parsed as " + parsedValue
+                            + "! Expected: " + expectedValue);
+                }
+            }
+        }
+        throw new Exception(searchName + " not found as a parsed Argument!");
+    }
+
+    private void shouldFail(String argument, DiagnosticCommand[] argumentTypes) throws Exception {
+        try {
+            wb.parseCommandLine(argument, argumentTypes);
+            throw new Exception("Parser accepted argument: " + argument);
+        } catch (IllegalArgumentException e) {
+            //expected
+        }
+    }
+}
diff --git a/jaxp/.hgtags b/jaxp/.hgtags
index 732db52..3e3da67 100644
--- a/jaxp/.hgtags
+++ b/jaxp/.hgtags
@@ -199,6 +199,7 @@
 8824bcbfd7cd8059ededf70f1e7f2b06f02cb33f jdk7u6-b23
 378f719cfb9491b766cd9f7cd47ad7fa3503e141 jdk7u6-b24
 5f1b80e8baec46fc28826a3a6ab8e1913c872f4c jdk7u6-b30
+2eafa8a6fd8fdb54b10045e247d1a57f9817f473 jdk7u6-b31
 2eafa8a6fd8fdb54b10045e247d1a57f9817f473 jdk7u7-b10
 c4aa15da8529451cc678d5747e7b82e9cc38627e jdk7u7-b30
 f6e11679b12e1548f407b78a940c568401dd2a19 jdk7u7-b11
@@ -221,3 +222,20 @@
 5449d5396bd8deee90f18f29899343129e3cdc4e jdk7u10-b16
 86c75e6aa3a7fa9a587fc7dd2d08af8aa8ffb9a9 jdk7u10-b17
 162a2c6ad8718a63253fa53724f704a4f85731bc jdk7u10-b18
+c59eb287de720ae5ce8087f179ec01f4f6525a32 jdk7u10-b30
+1365e7472a3b737dda4a73e06ad41718d667d9be jdk7u8-b01
+0a313d4307930be3a64106b9b8c90f9342673aa0 jdk7u8-b02
+36cba5ea434944cef64fa281112b158fae93c0fa jdk7u8-b03
+07c07608384e1b5b09fc82ff8e42ca72d374b178 jdk7u8-b04
+c579d804e5ca54e3c7f0ba1eb90a7b97c980b889 jdk7u8-b05
+d4e27ea952ad62432d24f7c880227140af5f50ec jdk7u10-b06
+9205eb81886de12f9e3324ac8e0c7cec536b22d5 jdk7u10-b07
+720eb6c26227887ad11eb401f91a10878c3c7b6b jdk7u10-b08
+3a33a35b2d24cb671050e61aa4930a951bc35d2b jdk7u10-b09
+27bab008eee997a2a8a78d6fe72a56c87c1c2b2b jdk7u12-b01
+8e3a4e47ce71a0add89eca5b079e02ae3a81c594 jdk7u12-b02
+1aa52991dfa7468d676557bf9fd6fd0e98c3d097 jdk7u12-b03
+464e19bd9db89b200a002e2001d0e8f352cf5ff9 jdk7u12-b04
+3db0cfb507771458da8978248de7598ebe7c20d8 jdk7u12-b05
+c84c463893504a93a38f4abfa4d057869e9ae918 jdk7u12-b06
+1b914599a6d5560e743b9fecd390924ed0bf7d15 jdk7u12-b07
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Version.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Version.java
index 165a334..ac62db7 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/Version.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/Version.java
@@ -74,7 +74,7 @@
 
     /** Version string.
      * @deprecated  getVersion() should be used instead.  */
-    public static String fVersion = "Xerces-J 2.7.1";
+    public static final String fVersion = getVersion();
 
     private static final String fImmutableVersion = "Xerces-J 2.7.1";
 
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
index d6680ec..abbd696 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java
@@ -193,9 +193,12 @@
                 null,
     };
 
-    protected static final char [] cdata = {'[','C','D','A','T','A','['};
-    protected static final char [] xmlDecl = {'<','?','x','m','l'};
-    protected static final char [] endTag = {'<','/'};
+    private static final char [] cdata = {'[','C','D','A','T','A','['};
+    private static final char [] endTag = {'<','/'};
+
+    //this variable is also used by XMLDocumentScannerImpl in the same package
+    static final char [] xmlDecl = {'<','?','x','m','l'};
+
     // debugging
 
     /** Debug scanner state. */
@@ -806,6 +809,7 @@
      *                 where the entity encoding is not auto-detected (e.g.
      *                 internal entities or a document entity that is
      *                 parsed from a java.io.Reader).
+     * @param augs     Additional information that may include infoset augmentations
      *
      * @throws XNIException Thrown by handler to signal an error.
      */
@@ -833,7 +837,7 @@
         // call handler
         if (fDocumentHandler != null && !fScanningAttribute) {
             if (!name.equals("[xml]")) {
-                fDocumentHandler.startGeneralEntity(name, identifier, encoding, null);
+                fDocumentHandler.startGeneralEntity(name, identifier, encoding, augs);
             }
         }
 
@@ -845,6 +849,7 @@
      * are just specified by their name.
      *
      * @param name The name of the entity.
+     * @param augs Additional information that may include infoset augmentations
      *
      * @throws XNIException Thrown by handler to signal an error.
      */
@@ -869,7 +874,7 @@
         // call handler
         if (fDocumentHandler != null && !fScanningAttribute) {
             if (!name.equals("[xml]")) {
-                fDocumentHandler.endGeneralEntity(name, null);
+                fDocumentHandler.endGeneralEntity(name, augs);
             }
         }
 
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
index 7f3295d..84e2c81 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java
@@ -602,7 +602,7 @@
         if (reader == null) {
             stream = xmlInputSource.getByteStream();
             if (stream == null) {
-                URL location = new URL(escapeNonUSAscii(expandedSystemId));
+                URL location = new URL(expandedSystemId);
                 URLConnection connect = location.openConnection();
                 if (!(connect instanceof HttpURLConnection)) {
                     stream = connect.getInputStream();
@@ -2586,64 +2586,6 @@
 
     } // fixURI(String):String
 
-    /**
-     * Escape invalid URI characters.
-     *
-     * Passed a URI that contains invalid characters (like spaces, non-ASCII Unicode characters, and the like),
-     * this function percent encodes the invalid characters per the URI specification (i.e., as a sequence of
-     * %-encoded UTF-8 octets).
-     *
-     * N.B. There are two problems. If the URI contains a '%' character, that might be an indication that
-     * the URI has already been escaped by the author, or it might be an invalid '%'. In the former case,
-     * it's important not to escape it, or we'll wind up with invalid, doubly-escaped '%'s. In the latter,
-     * the URI is broken if we don't encode it. Similarly, a '#' character might be the start of a fragment
-     * identifier or it might be an invalid '#'.
-     *
-     * Given that the former is vastly more likely than the latter in each case (most users are familiar with
-     * the magic status of '%' and '#' and they occur relatively infrequently in filenames, and if the user parses
-     * a proper Java File, we will already have %-escaped the URI), we simply assume that %'s and #'s are legit.
-     *
-     * Very rarely, we may be wrong. If so, tell the user to fix the clearly broken URI.
-     */
-    protected static String escapeNonUSAscii(String str) {
-        if (str == null) {
-            return str;
-        }
-
-        // get UTF-8 bytes for the string
-        StringBuffer buffer = new StringBuffer();
-        byte[] bytes = null;
-        byte b;
-        try {
-            bytes = str.getBytes("UTF-8");
-        } catch (java.io.UnsupportedEncodingException e) {
-            // should never happen
-            return str;
-        }
-        int len = bytes.length;
-        int ch;
-
-        // for each byte
-        for (int i = 0; i < len; i++) {
-            b = bytes[i];
-            // for non-ascii character: make it positive, then escape
-            if (b < 0) {
-                ch = b + 256;
-                buffer.append('%');
-                buffer.append(gHexChs[ch >> 4]);
-                buffer.append(gHexChs[ch & 0xf]);
-            }
-            else if (b != '%' && b != '#' && gNeedEscaping[b]) {
-                buffer.append('%');
-                buffer.append(gAfterEscaping1[b]);
-                buffer.append(gAfterEscaping2[b]);
-            }
-            else {
-                buffer.append((char)b);
-            }
-        }
-        return buffer.toString();
-    }
 
     //
     // Package visible methods
diff --git a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
index 48a1c88..4acc9c9 100644
--- a/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
+++ b/jaxp/src/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java
@@ -71,7 +71,7 @@
     /** Listeners which should know when load is being called */
     private Vector listeners = new Vector();
 
-    public static final boolean [] VALID_NAMES = new boolean[127];
+    private static final boolean [] VALID_NAMES = new boolean[127];
 
     /**
      * Debug printing of buffer. This debugging flag works best when you
diff --git a/jaxp/src/javax/xml/stream/XMLEventFactory.java b/jaxp/src/javax/xml/stream/XMLEventFactory.java
index 9f9e86e..f92d778 100644
--- a/jaxp/src/javax/xml/stream/XMLEventFactory.java
+++ b/jaxp/src/javax/xml/stream/XMLEventFactory.java
@@ -49,6 +49,10 @@
 public abstract class XMLEventFactory {
   protected XMLEventFactory(){}
 
+    static final String JAXPFACTORYID = "javax.xml.stream.XMLEventFactory";
+    static final String DEFAULIMPL = "com.sun.xml.internal.stream.events.XMLEventFactoryImpl";
+
+
   /**
    * Create a new instance of the factory
    * @throws FactoryConfigurationError if an instance of this factory cannot be loaded
@@ -57,8 +61,8 @@
     throws FactoryConfigurationError
   {
     return (XMLEventFactory) FactoryFinder.find(
-      "javax.xml.stream.XMLEventFactory",
-      "com.sun.xml.internal.stream.events.XMLEventFactoryImpl");
+      JAXPFACTORYID,
+      DEFAULIMPL);
   }
 
   /**
@@ -90,8 +94,8 @@
     throws FactoryConfigurationError
   {
     return (XMLEventFactory) FactoryFinder.find(
-      "javax.xml.stream.XMLEventFactory",
-      "com.sun.xml.internal.stream.events.XMLEventFactoryImpl");
+      JAXPFACTORYID,
+      DEFAULIMPL);
   }
 
   /**
@@ -114,7 +118,7 @@
           throws FactoryConfigurationError {
       try {
           //do not fallback if given classloader can't find the class, throw exception
-          return (XMLEventFactory) FactoryFinder.newInstance(factoryId, classLoader, false);
+          return (XMLEventFactory) FactoryFinder.find(factoryId, classLoader, null);
       } catch (FactoryFinder.ConfigurationError e) {
           throw new FactoryConfigurationError(e.getException(),
                   e.getMessage());
@@ -141,7 +145,7 @@
           throws FactoryConfigurationError {
       try {
           //do not fallback if given classloader can't find the class, throw exception
-          return (XMLEventFactory) FactoryFinder.newInstance(factoryId, classLoader, false);
+          return (XMLEventFactory) FactoryFinder.find(factoryId, classLoader, null);
       } catch (FactoryFinder.ConfigurationError e) {
           throw new FactoryConfigurationError(e.getException(),
                   e.getMessage());
diff --git a/jaxws/.hgtags b/jaxws/.hgtags
index 88d4b9c..04f0c35 100644
--- a/jaxws/.hgtags
+++ b/jaxws/.hgtags
@@ -199,6 +199,7 @@
 afb6d773328fa76cea65dc024a448cd931d111f2 jdk7u6-b23
 b8b85e62d2c5347df8cf2e825e51e3de178508ea jdk7u6-b24
 fb03d08f73e98f0dd67cb81632eb9b685de49b7e jdk7u6-b30
+739ffa9dffad4cc2febe66ca1c2d86496e80741a jdk7u6-b31
 739ffa9dffad4cc2febe66ca1c2d86496e80741a jdk7u7-b10
 e9a5a78329d0518efafd9f6f6149f359a7db4e2e jdk7u7-b30
 ed6262e7bb0db4cd116c31f3c88cbd7c0288de40 jdk7u7-b11
@@ -221,3 +222,20 @@
 ed609545e38c2e499437292c1541e4d1c2b8b992 jdk7u10-b16
 e63292c59ed8481864302cc3f53b498cbdea3470 jdk7u10-b17
 6a372e9b4ae978cdaf0b95277db31827794e2c1f jdk7u10-b18
+df3e4c85e26c651d098cddd546916a625fd777cd jdk7u10-b30
+55dcda93e8c8b5c3170def946de35dd0407eab59 jdk7u8-b01
+c025e953f655b375f27f8f94493ceeb43ef1d979 jdk7u8-b02
+705b60b56ead99d64d1b7302cba3a200ab048ff7 jdk7u8-b03
+d8e70e528bbfb0a3fd62936871edb3481e213ea8 jdk7u8-b04
+76e35b812e820e9cb5c9815ee03bd0b3240c749b jdk7u8-b05
+e878887a8ac51f20ce529da2c7a5a1a627670436 jdk7u10-b06
+d89923177680905d0de7501fd67949c2f8c3cb35 jdk7u10-b07
+27853948201f8c9696d00b2ed490bbcd74dfa6fa jdk7u10-b08
+aa14c4c7195613cce35e27b7b7c2cb0817121fd4 jdk7u10-b09
+e43fea2b28aa66647c2116cace8af3294c6bfa06 jdk7u12-b01
+452faa8d6ee8840c19080bee2aba70e48a256c6e jdk7u12-b02
+4362e3ae3e2be92961621f76578d78b1a3fa407c jdk7u12-b03
+2d9e8b5bfbb636b9668b77530a1b24c34fff017d jdk7u12-b04
+8df2f42e2628e7b8d2e0cd69786a1bdc2a8dbe32 jdk7u12-b05
+01111bd50d31c89fe671bccb1400c62a67c7055e jdk7u12-b06
+42ba62cdc1f3c357b6d192612dd1c4b209df2662 jdk7u12-b07
diff --git a/jdk/.hgtags b/jdk/.hgtags
index f19639d..0ee4da7 100644
--- a/jdk/.hgtags
+++ b/jdk/.hgtags
@@ -199,6 +199,7 @@
 0ae89e53f5300da1961984a7d81c220c7cf717d7 jdk7u6-b23
 1c775da998735711853cfe1ae1d6baddc5f12a66 jdk7u6-b24
 4bd0528374971157afd6372890f4250e1cf712d9 jdk7u6-b30
+8c2c5d63a17ee5aa85face026d6f60fb7d34aded jdk7u6-b31
 78e01a6ca8d30e8fc4eb297d297a098edfb3fec6 jdk7u7-b10
 9666d4e4bbf3f80614e246d5c15df86154544013 jdk7u7-b30
 94154c14973aee7c5ff4846af7bcb71fe7a82fa5 jdk7u7-b11
@@ -221,3 +222,20 @@
 ed59989fb0635f2d4461173e218c43494f06bb82 jdk7u10-b16
 a1c5bac982a6d4aa58f551cb46cde53f526aca48 jdk7u10-b17
 115d1e4365293846bbc911cf312886c471e37fbd jdk7u10-b18
+84218dff5e4c7bc00fd9266769c0d12bdde866f5 jdk7u10-b30
+df945ef30444adf08f3ef14b0c49c8bda6dda587 jdk7u8-b01
+dd1e513c05b8b8c8402e9ecf9c0d5bdbebb1a089 jdk7u8-b02
+355cf1937d0824b54ac38ee5a5496197647840f9 jdk7u8-b03
+d099fc840e6c0f07e7b6f52d11fae98ae217bc9a jdk7u8-b04
+1c3a91a1dabdcd7e4407f9e7be08718339eafaad jdk7u8-b05
+147401296df6355464007cfb16f76dfe4d6b9fa6 jdk7u10-b06
+fd190f90dc174c89f1bc447aab800f4eb99edda5 jdk7u10-b07
+cd32baf1524847463bab29b83b9fe33740a37313 jdk7u10-b08
+a5b1c01d1929f6b3e9d49e70db3d0263e11c9ab4 jdk7u10-b09
+448626eae40d303a2627a0b3613a98d32d4419f1 jdk7u12-b01
+c49b6f0315799a9deadf8f4661c67ed2dd1bfcfb jdk7u12-b02
+c4f6412aa2dee96cb209b37a0c6ebb4bea482d2c jdk7u12-b03
+0d25ad745892a146e8e4e1fb7caeeee7739b7019 jdk7u12-b04
+fdd0d43ba0f9c3f58959e2de7d1958f771d84565 jdk7u12-b05
+b5449e3dcf1f317002840dc5c2093be47c60fe8c jdk7u12-b06
+cb81ee79a72d84f99b8e7d73b5ae73124b661fe7 jdk7u12-b07
diff --git a/jdk/make/com/sun/java/pack/Makefile b/jdk/make/com/sun/java/pack/Makefile
index c4973fc..d5a55c1 100644
--- a/jdk/make/com/sun/java/pack/Makefile
+++ b/jdk/make/com/sun/java/pack/Makefile
@@ -75,8 +75,8 @@
   OTHER_CXXFLAGS += $(ZINCLUDE)
   LDDFLAGS += $(ZIPOBJS)
  else
-  LDDFLAGS += -lz
-  OTHER_CXXFLAGS += -DSYSTEM_ZLIB
+  LDDFLAGS += $(ZLIB_LIBS)
+  OTHER_CXXFLAGS += $(ZLIB_CFLAGS) -DSYSTEM_ZLIB
  endif
 else
   OTHER_CXXFLAGS += -DNO_ZLIB -DUNPACK_JNI
diff --git a/jdk/make/common/Defs-linux.gmk b/jdk/make/common/Defs-linux.gmk
index 86668f4..db83599 100644
--- a/jdk/make/common/Defs-linux.gmk
+++ b/jdk/make/common/Defs-linux.gmk
@@ -112,21 +112,18 @@
 # since objcopy is optional, we set ZIP_DEBUGINFO_FILES later
 
 ifeq ($(ENABLE_FULL_DEBUG_SYMBOLS),1)
-  # Default OBJCOPY comes from GNU Binutils on Linux:
-  DEF_OBJCOPY=/usr/bin/objcopy
-  ifdef CROSS_COMPILE_ARCH
-    # don't try to generate .debuginfo files when cross compiling
-    _JUNK_ := $(shell \
-      echo >&2 "INFO: cross compiling for ARCH $(CROSS_COMPILE_ARCH)," \
-        "skipping .debuginfo generation.")
-    OBJCOPY=
+  ifndef CROSS_COMPILE_ARCH
+    # Default OBJCOPY comes from GNU Binutils on Linux:
+    DEF_OBJCOPY=/usr/bin/objcopy
   else
-    OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
-    ifneq ($(ALT_OBJCOPY),)
-      _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
-      # disable .debuginfo support by setting ALT_OBJCOPY to a non-existent path
-      OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
-    endif
+    # Assume objcopy is part of the cross-compilation toolkit
+    DEF_OBJCOPY=$(COMPILER_PATH)/objcopy
+  endif
+  OBJCOPY=$(shell test -x $(DEF_OBJCOPY) && echo $(DEF_OBJCOPY))
+  ifneq ($(ALT_OBJCOPY),)
+    _JUNK_ := $(shell echo >&2 "INFO: ALT_OBJCOPY=$(ALT_OBJCOPY)")
+    # disable .debuginfo support by setting ALT_OBJCOPY to a non-existent path
+    OBJCOPY=$(shell test -x $(ALT_OBJCOPY) && echo $(ALT_OBJCOPY))
   endif
 
   # Setting ENABLE_FULL_DEBUG_SYMBOLS=1 (and OBJCOPY) above enables the
@@ -138,7 +135,7 @@
 
   ifeq ($(OBJCOPY),)
     _JUNK_ := $(shell \
-      echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files.")
+      echo >&2 "INFO: no objcopy cmd found so cannot create .debuginfo files. You may need to set ALT_OBJCOPY.")
     ENABLE_FULL_DEBUG_SYMBOLS=0
   else
     _JUNK_ := $(shell \
diff --git a/jdk/make/common/Demo.gmk b/jdk/make/common/Demo.gmk
index a3788ae..429c4e5 100644
--- a/jdk/make/common/Demo.gmk
+++ b/jdk/make/common/Demo.gmk
@@ -158,6 +158,8 @@
     #       bit between them.
     LINK.demo   = $(LINK.c)
     LDLIBS.demo = $(EXTRA_LIBS) $(LFLAGS_$(COMPILER_VERSION))
+    DEMO_VERSION_INFO = $(OBJDIR)/$(LIBRARY).res
+    LDLIBS.demo += $(DEMO_VERSION_INFO)
   else
     ifneq ($(DEMO_NEEDS_CPP),)
       LINK.demo   = $(LINK.cpp)
@@ -288,6 +290,13 @@
 	$(install-file)
 endif
 
+ifeq ($(PLATFORM),windows)
+# JDK name required here
+RC_FLAGS += /D "JDK_FNAME=$(LIBRARY).dll" \
+            /D "JDK_INTERNAL_NAME=$(LIBRARY)" \
+            /D "JDK_FTYPE=0x2L"
+endif
+
 # Native library building
 ifdef DEMO_LIBRARY
 
@@ -308,6 +317,9 @@
   # Actual creation of the native shared library (C++ and C are different)
 $(DEMO_LIBRARY): $(DEMO_FULL_OBJECTS)
 	@$(prep-target)
+  ifeq ($(PLATFORM),windows)
+	$(RC) $(RC_FLAGS) $(CC_OBJECT_OUTPUT_FLAG)$(DEMO_VERSION_INFO) $(VERSIONINFO_RESOURCE)
+  endif
 	$(LINK.demo) $(SHARED_LIBRARY_FLAG) $(CC_PROGRAM_OUTPUT_FLAG)$@ \
 	    $(DEMO_FULL_OBJECTS) $(LDLIBS.demo)
 	@$(call binary_file_verification,$@)
diff --git a/jdk/make/common/Program.gmk b/jdk/make/common/Program.gmk
index 2ebcecf..091800d 100644
--- a/jdk/make/common/Program.gmk
+++ b/jdk/make/common/Program.gmk
@@ -91,7 +91,7 @@
   LDFLAGS += $(OUTPUTDIR)/tmp/java/jli/$(OBJDIRNAME)/static/libjli.a
 
   ifeq ($(SYSTEM_ZLIB),true)
-    OTHER_LDLIBS += -lz
+    OTHER_LDLIBS += $(ZLIB_LIBS)
   endif # SYSTEM_ZLIB
 endif # PLATFORM
 
diff --git a/jdk/make/common/Release.gmk b/jdk/make/common/Release.gmk
index c3db363..4802c3b 100644
--- a/jdk/make/common/Release.gmk
+++ b/jdk/make/common/Release.gmk
@@ -158,7 +158,6 @@
         jstack.1           \
         jstat.1            \
         jstatd.1           \
-        jvisualvm.1        \
 	native2ascii.1     \
 	rmic.1             \
         schemagen.1        \
@@ -167,6 +166,10 @@
         wsimport.1         \
         xjc.1
 
+ifndef OPENJDK
+  JDK_MAN_PAGES += jvisualvm.1
+endif
+
 ifeq ($(PLATFORM), solaris)
   MANBASEDIRS=$(JDK_TOPDIR)/src/solaris/doc $(IMPORTDOCDIR)
   MAN1SUBDIR=sun/man/man1
diff --git a/jdk/make/common/shared/Defs-java.gmk b/jdk/make/common/shared/Defs-java.gmk
index a38c5d0..12c7497 100644
--- a/jdk/make/common/shared/Defs-java.gmk
+++ b/jdk/make/common/shared/Defs-java.gmk
@@ -156,7 +156,7 @@
 
 # Needed for javadoc to ensure it builds documentation
 # against the newly built classes
-JAVADOCFLAGS += -bootclasspath $(CLASSBINDIR)
+JAVADOCFLAGS += -bootclasspath "$(CLASSBINDIR)$(JCE_PATH)"
 
 # Needed for JAVADOC and BOOT_JAVACFLAGS
 NO_PROPRIETARY_API_WARNINGS = -XDignore.symbol.file=true
diff --git a/jdk/make/common/shared/Defs-linux.gmk b/jdk/make/common/shared/Defs-linux.gmk
index ecdf5d7..3238805 100644
--- a/jdk/make/common/shared/Defs-linux.gmk
+++ b/jdk/make/common/shared/Defs-linux.gmk
@@ -129,6 +129,11 @@
 BUILD_HEADLESS = true
 LIBM=-lm
 
+# Set ZLIB_LIBS if not already set
+ifeq ("$(ZLIB_LIBS)", "")
+  ZLIB_LIBS=-lz
+endif
+
 # GCC29_COMPILER_PATH: is the path to where the gcc 2.9 compiler is installed
 #  NOTE: Must end with / so that it could be empty, allowing PATH usage.
 ifdef ALT_GCC29_COMPILER_PATH
diff --git a/jdk/make/common/shared/Defs-macosx.gmk b/jdk/make/common/shared/Defs-macosx.gmk
index b966296..1bd9b92 100644
--- a/jdk/make/common/shared/Defs-macosx.gmk
+++ b/jdk/make/common/shared/Defs-macosx.gmk
@@ -143,6 +143,11 @@
   _CUPS_HEADERS_PATH=$(PACKAGE_PATH)/include
 endif
 
+# Set ZLIB_LIBS if not already set
+ifeq ("$(ZLIB_LIBS)", "")
+  ZLIB_LIBS=-lz
+endif
+
 # Import JDK images allow for partial builds, components not built are
 #    imported (or copied from) these import areas when needed.
 
diff --git a/jdk/make/common/shared/Defs-solaris.gmk b/jdk/make/common/shared/Defs-solaris.gmk
index 261583d..ec1dd14 100644
--- a/jdk/make/common/shared/Defs-solaris.gmk
+++ b/jdk/make/common/shared/Defs-solaris.gmk
@@ -140,6 +140,11 @@
 
 _CUPS_HEADERS_PATH=/opt/sfw/cups/include
 
+# Set ZLIB_LIBS if not already set
+ifeq ("$(ZLIB_LIBS)", "")
+  ZLIB_LIBS=-lz
+endif
+
 # Import JDK images allow for partial builds, components not built are
 #    imported (or copied from) these import areas when needed.
 
diff --git a/jdk/make/docs/Makefile b/jdk/make/docs/Makefile
index a9e55b7..830a49e 100644
--- a/jdk/make/docs/Makefile
+++ b/jdk/make/docs/Makefile
@@ -47,11 +47,11 @@
 
 # Url to devdocs page
 #   Was: http://java.sun.com/javase/6/webnotes/devdocs-vs-specs.html
-DEV_DOCS_URL-5 = http://java.sun.com/j2se/1.5.0/docs/index.html
-DEV_DOCS_URL-6 = http://download.oracle.com/javase/6/docs/index.html
-DEV_DOCS_URL-7 = http://download.oracle.com/javase/7/docs/index.html
+DEV_DOCS_URL-5 = http://docs.oracle.com/javase/1.5.0/docs/index.html
+DEV_DOCS_URL-6 = http://docs.oracle.com/javase/6/docs/index.html
+DEV_DOCS_URL-7 = http://docs.oracle.com/javase/7/docs/index.html
 DEV_DOCS_URL = $(DEV_DOCS_URL-$(JDK_MINOR_VERSION))
-DOCS_BASE_URL = http://download.oracle.com/javase/7/docs
+DOCS_BASE_URL = http://docs.oracle.com/javase/7/docs
 
 # Url to Java Language Spec
 #JLS3_URL = http://java.sun.com/docs/books/jls/
diff --git a/jdk/make/java/java/mapfile-vers b/jdk/make/java/java/mapfile-vers
index 74523b4..b788119 100644
--- a/jdk/make/java/java/mapfile-vers
+++ b/jdk/make/java/java/mapfile-vers
@@ -79,7 +79,7 @@
 		Java_java_io_FileInputStream_close0;
 		Java_java_io_FileInputStream_initIDs;
 		Java_java_io_FileInputStream_open;
-		Java_java_io_FileInputStream_read;
+		Java_java_io_FileInputStream_read0;
 		Java_java_io_FileInputStream_readBytes;
 		Java_java_io_FileInputStream_skip;
 		Java_java_io_FileOutputStream_close0;
@@ -90,7 +90,6 @@
 		Java_java_io_FileSystem_getFileSystem;
 		Java_java_io_ObjectInputStream_bytesToDoubles;
 		Java_java_io_ObjectInputStream_bytesToFloats;
-		Java_java_io_ObjectInputStream_latestUserDefinedLoader;
 		Java_java_io_ObjectOutputStream_doublesToBytes;
 		Java_java_io_ObjectOutputStream_floatsToBytes;
 		Java_java_io_ObjectStreamClass_hasStaticInitializer;
@@ -100,12 +99,12 @@
 		Java_java_io_RandomAccessFile_initIDs;
 		Java_java_io_RandomAccessFile_length;
 		Java_java_io_RandomAccessFile_open;
-		Java_java_io_RandomAccessFile_read;
-		Java_java_io_RandomAccessFile_readBytes;
+		Java_java_io_RandomAccessFile_read0;
+		Java_java_io_RandomAccessFile_readBytes0;
 		Java_java_io_RandomAccessFile_seek;
 		Java_java_io_RandomAccessFile_setLength;
-		Java_java_io_RandomAccessFile_write;
-		Java_java_io_RandomAccessFile_writeBytes;
+		Java_java_io_RandomAccessFile_write0;
+		Java_java_io_RandomAccessFile_writeBytes0;
 		Java_java_io_UnixFileSystem_canonicalize0;
 		Java_java_io_UnixFileSystem_checkAccess;
 		Java_java_io_UnixFileSystem_createDirectory;
@@ -275,6 +274,7 @@
                 Java_sun_misc_Version_getJvmVersionInfo;
                 Java_sun_misc_Version_getJvmSpecialVersion;
                 Java_sun_misc_VM_getThreadStateValues;
+		Java_sun_misc_VM_latestUserDefinedLoader;
                 Java_sun_misc_VM_initialize;
 		Java_sun_misc_VMSupport_initAgentProperties;
 
diff --git a/jdk/make/java/jli/Makefile b/jdk/make/java/jli/Makefile
index 4d9de79..70be3e8 100644
--- a/jdk/make/java/jli/Makefile
+++ b/jdk/make/java/jli/Makefile
@@ -46,6 +46,8 @@
 
 ifneq ($(SYSTEM_ZLIB),true)
   ZIP_SRC = $(SHARE_SRC)/native/java/util/zip/zlib-$(ZLIB_VERSION)
+else # SYSTEM_ZLIB
+  OTHER_CFLAGS += $(ZLIB_CFLAGS)
 endif #SYSTEM_ZLIB
 LAUNCHER_SHARE_SRC = $(SHARE_SRC)/bin
 
@@ -162,7 +164,7 @@
 ifneq ($(SYSTEM_ZLIB),true)
   OTHER_INCLUDES += -I$(ZIP_SRC)
 else # !SYSTEM_ZLIB
-  LDLIBS += -lz
+  LDLIBS += $(ZLIB_LIBS)
 endif # SYSTEM_ZLIB
 
 #
diff --git a/jdk/make/java/nio/Makefile b/jdk/make/java/nio/Makefile
index 505c05e..620e56c 100644
--- a/jdk/make/java/nio/Makefile
+++ b/jdk/make/java/nio/Makefile
@@ -54,6 +54,9 @@
 	sun/nio/ch/DevPollArrayWrapper.java \
 	sun/nio/ch/DevPollSelectorImpl.java \
         sun/nio/ch/DevPollSelectorProvider.java \
+	sun/nio/ch/EventPortSelectorImpl.java \
+	sun/nio/ch/EventPortSelectorProvider.java \
+	sun/nio/ch/EventPortWrapper.java \
 	sun/nio/ch/InheritedChannel.java \
         sun/nio/ch/PollSelectorProvider.java \
         sun/nio/ch/PollSelectorImpl.java \
@@ -274,11 +277,13 @@
 	sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java \
 	sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
 	\
-	sun/nio/fs/GnomeFileTypeDetector.java \
 	sun/nio/fs/BsdFileStore.java \
 	sun/nio/fs/BsdFileSystem.java \
 	sun/nio/fs/BsdFileSystemProvider.java \
 	sun/nio/fs/BsdNativeDispatcher.java \
+	sun/nio/fs/MacOSXFileSystemProvider.java \
+	sun/nio/fs/MacOSXFileSystem.java \
+	sun/nio/fs/MacOSXNativeDispatcher.java \
 	sun/nio/fs/PollingWatchService.java \
 	sun/nio/fs/UnixChannelFactory.java \
 	sun/nio/fs/UnixCopyFile.java \
@@ -306,8 +311,8 @@
 	UnixAsynchronousServerSocketChannelImpl.c \
 	UnixAsynchronousSocketChannelImpl.c \
 	\
-	GnomeFileTypeDetector.c \
 	BsdNativeDispatcher.c \
+	MacOSXNativeDispatcher.c \
 	UnixCopyFile.c \
 	UnixNativeDispatcher.c \
 	\
@@ -322,7 +327,6 @@
 	sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java \
 	sun/nio/ch/UnixAsynchronousSocketChannelImpl.java \
 	\
-	sun/nio/fs/GnomeFileTypeDetector.java \
 	sun/nio/fs/BsdNativeDispatcher.java \
 	sun/nio/fs/UnixCopyFile.java \
 	sun/nio/fs/UnixNativeDispatcher.java
@@ -382,7 +386,7 @@
 OTHER_LDLIBS += -L$(LIBDIR)/$(LIBARCH) -ljava -lnet -lpthread $(LIBDL)
 endif
 ifeq ($(PLATFORM), macosx)
-OTHER_LDLIBS += -L$(LIBDIR) -ljava -lnet -pthread
+OTHER_LDLIBS += -L$(LIBDIR) -ljava -lnet -pthread -framework CoreFoundation
 endif
 ifeq ($(PLATFORM), solaris)
 OTHER_LDLIBS += $(JVMLIB) $(LIBSOCKET) -lposix4 $(LIBDL) -lsendfile \
diff --git a/jdk/make/java/nio/mapfile-bsd b/jdk/make/java/nio/mapfile-bsd
index b3f50ff..070646b 100644
--- a/jdk/make/java/nio/mapfile-bsd
+++ b/jdk/make/java/nio/mapfile-bsd
@@ -121,10 +121,6 @@
 		Java_sun_nio_fs_BsdNativeDispatcher_getfsstat;
 		Java_sun_nio_fs_BsdNativeDispatcher_fsstatEntry;
 		Java_sun_nio_fs_BsdNativeDispatcher_endfsstat;
-		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGio;
-		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
-		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
-		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGnomeVfs;
 		Java_sun_nio_fs_UnixNativeDispatcher_init;
 		Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
 		Java_sun_nio_fs_UnixNativeDispatcher_strerror;
@@ -170,7 +166,6 @@
 		Java_sun_nio_fs_UnixNativeDispatcher_getgrgid;
 		Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0;
 		Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0;
-		Java_sun_nio_fs_UnixNativeDispatcher_getextmntent;
 		Java_sun_nio_fs_UnixCopyFile_transfer;
 		handleSocketError;
 
diff --git a/jdk/make/java/nio/mapfile-linux b/jdk/make/java/nio/mapfile-linux
index 4fd1058..4cc3b29 100644
--- a/jdk/make/java/nio/mapfile-linux
+++ b/jdk/make/java/nio/mapfile-linux
@@ -39,7 +39,6 @@
                 Java_sun_nio_ch_EPollArrayWrapper_epollCreate;
                 Java_sun_nio_ch_EPollArrayWrapper_epollCtl;
                 Java_sun_nio_ch_EPollArrayWrapper_epollWait;
-		Java_sun_nio_ch_EPollArrayWrapper_fdLimit;
 		Java_sun_nio_ch_EPollArrayWrapper_init;
 		Java_sun_nio_ch_EPollArrayWrapper_interrupt;
 		Java_sun_nio_ch_EPollArrayWrapper_offsetofData;
@@ -87,6 +86,7 @@
                 Java_sun_nio_ch_IOUtil_configureBlocking;
                 Java_sun_nio_ch_IOUtil_drain;
                 Java_sun_nio_ch_IOUtil_fdVal;
+		Java_sun_nio_ch_IOUtil_fdLimit;
                 Java_sun_nio_ch_IOUtil_initIDs;
 		Java_sun_nio_ch_IOUtil_iovMax;
                 Java_sun_nio_ch_IOUtil_makePipe;
@@ -143,6 +143,7 @@
 		Java_sun_nio_fs_LinuxNativeDispatcher_fsetxattr0;
 		Java_sun_nio_fs_LinuxNativeDispatcher_fremovexattr0;
 		Java_sun_nio_fs_LinuxNativeDispatcher_setmntent0;
+                Java_sun_nio_fs_LinuxNativeDispatcher_getmntent;
 		Java_sun_nio_fs_LinuxNativeDispatcher_endmntent;
 		Java_sun_nio_fs_UnixNativeDispatcher_init;
 		Java_sun_nio_fs_UnixNativeDispatcher_getcwd;
@@ -189,7 +190,6 @@
 		Java_sun_nio_fs_UnixNativeDispatcher_getgrgid;
 		Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0;
 		Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0;
-		Java_sun_nio_fs_UnixNativeDispatcher_getextmntent;
 		Java_sun_nio_fs_UnixCopyFile_transfer;
 		handleSocketError;
 
diff --git a/jdk/make/java/nio/mapfile-solaris b/jdk/make/java/nio/mapfile-solaris
index b4b68ab..e05ea72 100644
--- a/jdk/make/java/nio/mapfile-solaris
+++ b/jdk/make/java/nio/mapfile-solaris
@@ -36,7 +36,6 @@
                 Java_sun_nio_ch_DatagramDispatcher_readv0;
                 Java_sun_nio_ch_DatagramDispatcher_write0;
                 Java_sun_nio_ch_DatagramDispatcher_writev0;
-                Java_sun_nio_ch_DevPollArrayWrapper_fdLimit;
                 Java_sun_nio_ch_DevPollArrayWrapper_init;
                 Java_sun_nio_ch_DevPollArrayWrapper_interrupt;
                 Java_sun_nio_ch_DevPollArrayWrapper_poll0;
@@ -74,6 +73,7 @@
 		Java_sun_nio_ch_InheritedChannel_soType0;
                 Java_sun_nio_ch_IOUtil_configureBlocking;
                 Java_sun_nio_ch_IOUtil_drain;
+		Java_sun_nio_ch_IOUtil_fdLimit;
                 Java_sun_nio_ch_IOUtil_fdVal;
                 Java_sun_nio_ch_IOUtil_initIDs;
 		Java_sun_nio_ch_IOUtil_iovMax;
@@ -113,13 +113,13 @@
 		Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_accept0;
 		Java_sun_nio_ch_UnixAsynchronousServerSocketChannelImpl_initIDs;
 		Java_sun_nio_ch_UnixAsynchronousSocketChannelImpl_checkConnect;
-		Java_sun_nio_ch_SolarisEventPort_init;
-		Java_sun_nio_ch_SolarisEventPort_portCreate;
-		Java_sun_nio_ch_SolarisEventPort_portClose;
-		Java_sun_nio_ch_SolarisEventPort_portAssociate;
-		Java_sun_nio_ch_SolarisEventPort_portGet;
-		Java_sun_nio_ch_SolarisEventPort_portGetn;
-		Java_sun_nio_ch_SolarisEventPort_portSend;
+		Java_sun_nio_ch_SolarisEventPort_port_1create;
+		Java_sun_nio_ch_SolarisEventPort_port_1close;
+		Java_sun_nio_ch_SolarisEventPort_port_1associate;
+		Java_sun_nio_ch_SolarisEventPort_port_1dissociate;
+		Java_sun_nio_ch_SolarisEventPort_port_1get;
+		Java_sun_nio_ch_SolarisEventPort_port_1getn;
+		Java_sun_nio_ch_SolarisEventPort_port_1send;
 		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGio;
 		Java_sun_nio_fs_GnomeFileTypeDetector_probeUsingGio;
 		Java_sun_nio_fs_GnomeFileTypeDetector_initializeGnomeVfs;
@@ -169,10 +169,10 @@
 		Java_sun_nio_fs_UnixNativeDispatcher_getgrgid;
 		Java_sun_nio_fs_UnixNativeDispatcher_getpwnam0;
 		Java_sun_nio_fs_UnixNativeDispatcher_getgrnam0;
-		Java_sun_nio_fs_UnixNativeDispatcher_getextmntent;
 		Java_sun_nio_fs_UnixCopyFile_transfer;
 		Java_sun_nio_fs_SolarisNativeDispatcher_init;
 		Java_sun_nio_fs_SolarisNativeDispatcher_facl;
+		Java_sun_nio_fs_SolarisNativeDispatcher_getextmntent;
 		Java_sun_nio_fs_SolarisWatchService_init;
 		Java_sun_nio_fs_SolarisWatchService_portCreate;
 		Java_sun_nio_fs_SolarisWatchService_portAssociate;
diff --git a/jdk/make/java/security/Makefile b/jdk/make/java/security/Makefile
index 4cbc60f..2b72f35 100644
--- a/jdk/make/java/security/Makefile
+++ b/jdk/make/java/security/Makefile
@@ -37,7 +37,8 @@
 # Directories
 #
 
-PROPS_SRC   = $(TOPDIR)/src/share/lib/security/java.security
+# The default security properties file is for linux
+PROPS_SRC   = $(TOPDIR)/src/share/lib/security/java.security-linux
 
 ifeq ($(PLATFORM), solaris)
 PROPS_SRC   = $(TOPDIR)/src/share/lib/security/java.security-solaris
diff --git a/jdk/make/java/zip/Makefile b/jdk/make/java/zip/Makefile
index 5955335..e1d3c5b 100644
--- a/jdk/make/java/zip/Makefile
+++ b/jdk/make/java/zip/Makefile
@@ -56,6 +56,10 @@
   endif
 endif
 
+ifeq ($(SYSTEM_ZLIB),true)
+  OTHER_CFLAGS += $(ZLIB_CFLAGS)
+endif
+
 #
 # Library to compile.
 #
@@ -90,7 +94,7 @@
 # Link to JVM library for JVM_Zip* functions
 #
 ifeq ($(SYSTEM_ZLIB),true)
-OTHER_LDLIBS = -lz
+OTHER_LDLIBS = $(ZLIB_LIBS)
 else
 OTHER_LDLIBS = $(JVMLIB)
 endif
diff --git a/jdk/make/java/zip/mapfile-vers b/jdk/make/java/zip/mapfile-vers
index f150452..836b0f8 100644
--- a/jdk/make/java/zip/mapfile-vers
+++ b/jdk/make/java/zip/mapfile-vers
@@ -36,16 +36,12 @@
 		Java_java_util_zip_Deflater_deflateBytes;
 		Java_java_util_zip_Deflater_end;
 		Java_java_util_zip_Deflater_getAdler;
-		Java_java_util_zip_Deflater_getBytesRead;
-		Java_java_util_zip_Deflater_getBytesWritten;
 		Java_java_util_zip_Deflater_init;
 		Java_java_util_zip_Deflater_initIDs;
 		Java_java_util_zip_Deflater_reset;
 		Java_java_util_zip_Deflater_setDictionary;
 		Java_java_util_zip_Inflater_end;
 		Java_java_util_zip_Inflater_getAdler;
-		Java_java_util_zip_Inflater_getBytesRead;
-		Java_java_util_zip_Inflater_getBytesWritten;
 		Java_java_util_zip_Inflater_inflateBytes;
 		Java_java_util_zip_Inflater_init;
 		Java_java_util_zip_Inflater_initIDs;
diff --git a/jdk/make/javax/crypto/Makefile b/jdk/make/javax/crypto/Makefile
index b9eee08..4dcf097 100644
--- a/jdk/make/javax/crypto/Makefile
+++ b/jdk/make/javax/crypto/Makefile
@@ -156,7 +156,12 @@
 #
 
 ifdef OPENJDK
-all: build-jar install-jar build-policy install-limited
+ifdef UNLIMITED_CRYPTO
+POLICY = install-unlimited
+else
+POLICY = install-limited
+endif
+all: build-jar install-jar build-policy $(POLICY)
 else  # OPENJDK
 ifeq ($(strip $(FILES_java)),)
 all:
diff --git a/jdk/make/jdk_generic_profile.sh b/jdk/make/jdk_generic_profile.sh
index 0190fc6..93aa1cd 100644
--- a/jdk/make/jdk_generic_profile.sh
+++ b/jdk/make/jdk_generic_profile.sh
@@ -378,3 +378,22 @@
     export LLVM_LIBS
   fi
 fi
+
+# Export variables for system zlib
+# ZLIB_CFLAGS and ZLIB_LIBS tell the compiler how to compile and
+# link against zlib
+pkgconfig=$(which pkg-config 2>/dev/null)
+if [ -x "${pkgconfig}" ] ; then
+  if [ "${ZLIB_CFLAGS}" = "" ] ; then
+    ZLIB_CFLAGS=$("${pkgconfig}" --cflags zlib)
+  fi
+  if [ "${ZLIB_LIBS}" = "" ] ; then
+    ZLIB_LIBS=$("${pkgconfig}" --libs zlib)
+  fi
+fi
+if [ "${ZLIB_LIBS}" = "" ] ; then
+    ZLIB_LIBS="-lz"
+fi
+export ZLIB_CFLAGS
+export ZLIB_LIBS
+
diff --git a/jdk/make/jprt.properties b/jdk/make/jprt.properties
index df1bfbb..6176952 100644
--- a/jdk/make/jprt.properties
+++ b/jdk/make/jprt.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2012, 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
@@ -77,20 +77,17 @@
     ${jprt.my.test.target.set:TESTNAME=jdk_util},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_io},			\
     ${jprt.my.test.target.set:TESTNAME=jdk_net},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_nio1},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_nio2},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_nio3},		\
+    ${jprt.my.test.target.set:TESTNAME=jdk_nio},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_security1},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_security2},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_security3},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_rmi},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_management1},	\
-    ${jprt.my.test.target.set:TESTNAME=jdk_management2},	\
+    ${jprt.my.test.target.set:TESTNAME=jdk_management},		\
+    ${jprt.my.test.target.set:TESTNAME=jdk_jmx},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_text},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_tools1},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_tools2},		\
+    ${jprt.my.test.target.set:TESTNAME=jdk_tools},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_jfr},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_misc}
+    ${jprt.my.test.target.set:TESTNAME=jdk_other}
 
 # All vm test targets (testset=all)
 jprt.vm.all.test.targets=                                       \
@@ -105,6 +102,7 @@
     ${jprt.my.test.target.set:TESTNAME=jdk_beans1},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_beans2},             \
     ${jprt.my.test.target.set:TESTNAME=jdk_beans3},             \
+    ${jprt.my.test.target.set:TESTNAME=jdk_jdi},                \
     ${jprt.my.test.target.set:TESTNAME=jdk_sound},              \
     ${jprt.my.test.target.set:TESTNAME=jdk_swing}
 
diff --git a/jdk/make/netbeans/jconsole/build.xml b/jdk/make/netbeans/jconsole/build.xml
index a696067..9c1fc95 100644
--- a/jdk/make/netbeans/jconsole/build.xml
+++ b/jdk/make/netbeans/jconsole/build.xml
@@ -50,6 +50,7 @@
             <fileset dir="${classes.dir}">
                 <include name="sun/tools/jconsole/**/*.class"/>
                 <include name="com/sun/tools/jconsole/**/*.class"/>
+                <include name="sun/tools/jconsole/resources/*.properties"/>
                 <include name="sun/tools/jconsole/resources/*.gif"/>
                 <include name="sun/tools/jconsole/resources/*.png"/>
             </fileset>
diff --git a/jdk/make/sun/jconsole/FILES.gmk b/jdk/make/sun/jconsole/FILES.gmk
index 61085e6..8fc34ac 100644
--- a/jdk/make/sun/jconsole/FILES.gmk
+++ b/jdk/make/sun/jconsole/FILES.gmk
@@ -30,17 +30,22 @@
 MANIFEST = sun/tools/jconsole/manifest
 
 PNG_FILES = \
-	sun/tools/jconsole/resources/brandlogo.png \
-	sun/tools/jconsole/resources/collapse-winlf.png \
-	sun/tools/jconsole/resources/connected16.png \
-	sun/tools/jconsole/resources/connected24.png \
-	sun/tools/jconsole/resources/disconnected16.png \
-	sun/tools/jconsole/resources/disconnected24.png \
-	sun/tools/jconsole/resources/expand-winlf.png \
-	sun/tools/jconsole/resources/masthead-left.png \
-	sun/tools/jconsole/resources/masthead-right.png
+  sun/tools/jconsole/resources/brandlogo.png \
+  sun/tools/jconsole/resources/collapse-winlf.png \
+  sun/tools/jconsole/resources/connected16.png \
+  sun/tools/jconsole/resources/connected24.png \
+  sun/tools/jconsole/resources/disconnected16.png \
+  sun/tools/jconsole/resources/disconnected24.png \
+  sun/tools/jconsole/resources/expand-winlf.png \
+  sun/tools/jconsole/resources/masthead-left.png \
+  sun/tools/jconsole/resources/masthead-right.png
 
 GIF_FILES = \
-	sun/tools/jconsole/resources/mbean.gif \
-	sun/tools/jconsole/resources/mbeanserverdelegate.gif \
-	sun/tools/jconsole/resources/xobject.gif
+  sun/tools/jconsole/resources/mbean.gif \
+  sun/tools/jconsole/resources/mbeanserverdelegate.gif \
+  sun/tools/jconsole/resources/xobject.gif
+
+PROP_FILES = \
+  sun/tools/jconsole/resources/messages.properties \
+  sun/tools/jconsole/resources/messages_ja.properties \
+  sun/tools/jconsole/resources/messages_zh_CN.properties
diff --git a/jdk/make/sun/jconsole/Makefile b/jdk/make/sun/jconsole/Makefile
index da0200d..c2651ce 100644
--- a/jdk/make/sun/jconsole/Makefile
+++ b/jdk/make/sun/jconsole/Makefile
@@ -53,21 +53,21 @@
 
 FILES_png = $(PNG_FILES:%.png=$(CLASSBINDIR)/%.png)
 FILES_gif = $(GIF_FILES:%.gif=$(CLASSBINDIR)/%.gif)
-
+FILES_prop = $(PROP_FILES:%.properties=$(CLASSBINDIR)/%.properties)
 build: $(GENSRCDIR)/sun/tools/jconsole/Version.java
 
 #
 # Resources
 #
 LOCALE_SET_DEFINITION = jdk
-RESOURCE_BUNDLES_JAVA = $(PKGDIR)/resources/JConsoleResources.java
+RESOURCE_BUNDLES_UNCOMPILED_PROPERTIES = $(PKGDIR)/resources/messages.properties
 
 #
 # Rules.
 #
 include $(BUILDDIR)/common/Classes.gmk
 
-build: $(FILES_png) $(FILES_gif) $(TEMPDIR)/manifest $(JARFILE)
+build: $(FILES_png) $(FILES_gif) $(FILES_prop) $(TEMPDIR)/manifest $(JARFILE)
 
 $(GENSRCDIR)/sun/tools/jconsole/Version.java: \
                 $(SHARE_SRC)/classes/sun/tools/jconsole/Version.java.template
@@ -85,7 +85,7 @@
 # Extra rule to build jconsole.jar
 #
 
-$(JARFILE): $(LIBDIR) $(FILES_class) $(FILES_png) $(FILES_gif) $(TEMPDIR)/manifest
+$(JARFILE): $(LIBDIR) $(FILES_class) $(FILES_png) $(FILES_gif) $(FILES_prop) $(TEMPDIR)/manifest
 	$(BOOT_JAR_CMD) -cfm $(JARFILE) $(TEMPDIR)/manifest \
                -C $(CLASSBINDIR) sun/tools/jconsole \
                -C $(CLASSBINDIR) com/sun/tools/jconsole \
diff --git a/jdk/make/sun/rmi/cgi/Makefile b/jdk/make/sun/rmi/cgi/Makefile
index 0400417..48a0805 100644
--- a/jdk/make/sun/rmi/cgi/Makefile
+++ b/jdk/make/sun/rmi/cgi/Makefile
@@ -28,6 +28,8 @@
 #
 
 BUILDDIR = ../../..
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
 # java-rmi.cgi is a JDK tool
 PACKAGE = sun.rmi
 PRODUCT = sun
diff --git a/jdk/make/sun/rmi/registry/Makefile b/jdk/make/sun/rmi/registry/Makefile
index bd5dffe..fbfa4b7 100644
--- a/jdk/make/sun/rmi/registry/Makefile
+++ b/jdk/make/sun/rmi/registry/Makefile
@@ -28,6 +28,9 @@
 #
 
 BUILDDIR = ../../..
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+JAVAC_LINT_OPTIONS = -Xlint:all,-deprecation
 PACKAGE = sun.rmi.registry
 PRODUCT = sun
 include $(BUILDDIR)/common/Defs.gmk
diff --git a/jdk/make/sun/rmi/rmi/Makefile b/jdk/make/sun/rmi/rmi/Makefile
index 1277772..4aecf02 100644
--- a/jdk/make/sun/rmi/rmi/Makefile
+++ b/jdk/make/sun/rmi/rmi/Makefile
@@ -28,18 +28,14 @@
 #
 
 BUILDDIR = ../../..
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
+JAVAC_LINT_OPTIONS = -Xlint:all,-deprecation
 PACKAGE = sun.rmi
 PRODUCT = sun
-LIBRARY = rmi
 include $(BUILDDIR)/common/Defs.gmk
 
 #
-# Add use of a mapfile
-#
-FILES_m = mapfile-vers
-include $(BUILDDIR)/common/Mapfile-vers.gmk
-
-#
 # Java files to compile.
 #
 AUTO_FILES_JAVA_DIRS = \
@@ -52,31 +48,9 @@
 	com/sun/rmi
 
 #
-# Native files to compile.
-#
-FILES_c = \
-	sun/rmi/server/MarshalInputStream.c
-
-#
-# Add ambient vpath to pick up files not part of sun.rmi package
-#
-vpath %.c $(SHARE_SRC)/native/sun/rmi/server
-
-#
-# Exported files that require generated .h 
-#
-FILES_export = \
-    sun/rmi/server/MarshalInputStream.java
-
-#
-# Link to JVM for JVM_LatestUserDefinedLoader
-#
-OTHER_LDLIBS = $(JVMLIB)
-
-#
 # Rules
 #
-include $(BUILDDIR)/common/Library.gmk
+include $(BUILDDIR)/common/Rules.gmk
 
 #
 # Full package names of implementations requiring stubs
diff --git a/jdk/make/sun/rmi/rmid/Makefile b/jdk/make/sun/rmi/rmid/Makefile
index c8f3ce6..10f36ce 100644
--- a/jdk/make/sun/rmi/rmid/Makefile
+++ b/jdk/make/sun/rmi/rmid/Makefile
@@ -29,6 +29,8 @@
 #
 
 BUILDDIR = ../../..
+JAVAC_MAX_WARNINGS = true
+JAVAC_WARNINGS_FATAL = true
 PACKAGE = sun.rmi.activation
 PRODUCT = sun
 include $(BUILDDIR)/common/Defs.gmk
diff --git a/jdk/make/sun/splashscreen/Makefile b/jdk/make/sun/splashscreen/Makefile
index 5b0e18a..1eb89e5 100644
--- a/jdk/make/sun/splashscreen/Makefile
+++ b/jdk/make/sun/splashscreen/Makefile
@@ -126,7 +126,8 @@
 ifneq ($(SYSTEM_ZLIB),true)
   CPPFLAGS += -I$(SHARE_SRC)/native/java/util/zip/zlib-$(ZLIB_VERSION)
 else
-  OTHER_LDLIBS += -lz
+  OTHER_CFLAGS += $(ZLIB_CFLAGS)
+  OTHER_LDLIBS += $(ZLIB_LIBS)
 endif
 
 # Shun the less than portable MMX assembly code in pnggccrd.c,
diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaPanelUI.java b/jdk/src/macosx/classes/com/apple/laf/AquaPanelUI.java
index 07a758f..960705b 100644
--- a/jdk/src/macosx/classes/com/apple/laf/AquaPanelUI.java
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaPanelUI.java
@@ -32,10 +32,20 @@
 import com.apple.laf.AquaUtils.RecyclableSingleton;
 import com.apple.laf.AquaUtils.RecyclableSingletonFromDefaultConstructor;
 
+import java.awt.Graphics;
+
 public class AquaPanelUI extends BasicPanelUI {
     static RecyclableSingleton<AquaPanelUI> instance = new RecyclableSingletonFromDefaultConstructor<AquaPanelUI>(AquaPanelUI.class);
 
     public static ComponentUI createUI(final JComponent c) {
         return instance.get();
     }
+
+    @Override
+    public final void update(final Graphics g, final JComponent c) {
+        if (c.isOpaque()) {
+            AquaUtils.fillRect(g, c);
+        }
+        paint(g, c);
+    }
 }
diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaRootPaneUI.java b/jdk/src/macosx/classes/com/apple/laf/AquaRootPaneUI.java
index e727712..6f3c1f2 100644
--- a/jdk/src/macosx/classes/com/apple/laf/AquaRootPaneUI.java
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaRootPaneUI.java
@@ -319,4 +319,12 @@
             updateComponentTreeUIActivation(element, active);
         }
     }
+
+    @Override
+    public final void update(final Graphics g, final JComponent c) {
+        if (c.isOpaque()) {
+            AquaUtils.fillRect(g, c);
+        }
+        paint(g, c);
+    }
 }
diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaToolBarUI.java b/jdk/src/macosx/classes/com/apple/laf/AquaToolBarUI.java
index 660cff3..bf87e2d 100644
--- a/jdk/src/macosx/classes/com/apple/laf/AquaToolBarUI.java
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaToolBarUI.java
@@ -73,9 +73,7 @@
             g.translate(x, y);
 
             if (c.isOpaque()) {
-                final Color background = c.getBackground();
-                g.setColor(background);
-                g.fillRect(0, 0, w - 1, h - 1);
+                AquaUtils.fillRect(g, c, c.getBackground(), 0, 0, w - 1, h - 1);
             }
 
             final Color oldColor = g.getColor();
@@ -137,4 +135,12 @@
             return true;
         }
     }
+
+    @Override
+    public final void update(final Graphics g, final JComponent c) {
+        if (c.isOpaque()) {
+            AquaUtils.fillRect(g, c);
+        }
+        paint(g, c);
+    }
 }
diff --git a/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java b/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java
index 58b0d1e..0592da7 100644
--- a/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java
+++ b/jdk/src/macosx/classes/com/apple/laf/AquaUtils.java
@@ -28,18 +28,19 @@
 import java.awt.*;
 import java.awt.image.*;
 import java.lang.ref.SoftReference;
-import java.lang.ref.WeakReference;
 import java.lang.reflect.Method;
 import java.security.PrivilegedAction;
 import java.util.*;
 
 import javax.swing.*;
 import javax.swing.border.Border;
+import javax.swing.plaf.UIResource;
 
 import sun.awt.AppContext;
 
 import sun.lwawt.macosx.CImage;
 import sun.lwawt.macosx.CImage.Creator;
+import sun.lwawt.macosx.CPlatformWindow;
 import sun.swing.SwingUtilities2;
 
 import com.apple.laf.AquaImageFactory.SlicedImageControl;
@@ -389,4 +390,51 @@
             return false;
         }
     }
+
+    protected static boolean isWindowTextured(final Component c) {
+        if (!(c instanceof JComponent)) {
+            return false;
+        }
+        final JRootPane pane = ((JComponent) c).getRootPane();
+        if (pane == null) {
+            return false;
+        }
+        Object prop = pane.getClientProperty(
+                CPlatformWindow.WINDOW_BRUSH_METAL_LOOK);
+        if (prop != null) {
+            return Boolean.parseBoolean(prop.toString());
+        }
+        prop = pane.getClientProperty(CPlatformWindow.WINDOW_STYLE);
+        return prop != null && "textured".equals(prop);
+    }
+
+    private static Color resetAlpha(final Color color) {
+        return new Color(color.getRed(), color.getGreen(), color.getBlue(), 0);
+    }
+
+    protected static void fillRect(final Graphics g, final Component c) {
+        fillRect(g, c, c.getBackground(), 0, 0, c.getWidth(), c.getHeight());
+    }
+
+    protected static void fillRect(final Graphics g, final Component c,
+                                   final Color color, final int x, final int y,
+                                   final int w, final int h) {
+        if (!(g instanceof Graphics2D)) {
+            return;
+        }
+        final Graphics2D cg = (Graphics2D) g.create();
+        try {
+            if (color instanceof UIResource && isWindowTextured(c)
+                    && color.equals(SystemColor.window)) {
+                cg.setComposite(AlphaComposite.Src);
+                cg.setColor(resetAlpha(color));
+            } else {
+                cg.setColor(color);
+            }
+            cg.fillRect(x, y, w, h);
+        } finally {
+            cg.dispose();
+        }
+    }
 }
+
diff --git a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java
index 97d71c7..29e0ac8 100644
--- a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java
+++ b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferences.java
@@ -33,16 +33,16 @@
     private static final String defaultAppName = "com.apple.java.util.prefs";
 
     // true if this node is a child of userRoot or is userRoot
-    private boolean isUser;
+    private final boolean isUser;
 
     // true if this node is userRoot or systemRoot
-    private boolean isRoot;
+    private final boolean isRoot;
 
     // CF's storage location for this node and its keys
-    private MacOSXPreferencesFile file;
+    private final MacOSXPreferencesFile file;
 
     // absolutePath() + "/"
-    private String path;
+    private final String path;
 
     // User root and system root nodes
     private static MacOSXPreferences userRoot = null;
@@ -71,36 +71,40 @@
 
     // Create a new root node. Called by getUserRoot() and getSystemRoot()
     // Synchronization is provided by the caller.
-    private MacOSXPreferences(boolean newIsUser)
-    {
-        super(null, "");
-        isUser = newIsUser;
-        isRoot = true;
-
-        initFields();
+    private MacOSXPreferences(boolean newIsUser) {
+        this(null, "", false, true, newIsUser);
     }
 
 
     // Create a new non-root node with the given parent.
     // Called by childSpi().
-    private MacOSXPreferences(MacOSXPreferences parent, String name)
+    private MacOSXPreferences(MacOSXPreferences parent, String name) {
+        this(parent, name, false, false, false);
+    }
+
+    private MacOSXPreferences(MacOSXPreferences parent, String name,
+                              boolean isNew)
+    {
+        this(parent, name, isNew, false, false);
+    }
+
+    private MacOSXPreferences(MacOSXPreferences parent, String name,
+                              boolean isNew, boolean isRoot, boolean isUser)
     {
         super(parent, name);
-        isUser = isUserNode();
-        isRoot = false;
-
-        initFields();
-    }
-
-
-    private void initFields()
-    {
+        this.isRoot = isRoot;
+        if (isRoot)
+            this.isUser = isUser;
+        else
+            this.isUser = isUserNode();
         path = isRoot ? absolutePath() : absolutePath() + "/";
-        file = cfFileForNode(isUser);
-        newNode = file.addNode(path);
+        file = cfFileForNode(this.isUser);
+        if (isNew)
+            newNode = isNew;
+        else
+            newNode = file.addNode(path);
     }
 
-
     // Create and return the MacOSXPreferencesFile for this node.
     // Does not write anything to the file.
     private MacOSXPreferencesFile cfFileForNode(boolean isUser)
@@ -194,8 +198,8 @@
         // Add to parent's child list here and disallow sync
         // because parent and child might be in different files.
         synchronized(MacOSXPreferencesFile.class) {
-            file.addChildToNode(path, name);
-            return new MacOSXPreferences(this, name);
+            boolean isNew = file.addChildToNode(path, name);
+            return new MacOSXPreferences(this, name, isNew);
         }
     }
 
@@ -206,9 +210,14 @@
         // Flush should *not* check for removal, unlike sync, but should
         // prevent simultaneous removal.
         synchronized(lock) {
-            // fixme! overkill
-            if (!MacOSXPreferencesFile.flushWorld()) {
-                throw new BackingStoreException("Synchronization failed for node '" + path + "'");
+            if (isUser) {
+                if (!MacOSXPreferencesFile.flushUser()) {
+                    throw new BackingStoreException("Synchronization failed for node '" + path + "'");
+                }
+            } else {
+                if (!MacOSXPreferencesFile.flushWorld()) {
+                    throw new BackingStoreException("Synchronization failed for node '" + path + "'");
+                }
             }
         }
     }
diff --git a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java
index 7cfb899..bb3b760 100644
--- a/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java
+++ b/jdk/src/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java
@@ -223,7 +223,23 @@
         return ok;
     }
 
-
+    //Flush only current user preferences
+    static synchronized boolean flushUser() {
+        boolean ok = true;
+        if (changedFiles != null  &&  !changedFiles.isEmpty()) {
+            Iterator<MacOSXPreferencesFile> iterator = changedFiles.iterator();
+            while(iterator.hasNext()) {
+                MacOSXPreferencesFile f = iterator.next();
+                if (f.user == cfCurrentUser) {
+                    if (!f.synchronize())
+                        ok = false;
+                    else
+                        iterator.remove();
+                }
+            }
+        }
+        return ok;
+    }
 
     // Write all prefs changes to disk, but do not clear all cached prefs
     // values. Also kills any scheduled flush task.
@@ -348,11 +364,11 @@
         }
     }
 
-    void addChildToNode(String path, String child)
+    boolean addChildToNode(String path, String child)
     {
         synchronized(MacOSXPreferencesFile.class) {
             markChanged();
-            addChildToNode(path, child+"/", appName, user, host);
+            return addChildToNode(path, child+"/", appName, user, host);
         }
     }
 
@@ -421,7 +437,7 @@
         addNode(String path, String name, long user, long host);
     private static final native void
         removeNode(String path, String name, long user, long host);
-    private static final native void
+    private static final native boolean
         addChildToNode(String path, String child,
                        String name, long user, long host);
     private static final native void
diff --git a/jdk/src/macosx/classes/sun/font/CFontManager.java b/jdk/src/macosx/classes/sun/font/CFontManager.java
index 5caca1e..a37fd81 100644
--- a/jdk/src/macosx/classes/sun/font/CFontManager.java
+++ b/jdk/src/macosx/classes/sun/font/CFontManager.java
@@ -37,6 +37,7 @@
 import javax.swing.plaf.FontUIResource;
 
 import sun.awt.FontConfiguration;
+import sun.awt.HeadlessToolkit;
 import sun.lwawt.macosx.*;
 
 public class CFontManager extends SunFontManager {
@@ -342,9 +343,14 @@
     @Override
     public String getFontPath(boolean noType1Fonts) {
         // In the case of the Cocoa toolkit, since we go through NSFont, we dont need to register /Library/Fonts
-        if (Toolkit.getDefaultToolkit() instanceof LWCToolkit) {
+        Toolkit tk = Toolkit.getDefaultToolkit();
+        if (tk instanceof HeadlessToolkit) {
+            tk = ((HeadlessToolkit)tk).getUnderlyingToolkit();
+        }
+        if (tk instanceof LWCToolkit) {
             return "";
         }
+
         // X11 case
         return "/Library/Fonts";
     }
diff --git a/jdk/src/macosx/classes/sun/java2d/opengl/CGLLayer.java b/jdk/src/macosx/classes/sun/java2d/opengl/CGLLayer.java
index 219c84c..674b979 100644
--- a/jdk/src/macosx/classes/sun/java2d/opengl/CGLLayer.java
+++ b/jdk/src/macosx/classes/sun/java2d/opengl/CGLLayer.java
@@ -68,11 +68,12 @@
     }
 
     public boolean isOpaque() {
-        return peer.isOpaque();
+        return !peer.isTranslucent();
     }
 
     public int getTransparency() {
-        return (peer.isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT);
+        return peer.isTranslucent() ? Transparency.TRANSLUCENT :
+               Transparency.OPAQUE;
     }
 
     public Object getDestination() {
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java
index fd71bc7..86093e6 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWComponentPeer.java
@@ -40,6 +40,7 @@
 import java.awt.peer.ComponentPeer;
 import java.awt.peer.ContainerPeer;
 
+import java.awt.peer.KeyboardFocusManagerPeer;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.lang.reflect.Field;
 import java.security.AccessController;
@@ -282,7 +283,7 @@
      * Note that we call setVisible() at the end of initialization.
      */
     public final void initialize() {
-        platformComponent.initialize(target, this, getPlatformWindow());
+        platformComponent.initialize(getPlatformWindow());
         initializeImpl();
         setVisible(target.isVisible());
     }
@@ -424,8 +425,7 @@
 
     @Override
     public final Graphics getGraphics() {
-        Graphics g = getWindowPeerOrSelf().isOpaque() ? getOnscreenGraphics()
-                                                      : getOffscreenGraphics();
+        final Graphics g = getOnscreenGraphics();
         if (g != null) {
             synchronized (getPeerTreeLock()){
                 applyConstrain(g);
@@ -443,13 +443,7 @@
         final LWWindowPeer wp = getWindowPeerOrSelf();
         return wp.getOnscreenGraphics(getForeground(), getBackground(),
                                       getFont());
-    }
 
-    public final Graphics getOffscreenGraphics() {
-        final LWWindowPeer wp = getWindowPeerOrSelf();
-
-        return wp.getOffscreenGraphics(getForeground(), getBackground(),
-                                       getFont());
     }
 
     private void applyConstrain(final Graphics g) {
@@ -463,7 +457,7 @@
     }
 
     //TODO Move this method to SG2D?
-    private void SG2DConstraint(final SunGraphics2D sg2d, Region r) {
+    void SG2DConstraint(final SunGraphics2D sg2d, Region r) {
         sg2d.constrainX = sg2d.transX;
         sg2d.constrainY = sg2d.transY;
 
@@ -710,7 +704,7 @@
         // Obtain the metrics from the offscreen window where this peer is
         // mostly drawn to.
         // TODO: check for "use platform metrics" settings
-        Graphics g = getWindowPeer().getOffscreenGraphics();
+        Graphics g = getWindowPeer().getGraphics();
         try {
             if (g != null) {
                 return g.getFontMetrics(f);
@@ -901,15 +895,15 @@
                             ", focusedWindowChangeAllowed=" + focusedWindowChangeAllowed +
                             ", time= " + time + ", cause=" + cause);
         }
-        if (LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
-                processSynchronousLightweightTransfer(getTarget(), lightweightChild, temporary,
-                        focusedWindowChangeAllowed, time)) {
+        if (LWKeyboardFocusManagerPeer.processSynchronousLightweightTransfer(
+                getTarget(), lightweightChild, temporary,
+                focusedWindowChangeAllowed, time)) {
             return true;
         }
 
-        int result = LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
-                shouldNativelyFocusHeavyweight(getTarget(), lightweightChild, temporary,
-                        focusedWindowChangeAllowed, time, cause);
+        int result = LWKeyboardFocusManagerPeer.shouldNativelyFocusHeavyweight(
+                getTarget(), lightweightChild, temporary,
+                focusedWindowChangeAllowed, time, cause);
         switch (result) {
             case LWKeyboardFocusManagerPeer.SNFH_FAILURE:
                 return false;
@@ -958,14 +952,13 @@
                     return false;
                 }
 
-                LWComponentPeer focusOwnerPeer =
-                    LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
-                        getFocusOwner();
-                Component focusOwner = (focusOwnerPeer != null) ? focusOwnerPeer.getTarget() : null;
+                KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+                Component focusOwner = kfmPeer.getCurrentFocusOwner();
                 return LWKeyboardFocusManagerPeer.deliverFocus(lightweightChild,
                         getTarget(), temporary,
                         focusedWindowChangeAllowed,
                         time, cause, focusOwner);
+
             case LWKeyboardFocusManagerPeer.SNFH_SUCCESS_HANDLED:
                 return true;
         }
@@ -1011,14 +1004,33 @@
     @Override
     public final void applyShape(final Region shape) {
         synchronized (getStateLock()) {
-            region = shape;
+            if (region == shape || (region != null && region.equals(shape))) {
+                return;
+            }
+        }
+        applyShapeImpl(shape);
+    }
+
+    void applyShapeImpl(final Region shape) {
+        synchronized (getStateLock()) {
+            if (shape != null) {
+                region = Region.WHOLE_REGION.getIntersection(shape);
+            } else {
+                region = null;
+            }
         }
         repaintParent(getBounds());
     }
 
     protected final Region getRegion() {
         synchronized (getStateLock()) {
-            return region == null ? Region.getInstance(getSize()) : region;
+            return isShaped() ? region : Region.getInstance(getSize());
+        }
+    }
+
+    public boolean isShaped() {
+        synchronized (getStateLock()) {
+            return region != null;
         }
     }
 
@@ -1251,8 +1263,8 @@
     protected void handleJavaFocusEvent(FocusEvent e) {
         // Note that the peer receives all the FocusEvents from
         // its lightweight children as well
-        LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
-                setFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? this : null);
+        KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+        kfmPeer.setCurrentFocusOwner(e.getID() == FocusEvent.FOCUS_GAINED ? getTarget() : null);
     }
 
     /**
@@ -1386,11 +1398,6 @@
         }
     }
 
-    // Just a helper method, thus final
-    protected final void flushOffscreenGraphics() {
-        flushOffscreenGraphics(getSize());
-    }
-
     protected static final void flushOnscreenGraphics(){
         final OGLRenderQueue rq = OGLRenderQueue.getInstance();
         rq.lock();
@@ -1401,36 +1408,6 @@
         }
     }
 
-    /*
-     * Flushes the given rectangle from the back buffer to the screen.
-     */
-    protected void flushOffscreenGraphics(Rectangle r) {
-        flushOffscreenGraphics(r.x, r.y, r.width, r.height);
-    }
-
-    private void flushOffscreenGraphics(int x, int y, int width, int height) {
-        Image bb = getWindowPeerOrSelf().getBackBuffer();
-        if (bb != null) {
-            // g is a screen Graphics from the delegate
-            final Graphics g = getOnscreenGraphics();
-
-            if (g != null && g instanceof Graphics2D) {
-                try {
-                    Graphics2D g2d = (Graphics2D)g;
-                    Point p = localToWindow(new Point(0, 0));
-                    Composite composite = g2d.getComposite();
-                    g2d.setComposite(AlphaComposite.Src);
-                    g.drawImage(bb, x, y, x + width, y + height, p.x + x,
-                            p.y + y, p.x + x + width, p.y + y + height,
-                            null);
-                    g2d.setComposite(composite);
-                } finally {
-                    g.dispose();
-                }
-            }
-        }
-    }
-
     /**
      * Used by ContainerPeer to skip all the paint events during layout.
      *
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java
index 4263660..421c8af 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java
@@ -26,85 +26,47 @@
 package sun.lwawt;
 
 import java.awt.Component;
-import java.awt.KeyboardFocusManager;
 import java.awt.Window;
-
-import java.util.Map;
-import java.util.HashMap;
-
-import sun.awt.AWTAccessor;
-import sun.awt.AppContext;
 import sun.awt.KeyboardFocusManagerPeerImpl;
 
 public class LWKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
+    private static final LWKeyboardFocusManagerPeer inst = new LWKeyboardFocusManagerPeer();
 
-    private Object lock = new Object();
-    private LWWindowPeer focusedWindow;
-    private LWComponentPeer focusOwner;
+    private Window focusedWindow;
+    private Component focusOwner;
 
-    private static Map<KeyboardFocusManager, LWKeyboardFocusManagerPeer> instances =
-        new HashMap<KeyboardFocusManager, LWKeyboardFocusManagerPeer>();
-
-    public static synchronized LWKeyboardFocusManagerPeer getInstance(AppContext ctx) {
-        return getInstance(AWTAccessor.getKeyboardFocusManagerAccessor().
-                           getCurrentKeyboardFocusManager(ctx));
+    public static LWKeyboardFocusManagerPeer getInstance() {
+        return inst;
     }
 
-    public static synchronized LWKeyboardFocusManagerPeer getInstance(KeyboardFocusManager manager) {
-        LWKeyboardFocusManagerPeer instance = instances.get(manager);
-        if (instance == null) {
-            instance = new LWKeyboardFocusManagerPeer(manager);
-            instances.put(manager, instance);
+    private LWKeyboardFocusManagerPeer() {
+    }
+
+    @Override
+    public void setCurrentFocusedWindow(Window win) {
+        synchronized (this) {
+            focusedWindow = win;
         }
-        return instance;
-    }
-
-    public LWKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
-        super(manager);
     }
 
     @Override
     public Window getCurrentFocusedWindow() {
-        synchronized (lock) {
-            return (focusedWindow != null) ? (Window)focusedWindow.getTarget() : null;
+        synchronized (this) {
+            return focusedWindow;
         }
     }
 
     @Override
     public Component getCurrentFocusOwner() {
-        synchronized (lock) {
-            return (focusOwner != null) ? focusOwner.getTarget() : null;
+        synchronized (this) {
+            return focusOwner;
         }
     }
 
     @Override
     public void setCurrentFocusOwner(Component comp) {
-        synchronized (lock) {
-            focusOwner = (comp != null) ? (LWComponentPeer)comp.getPeer() : null;
-        }
-    }
-
-    void setFocusedWindow(LWWindowPeer peer) {
-        synchronized (lock) {
-            focusedWindow = peer;
-        }
-    }
-
-    LWWindowPeer getFocusedWindow() {
-        synchronized (lock) {
-            return focusedWindow;
-        }
-    }
-
-    void setFocusOwner(LWComponentPeer peer) {
-        synchronized (lock) {
-            focusOwner = peer;
-        }
-    }
-
-    LWComponentPeer getFocusOwner() {
-        synchronized (lock) {
-            return focusOwner;
+        synchronized (this) {
+            focusOwner = comp;
         }
     }
 }
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java b/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java
index 54cbd33..e67b2fa 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWRepaintArea.java
@@ -58,9 +58,6 @@
 
     private static void flushBuffers(final LWComponentPeer peer) {
         if (peer != null) {
-            if (!peer.getWindowPeerOrSelf().isOpaque()) {
-                peer.flushOffscreenGraphics();
-            }
             peer.flushOnscreenGraphics();
         }
     }
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java
index 8517313..48467c1 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWTextAreaPeer.java
@@ -129,16 +129,6 @@
     }
 
     @Override
-    public void setText(final String l) {
-        // Please note that we do not want to post an event
-        // if TextArea.setText() replaces an empty text by an empty text,
-        // that is, if component's text remains unchanged.
-        if (!l.isEmpty() || getTextComponent().getDocument().getLength() != 0) {
-            super.setText(l);
-        }
-    }
-
-    @Override
     public void replaceRange(final String text, final int start,
                              final int end) {
         synchronized (getDelegateLock()) {
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java
index f0215d4..9db975d 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWTextComponentPeer.java
@@ -124,7 +124,7 @@
     }
 
     @Override
-    public void setText(final String l) {
+    public final void setText(final String l) {
         synchronized (getDelegateLock()) {
             // JTextArea.setText() posts two different events (remove & insert).
             // Since we make no differences between text events,
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
index f41a944..7e0e0c5 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWToolkit.java
@@ -210,9 +210,9 @@
      * and DialogPeer interfaces.
      */
     private LWWindowPeer createDelegatedPeer(Window target, PlatformComponent platformComponent,
-                                             PlatformWindow platformWindow)
+                                             PlatformWindow platformWindow, LWWindowPeer.PeerType peerType)
     {
-        LWWindowPeer peer = new LWWindowPeer(target, platformComponent, platformWindow);
+        LWWindowPeer peer = new LWWindowPeer(target, platformComponent, platformWindow, peerType);
         targetCreatedPeer(target, peer);
         peer.initialize();
         return peer;
@@ -222,22 +222,29 @@
     public WindowPeer createWindow(Window target) {
         PlatformComponent platformComponent = createPlatformComponent();
         PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.SIMPLEWINDOW);
-        return createDelegatedPeer(target, platformComponent, platformWindow);
+        return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.SIMPLEWINDOW);
     }
 
     @Override
     public FramePeer createFrame(Frame target) {
         PlatformComponent platformComponent = createPlatformComponent();
         PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.FRAME);
-        return createDelegatedPeer(target, platformComponent, platformWindow);
+        return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.FRAME);
     }
 
     public LWWindowPeer createEmbeddedFrame(CEmbeddedFrame target) {
         PlatformComponent platformComponent = createPlatformComponent();
-        PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.EMBEDDEDFRAME);
-        return createDelegatedPeer(target, platformComponent, platformWindow);
+        PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.EMBEDDED_FRAME);
+        return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.EMBEDDED_FRAME);
     }
 
+    public LWWindowPeer createEmbeddedFrame(CViewEmbeddedFrame target) {
+        PlatformComponent platformComponent = createPlatformComponent();
+        PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.VIEW_EMBEDDED_FRAME);
+        return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.VIEW_EMBEDDED_FRAME);
+    }
+
+
     CPrinterDialogPeer createCPrinterDialog(CPrinterDialog target) {
         PlatformComponent platformComponent = createPlatformComponent();
         PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.DIALOG);
@@ -254,7 +261,7 @@
 
         PlatformComponent platformComponent = createPlatformComponent();
         PlatformWindow platformWindow = createPlatformWindow(LWWindowPeer.PeerType.DIALOG);
-        return createDelegatedPeer(target, platformComponent, platformWindow);
+        return createDelegatedPeer(target, platformComponent, platformWindow, LWWindowPeer.PeerType.DIALOG);
     }
 
     @Override
@@ -415,8 +422,8 @@
     }
 
     @Override
-    public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
-        return LWKeyboardFocusManagerPeer.getInstance(manager);
+    public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
+        return LWKeyboardFocusManagerPeer.getInstance();
     }
 
     @Override
@@ -522,12 +529,6 @@
         postEvent(targetToAppContext(event.getSource()), event);
     }
 
-    // use peer's back buffer to implement non-opaque windows.
-    @Override
-    public boolean needUpdateWindow() {
-        return true;
-    }
-
     @Override
     public void grab(Window w) {
         if (w.getPeer() != null) {
diff --git a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
index 6b96878..0b20b06 100644
--- a/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/LWWindowPeer.java
@@ -37,6 +37,7 @@
 import sun.java2d.*;
 import sun.java2d.loops.Blit;
 import sun.java2d.loops.CompositeType;
+import sun.java2d.pipe.Region;
 import sun.util.logging.PlatformLogger;
 
 public class LWWindowPeer
@@ -47,7 +48,8 @@
         SIMPLEWINDOW,
         FRAME,
         DIALOG,
-        EMBEDDEDFRAME
+        EMBEDDED_FRAME,
+        VIEW_EMBEDDED_FRAME
     }
 
     private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.lwawt.focus.LWWindowPeer");
@@ -109,6 +111,12 @@
 
     private volatile boolean skipNextFocusChange;
 
+    private static final Color nonOpaqueBackground = new Color(0, 0, 0, 0);
+
+    private volatile boolean textured;
+
+    private final PeerType peerType;
+
     /**
      * Current modal blocker or null.
      *
@@ -117,10 +125,11 @@
     private LWWindowPeer blocker;
 
     public LWWindowPeer(Window target, PlatformComponent platformComponent,
-                        PlatformWindow platformWindow)
+                        PlatformWindow platformWindow, PeerType peerType)
     {
         super(target, platformComponent);
         this.platformWindow = platformWindow;
+        this.peerType = peerType;
 
         Window owner = target.getOwner();
         LWWindowPeer ownerPeer = (owner != null) ? (LWWindowPeer)owner.getPeer() : null;
@@ -169,6 +178,11 @@
         setAlwaysOnTop(getTarget().isAlwaysOnTop());
         updateMinimumSize();
 
+        final Shape shape = getTarget().getShape();
+        if (shape != null) {
+            applyShape(Region.getInstance(shape, null));
+        }
+
         final float opacity = getTarget().getOpacity();
         if (opacity < 1.0f) {
             setOpacity(opacity);
@@ -178,7 +192,7 @@
 
         updateInsets(platformWindow.getInsets());
         if (getSurfaceData() == null) {
-            replaceSurfaceData();
+            replaceSurfaceData(false);
         }
     }
 
@@ -222,8 +236,7 @@
         // TODO: update graphicsConfig, see 4868278
         platformWindow.setVisible(visible);
         if (isSimpleWindow()) {
-            LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
-                getInstance(getAppContext());
+            KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
 
             if (visible) {
                 if (!getTarget().isAutoRequestFocus()) {
@@ -231,7 +244,7 @@
                 } else {
                     requestWindowFocus(CausedFocusEvent.Cause.ACTIVATION);
                 }
-            } else if (manager.getCurrentFocusedWindow() == getTarget()) {
+            } else if (kfmPeer.getCurrentFocusedWindow() == getTarget()) {
                 // Transfer focus to the owner.
                 LWWindowPeer owner = getOwnerFrameDialog(LWWindowPeer.this);
                 if (owner != null) {
@@ -279,7 +292,7 @@
             // "buffer", that's why numBuffers - 1
             assert numBuffers > 1;
 
-            replaceSurfaceData(numBuffers - 1, caps);
+            replaceSurfaceData(numBuffers - 1, caps, false);
         } catch (InvalidPipeException z) {
             throw new AWTException(z.toString());
         }
@@ -330,6 +343,11 @@
 
     @Override
     public void setBounds(int x, int y, int w, int h, int op) {
+
+        if((op & NO_EMBEDDED_CHECK) == 0 && getPeerType() == PeerType.VIEW_EMBEDDED_FRAME) {
+            return;
+        }
+
         if ((op & SET_CLIENT_SIZE) != 0) {
             // SET_CLIENT_SIZE is only applicable to window peers, so handle it here
             // instead of pulling 'insets' field up to LWComponentPeer
@@ -472,19 +490,44 @@
     public final void setOpaque(final boolean isOpaque) {
         if (this.isOpaque != isOpaque) {
             this.isOpaque = isOpaque;
-            getPlatformWindow().setOpaque(isOpaque);
-            replaceSurfaceData();
-            repaintPeer();
+            updateOpaque();
         }
     }
 
-    public final boolean isOpaque() {
-        return isOpaque;
+    private void updateOpaque() {
+        getPlatformWindow().setOpaque(!isTranslucent());
+        replaceSurfaceData(false);
+        repaintPeer();
     }
 
     @Override
     public void updateWindow() {
-        flushOffscreenGraphics();
+    }
+
+    public final boolean isTextured() {
+        return textured;
+    }
+
+    public final void setTextured(final boolean isTextured) {
+        textured = isTextured;
+    }
+
+    public final boolean isTranslucent() {
+        synchronized (getStateLock()) {
+            /*
+             * Textured window is a special case of translucent window.
+             * The difference is only in nswindow background. So when we set
+             * texture property our peer became fully translucent. It doesn't
+             * fill background, create non opaque backbuffers and layer etc.
+             */
+            return !isOpaque || isShaped() || isTextured();
+        }
+    }
+
+    @Override
+    final void applyShapeImpl(final Region shape) {
+        super.applyShapeImpl(shape);
+        updateOpaque();
     }
 
     @Override
@@ -639,7 +682,20 @@
                                                getFont());
         if (g != null) {
             try {
-                g.clearRect(0, 0, w, h);
+                if (g instanceof Graphics2D) {
+                    ((Graphics2D) g).setComposite(AlphaComposite.Src);
+                }
+                if (isTranslucent()) {
+                    g.setColor(nonOpaqueBackground);
+                    g.fillRect(0, 0, w, h);
+                }
+                if (!isTextured()) {
+                    if (g instanceof SunGraphics2D) {
+                        SG2DConstraint((SunGraphics2D) g, getRegion());
+                    }
+                    g.setColor(getBackground());
+                    g.fillRect(0, 0, w, h);
+                }
             } finally {
                 g.dispose();
             }
@@ -703,42 +759,39 @@
             }
         } else {
             if (targetPeer != lastMouseEventPeer) {
-
-                if (id != MouseEvent.MOUSE_DRAGGED || lastMouseEventPeer == null) {
-                    // lastMouseEventPeer may be null if mouse was out of Java windows
-                    if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
-                        // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
-                        // later), in which case lastWindowPeer is another window
-                        if (lastWindowPeer != this) {
-                            Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
-                            // Additionally translate from this to lastWindowPeer coordinates
-                            Rectangle lr = lastWindowPeer.getBounds();
-                            oldp.x += r.x - lr.x;
-                            oldp.y += r.y - lr.y;
-                            postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
-                                                     MouseEvent.MOUSE_EXITED,
-                                                     when, modifiers,
-                                                     oldp.x, oldp.y, screenX, screenY,
-                                                     clickCount, popupTrigger, button));
-                        } else {
-                            Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
-                            postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
-                                                     MouseEvent.MOUSE_EXITED,
-                                                     when, modifiers,
-                                                     oldp.x, oldp.y, screenX, screenY,
-                                                     clickCount, popupTrigger, button));
-                        }
-                    }
-                    if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
-                        Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
-                        postEvent(new MouseEvent(targetPeer.getTarget(),
-                                                 MouseEvent.MOUSE_ENTERED,
+                // lastMouseEventPeer may be null if mouse was out of Java windows
+                if (lastMouseEventPeer != null && lastMouseEventPeer.isEnabled()) {
+                    // Sometimes, MOUSE_EXITED is not sent by delegate (or is sent a bit
+                    // later), in which case lastWindowPeer is another window
+                    if (lastWindowPeer != this) {
+                        Point oldp = lastMouseEventPeer.windowToLocal(x, y, lastWindowPeer);
+                        // Additionally translate from this to lastWindowPeer coordinates
+                        Rectangle lr = lastWindowPeer.getBounds();
+                        oldp.x += r.x - lr.x;
+                        oldp.y += r.y - lr.y;
+                        postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
+                                                 MouseEvent.MOUSE_EXITED,
                                                  when, modifiers,
-                                                 newp.x, newp.y, screenX, screenY,
+                                                 oldp.x, oldp.y, screenX, screenY,
+                                                 clickCount, popupTrigger, button));
+                    } else {
+                        Point oldp = lastMouseEventPeer.windowToLocal(x, y, this);
+                        postEvent(new MouseEvent(lastMouseEventPeer.getTarget(),
+                                                 MouseEvent.MOUSE_EXITED,
+                                                 when, modifiers,
+                                                 oldp.x, oldp.y, screenX, screenY,
                                                  clickCount, popupTrigger, button));
                     }
                 }
                 lastMouseEventPeer = targetPeer;
+                if (targetPeer != null && targetPeer.isEnabled() && id != MouseEvent.MOUSE_ENTERED) {
+                    Point newp = targetPeer.windowToLocal(x, y, curWindowPeer);
+                    postEvent(new MouseEvent(targetPeer.getTarget(),
+                                             MouseEvent.MOUSE_ENTERED,
+                                             when, modifiers,
+                                             newp.x, newp.y, screenX, screenY,
+                                             clickCount, popupTrigger, button));
+                }
             }
             // TODO: fill "bdata" member of AWTEvent
 
@@ -857,9 +910,8 @@
     public void dispatchKeyEvent(int id, long when, int modifiers,
                                  int keyCode, char keyChar, int keyLocation)
     {
-        LWComponentPeer focusOwner =
-            LWKeyboardFocusManagerPeer.getInstance(getAppContext()).
-                getFocusOwner();
+        KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+        Component focusOwner = kfmPeer.getCurrentFocusOwner();
 
         // Null focus owner may receive key event when
         // application hides the focused window upon ESC press
@@ -867,9 +919,10 @@
         // may come to already hidden window. This check eliminates NPE.
         if (focusOwner != null) {
             KeyEvent event =
-                new KeyEvent(focusOwner.getTarget(), id, when, modifiers,
+                new KeyEvent(focusOwner, id, when, modifiers,
                              keyCode, keyChar, keyLocation);
-            focusOwner.postEvent(event);
+            LWComponentPeer peer = (LWComponentPeer)focusOwner.getPeer();
+            peer.postEvent(event);
         }
     }
 
@@ -946,35 +999,6 @@
         });
     }
 
-    /**
-     * This method returns a back buffer Graphics to render all the
-     * peers to. After the peer is painted, the back buffer contents
-     * should be flushed to the screen. All the target painting
-     * (Component.paint() method) should be done directly to the screen.
-     */
-    protected final Graphics getOffscreenGraphics(Color fg, Color bg, Font f) {
-        final Image bb = getBackBuffer();
-        if (bb == null) {
-            return null;
-        }
-        if (fg == null) {
-            fg = SystemColor.windowText;
-        }
-        if (bg == null) {
-            bg = SystemColor.window;
-        }
-        if (f == null) {
-            f = DEFAULT_FONT;
-        }
-        final Graphics2D g = (Graphics2D) bb.getGraphics();
-        if (g != null) {
-            g.setColor(fg);
-            g.setBackground(bg);
-            g.setFont(f);
-        }
-        return g;
-    }
-
     /*
      * May be called by delegate to provide SD to Java2D code.
      */
@@ -985,11 +1009,16 @@
     }
 
     private void replaceSurfaceData() {
-        replaceSurfaceData(backBufferCount, backBufferCaps);
+        replaceSurfaceData(true);
+    }
+
+    private void replaceSurfaceData(boolean blit) {
+        replaceSurfaceData(backBufferCount, backBufferCaps, blit);
     }
 
     private void replaceSurfaceData(int newBackBufferCount,
-                                                 BufferCapabilities newBackBufferCaps) {
+                                    BufferCapabilities newBackBufferCaps,
+                                    boolean blit) {
         synchronized (surfaceDataLock) {
             final SurfaceData oldData = getSurfaceData();
             surfaceData = platformWindow.replaceSurfaceData();
@@ -1002,7 +1031,10 @@
             if (getSurfaceData() != null && oldData != getSurfaceData()) {
                 clearBackground(size.width, size.height);
             }
-            blitSurfaceData(oldData, getSurfaceData());
+
+            if (blit) {
+                blitSurfaceData(oldData, getSurfaceData());
+            }
 
             if (oldData != null && oldData != getSurfaceData()) {
                 // TODO: drop oldData for D3D/WGL pipelines
@@ -1017,11 +1049,18 @@
                 Graphics g = backBuffer.getGraphics();
                 try {
                     Rectangle r = getBounds();
-                    g.setColor(getBackground());
                     if (g instanceof Graphics2D) {
                         ((Graphics2D) g).setComposite(AlphaComposite.Src);
                     }
+                    g.setColor(nonOpaqueBackground);
                     g.fillRect(0, 0, r.width, r.height);
+                    if (g instanceof SunGraphics2D) {
+                        SG2DConstraint((SunGraphics2D) g, getRegion());
+                    }
+                    if (!isTextured()) {
+                        g.setColor(getBackground());
+                        g.fillRect(0, 0, r.width, r.height);
+                    }
                     if (oldBB != null) {
                         // Draw the old back buffer to the new one
                         g.drawImage(oldBB, 0, 0, null);
@@ -1045,7 +1084,7 @@
                                           CompositeType.Src,
                                           dst.getSurfaceType());
             if (blit != null) {
-                blit.Blit(src, dst, ((Graphics2D) getGraphics()).getComposite(),
+                blit.Blit(src, dst, AlphaComposite.Src,
                           getRegion(), 0, 0, 0, 0, size.width, size.height);
             }
         }
@@ -1200,10 +1239,8 @@
             }
         }
 
-        LWKeyboardFocusManagerPeer manager = LWKeyboardFocusManagerPeer.
-            getInstance(getAppContext());
-
-        Window oppositeWindow = becomesFocused ? manager.getCurrentFocusedWindow() : null;
+        KeyboardFocusManagerPeer kfmPeer = LWKeyboardFocusManagerPeer.getInstance();
+        Window oppositeWindow = becomesFocused ? kfmPeer.getCurrentFocusedWindow() : null;
 
         // Note, the method is not called:
         // - when the opposite (gaining focus) window is an owned/owner window.
@@ -1216,7 +1253,7 @@
             grabbingWindow.ungrab();
         }
 
-        manager.setFocusedWindow(becomesFocused ? LWWindowPeer.this : null);
+        kfmPeer.setCurrentFocusedWindow(becomesFocused ? getTarget() : null);
 
         int eventID = becomesFocused ? WindowEvent.WINDOW_GAINED_FOCUS : WindowEvent.WINDOW_LOST_FOCUS;
         WindowEvent windowEvent = new WindowEvent(getTarget(), eventID, oppositeWindow);
@@ -1279,6 +1316,10 @@
         return this == grabbingWindow;
     }
 
+    public PeerType getPeerType() {
+        return peerType;
+    }
+
     @Override
     public String toString() {
         return super.toString() + " [target is " + getTarget() + "]";
diff --git a/jdk/src/macosx/classes/sun/lwawt/PlatformComponent.java b/jdk/src/macosx/classes/sun/lwawt/PlatformComponent.java
index e791e0d..836a19c 100644
--- a/jdk/src/macosx/classes/sun/lwawt/PlatformComponent.java
+++ b/jdk/src/macosx/classes/sun/lwawt/PlatformComponent.java
@@ -23,15 +23,38 @@
  * questions.
  */
 
+
 package sun.lwawt;
 
-import java.awt.Component;
-
+/**
+ * Can be used to store information about native resource related to the
+ * lightweight component.
+ */
 public interface PlatformComponent {
 
-    public void initialize(Component target, LWComponentPeer peer, PlatformWindow platformWindow);
+    /**
+     * Initializes platform component.
+     *
+     * @param platformWindow already initialized {@code PlatformWindow}.
+     */
+    void initialize(PlatformWindow platformWindow);
 
-    public void setBounds(int x, int y, int w, int h);
+    /**
+     * Moves and resizes this component. The new location of the top-left corner
+     * is specified by {@code x} and {@code y}, and the new size is specified by
+     * {@code w} and {@code h}. The location is specified relative to the {@code
+     * platformWindow}.
+     *
+     * @param x the X location of the component
+     * @param y the Y location of the component
+     * @param w the width of the component
+     * @param h the height of the component
+     */
+    void setBounds(int x, int y, int w, int h);
 
-    public void dispose();
+    /**
+     * Releases all of the native resources used by this {@code
+     * PlatformComponent}.
+     */
+    void dispose();
 }
diff --git a/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java
index 2c7df7c..4944fa1 100644
--- a/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java
+++ b/jdk/src/macosx/classes/sun/lwawt/PlatformWindow.java
@@ -160,4 +160,6 @@
     public long getLayerPtr();
 
     public LWWindowPeer getPeer();
+
+    public boolean isUnderMouse();
 }
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java
index 5ff47d6..a92545e 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CFRetainedResource.java
@@ -33,8 +33,8 @@
 public class CFRetainedResource {
     private static native void nativeCFRelease(final long ptr, final boolean disposeOnAppKitThread);
 
-    final boolean disposeOnAppKitThread;
-    protected long ptr;
+    private final boolean disposeOnAppKitThread;
+    protected volatile long ptr;
 
     /**
      * @param ptr CFRetained native object pointer
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java
index b905f0b..359f606 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CFileDialog.java
@@ -30,12 +30,14 @@
 import java.awt.BufferCapabilities.FlipContents;
 import java.awt.event.*;
 import java.awt.image.*;
+import java.security.AccessController;
 import java.util.List;
 import java.io.*;
 
 import sun.awt.CausedFocusEvent.Cause;
 import sun.awt.AWTAccessor;
 import sun.java2d.pipe.Region;
+import sun.security.action.GetBooleanAction;
 
 class CFileDialog implements FileDialogPeer {
 
@@ -53,11 +55,14 @@
                 if (title == null) {
                     title = " ";
                 }
+                Boolean chooseDirectories = AccessController.doPrivileged(
+                        new GetBooleanAction("apple.awt.fileDialogForDirectories"));
 
                 String[] userFileNames = nativeRunFileDialog(title,
                         dialogMode,
                         target.isMultipleMode(),
                         navigateApps,
+                        chooseDirectories,
                         target.getFilenameFilter() != null,
                         target.getDirectory(),
                         target.getFile());
@@ -142,7 +147,8 @@
     }
 
     private native String[] nativeRunFileDialog(String title, int mode,
-            boolean multipleMode, boolean shouldNavigateApps, boolean hasFilenameFilter,
+            boolean multipleMode, boolean shouldNavigateApps,
+            boolean canChooseDirectories, boolean hasFilenameFilter,
             String directory, String file);
 
     @Override
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java
index 8651aa3..8ee5801 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CMouseInfoPeer.java
@@ -26,7 +26,6 @@
 package sun.lwawt.macosx;
 
 import java.awt.Window;
-
 import sun.lwawt.LWMouseInfoPeer;
 import sun.lwawt.LWWindowPeer;
 
@@ -41,10 +40,6 @@
             return false;
         }
 
-        LWWindowPeer peer = (LWWindowPeer)w.getPeer();
-        CPlatformWindow platformWindow = (CPlatformWindow)peer.getPlatformWindow();
-        return nativeIsWindowUnderMouse(platformWindow.getNSWindowPtr());
+        return ((LWWindowPeer)w.getPeer()).getPlatformWindow().isUnderMouse();
     }
-
-    private static native boolean nativeIsWindowUnderMouse(long ptr);
 }
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java
index dec2547..370b930 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformComponent.java
@@ -23,27 +23,24 @@
  * questions.
  */
 
+
 package sun.lwawt.macosx;
 
-import java.awt.Component;
 import java.awt.Insets;
 
 import sun.lwawt.PlatformComponent;
 import sun.lwawt.PlatformWindow;
-import sun.lwawt.LWComponentPeer;
 
-import sun.lwawt.macosx.CFRetainedResource;
+/**
+ * On OSX {@code CPlatformComponent} stores pointer to the native CAlayer which
+ * can be used from JAWT.
+ */
+final class CPlatformComponent extends CFRetainedResource
+        implements PlatformComponent {
 
-public class CPlatformComponent extends CFRetainedResource implements PlatformComponent {
+    private volatile PlatformWindow platformWindow;
 
-    Component target;
-    LWComponentPeer peer;
-    PlatformWindow platformWindow;
-
-    private native long nativeCreateComponent(long windowLayer);
-    private native long nativeSetBounds(long ptr, int x, int y, int width, int height);
-
-    public CPlatformComponent() {
+    CPlatformComponent() {
         super(0, true);
     }
 
@@ -51,27 +48,28 @@
         return ptr;
     }
 
-    public void initialize(Component target, LWComponentPeer peer, PlatformWindow platformWindow) {
-        this.target = target;
-        this.peer = peer;
+    @Override
+    public void initialize(final PlatformWindow platformWindow) {
         this.platformWindow = platformWindow;
-
-        long windowLayerPtr = platformWindow.getLayerPtr();
-        setPtr(nativeCreateComponent(windowLayerPtr));
+        setPtr(nativeCreateComponent(platformWindow.getLayerPtr()));
     }
 
     // TODO: visibility, z-order
 
     @Override
-    public void setBounds(int x, int y, int width, int height) {
+    public void setBounds(final int x, final int y, final int w, final int h) {
         // translates values from the coordinate system of the top-level window
         // to the coordinate system of the content view
-        Insets insets = platformWindow.getPeer().getInsets();
-        nativeSetBounds(getPointer(), x - insets.left, y - insets.top, width, height);
+        final Insets insets = platformWindow.getPeer().getInsets();
+        nativeSetBounds(getPointer(), x - insets.left, y - insets.top, w, h);
     }
 
     @Override
     public void dispose() {
         super.dispose();
     }
+
+    private native long nativeCreateComponent(long windowLayer);
+
+    private native void nativeSetBounds(long ptr, int x, int y, int w, int h);
 }
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java
index ee07977..80b5715 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformEmbeddedFrame.java
@@ -117,7 +117,7 @@
         Rectangle r = peer.getBounds();
         Image im = null;
         if (!r.isEmpty()) {
-            int transparency = (peer.isOpaque() ? Transparency.OPAQUE : Transparency.TRANSLUCENT);
+            int transparency = peer.isTranslucent() ? Transparency.TRANSLUCENT : Transparency.OPAQUE;
             im = peer.getGraphicsConfiguration().createCompatibleImage(r.width, r.height, transparency);
         }
         return im;
@@ -207,4 +207,13 @@
 
     @Override
     public void setModalBlocked(boolean blocked) {}
+
+    /*
+     * The method could not be implemented due to CALayer restrictions.
+     * The exeption enforce clients not to use it.
+     */
+    @Override
+    public boolean isUnderMouse() {
+        throw new RuntimeException("Not implemented");
+    }
 }
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java
index 059ef01..a7580a6 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformResponder.java
@@ -134,7 +134,7 @@
         boolean postsTyped = false;
 
         char testChar = KeyEvent.CHAR_UNDEFINED;
-        char testDeadChar = 0;
+        boolean isDeadChar = (chars!= null && chars.length() == 0);
 
         if (isFlagsChangedEvent) {
             int[] in = new int[] {modifierFlags, keyCode};
@@ -150,14 +150,21 @@
                 testChar = chars.charAt(0);
             }
 
-            int[] in = new int[] {testChar, testDeadChar, modifierFlags, keyCode};
-            int[] out = new int[2]; // [jkeyCode, jkeyLocation]
+            int[] in = new int[] {testChar, isDeadChar ? 1 : 0, modifierFlags, keyCode};
+            int[] out = new int[3]; // [jkeyCode, jkeyLocation, deadChar]
 
             postsTyped = NSEvent.nsToJavaKeyInfo(in, out);
             if (!postsTyped) {
                 testChar = KeyEvent.CHAR_UNDEFINED;
             }
 
+            if(isDeadChar){
+                testChar = (char) out[2];
+                if(testChar == 0){
+                    return;
+                }
+            }
+
             jkeyCode = out[0];
             jkeyLocation = out[1];
             jeventType = isNpapiCallback ? NSEvent.npToJavaEventType(eventType) :
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java
index 5c072a6..ebae30c 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformView.java
@@ -27,9 +27,11 @@
 
 import java.awt.*;
 import java.awt.event.*;
+import java.awt.geom.Rectangle2D;
 import java.awt.image.VolatileImage;
 
 import sun.awt.CGraphicsConfig;
+import sun.awt.CGraphicsEnvironment;
 import sun.lwawt.LWWindowPeer;
 import sun.lwawt.macosx.event.NSEvent;
 
@@ -39,6 +41,10 @@
 
 public class CPlatformView extends CFRetainedResource {
     private native long nativeCreateView(int x, int y, int width, int height, long windowLayerPtr);
+    private static native void nativeSetAutoResizable(long awtView, boolean toResize);
+    private static native int nativeGetNSViewDisplayID(long awtView);
+    private static native Rectangle2D nativeGetLocationOnScreen(long awtView);
+    private static native boolean nativeIsViewUnderMouse(long ptr);
 
     private LWWindowPeer peer;
     private SurfaceData surfaceData;
@@ -61,10 +67,10 @@
 
     public long getAWTView() {
         return ptr;
-    }
+        }
 
     public boolean isOpaque() {
-        return peer.isOpaque();
+        return !peer.isTranslucent();
     }
 
     /*
@@ -180,10 +186,46 @@
         }
     }
 
+    public void setAutoResizable(boolean toResize) {
+        nativeSetAutoResizable(this.getAWTView(), toResize);
+    }
+
+    public boolean isUnderMouse() {
+        return nativeIsViewUnderMouse(getAWTView());
+    }
+
+    public GraphicsDevice getGraphicsDevice() {
+        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        CGraphicsEnvironment cge = (CGraphicsEnvironment)ge;
+        int displayID = nativeGetNSViewDisplayID(getAWTView());
+        GraphicsDevice gd = cge.getScreenDevice(displayID);
+        if (gd == null) {
+            // this could possibly happen during device removal
+            // use the default screen device in this case
+            gd = ge.getDefaultScreenDevice();
+        }
+        return gd;
+    }
+
+    public Point getLocationOnScreen() {
+        Rectangle r = nativeGetLocationOnScreen(this.getAWTView()).getBounds();
+        return new Point(r.x, r.y);
+    }
+
     // ----------------------------------------------------------------------
     // NATIVE CALLBACKS
     // ----------------------------------------------------------------------
 
+    /*
+     * The callback is called only in the embedded case when the view is
+     * automatically resized by the superview.
+     * In normal mode this method is never called.
+     */
+    private void deliverResize(int x, int y, int w, int h) {
+        peer.notifyReshape(x, y, w, h);
+    }
+
+
     private void deliverMouseEvent(NSEvent event) {
         int x = event.getX();
         int y = getBounds().height - event.getY();
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
index 58e728e..519e2dd 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java
@@ -64,8 +64,6 @@
     private static native void nativeSynthesizeMouseEnteredExitedEvents(long nsWindowPtr);
     private static native void nativeDispose(long nsWindowPtr);
 
-    private static native int nativeGetNSWindowDisplayID_AppKitThread(long nsWindowPtr);
-
     // Loger to report issues happened during execution but that do not affect functionality
     private static final PlatformLogger logger = PlatformLogger.getLogger("sun.lwawt.macosx.CPlatformWindow");
     private static final PlatformLogger focusLogger = PlatformLogger.getLogger("sun.lwawt.macosx.focus.CPlatformWindow");
@@ -211,9 +209,8 @@
     private CPlatformResponder responder;
     private volatile boolean zoomed = false; // from native perspective
 
-    public CPlatformWindow(final PeerType peerType) {
+    public CPlatformWindow() {
         super(0, true);
-        assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
     }
 
     /*
@@ -299,7 +296,7 @@
 
         // If the target is a dialog, popup or tooltip we want it to ignore the brushed metal look.
         if (isPopup) {
-            styleBits = SET(styleBits, TEXTURED, true);
+            styleBits = SET(styleBits, TEXTURED, false);
             // Popups in applets don't activate applet's process
             styleBits = SET(styleBits, NONACTIVATING, true);
         }
@@ -373,6 +370,8 @@
             }
         }
 
+        peer.setTextured(IS(TEXTURED, styleBits));
+
         return styleBits;
     }
 
@@ -439,16 +438,7 @@
 
     @Override
     public GraphicsDevice getGraphicsDevice() {
-        GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
-        CGraphicsEnvironment cge = (CGraphicsEnvironment)ge;
-        int displayID = nativeGetNSWindowDisplayID_AppKitThread(getNSWindowPtr());
-        GraphicsDevice gd = cge.getScreenDevice(displayID);
-        if (gd == null) {
-            // this could possibly happen during device removal
-            // use the default screen device in this case
-            gd = ge.getDefaultScreenDevice();
-        }
-        return gd;
+        return contentView.getGraphicsDevice();
     }
 
     @Override // PlatformWindow
@@ -735,10 +725,19 @@
     @Override
     public void setOpaque(boolean isOpaque) {
         CWrapper.NSWindow.setOpaque(getNSWindowPtr(), isOpaque);
-        if (!isOpaque) {
+        if (!isOpaque && !peer.isTextured()) {
             long clearColor = CWrapper.NSColor.clearColor();
             CWrapper.NSWindow.setBackgroundColor(getNSWindowPtr(), clearColor);
         }
+
+        //This is a temporary workaround. Looks like after 7124236 will be fixed
+        //the correct place for invalidateShadow() is CGLayer.drawInCGLContext.
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                invalidateShadow();
+            }
+        });
     }
 
     @Override
@@ -808,6 +807,10 @@
     }
 
 
+    public final void invalidateShadow(){
+        nativeRevalidateNSWindowShadow(getNSWindowPtr());
+    }
+
     // ----------------------------------------------------------------------
     //                          UTILITY METHODS
     // ----------------------------------------------------------------------
@@ -846,6 +849,11 @@
         return peer;
     }
 
+    @Override
+    public boolean isUnderMouse() {
+        return contentView.isUnderMouse();
+    }
+
     public CPlatformView getContentView() {
         return contentView;
     }
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java
index f50f286..1ca65e7 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CPrinterDialogPeer.java
@@ -41,7 +41,7 @@
     public CPrinterDialogPeer(CPrinterDialog target, PlatformComponent platformComponent,
                               PlatformWindow platformWindow)
     {
-        super(target, platformComponent, platformWindow);
+        super(target, platformComponent, platformWindow, LWWindowPeer.PeerType.DIALOG);
         //super(target);
         fTarget = target;
         super.initialize();
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java
new file mode 100644
index 0000000..9ba045b
--- /dev/null
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CViewEmbeddedFrame.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.lwawt.macosx;
+
+import java.awt.AWTKeyStroke;
+import java.awt.Toolkit;
+import java.lang.reflect.InvocationTargetException;
+import sun.awt.EmbeddedFrame;
+import sun.lwawt.LWToolkit;
+import sun.lwawt.LWWindowPeer;
+/*
+ * The CViewEmbeddedFrame class is used in the SWT_AWT bridge.
+ * This is a part of public API and should not be renamed or moved
+ */
+public class CViewEmbeddedFrame extends EmbeddedFrame {
+
+    private final long nsViewPtr;
+
+    private boolean isActive = false;
+
+    public CViewEmbeddedFrame(long nsViewPtr) {
+        this.nsViewPtr = nsViewPtr;
+    }
+
+    @SuppressWarnings("deprecation")
+    @Override
+    public void addNotify() {
+        if (getPeer() == null) {
+            LWToolkit toolkit = (LWToolkit) Toolkit.getDefaultToolkit();
+            setPeer(toolkit.createEmbeddedFrame(this));
+        }
+        super.addNotify();
+    }
+
+    public long getEmbedderHandle() {
+        return nsViewPtr;
+    }
+
+    @Override
+    public void registerAccelerator(AWTKeyStroke awtks) {
+    }
+
+    @Override
+    public void unregisterAccelerator(AWTKeyStroke awtks) {
+    }
+
+    public boolean isParentWindowActive() {
+        return isActive;
+    }
+
+    /*
+     * Synthetic event delivery for focus management
+     */
+    @Override
+    public void synthesizeWindowActivation(boolean activated) {
+        if (isActive != activated) {
+            isActive = activated;
+            ((LWWindowPeer)getPeer()).notifyActivation(activated);
+        }
+    }
+
+    /*
+     * Initializes the embedded frame bounds and validates a component.
+     * Designed to be called from the main thread
+     * This method should be called once from the initialization of the SWT_AWT Bridge
+     */
+    @SuppressWarnings("deprecation")
+    public void validateWithBounds(final int x, final int y, final int width, final int height) {
+        try {
+            LWCToolkit.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    ((LWWindowPeer) getPeer()).setBoundsPrivate(0, 0, width, height);
+                    validate();
+                    setVisible(true);
+                }
+            }, null);
+        } catch (InterruptedException | InvocationTargetException ex) {}
+    }
+}
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java
new file mode 100644
index 0000000..35ea45d
--- /dev/null
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CViewPlatformEmbeddedFrame.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.lwawt.macosx;
+
+import java.awt.BufferCapabilities.FlipContents;
+import java.awt.Font;
+import java.awt.FontMetrics;
+import java.awt.Graphics;
+import java.awt.GraphicsDevice;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.MenuBar;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.Window;
+import sun.awt.CausedFocusEvent.Cause;
+import sun.java2d.SurfaceData;
+import sun.lwawt.LWWindowPeer;
+import sun.lwawt.PlatformWindow;
+
+public class CViewPlatformEmbeddedFrame implements PlatformWindow {
+
+    private CPlatformView view;
+    private LWWindowPeer peer;
+    private CViewEmbeddedFrame target;
+    private CPlatformResponder responder;
+
+    @Override // PlatformWindow
+    public void initialize(Window target, final LWWindowPeer peer, PlatformWindow owner) {
+        this.peer = peer;
+        this.target = (CViewEmbeddedFrame) target;
+        responder = new CPlatformResponder(peer, false);
+
+        view = new CPlatformView();
+        view.initialize(peer, responder);
+
+        CWrapper.NSView.addSubview(this.target.getEmbedderHandle(), view.getAWTView());
+        view.setAutoResizable(true);
+    }
+
+    public long getNSViewPtr() {
+        return view.getAWTView();
+    }
+
+    @Override
+    public long getLayerPtr() {
+        return view.getWindowLayerPtr();
+    }
+
+    @Override
+    public LWWindowPeer getPeer() {
+        return peer;
+    }
+
+    @Override
+    public void dispose() {
+        CWrapper.NSView.removeFromSuperview(view.getAWTView());
+        view.dispose();
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        CWrapper.NSView.setHidden(view.getAWTView(), !visible);
+    }
+
+    @Override
+    public void setTitle(String title) {
+    }
+
+    @Override
+    public void setBounds(int x, int y, int w, int h) {
+        view.setBounds(x, y, w, h);
+        peer.notifyReshape(x, y, w, h);
+    }
+
+    @Override
+    public GraphicsDevice getGraphicsDevice() {
+        return view.getGraphicsDevice();
+    }
+
+    @Override
+    public Point getLocationOnScreen() {
+        return view.getLocationOnScreen();
+    }
+
+    @Override
+    public Insets getInsets() {
+        return new Insets(0, 0, 0, 0);
+    }
+
+    @Override
+    public FontMetrics getFontMetrics(Font f) {
+        throw new RuntimeException("Not implemented");
+    }
+
+    @Override
+    public SurfaceData getScreenSurface() {
+        return view.getSurfaceData();
+    }
+
+    @Override
+    public SurfaceData replaceSurfaceData() {
+        return view.replaceSurfaceData();
+    }
+
+    @Override
+    public void setModalBlocked(boolean blocked) {
+    }
+
+    @Override
+    public void toFront() {
+    }
+
+    @Override
+    public void toBack() {
+    }
+
+    @Override
+    public void setMenuBar(MenuBar mb) {
+    }
+
+    @Override
+    public void setAlwaysOnTop(boolean value) {
+    }
+
+    @Override
+    public void updateFocusableWindowState() {
+    }
+
+    @Override
+    public boolean rejectFocusRequest(Cause cause) {
+        return false;
+    }
+
+    @Override
+    public boolean requestWindowFocus() {
+        return true;
+    }
+
+    @Override
+    public boolean isActive() {
+        return target.isParentWindowActive();
+    }
+
+    @Override
+    public void setResizable(boolean resizable) {
+    }
+
+    @Override
+    public void setSizeConstraints(int minW, int minH, int maxW, int maxH) {
+    }
+
+    @Override
+    public Graphics transformGraphics(Graphics g) {
+        return g;
+    }
+
+    @Override
+    public void updateIconImages() {
+    }
+
+    @Override
+    public void setOpacity(float opacity) {
+    }
+
+    @Override
+    public void setOpaque(boolean isOpaque) {
+    }
+
+    @Override
+    public void enterFullScreenMode() {
+    }
+
+    @Override
+    public void exitFullScreenMode() {
+    }
+
+    @Override
+    public void setWindowState(int windowState) {
+    }
+
+    @Override
+    public boolean isUnderMouse() {
+        return view.isUnderMouse();
+    }
+
+    @Override
+    public Image createBackBuffer() {
+        return view.createBackBuffer();
+    }
+
+    @Override
+    public void flip(int x1, int y1, int x2, int y2, FlipContents flipAction) {
+        throw new RuntimeException("Not implemented");
+    }
+}
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java b/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java
index 385259e..52aa16c 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/CWrapper.java
@@ -85,6 +85,8 @@
 
         public static native void enterFullScreenMode(long view);
         public static native void exitFullScreenMode(long view);
+
+        public static native void setHidden(long view, boolean hidden);
     }
 
     public static final class NSObject {
diff --git a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
index 36640ea..97d4c32 100644
--- a/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
+++ b/jdk/src/macosx/classes/sun/lwawt/macosx/LWCToolkit.java
@@ -162,10 +162,13 @@
 
     @Override
     protected PlatformWindow createPlatformWindow(PeerType peerType) {
-        if (peerType == PeerType.EMBEDDEDFRAME) {
+        if (peerType == PeerType.EMBEDDED_FRAME) {
             return new CPlatformEmbeddedFrame();
+        } else if (peerType == PeerType.VIEW_EMBEDDED_FRAME) {
+            return new CViewPlatformEmbeddedFrame();
         } else {
-            return new CPlatformWindow(peerType);
+            assert (peerType == PeerType.SIMPLEWINDOW || peerType == PeerType.DIALOG || peerType == PeerType.FRAME);
+            return new CPlatformWindow();
         }
     }
 
@@ -752,6 +755,11 @@
     }
 
     @Override
+    public boolean isWindowShapingSupported() {
+        return true;
+    }
+
+    @Override
     public boolean isWindowTranslucencySupported() {
         return true;
     }
@@ -761,6 +769,10 @@
         return true;
     }
 
+    public boolean isSwingBackbufferTranslucencySupported() {
+        return true;
+    }
+
     @Override
     public boolean enableInputMethodsForTextComponent() {
         return true;
diff --git a/jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java b/jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
index e060212..03c8630 100644
--- a/jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
+++ b/jdk/src/macosx/classes/sun/nio/ch/KQueueArrayWrapper.java
@@ -34,7 +34,8 @@
 import sun.misc.*;
 import java.io.IOException;
 import java.io.FileDescriptor;
-
+import java.util.Iterator;
+import java.util.LinkedList;
 
 /*
  * struct kevent {           // 32-bit    64-bit
@@ -99,6 +100,18 @@
         kq = init();
     }
 
+    // Used to update file description registrations
+    private static class Update {
+        SelChImpl channel;
+        int events;
+        Update(SelChImpl channel, int events) {
+            this.channel = channel;
+            this.events = events;
+        }
+    }
+
+    private LinkedList<Update> updateList = new LinkedList<Update>();
+
     void initInterrupt(int fd0, int fd1) {
         outgoingInterruptFD = fd1;
         incomingInterruptFD = fd0;
@@ -136,14 +149,41 @@
         }
     }
 
-    void setInterest(int fd, int events) {
-        register0(kq, fd, events & POLLIN, events & POLLOUT);
+    void setInterest(SelChImpl channel, int events) {
+        synchronized (updateList) {
+            // update existing registration
+            updateList.add(new Update(channel, events));
+        }
     }
 
-    void release(int fd) {
-        register0(kq, fd, 0, 0);
+    void release(SelChImpl channel) {
+        synchronized (updateList) {
+            // flush any pending updates
+            for (Iterator<Update> it = updateList.iterator(); it.hasNext();) {
+                if (it.next().channel == channel) {
+                    it.remove();
+                }
+            }
+
+            // remove
+            register0(kq, channel.getFDVal(), 0, 0);
+        }
     }
 
+    void updateRegistrations() {
+        synchronized (updateList) {
+            Update u = null;
+            while ((u = updateList.poll()) != null) {
+                SelChImpl ch = u.channel;
+                if (!ch.isOpen())
+                    continue;
+
+                register0(kq, ch.getFDVal(), u.events & POLLIN, u.events & POLLOUT);
+            }
+        }
+    }
+
+
     void close() throws IOException {
         if (keventArray != null) {
             keventArray.free();
@@ -156,6 +196,7 @@
     }
 
     int poll(long timeout) {
+        updateRegistrations();
         int updated = kevent0(kq, keventArrayAddress, NUM_KEVENTS, timeout);
         return updated;
     }
@@ -172,4 +213,3 @@
                                long timeout);
     private static native void interrupt(int fd);
 }
-
diff --git a/jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java b/jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
index b150426..7639ef0 100644
--- a/jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
+++ b/jdk/src/macosx/classes/sun/nio/ch/KQueueSelectorImpl.java
@@ -184,7 +184,6 @@
             FileDispatcherImpl.closeIntFD(fd0);
             FileDispatcherImpl.closeIntFD(fd1);
             if (kqueueWrapper != null) {
-                kqueueWrapper.release(fd0);
                 kqueueWrapper.close();
                 kqueueWrapper = null;
                 selectedKeys = null;
@@ -220,7 +219,7 @@
     protected void implDereg(SelectionKeyImpl ski) throws IOException {
         int fd = ski.channel.getFDVal();
         fdMap.remove(Integer.valueOf(fd));
-        kqueueWrapper.release(fd);
+        kqueueWrapper.release(ski.channel);
         totalChannels--;
         keys.remove(ski);
         selectedKeys.remove(ski);
@@ -234,8 +233,7 @@
     public void putEventOps(SelectionKeyImpl ski, int ops) {
         if (closed)
             throw new ClosedSelectorException();
-        int fd = IOUtil.fdVal(ski.channel.getFD());
-        kqueueWrapper.setInterest(fd, ops);
+        kqueueWrapper.setInterest(ski.channel, ops);
     }
 
 
@@ -254,4 +252,3 @@
         Util.load();
     }
 }
-
diff --git a/jdk/src/macosx/native/java/util/MacOSXPreferencesFile.m b/jdk/src/macosx/native/java/util/MacOSXPreferencesFile.m
index a564e4b..d8bef39 100644
--- a/jdk/src/macosx/native/java/util/MacOSXPreferencesFile.m
+++ b/jdk/src/macosx/native/java/util/MacOSXPreferencesFile.m
@@ -641,7 +641,7 @@
 
 
 // child must end with '/'
-JNIEXPORT void JNICALL
+JNIEXPORT Boolean JNICALL
 Java_java_util_prefs_MacOSXPreferencesFile_addChildToNode
 (JNIEnv *env, jobject klass, jobject jpath, jobject jchild,
  jobject jname, jlong juser, jlong jhost)
@@ -656,6 +656,7 @@
     CFDictionaryRef node;
     CFStringRef topKey;
     CFMutableDictionaryRef topValue;
+    Boolean beforeAdd = false;
 
     if (!path  ||  !child  ||  !name) goto badparams;
 
@@ -665,9 +666,12 @@
     // copyMutableNode creates the node if necessary
     parent = copyMutableNode(path, name, user, host, &topKey, &topValue);
     throwIfNull(parent, "copyMutableNode failed");
-
+    beforeAdd = CFDictionaryContainsKey(parent, child);
     CFDictionaryAddValue(parent, child, node);
-
+    if (!beforeAdd)
+        beforeAdd = CFDictionaryContainsKey(parent, child);
+    else
+        beforeAdd = false;
     CFPreferencesSetValue(topKey, topValue, name, user, host);
 
     CFRelease(parent);
@@ -680,6 +684,7 @@
     if (path) CFRelease(path);
     if (child) CFRelease(child);
     if (name) CFRelease(name);
+    return beforeAdd;
 }
 
 
diff --git a/jdk/src/macosx/native/sun/awt/AWTEvent.m b/jdk/src/macosx/native/sun/awt/AWTEvent.m
index 5692b60..845e528 100644
--- a/jdk/src/macosx/native/sun/awt/AWTEvent.m
+++ b/jdk/src/macosx/native/sun/awt/AWTEvent.m
@@ -26,6 +26,7 @@
 #import <JavaNativeFoundation/JavaNativeFoundation.h>
 #import <JavaRuntimeSupport/JavaRuntimeSupport.h>
 #import <sys/time.h>
+#include <Carbon/Carbon.h>
 
 #import "LWCToolkit.h"
 #import "ThreadUtilities.h"
@@ -378,26 +379,68 @@
     return nsChar;
 }
 
+static unichar NsGetDeadKeyChar(unsigned short keyCode)
+{
+    TISInputSourceRef currentKeyboard = TISCopyCurrentKeyboardInputSource();
+    CFDataRef uchr = (CFDataRef)TISGetInputSourceProperty(currentKeyboard, kTISPropertyUnicodeKeyLayoutData);
+    if (uchr == nil) { return; }
+    const UCKeyboardLayout *keyboardLayout = (const UCKeyboardLayout*)CFDataGetBytePtr(uchr);
+    // Carbon modifiers should be used instead of NSEvent modifiers
+    UInt32 modifierKeyState = (GetCurrentEventKeyModifiers() >> 8) & 0xFF;
+
+    if (keyboardLayout) {
+        UInt32 deadKeyState = 0;
+        UniCharCount maxStringLength = 255;
+        UniCharCount actualStringLength = 0;
+        UniChar unicodeString[maxStringLength];
+
+        // get the deadKeyState
+        OSStatus status = UCKeyTranslate(keyboardLayout,
+                                         keyCode, kUCKeyActionDown, modifierKeyState,
+                                         LMGetKbdType(), kUCKeyTranslateNoDeadKeysBit,
+                                         &deadKeyState,
+                                         maxStringLength,
+                                         &actualStringLength, unicodeString);
+
+        if (status == noErr && deadKeyState != 0) {
+            // Press SPACE to get the dead key char
+            status = UCKeyTranslate(keyboardLayout,
+                                    kVK_Space, kUCKeyActionDown, 0,
+                                    LMGetKbdType(), 0,
+                                    &deadKeyState,
+                                    maxStringLength,
+                                    &actualStringLength, unicodeString);
+
+            if (status == noErr && actualStringLength > 0) {
+                return unicodeString[0];
+            }
+        }
+    }
+    return 0;
+}
+
 /*
  * This is the function that uses the table above to take incoming
  * NSEvent keyCodes and translate to the Java virtual key code.
  */
 static void
-NsCharToJavaVirtualKeyCode(unichar ch, unichar deadChar,
+NsCharToJavaVirtualKeyCode(unichar ch, BOOL isDeadChar,
                            NSUInteger flags, unsigned short key,
-                           jint *keyCode, jint *keyLocation, BOOL *postsTyped)
+                           jint *keyCode, jint *keyLocation, BOOL *postsTyped, unichar *deadChar)
 {
     static size_t size = sizeof(keyTable) / sizeof(struct _key);
     NSInteger offset;
 
-    if (deadChar) {
+    if (isDeadChar) {
+        unichar testDeadChar = NsGetDeadKeyChar(key);
         const struct CharToVKEntry *map;
         for (map = charToDeadVKTable; map->c != 0; ++map) {
-            if (deadChar == map->c) {
+            if (testDeadChar == map->c) {
                 *keyCode = map->javaKey;
                 *postsTyped = NO;
                 // TODO: use UNKNOWN here?
                 *keyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
+                *deadChar = testDeadChar;
                 return;
             }
         }
@@ -521,18 +564,18 @@
     const struct _nsKeyToJavaModifier* cur;
 
     for (cur = nsKeyToJavaModifierTable; cur->nsMask != 0; ++cur) {
-        jint mask = isExtMods? cur->javaExtMask : cur->javaMask; 
+        jint mask = isExtMods? cur->javaExtMask : cur->javaMask;
         if ((mask & javaModifiers) != 0) {
             nsFlags |= cur->nsMask;
         }
     }
 
     // special case
-    jint mask = isExtMods? java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK : 
+    jint mask = isExtMods? java_awt_event_InputEvent_ALT_GRAPH_DOWN_MASK :
                            java_awt_event_InputEvent_ALT_GRAPH_MASK;
 
     if ((mask & javaModifiers) != 0) {
-        nsFlags |= NSAlternateKeyMask;      
+        nsFlags |= NSAlternateKeyMask;
     }
 
     return nsFlags;
@@ -691,14 +734,10 @@
         }
 
         javaModifiers = NsKeyModifiersToJavaModifiers([event modifierFlags], TRUE);
-        if (javaModifiers == 0) {
-      // TODO: dead key chars
-//            testDeadChar = GetDeadKeyCharacter(event);
-        }
 
-        NsCharToJavaVirtualKeyCode(testChar, testDeadChar,
+        NsCharToJavaVirtualKeyCode(testChar, NO,
                                    [event modifierFlags], [event keyCode],
-                                   &javaKeyCode, &javaKeyLocation, &postsTyped);
+                                   &javaKeyCode, &javaKeyLocation, &postsTyped, &testDeadChar);
         if( !postsTyped ) {
             testChar = java_awt_event_KeyEvent_CHAR_UNDEFINED;
         }
@@ -823,18 +862,14 @@
     unichar testChar, testDeadChar = 0;
     jint javaModifiers = NsKeyModifiersToJavaModifiers([nsEvent modifierFlags], TRUE);
 
-    if (javaModifiers == 0) {
-        testDeadChar = [nsEvent deadKeyCharacter];
-    }
-
     NSString *theChars = [nsEvent characters];
     unsigned i, stringLength = [theChars length];
 
     for (i = 0; i < stringLength; i++) {
         testChar = [theChars characterAtIndex:i];
-        NsCharToJavaVirtualKeyCode(testChar, testDeadChar,
+        NsCharToJavaVirtualKeyCode(testChar, NO,
                                    [nsEvent modifierFlags], [nsEvent keyCode],
-                                   &javaKeyCode, &javaKeyLocation, &postsTyped);
+                                   &javaKeyCode, &javaKeyLocation, &postsTyped, &testDeadChar);
 
         if (postsTyped) {
             // Some keys may generate a KEY_TYPED, but we can't determine
@@ -1042,23 +1077,25 @@
 
     // in  = [testChar, testDeadChar, modifierFlags, keyCode]
     jchar testChar = (jchar)data[0];
-    jchar testDeadChar = (jchar)data[1];
+    BOOL isDeadChar = (data[1] != 0);
     jint modifierFlags = data[2];
     jshort keyCode = (jshort)data[3];
 
     jint jkeyCode = java_awt_event_KeyEvent_VK_UNDEFINED;
     jint jkeyLocation = java_awt_event_KeyEvent_KEY_LOCATION_UNKNOWN;
+    jchar testDeadChar = 0;
 
-    NsCharToJavaVirtualKeyCode((unichar)testChar, (unichar)testDeadChar,
+    NsCharToJavaVirtualKeyCode((unichar)testChar, isDeadChar,
                                (NSUInteger)modifierFlags, (unsigned short)keyCode,
-                               &jkeyCode, &jkeyLocation, &postsTyped);
+                               &jkeyCode, &jkeyLocation, &postsTyped, &testDeadChar);
 
-    // out = [jkeyCode, jkeyLocation];
+    // out = [jkeyCode, jkeyLocation, deadKeyChar];
     (*env)->SetIntArrayRegion(env, outData, 0, 1, &jkeyCode);
     (*env)->SetIntArrayRegion(env, outData, 1, 1, &jkeyLocation);
-    
+    (*env)->SetIntArrayRegion(env, outData, 2, 1, (jint *)&testDeadChar);
+
     (*env)->ReleaseIntArrayElements(env, inData, data, 0);
-    
+
 JNF_COCOA_EXIT(env);
 
     return postsTyped;
@@ -1098,7 +1135,7 @@
     (*env)->SetIntArrayRegion(env, outData, 2, 1, &jkeyType);
 
     (*env)->ReleaseIntArrayElements(env, inData, data, 0);
-    
+
 JNF_COCOA_EXIT(env);
 }
 
@@ -1112,12 +1149,12 @@
 (JNIEnv *env, jclass cls, char nsChar, jint modifierFlags)
 {
     jchar javaChar = 0;
-    
+
 JNF_COCOA_ENTER(env);
-    
+
     javaChar = NsCharToJavaChar(nsChar, modifierFlags);
 
 JNF_COCOA_EXIT(env);
-    
+
     return javaChar;
 }
diff --git a/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m b/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
index f3ab2d7..c6fec1f 100644
--- a/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
+++ b/jdk/src/macosx/native/sun/awt/AWTSurfaceLayers.m
@@ -78,11 +78,10 @@
 
     // translates values to the coordinate system of the "root" layer
     CGFloat newY = windowLayer.bounds.size.height - rect.origin.y - rect.size.height;
+    CGRect newRect = CGRectMake(rect.origin.x, newY, rect.size.width, rect.size.height);
 
-    // REMIND: why do we need to inverse position?
-    CGRect newRect = CGRectMake(-rect.origin.x, -newY, rect.size.width, rect.size.height);
+    layer.frame = newRect;
 
-    layer.bounds = newRect;
     [AWTSurfaceLayers repaintLayersRecursively:layer];
 }
 
@@ -100,17 +99,16 @@
   __block AWTSurfaceLayers *surfaceLayers = nil;
 
 JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
 
-  [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
-      AWT_ASSERT_APPKIT_THREAD;
-
-      CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
-      surfaceLayers = [[AWTSurfaceLayers alloc] initWithWindowLayer: windowLayer];
-      CFRetain(surfaceLayers);
-      [surfaceLayers release];
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+        AWT_ASSERT_APPKIT_THREAD;
+        
+        CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
+        surfaceLayers = [[AWTSurfaceLayers alloc] initWithWindowLayer: windowLayer];
+        CFRetain(surfaceLayers);
+        [surfaceLayers release];
     }];
-
+    
 JNF_COCOA_EXIT(env);
 
   return ptr_to_jlong(surfaceLayers);
@@ -127,12 +125,13 @@
 JNF_COCOA_ENTER(env);
 
   AWTSurfaceLayers *surfaceLayers = OBJC(surfaceLayersPtr);
-  [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+    
+  [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
       AWT_ASSERT_APPKIT_THREAD;
 
       CGRect rect = CGRectMake(x, y, width, height);
       [surfaceLayers setBounds: rect];
-    }];
+  }];
 
 JNF_COCOA_EXIT(env);
 }
diff --git a/jdk/src/macosx/native/sun/awt/AWTView.m b/jdk/src/macosx/native/sun/awt/AWTView.m
index c049e6a..3342d3c 100644
--- a/jdk/src/macosx/native/sun/awt/AWTView.m
+++ b/jdk/src/macosx/native/sun/awt/AWTView.m
@@ -170,6 +170,11 @@
  * Automatically triggered functions.
  */
 
+- (void)resizeWithOldSuperviewSize:(NSSize)oldBoundsSize {
+    [super resizeWithOldSuperviewSize: oldBoundsSize];
+    [self deliverResize: [self frame]];
+}
+
 /*
  * MouseEvents support
  */
@@ -278,7 +283,10 @@
         return;
     }
 
-    if (![self hasMarkedText] && fKeyEventsNeeded) {
+    NSString *eventCharacters = [event characters];
+    BOOL isDeadKey = (eventCharacters != nil && [eventCharacters length] == 0);
+
+    if ((![self hasMarkedText] && fKeyEventsNeeded) || isDeadKey) {
         [self deliverJavaKeyEventHelper: event];
     }
 
@@ -430,6 +438,18 @@
     }
 }
 
+-(void) deliverResize: (NSRect) rect {
+    jint x = (jint) rect.origin.x;
+    jint y = (jint) rect.origin.y;
+    jint w = (jint) rect.size.width;
+    jint h = (jint) rect.size.height;
+    JNIEnv *env = [ThreadUtilities getJNIEnv];
+    static JNF_CLASS_CACHE(jc_PlatformView, "sun/lwawt/macosx/CPlatformView");
+    static JNF_MEMBER_CACHE(jm_deliverResize, jc_PlatformView, "deliverResize", "(IIII)V");
+    JNFCallVoidMethod(env, m_cPlatformView, jm_deliverResize, x,y,w,h);
+}
+
+
 - (void) drawRect:(NSRect)dirtyRect {
 AWT_ASSERT_APPKIT_THREAD;
 
@@ -1213,21 +1233,19 @@
     __block AWTView *newView = nil;
 
 JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
 
     NSRect rect = NSMakeRect(originX, originY, width, height);
     jobject cPlatformView = (*env)->NewGlobalRef(env, obj);
 
-    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
         AWT_ASSERT_APPKIT_THREAD;
-
+                                           
         CALayer *windowLayer = jlong_to_ptr(windowLayerPtr);
         AWTView *view = [[AWTView alloc] initWithRect:rect
                                          platformView:cPlatformView
                                          windowLayer:windowLayer];
         CFRetain(view);
         [view release]; // GC
-
         newView = view;
     }];
 
@@ -1235,3 +1253,125 @@
 
     return ptr_to_jlong(newView);
 }
+
+/*
+ * Class:     sun_lwawt_macosx_CPlatformView
+ * Method:    nativeSetAutoResizable
+ * Signature: (JZ)V;
+ */
+
+JNIEXPORT void JNICALL
+Java_sun_lwawt_macosx_CPlatformView_nativeSetAutoResizable
+(JNIEnv *env, jclass cls, jlong viewPtr, jboolean toResize)
+{
+JNF_COCOA_ENTER(env);
+    
+    NSView *view = (NSView *)jlong_to_ptr(viewPtr);    
+
+   [ThreadUtilities performOnMainThreadWaiting:NO block:^(){
+       AWT_ASSERT_APPKIT_THREAD;
+       
+       if (toResize) {
+           [view setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
+       } else {
+           [view setAutoresizingMask: NSViewMinYMargin | NSViewMaxXMargin];
+       }
+       
+       if ([view superview] != nil) {
+           [[view superview] setAutoresizesSubviews:(BOOL)toResize];
+       }
+       
+    }];
+JNF_COCOA_EXIT(env);
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CPlatformView
+ * Method:    nativeGetNSViewDisplayID
+ * Signature: (J)I;
+ */
+
+JNIEXPORT jint JNICALL
+Java_sun_lwawt_macosx_CPlatformView_nativeGetNSViewDisplayID
+(JNIEnv *env, jclass cls, jlong viewPtr)
+{
+    __block jint ret; //CGDirectDisplayID
+    
+JNF_COCOA_ENTER(env);
+    
+    NSView *view = (NSView *)jlong_to_ptr(viewPtr);    
+    NSWindow *window = [view window];
+    
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+            AWT_ASSERT_APPKIT_THREAD;
+        
+            ret = (jint)[[AWTWindow getNSWindowDisplayID_AppKitThread: window] intValue];
+    }];
+    
+JNF_COCOA_EXIT(env);
+    
+    return ret;
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CPlatformView
+ * Method:    nativeGetLocationOnScreen
+ * Signature: (J)Ljava/awt/Rectangle;
+ */
+
+JNIEXPORT jobject JNICALL
+Java_sun_lwawt_macosx_CPlatformView_nativeGetLocationOnScreen
+(JNIEnv *env, jclass cls, jlong viewPtr)
+{
+    jobject jRect = NULL;
+    
+JNF_COCOA_ENTER(env);
+    
+    __block NSRect rect = NSZeroRect;
+    
+    NSView *view = (NSView *)jlong_to_ptr(viewPtr);    
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+        AWT_ASSERT_APPKIT_THREAD;
+        
+        NSRect viewBounds = [view bounds];
+        NSRect frameInWindow = [view convertRect:viewBounds toView:nil];
+        rect = [[view window] convertRectToScreen:frameInWindow];
+        NSRect screenRect = [[NSScreen mainScreen] frame];
+        //Convert coordinates to top-left corner origin
+        rect.origin.y = screenRect.size.height - rect.origin.y - viewBounds.size.height;
+    }];
+    jRect = NSToJavaRect(env, rect);
+    
+JNF_COCOA_EXIT(env);
+    
+    return jRect;
+}
+
+/*
+ * Class:     sun_lwawt_macosx_CPlatformView
+ * Method:    nativeIsViewUnderMouse
+ * Signature: (J)Z;
+ */
+
+JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CPlatformView_nativeIsViewUnderMouse
+(JNIEnv *env, jclass clazz, jlong viewPtr)
+{
+    __block jboolean underMouse = JNI_FALSE;
+    
+JNF_COCOA_ENTER(env);
+    
+    NSView *nsView = OBJC(viewPtr);
+   [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+       AWT_ASSERT_APPKIT_THREAD;
+       
+       NSPoint ptWindowCoords = [[nsView window] mouseLocationOutsideOfEventStream];
+       NSPoint ptViewCoords = [nsView convertPoint:ptWindowCoords fromView:nil];
+       underMouse = [nsView hitTest:ptViewCoords] != nil;
+    }];
+    
+JNF_COCOA_EXIT(env);
+    
+    return underMouse;
+}
+
+
diff --git a/jdk/src/macosx/native/sun/awt/AWTWindow.m b/jdk/src/macosx/native/sun/awt/AWTWindow.m
index 198cbea..ccf850a 100644
--- a/jdk/src/macosx/native/sun/awt/AWTWindow.m
+++ b/jdk/src/macosx/native/sun/awt/AWTWindow.m
@@ -358,6 +358,13 @@
     [[self.nsWindow contentView] deliverJavaMouseEvent: mouseEvent];
 }
 
++ (NSNumber *) getNSWindowDisplayID_AppKitThread:(NSWindow *)window {
+    AWT_ASSERT_APPKIT_THREAD;
+    NSScreen *screen = [window screen];
+    NSDictionary *deviceDescription = [screen deviceDescription];
+    return [deviceDescription objectForKey:@"NSScreenNumber"];
+}
+
 - (void) dealloc {
 AWT_ASSERT_APPKIT_THREAD;
 
@@ -1017,14 +1024,17 @@
 (JNIEnv *env, jclass clazz, jlong windowPtr)
 {
 JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
 
     NSWindow *nsWindow = OBJC(windowPtr);
-    [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
-        AWT_ASSERT_APPKIT_THREAD;
-
+    if ([NSThread isMainThread]) {
         [nsWindow invalidateShadow];
-    }];
+    } else {
+        [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+            AWT_ASSERT_APPKIT_THREAD;
+
+            [nsWindow invalidateShadow];
+        }];
+    }
 
 JNF_COCOA_EXIT(env);
 }
@@ -1135,31 +1145,6 @@
 
 /*
  * Class:     sun_lwawt_macosx_CPlatformWindow
- * Method:    nativeGetDisplayID_AppKitThread
- * Signature: (J)I
- */
-JNIEXPORT jint JNICALL
-Java_sun_lwawt_macosx_CPlatformWindow_nativeGetNSWindowDisplayID_1AppKitThread
-(JNIEnv *env, jclass clazz, jlong windowPtr)
-{
-    jint ret; // CGDirectDisplayID
-
-JNF_COCOA_ENTER(env);
-AWT_ASSERT_APPKIT_THREAD;
-
-    NSWindow *window = OBJC(windowPtr);
-    NSScreen *screen = [window screen];
-    NSDictionary *deviceDescription = [screen deviceDescription];
-    NSNumber *displayID = [deviceDescription objectForKey:@"NSScreenNumber"];
-    ret = (jint)[displayID intValue];
-
-JNF_COCOA_EXIT(env);
-
-    return ret;
-}
-
-/*
- * Class:     sun_lwawt_macosx_CPlatformWindow
  * Method:    _toggleFullScreenMode
  * Signature: (J)V
  */
@@ -1179,27 +1164,6 @@
 JNF_COCOA_EXIT(env);
 }
 
-JNIEXPORT jboolean JNICALL Java_sun_lwawt_macosx_CMouseInfoPeer_nativeIsWindowUnderMouse
-(JNIEnv *env, jclass clazz, jlong windowPtr)
-{
-    __block jboolean underMouse = JNI_FALSE;
-
-JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
-
-    NSWindow *nsWindow = OBJC(windowPtr);
-    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^() {
-        AWT_ASSERT_APPKIT_THREAD;
-
-        NSPoint pt = [nsWindow mouseLocationOutsideOfEventStream];
-        underMouse = [[nsWindow contentView] hitTest:pt] != nil;
-    }];
-
-JNF_COCOA_EXIT(env);
-
-    return underMouse;
-}
-
 JNIEXPORT void JNICALL Java_sun_lwawt_macosx_CPlatformWindow_nativeSetEnabled
 (JNIEnv *env, jclass clazz, jlong windowPtr, jboolean isEnabled)
 {
diff --git a/jdk/src/macosx/native/sun/awt/CCursorManager.m b/jdk/src/macosx/native/sun/awt/CCursorManager.m
index e7378d3..601ea91 100644
--- a/jdk/src/macosx/native/sun/awt/CCursorManager.m
+++ b/jdk/src/macosx/native/sun/awt/CCursorManager.m
@@ -123,14 +123,15 @@
     jobject jpt = NULL;
 
 JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
 
     __block NSPoint pt = NSZeroPoint;
-    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
-        AWT_ASSERT_APPKIT_THREAD;
-
-        pt = ConvertNSScreenPoint(env, [NSEvent mouseLocation]);
+    
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+            AWT_ASSERT_APPKIT_THREAD;
+        
+            pt = ConvertNSScreenPoint(env, [NSEvent mouseLocation]);
     }];
+    
     jpt = NSToJavaPoint(env, pt);
 
 JNF_COCOA_EXIT(env);
diff --git a/jdk/src/macosx/native/sun/awt/CFileDialog.h b/jdk/src/macosx/native/sun/awt/CFileDialog.h
index 14ed63d..b8f6e14 100644
--- a/jdk/src/macosx/native/sun/awt/CFileDialog.h
+++ b/jdk/src/macosx/native/sun/awt/CFileDialog.h
@@ -52,6 +52,9 @@
     // Should we navigate into apps?
     BOOL fNavigateApps;
 
+    // Can the dialog choose directories ?
+    BOOL fChooseDirectories;
+
     // Contains the absolute paths of the selected files as URLs
     NSArray *fURLs;
 }
@@ -65,6 +68,7 @@
                  mode:(jint)inMode
          multipleMode:(BOOL)inMultipleMode
        shouldNavigate:(BOOL)inNavigateApps
+ canChooseDirectories:(BOOL)inChooseDirectories
               withEnv:(JNIEnv*)env;
 
 // Invoked from the main thread
diff --git a/jdk/src/macosx/native/sun/awt/CFileDialog.m b/jdk/src/macosx/native/sun/awt/CFileDialog.m
index 283cc8c..be7cadc 100644
--- a/jdk/src/macosx/native/sun/awt/CFileDialog.m
+++ b/jdk/src/macosx/native/sun/awt/CFileDialog.m
@@ -43,6 +43,7 @@
                 mode:(jint)inMode
         multipleMode:(BOOL)inMultipleMode
       shouldNavigate:(BOOL)inNavigateApps
+canChooseDirectories:(BOOL)inChooseDirectories
              withEnv:(JNIEnv*)env;
 {
     if (self == [super init]) {
@@ -57,6 +58,7 @@
         fMode = inMode;
         fMultipleMode = inMultipleMode;
         fNavigateApps = inNavigateApps;
+        fChooseDirectories = inChooseDirectories;
         fPanelResult = NSCancelButton;
     }
 
@@ -109,7 +111,7 @@
             NSOpenPanel *openPanel = (NSOpenPanel *)thePanel;
             [openPanel setAllowsMultipleSelection:fMultipleMode];
             [openPanel setCanChooseFiles:YES];
-            [openPanel setCanChooseDirectories:NO];
+            [openPanel setCanChooseDirectories:fChooseDirectories];
             [openPanel setCanCreateDirectories:YES];
         }
 
@@ -182,7 +184,8 @@
 JNIEXPORT jobjectArray JNICALL
 Java_sun_lwawt_macosx_CFileDialog_nativeRunFileDialog
 (JNIEnv *env, jobject peer, jstring title, jint mode, jboolean multipleMode,
- jboolean navigateApps, jboolean hasFilter, jstring directory, jstring file)
+ jboolean navigateApps, jboolean chooseDirectories, jboolean hasFilter,
+ jstring directory, jstring file)
 {
     jobjectArray returnValue = NULL;
 
@@ -200,6 +203,7 @@
                                                                  mode:mode
                                                          multipleMode:multipleMode
                                                        shouldNavigate:navigateApps
+                                                 canChooseDirectories:chooseDirectories
                                                               withEnv:env];
 
     [JNFRunLoop performOnMainThread:@selector(safeSaveOrLoad)
diff --git a/jdk/src/macosx/native/sun/awt/CMenuItem.m b/jdk/src/macosx/native/sun/awt/CMenuItem.m
index 50c6ef7..8090e84 100644
--- a/jdk/src/macosx/native/sun/awt/CMenuItem.m
+++ b/jdk/src/macosx/native/sun/awt/CMenuItem.m
@@ -76,7 +76,7 @@
     NSEvent *currEvent = [[NSApplication sharedApplication] currentEvent];
     if ([currEvent type] == NSKeyDown) {
         NSString *menuKey = [sender keyEquivalent];
-        NSString *eventKey = [currEvent charactersIgnoringModifiers];
+        NSString *eventKey = [currEvent characters];
         if ([menuKey isEqualToString:eventKey]) {
             return;
         }
diff --git a/jdk/src/macosx/native/sun/awt/CTextPipe.m b/jdk/src/macosx/native/sun/awt/CTextPipe.m
index 37e8d4a..3adc847 100644
--- a/jdk/src/macosx/native/sun/awt/CTextPipe.m
+++ b/jdk/src/macosx/native/sun/awt/CTextPipe.m
@@ -235,9 +235,22 @@
     CGContextSetTextMatrix(cgRef, CGAffineTransformIdentity); // resets the damage from CoreText
 
     NSString *string = [NSString stringWithCharacters:chars length:length];
+    /*
+       The calls below were used previously but for unknown reason did not 
+       render using the right font (see bug 7183516) when attribString is not 
+       initialized with font dictionary attributes.  It seems that "options" 
+       in CTTypesetterCreateWithAttributedStringAndOptions which contains the 
+       font dictionary is ignored.
+
     NSAttributedString *attribString = [[NSAttributedString alloc] initWithString:string];
 
     CTTypesetterRef typeSetterRef = CTTypesetterCreateWithAttributedStringAndOptions((CFAttributedStringRef) attribString, (CFDictionaryRef) ctsDictionaryFor(nsFont, JRSFontStyleUsesFractionalMetrics(strike->fStyle)));
+    */
+    NSAttributedString *attribString = [[NSAttributedString alloc]
+        initWithString:string
+        attributes:ctsDictionaryFor(nsFont, JRSFontStyleUsesFractionalMetrics(strike->fStyle))];
+    
+    CTTypesetterRef typeSetterRef = CTTypesetterCreateWithAttributedString((CFAttributedStringRef) attribString);
 
     CFRange range = {0, length};
     CTLineRef lineRef = CTTypesetterCreateLine(typeSetterRef, range);
diff --git a/jdk/src/macosx/native/sun/awt/CWrapper.m b/jdk/src/macosx/native/sun/awt/CWrapper.m
index 52979ac..2e8b3e7 100644
--- a/jdk/src/macosx/native/sun/awt/CWrapper.m
+++ b/jdk/src/macosx/native/sun/awt/CWrapper.m
@@ -651,6 +651,26 @@
 }
 
 /*
+ * Class:     sun_lwawt_macosx_CWrapper$NSView
+ * Method:    setHidden
+ * Signature: (JZ)V
+ */
+JNIEXPORT jlong JNICALL
+Java_sun_lwawt_macosx_CWrapper_00024NSView_setHidden
+(JNIEnv *env, jclass cls, jlong viewPtr, jboolean toHide)
+{    
+    JNF_COCOA_ENTER(env);
+    
+    NSView *view = (NSView *)jlong_to_ptr(viewPtr);
+    [JNFRunLoop performOnMainThreadWaiting:NO withBlock:^(){
+        [view setHidden:(BOOL)toHide];
+    }];
+    
+    JNF_COCOA_EXIT(env);
+}
+
+
+/*
  * Class:     sun_lwawt_macosx_CWrapper$NSScreen
  * Method:    frame
  * Signature: (J)Ljava/awt/Rectangle;
diff --git a/jdk/src/macosx/native/sun/awt/awt.m b/jdk/src/macosx/native/sun/awt/awt.m
index c1216e7..3241ecc 100644
--- a/jdk/src/macosx/native/sun/awt/awt.m
+++ b/jdk/src/macosx/native/sun/awt/awt.m
@@ -371,7 +371,8 @@
             CFRunLoopRef runLoop = [[NSRunLoop currentRunLoop] getCFRunLoop];
             CFRunLoopRemoveObserver(runLoop, busyObserver, kCFRunLoopDefaultMode);
             CFRunLoopRemoveObserver(runLoop, notBusyObserver, kCFRunLoopDefaultMode);
-
+            // We don't track if the runloop is busy, so set it free to let AWT finish when it needs
+            setBusy(NO);
             busyObserver = NULL;
             notBusyObserver = NULL;
         } else {
diff --git a/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m b/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
index 736a24b..978fbe2 100644
--- a/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
+++ b/jdk/src/macosx/native/sun/java2d/opengl/CGLLayer.m
@@ -146,16 +146,15 @@
     __block CGLLayer *layer = nil;
 
 JNF_COCOA_ENTER(env);
-AWT_ASSERT_NOT_APPKIT_THREAD;
 
     JNFJObjectWrapper *javaLayer = [JNFJObjectWrapper wrapperWithJObject:obj withEnv:env];
 
-    [JNFRunLoop performOnMainThreadWaiting:YES withBlock:^(){
-        AWT_ASSERT_APPKIT_THREAD;
-
-        layer = [[CGLLayer alloc] initWithJavaLayer: javaLayer];
+    [ThreadUtilities performOnMainThreadWaiting:YES block:^(){
+            AWT_ASSERT_APPKIT_THREAD;
+        
+            layer = [[CGLLayer alloc] initWithJavaLayer: javaLayer];
     }];
-
+    
 JNF_COCOA_EXIT(env);
 
     return ptr_to_jlong(layer);
diff --git a/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.h b/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.h
index c681122..4bc5b7b 100644
--- a/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.h
+++ b/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.h
@@ -139,7 +139,7 @@
 + (JNIEnv*)getJNIEnvUncached;
 
 + (void)performOnMainThread:(SEL)aSelector onObject:(id)target withObject:(id)arg waitUntilDone:(BOOL)wait awtMode:(BOOL)inAWT;
-
++ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block;
 @end
 
 void OSXAPP_SetJavaVM(JavaVM *vm);
diff --git a/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.m b/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.m
index 6ff6b13..a13d6cd 100644
--- a/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.m
+++ b/jdk/src/macosx/native/sun/osxapp/ThreadUtilities.m
@@ -245,6 +245,14 @@
     }
 }
 
++ (void)performOnMainThreadWaiting:(BOOL)wait block:(void (^)())block {
+    if ([NSThread isMainThread] && wait == YES) {
+        block(); 
+    } else { 
+        [JNFRunLoop performOnMainThreadWaiting:wait withBlock:block]; 
+    }
+}
+
 @end
 
 
diff --git a/jdk/src/share/back/debugInit.c b/jdk/src/share/back/debugInit.c
index 490099b..25ffbff 100644
--- a/jdk/src/share/back/debugInit.c
+++ b/jdk/src/share/back/debugInit.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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,6 +37,7 @@
 #include "debugLoop.h"
 #include "bag.h"
 #include "invoker.h"
+#include "sys.h"
 
 /* How the options get to OnLoad: */
 #define XDEBUG "-Xdebug"
@@ -201,6 +202,8 @@
     jint              jvmtiCompileTimeMajorVersion;
     jint              jvmtiCompileTimeMinorVersion;
     jint              jvmtiCompileTimeMicroVersion;
+    char              *boot_path = NULL;
+    char              npt_lib[MAXPATHLEN];
 
     /* See if it's already loaded */
     if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
@@ -227,18 +230,6 @@
     vmInitialized = JNI_FALSE;
     gdata->vmDead = JNI_FALSE;
 
-    /* Npt and Utf function init */
-    NPT_INITIALIZE(&(gdata->npt), NPT_VERSION, NULL);
-    if (gdata->npt == NULL) {
-        ERROR_MESSAGE(("JDWP: unable to initialize NPT library"));
-        return JNI_ERR;
-    }
-    gdata->npt->utf = (gdata->npt->utfInitialize)(NULL);
-    if (gdata->npt->utf == NULL) {
-        ERROR_MESSAGE(("JDWP: UTF function initialization failed"));
-        return JNI_ERR;
-    }
-
     /* Get the JVMTI Env, IMPORTANT: Do this first! For jvmtiAllocate(). */
     error = JVM_FUNC_PTR(vm,GetEnv)
                 (vm, (void **)&(gdata->jvmti), JVMTI_VERSION_1);
@@ -277,6 +268,24 @@
         forceExit(1); /* Kill entire process, no core dump wanted */
     }
 
+    JVMTI_FUNC_PTR(gdata->jvmti, GetSystemProperty)
+        (gdata->jvmti, (const char *)"sun.boot.library.path",
+         &boot_path);
+
+    dbgsysBuildLibName(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
+    /* Npt and Utf function init */
+    NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
+    jvmtiDeallocate(boot_path);
+    if (gdata->npt == NULL) {
+        ERROR_MESSAGE(("JDWP: unable to initialize NPT library"));
+        return JNI_ERR;
+    }
+    gdata->npt->utf = (gdata->npt->utfInitialize)(NULL);
+    if (gdata->npt->utf == NULL) {
+        ERROR_MESSAGE(("JDWP: UTF function initialization failed"));
+        return JNI_ERR;
+    }
+
     /* Parse input options */
     if (!parseOptions(options)) {
         /* No message necessary, should have been printed out already */
diff --git a/jdk/src/share/back/error_messages.c b/jdk/src/share/back/error_messages.c
index 13a04b5..2ec5bbf 100644
--- a/jdk/src/share/back/error_messages.c
+++ b/jdk/src/share/back/error_messages.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -70,8 +70,13 @@
     len = (int)strlen((char*)utf8buf);
 
     /* Convert to platform encoding (ignore errors, dangerous area) */
-    (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
-           utf8buf, len, pbuf, MAX_MESSAGE_LEN);
+    if (gdata->npt != NULL) {
+        (void)(gdata->npt->utf8ToPlatform)(gdata->npt->utf,
+               utf8buf, len, pbuf, MAX_MESSAGE_LEN);
+    } else {
+        /* May be called before NPT is initialized so don't fault */
+        strncpy(pbuf, (char*)utf8buf, len);
+    }
     (void)fprintf(fp, "%s%s%s", prefix, pbuf, suffix);
 }
 
diff --git a/jdk/src/share/back/transport.c b/jdk/src/share/back/transport.c
index b315494..40608b3 100644
--- a/jdk/src/share/back/transport.c
+++ b/jdk/src/share/back/transport.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -144,7 +144,9 @@
     /* First, look in sun.boot.library.path. This should find the standard
      *  dt_socket and dt_shmem transport libraries, or any library
      *  that was delivered with the J2SE.
-     *  Note: Java property sun.boot.library.path contains a single directory.
+     *  Note: Since 6819213 fixed, Java property sun.boot.library.path can
+     *  contain multiple paths. Dll_dir is the first entry and
+     *  -Dsun.boot.library.path entries are appended.
      */
     libdir = gdata->property_sun_boot_library_path;
     if (libdir == NULL) {
diff --git a/jdk/src/share/bin/java.c b/jdk/src/share/bin/java.c
index 07af739..b1c5d94 100644
--- a/jdk/src/share/bin/java.c
+++ b/jdk/src/share/bin/java.c
@@ -693,6 +693,13 @@
     char *def;
     const char *orig = s;
     static const char format[] = "-Djava.class.path=%s";
+    /*
+     * usually we should not get a null pointer, but there are cases where
+     * we might just get one, in which case we simply ignore it, and let the
+     * caller deal with it
+     */
+    if (s == NULL)
+        return;
     s = JLI_WildcardExpandClasspath(s);
     def = JLI_MemAlloc(sizeof(format)
                        - 2 /* strlen("%s") */
diff --git a/jdk/src/share/classes/com/sun/beans/TypeResolver.java b/jdk/src/share/classes/com/sun/beans/TypeResolver.java
index baba362..e4cb0f3 100644
--- a/jdk/src/share/classes/com/sun/beans/TypeResolver.java
+++ b/jdk/src/share/classes/com/sun/beans/TypeResolver.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -45,6 +45,9 @@
  * @author Sergey Malenkov
  */
 public final class TypeResolver {
+
+    private static final WeakCache<Type, Map<Type, Type>> CACHE = new WeakCache<>();
+
     /**
      * Replaces the given {@code type} in an inherited method
      * with the actual type it has in the given {@code inClass}.
@@ -149,12 +152,55 @@
      * @param formal  the type where occurrences of the variables
      *                in {@code actual} will be replaced by the corresponding bound values
      * @return a resolved type
-     *
-     * @see #TypeResolver(Type)
-     * @see #resolve(Type)
      */
     public static Type resolve(Type actual, Type formal) {
-        return getTypeResolver(actual).resolve(formal);
+        if (formal instanceof Class) {
+            return formal;
+        }
+        if (formal instanceof GenericArrayType) {
+            Type comp = ((GenericArrayType) formal).getGenericComponentType();
+            comp = resolve(actual, comp);
+            return (comp instanceof Class)
+                    ? Array.newInstance((Class<?>) comp, 0).getClass()
+                    : GenericArrayTypeImpl.make(comp);
+        }
+        if (formal instanceof ParameterizedType) {
+            ParameterizedType fpt = (ParameterizedType) formal;
+            Type[] actuals = resolve(actual, fpt.getActualTypeArguments());
+            return ParameterizedTypeImpl.make(
+                    (Class<?>) fpt.getRawType(), actuals, fpt.getOwnerType());
+        }
+        if (formal instanceof WildcardType) {
+            WildcardType fwt = (WildcardType) formal;
+            Type[] upper = resolve(actual, fwt.getUpperBounds());
+            Type[] lower = resolve(actual, fwt.getLowerBounds());
+            return new WildcardTypeImpl(upper, lower);
+        }
+        if (formal instanceof TypeVariable) {
+            Map<Type, Type> map;
+            synchronized (CACHE) {
+                map = CACHE.get(actual);
+                if (map == null) {
+                    map = new HashMap<>();
+                    prepare(map, actual);
+                    CACHE.put(actual, map);
+                }
+            }
+            Type result = map.get(formal);
+            if (result == null || result.equals(formal)) {
+                return formal;
+            }
+            result = fixGenericArray(result);
+            // A variable can be bound to another variable that is itself bound
+            // to something.  For example, given:
+            // class Super<T> {...}
+            // class Mid<X> extends Super<T> {...}
+            // class Sub extends Mid<String>
+            // the variable T is bound to X, which is in turn bound to String.
+            // So if we have to resolve T, we need the tail recursion here.
+            return resolve(actual, result);
+        }
+        throw new IllegalArgumentException("Bad Type kind: " + formal.getClass());
     }
 
     /**
@@ -164,12 +210,14 @@
      * @param actual   the type that supplies bindings for type variables
      * @param formals  the array of types to resolve
      * @return an array of resolved types
-     *
-     * @see #TypeResolver(Type)
-     * @see #resolve(Type[])
      */
     public static Type[] resolve(Type actual, Type[] formals) {
-        return getTypeResolver(actual).resolve(formals);
+        int length = formals.length;
+        Type[] actuals = new Type[length];
+        for (int i = 0; i < length; i++) {
+            actuals[i] = resolve(actual, formals[i]);
+        }
+        return actuals;
     }
 
     /**
@@ -228,32 +276,6 @@
         return classes;
     }
 
-    public static TypeResolver getTypeResolver(Type type) {
-        synchronized (CACHE) {
-            TypeResolver resolver = CACHE.get(type);
-            if (resolver == null) {
-                resolver = new TypeResolver(type);
-                CACHE.put(type, resolver);
-            }
-            return resolver;
-        }
-    }
-
-    private static final WeakCache<Type, TypeResolver> CACHE = new WeakCache<>();
-
-    private final Map<TypeVariable<?>, Type> map = new HashMap<>();
-
-    /**
-     * Constructs the type resolver for the given actual type.
-     *
-     * @param actual  the type that supplies bindings for type variables
-     *
-     * @see #prepare(Type)
-     */
-    private TypeResolver(Type actual) {
-        prepare(actual);
-    }
-
     /**
      * Fills the map from type parameters
      * to types as seen by the given {@code type}.
@@ -265,9 +287,10 @@
      * to a {@link ParameterizedType ParameterizedType} with no parameters,
      * or it represents the erasure of a {@link ParameterizedType ParameterizedType}.
      *
+     * @param map   the mappings of all type variables
      * @param type  the next type in the hierarchy
      */
-    private void prepare(Type type) {
+    private static void prepare(Map<Type, Type> map, Type type) {
         Class<?> raw = (Class<?>)((type instanceof Class<?>)
                 ? type
                 : ((ParameterizedType)type).getRawType());
@@ -280,91 +303,25 @@
 
         assert formals.length == actuals.length;
         for (int i = 0; i < formals.length; i++) {
-            this.map.put(formals[i], actuals[i]);
+            map.put(formals[i], actuals[i]);
         }
         Type gSuperclass = raw.getGenericSuperclass();
         if (gSuperclass != null) {
-            prepare(gSuperclass);
+            prepare(map, gSuperclass);
         }
         for (Type gInterface : raw.getGenericInterfaces()) {
-            prepare(gInterface);
+            prepare(map, gInterface);
         }
         // If type is the raw version of a parameterized class, we type-erase
         // all of its type variables, including inherited ones.
         if (type instanceof Class<?> && formals.length > 0) {
-            for (Map.Entry<TypeVariable<?>, Type> entry : this.map.entrySet()) {
+            for (Map.Entry<Type, Type> entry : map.entrySet()) {
                 entry.setValue(erase(entry.getValue()));
             }
         }
     }
 
     /**
-     * Replaces the given {@code formal} type
-     * with the type it stand for in this type resolver.
-     *
-     * @param formal  the array of types to resolve
-     * @return a resolved type
-     */
-    private Type resolve(Type formal) {
-        if (formal instanceof Class) {
-            return formal;
-        }
-        if (formal instanceof GenericArrayType) {
-            Type comp = ((GenericArrayType)formal).getGenericComponentType();
-            comp = resolve(comp);
-            return (comp instanceof Class)
-                    ? Array.newInstance((Class<?>)comp, 0).getClass()
-                    : GenericArrayTypeImpl.make(comp);
-        }
-        if (formal instanceof ParameterizedType) {
-            ParameterizedType fpt = (ParameterizedType)formal;
-            Type[] actuals = resolve(fpt.getActualTypeArguments());
-            return ParameterizedTypeImpl.make(
-                    (Class<?>)fpt.getRawType(), actuals, fpt.getOwnerType());
-        }
-        if (formal instanceof WildcardType) {
-            WildcardType fwt = (WildcardType)formal;
-            Type[] upper = resolve(fwt.getUpperBounds());
-            Type[] lower = resolve(fwt.getLowerBounds());
-            return new WildcardTypeImpl(upper, lower);
-        }
-        if (!(formal instanceof TypeVariable)) {
-            throw new IllegalArgumentException("Bad Type kind: " + formal.getClass());
-        }
-        Type actual = this.map.get((TypeVariable) formal);
-        if (actual == null || actual.equals(formal)) {
-            return formal;
-        }
-        actual = fixGenericArray(actual);
-        return resolve(actual);
-        // A variable can be bound to another variable that is itself bound
-        // to something.  For example, given:
-        // class Super<T> {...}
-        // class Mid<X> extends Super<T> {...}
-        // class Sub extends Mid<String>
-        // the variable T is bound to X, which is in turn bound to String.
-        // So if we have to resolve T, we need the tail recursion here.
-    }
-
-    /**
-     * Replaces all formal types in the given array
-     * with the types they stand for in this type resolver.
-     *
-     * @param formals  the array of types to resolve
-     * @return an array of resolved types
-     *
-     * @see #resolve(Type)
-     */
-    private Type[] resolve(Type[] formals) {
-        int length = formals.length;
-        Type[] actuals = new Type[length];
-        for (int i = 0; i < length; i++) {
-            actuals[i] = resolve(formals[i]);
-        }
-        return actuals;
-    }
-
-    /**
      * Replaces a {@link GenericArrayType GenericArrayType}
      * with plain array class where it is possible.
      * Bug <a href="http://bugs.sun.com/view_bug.do?bug_id=5041784">5041784</a>
diff --git a/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java
index 618eb2c..fa7cc56 100644
--- a/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java
+++ b/jdk/src/share/classes/com/sun/beans/finder/MethodFinder.java
@@ -166,8 +166,10 @@
                             return findAccessibleMethod(m);
                         }
                         Type[] gpts = m.getGenericParameterTypes();
-                        if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) {
-                            return findAccessibleMethod(m);
+                        if (params.length == gpts.length) {
+                            if (Arrays.equals(params, TypeResolver.erase(TypeResolver.resolve(pt, gpts)))) {
+                                return findAccessibleMethod(m);
+                            }
                         }
                     }
                 }
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java
index 57a8169..4a1f429 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java
@@ -926,9 +926,20 @@
                                      int x, int y, int w, int h) {
         // Text is odd in that it uses the TEXT_BACKGROUND vs BACKGROUND.
         JComponent c = context.getComponent();
+        Container container = c.getParent();
+        Container containerParent = null;
         GTKStyle style = (GTKStyle)context.getStyle();
         Region id = context.getRegion();
         int state = context.getComponentState();
+
+        if (c instanceof ListCellRenderer && container != null) {
+            containerParent = container.getParent();
+            if (containerParent instanceof JComboBox
+                    && containerParent.hasFocus()) {
+                state |= SynthConstants.FOCUSED;
+            }
+        }
+
         synchronized (UNIXToolkit.GTK_LOCK) {
             if (ENGINE.paintCachedImage(g, x, y, w, h, id, state)) {
                 return;
@@ -938,9 +949,10 @@
             int focusSize = 0;
             boolean interiorFocus = style.getClassSpecificBoolValue(
                     context, "interior-focus", true);
+
+            focusSize = style.getClassSpecificIntValue(context,
+                    "focus-line-width",1);
             if (!interiorFocus && (state & SynthConstants.FOCUSED) != 0) {
-                focusSize = style.getClassSpecificIntValue(context,
-                        "focus-line-width",1);
                 x += focusSize;
                 y += focusSize;
                 w -= 2 * focusSize;
@@ -961,11 +973,25 @@
                                 h - (2 * yThickness),
                                 ColorType.TEXT_BACKGROUND);
 
-            if (focusSize > 0) {
-                x -= focusSize;
-                y -= focusSize;
-                w += 2 * focusSize;
-                h += 2 * focusSize;
+            if (focusSize > 0 && (state & SynthConstants.FOCUSED) != 0) {
+                if (!interiorFocus) {
+                    x -=  focusSize;
+                    y -=  focusSize;
+                    w +=  2 * focusSize;
+                    h +=  2 * focusSize;
+                } else {
+                    if (containerParent instanceof JComboBox) {
+                        x += (focusSize + 2);
+                        y += (focusSize + 1);
+                        w -= (2 * focusSize + 1);
+                        h -= (2 * focusSize + 2);
+                    } else {
+                        x += focusSize;
+                        y += focusSize;
+                        w -= 2 * focusSize;
+                        h -= 2 * focusSize;
+                    }
+                }
                 ENGINE.paintFocus(g, context, id, gtkState,
                         "entry", x, y, w, h);
             }
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java
index 97df238..9f2814e 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java
@@ -529,21 +529,25 @@
         Locale l = fc.getLocale();
 
         enterFolderNameLabelText = UIManager.getString("FileChooser.enterFolderNameLabelText",l);
-        enterFolderNameLabelMnemonic = UIManager.getInt("FileChooser.enterFolderNameLabelMnemonic");
+        enterFolderNameLabelMnemonic = getMnemonic("FileChooser.enterFolderNameLabelMnemonic", l);
         enterFileNameLabelText = UIManager.getString("FileChooser.enterFileNameLabelText",l);
-        enterFileNameLabelMnemonic = UIManager.getInt("FileChooser.enterFileNameLabelMnemonic");
+        enterFileNameLabelMnemonic = getMnemonic("FileChooser.enterFileNameLabelMnemonic", l);
 
         filesLabelText = UIManager.getString("FileChooser.filesLabelText",l);
-        filesLabelMnemonic = UIManager.getInt("FileChooser.filesLabelMnemonic");
+        filesLabelMnemonic = getMnemonic("FileChooser.filesLabelMnemonic", l);
 
         foldersLabelText = UIManager.getString("FileChooser.foldersLabelText",l);
-        foldersLabelMnemonic = UIManager.getInt("FileChooser.foldersLabelMnemonic");
+        foldersLabelMnemonic = getMnemonic("FileChooser.foldersLabelMnemonic", l);
 
         pathLabelText = UIManager.getString("FileChooser.pathLabelText",l);
-        pathLabelMnemonic = UIManager.getInt("FileChooser.pathLabelMnemonic");
+        pathLabelMnemonic = getMnemonic("FileChooser.pathLabelMnemonic", l);
 
         filterLabelText = UIManager.getString("FileChooser.filterLabelText",l);
-        filterLabelMnemonic = UIManager.getInt("FileChooser.filterLabelMnemonic");
+        filterLabelMnemonic = getMnemonic("FileChooser.filterLabelMnemonic", l);
+    }
+
+    private Integer getMnemonic(String key, Locale l) {
+        return SwingUtilities2.getUIDefaultsInt(key, l);
     }
 
     protected void installIcons(JFileChooser fc) {
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java
index 60ab1ac..923cd9d 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/MotifLookAndFeel.java
@@ -1215,11 +1215,6 @@
             "EditorPane.focusInputMap", multilineInputMap,
 
 
-            "FileChooser.pathLabelMnemonic", new Integer(KeyEvent.VK_P), // 'p'
-            "FileChooser.filterLabelMnemonic", new Integer (KeyEvent.VK_R), // 'r'
-            "FileChooser.foldersLabelMnemonic", new Integer (KeyEvent.VK_L), // 'l'
-            "FileChooser.filesLabelMnemonic", new Integer (KeyEvent.VK_I), // 'i'
-            "FileChooser.enterFileNameLabelMnemonic", new Integer (KeyEvent.VK_N), // 'n'
             "FileChooser.ancestorInputMap",
                new UIDefaults.LazyInputMap(new Object[] {
                      "ESCAPE", "cancelSelection"
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif.properties
index 9e22116..fed806c 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=Open
 FileChooser.updateButton.textAndMnemonic=Update
 FileChooser.helpButton.textAndMnemonic=Help
-FileChooser.pathLabel.textAndMnemonic=Enter path or folder name:
-FileChooser.filterLabel.textAndMnemonic=Filter
-FileChooser.foldersLabel.textAndMnemonic=Folders
-FileChooser.filesLabel.textAndMnemonic=Files
-FileChooser.enterFileNameLabel.textAndMnemonic=Enter file name:
+FileChooser.pathLabel.textAndMnemonic=Enter &path or folder name:
+FileChooser.filterLabel.textAndMnemonic=Filte&r
+FileChooser.foldersLabel.textAndMnemonic=Fo&lders
+FileChooser.filesLabel.textAndMnemonic=F&iles
+FileChooser.enterFileNameLabel.textAndMnemonic=E&nter file name:
 FileChooser.enterFolderNameLabel.textAndMnemonic=Enter folder name:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=Abort file chooser dialog.
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties
index 79f0f65..1d2cc25 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_de.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=\u00D6ffnen
 FileChooser.updateButton.textAndMnemonic=Aktualisieren
 FileChooser.helpButton.textAndMnemonic=Hilfe
-FileChooser.pathLabel.textAndMnemonic=Pfad- oder Ordnernamen eingeben:
-FileChooser.filterLabel.textAndMnemonic=Filter
-FileChooser.foldersLabel.textAndMnemonic=Ordner
-FileChooser.filesLabel.textAndMnemonic=Dateien
-FileChooser.enterFileNameLabel.textAndMnemonic=Dateinamen eingeben:
+FileChooser.pathLabel.textAndMnemonic=&Pfad- oder Ordnernamen eingeben:
+FileChooser.filterLabel.textAndMnemonic=Filte&r
+FileChooser.foldersLabel.textAndMnemonic=Ordner(&L)
+FileChooser.filesLabel.textAndMnemonic=Date&ien
+FileChooser.enterFileNameLabel.textAndMnemonic=Datei&namen eingeben:
 FileChooser.enterFolderNameLabel.textAndMnemonic=Ordnernamen eingeben:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=Dialogfeld f\u00FCr Dateiauswahl schlie\u00DFen.
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_es.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_es.properties
index 3e10e16..2add8f2 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_es.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_es.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=Abrir
 FileChooser.updateButton.textAndMnemonic=Actualizar
 FileChooser.helpButton.textAndMnemonic=Ayuda
-FileChooser.pathLabel.textAndMnemonic=Introducir nombre de la ruta de acceso o carpeta:
-FileChooser.filterLabel.textAndMnemonic=Filtro
-FileChooser.foldersLabel.textAndMnemonic=Carpetas
-FileChooser.filesLabel.textAndMnemonic=Archivos
-FileChooser.enterFileNameLabel.textAndMnemonic=Introducir nombre de archivo:
+FileChooser.pathLabel.textAndMnemonic=Introducir nombre de la ruta de acceso o car&peta:
+FileChooser.filterLabel.textAndMnemonic=Filt&ro
+FileChooser.foldersLabel.textAndMnemonic=Carpetas(&L)
+FileChooser.filesLabel.textAndMnemonic=Arch&ivos
+FileChooser.enterFileNameLabel.textAndMnemonic=I&ntroducir nombre de archivo:
 FileChooser.enterFolderNameLabel.textAndMnemonic=Introducir nombre de carpeta:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=Abortar cuadro de di\u00E1logo del selector de archivos.
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_fr.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_fr.properties
index 6b998d6..8fd4490 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_fr.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_fr.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=Ouvrir
 FileChooser.updateButton.textAndMnemonic=Mettre \u00E0 jour
 FileChooser.helpButton.textAndMnemonic=Aide
-FileChooser.pathLabel.textAndMnemonic=Entrez le chemin ou le nom du dossier :
-FileChooser.filterLabel.textAndMnemonic=Filtre
-FileChooser.foldersLabel.textAndMnemonic=Dossiers
-FileChooser.filesLabel.textAndMnemonic=Fichiers
-FileChooser.enterFileNameLabel.textAndMnemonic=Entrez le nom du fichier :
+FileChooser.pathLabel.textAndMnemonic=Entrez le chemin ou le nom du dossier (&P):
+FileChooser.filterLabel.textAndMnemonic=Filt&re
+FileChooser.foldersLabel.textAndMnemonic=Dossiers(&L)
+FileChooser.filesLabel.textAndMnemonic=Fich&iers
+FileChooser.enterFileNameLabel.textAndMnemonic=E&ntrez le nom du fichier :
 FileChooser.enterFolderNameLabel.textAndMnemonic=Entrez le nom du dossier :
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=Ferme la bo\u00EEte de dialogue du s\u00E9lecteur de fichiers.
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_it.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_it.properties
index 8afe32e..352a9d7 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_it.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_it.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=Apri
 FileChooser.updateButton.textAndMnemonic=Aggiorna
 FileChooser.helpButton.textAndMnemonic=?
-FileChooser.pathLabel.textAndMnemonic=Percorso o nome cartella:
-FileChooser.filterLabel.textAndMnemonic=Filtro
-FileChooser.foldersLabel.textAndMnemonic=Cartelle
-FileChooser.filesLabel.textAndMnemonic=File
-FileChooser.enterFileNameLabel.textAndMnemonic=Nome file:
+FileChooser.pathLabel.textAndMnemonic=&Percorso o nome cartella:
+FileChooser.filterLabel.textAndMnemonic=Filt&ro
+FileChooser.foldersLabel.textAndMnemonic=Carte&lle
+FileChooser.filesLabel.textAndMnemonic=F&ile
+FileChooser.enterFileNameLabel.textAndMnemonic=&Nome file:
 FileChooser.enterFolderNameLabel.textAndMnemonic=Nome cartella:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=Chiude la finestra di dialogo di selezione file.
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ja.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ja.properties
index 1875d2e..9b28788 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ja.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ja.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=\u958B\u304F
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0
 FileChooser.helpButton.textAndMnemonic=\u30D8\u30EB\u30D7
-FileChooser.pathLabel.textAndMnemonic=\u30D1\u30B9\u307E\u305F\u306F\u30D5\u30A9\u30EB\u30C0\u540D\u3092\u5165\u529B:
-FileChooser.filterLabel.textAndMnemonic=\u30D5\u30A3\u30EB\u30BF
-FileChooser.foldersLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0
-FileChooser.filesLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB
-FileChooser.enterFileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u5165\u529B:
+FileChooser.pathLabel.textAndMnemonic=\u30D1\u30B9\u307E\u305F\u306F\u30D5\u30A9\u30EB\u30C0\u540D\u3092\u5165\u529B(&P):
+FileChooser.filterLabel.textAndMnemonic=\u30D5\u30A3\u30EB\u30BF(&R)
+FileChooser.foldersLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0(&L)
+FileChooser.filesLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB(&I)
+FileChooser.enterFileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D\u3092\u5165\u529B(&N):
 FileChooser.enterFolderNameLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0\u540D\u3092\u5165\u529B:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u30FB\u30C1\u30E5\u30FC\u30B6\u30FB\u30C0\u30A4\u30A2\u30ED\u30B0\u3092\u7D42\u4E86\u3057\u307E\u3059\u3002
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties
index 31ce043..f7e2625 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_ko.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=\uC5F4\uAE30
 FileChooser.updateButton.textAndMnemonic=\uAC31\uC2E0
 FileChooser.helpButton.textAndMnemonic=\uB3C4\uC6C0\uB9D0
-FileChooser.pathLabel.textAndMnemonic=\uACBD\uB85C \uB610\uB294 \uD3F4\uB354 \uC774\uB984 \uC785\uB825:
-FileChooser.filterLabel.textAndMnemonic=\uD544\uD130
-FileChooser.foldersLabel.textAndMnemonic=\uD3F4\uB354
-FileChooser.filesLabel.textAndMnemonic=\uD30C\uC77C
-FileChooser.enterFileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984 \uC785\uB825:
+FileChooser.pathLabel.textAndMnemonic=\uACBD\uB85C \uB610\uB294 \uD3F4\uB354 \uC774\uB984 \uC785\uB825(&P):
+FileChooser.filterLabel.textAndMnemonic=\uD544\uD130(&R)
+FileChooser.foldersLabel.textAndMnemonic=\uD3F4\uB354(&L)
+FileChooser.filesLabel.textAndMnemonic=\uD30C\uC77C(&I)
+FileChooser.enterFileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984 \uC785\uB825(&N):
 FileChooser.enterFolderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984 \uC785\uB825:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=\uD30C\uC77C \uC120\uD0DD\uAE30 \uB300\uD654\uC0C1\uC790\uB97C \uC911\uB2E8\uD569\uB2C8\uB2E4.
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_pt_BR.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_pt_BR.properties
index 1edb05a..a1af539 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_pt_BR.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_pt_BR.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=Abrir
 FileChooser.updateButton.textAndMnemonic=Atualizar
 FileChooser.helpButton.textAndMnemonic=Ajuda
-FileChooser.pathLabel.textAndMnemonic=Informar caminho ou nome da pasta:
-FileChooser.filterLabel.textAndMnemonic=Filtro
-FileChooser.foldersLabel.textAndMnemonic=Pastas
-FileChooser.filesLabel.textAndMnemonic=Arquivos
-FileChooser.enterFileNameLabel.textAndMnemonic=Informar nome do arquivo:
+FileChooser.pathLabel.textAndMnemonic=Informar caminho ou nome da &pasta:
+FileChooser.filterLabel.textAndMnemonic=Filt&ro
+FileChooser.foldersLabel.textAndMnemonic=Pastas(&L)
+FileChooser.filesLabel.textAndMnemonic=Arqu&ivos
+FileChooser.enterFileNameLabel.textAndMnemonic=I&nformar nome do arquivo:
 FileChooser.enterFolderNameLabel.textAndMnemonic=Informar nome da pasta:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=Abortar caixa de di\u00E1logo do seletor de arquivos.
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_sv.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_sv.properties
index 7f806f9..3592f4d 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_sv.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_sv.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=\u00D6ppna
 FileChooser.updateButton.textAndMnemonic=Uppdatera
 FileChooser.helpButton.textAndMnemonic=Hj\u00E4lp
-FileChooser.pathLabel.textAndMnemonic=Ange s\u00F6kv\u00E4g eller mappnamn:
-FileChooser.filterLabel.textAndMnemonic=Filter
-FileChooser.foldersLabel.textAndMnemonic=Mappar
-FileChooser.filesLabel.textAndMnemonic=Filer
-FileChooser.enterFileNameLabel.textAndMnemonic=Ange filnamn:
+FileChooser.pathLabel.textAndMnemonic=Ange s\u00F6kv\u00E4g eller mappnamn(&P):
+FileChooser.filterLabel.textAndMnemonic=Filte&r
+FileChooser.foldersLabel.textAndMnemonic=Mappar(&L)
+FileChooser.filesLabel.textAndMnemonic=F&iler
+FileChooser.enterFileNameLabel.textAndMnemonic=A&nge filnamn:
 FileChooser.enterFolderNameLabel.textAndMnemonic=Ange ett mappnamn:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=Avbryt dialogrutan Filv\u00E4ljare.
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_zh_CN.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_zh_CN.properties
index b57fce4..c2c1ecd 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_zh_CN.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_zh_CN.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=\u6253\u5F00
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0
 FileChooser.helpButton.textAndMnemonic=\u5E2E\u52A9
-FileChooser.pathLabel.textAndMnemonic=\u952E\u5165\u8DEF\u5F84\u6216\u6587\u4EF6\u5939\u540D: 
-FileChooser.filterLabel.textAndMnemonic=\u7B5B\u9009\u5668
-FileChooser.foldersLabel.textAndMnemonic=\u6587\u4EF6\u5939
-FileChooser.filesLabel.textAndMnemonic=\u6587\u4EF6
-FileChooser.enterFileNameLabel.textAndMnemonic=\u952E\u5165\u6587\u4EF6\u540D: 
+FileChooser.pathLabel.textAndMnemonic=\u952E\u5165\u8DEF\u5F84\u6216\u6587\u4EF6\u5939\u540D: (&P)
+FileChooser.filterLabel.textAndMnemonic=\u7B5B\u9009\u5668(&R)
+FileChooser.foldersLabel.textAndMnemonic=\u6587\u4EF6\u5939(&L)
+FileChooser.filesLabel.textAndMnemonic=\u6587\u4EF6(&I)
+FileChooser.enterFileNameLabel.textAndMnemonic=\u952E\u5165\u6587\u4EF6\u540D: (&N)
 FileChooser.enterFolderNameLabel.textAndMnemonic=\u8F93\u5165\u6587\u4EF6\u5939\u540D:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=\u4E2D\u6B62\u6587\u4EF6\u9009\u62E9\u5668\u5BF9\u8BDD\u6846\u3002
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_zh_TW.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_zh_TW.properties
index 8387184..6e77bba 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_zh_TW.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/motif/resources/motif_zh_TW.properties
@@ -26,11 +26,11 @@
 FileChooser.openDialogTitle.textAndMnemonic=\u958B\u555F
 FileChooser.updateButton.textAndMnemonic=\u66F4\u65B0
 FileChooser.helpButton.textAndMnemonic=\u8AAA\u660E
-FileChooser.pathLabel.textAndMnemonic=\u8F38\u5165\u8DEF\u5F91\u6216\u8CC7\u6599\u593E\u540D\u7A31:
-FileChooser.filterLabel.textAndMnemonic=\u7BE9\u9078
-FileChooser.foldersLabel.textAndMnemonic=\u8CC7\u6599\u593E
-FileChooser.filesLabel.textAndMnemonic=\u6A94\u6848
-FileChooser.enterFileNameLabel.textAndMnemonic=\u8F38\u5165\u6A94\u6848\u540D\u7A31:
+FileChooser.pathLabel.textAndMnemonic=\u8F38\u5165\u8DEF\u5F91\u6216\u8CC7\u6599\u593E\u540D\u7A31(&P):
+FileChooser.filterLabel.textAndMnemonic=\u7BE9\u9078(&R)
+FileChooser.foldersLabel.textAndMnemonic=\u8CC7\u6599\u593E(&L)
+FileChooser.filesLabel.textAndMnemonic=\u6A94\u6848(&I)
+FileChooser.enterFileNameLabel.textAndMnemonic=\u8F38\u5165\u6A94\u6848\u540D\u7A31(&N):
 FileChooser.enterFolderNameLabel.textAndMnemonic=\u8F38\u5165\u8CC7\u6599\u593E\u540D\u7A31:
 
 FileChooser.cancelButtonToolTip.textAndMnemonic=\u4E2D\u6B62\u6A94\u6848\u9078\u64C7\u5668\u5C0D\u8A71\u65B9\u584A\u3002
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java
index 4b61522..2c7e16e 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsFileChooserUI.java
@@ -528,16 +528,16 @@
 
         Locale l = fc.getLocale();
 
-        lookInLabelMnemonic = UIManager.getInt("FileChooser.lookInLabelMnemonic");
+        lookInLabelMnemonic = getMnemonic("FileChooser.lookInLabelMnemonic", l);
         lookInLabelText = UIManager.getString("FileChooser.lookInLabelText",l);
         saveInLabelText = UIManager.getString("FileChooser.saveInLabelText",l);
 
-        fileNameLabelMnemonic = UIManager.getInt("FileChooser.fileNameLabelMnemonic");
+        fileNameLabelMnemonic = getMnemonic("FileChooser.fileNameLabelMnemonic", l);
         fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText",l);
-        folderNameLabelMnemonic = UIManager.getInt("FileChooser.folderNameLabelMnemonic");
+        folderNameLabelMnemonic = getMnemonic("FileChooser.folderNameLabelMnemonic", l);
         folderNameLabelText = UIManager.getString("FileChooser.folderNameLabelText",l);
 
-        filesOfTypeLabelMnemonic = UIManager.getInt("FileChooser.filesOfTypeLabelMnemonic");
+        filesOfTypeLabelMnemonic = getMnemonic("FileChooser.filesOfTypeLabelMnemonic", l);
         filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText",l);
 
         upFolderToolTipText =  UIManager.getString("FileChooser.upFolderToolTipText",l);
@@ -550,6 +550,10 @@
         viewMenuButtonAccessibleName = UIManager.getString("FileChooser.viewMenuButtonAccessibleName",l);
     }
 
+    private Integer getMnemonic(String key, Locale l) {
+        return SwingUtilities2.getUIDefaultsInt(key, l);
+    }
+
     protected void installListeners(JFileChooser fc) {
         super.installListeners(fc);
         ActionMap actionMap = getActionMap();
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java
index 3648a76..48961a0 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java
@@ -523,6 +523,7 @@
         Object ScrollbarBackgroundColor = new DesktopProperty(
                                                        "win.scrollbar.backgroundColor",
                                                         table.get("scrollbar"));
+        Object buttonFocusColor = new FocusColorProperty();
 
         Object TextBackground         = new XPColorValue(Part.EP_EDIT, null, Prop.FILLCOLOR,
                                                          WindowBackgroundColor);
@@ -629,7 +630,7 @@
             "Button.highlight", ControlHighlightColor,
             "Button.disabledForeground", InactiveTextColor,
             "Button.disabledShadow", ControlHighlightColor,
-            "Button.focus", black,
+            "Button.focus", buttonFocusColor,
             "Button.dashedRectGapX", new XPValue(Integer.valueOf(3), Integer.valueOf(5)),
             "Button.dashedRectGapY", new XPValue(Integer.valueOf(3), Integer.valueOf(4)),
             "Button.dashedRectGapWidth", new XPValue(Integer.valueOf(6), Integer.valueOf(10)),
@@ -655,7 +656,7 @@
             "CheckBox.darkShadow", ControlDarkShadowColor,
             "CheckBox.light", ControlLightColor,
             "CheckBox.highlight", ControlHighlightColor,
-            "CheckBox.focus", black,
+            "CheckBox.focus", buttonFocusColor,
             "CheckBox.focusInputMap",
                new UIDefaults.LazyInputMap(new Object[] {
                             "SPACE", "pressed",
@@ -773,9 +774,6 @@
                                                                "icons/NewFolder.gif"),
             "FileChooser.useSystemExtensionHiding", Boolean.TRUE,
 
-            "FileChooser.lookInLabelMnemonic", Integer.valueOf(KeyEvent.VK_I),
-            "FileChooser.fileNameLabelMnemonic", Integer.valueOf(KeyEvent.VK_N),
-            "FileChooser.filesOfTypeLabelMnemonic", Integer.valueOf(KeyEvent.VK_T),
             "FileChooser.usesSingleFilePane", Boolean.TRUE,
             "FileChooser.noPlacesBar", new DesktopProperty("win.comdlg.noPlacesBar",
                                                            Boolean.FALSE),
@@ -1013,7 +1011,7 @@
             "RadioButton.darkShadow", ControlDarkShadowColor,
             "RadioButton.light", ControlLightColor,
             "RadioButton.highlight", ControlHighlightColor,
-            "RadioButton.focus", black,
+            "RadioButton.focus", buttonFocusColor,
             "RadioButton.focusInputMap",
                new UIDefaults.LazyInputMap(new Object[] {
                           "SPACE", "pressed",
@@ -2620,4 +2618,19 @@
         }
     }
 
+    private static class FocusColorProperty extends DesktopProperty {
+        public FocusColorProperty () {
+            // Fallback value is never used bacause of the configureValue method doesn't return null
+            super("win.3d.backgroundColor", Color.BLACK);
+        }
+
+        @Override
+        protected Object configureValue(Object value) {
+            if (! ((Boolean)Toolkit.getDefaultToolkit().getDesktopProperty("win.highContrast.on")).booleanValue()){
+                return Color.BLACK;
+            }
+            return Color.BLACK.equals(value) ? Color.WHITE : Color.BLACK;
+        }
+    }
+
 }
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java
index 56214ac..81c97f4 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI.java
@@ -89,6 +89,11 @@
         }
     }
 
+    protected void uninstallDefaults(AbstractButton b) {
+        super.uninstallDefaults(b);
+        initialized = false;
+    }
+
     protected Color getFocusColor() {
         return focusColor;
     }
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows.properties
index 9ec285a..7f36db6 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Look in:
+FileChooser.lookInLabel.textAndMnemonic=Look &in:
 FileChooser.saveInLabel.textAndMnemonic=Save in:
-FileChooser.fileNameLabel.textAndMnemonic=File name:
-FileChooser.folderNameLabel.textAndMnemonic=Folder name:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Files of type:
+FileChooser.fileNameLabel.textAndMnemonic=File &name:
+FileChooser.folderNameLabel.textAndMnemonic=Folder &name:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Files of &type:
 FileChooser.upFolderToolTip.textAndMnemonic=Up One Level
 FileChooser.upFolderAccessibleName=Up
 FileChooser.homeFolderToolTip.textAndMnemonic=Home
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_de.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_de.properties
index dc882fb..0fb0499 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_de.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_de.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Suchen in:
+FileChooser.lookInLabel.textAndMnemonic=Suchen &in:
 FileChooser.saveInLabel.textAndMnemonic=Speichern in:
-FileChooser.fileNameLabel.textAndMnemonic=Dateiname:
-FileChooser.folderNameLabel.textAndMnemonic=Ordnername:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Dateityp:
+FileChooser.fileNameLabel.textAndMnemonic=Datei&name:
+FileChooser.folderNameLabel.textAndMnemonic=Ord&nername:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Da&teityp:
 FileChooser.upFolderToolTip.textAndMnemonic=Eine Ebene h\u00F6her
 FileChooser.upFolderAccessibleName=Nach oben
 FileChooser.homeFolderToolTip.textAndMnemonic=Home
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_es.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_es.properties
index 8e77118..4e68630 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_es.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_es.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Buscar en:
+FileChooser.lookInLabel.textAndMnemonic=Buscar en(&I):
 FileChooser.saveInLabel.textAndMnemonic=Guardar en:
-FileChooser.fileNameLabel.textAndMnemonic=Nombre de Archivo:
-FileChooser.folderNameLabel.textAndMnemonic=Nombre de la Carpeta:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Archivos de Tipo:
+FileChooser.fileNameLabel.textAndMnemonic=&Nombre de Archivo:
+FileChooser.folderNameLabel.textAndMnemonic=&Nombre de la Carpeta:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Archivos de &Tipo:
 FileChooser.upFolderToolTip.textAndMnemonic=Subir un Nivel
 FileChooser.upFolderAccessibleName=Arriba
 FileChooser.homeFolderToolTip.textAndMnemonic=Inicio
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_fr.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_fr.properties
index fe63481..b410f5f 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_fr.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_fr.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Rechercher dans :
+FileChooser.lookInLabel.textAndMnemonic=Rechercher dans (&I):
 FileChooser.saveInLabel.textAndMnemonic=Enregistrer dans :
-FileChooser.fileNameLabel.textAndMnemonic=Nom du fichier :
-FileChooser.folderNameLabel.textAndMnemonic=Nom du dossier :
-FileChooser.filesOfTypeLabel.textAndMnemonic=Fichiers de type :
+FileChooser.fileNameLabel.textAndMnemonic=&Nom du fichier :
+FileChooser.folderNameLabel.textAndMnemonic=&Nom du dossier :
+FileChooser.filesOfTypeLabel.textAndMnemonic=Fichiers de &type :
 FileChooser.upFolderToolTip.textAndMnemonic=Remonte d'un niveau.
 FileChooser.upFolderAccessibleName=Monter
 FileChooser.homeFolderToolTip.textAndMnemonic=R\u00E9pertoire d'origine
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_it.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_it.properties
index 4d5ca2d..dc9e9c0 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_it.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_it.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Cerca in:
+FileChooser.lookInLabel.textAndMnemonic=Cerca &in:
 FileChooser.saveInLabel.textAndMnemonic=Salva in:
-FileChooser.fileNameLabel.textAndMnemonic=Nome file:
-FileChooser.folderNameLabel.textAndMnemonic=Nome della cartella:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Tipo file:
+FileChooser.fileNameLabel.textAndMnemonic=&Nome file:
+FileChooser.folderNameLabel.textAndMnemonic=&Nome della cartella:
+FileChooser.filesOfTypeLabel.textAndMnemonic=&Tipo file:
 FileChooser.upFolderToolTip.textAndMnemonic=Cartella superiore
 FileChooser.upFolderAccessibleName=Superiore
 FileChooser.homeFolderToolTip.textAndMnemonic=Home
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ja.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ja.properties
index d3d5e6c..edeaac2 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ja.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ja.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u53C2\u7167:
+FileChooser.lookInLabel.textAndMnemonic=\u53C2\u7167(&I):
 FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58:
-FileChooser.fileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D:
-FileChooser.folderNameLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0\u540D:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u306E\u30BF\u30A4\u30D7:
+FileChooser.fileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0\u540D(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u306E\u30BF\u30A4\u30D7(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=1\u30EC\u30D9\u30EB\u4E0A\u3078
 FileChooser.upFolderAccessibleName=\u4E0A\u3078
 FileChooser.homeFolderToolTip.textAndMnemonic=\u30DB\u30FC\u30E0
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ko.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ko.properties
index 189555c..94a1054 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ko.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_ko.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\uAC80\uC0C9 \uC704\uCE58:
+FileChooser.lookInLabel.textAndMnemonic=\uAC80\uC0C9 \uC704\uCE58(&I):
 FileChooser.saveInLabel.textAndMnemonic=\uC800\uC7A5 \uC704\uCE58:
-FileChooser.fileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984:
-FileChooser.folderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\uD30C\uC77C \uC720\uD615:
+FileChooser.fileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\uD30C\uC77C \uC720\uD615(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=\uD55C \uB808\uBCA8 \uC704\uB85C
 FileChooser.upFolderAccessibleName=\uC704\uB85C
 FileChooser.homeFolderToolTip.textAndMnemonic=\uD648
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_pt_BR.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_pt_BR.properties
index 031bc93..44ecb60 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_pt_BR.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_pt_BR.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Consultar em:
+FileChooser.lookInLabel.textAndMnemonic=Consultar em(&I):
 FileChooser.saveInLabel.textAndMnemonic=Salvar em:
-FileChooser.fileNameLabel.textAndMnemonic=Nome do arquivo:
-FileChooser.folderNameLabel.textAndMnemonic=Nome da pasta:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Arquivos do tipo:
+FileChooser.fileNameLabel.textAndMnemonic=&Nome do arquivo:
+FileChooser.folderNameLabel.textAndMnemonic=&Nome da pasta:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Arquivos do &tipo:
 FileChooser.upFolderToolTip.textAndMnemonic=Um N\u00EDvel Acima
 FileChooser.upFolderAccessibleName=Acima
 FileChooser.homeFolderToolTip.textAndMnemonic=In\u00EDcio
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_sv.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_sv.properties
index 0e716a7..e44a096 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_sv.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_sv.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Leta i:
+FileChooser.lookInLabel.textAndMnemonic=Leta &i:
 FileChooser.saveInLabel.textAndMnemonic=Spara i:
-FileChooser.fileNameLabel.textAndMnemonic=Filnamn:
-FileChooser.folderNameLabel.textAndMnemonic=Mapp:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Filformat:
+FileChooser.fileNameLabel.textAndMnemonic=Fil&namn:
+FileChooser.folderNameLabel.textAndMnemonic=Mapp(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=Filforma&t:
 FileChooser.upFolderToolTip.textAndMnemonic=Upp en niv\u00E5
 FileChooser.upFolderAccessibleName=Upp
 FileChooser.homeFolderToolTip.textAndMnemonic=Hem
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_CN.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_CN.properties
index 953250b..3dfa753 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_CN.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_CN.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u67E5\u770B: 
+FileChooser.lookInLabel.textAndMnemonic=\u67E5\u770B: (&I)
 FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58: 
-FileChooser.fileNameLabel.textAndMnemonic=\u6587\u4EF6\u540D: 
-FileChooser.folderNameLabel.textAndMnemonic=\u6587\u4EF6\u5939\u540D: 
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u6587\u4EF6\u7C7B\u578B: 
+FileChooser.fileNameLabel.textAndMnemonic=\u6587\u4EF6\u540D: (&N)
+FileChooser.folderNameLabel.textAndMnemonic=\u6587\u4EF6\u5939\u540D: (&N)
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u6587\u4EF6\u7C7B\u578B: (&T)
 FileChooser.upFolderToolTip.textAndMnemonic=\u5411\u4E0A\u4E00\u7EA7
 FileChooser.upFolderAccessibleName=\u5411\u4E0A
 FileChooser.homeFolderToolTip.textAndMnemonic=\u4E3B\u76EE\u5F55
diff --git a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_TW.properties b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_TW.properties
index 730c917..099caad 100644
--- a/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_TW.properties
+++ b/jdk/src/share/classes/com/sun/java/swing/plaf/windows/resources/windows_zh_TW.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u67E5\u8A62:
+FileChooser.lookInLabel.textAndMnemonic=\u67E5\u8A62(&I):
 FileChooser.saveInLabel.textAndMnemonic=\u5132\u5B58\u65BC: 
-FileChooser.fileNameLabel.textAndMnemonic=\u6A94\u6848\u540D\u7A31:
-FileChooser.folderNameLabel.textAndMnemonic=\u8CC7\u6599\u593E\u540D\u7A31:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u6A94\u6848\u985E\u578B:
+FileChooser.fileNameLabel.textAndMnemonic=\u6A94\u6848\u540D\u7A31(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\u8CC7\u6599\u593E\u540D\u7A31(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u6A94\u6848\u985E\u578B(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=\u5F80\u4E0A\u4E00\u5C64
 FileChooser.upFolderAccessibleName=\u5F80\u4E0A
 FileChooser.homeFolderToolTip.textAndMnemonic=\u4E3B\u76EE\u9304
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java
index 4f3eec2..02d67c0 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/Connection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -157,7 +157,8 @@
     volatile IOException closureReason = null;
     volatile boolean useable = true;  // is Connection still useable
 
-    private int readTimeout;
+    int readTimeout;
+    int connectTimeout;
 
     // true means v3; false means v2
     // Called in LdapClient.authenticate() (which is synchronized)
@@ -187,6 +188,7 @@
         this.port = port;
         this.parent = parent;
         this.readTimeout = readTimeout;
+        this.connectTimeout = connectTimeout;
 
         if (trace != null) {
             traceFile = trace;
@@ -685,9 +687,11 @@
                         ldr = ldr.next;
                     }
                 }
-                parent.processConnectionClosure();
             }
         }
+        if (nparent) {
+            parent.processConnectionClosure();
+        }
     }
 
 
diff --git a/jdk/src/share/classes/com/sun/jndi/ldap/LdapClient.java b/jdk/src/share/classes/com/sun/jndi/ldap/LdapClient.java
index 41a3dfb..38b1d4d 100644
--- a/jdk/src/share/classes/com/sun/jndi/ldap/LdapClient.java
+++ b/jdk/src/share/classes/com/sun/jndi/ldap/LdapClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -149,149 +149,155 @@
         String authMechanism, Control[] ctls,  Hashtable env)
         throws NamingException {
 
-        authenticateCalled = true;
-
-        try {
-            ensureOpen();
-        } catch (IOException e) {
-            NamingException ne = new CommunicationException();
-            ne.setRootCause(e);
-            throw ne;
-        }
-
-        switch (version) {
-        case LDAP_VERSION3_VERSION2:
-        case LDAP_VERSION3:
-            isLdapv3 = true;
-            break;
-        case LDAP_VERSION2:
-            isLdapv3 = false;
-            break;
-        default:
-            throw new CommunicationException("Protocol version " + version +
-                " not supported");
-        }
-
+        int readTimeout = conn.readTimeout;
+        conn.readTimeout = conn.connectTimeout;
         LdapResult res = null;
 
-        if (authMechanism.equalsIgnoreCase("none") ||
-            authMechanism.equalsIgnoreCase("anonymous")) {
+        try {
+            authenticateCalled = true;
 
-            // Perform LDAP bind if we are reauthenticating, using LDAPv2,
-            // supporting failover to LDAPv2, or controls have been supplied.
-            if (!initial ||
-                (version == LDAP_VERSION2) ||
-                (version == LDAP_VERSION3_VERSION2) ||
-                ((ctls != null) && (ctls.length > 0))) {
+            try {
+                ensureOpen();
+            } catch (IOException e) {
+                NamingException ne = new CommunicationException();
+                ne.setRootCause(e);
+                throw ne;
+            }
+
+            switch (version) {
+            case LDAP_VERSION3_VERSION2:
+            case LDAP_VERSION3:
+                isLdapv3 = true;
+                break;
+            case LDAP_VERSION2:
+                isLdapv3 = false;
+                break;
+            default:
+                throw new CommunicationException("Protocol version " + version +
+                    " not supported");
+            }
+
+            if (authMechanism.equalsIgnoreCase("none") ||
+                authMechanism.equalsIgnoreCase("anonymous")) {
+
+                // Perform LDAP bind if we are reauthenticating, using LDAPv2,
+                // supporting failover to LDAPv2, or controls have been supplied.
+                if (!initial ||
+                    (version == LDAP_VERSION2) ||
+                    (version == LDAP_VERSION3_VERSION2) ||
+                    ((ctls != null) && (ctls.length > 0))) {
+                    try {
+                        // anonymous bind; update name/pw for LDAPv2 retry
+                        res = ldapBind(name=null, (byte[])(pw=null), ctls, null,
+                            false);
+                        if (res.status == LdapClient.LDAP_SUCCESS) {
+                            conn.setBound();
+                        }
+                    } catch (IOException e) {
+                        NamingException ne =
+                            new CommunicationException("anonymous bind failed: " +
+                            conn.host + ":" + conn.port);
+                        ne.setRootCause(e);
+                        throw ne;
+                    }
+                } else {
+                    // Skip LDAP bind for LDAPv3 anonymous bind
+                    res = new LdapResult();
+                    res.status = LdapClient.LDAP_SUCCESS;
+                }
+            } else if (authMechanism.equalsIgnoreCase("simple")) {
+                // simple authentication
+                byte[] encodedPw = null;
                 try {
-                    // anonymous bind; update name/pw for LDAPv2 retry
-                    res = ldapBind(name=null, (byte[])(pw=null), ctls, null,
-                        false);
+                    encodedPw = encodePassword(pw, isLdapv3);
+                    res = ldapBind(name, encodedPw, ctls, null, false);
                     if (res.status == LdapClient.LDAP_SUCCESS) {
                         conn.setBound();
                     }
                 } catch (IOException e) {
                     NamingException ne =
-                        new CommunicationException("anonymous bind failed: " +
+                        new CommunicationException("simple bind failed: " +
+                            conn.host + ":" + conn.port);
+                    ne.setRootCause(e);
+                    throw ne;
+                } finally {
+                    // If pw was copied to a new array, clear that array as
+                    // a security precaution.
+                    if (encodedPw != pw && encodedPw != null) {
+                        for (int i = 0; i < encodedPw.length; i++) {
+                            encodedPw[i] = 0;
+                        }
+                    }
+                }
+            } else if (isLdapv3) {
+                // SASL authentication
+                try {
+                    res = LdapSasl.saslBind(this, conn, conn.host, name, pw,
+                        authMechanism, env, ctls);
+                    if (res.status == LdapClient.LDAP_SUCCESS) {
+                        conn.setBound();
+                    }
+                } catch (IOException e) {
+                    NamingException ne =
+                        new CommunicationException("SASL bind failed: " +
                         conn.host + ":" + conn.port);
                     ne.setRootCause(e);
                     throw ne;
                 }
             } else {
-                // Skip LDAP bind for LDAPv3 anonymous bind
-                res = new LdapResult();
-                res.status = LdapClient.LDAP_SUCCESS;
+                throw new AuthenticationNotSupportedException(authMechanism);
             }
-        } else if (authMechanism.equalsIgnoreCase("simple")) {
-            // simple authentication
-            byte[] encodedPw = null;
-            try {
-                encodedPw = encodePassword(pw, isLdapv3);
-                res = ldapBind(name, encodedPw, ctls, null, false);
-                if (res.status == LdapClient.LDAP_SUCCESS) {
-                    conn.setBound();
-                }
-            } catch (IOException e) {
-                NamingException ne =
-                    new CommunicationException("simple bind failed: " +
-                        conn.host + ":" + conn.port);
-                ne.setRootCause(e);
-                throw ne;
-            } finally {
-                // If pw was copied to a new array, clear that array as
-                // a security precaution.
-                if (encodedPw != pw && encodedPw != null) {
-                    for (int i = 0; i < encodedPw.length; i++) {
-                        encodedPw[i] = 0;
+
+            //
+            // re-try login using v2 if failing over
+            //
+            if (initial &&
+                (res.status == LdapClient.LDAP_PROTOCOL_ERROR) &&
+                (version == LdapClient.LDAP_VERSION3_VERSION2) &&
+                (authMechanism.equalsIgnoreCase("none") ||
+                    authMechanism.equalsIgnoreCase("anonymous") ||
+                    authMechanism.equalsIgnoreCase("simple"))) {
+
+                byte[] encodedPw = null;
+                try {
+                    isLdapv3 = false;
+                    encodedPw = encodePassword(pw, false);
+                    res = ldapBind(name, encodedPw, ctls, null, false);
+                    if (res.status == LdapClient.LDAP_SUCCESS) {
+                        conn.setBound();
+                    }
+                } catch (IOException e) {
+                    NamingException ne =
+                        new CommunicationException(authMechanism + ":" +
+                            conn.host +     ":" + conn.port);
+                    ne.setRootCause(e);
+                    throw ne;
+                } finally {
+                    // If pw was copied to a new array, clear that array as
+                    // a security precaution.
+                    if (encodedPw != pw && encodedPw != null) {
+                        for (int i = 0; i < encodedPw.length; i++) {
+                            encodedPw[i] = 0;
+                        }
                     }
                 }
             }
-        } else if (isLdapv3) {
-            // SASL authentication
-            try {
-                res = LdapSasl.saslBind(this, conn, conn.host, name, pw,
-                    authMechanism, env, ctls);
-                if (res.status == LdapClient.LDAP_SUCCESS) {
-                    conn.setBound();
-                }
-            } catch (IOException e) {
-                NamingException ne =
-                    new CommunicationException("SASL bind failed: " +
-                    conn.host + ":" + conn.port);
-                ne.setRootCause(e);
-                throw ne;
+
+            // principal name not found
+            // (map NameNotFoundException to AuthenticationException)
+            // %%% This is a workaround for Netscape servers returning
+            // %%% no such object when the principal name is not found
+            // %%% Note that when this workaround is applied, it does not allow
+            // %%% response controls to be recorded by the calling context
+            if (res.status == LdapClient.LDAP_NO_SUCH_OBJECT) {
+                throw new AuthenticationException(
+                    getErrorMessage(res.status, res.errorMessage));
             }
-        } else {
-            throw new AuthenticationNotSupportedException(authMechanism);
+            conn.setV3(isLdapv3);
+            return res;
+        } finally {
+            conn.readTimeout = readTimeout;
         }
-
-        //
-        // re-try login using v2 if failing over
-        //
-        if (initial &&
-            (res.status == LdapClient.LDAP_PROTOCOL_ERROR) &&
-            (version == LdapClient.LDAP_VERSION3_VERSION2) &&
-            (authMechanism.equalsIgnoreCase("none") ||
-                authMechanism.equalsIgnoreCase("anonymous") ||
-                authMechanism.equalsIgnoreCase("simple"))) {
-
-            byte[] encodedPw = null;
-            try {
-                isLdapv3 = false;
-                encodedPw = encodePassword(pw, false);
-                res = ldapBind(name, encodedPw, ctls, null, false);
-                if (res.status == LdapClient.LDAP_SUCCESS) {
-                    conn.setBound();
-                }
-            } catch (IOException e) {
-                NamingException ne =
-                    new CommunicationException(authMechanism + ":" +
-                        conn.host +     ":" + conn.port);
-                ne.setRootCause(e);
-                throw ne;
-            } finally {
-                // If pw was copied to a new array, clear that array as
-                // a security precaution.
-                if (encodedPw != pw && encodedPw != null) {
-                    for (int i = 0; i < encodedPw.length; i++) {
-                        encodedPw[i] = 0;
-                    }
-                }
-            }
-        }
-
-        // principal name not found
-        // (map NameNotFoundException to AuthenticationException)
-        // %%% This is a workaround for Netscape servers returning
-        // %%% no such object when the principal name is not found
-        // %%% Note that when this workaround is applied, it does not allow
-        // %%% response controls to be recorded by the calling context
-        if (res.status == LdapClient.LDAP_NO_SUCH_OBJECT) {
-            throw new AuthenticationException(
-                getErrorMessage(res.status, res.errorMessage));
-        }
-        conn.setV3(isLdapv3);
-        return res;
     }
 
     /**
@@ -487,14 +493,16 @@
      */
     void processConnectionClosure() {
         // Notify listeners
-        if (unsolicited.size() > 0) {
-            String msg;
-            if (conn != null) {
-                msg = conn.host + ":" + conn.port + " connection closed";
-            } else {
-                msg = "Connection closed";
+        synchronized (unsolicited) {
+            if (unsolicited.size() > 0) {
+                String msg;
+                if (conn != null) {
+                    msg = conn.host + ":" + conn.port + " connection closed";
+                } else {
+                    msg = "Connection closed";
+                }
+                notifyUnsolicited(new CommunicationException(msg));
             }
-            notifyUnsolicited(new CommunicationException(msg));
         }
 
         // Remove from pool
diff --git a/jdk/src/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java b/jdk/src/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java
index 75fe0a2..fd6f50c 100644
--- a/jdk/src/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java
+++ b/jdk/src/share/classes/com/sun/rmi/rmid/ExecOptionPermission.java
@@ -223,7 +223,7 @@
         implements java.io.Serializable
     {
 
-        private Hashtable permissions;
+        private Hashtable<String, Permission> permissions;
         private boolean all_allowed; // true if "*" is in the collection
         private static final long serialVersionUID = -1242475729790124375L;
 
@@ -231,7 +231,7 @@
          * Create an empty ExecOptionPermissionCollection.
          */
         public ExecOptionPermissionCollection() {
-            permissions = new Hashtable(11);
+            permissions = new Hashtable<>(11);
             all_allowed = false;
         }
 
@@ -291,7 +291,7 @@
 
             String pname = p.getName();
 
-            Permission x = (Permission) permissions.get(pname);
+            Permission x = permissions.get(pname);
 
             if (x != null)
                 // we have a direct hit!
@@ -306,7 +306,7 @@
             while ((last = pname.lastIndexOf(".", offset)) != -1) {
 
                 pname = pname.substring(0, last+1) + "*";
-                x = (Permission) permissions.get(pname);
+                x = permissions.get(pname);
 
                 if (x != null) {
                     return x.implies(permission);
@@ -321,7 +321,7 @@
             while ((last = pname.lastIndexOf("=", offset)) != -1) {
 
                 pname = pname.substring(0, last+1) + "*";
-                x = (Permission) permissions.get(pname);
+                x = permissions.get(pname);
 
                 if (x != null) {
                     return x.implies(permission);
@@ -341,7 +341,7 @@
          * @return an enumeration of all the ExecOptionPermission objects.
          */
 
-        public Enumeration elements()
+        public Enumeration<Permission> elements()
         {
             return permissions.elements();
         }
diff --git a/jdk/src/share/classes/com/sun/rmi/rmid/ExecPermission.java b/jdk/src/share/classes/com/sun/rmi/rmid/ExecPermission.java
index 45674fe..067b9db 100644
--- a/jdk/src/share/classes/com/sun/rmi/rmid/ExecPermission.java
+++ b/jdk/src/share/classes/com/sun/rmi/rmid/ExecPermission.java
@@ -227,7 +227,7 @@
         extends PermissionCollection
         implements java.io.Serializable
     {
-        private Vector permissions;
+        private Vector<Permission> permissions;
 
         private static final long serialVersionUID = -3352558508888368273L;
 
@@ -235,7 +235,7 @@
          * Create an empty ExecPermissionCollection.
          */
         public ExecPermissionCollection() {
-            permissions = new Vector();
+            permissions = new Vector<>();
         }
 
         /**
@@ -274,10 +274,10 @@
             if (! (permission instanceof ExecPermission))
                 return false;
 
-            Enumeration e = permissions.elements();
+            Enumeration<Permission> e = permissions.elements();
 
             while (e.hasMoreElements()) {
-                ExecPermission x = (ExecPermission) e.nextElement();
+                ExecPermission x = (ExecPermission)e.nextElement();
                 if (x.implies(permission)) {
                     return true;
                 }
@@ -291,7 +291,7 @@
          *
          * @return an enumeration of all the ExecPermission objects.
          */
-        public Enumeration elements()
+        public Enumeration<Permission> elements()
         {
             return permissions.elements();
         }
diff --git a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
index 94bd9c3..ef02c26 100644
--- a/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
+++ b/jdk/src/share/classes/com/sun/security/auth/module/Krb5LoginModule.java
@@ -454,6 +454,10 @@
         useKeyTab = "true".equalsIgnoreCase((String)options.get("useKeyTab"));
         ticketCacheName = (String)options.get("ticketCache");
         keyTabName = (String)options.get("keyTab");
+        if (keyTabName != null) {
+            keyTabName = sun.security.krb5.internal.ktab.KeyTab.normalize(
+                         keyTabName);
+        }
         princName = (String)options.get("principal");
         refreshKrb5Config =
             "true".equalsIgnoreCase((String)options.get("refreshKrb5Config"));
@@ -1056,12 +1060,17 @@
 
             if (storeKey) {
                 if (encKeys == null) {
-                    if (!privCredSet.contains(ktab)) {
-                        privCredSet.add(ktab);
-                        // Compatibility; also add keys to privCredSet
-                        for (KerberosKey key: ktab.getKeys(kerbClientPrinc)) {
-                            privCredSet.add(new Krb5Util.KeysFromKeyTab(key));
+                    if (ktab != null) {
+                        if (!privCredSet.contains(ktab)) {
+                            privCredSet.add(ktab);
+                            // Compatibility; also add keys to privCredSet
+                            for (KerberosKey key: ktab.getKeys(kerbClientPrinc)) {
+                                privCredSet.add(new Krb5Util.KeysFromKeyTab(key));
+                            }
                         }
+                    } else {
+                        succeeded = false;
+                        throw new LoginException("No key to store");
                     }
                 } else {
                     for (int i = 0; i < kerbKeys.length; i ++) {
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties
index b0feea3..722d302 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic.properties
@@ -1,186 +1,189 @@
-# This properties file is used to create a PropertyResourceBundle

-# It contains Locale specific strings used in Swing

-# Currently, the following components need this for support:

-#

-#    ColorChooser

-#    FileChooser

-#    OptionPane

-#

-# When this file is read in, the strings are put into the

-# defaults table.  This is an implementation detail of the current

-# workings of Swing.  DO NOT DEPEND ON THIS.

-# This may change in future versions of Swing as we improve localization

-# support.

-#

-#                        MNEMONIC NOTE:

-# Many of strings in this file are used by widgets that have a

-# mnemonic, for example:

-#   ColorChooser.rgbNameTextAndMnemonic=R&GB

-#

-# Indicates that the tab in the ColorChooser for RGB colors will have

-# the text 'RGB', further the mnemonic character will be 'g' and that

-# a decoration will be provided under the 'G'. This will typically

-# look like:  RGB

-#              -

-#

-# One important thing to remember is that the mnemonic MUST exist in

-# the String, if it does not exist you should add text that makes it

-# exist. This will typically take the form 'XXXX (M)' where M is the

-# character for the mnemonic.

-#

-# @author Steve Wilson

-

-############ FILE CHOOSER STRINGS #############

-FileChooser.fileDescription.textAndMnemonic=Generic File

-FileChooser.directoryDescription.textAndMnemonic=Directory

-FileChooser.newFolderError.textAndMnemonic=Error creating new folder

-FileChooser.newFolderErrorSeparator= :

-FileChooser.newFolderParentDoesntExistTitle.textAndMnemonic=Unable to create folder

-FileChooser.newFolderParentDoesntExist.textAndMnemonic=Unable to create the folder.\n\nThe system cannot find the path specified.

-FileChooser.renameErrorTitle.textAndMnemonic=Error Renaming File or Folder

-FileChooser.renameError.textAndMnemonic=Cannot rename {0}

+# This properties file is used to create a PropertyResourceBundle
+# It contains Locale specific strings used in Swing
+# Currently, the following components need this for support:
+#
+#    ColorChooser
+#    FileChooser
+#    OptionPane
+#
+# When this file is read in, the strings are put into the
+# defaults table.  This is an implementation detail of the current
+# workings of Swing.  DO NOT DEPEND ON THIS.
+# This may change in future versions of Swing as we improve localization
+# support.
+#
+#                        MNEMONIC NOTE:
+# Many of strings in this file are used by widgets that have a
+# mnemonic, for example:
+#   ColorChooser.rgbNameTextAndMnemonic=R&GB
+#
+# Indicates that the tab in the ColorChooser for RGB colors will have
+# the text 'RGB', further the mnemonic character will be 'g' and that
+# a decoration will be provided under the 'G'. This will typically
+# look like:  RGB
+#              -
+#
+# One important thing to remember is that the mnemonic MUST exist in
+# the String, if it does not exist you should add text that makes it
+# exist. This will typically take the form 'XXXX (M)' where M is the
+# character for the mnemonic.
+#
+# @author Steve Wilson
+
+############ FILE CHOOSER STRINGS #############
+FileChooser.fileDescription.textAndMnemonic=Generic File
+FileChooser.directoryDescription.textAndMnemonic=Directory
+FileChooser.newFolderError.textAndMnemonic=Error creating new folder
+FileChooser.newFolderErrorSeparator= :
+FileChooser.newFolderParentDoesntExistTitle.textAndMnemonic=Unable to create folder
+FileChooser.newFolderParentDoesntExist.textAndMnemonic=Unable to create the folder.\n\nThe system cannot find the path specified.
+FileChooser.renameErrorTitle.textAndMnemonic=Error Renaming File or Folder
+FileChooser.renameError.textAndMnemonic=Cannot rename {0}
 FileChooser.renameErrorFileExists.textAndMnemonic=Cannot rename {0}: A file with the name you specified already exists. \
-  Specify a different file name.

-FileChooser.acceptAllFileFilter.textAndMnemonic=All Files

-FileChooser.cancelButton.textAndMnemonic=Cancel

-FileChooser.saveButton.textAndMnemonic=&Save

-FileChooser.openButton.textAndMnemonic=&Open

-FileChooser.saveDialogTitle.textAndMnemonic=Save

-FileChooser.openDialogTitle.textAndMnemonic=Open

-FileChooser.updateButton.textAndMnemonic=&Update

-FileChooser.helpButton.textAndMnemonic=&Help

-FileChooser.directoryOpenButton.textAndMnemonic=&Open

-

-# File Size Units

-FileChooser.fileSizeKiloBytes={0} KB

-FileChooser.fileSizeMegaBytes={0} MB

-FileChooser.fileSizeGigaBytes={0} GB

-

-# These strings are platform dependent not look and feel dependent.

-FileChooser.win32.newFolder=New Folder

-FileChooser.win32.newFolder.subsequent=New Folder ({0})

-FileChooser.other.newFolder=NewFolder

-FileChooser.other.newFolder.subsequent=NewFolder.{0}

-

-

-## file chooser tooltips ###

-FileChooser.cancelButtonToolTip.textAndMnemonic=Abort file chooser dialog

-FileChooser.saveButtonToolTip.textAndMnemonic=Save selected file

-FileChooser.openButtonToolTip.textAndMnemonic=Open selected file

-FileChooser.updateButtonToolTip.textAndMnemonic=Update directory listing

-FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser help

-FileChooser.directoryOpenButtonToolTip.textAndMnemonic=Open selected directory

-

-############ COLOR CHOOSER STRINGS #############

-ColorChooser.preview.textAndMnemonic=Preview

-ColorChooser.ok.textAndMnemonic=OK

-ColorChooser.cancel.textAndMnemonic=Cancel

-ColorChooser.reset.textAndMnemonic=&Reset

-ColorChooser.sample.textAndMnemonic=Sample Text  Sample Text

-ColorChooser.swatches.textAndMnemonic=&Swatches

-ColorChooser.swatchesRecent.textAndMnemonic=Recent:

-ColorChooser.hsv.textAndMnemonic=&HSV

-ColorChooser.hsvHue.textAndMnemonic=Hue

-ColorChooser.hsvSaturation.textAndMnemonic=Saturation

-ColorChooser.hsvValue.textAndMnemonic=Value

-ColorChooser.hsvTransparency.textAndMnemonic=Transparency

-ColorChooser.hsl.textAndMnemonic=HS&L

-ColorChooser.hslHue.textAndMnemonic=Hue

-ColorChooser.hslSaturation.textAndMnemonic=Saturation

-ColorChooser.hslLightness.textAndMnemonic=Lightness

-ColorChooser.hslTransparency.textAndMnemonic=Transparency

-ColorChooser.rgb.textAndMnemonic=R&GB

-ColorChooser.rgbRed.textAndMnemonic=Re&d

-ColorChooser.rgbGreen.textAndMnemonic=Gree&n

-ColorChooser.rgbBlue.textAndMnemonic=&Blue

-ColorChooser.rgbAlpha.textAndMnemonic=Alpha

-ColorChooser.rgbHexCode.textAndMnemonic=&Color Code

-ColorChooser.cmyk.textAndMnemonic=C&MYK

-ColorChooser.cmykCyan.textAndMnemonic=Cyan

-ColorChooser.cmykMagenta.textAndMnemonic=Magenta

-ColorChooser.cmykYellow.textAndMnemonic=Yellow

-ColorChooser.cmykBlack.textAndMnemonic=Black

-ColorChooser.cmykAlpha.textAndMnemonic=Alpha

-

-############ OPTION PANE STRINGS #############

-# We only define mnemonics for YES/NO, but for completeness you can

-# define mnemonics for any of the buttons.

-OptionPane.yesButton.textAndMnemonic=&Yes

-OptionPane.noButton.textAndMnemonic=&No

-OptionPane.okButton.textAndMnemonic=OK

-#OptionPane.okButtonMnemonic=0

-OptionPane.cancelButton.textAndMnemonic=Cancel

-#OptionPane.cancelButtonMnemonic=0

-OptionPane.title.textAndMnemonic=Select an Option

-# Title for the dialog for the showInputDialog methods. Only used if

-# the developer uses one of the variants that doesn't take a title.

-OptionPane.inputDialog.titleAndMnemonic=Input

-# Title for the dialog for the showMessageDialog methods. Only used if

-# the developer uses one of the variants that doesn't take a title.

-OptionPane.messageDialog.titleAndMnemonic=Message

-

-############ Printing Dialog Strings ############

-PrintingDialog.titleProgress.textAndMnemonic=Printing

-PrintingDialog.titleAborting.textAndMnemonic=Printing (Aborting)

-

-PrintingDialog.contentInitial.textAndMnemonic=Printing in progress...

-

-# The following string will be formatted by a MessageFormat

-# and {0} will be replaced by page number being printed

-PrintingDialog.contentProgress.textAndMnemonic=Printed page {0}...

-

-PrintingDialog.contentAborting.textAndMnemonic=Printing aborting...

-

-PrintingDialog.abortButton.textAndMnemonic=&Abort

-PrintingDialog.abortButtonToolTip.textAndMnemonic=Abort Printing

-

-############ Internal Frame Strings ############

-InternalFrame.iconButtonToolTip=Minimize

-InternalFrame.maxButtonToolTip=Maximize

-InternalFrame.restoreButtonToolTip=Restore

-InternalFrame.closeButtonToolTip=Close

-

-############ Internal Frame Title Pane Strings ############

-InternalFrameTitlePane.restoreButton.textAndMnemonic=Restore

-InternalFrameTitlePane.moveButton.textAndMnemonic=Move

-InternalFrameTitlePane.sizeButton.textAndMnemonic=Size

-InternalFrameTitlePane.minimizeButton.textAndMnemonic=Minimize

-InternalFrameTitlePane.maximizeButton.textAndMnemonic=Maximize

-InternalFrameTitlePane.closeButton.textAndMnemonic=Close

-

-############ Text strings #############

-# Used for html forms

-FormView.submitButton.textAndMnemonic=Submit Query

-FormView.resetButton.textAndMnemonic=Reset

-FormView.browseFileButton.textAndMnemonic=Browse...

-

-############ Abstract Document Strings ############

-AbstractDocument.styleChange.textAndMnemonic=style change

-AbstractDocument.addition.textAndMnemonic=addition

-AbstractDocument.deletion.textAndMnemonic=deletion

-AbstractDocument.undo.textAndMnemonic=Undo

-AbstractDocument.redo.textAndMnemonic=Redo

-

-############ Abstract Button Strings ############

-AbstractButton.click.textAndMnemonic=click

-

-############ Abstract Undoable Edit Strings ############

-AbstractUndoableEdit.undo.textAndMnemonic=Undo

-AbstractUndoableEdit.redo.textAndMnemonic=Redo

-

-############ Combo Box Strings ############

-ComboBox.togglePopup.textAndMnemonic=togglePopup

-

-############ Progress Monitor Strings ############

-ProgressMonitor.progress.textAndMnemonic=Progress...

-

-############ Split Pane Strings ############

-SplitPane.leftButton.textAndMnemonic=left button

-SplitPane.rightButton.textAndMnemonic=right button

-# Used for Isindex

-IsindexView.prompt=This is a searchable index.  Enter search keywords:

-

-############ InternalFrameTitlePane Strings ############

-InternalFrameTitlePane.iconifyButtonAccessibleName=Iconify

-InternalFrameTitlePane.maximizeButtonAccessibleName=Maximize

-InternalFrameTitlePane.closeButtonAccessibleName=Close

+  Specify a different file name.
+FileChooser.acceptAllFileFilter.textAndMnemonic=All Files
+FileChooser.cancelButton.textAndMnemonic=Cancel
+FileChooser.saveButton.textAndMnemonic=&Save
+FileChooser.openButton.textAndMnemonic=&Open
+FileChooser.saveDialogTitle.textAndMnemonic=Save
+FileChooser.openDialogTitle.textAndMnemonic=Open
+FileChooser.updateButton.textAndMnemonic=&Update
+FileChooser.helpButton.textAndMnemonic=&Help
+FileChooser.directoryOpenButton.textAndMnemonic=&Open
+
+# File Size Units
+FileChooser.fileSizeKiloBytes={0} KB
+FileChooser.fileSizeMegaBytes={0} MB
+FileChooser.fileSizeGigaBytes={0} GB
+
+# These strings are platform dependent not look and feel dependent.
+FileChooser.win32.newFolder=New Folder
+FileChooser.win32.newFolder.subsequent=New Folder ({0})
+FileChooser.other.newFolder=NewFolder
+FileChooser.other.newFolder.subsequent=NewFolder.{0}
+
+
+## file chooser tooltips ###
+FileChooser.cancelButtonToolTip.textAndMnemonic=Abort file chooser dialog
+FileChooser.saveButtonToolTip.textAndMnemonic=Save selected file
+FileChooser.openButtonToolTip.textAndMnemonic=Open selected file
+FileChooser.updateButtonToolTip.textAndMnemonic=Update directory listing
+FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser help
+FileChooser.directoryOpenButtonToolTip.textAndMnemonic=Open selected directory
+
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
+############ COLOR CHOOSER STRINGS #############
+ColorChooser.preview.textAndMnemonic=Preview
+ColorChooser.ok.textAndMnemonic=OK
+ColorChooser.cancel.textAndMnemonic=Cancel
+ColorChooser.reset.textAndMnemonic=&Reset
+ColorChooser.sample.textAndMnemonic=Sample Text  Sample Text
+ColorChooser.swatches.textAndMnemonic=&Swatches
+ColorChooser.swatchesRecent.textAndMnemonic=Recent:
+ColorChooser.hsv.textAndMnemonic=&HSV
+ColorChooser.hsvHue.textAndMnemonic=Hue
+ColorChooser.hsvSaturation.textAndMnemonic=Saturation
+ColorChooser.hsvValue.textAndMnemonic=Value
+ColorChooser.hsvTransparency.textAndMnemonic=Transparency
+ColorChooser.hsl.textAndMnemonic=HS&L
+ColorChooser.hslHue.textAndMnemonic=Hue
+ColorChooser.hslSaturation.textAndMnemonic=Saturation
+ColorChooser.hslLightness.textAndMnemonic=Lightness
+ColorChooser.hslTransparency.textAndMnemonic=Transparency
+ColorChooser.rgb.textAndMnemonic=R&GB
+ColorChooser.rgbRed.textAndMnemonic=Re&d
+ColorChooser.rgbGreen.textAndMnemonic=Gree&n
+ColorChooser.rgbBlue.textAndMnemonic=&Blue
+ColorChooser.rgbAlpha.textAndMnemonic=Alpha
+ColorChooser.rgbHexCode.textAndMnemonic=&Color Code
+ColorChooser.cmyk.textAndMnemonic=C&MYK
+ColorChooser.cmykCyan.textAndMnemonic=Cyan
+ColorChooser.cmykMagenta.textAndMnemonic=Magenta
+ColorChooser.cmykYellow.textAndMnemonic=Yellow
+ColorChooser.cmykBlack.textAndMnemonic=Black
+ColorChooser.cmykAlpha.textAndMnemonic=Alpha
+
+############ OPTION PANE STRINGS #############
+# We only define mnemonics for YES/NO, but for completeness you can
+# define mnemonics for any of the buttons.
+OptionPane.yesButton.textAndMnemonic=&Yes
+OptionPane.noButton.textAndMnemonic=&No
+OptionPane.okButton.textAndMnemonic=OK
+#OptionPane.okButtonMnemonic=0
+OptionPane.cancelButton.textAndMnemonic=Cancel
+#OptionPane.cancelButtonMnemonic=0
+OptionPane.title.textAndMnemonic=Select an Option
+# Title for the dialog for the showInputDialog methods. Only used if
+# the developer uses one of the variants that doesn't take a title.
+OptionPane.inputDialog.titleAndMnemonic=Input
+# Title for the dialog for the showMessageDialog methods. Only used if
+# the developer uses one of the variants that doesn't take a title.
+OptionPane.messageDialog.titleAndMnemonic=Message
+
+############ Printing Dialog Strings ############
+PrintingDialog.titleProgress.textAndMnemonic=Printing
+PrintingDialog.titleAborting.textAndMnemonic=Printing (Aborting)
+
+PrintingDialog.contentInitial.textAndMnemonic=Printing in progress...
+
+# The following string will be formatted by a MessageFormat
+# and {0} will be replaced by page number being printed
+PrintingDialog.contentProgress.textAndMnemonic=Printed page {0}...
+
+PrintingDialog.contentAborting.textAndMnemonic=Printing aborting...
+
+PrintingDialog.abortButton.textAndMnemonic=&Abort
+PrintingDialog.abortButtonToolTip.textAndMnemonic=Abort Printing
+
+############ Internal Frame Strings ############
+InternalFrame.iconButtonToolTip=Minimize
+InternalFrame.maxButtonToolTip=Maximize
+InternalFrame.restoreButtonToolTip=Restore
+InternalFrame.closeButtonToolTip=Close
+
+############ Internal Frame Title Pane Strings ############
+InternalFrameTitlePane.restoreButton.textAndMnemonic=Restore
+InternalFrameTitlePane.moveButton.textAndMnemonic=Move
+InternalFrameTitlePane.sizeButton.textAndMnemonic=Size
+InternalFrameTitlePane.minimizeButton.textAndMnemonic=Minimize
+InternalFrameTitlePane.maximizeButton.textAndMnemonic=Maximize
+InternalFrameTitlePane.closeButton.textAndMnemonic=Close
+
+############ Text strings #############
+# Used for html forms
+FormView.submitButton.textAndMnemonic=Submit Query
+FormView.resetButton.textAndMnemonic=Reset
+FormView.browseFileButton.textAndMnemonic=Browse...
+
+############ Abstract Document Strings ############
+AbstractDocument.styleChange.textAndMnemonic=style change
+AbstractDocument.addition.textAndMnemonic=addition
+AbstractDocument.deletion.textAndMnemonic=deletion
+AbstractDocument.undo.textAndMnemonic=Undo
+AbstractDocument.redo.textAndMnemonic=Redo
+
+############ Abstract Button Strings ############
+AbstractButton.click.textAndMnemonic=click
+
+############ Abstract Undoable Edit Strings ############
+AbstractUndoableEdit.undo.textAndMnemonic=Undo
+AbstractUndoableEdit.redo.textAndMnemonic=Redo
+
+############ Combo Box Strings ############
+ComboBox.togglePopup.textAndMnemonic=togglePopup
+
+############ Progress Monitor Strings ############
+ProgressMonitor.progress.textAndMnemonic=Progress...
+
+############ Split Pane Strings ############
+SplitPane.leftButton.textAndMnemonic=left button
+SplitPane.rightButton.textAndMnemonic=right button
+# Used for Isindex
+IsindexView.prompt=This is a searchable index.  Enter search keywords:
+
+############ InternalFrameTitlePane Strings ############
+InternalFrameTitlePane.iconifyButtonAccessibleName=Iconify
+InternalFrameTitlePane.maximizeButtonAccessibleName=Maximize
+InternalFrameTitlePane.closeButtonAccessibleName=Close
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties
index c620dbe..0eeacee 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_de.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser-Hilfe
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=Ausgew\u00E4hltes Verzeichnis \u00F6ffnen
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=Vorschau
 ColorChooser.ok.textAndMnemonic=OK
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties
index fd804a3..4d4839e 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_es.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=Ayuda del Selector de Archivos
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=Abrir directorio seleccionado
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=Vista Previa
 ColorChooser.ok.textAndMnemonic=Aceptar
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties
index 24d0e92..88f5152 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_fr.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=Aide du s\u00E9lecteur de fichiers
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=Ouvre le r\u00E9pertoire s\u00E9lectionn\u00E9
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=Aper\u00E7u
 ColorChooser.ok.textAndMnemonic=OK
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties
index 2ef0c7c..bfeee66 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_it.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=Guida FileChooser
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=Apre la directory selezionata
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=Anteprima
 ColorChooser.ok.textAndMnemonic=OK
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties
index a75ab29..5a49c6b 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ja.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser\u306E\u30D8\u30EB\u30D7\u3067\u3059
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=\u9078\u629E\u3057\u305F\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u3092\u958B\u304D\u307E\u3059
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=\u30D7\u30EC\u30D3\u30E5\u30FC
 ColorChooser.ok.textAndMnemonic=OK
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties
index a06dc01..1652e73 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_ko.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser \uB3C4\uC6C0\uB9D0
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=\uC120\uD0DD\uB41C \uB514\uB809\uD1A0\uB9AC \uC5F4\uAE30
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=\uBBF8\uB9AC\uBCF4\uAE30
 ColorChooser.ok.textAndMnemonic=\uD655\uC778
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_pt_BR.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_pt_BR.properties
index 48ccc1a..ab844d1 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_pt_BR.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_pt_BR.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=Ajuda do FileChooser
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=Abrir diret\u00F3rio selecionado
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=Visualizar
 ColorChooser.ok.textAndMnemonic=OK
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties
index e7268f3..8ed1782 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_sv.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=Hj\u00E4lp - Filv\u00E4ljare
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=\u00D6ppna vald katalog
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=Granska
 ColorChooser.ok.textAndMnemonic=OK
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties
index fc5199d..da4f5f8 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_CN.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=FileChooser \u5E2E\u52A9
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=\u6253\u5F00\u9009\u62E9\u7684\u76EE\u5F55
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=\u9884\u89C8
 ColorChooser.ok.textAndMnemonic=\u786E\u5B9A
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties
index 8be6aef..cf4708b 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/basic/resources/basic_zh_TW.properties
@@ -70,6 +70,9 @@
 FileChooser.helpButtonToolTip.textAndMnemonic=\u300C\u6A94\u6848\u9078\u64C7\u5668\u300D\u8AAA\u660E
 FileChooser.directoryOpenButtonToolTip.textAndMnemonic=\u958B\u555F\u9078\u53D6\u7684\u76EE\u9304
 
+FileChooser.filesListAccessibleName=Files List
+FileChooser.filesDetailsAccessibleName=Files Details
+
 ############ COLOR CHOOSER STRINGS #############
 ColorChooser.preview.textAndMnemonic=\u9810\u89BD
 ColorChooser.ok.textAndMnemonic=\u78BA\u5B9A
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal.properties
index ece884a..e3cc230 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal.properties
@@ -18,11 +18,11 @@
 

 ############ FILE CHOOSER STRINGS #############

 

-FileChooser.lookInLabel.textAndMnemonic=Look In:

+FileChooser.lookInLabel.textAndMnemonic=Look &In:

 FileChooser.saveInLabel.textAndMnemonic=Save In:

-FileChooser.fileNameLabel.textAndMnemonic=File Name:

-FileChooser.folderNameLabel.textAndMnemonic=Folder name:

-FileChooser.filesOfTypeLabel.textAndMnemonic=Files of Type:

+FileChooser.fileNameLabel.textAndMnemonic=File &Name:

+FileChooser.folderNameLabel.textAndMnemonic=Folder &name:

+FileChooser.filesOfTypeLabel.textAndMnemonic=Files of &Type:

 FileChooser.upFolderToolTip.textAndMnemonic=Up One Level

 FileChooser.upFolderAccessibleName=Up

 FileChooser.homeFolderToolTip.textAndMnemonic=Home

diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_de.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_de.properties
index a7347da..3eacc04 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_de.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_de.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Suchen in:
+FileChooser.lookInLabel.textAndMnemonic=Suchen &in:
 FileChooser.saveInLabel.textAndMnemonic=Speichern in:
-FileChooser.fileNameLabel.textAndMnemonic=Dateiname:
-FileChooser.folderNameLabel.textAndMnemonic=Ordnername:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Dateityp:
+FileChooser.fileNameLabel.textAndMnemonic=Datei&name:
+FileChooser.folderNameLabel.textAndMnemonic=Ord&nername:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Da&teityp:
 FileChooser.upFolderToolTip.textAndMnemonic=Eine Ebene h\u00F6her
 FileChooser.upFolderAccessibleName=Nach oben
 FileChooser.homeFolderToolTip.textAndMnemonic=Home
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_es.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_es.properties
index df44871..d78e35b 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_es.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_es.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Buscar en:
+FileChooser.lookInLabel.textAndMnemonic=Buscar en(&I):
 FileChooser.saveInLabel.textAndMnemonic=Guardar en:
-FileChooser.fileNameLabel.textAndMnemonic=Nombre de Archivo:
-FileChooser.folderNameLabel.textAndMnemonic=Nombre de la Carpeta:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Archivos de Tipo:
+FileChooser.fileNameLabel.textAndMnemonic=&Nombre de Archivo:
+FileChooser.folderNameLabel.textAndMnemonic=&Nombre de la Carpeta:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Archivos de &Tipo:
 FileChooser.upFolderToolTip.textAndMnemonic=Subir un Nivel
 FileChooser.upFolderAccessibleName=Arriba
 FileChooser.homeFolderToolTip.textAndMnemonic=Inicio
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_fr.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_fr.properties
index 0df6e52..2a9187d 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_fr.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_fr.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Rechercher dans :
+FileChooser.lookInLabel.textAndMnemonic=Rechercher dans (&I):
 FileChooser.saveInLabel.textAndMnemonic=Enregistrer dans :
-FileChooser.fileNameLabel.textAndMnemonic=Nom du fichier :
-FileChooser.folderNameLabel.textAndMnemonic=Nom du dossier :
-FileChooser.filesOfTypeLabel.textAndMnemonic=Fichiers de type :
+FileChooser.fileNameLabel.textAndMnemonic=&Nom du fichier :
+FileChooser.folderNameLabel.textAndMnemonic=&Nom du dossier :
+FileChooser.filesOfTypeLabel.textAndMnemonic=Fichiers de &type :
 FileChooser.upFolderToolTip.textAndMnemonic=Remonte d'un niveau.
 FileChooser.upFolderAccessibleName=Monter
 FileChooser.homeFolderToolTip.textAndMnemonic=R\u00E9pertoire d'origine
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_it.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_it.properties
index 65e17a7..65e6eec 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_it.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_it.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Cerca in:
+FileChooser.lookInLabel.textAndMnemonic=Cerca &in:
 FileChooser.saveInLabel.textAndMnemonic=Salva in:
-FileChooser.fileNameLabel.textAndMnemonic=Nome file:
-FileChooser.folderNameLabel.textAndMnemonic=Nome della cartella:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Tipo file:
+FileChooser.fileNameLabel.textAndMnemonic=&Nome file:
+FileChooser.folderNameLabel.textAndMnemonic=&Nome della cartella:
+FileChooser.filesOfTypeLabel.textAndMnemonic=&Tipo file:
 FileChooser.upFolderToolTip.textAndMnemonic=Cartella superiore
 FileChooser.upFolderAccessibleName=Superiore
 FileChooser.homeFolderToolTip.textAndMnemonic=Home
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_ja.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_ja.properties
index 5478f7f..b1aeb00 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_ja.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_ja.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u53C2\u7167:
+FileChooser.lookInLabel.textAndMnemonic=\u53C2\u7167(&I):
 FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58:
-FileChooser.fileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D:
-FileChooser.folderNameLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0\u540D:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u306E\u30BF\u30A4\u30D7:
+FileChooser.fileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0\u540D(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u306E\u30BF\u30A4\u30D7(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=1\u30EC\u30D9\u30EB\u4E0A\u3078
 FileChooser.upFolderAccessibleName=\u4E0A\u3078
 FileChooser.homeFolderToolTip.textAndMnemonic=\u30DB\u30FC\u30E0
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_ko.properties
index d3e0cfa..326f9cf 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_ko.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_ko.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\uAC80\uC0C9 \uC704\uCE58:
+FileChooser.lookInLabel.textAndMnemonic=\uAC80\uC0C9 \uC704\uCE58(&I):
 FileChooser.saveInLabel.textAndMnemonic=\uC800\uC7A5 \uC704\uCE58:
-FileChooser.fileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984:
-FileChooser.folderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\uD30C\uC77C \uC720\uD615:
+FileChooser.fileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\uD30C\uC77C \uC720\uD615(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=\uD55C \uB808\uBCA8 \uC704\uB85C
 FileChooser.upFolderAccessibleName=\uC704\uB85C
 FileChooser.homeFolderToolTip.textAndMnemonic=\uD648
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_pt_BR.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_pt_BR.properties
index 9d0f0a0..8ec8d1d 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_pt_BR.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_pt_BR.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Consultar Em:
+FileChooser.lookInLabel.textAndMnemonic=Consultar Em(&I):
 FileChooser.saveInLabel.textAndMnemonic=Salvar Em:
-FileChooser.fileNameLabel.textAndMnemonic=Nome do Arquivo:
-FileChooser.folderNameLabel.textAndMnemonic=Nome da pasta:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Arquivos do Tipo:
+FileChooser.fileNameLabel.textAndMnemonic=&Nome do Arquivo:
+FileChooser.folderNameLabel.textAndMnemonic=&Nome da pasta:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Arquivos do &Tipo:
 FileChooser.upFolderToolTip.textAndMnemonic=Um N\u00EDvel Acima
 FileChooser.upFolderAccessibleName=Acima
 FileChooser.homeFolderToolTip.textAndMnemonic=In\u00EDcio
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties
index 988cee1..d161d0e 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_sv.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Leta i:
+FileChooser.lookInLabel.textAndMnemonic=Leta &i:
 FileChooser.saveInLabel.textAndMnemonic=Spara i:
-FileChooser.fileNameLabel.textAndMnemonic=Filnamn:
-FileChooser.folderNameLabel.textAndMnemonic=Mapp:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Filformat:
+FileChooser.fileNameLabel.textAndMnemonic=Fil&namn:
+FileChooser.folderNameLabel.textAndMnemonic=Mapp(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=Filforma&t:
 FileChooser.upFolderToolTip.textAndMnemonic=Upp en niv\u00E5
 FileChooser.upFolderAccessibleName=Upp
 FileChooser.homeFolderToolTip.textAndMnemonic=Hem
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_zh_CN.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_zh_CN.properties
index 70dc8f3..f0cbf3b 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_zh_CN.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_zh_CN.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u67E5\u770B: 
+FileChooser.lookInLabel.textAndMnemonic=\u67E5\u770B(&I): 
 FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58: 
-FileChooser.fileNameLabel.textAndMnemonic=\u6587\u4EF6\u540D: 
-FileChooser.folderNameLabel.textAndMnemonic=\u6587\u4EF6\u5939\u540D: 
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u6587\u4EF6\u7C7B\u578B: 
+FileChooser.fileNameLabel.textAndMnemonic=\u6587\u4EF6\u540D(&N): 
+FileChooser.folderNameLabel.textAndMnemonic=\u6587\u4EF6\u5939\u540D(&N): 
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u6587\u4EF6\u7C7B\u578B(&T): 
 FileChooser.upFolderToolTip.textAndMnemonic=\u5411\u4E0A\u4E00\u7EA7
 FileChooser.upFolderAccessibleName=\u5411\u4E0A
 FileChooser.homeFolderToolTip.textAndMnemonic=\u4E3B\u76EE\u5F55
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_zh_TW.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_zh_TW.properties
index b075d44..1d2b826 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_zh_TW.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/metal/resources/metal_zh_TW.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u67E5\u8A62:
+FileChooser.lookInLabel.textAndMnemonic=\u67E5\u8A62(&I):
 FileChooser.saveInLabel.textAndMnemonic=\u5132\u5B58\u65BC: 
-FileChooser.fileNameLabel.textAndMnemonic=\u6A94\u6848\u540D\u7A31:
-FileChooser.folderNameLabel.textAndMnemonic=\u8CC7\u6599\u593E\u540D\u7A31:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u6A94\u6848\u985E\u578B:
+FileChooser.fileNameLabel.textAndMnemonic=\u6A94\u6848\u540D\u7A31(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\u8CC7\u6599\u593E\u540D\u7A31(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u6A94\u6848\u985E\u578B(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=\u5F80\u4E0A\u4E00\u5C64
 FileChooser.upFolderAccessibleName=\u5F80\u4E0A
 FileChooser.homeFolderToolTip.textAndMnemonic=\u4E3B\u76EE\u9304
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth.properties
index 0aadeae..35d2356 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth.properties
@@ -18,11 +18,11 @@
 

 ############ FILE CHOOSER STRINGS #############

 

-FileChooser.lookInLabel.textAndMnemonic=Look In:

+FileChooser.lookInLabel.textAndMnemonic=Look &In:

 FileChooser.saveInLabel.textAndMnemonic=Save In:

-FileChooser.fileNameLabel.textAndMnemonic=File Name:

-FileChooser.folderNameLabel.textAndMnemonic=Folder name:

-FileChooser.filesOfTypeLabel.textAndMnemonic=Files of Type:

+FileChooser.fileNameLabel.textAndMnemonic=File &Name:

+FileChooser.folderNameLabel.textAndMnemonic=Folder &Name:

+FileChooser.filesOfTypeLabel.textAndMnemonic=Files of &Type:

 FileChooser.upFolderToolTip.textAndMnemonic=Up One Level

 FileChooser.upFolderAccessibleName=Up

 FileChooser.homeFolderToolTip.textAndMnemonic=Home

diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_de.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_de.properties
index f0ea8b8..b120862 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_de.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_de.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Suchen in:
+FileChooser.lookInLabel.textAndMnemonic=Suchen &in:
 FileChooser.saveInLabel.textAndMnemonic=Speichern in:
-FileChooser.fileNameLabel.textAndMnemonic=Dateiname:
-FileChooser.folderNameLabel.textAndMnemonic=Ordnername:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Dateityp:
+FileChooser.fileNameLabel.textAndMnemonic=Datei&name:
+FileChooser.folderNameLabel.textAndMnemonic=Ord&nername:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Da&teityp:
 FileChooser.upFolderToolTip.textAndMnemonic=Eine Ebene h\u00F6her
 FileChooser.upFolderAccessibleName=Nach oben
 FileChooser.homeFolderToolTip.textAndMnemonic=Home
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_es.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_es.properties
index f011d42..d308337 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_es.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_es.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Buscar en:
+FileChooser.lookInLabel.textAndMnemonic=Buscar en(&I):
 FileChooser.saveInLabel.textAndMnemonic=Guardar en:
-FileChooser.fileNameLabel.textAndMnemonic=Nombre de Archivo:
-FileChooser.folderNameLabel.textAndMnemonic=Nombre de la Carpeta:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Archivos de Tipo:
+FileChooser.fileNameLabel.textAndMnemonic=&Nombre de Archivo:
+FileChooser.folderNameLabel.textAndMnemonic=&Nombre de la Carpeta:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Archivos de &Tipo:
 FileChooser.upFolderToolTip.textAndMnemonic=Subir un Nivel
 FileChooser.upFolderAccessibleName=Arriba
 FileChooser.homeFolderToolTip.textAndMnemonic=Inicio
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_fr.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_fr.properties
index ff129b8..6103828 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_fr.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_fr.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Rechercher dans :
+FileChooser.lookInLabel.textAndMnemonic=Rechercher dans (&I):
 FileChooser.saveInLabel.textAndMnemonic=Enregistrer dans :
-FileChooser.fileNameLabel.textAndMnemonic=Nom du fichier :
-FileChooser.folderNameLabel.textAndMnemonic=Nom du dossier :
-FileChooser.filesOfTypeLabel.textAndMnemonic=Fichiers de type :
+FileChooser.fileNameLabel.textAndMnemonic=&Nom du fichier :
+FileChooser.folderNameLabel.textAndMnemonic=&Nom du dossier :
+FileChooser.filesOfTypeLabel.textAndMnemonic=Fichiers de &type :
 FileChooser.upFolderToolTip.textAndMnemonic=Remonte d'un niveau.
 FileChooser.upFolderAccessibleName=Monter
 FileChooser.homeFolderToolTip.textAndMnemonic=R\u00E9pertoire d'origine
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_it.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_it.properties
index 1eb897b..a95c218 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_it.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_it.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Cerca in:
+FileChooser.lookInLabel.textAndMnemonic=Cerca &in:
 FileChooser.saveInLabel.textAndMnemonic=Salva in:
-FileChooser.fileNameLabel.textAndMnemonic=Nome file:
-FileChooser.folderNameLabel.textAndMnemonic=Nome della cartella:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Tipo file:
+FileChooser.fileNameLabel.textAndMnemonic=&Nome file:
+FileChooser.folderNameLabel.textAndMnemonic=&Nome della cartella:
+FileChooser.filesOfTypeLabel.textAndMnemonic=&Tipo file:
 FileChooser.upFolderToolTip.textAndMnemonic=Cartella superiore
 FileChooser.upFolderAccessibleName=Superiore
 FileChooser.homeFolderToolTip.textAndMnemonic=Home
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_ja.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_ja.properties
index d6d6e56..f492300 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_ja.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_ja.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u53C2\u7167:
+FileChooser.lookInLabel.textAndMnemonic=\u53C2\u7167(&I):
 FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58:
-FileChooser.fileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D:
-FileChooser.folderNameLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0\u540D:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u306E\u30BF\u30A4\u30D7:
+FileChooser.fileNameLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u540D(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\u30D5\u30A9\u30EB\u30C0\u540D(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u30D5\u30A1\u30A4\u30EB\u306E\u30BF\u30A4\u30D7(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=1\u30EC\u30D9\u30EB\u4E0A\u3078
 FileChooser.upFolderAccessibleName=\u4E0A\u3078
 FileChooser.homeFolderToolTip.textAndMnemonic=\u30DB\u30FC\u30E0
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_ko.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_ko.properties
index 691826d..3fa720d 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_ko.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_ko.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\uAC80\uC0C9 \uC704\uCE58:
+FileChooser.lookInLabel.textAndMnemonic=\uAC80\uC0C9 \uC704\uCE58(&I):
 FileChooser.saveInLabel.textAndMnemonic=\uC800\uC7A5 \uC704\uCE58:
-FileChooser.fileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984:
-FileChooser.folderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\uD30C\uC77C \uC720\uD615:
+FileChooser.fileNameLabel.textAndMnemonic=\uD30C\uC77C \uC774\uB984(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\uD3F4\uB354 \uC774\uB984(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\uD30C\uC77C \uC720\uD615(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=\uD55C \uB808\uBCA8 \uC704\uB85C
 FileChooser.upFolderAccessibleName=\uC704\uB85C
 FileChooser.homeFolderToolTip.textAndMnemonic=\uD648
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_pt_BR.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_pt_BR.properties
index dc0b9a0..0eb5bfe 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_pt_BR.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_pt_BR.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Consultar Em:
+FileChooser.lookInLabel.textAndMnemonic=Consultar Em(&I):
 FileChooser.saveInLabel.textAndMnemonic=Salvar Em:
-FileChooser.fileNameLabel.textAndMnemonic=Nome do Arquivo:
-FileChooser.folderNameLabel.textAndMnemonic=Nome da pasta:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Arquivos do Tipo:
+FileChooser.fileNameLabel.textAndMnemonic=&Nome do Arquivo:
+FileChooser.folderNameLabel.textAndMnemonic=&Nome da pasta:
+FileChooser.filesOfTypeLabel.textAndMnemonic=Arquivos do &Tipo:
 FileChooser.upFolderToolTip.textAndMnemonic=Um N\u00EDvel Acima
 FileChooser.upFolderAccessibleName=Acima
 FileChooser.homeFolderToolTip.textAndMnemonic=In\u00EDcio
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_sv.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_sv.properties
index 76188e2..8a28500 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_sv.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_sv.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=Leta i:
+FileChooser.lookInLabel.textAndMnemonic=Leta &i:
 FileChooser.saveInLabel.textAndMnemonic=Spara i:
-FileChooser.fileNameLabel.textAndMnemonic=Filnamn:
-FileChooser.folderNameLabel.textAndMnemonic=Mapp:
-FileChooser.filesOfTypeLabel.textAndMnemonic=Filformat:
+FileChooser.fileNameLabel.textAndMnemonic=Fil&namn:
+FileChooser.folderNameLabel.textAndMnemonic=Mapp(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=Filforma&t:
 FileChooser.upFolderToolTip.textAndMnemonic=Upp en niv\u00E5
 FileChooser.upFolderAccessibleName=Upp
 FileChooser.homeFolderToolTip.textAndMnemonic=Hem
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_zh_CN.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_zh_CN.properties
index b03c34c..4ba9bba 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_zh_CN.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_zh_CN.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u67E5\u770B: 
-FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58: 
-FileChooser.fileNameLabel.textAndMnemonic=\u6587\u4EF6\u540D: 
-FileChooser.folderNameLabel.textAndMnemonic=\u6587\u4EF6\u5939\u540D: 
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u6587\u4EF6\u7C7B\u578B: 
+FileChooser.lookInLabel.textAndMnemonic=\u67E5\u770B(&I):
+FileChooser.saveInLabel.textAndMnemonic=\u4FDD\u5B58:
+FileChooser.fileNameLabel.textAndMnemonic=\u6587\u4EF6\u540D(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\u6587\u4EF6\u5939\u540D(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u6587\u4EF6\u7C7B\u578B(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=\u5411\u4E0A\u4E00\u7EA7
 FileChooser.upFolderAccessibleName=\u5411\u4E0A
 FileChooser.homeFolderToolTip.textAndMnemonic=\u4E3B\u76EE\u5F55
diff --git a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_zh_TW.properties b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_zh_TW.properties
index e5ed4bc..60d8410 100644
--- a/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_zh_TW.properties
+++ b/jdk/src/share/classes/com/sun/swing/internal/plaf/synth/resources/synth_zh_TW.properties
@@ -18,11 +18,11 @@
 
 ############ FILE CHOOSER STRINGS #############
 
-FileChooser.lookInLabel.textAndMnemonic=\u67E5\u8A62:
+FileChooser.lookInLabel.textAndMnemonic=\u67E5\u8A62(&I):
 FileChooser.saveInLabel.textAndMnemonic=\u5132\u5B58\u65BC: 
-FileChooser.fileNameLabel.textAndMnemonic=\u6A94\u6848\u540D\u7A31:
-FileChooser.folderNameLabel.textAndMnemonic=\u8CC7\u6599\u593E\u540D\u7A31:
-FileChooser.filesOfTypeLabel.textAndMnemonic=\u6A94\u6848\u985E\u578B:
+FileChooser.fileNameLabel.textAndMnemonic=\u6A94\u6848\u540D\u7A31(&N):
+FileChooser.folderNameLabel.textAndMnemonic=\u8CC7\u6599\u593E\u540D\u7A31(&N):
+FileChooser.filesOfTypeLabel.textAndMnemonic=\u6A94\u6848\u985E\u578B(&T):
 FileChooser.upFolderToolTip.textAndMnemonic=\u5F80\u4E0A\u4E00\u5C64
 FileChooser.upFolderAccessibleName=\u5F80\u4E0A
 FileChooser.homeFolderToolTip.textAndMnemonic=\u4E3B\u76EE\u9304
diff --git a/jdk/src/share/classes/java/awt/Component.java b/jdk/src/share/classes/java/awt/Component.java
index ae23c31..159af84 100644
--- a/jdk/src/share/classes/java/awt/Component.java
+++ b/jdk/src/share/classes/java/awt/Component.java
@@ -150,7 +150,7 @@
  *    import java.awt.event.*;
  *    import java.io.Serializable;
  *
- *    class MyApp java.io.Serializable
+ *    class MyApp implements java.io.Serializable
  *    {
  *         BigObjectThatShouldNotBeSerializedWithAButton bigOne;
  *         Button aButton = new Button();
diff --git a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java
index 97ebe0b..b0b32f8 100644
--- a/jdk/src/share/classes/java/awt/KeyboardFocusManager.java
+++ b/jdk/src/share/classes/java/awt/KeyboardFocusManager.java
@@ -458,7 +458,7 @@
     private void initPeer() {
         Toolkit tk = Toolkit.getDefaultToolkit();
         KeyboardFocusManagerPeerProvider peerProvider = (KeyboardFocusManagerPeerProvider)tk;
-        peer = peerProvider.createKeyboardFocusManagerPeer(this);
+        peer = peerProvider.getKeyboardFocusManagerPeer();
     }
 
     /**
diff --git a/jdk/src/share/classes/java/awt/TextComponent.java b/jdk/src/share/classes/java/awt/TextComponent.java
index beb0b98..fef4a9f 100644
--- a/jdk/src/share/classes/java/awt/TextComponent.java
+++ b/jdk/src/share/classes/java/awt/TextComponent.java
@@ -233,9 +233,14 @@
      * @see         java.awt.TextComponent#getText
      */
     public synchronized void setText(String t) {
+        boolean skipTextEvent = (text == null || text.isEmpty())
+                && (t == null || t.isEmpty());
         text = (t != null) ? t : "";
         TextComponentPeer peer = (TextComponentPeer)this.peer;
-        if (peer != null) {
+        // Please note that we do not want to post an event
+        // if TextArea.setText() or TextField.setText() replaces an empty text
+        // by an empty text, that is, if component's text remains unchanged.
+        if (peer != null && !skipTextEvent) {
             peer.setText(text);
         }
     }
diff --git a/jdk/src/share/classes/java/awt/peer/KeyboardFocusManagerPeer.java b/jdk/src/share/classes/java/awt/peer/KeyboardFocusManagerPeer.java
index 0d533e5..97d9b60 100644
--- a/jdk/src/share/classes/java/awt/peer/KeyboardFocusManagerPeer.java
+++ b/jdk/src/share/classes/java/awt/peer/KeyboardFocusManagerPeer.java
@@ -34,6 +34,14 @@
 public interface KeyboardFocusManagerPeer {
 
     /**
+     * Sets the window that should become the focused window.
+     *
+     * @param win the window that should become the focused window
+     *
+     */
+    void setCurrentFocusedWindow(Window win);
+
+    /**
      * Returns the currently focused window.
      *
      * @return the currently focused window
diff --git a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java
index 96b4155..99d1c7e 100644
--- a/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java
+++ b/jdk/src/share/classes/java/beans/IndexedPropertyDescriptor.java
@@ -181,20 +181,21 @@
                 // the Indexed readMethod was explicitly set to null.
                 return null;
             }
+            String nextMethodName = Introspector.GET_PREFIX + getBaseName();
             if (indexedReadMethodName == null) {
                 Class type = getIndexedPropertyType0();
                 if (type == boolean.class || type == null) {
                     indexedReadMethodName = Introspector.IS_PREFIX + getBaseName();
                 } else {
-                    indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
+                    indexedReadMethodName = nextMethodName;
                 }
             }
 
             Class[] args = { int.class };
             indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
-            if (indexedReadMethod == null) {
+            if ((indexedReadMethod == null) && !indexedReadMethodName.equals(nextMethodName)) {
                 // no "is" method, so look for a "get" method.
-                indexedReadMethodName = Introspector.GET_PREFIX + getBaseName();
+                indexedReadMethodName = nextMethodName;
                 indexedReadMethod = Introspector.findMethod(cls, indexedReadMethodName, 1, args);
             }
             setIndexedReadMethod0(indexedReadMethod);
diff --git a/jdk/src/share/classes/java/beans/Introspector.java b/jdk/src/share/classes/java/beans/Introspector.java
index 447f060..8276e5d 100644
--- a/jdk/src/share/classes/java/beans/Introspector.java
+++ b/jdk/src/share/classes/java/beans/Introspector.java
@@ -25,6 +25,7 @@
 
 package java.beans;
 
+import com.sun.beans.TypeResolver;
 import com.sun.beans.WeakCache;
 import com.sun.beans.finder.ClassFinder;
 
@@ -34,6 +35,7 @@
 import java.lang.ref.SoftReference;
 import java.lang.reflect.Method;
 import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
 
 import java.util.Map;
 import java.util.ArrayList;
@@ -584,7 +586,7 @@
                 if (readI != null) cls = cls && readI.getGenericReturnType() instanceof Class;
                 if (writeI != null) cls = cls && writeI.getGenericParameterTypes()[1] instanceof Class;
                 if (!cls) {
-                    pd = new IndexedPropertyDescriptor((IndexedPropertyDescriptor) pd);
+                    pd = new IndexedPropertyDescriptor(ipd);
                     pd.updateGenericsFor(this.beanClass);
                 }
             }
@@ -950,44 +952,61 @@
                     continue;
                 }
 
-                Class argTypes[] = FeatureDescriptor.getParameterTypes(beanClass, method);
-                Class resultType = FeatureDescriptor.getReturnType(beanClass, method);
-
-                if (name.startsWith(ADD_PREFIX) && argTypes.length == 1 &&
-                    resultType == Void.TYPE &&
-                    Introspector.isSubclass(argTypes[0], eventListenerType)) {
-                    String listenerName = name.substring(3);
-                    if (listenerName.length() > 0 &&
-                        argTypes[0].getName().endsWith(listenerName)) {
-                        if (adds == null) {
-                            adds = new HashMap();
+                if (name.startsWith(ADD_PREFIX)) {
+                    Class<?> returnType = method.getReturnType();
+                    if (returnType == void.class) {
+                        Type[] parameterTypes = method.getGenericParameterTypes();
+                        if (parameterTypes.length == 1) {
+                            Class<?> type = TypeResolver.erase(TypeResolver.resolveInClass(beanClass, parameterTypes[0]));
+                            if (Introspector.isSubclass(type, eventListenerType)) {
+                                String listenerName = name.substring(3);
+                                if (listenerName.length() > 0 &&
+                                    type.getName().endsWith(listenerName)) {
+                                    if (adds == null) {
+                                        adds = new HashMap();
+                                    }
+                                    adds.put(listenerName, method);
+                                }
+                            }
                         }
-                        adds.put(listenerName, method);
                     }
                 }
-                else if (name.startsWith(REMOVE_PREFIX) && argTypes.length == 1 &&
-                         resultType == Void.TYPE &&
-                         Introspector.isSubclass(argTypes[0], eventListenerType)) {
-                    String listenerName = name.substring(6);
-                    if (listenerName.length() > 0 &&
-                        argTypes[0].getName().endsWith(listenerName)) {
-                        if (removes == null) {
-                            removes = new HashMap();
+                else if (name.startsWith(REMOVE_PREFIX)) {
+                    Class<?> returnType = method.getReturnType();
+                    if (returnType == void.class) {
+                        Type[] parameterTypes = method.getGenericParameterTypes();
+                        if (parameterTypes.length == 1) {
+                            Class<?> type = TypeResolver.erase(TypeResolver.resolveInClass(beanClass, parameterTypes[0]));
+                            if (Introspector.isSubclass(type, eventListenerType)) {
+                                String listenerName = name.substring(6);
+                                if (listenerName.length() > 0 &&
+                                    type.getName().endsWith(listenerName)) {
+                                    if (removes == null) {
+                                        removes = new HashMap();
+                                    }
+                                    removes.put(listenerName, method);
+                                }
+                            }
                         }
-                        removes.put(listenerName, method);
                     }
                 }
-                else if (name.startsWith(GET_PREFIX) && argTypes.length == 0 &&
-                         resultType.isArray() &&
-                         Introspector.isSubclass(resultType.getComponentType(),
-                                                 eventListenerType)) {
-                    String listenerName  = name.substring(3, name.length() - 1);
-                    if (listenerName.length() > 0 &&
-                        resultType.getComponentType().getName().endsWith(listenerName)) {
-                        if (gets == null) {
-                            gets = new HashMap();
+                else if (name.startsWith(GET_PREFIX)) {
+                    Class<?>[] parameterTypes = method.getParameterTypes();
+                    if (parameterTypes.length == 0) {
+                        Class<?> returnType = FeatureDescriptor.getReturnType(beanClass, method);
+                        if (returnType.isArray()) {
+                            Class<?> type = returnType.getComponentType();
+                            if (Introspector.isSubclass(type, eventListenerType)) {
+                                String listenerName  = name.substring(3, name.length() - 1);
+                                if (listenerName.length() > 0 &&
+                                    type.getName().endsWith(listenerName)) {
+                                    if (gets == null) {
+                                        gets = new HashMap();
+                                    }
+                                    gets.put(listenerName, method);
+                                }
+                            }
                         }
-                        gets.put(listenerName, method);
                     }
                 }
             }
@@ -1239,11 +1258,11 @@
     private boolean isEventHandler(Method m) {
         // We assume that a method is an event handler if it has a single
         // argument, whose type inherit from java.util.Event.
-        Class argTypes[] = FeatureDescriptor.getParameterTypes(beanClass, m);
+        Type argTypes[] = m.getGenericParameterTypes();
         if (argTypes.length != 1) {
             return false;
         }
-        return isSubclass(argTypes[0], EventObject.class);
+        return isSubclass(TypeResolver.erase(TypeResolver.resolveInClass(beanClass, argTypes[0])), EventObject.class);
     }
 
     /*
@@ -1295,24 +1314,25 @@
                 }
 
                 // make sure method signature matches.
-                Class params[] = FeatureDescriptor.getParameterTypes(start, method);
-                if (method.getName().equals(methodName) &&
-                    params.length == argCount) {
-                    if (args != null) {
-                        boolean different = false;
-                        if (argCount > 0) {
-                            for (int j = 0; j < argCount; j++) {
-                                if (params[j] != args[j]) {
-                                    different = true;
+                if (method.getName().equals(methodName)) {
+                    Type[] params = method.getGenericParameterTypes();
+                    if (params.length == argCount) {
+                        if (args != null) {
+                            boolean different = false;
+                            if (argCount > 0) {
+                                for (int j = 0; j < argCount; j++) {
+                                    if (TypeResolver.erase(TypeResolver.resolveInClass(start, params[j])) != args[j]) {
+                                        different = true;
+                                        continue;
+                                    }
+                                }
+                                if (different) {
                                     continue;
                                 }
                             }
-                            if (different) {
-                                continue;
-                            }
                         }
+                        return method;
                     }
-                    return method;
                 }
             }
         }
diff --git a/jdk/src/share/classes/java/beans/PropertyDescriptor.java b/jdk/src/share/classes/java/beans/PropertyDescriptor.java
index 2f319e1..49ddfe1 100644
--- a/jdk/src/share/classes/java/beans/PropertyDescriptor.java
+++ b/jdk/src/share/classes/java/beans/PropertyDescriptor.java
@@ -109,6 +109,10 @@
         if (writeMethodName != null && getWriteMethod() == null) {
             throw new IntrospectionException("Method not found: " + writeMethodName);
         }
+        boundInitialization(beanClass);
+    }
+
+    private void boundInitialization(Class<?> beanClass) {
         // If this class or one of its base classes allow PropertyChangeListener,
         // then we assume that any properties we discover are "bound".
         // See Introspector.getTargetPropertyInfo() method.
@@ -159,6 +163,7 @@
         setReadMethod(read);
         setWriteMethod(write);
         this.baseName = base;
+        boundInitialization(bean);
     }
 
     /**
@@ -210,12 +215,13 @@
                 // The read method was explicitly set to null.
                 return null;
             }
+            String nextMethodName = Introspector.GET_PREFIX + getBaseName();
             if (readMethodName == null) {
                 Class type = getPropertyType0();
                 if (type == boolean.class || type == null) {
                     readMethodName = Introspector.IS_PREFIX + getBaseName();
                 } else {
-                    readMethodName = Introspector.GET_PREFIX + getBaseName();
+                    readMethodName = nextMethodName;
                 }
             }
 
@@ -225,8 +231,8 @@
             // methods.  If an "is" method exists, this is the official
             // reader method so look for this one first.
             readMethod = Introspector.findMethod(cls, readMethodName, 0);
-            if (readMethod == null) {
-                readMethodName = Introspector.GET_PREFIX + getBaseName();
+            if ((readMethod == null) && !readMethodName.equals(nextMethodName)) {
+                readMethodName = nextMethodName;
                 readMethod = Introspector.findMethod(cls, readMethodName, 0);
             }
             try {
@@ -590,7 +596,7 @@
         Method yw = y.getWriteMethod();
 
         try {
-            if (yw != null && yw.getDeclaringClass() == getClass0()) {
+            if (yw != null) {
                 setWriteMethod(yw);
             } else {
                 setWriteMethod(xw);
@@ -669,7 +675,7 @@
                     throw new IntrospectionException("bad write method arg count: "
                                                      + writeMethod);
                 }
-                if (propertyType != null && propertyType != params[0]) {
+                if (propertyType != null && !params[0].isAssignableFrom(propertyType)) {
                     throw new IntrospectionException("type mismatch between read and write methods");
                 }
                 propertyType = params[0];
diff --git a/jdk/src/share/classes/java/io/FileInputStream.java b/jdk/src/share/classes/java/io/FileInputStream.java
index 36a0278..33f821f 100644
--- a/jdk/src/share/classes/java/io/FileInputStream.java
+++ b/jdk/src/share/classes/java/io/FileInputStream.java
@@ -27,6 +27,7 @@
 
 import java.nio.channels.FileChannel;
 import sun.nio.ch.FileChannelImpl;
+import sun.misc.IoTrace;
 
 
 /**
@@ -51,6 +52,9 @@
     /* File Descriptor - handle to the open file */
     private final FileDescriptor fd;
 
+    /* The path of the referenced file (null if the stream is created with a file descriptor) */
+    private final String path;
+
     private FileChannel channel = null;
 
     private final Object closeLock = new Object();
@@ -135,6 +139,7 @@
         }
         fd = new FileDescriptor();
         fd.incrementAndGetUseCount();
+        this.path = name;
         open(name);
     }
 
@@ -171,6 +176,7 @@
             security.checkRead(fdObj);
         }
         fd = fdObj;
+        path = null;
 
         /*
          * FileDescriptor is being shared by streams.
@@ -194,7 +200,18 @@
      *             file is reached.
      * @exception  IOException  if an I/O error occurs.
      */
-    public native int read() throws IOException;
+    public int read() throws IOException {
+        Object traceContext = IoTrace.fileReadBegin(path);
+        int b = 0;
+        try {
+            b = read0();
+        } finally {
+            IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1);
+        }
+        return b;
+    }
+
+    private native int read0() throws IOException;
 
     /**
      * Reads a subarray as a sequence of bytes.
@@ -217,7 +234,14 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public int read(byte b[]) throws IOException {
-        return readBytes(b, 0, b.length);
+        Object traceContext = IoTrace.fileReadBegin(path);
+        int bytesRead = 0;
+        try {
+            bytesRead = readBytes(b, 0, b.length);
+        } finally {
+            IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
+        }
+        return bytesRead;
     }
 
     /**
@@ -239,7 +263,14 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public int read(byte b[], int off, int len) throws IOException {
-        return readBytes(b, off, len);
+        Object traceContext = IoTrace.fileReadBegin(path);
+        int bytesRead = 0;
+        try {
+            bytesRead = readBytes(b, off, len);
+        } finally {
+            IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
+        }
+        return bytesRead;
     }
 
     /**
@@ -361,7 +392,7 @@
     public FileChannel getChannel() {
         synchronized (this) {
             if (channel == null) {
-                channel = FileChannelImpl.open(fd, true, false, this);
+                channel = FileChannelImpl.open(fd, path, true, false, this);
 
                 /*
                  * Increment fd's use count. Invoking the channel's close()
diff --git a/jdk/src/share/classes/java/io/FileOutputStream.java b/jdk/src/share/classes/java/io/FileOutputStream.java
index afe9367..137e756 100644
--- a/jdk/src/share/classes/java/io/FileOutputStream.java
+++ b/jdk/src/share/classes/java/io/FileOutputStream.java
@@ -27,6 +27,7 @@
 
 import java.nio.channels.FileChannel;
 import sun.nio.ch.FileChannelImpl;
+import sun.misc.IoTrace;
 
 
 /**
@@ -58,6 +59,11 @@
     private final FileDescriptor fd;
 
     /**
+     * The path of the referenced file (null if the stream is created with a file descriptor)
+     */
+    private final String path;
+
+    /**
      * True if the file is opened for append.
      */
     private final boolean append;
@@ -207,7 +213,7 @@
         }
         this.fd = new FileDescriptor();
         this.append = append;
-
+        this.path = name;
         fd.incrementAndGetUseCount();
         open(name, append);
     }
@@ -244,6 +250,7 @@
             security.checkWrite(fdObj);
         }
         this.fd = fdObj;
+        this.path = null;
         this.append = false;
 
         /*
@@ -279,7 +286,14 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public void write(int b) throws IOException {
-        write(b, append);
+        Object traceContext = IoTrace.fileWriteBegin(path);
+        int bytesWritten = 0;
+        try {
+            write(b, append);
+            bytesWritten = 1;
+        } finally {
+            IoTrace.fileWriteEnd(traceContext, bytesWritten);
+        }
     }
 
     /**
@@ -302,7 +316,14 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public void write(byte b[]) throws IOException {
-        writeBytes(b, 0, b.length, append);
+        Object traceContext = IoTrace.fileWriteBegin(path);
+        int bytesWritten = 0;
+        try {
+            writeBytes(b, 0, b.length, append);
+            bytesWritten = b.length;
+        } finally {
+            IoTrace.fileWriteEnd(traceContext, bytesWritten);
+        }
     }
 
     /**
@@ -315,7 +336,14 @@
      * @exception  IOException  if an I/O error occurs.
      */
     public void write(byte b[], int off, int len) throws IOException {
-        writeBytes(b, off, len, append);
+        Object traceContext = IoTrace.fileWriteBegin(path);
+        int bytesWritten = 0;
+        try {
+            writeBytes(b, off, len, append);
+            bytesWritten = len;
+        } finally {
+            IoTrace.fileWriteEnd(traceContext, bytesWritten);
+        }
     }
 
     /**
@@ -398,7 +426,7 @@
     public FileChannel getChannel() {
         synchronized (this) {
             if (channel == null) {
-                channel = FileChannelImpl.open(fd, false, true, append, this);
+                channel = FileChannelImpl.open(fd, path, false, true, append, this);
 
                 /*
                  * Increment fd's use count. Invoking the channel's close()
diff --git a/jdk/src/share/classes/java/io/ObjectInputStream.java b/jdk/src/share/classes/java/io/ObjectInputStream.java
index 26a764f..04705e6 100644
--- a/jdk/src/share/classes/java/io/ObjectInputStream.java
+++ b/jdk/src/share/classes/java/io/ObjectInputStream.java
@@ -2025,8 +2025,9 @@
      * This method should not be removed or its signature changed without
      * corresponding modifications to the above class.
      */
-    // REMIND: change name to something more accurate?
-    private static native ClassLoader latestUserDefinedLoader();
+    private static ClassLoader latestUserDefinedLoader() {
+        return sun.misc.VM.latestUserDefinedLoader();
+    }
 
     /**
      * Default GetField implementation.
diff --git a/jdk/src/share/classes/java/io/RandomAccessFile.java b/jdk/src/share/classes/java/io/RandomAccessFile.java
index 9ef3788..5610247 100644
--- a/jdk/src/share/classes/java/io/RandomAccessFile.java
+++ b/jdk/src/share/classes/java/io/RandomAccessFile.java
@@ -27,6 +27,7 @@
 
 import java.nio.channels.FileChannel;
 import sun.nio.ch.FileChannelImpl;
+import sun.misc.IoTrace;
 
 
 /**
@@ -62,6 +63,9 @@
     private FileChannel channel = null;
     private boolean rw;
 
+    /* The path of the referenced file */
+    private final String path;
+
     private Object closeLock = new Object();
     private volatile boolean closed = false;
 
@@ -230,6 +234,7 @@
         }
         fd = new FileDescriptor();
         fd.incrementAndGetUseCount();
+        this.path = name;
         open(name, imode);
     }
 
@@ -267,7 +272,7 @@
     public final FileChannel getChannel() {
         synchronized (this) {
             if (channel == null) {
-                channel = FileChannelImpl.open(fd, true, rw, this);
+                channel = FileChannelImpl.open(fd, path, true, rw, this);
 
                 /*
                  * FileDescriptor could be shared by FileInputStream or
@@ -315,7 +320,18 @@
      * @exception  IOException  if an I/O error occurs. Not thrown if
      *                          end-of-file has been reached.
      */
-    public native int read() throws IOException;
+    public int read() throws IOException {
+        Object traceContext = IoTrace.fileReadBegin(path);
+        int b = 0;
+        try {
+            b = read0();
+        } finally {
+            IoTrace.fileReadEnd(traceContext, b == -1 ? 0 : 1);
+        }
+        return b;
+    }
+
+    private native int read0() throws IOException;
 
     /**
      * Reads a sub array as a sequence of bytes.
@@ -324,7 +340,18 @@
      * @param len the number of bytes to read.
      * @exception IOException If an I/O error has occurred.
      */
-    private native int readBytes(byte b[], int off, int len) throws IOException;
+    private int readBytes(byte b[], int off, int len) throws IOException {
+        Object traceContext = IoTrace.fileReadBegin(path);
+        int bytesRead = 0;
+        try {
+            bytesRead = readBytes0(b, off, len);
+        } finally {
+            IoTrace.fileReadEnd(traceContext, bytesRead == -1 ? 0 : bytesRead);
+        }
+        return bytesRead;
+    }
+
+    private native int readBytes0(byte b[], int off, int len) throws IOException;
 
     /**
      * Reads up to <code>len</code> bytes of data from this file into an
@@ -463,17 +490,38 @@
      * @param      b   the <code>byte</code> to be written.
      * @exception  IOException  if an I/O error occurs.
      */
-    public native void write(int b) throws IOException;
+    public void write(int b) throws IOException {
+        Object traceContext = IoTrace.fileWriteBegin(path);
+        int bytesWritten = 0;
+        try {
+            write0(b);
+            bytesWritten = 1;
+        } finally {
+            IoTrace.fileWriteEnd(traceContext, bytesWritten);
+        }
+    }
+
+    private native void write0(int b) throws IOException;
 
     /**
      * Writes a sub array as a sequence of bytes.
      * @param b the data to be written
-
      * @param off the start offset in the data
      * @param len the number of bytes that are written
      * @exception IOException If an I/O error has occurred.
      */
-    private native void writeBytes(byte b[], int off, int len) throws IOException;
+    private void writeBytes(byte b[], int off, int len) throws IOException {
+        Object traceContext = IoTrace.fileWriteBegin(path);
+        int bytesWritten = 0;
+        try {
+            writeBytes0(b, off, len);
+            bytesWritten = len;
+        } finally {
+            IoTrace.fileWriteEnd(traceContext, bytesWritten);
+        }
+    }
+
+    private native void writeBytes0(byte b[], int off, int len) throws IOException;
 
     /**
      * Writes <code>b.length</code> bytes from the specified byte array
diff --git a/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java
deleted file mode 100644
index 2491db1..0000000
--- a/jdk/src/share/classes/java/lang/invoke/AdapterMethodHandle.java
+++ /dev/null
@@ -1,1204 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import sun.invoke.util.VerifyType;
-import sun.invoke.util.Wrapper;
-import sun.invoke.util.ValueConversions;
-import java.util.Arrays;
-import java.util.ArrayList;
-import java.util.Collections;
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
-import static java.lang.invoke.MethodHandleStatics.*;
-
-/**
- * This method handle performs simple conversion or checking of a single argument.
- * @author jrose
- */
-class AdapterMethodHandle extends BoundMethodHandle {
-
-    //MethodHandle vmtarget;   // next AMH or BMH in chain or final DMH
-    //Object       argument;   // parameter to the conversion if needed
-    //int          vmargslot;  // which argument slot is affected
-    private final int conversion;  // the type of conversion: RETYPE_ONLY, etc.
-
-    // Constructors in this class *must* be package scoped or private.
-    private AdapterMethodHandle(MethodHandle target, MethodType newType,
-                long conv, Object convArg) {
-        super(newType, convArg, newType.parameterSlotDepth(1+convArgPos(conv)));
-        this.conversion = convCode(conv);
-        // JVM might update VM-specific bits of conversion (ignore)
-        MethodHandleNatives.init(this, target, convArgPos(conv));
-    }
-    AdapterMethodHandle(MethodHandle target, MethodType newType,
-                long conv) {
-        this(target, newType, conv, null);
-    }
-
-    int getConversion() { return conversion; }
-
-    // TO DO:  When adapting another MH with a null conversion, clone
-    // the target and change its type, instead of adding another layer.
-
-    /** Can a JVM-level adapter directly implement the proposed
-     *  argument conversions, as if by fixed-arity MethodHandle.asType?
-     */
-    static boolean canPairwiseConvert(MethodType newType, MethodType oldType, int level) {
-        // same number of args, of course
-        int len = newType.parameterCount();
-        if (len != oldType.parameterCount())
-            return false;
-
-        // Check return type.
-        Class<?> exp = newType.returnType();
-        Class<?> ret = oldType.returnType();
-        if (!VerifyType.isNullConversion(ret, exp)) {
-            if (!convOpSupported(OP_COLLECT_ARGS))
-                return false;
-            if (!canConvertArgument(ret, exp, level))
-                return false;
-        }
-
-        // Check args pairwise.
-        for (int i = 0; i < len; i++) {
-            Class<?> src = newType.parameterType(i); // source type
-            Class<?> dst = oldType.parameterType(i); // destination type
-            if (!canConvertArgument(src, dst, level))
-                return false;
-        }
-
-        return true;
-    }
-
-    /** Can a JVM-level adapter directly implement the proposed
-     *  argument conversion, as if by fixed-arity MethodHandle.asType?
-     */
-    static boolean canConvertArgument(Class<?> src, Class<?> dst, int level) {
-        // ? Retool this logic to use RETYPE_ONLY, CHECK_CAST, etc., as opcodes,
-        // so we don't need to repeat so much decision making.
-        if (VerifyType.isNullConversion(src, dst)) {
-            return true;
-        } else if (convOpSupported(OP_COLLECT_ARGS)) {
-            // If we can build filters, we can convert anything to anything.
-            return true;
-        } else if (src.isPrimitive()) {
-            if (dst.isPrimitive())
-                return canPrimCast(src, dst);
-            else
-                return canBoxArgument(src, dst);
-        } else {
-            if (dst.isPrimitive())
-                return canUnboxArgument(src, dst, level);
-            else
-                return true;  // any two refs can be interconverted
-        }
-    }
-
-    /**
-     * Create a JVM-level adapter method handle to conform the given method
-     * handle to the similar newType, using only pairwise argument conversions.
-     * For each argument, convert incoming argument to the exact type needed.
-     * The argument conversions allowed are casting, boxing and unboxing,
-     * integral widening or narrowing, and floating point widening or narrowing.
-     * @param newType required call type
-     * @param target original method handle
-     * @param level which strength of conversion is allowed
-     * @return an adapter to the original handle with the desired new type,
-     *          or the original target if the types are already identical
-     *          or null if the adaptation cannot be made
-     */
-    static MethodHandle makePairwiseConvert(MethodType newType, MethodHandle target, int level) {
-        MethodType oldType = target.type();
-        if (newType == oldType)  return target;
-
-        if (!canPairwiseConvert(newType, oldType, level))
-            return null;
-        // (after this point, it is an assertion error to fail to convert)
-
-        // Find last non-trivial conversion (if any).
-        int lastConv = newType.parameterCount()-1;
-        while (lastConv >= 0) {
-            Class<?> src = newType.parameterType(lastConv); // source type
-            Class<?> dst = oldType.parameterType(lastConv); // destination type
-            if (isTrivialConversion(src, dst, level)) {
-                --lastConv;
-            } else {
-                break;
-            }
-        }
-
-        Class<?> needReturn = newType.returnType();
-        Class<?> haveReturn = oldType.returnType();
-        boolean retConv = !isTrivialConversion(haveReturn, needReturn, level);
-
-        // Now build a chain of one or more adapters.
-        MethodHandle adapter = target, adapter2;
-        MethodType midType = oldType;
-        for (int i = 0; i <= lastConv; i++) {
-            Class<?> src = newType.parameterType(i); // source type
-            Class<?> dst = midType.parameterType(i); // destination type
-            if (isTrivialConversion(src, dst, level)) {
-                // do nothing: difference is trivial
-                continue;
-            }
-            // Work the current type backward toward the desired caller type:
-            midType = midType.changeParameterType(i, src);
-            if (i == lastConv) {
-                // When doing the last (or only) real conversion,
-                // force all remaining null conversions to happen also.
-                MethodType lastMidType = newType;
-                if (retConv)  lastMidType = lastMidType.changeReturnType(haveReturn);
-                assert(VerifyType.isNullConversion(lastMidType, midType));
-                midType = lastMidType;
-            }
-
-            // Tricky case analysis follows.
-            // It parallels canConvertArgument() above.
-            if (src.isPrimitive()) {
-                if (dst.isPrimitive()) {
-                    adapter2 = makePrimCast(midType, adapter, i, dst);
-                } else {
-                    adapter2 = makeBoxArgument(midType, adapter, i, src);
-                }
-            } else {
-                if (dst.isPrimitive()) {
-                    // Caller has boxed a primitive.  Unbox it for the target.
-                    // The box type must correspond exactly to the primitive type.
-                    // This is simpler than the powerful set of widening
-                    // conversions supported by reflect.Method.invoke.
-                    // Those conversions require a big nest of if/then/else logic,
-                    // which we prefer to make a user responsibility.
-                    adapter2 = makeUnboxArgument(midType, adapter, i, dst, level);
-                } else {
-                    // Simple reference conversion.
-                    // Note:  Do not check for a class hierarchy relation
-                    // between src and dst.  In all cases a 'null' argument
-                    // will pass the cast conversion.
-                    adapter2 = makeCheckCast(midType, adapter, i, dst);
-                }
-            }
-            assert(adapter2 != null) : Arrays.asList(src, dst, midType, adapter, i, target, newType);
-            assert(adapter2.type() == midType);
-            adapter = adapter2;
-        }
-        if (retConv) {
-            adapter2 = makeReturnConversion(adapter, haveReturn, needReturn);
-            assert(adapter2 != null);
-            adapter = adapter2;
-        }
-        if (adapter.type() != newType) {
-            // Only trivial conversions remain.
-            adapter2 = makeRetypeOnly(newType, adapter);
-            assert(adapter2 != null);
-            adapter = adapter2;
-            // Actually, that's because there were no non-trivial ones:
-            assert(lastConv == -1 || retConv);
-        }
-        assert(adapter.type() == newType);
-        return adapter;
-    }
-
-    private static boolean isTrivialConversion(Class<?> src, Class<?> dst, int level) {
-        if (src == dst || dst == void.class)  return true;
-        if (!VerifyType.isNullConversion(src, dst))  return false;
-        if (level > 1)  return true;  // explicitCastArguments
-        boolean sp = src.isPrimitive();
-        boolean dp = dst.isPrimitive();
-        if (sp != dp)  return false;
-        if (sp) {
-            // in addition to being a null conversion, forbid boolean->int etc.
-            return Wrapper.forPrimitiveType(dst)
-                    .isConvertibleFrom(Wrapper.forPrimitiveType(src));
-        } else {
-            return dst.isAssignableFrom(src);
-        }
-    }
-
-    private static MethodHandle makeReturnConversion(MethodHandle target, Class<?> haveReturn, Class<?> needReturn) {
-        MethodHandle adjustReturn;
-        if (haveReturn == void.class) {
-            // synthesize a zero value for the given void
-            Object zero = Wrapper.forBasicType(needReturn).zero();
-            adjustReturn = MethodHandles.constant(needReturn, zero);
-        } else {
-            MethodType needConversion = MethodType.methodType(needReturn, haveReturn);
-            adjustReturn = MethodHandles.identity(needReturn).asType(needConversion);
-        }
-        if (!canCollectArguments(adjustReturn.type(), target.type(), 0, false)) {
-            assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-            throw new InternalError("NYI");
-        }
-        return makeCollectArguments(adjustReturn, target, 0, false);
-    }
-
-    /**
-     * Create a JVM-level adapter method handle to permute the arguments
-     * of the given method.
-     * @param newType required call type
-     * @param target original method handle
-     * @param argumentMap for each target argument, position of its source in newType
-     * @return an adapter to the original handle with the desired new type,
-     *          or the original target if the types are already identical
-     *          and the permutation is null
-     * @throws IllegalArgumentException if the adaptation cannot be made
-     *          directly by a JVM-level adapter, without help from Java code
-     */
-    static MethodHandle makePermutation(MethodType newType, MethodHandle target,
-                int[] argumentMap) {
-        MethodType oldType = target.type();
-        boolean nullPermutation = true;
-        for (int i = 0; i < argumentMap.length; i++) {
-            int pos = argumentMap[i];
-            if (pos != i)
-                nullPermutation = false;
-            if (pos < 0 || pos >= newType.parameterCount()) {
-                argumentMap = new int[0]; break;
-            }
-        }
-        if (argumentMap.length != oldType.parameterCount())
-            throw newIllegalArgumentException("bad permutation: "+Arrays.toString(argumentMap));
-        if (nullPermutation) {
-            MethodHandle res = makePairwiseConvert(newType, target, 0);
-            // well, that was easy
-            if (res == null)
-                throw newIllegalArgumentException("cannot convert pairwise: "+newType);
-            return res;
-        }
-
-        // Check return type.  (Not much can be done with it.)
-        Class<?> exp = newType.returnType();
-        Class<?> ret = oldType.returnType();
-        if (!VerifyType.isNullConversion(ret, exp))
-            throw newIllegalArgumentException("bad return conversion for "+newType);
-
-        // See if the argument types match up.
-        for (int i = 0; i < argumentMap.length; i++) {
-            int j = argumentMap[i];
-            Class<?> src = newType.parameterType(j);
-            Class<?> dst = oldType.parameterType(i);
-            if (!VerifyType.isNullConversion(src, dst))
-                throw newIllegalArgumentException("bad argument #"+j+" conversion for "+newType);
-        }
-
-        // Now figure out a nice mix of SWAP, ROT, DUP, and DROP adapters.
-        // A workable greedy algorithm is as follows:
-        // Drop unused outgoing arguments (right to left: shallowest first).
-        // Duplicate doubly-used outgoing arguments (left to right: deepest first).
-        // Then the remaining problem is a true argument permutation.
-        // Marshal the outgoing arguments as required from left to right.
-        // That is, find the deepest outgoing stack position that does not yet
-        // have the correct argument value, and correct at least that position
-        // by swapping or rotating in the misplaced value (from a shallower place).
-        // If the misplaced value is followed by one or more consecutive values
-        // (also misplaced)  issue a rotation which brings as many as possible
-        // into position.  Otherwise make progress with either a swap or a
-        // rotation.  Prefer the swap as cheaper, but do not use it if it
-        // breaks a slot pair.  Prefer the rotation over the swap if it would
-        // preserve more consecutive values shallower than the target position.
-        // When more than one rotation will work (because the required value
-        // is already adjacent to the target position), then use a rotation
-        // which moves the old value in the target position adjacent to
-        // one of its consecutive values.  Also, prefer shorter rotation
-        // spans, since they use fewer memory cycles for shuffling.
-
-        throw new UnsupportedOperationException("NYI");
-    }
-
-    private static byte basicType(Class<?> type) {
-        if (type == null)  return T_VOID;
-        switch (Wrapper.forBasicType(type)) {
-            case BOOLEAN:  return T_BOOLEAN;
-            case CHAR:     return T_CHAR;
-            case FLOAT:    return T_FLOAT;
-            case DOUBLE:   return T_DOUBLE;
-            case BYTE:     return T_BYTE;
-            case SHORT:    return T_SHORT;
-            case INT:      return T_INT;
-            case LONG:     return T_LONG;
-            case OBJECT:   return T_OBJECT;
-            case VOID:     return T_VOID;
-        }
-        return 99; // T_ILLEGAL or some such
-    }
-
-    /** Number of stack slots for the given type.
-     *  Two for T_DOUBLE and T_FLOAT, one for the rest.
-     */
-    private static int type2size(int type) {
-        assert(type >= T_BOOLEAN && type <= T_OBJECT);
-        return (type == T_LONG || type == T_DOUBLE) ? 2 : 1;
-    }
-    private static int type2size(Class<?> type) {
-        return type2size(basicType(type));
-    }
-
-    /** The given stackMove is the number of slots pushed.
-     * It might be negative.  Scale it (multiply) by the
-     * VM's notion of how an address changes with a push,
-     * to get the raw SP change for stackMove.
-     * Then shift and mask it into the correct field.
-     */
-    private static long insertStackMove(int stackMove) {
-        // following variable must be long to avoid sign extension after '<<'
-        long spChange = stackMove * MethodHandleNatives.JVM_STACK_MOVE_UNIT;
-        return (spChange & CONV_STACK_MOVE_MASK) << CONV_STACK_MOVE_SHIFT;
-    }
-
-    static int extractStackMove(int convOp) {
-        int spChange = convOp >> CONV_STACK_MOVE_SHIFT;
-        return spChange / MethodHandleNatives.JVM_STACK_MOVE_UNIT;
-    }
-
-    static int extractStackMove(MethodHandle target) {
-        if (target instanceof AdapterMethodHandle) {
-            AdapterMethodHandle amh = (AdapterMethodHandle) target;
-            return extractStackMove(amh.getConversion());
-        } else {
-            return 0;
-        }
-    }
-
-    /** Construct an adapter conversion descriptor for a single-argument conversion. */
-    private static long makeConv(int convOp, int argnum, int src, int dest) {
-        assert(src  == (src  & CONV_TYPE_MASK));
-        assert(dest == (dest & CONV_TYPE_MASK));
-        assert(convOp >= OP_CHECK_CAST && convOp <= OP_PRIM_TO_REF || convOp == OP_COLLECT_ARGS);
-        int stackMove = type2size(dest) - type2size(src);
-        return ((long) argnum << 32 |
-                (long) convOp << CONV_OP_SHIFT |
-                (int)  src    << CONV_SRC_TYPE_SHIFT |
-                (int)  dest   << CONV_DEST_TYPE_SHIFT |
-                insertStackMove(stackMove)
-                );
-    }
-    private static long makeDupConv(int convOp, int argnum, int stackMove) {
-        // simple argument motion, requiring one slot to specify
-        assert(convOp == OP_DUP_ARGS || convOp == OP_DROP_ARGS);
-        byte src = 0, dest = 0;
-        return ((long) argnum << 32 |
-                (long) convOp << CONV_OP_SHIFT |
-                (int)  src    << CONV_SRC_TYPE_SHIFT |
-                (int)  dest   << CONV_DEST_TYPE_SHIFT |
-                insertStackMove(stackMove)
-                );
-    }
-    private static long makeSwapConv(int convOp, int srcArg, byte srcType, int destSlot, byte destType) {
-        // more complex argument motion, requiring two slots to specify
-        assert(convOp == OP_SWAP_ARGS || convOp == OP_ROT_ARGS);
-        return ((long) srcArg << 32 |
-                (long) convOp << CONV_OP_SHIFT |
-                (int)  srcType << CONV_SRC_TYPE_SHIFT |
-                (int)  destType << CONV_DEST_TYPE_SHIFT |
-                (int)  destSlot << CONV_VMINFO_SHIFT
-                );
-    }
-    private static long makeSpreadConv(int convOp, int argnum, int src, int dest, int stackMove) {
-        // spreading or collecting, at a particular slot location
-        assert(convOp == OP_SPREAD_ARGS || convOp == OP_COLLECT_ARGS || convOp == OP_FOLD_ARGS);
-        // src  = spread ? T_OBJECT (for array)  : common type of collected args (else void)
-        // dest = spread ? element type of array : result type of collector (can be void)
-        return ((long) argnum << 32 |
-                (long) convOp << CONV_OP_SHIFT |
-                (int)  src    << CONV_SRC_TYPE_SHIFT |
-                (int)  dest   << CONV_DEST_TYPE_SHIFT |
-                insertStackMove(stackMove)
-                );
-    }
-    static long makeConv(int convOp) {
-        assert(convOp == OP_RETYPE_ONLY || convOp == OP_RETYPE_RAW);
-        return ((long)-1 << 32) | (convOp << CONV_OP_SHIFT);   // stackMove, src, dst all zero
-    }
-    private static int convCode(long conv) {
-        return (int)conv;
-    }
-    private static int convArgPos(long conv) {
-        return (int)(conv >>> 32);
-    }
-    private static boolean convOpSupported(int convOp) {
-        assert(convOp >= 0 && convOp <= CONV_OP_LIMIT);
-        return ((1<<convOp) & MethodHandleNatives.CONV_OP_IMPLEMENTED_MASK) != 0;
-    }
-
-    /** One of OP_RETYPE_ONLY, etc. */
-    int conversionOp() { return (conversion & CONV_OP_MASK) >> CONV_OP_SHIFT; }
-
-    /* Return one plus the position of the first non-trivial difference
-     * between the given types.  This is not a symmetric operation;
-     * we are considering adapting the targetType to adapterType.
-     * Trivial differences are those which could be ignored by the JVM
-     * without subverting the verifier.  Otherwise, adaptable differences
-     * are ones for which we could create an adapter to make the type change.
-     * Return zero if there are no differences (other than trivial ones).
-     * Return 1+N if N is the only adaptable argument difference.
-     * Return the -2-N where N is the first of several adaptable
-     * argument differences.
-     * Return -1 if there there are differences which are not adaptable.
-     */
-    private static int diffTypes(MethodType adapterType,
-                                 MethodType targetType,
-                                 boolean raw) {
-        int diff;
-        diff = diffReturnTypes(adapterType, targetType, raw);
-        if (diff != 0)  return diff;
-        int nargs = adapterType.parameterCount();
-        if (nargs != targetType.parameterCount())
-            return -1;
-        diff = diffParamTypes(adapterType, 0, targetType, 0, nargs, raw);
-        //System.out.println("diff "+adapterType);
-        //System.out.println("  "+diff+" "+targetType);
-        return diff;
-    }
-    private static int diffReturnTypes(MethodType adapterType,
-                                       MethodType targetType,
-                                       boolean raw) {
-        Class<?> src = targetType.returnType();
-        Class<?> dst = adapterType.returnType();
-        if ((!raw
-             ? VerifyType.canPassUnchecked(src, dst)
-             : VerifyType.canPassRaw(src, dst)
-             ) > 0)
-            return 0;  // no significant difference
-        if (raw && !src.isPrimitive() && !dst.isPrimitive())
-            return 0;  // can force a reference return (very carefully!)
-        //if (false)  return 1;  // never adaptable!
-        return -1;  // some significant difference
-    }
-    private static int diffParamTypes(MethodType adapterType, int astart,
-                                      MethodType targetType, int tstart,
-                                      int nargs, boolean raw) {
-        assert(nargs >= 0);
-        int res = 0;
-        for (int i = 0; i < nargs; i++) {
-            Class<?> src  = adapterType.parameterType(astart+i);
-            Class<?> dest = targetType.parameterType(tstart+i);
-            if ((!raw
-                 ? VerifyType.canPassUnchecked(src, dest)
-                 : VerifyType.canPassRaw(src, dest)
-                ) <= 0) {
-                // found a difference; is it the only one so far?
-                if (res != 0)
-                    return -1-res; // return -2-i for prev. i
-                res = 1+i;
-            }
-        }
-        return res;
-    }
-
-    /** Can a retyping adapter (alone) validly convert the target to newType? */
-    static boolean canRetypeOnly(MethodType newType, MethodType targetType) {
-        return canRetype(newType, targetType, false);
-    }
-    /** Can a retyping adapter (alone) convert the target to newType?
-     *  It is allowed to widen subword types and void to int, to make bitwise
-     *  conversions between float/int and double/long, and to perform unchecked
-     *  reference conversions on return.  This last feature requires that the
-     *  caller be trusted, and perform explicit cast conversions on return values.
-     */
-    static boolean canRetypeRaw(MethodType newType, MethodType targetType) {
-        return canRetype(newType, targetType, true);
-    }
-    static boolean canRetype(MethodType newType, MethodType targetType, boolean raw) {
-        if (!convOpSupported(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY))  return false;
-        int diff = diffTypes(newType, targetType, raw);
-        // %%% This assert is too strong.  Factor diff into VerifyType and reconcile.
-        assert(raw || (diff == 0) == VerifyType.isNullConversion(newType, targetType));
-        return diff == 0;
-    }
-
-    /** Factory method:  Performs no conversions; simply retypes the adapter.
-     *  Allows unchecked argument conversions pairwise, if they are safe.
-     *  Returns null if not possible.
-     */
-    static MethodHandle makeRetypeOnly(MethodType newType, MethodHandle target) {
-        return makeRetype(newType, target, false);
-    }
-    static MethodHandle makeRetypeRaw(MethodType newType, MethodHandle target) {
-        return makeRetype(newType, target, true);
-    }
-    static MethodHandle makeRetype(MethodType newType, MethodHandle target, boolean raw) {
-        MethodType oldType = target.type();
-        if (oldType == newType)  return target;
-        if (!canRetype(newType, oldType, raw))
-            return null;
-        // TO DO:  clone the target guy, whatever he is, with new type.
-        return new AdapterMethodHandle(target, newType, makeConv(raw ? OP_RETYPE_RAW : OP_RETYPE_ONLY));
-    }
-
-    static MethodHandle makeVarargsCollector(MethodHandle target, Class<?> arrayType) {
-        MethodType type = target.type();
-        int last = type.parameterCount() - 1;
-        if (type.parameterType(last) != arrayType)
-            target = target.asType(type.changeParameterType(last, arrayType));
-        target = target.asFixedArity();  // make sure this attribute is turned off
-        return new AsVarargsCollector(target, arrayType);
-    }
-
-    static class AsVarargsCollector extends AdapterMethodHandle {
-        final MethodHandle target;
-        final Class<?> arrayType;
-        MethodHandle cache;
-
-        AsVarargsCollector(MethodHandle target, Class<?> arrayType) {
-            super(target, target.type(), makeConv(OP_RETYPE_ONLY));
-            this.target = target;
-            this.arrayType = arrayType;
-            this.cache = target.asCollector(arrayType, 0);
-        }
-
-        @Override
-        public boolean isVarargsCollector() {
-            return true;
-        }
-
-        @Override
-        public MethodHandle asFixedArity() {
-            return target;
-        }
-
-        @Override
-        public MethodHandle asType(MethodType newType) {
-            MethodType type = this.type();
-            int collectArg = type.parameterCount() - 1;
-            int newArity = newType.parameterCount();
-            if (newArity == collectArg+1 &&
-                type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
-                // if arity and trailing parameter are compatible, do normal thing
-                return super.asType(newType);
-            }
-            // check cache
-            if (cache.type().parameterCount() == newArity)
-                return cache.asType(newType);
-            // build and cache a collector
-            int arrayLength = newArity - collectArg;
-            MethodHandle collector;
-            try {
-                collector = target.asCollector(arrayType, arrayLength);
-            } catch (IllegalArgumentException ex) {
-                throw new WrongMethodTypeException("cannot build collector");
-            }
-            cache = collector;
-            return collector.asType(newType);
-        }
-    }
-
-    /** Can a checkcast adapter validly convert the target to newType?
-     *  The JVM supports all kind of reference casts, even silly ones.
-     */
-    static boolean canCheckCast(MethodType newType, MethodType targetType,
-                int arg, Class<?> castType) {
-        if (!convOpSupported(OP_CHECK_CAST))  return false;
-        Class<?> src = newType.parameterType(arg);
-        Class<?> dst = targetType.parameterType(arg);
-        if (!canCheckCast(src, castType)
-                || !VerifyType.isNullConversion(castType, dst))
-            return false;
-        int diff = diffTypes(newType, targetType, false);
-        return (diff == arg+1) || (diff == 0);  // arg is sole non-trivial diff
-    }
-    /** Can an primitive conversion adapter validly convert src to dst? */
-    static boolean canCheckCast(Class<?> src, Class<?> dst) {
-        return (!src.isPrimitive() && !dst.isPrimitive());
-    }
-
-    /** Factory method:  Forces a cast at the given argument.
-     *  The castType is the target of the cast, and can be any type
-     *  with a null conversion to the corresponding target parameter.
-     *  Return null if this cannot be done.
-     */
-    static MethodHandle makeCheckCast(MethodType newType, MethodHandle target,
-                int arg, Class<?> castType) {
-        if (!canCheckCast(newType, target.type(), arg, castType))
-            return null;
-        long conv = makeConv(OP_CHECK_CAST, arg, T_OBJECT, T_OBJECT);
-        return new AdapterMethodHandle(target, newType, conv, castType);
-    }
-
-    /** Can an primitive conversion adapter validly convert the target to newType?
-     *  The JVM currently supports all conversions except those between
-     *  floating and integral types.
-     */
-    static boolean canPrimCast(MethodType newType, MethodType targetType,
-                int arg, Class<?> convType) {
-        if (!convOpSupported(OP_PRIM_TO_PRIM))  return false;
-        Class<?> src = newType.parameterType(arg);
-        Class<?> dst = targetType.parameterType(arg);
-        if (!canPrimCast(src, convType)
-                || !VerifyType.isNullConversion(convType, dst))
-            return false;
-        int diff = diffTypes(newType, targetType, false);
-        return (diff == arg+1);  // arg is sole non-trivial diff
-    }
-    /** Can an primitive conversion adapter validly convert src to dst? */
-    static boolean canPrimCast(Class<?> src, Class<?> dst) {
-        if (src == dst || !src.isPrimitive() || !dst.isPrimitive()) {
-            return false;
-        } else {
-            boolean sflt = Wrapper.forPrimitiveType(src).isFloating();
-            boolean dflt = Wrapper.forPrimitiveType(dst).isFloating();
-            return !(sflt | dflt);  // no float support at present
-        }
-    }
-
-    /** Factory method:  Truncate the given argument with zero or sign extension,
-     *  and/or convert between single and doubleword versions of integer or float.
-     *  The convType is the target of the conversion, and can be any type
-     *  with a null conversion to the corresponding target parameter.
-     *  Return null if this cannot be done.
-     */
-    static MethodHandle makePrimCast(MethodType newType, MethodHandle target,
-                int arg, Class<?> convType) {
-        Class<?> src = newType.parameterType(arg);
-        if (canPrimCast(src, convType))
-            return makePrimCastOnly(newType, target, arg, convType);
-        Class<?> dst = convType;
-        boolean sflt = Wrapper.forPrimitiveType(src).isFloating();
-        boolean dflt = Wrapper.forPrimitiveType(dst).isFloating();
-        if (sflt | dflt) {
-            MethodHandle convMethod;
-            if (sflt)
-                convMethod = ((src == double.class)
-                        ? ValueConversions.convertFromDouble(dst)
-                        : ValueConversions.convertFromFloat(dst));
-            else
-                convMethod = ((dst == double.class)
-                        ? ValueConversions.convertToDouble(src)
-                        : ValueConversions.convertToFloat(src));
-            long conv = makeConv(OP_COLLECT_ARGS, arg, basicType(src), basicType(dst));
-            return new AdapterMethodHandle(target, newType, conv, convMethod);
-        }
-        throw new InternalError("makePrimCast");
-    }
-    static MethodHandle makePrimCastOnly(MethodType newType, MethodHandle target,
-                int arg, Class<?> convType) {
-        MethodType oldType = target.type();
-        if (!canPrimCast(newType, oldType, arg, convType))
-            return null;
-        Class<?> src = newType.parameterType(arg);
-        long conv = makeConv(OP_PRIM_TO_PRIM, arg, basicType(src), basicType(convType));
-        return new AdapterMethodHandle(target, newType, conv);
-    }
-
-    /** Can an unboxing conversion validly convert src to dst?
-     *  The JVM currently supports all kinds of casting and unboxing.
-     *  The convType is the unboxed type; it can be either a primitive or wrapper.
-     */
-    static boolean canUnboxArgument(MethodType newType, MethodType targetType,
-                int arg, Class<?> convType, int level) {
-        if (!convOpSupported(OP_REF_TO_PRIM))  return false;
-        Class<?> src = newType.parameterType(arg);
-        Class<?> dst = targetType.parameterType(arg);
-        Class<?> boxType = Wrapper.asWrapperType(convType);
-        convType = Wrapper.asPrimitiveType(convType);
-        if (!canCheckCast(src, boxType)
-                || boxType == convType
-                || !VerifyType.isNullConversion(convType, dst))
-            return false;
-        int diff = diffTypes(newType, targetType, false);
-        return (diff == arg+1);  // arg is sole non-trivial diff
-    }
-    /** Can an primitive unboxing adapter validly convert src to dst? */
-    static boolean canUnboxArgument(Class<?> src, Class<?> dst, int level) {
-        assert(dst.isPrimitive());
-        // if we have JVM support for boxing, we can also do complex unboxing
-        if (convOpSupported(OP_PRIM_TO_REF))  return true;
-        Wrapper dw = Wrapper.forPrimitiveType(dst);
-        // Level 0 means cast and unbox.  This works on any reference.
-        if (level == 0)  return !src.isPrimitive();
-        assert(level >= 0 && level <= 2);
-        // Levels 1 and 2 allow widening and/or narrowing conversions.
-        // These are not supported directly by the JVM.
-        // But if the input reference is monomorphic, we can do it.
-        return dw.wrapperType() == src;
-    }
-
-    /** Factory method:  Unbox the given argument.
-     *  Return null if this cannot be done.
-     */
-    static MethodHandle makeUnboxArgument(MethodType newType, MethodHandle target,
-                int arg, Class<?> convType, int level) {
-        MethodType oldType = target.type();
-        Class<?> src = newType.parameterType(arg);
-        Class<?> dst = oldType.parameterType(arg);
-        Class<?> boxType = Wrapper.asWrapperType(convType);
-        Class<?> primType = Wrapper.asPrimitiveType(convType);
-        if (!canUnboxArgument(newType, oldType, arg, convType, level))
-            return null;
-        MethodType castDone = newType;
-        if (!VerifyType.isNullConversion(src, boxType)) {
-            // Examples:  Object->int, Number->int, Comparable->int; Byte->int, Character->int
-            if (level != 0) {
-                // must include additional conversions
-                if (src == Object.class || !Wrapper.isWrapperType(src)) {
-                    // src must be examined at runtime, to detect Byte, Character, etc.
-                    MethodHandle unboxMethod = (level == 1
-                                                ? ValueConversions.unbox(dst)
-                                                : ValueConversions.unboxCast(dst));
-                    long conv = makeConv(OP_COLLECT_ARGS, arg, basicType(src), basicType(dst));
-                    return new AdapterMethodHandle(target, newType, conv, unboxMethod);
-                }
-                // Example: Byte->int
-                // Do this by reformulating the problem to Byte->byte.
-                Class<?> srcPrim = Wrapper.forWrapperType(src).primitiveType();
-                MethodType midType = newType.changeParameterType(arg, srcPrim);
-                MethodHandle fixPrim; // makePairwiseConvert(midType, target, 0);
-                if (canPrimCast(midType, oldType, arg, dst))
-                    fixPrim = makePrimCast(midType, target, arg, dst);
-                else
-                    fixPrim = target;
-                return makeUnboxArgument(newType, fixPrim, arg, srcPrim, 0);
-            }
-            castDone = newType.changeParameterType(arg, boxType);
-        }
-        long conv = makeConv(OP_REF_TO_PRIM, arg, T_OBJECT, basicType(primType));
-        MethodHandle adapter = new AdapterMethodHandle(target, castDone, conv, boxType);
-        if (castDone == newType)
-            return adapter;
-        return makeCheckCast(newType, adapter, arg, boxType);
-    }
-
-    /** Can a boxing conversion validly convert src to dst? */
-    static boolean canBoxArgument(MethodType newType, MethodType targetType,
-                int arg, Class<?> convType) {
-        if (!convOpSupported(OP_PRIM_TO_REF))  return false;
-        Class<?> src = newType.parameterType(arg);
-        Class<?> dst = targetType.parameterType(arg);
-        Class<?> boxType = Wrapper.asWrapperType(convType);
-        convType = Wrapper.asPrimitiveType(convType);
-        if (!canCheckCast(boxType, dst)
-                || boxType == convType
-                || !VerifyType.isNullConversion(src, convType))
-            return false;
-        int diff = diffTypes(newType, targetType, false);
-        return (diff == arg+1);  // arg is sole non-trivial diff
-    }
-
-    /** Can an primitive boxing adapter validly convert src to dst? */
-    static boolean canBoxArgument(Class<?> src, Class<?> dst) {
-        if (!convOpSupported(OP_PRIM_TO_REF))  return false;
-        return (src.isPrimitive() && !dst.isPrimitive());
-    }
-
-    /** Factory method:  Box the given argument.
-     *  Return null if this cannot be done.
-     */
-    static MethodHandle makeBoxArgument(MethodType newType, MethodHandle target,
-                int arg, Class<?> convType) {
-        MethodType oldType = target.type();
-        Class<?> src = newType.parameterType(arg);
-        Class<?> dst = oldType.parameterType(arg);
-        Class<?> boxType = Wrapper.asWrapperType(convType);
-        Class<?> primType = Wrapper.asPrimitiveType(convType);
-        if (!canBoxArgument(newType, oldType, arg, convType)) {
-            return null;
-        }
-        if (!VerifyType.isNullConversion(boxType, dst))
-            target = makeCheckCast(oldType.changeParameterType(arg, boxType), target, arg, dst);
-        MethodHandle boxerMethod = ValueConversions.box(Wrapper.forPrimitiveType(primType));
-        long conv = makeConv(OP_PRIM_TO_REF, arg, basicType(primType), T_OBJECT);
-        return new AdapterMethodHandle(target, newType, conv, boxerMethod);
-    }
-
-    /** Can an adapter simply drop arguments to convert the target to newType? */
-    static boolean canDropArguments(MethodType newType, MethodType targetType,
-                int dropArgPos, int dropArgCount) {
-        if (dropArgCount == 0)
-            return canRetypeOnly(newType, targetType);
-        if (!convOpSupported(OP_DROP_ARGS))  return false;
-        if (diffReturnTypes(newType, targetType, false) != 0)
-            return false;
-        int nptypes = newType.parameterCount();
-        // parameter types must be the same up to the drop point
-        if (dropArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, dropArgPos, false) != 0)
-            return false;
-        int afterPos = dropArgPos + dropArgCount;
-        int afterCount = nptypes - afterPos;
-        if (dropArgPos < 0 || dropArgPos >= nptypes ||
-            dropArgCount < 1 || afterPos > nptypes ||
-            targetType.parameterCount() != nptypes - dropArgCount)
-            return false;
-        // parameter types after the drop point must also be the same
-        if (afterCount != 0 && diffParamTypes(newType, afterPos, targetType, dropArgPos, afterCount, false) != 0)
-            return false;
-        return true;
-    }
-
-    /** Factory method:  Drop selected arguments.
-     *  Allow unchecked retyping of remaining arguments, pairwise.
-     *  Return null if this is not possible.
-     */
-    static MethodHandle makeDropArguments(MethodType newType, MethodHandle target,
-                int dropArgPos, int dropArgCount) {
-        if (dropArgCount == 0)
-            return makeRetypeOnly(newType, target);
-        if (!canDropArguments(newType, target.type(), dropArgPos, dropArgCount))
-            return null;
-        // in  arglist: [0: ...keep1 | dpos: drop... | dpos+dcount: keep2... ]
-        // out arglist: [0: ...keep1 |                        dpos: keep2... ]
-        int keep2InPos  = dropArgPos + dropArgCount;
-        int dropSlot    = newType.parameterSlotDepth(keep2InPos);
-        int keep1InSlot = newType.parameterSlotDepth(dropArgPos);
-        int slotCount   = keep1InSlot - dropSlot;
-        assert(slotCount >= dropArgCount);
-        assert(target.type().parameterSlotCount() + slotCount == newType.parameterSlotCount());
-        long conv = makeDupConv(OP_DROP_ARGS, dropArgPos + dropArgCount - 1, -slotCount);
-        return new AdapterMethodHandle(target, newType, conv);
-    }
-
-    /** Can an adapter duplicate an argument to convert the target to newType? */
-    static boolean canDupArguments(MethodType newType, MethodType targetType,
-                int dupArgPos, int dupArgCount) {
-        if (!convOpSupported(OP_DUP_ARGS))  return false;
-        if (diffReturnTypes(newType, targetType, false) != 0)
-            return false;
-        int nptypes = newType.parameterCount();
-        if (dupArgCount < 0 || dupArgPos + dupArgCount > nptypes)
-            return false;
-        if (targetType.parameterCount() != nptypes + dupArgCount)
-            return false;
-        // parameter types must be the same up to the duplicated arguments
-        if (diffParamTypes(newType, 0, targetType, 0, nptypes, false) != 0)
-            return false;
-        // duplicated types must be, well, duplicates
-        if (diffParamTypes(newType, dupArgPos, targetType, nptypes, dupArgCount, false) != 0)
-            return false;
-        return true;
-    }
-
-    /** Factory method:  Duplicate the selected argument.
-     *  Return null if this is not possible.
-     */
-    static MethodHandle makeDupArguments(MethodType newType, MethodHandle target,
-                int dupArgPos, int dupArgCount) {
-        if (!canDupArguments(newType, target.type(), dupArgPos, dupArgCount))
-            return null;
-        if (dupArgCount == 0)
-            return target;
-        // in  arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... ]
-        // out arglist: [0: ...keep1 | dpos: dup... | dpos+dcount: keep2... | dup... ]
-        int keep2InPos  = dupArgPos + dupArgCount;
-        int dupSlot     = newType.parameterSlotDepth(keep2InPos);
-        int keep1InSlot = newType.parameterSlotDepth(dupArgPos);
-        int slotCount   = keep1InSlot - dupSlot;
-        assert(target.type().parameterSlotCount() - slotCount == newType.parameterSlotCount());
-        long conv = makeDupConv(OP_DUP_ARGS, dupArgPos + dupArgCount - 1, slotCount);
-        return new AdapterMethodHandle(target, newType, conv);
-    }
-
-    /** Can an adapter swap two arguments to convert the target to newType? */
-    static boolean canSwapArguments(MethodType newType, MethodType targetType,
-                int swapArg1, int swapArg2) {
-        if (!convOpSupported(OP_SWAP_ARGS))  return false;
-        if (diffReturnTypes(newType, targetType, false) != 0)
-            return false;
-        if (swapArg1 >= swapArg2)  return false;  // caller resp
-        int nptypes = newType.parameterCount();
-        if (targetType.parameterCount() != nptypes)
-            return false;
-        if (swapArg1 < 0 || swapArg2 >= nptypes)
-            return false;
-        if (diffParamTypes(newType, 0, targetType, 0, swapArg1, false) != 0)
-            return false;
-        if (diffParamTypes(newType, swapArg1, targetType, swapArg2, 1, false) != 0)
-            return false;
-        if (diffParamTypes(newType, swapArg1+1, targetType, swapArg1+1, swapArg2-swapArg1-1, false) != 0)
-            return false;
-        if (diffParamTypes(newType, swapArg2, targetType, swapArg1, 1, false) != 0)
-            return false;
-        if (diffParamTypes(newType, swapArg2+1, targetType, swapArg2+1, nptypes-swapArg2-1, false) != 0)
-            return false;
-        return true;
-    }
-
-    /** Factory method:  Swap the selected arguments.
-     *  Return null if this is not possible.
-     */
-    static MethodHandle makeSwapArguments(MethodType newType, MethodHandle target,
-                int swapArg1, int swapArg2) {
-        if (swapArg1 == swapArg2)
-            return target;
-        if (swapArg1 > swapArg2) { int t = swapArg1; swapArg1 = swapArg2; swapArg2 = t; }
-        if (type2size(newType.parameterType(swapArg1)) !=
-            type2size(newType.parameterType(swapArg2))) {
-            // turn a swap into a pair of rotates:
-            // [x a b c y] rot2(-1,argc=5) => [a b c y x] rot1(+1,argc=4) => target[y a b c x]
-            int argc = swapArg2 - swapArg1 + 1;
-            final int ROT = 1;
-            ArrayList<Class<?>> rot1Params = new ArrayList<Class<?>>(target.type().parameterList());
-            Collections.rotate(rot1Params.subList(swapArg1, swapArg1 + argc), -ROT);
-            MethodType rot1Type = MethodType.methodType(target.type().returnType(), rot1Params);
-            MethodHandle rot1 = makeRotateArguments(rot1Type, target, swapArg1, argc, +ROT);
-            assert(rot1 != null);
-            if (argc == 2)  return rot1;
-            MethodHandle rot2 = makeRotateArguments(newType, rot1, swapArg1, argc-1, -ROT);
-            assert(rot2 != null);
-            return rot2;
-        }
-        if (!canSwapArguments(newType, target.type(), swapArg1, swapArg2))
-            return null;
-        Class<?> type1 = newType.parameterType(swapArg1);
-        Class<?> type2 = newType.parameterType(swapArg2);
-        // in  arglist: [0: ...keep1 | pos1: a1 | pos1+1: keep2... | pos2: a2 | pos2+1: keep3... ]
-        // out arglist: [0: ...keep1 | pos1: a2 | pos1+1: keep2... | pos2: a1 | pos2+1: keep3... ]
-        int swapSlot2  = newType.parameterSlotDepth(swapArg2 + 1);
-        long conv = makeSwapConv(OP_SWAP_ARGS, swapArg1, basicType(type1), swapSlot2, basicType(type2));
-        return new AdapterMethodHandle(target, newType, conv);
-    }
-
-    static int positiveRotation(int argCount, int rotateBy) {
-        assert(argCount > 0);
-        if (rotateBy >= 0) {
-            if (rotateBy < argCount)
-                return rotateBy;
-            return rotateBy % argCount;
-        } else if (rotateBy >= -argCount) {
-            return rotateBy + argCount;
-        } else {
-            return (-1-((-1-rotateBy) % argCount)) + argCount;
-        }
-    }
-
-    final static int MAX_ARG_ROTATION = 1;
-
-    /** Can an adapter rotate arguments to convert the target to newType? */
-    static boolean canRotateArguments(MethodType newType, MethodType targetType,
-                int firstArg, int argCount, int rotateBy) {
-        if (!convOpSupported(OP_ROT_ARGS))  return false;
-        rotateBy = positiveRotation(argCount, rotateBy);
-        if (rotateBy == 0)  return false;  // no rotation
-        if (rotateBy > MAX_ARG_ROTATION && rotateBy < argCount - MAX_ARG_ROTATION)
-            return false;  // too many argument positions
-        // Rotate incoming args right N to the out args, N in 1..(argCouunt-1).
-        if (diffReturnTypes(newType, targetType, false) != 0)
-            return false;
-        int nptypes = newType.parameterCount();
-        if (targetType.parameterCount() != nptypes)
-            return false;
-        if (firstArg < 0 || firstArg >= nptypes)  return false;
-        int argLimit = firstArg + argCount;
-        if (argLimit > nptypes)  return false;
-        if (diffParamTypes(newType, 0, targetType, 0, firstArg, false) != 0)
-            return false;
-        int newChunk1 = argCount - rotateBy, newChunk2 = rotateBy;
-        // swap new chunk1 with target chunk2
-        if (diffParamTypes(newType, firstArg, targetType, argLimit-newChunk1, newChunk1, false) != 0)
-            return false;
-        // swap new chunk2 with target chunk1
-        if (diffParamTypes(newType, firstArg+newChunk1, targetType, firstArg, newChunk2, false) != 0)
-            return false;
-        return true;
-    }
-
-    /** Factory method:  Rotate the selected argument range.
-     *  Return null if this is not possible.
-     */
-    static MethodHandle makeRotateArguments(MethodType newType, MethodHandle target,
-                int firstArg, int argCount, int rotateBy) {
-        rotateBy = positiveRotation(argCount, rotateBy);
-        if (!canRotateArguments(newType, target.type(), firstArg, argCount, rotateBy))
-            return null;
-        // Decide whether it should be done as a right or left rotation,
-        // on the JVM stack.  Return the number of stack slots to rotate by,
-        // positive if right, negative if left.
-        int limit = firstArg + argCount;
-        int depth0 = newType.parameterSlotDepth(firstArg);
-        int depth1 = newType.parameterSlotDepth(limit-rotateBy);
-        int depth2 = newType.parameterSlotDepth(limit);
-        int chunk1Slots = depth0 - depth1; assert(chunk1Slots > 0);
-        int chunk2Slots = depth1 - depth2; assert(chunk2Slots > 0);
-        // From here on out, it assumes a single-argument shift.
-        assert(MAX_ARG_ROTATION == 1);
-        int srcArg, dstArg;
-        int dstSlot;
-        int moveChunk;
-        if (rotateBy == 1) {
-            // Rotate right/down N (rotateBy = +N, N small, c2 small):
-            // in  arglist: [0: ...keep1 | arg1: c1...  | limit-N: c2 | limit: keep2... ]
-            // out arglist: [0: ...keep1 | arg1: c2 | arg1+N: c1...   | limit: keep2... ]
-            srcArg = limit-1;
-            dstArg = firstArg;
-            //dstSlot = depth0 - chunk2Slots;  //chunk2Slots is not relevant
-            dstSlot = depth0 + MethodHandleNatives.OP_ROT_ARGS_DOWN_LIMIT_BIAS;
-            moveChunk = chunk2Slots;
-        } else {
-            // Rotate left/up N (rotateBy = -N, N small, c1 small):
-            // in  arglist: [0: ...keep1 | arg1: c1 | arg1+N: c2...   | limit: keep2... ]
-            // out arglist: [0: ...keep1 | arg1: c2 ... | limit-N: c1 | limit: keep2... ]
-            srcArg = firstArg;
-            dstArg = limit-1;
-            dstSlot = depth2;
-            moveChunk = chunk1Slots;
-        }
-        byte srcType = basicType(newType.parameterType(srcArg));
-        byte dstType = basicType(newType.parameterType(dstArg));
-        assert(moveChunk == type2size(srcType));
-        long conv = makeSwapConv(OP_ROT_ARGS, srcArg, srcType, dstSlot, dstType);
-        return new AdapterMethodHandle(target, newType, conv);
-    }
-
-    /** Can an adapter spread an argument to convert the target to newType? */
-    static boolean canSpreadArguments(MethodType newType, MethodType targetType,
-                Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
-        if (!convOpSupported(OP_SPREAD_ARGS))  return false;
-        if (diffReturnTypes(newType, targetType, false) != 0)
-            return false;
-        int nptypes = newType.parameterCount();
-        // parameter types must be the same up to the spread point
-        if (spreadArgPos != 0 && diffParamTypes(newType, 0, targetType, 0, spreadArgPos, false) != 0)
-            return false;
-        int afterPos = spreadArgPos + spreadArgCount;
-        int afterCount = nptypes - (spreadArgPos + 1);
-        if (spreadArgPos < 0 || spreadArgPos >= nptypes ||
-            spreadArgCount < 0 ||
-            targetType.parameterCount() != afterPos + afterCount)
-            return false;
-        // parameter types after the spread point must also be the same
-        if (afterCount != 0 && diffParamTypes(newType, spreadArgPos+1, targetType, afterPos, afterCount, false) != 0)
-            return false;
-        // match the array element type to the spread arg types
-        Class<?> rawSpreadArgType = newType.parameterType(spreadArgPos);
-        if (rawSpreadArgType != spreadArgType && !canCheckCast(rawSpreadArgType, spreadArgType))
-            return false;
-        for (int i = 0; i < spreadArgCount; i++) {
-            Class<?> src = VerifyType.spreadArgElementType(spreadArgType, i);
-            Class<?> dst = targetType.parameterType(spreadArgPos + i);
-            if (src == null || !canConvertArgument(src, dst, 1))
-                return false;
-        }
-        return true;
-    }
-
-
-    /** Factory method:  Spread selected argument. */
-    static MethodHandle makeSpreadArguments(MethodType newType, MethodHandle target,
-                Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
-        // FIXME: Get rid of newType; derive new arguments from structure of spreadArgType
-        MethodType targetType = target.type();
-        assert(canSpreadArguments(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount))
-            : "[newType, targetType, spreadArgType, spreadArgPos, spreadArgCount] = "
-              + Arrays.asList(newType, targetType, spreadArgType, spreadArgPos, spreadArgCount);
-        // dest is not significant; remove?
-        int dest = T_VOID;
-        for (int i = 0; i < spreadArgCount; i++) {
-            Class<?> arg = VerifyType.spreadArgElementType(spreadArgType, i);
-            if (arg == null)  arg = Object.class;
-            int dest2 = basicType(arg);
-            if      (dest == T_VOID)  dest = dest2;
-            else if (dest != dest2)   dest = T_VOID;
-            if (dest == T_VOID)  break;
-            targetType = targetType.changeParameterType(spreadArgPos + i, arg);
-        }
-        target = target.asType(targetType);
-        int arrayArgSize = 1;  // always a reference
-        // in  arglist: [0: ...keep1 | spos: spreadArg | spos+1:      keep2... ]
-        // out arglist: [0: ...keep1 | spos: spread... | spos+scount: keep2... ]
-        int keep2OutPos  = spreadArgPos + spreadArgCount;
-        int keep1OutSlot = targetType.parameterSlotDepth(spreadArgPos);   // leading edge of |spread...|
-        int spreadSlot   = targetType.parameterSlotDepth(keep2OutPos);    // trailing edge of |spread...|
-        assert(spreadSlot == newType.parameterSlotDepth(spreadArgPos+arrayArgSize));
-        int slotCount    = keep1OutSlot - spreadSlot;                     // slots in |spread...|
-        assert(slotCount >= spreadArgCount);
-        int stackMove = - arrayArgSize + slotCount;  // pop array, push N slots
-        long conv = makeSpreadConv(OP_SPREAD_ARGS, spreadArgPos, T_OBJECT, dest, stackMove);
-        MethodHandle res = new AdapterMethodHandle(target, newType, conv, spreadArgType);
-        assert(res.type().parameterType(spreadArgPos) == spreadArgType);
-        return res;
-    }
-
-    /** Can an adapter collect a series of arguments, replacing them by zero or one results? */
-    static boolean canCollectArguments(MethodType targetType,
-                MethodType collectorType, int collectArgPos, boolean retainOriginalArgs) {
-        if (!convOpSupported(retainOriginalArgs ? OP_FOLD_ARGS : OP_COLLECT_ARGS))  return false;
-        int collectArgCount = collectorType.parameterCount();
-        Class<?> rtype = collectorType.returnType();
-        assert(rtype == void.class || targetType.parameterType(collectArgPos) == rtype)
-                // [(Object)Object[], (Object[])Object[], 0, 1]
-                : Arrays.asList(targetType, collectorType, collectArgPos, collectArgCount)
-                ;
-        return true;
-    }
-
-    /** Factory method:  Collect or filter selected argument(s). */
-    static MethodHandle makeCollectArguments(MethodHandle target,
-                MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
-        assert(canCollectArguments(target.type(), collector.type(), collectArgPos, retainOriginalArgs));
-        MethodType targetType = target.type();
-        MethodType collectorType = collector.type();
-        int collectArgCount = collectorType.parameterCount();
-        Class<?> collectValType = collectorType.returnType();
-        int collectValCount = (collectValType == void.class ? 0 : 1);
-        int collectValSlots = collectorType.returnSlotCount();
-        MethodType newType = targetType
-                .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
-        if (!retainOriginalArgs) {
-            newType = newType
-                .insertParameterTypes(collectArgPos, collectorType.parameterList());
-        } else {
-            // parameter types at the fold point must be the same
-            assert(diffParamTypes(newType, collectArgPos, targetType, collectValCount, collectArgCount, false) == 0)
-                : Arrays.asList(target, collector, collectArgPos, retainOriginalArgs);
-        }
-        // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
-        // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
-        // out(retain): [0: ...keep1 | cpos: cV? coll... | cpos+cvc+cac: keep2... ]
-        int keep2InPos   = collectArgPos + collectArgCount;
-        int keep1InSlot  = newType.parameterSlotDepth(collectArgPos);  // leading edge of |collect...|
-        int collectSlot  = newType.parameterSlotDepth(keep2InPos);     // trailing edge of |collect...|
-        int slotCount    = keep1InSlot - collectSlot;                  // slots in |collect...|
-        assert(slotCount >= collectArgCount);
-        assert(collectSlot == targetType.parameterSlotDepth(
-                collectArgPos + collectValCount + (retainOriginalArgs ? collectArgCount : 0) ));
-        int dest = basicType(collectValType);
-        int src = T_VOID;
-        // src is not significant; remove?
-        for (int i = 0; i < collectArgCount; i++) {
-            int src2 = basicType(collectorType.parameterType(i));
-            if      (src == T_VOID)  src = src2;
-            else if (src != src2)    src = T_VOID;
-            if (src == T_VOID)  break;
-        }
-        int stackMove = collectValSlots;  // push 0..2 results
-        if (!retainOriginalArgs)  stackMove -= slotCount; // pop N arguments
-        int lastCollectArg = keep2InPos-1;
-        long conv = makeSpreadConv(retainOriginalArgs ? OP_FOLD_ARGS : OP_COLLECT_ARGS,
-                                   lastCollectArg, src, dest, stackMove);
-        MethodHandle res = new AdapterMethodHandle(target, newType, conv, collector);
-        assert(res.type().parameterList().subList(collectArgPos, collectArgPos+collectArgCount)
-                .equals(collector.type().parameterList()));
-        return res;
-    }
-
-    @Override
-    String debugString() {
-        return getNameString(nonAdapter((MethodHandle)vmtarget), this);
-    }
-
-    private static MethodHandle nonAdapter(MethodHandle mh) {
-        while (mh instanceof AdapterMethodHandle) {
-            mh = (MethodHandle) mh.vmtarget;
-        }
-        return mh;
-    }
-}
diff --git a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java
index b41e9dc..dfc6e9d 100644
--- a/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java
+++ b/jdk/src/share/classes/java/lang/invoke/BoundMethodHandle.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,164 +25,833 @@
 
 package java.lang.invoke;
 
-import sun.invoke.util.VerifyType;
-import sun.invoke.util.Wrapper;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.*;
+import static java.lang.invoke.LambdaForm.basicTypes;
+import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
 import static java.lang.invoke.MethodHandleStatics.*;
 
+import java.lang.invoke.LambdaForm.Name;
+import java.lang.invoke.LambdaForm.NamedFunction;
+import java.lang.invoke.MethodHandles.Lookup;
+import java.lang.reflect.Field;
+import java.util.Arrays;
+import java.util.HashMap;
+
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.Wrapper;
+
+import com.sun.xml.internal.ws.org.objectweb.asm.ClassWriter;
+import com.sun.xml.internal.ws.org.objectweb.asm.MethodVisitor;
+import com.sun.xml.internal.ws.org.objectweb.asm.Type;
+
 /**
  * The flavor of method handle which emulates an invoke instruction
  * on a predetermined argument.  The JVM dispatches to the correct method
  * when the handle is created, not when it is invoked.
- * @author jrose
+ *
+ * All bound arguments are encapsulated in dedicated species.
  */
-class BoundMethodHandle extends MethodHandle {
-    //MethodHandle vmtarget;           // next BMH or final DMH or methodOop
-    private final Object argument;     // argument to insert
-    private final int    vmargslot;    // position at which it is inserted
+/* non-public */ abstract class BoundMethodHandle extends MethodHandle {
 
-    // Constructors in this class *must* be package scoped or private.
-
-    /** Bind a direct MH to its receiver (or first ref. argument).
-     *  The JVM will pre-dispatch the MH if it is not already static.
-     */
-    /*non-public*/ BoundMethodHandle(DirectMethodHandle mh, Object argument) {
-        super(mh.type().dropParameterTypes(0, 1));
-        // check the type now, once for all:
-        this.argument = checkReferenceArgument(argument, mh, 0);
-        this.vmargslot = this.type().parameterSlotCount();
-        initTarget(mh, 0);
+    /* non-public */ BoundMethodHandle(MethodType type, LambdaForm form) {
+        super(type, form);
     }
 
-    /** Insert an argument into an arbitrary method handle.
-     *  If argnum is zero, inserts the first argument, etc.
-     *  The argument type must be a reference.
-     */
-    /*non-public*/ BoundMethodHandle(MethodHandle mh, Object argument, int argnum) {
-        this(mh.type().dropParameterTypes(argnum, argnum+1),
-             mh, argument, argnum);
-    }
+    //
+    // BMH API and internals
+    //
 
-    /** Insert an argument into an arbitrary method handle.
-     *  If argnum is zero, inserts the first argument, etc.
-     */
-    /*non-public*/ BoundMethodHandle(MethodType type, MethodHandle mh, Object argument, int argnum) {
-        super(type);
-        if (mh.type().parameterType(argnum).isPrimitive())
-            this.argument = bindPrimitiveArgument(argument, mh, argnum);
-        else {
-            this.argument = checkReferenceArgument(argument, mh, argnum);
+    static MethodHandle bindSingle(MethodType type, LambdaForm form, char xtype, Object x) {
+        // for some type signatures, there exist pre-defined concrete BMH classes
+        try {
+            switch (xtype) {
+            case 'L':
+                if (true)  return bindSingle(type, form, x);  // Use known fast path.
+                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('L').constructor[0].invokeBasic(type, form, x);
+            case 'I':
+                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('I').constructor[0].invokeBasic(type, form, ValueConversions.widenSubword(x));
+            case 'J':
+                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('J').constructor[0].invokeBasic(type, form, (long) x);
+            case 'F':
+                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('F').constructor[0].invokeBasic(type, form, (float) x);
+            case 'D':
+                return (BoundMethodHandle) SpeciesData.EMPTY.extendWithType('D').constructor[0].invokeBasic(type, form, (double) x);
+            default : throw new InternalError("unexpected xtype: " + xtype);
+            }
+        } catch (Throwable t) {
+            throw newInternalError(t);
         }
-        this.vmargslot = type.parameterSlotDepth(argnum);
-        initTarget(mh, argnum);
     }
 
-    private void initTarget(MethodHandle mh, int argnum) {
-        //this.vmtarget = mh;  // maybe updated by JVM
-        MethodHandleNatives.init(this, mh, argnum);
+    static MethodHandle bindSingle(MethodType type, LambdaForm form, Object x) {
+            return new Species_L(type, form, x);
     }
 
-    /** For the AdapterMethodHandle subclass.
-     */
-    /*non-public*/ BoundMethodHandle(MethodType type, Object argument, int vmargslot) {
-        super(type);
-        this.argument = argument;
-        this.vmargslot = vmargslot;
-        assert(this instanceof AdapterMethodHandle);
-    }
-
-    /** Initialize the current object as a self-bound method handle, binding it
-     *  as the first argument of the method handle {@code entryPoint}.
-     *  The invocation type of the resulting method handle will be the
-     *  same as {@code entryPoint},  except that the first argument
-     *  type will be dropped.
-     */
-    /*non-public*/ BoundMethodHandle(MethodHandle entryPoint) {
-        super(entryPoint.type().dropParameterTypes(0, 1));
-        this.argument = this; // kludge; get rid of
-        this.vmargslot = this.type().parameterSlotDepth(0);
-        initTarget(entryPoint, 0);
-    }
-
-    /** Make sure the given {@code argument} can be used as {@code argnum}-th
-     *  parameter of the given method handle {@code mh}, which must be a reference.
-     *  <p>
-     *  If this fails, throw a suitable {@code WrongMethodTypeException},
-     *  which will prevent the creation of an illegally typed bound
-     *  method handle.
-     */
-    final static Object checkReferenceArgument(Object argument, MethodHandle mh, int argnum) {
-        Class<?> ptype = mh.type().parameterType(argnum);
-        if (ptype.isPrimitive()) {
-            // fail
-        } else if (argument == null) {
-            return null;
-        } else if (VerifyType.isNullReferenceConversion(argument.getClass(), ptype)) {
-            return argument;
+    MethodHandle cloneExtend(MethodType type, LambdaForm form, char xtype, Object x) {
+        try {
+            switch (xtype) {
+            case 'L': return cloneExtendL(type, form, x);
+            case 'I': return cloneExtendI(type, form, ValueConversions.widenSubword(x));
+            case 'J': return cloneExtendJ(type, form, (long) x);
+            case 'F': return cloneExtendF(type, form, (float) x);
+            case 'D': return cloneExtendD(type, form, (double) x);
+            }
+        } catch (Throwable t) {
+            throw newInternalError(t);
         }
-        throw badBoundArgumentException(argument, mh, argnum);
-    }
-
-    /** Make sure the given {@code argument} can be used as {@code argnum}-th
-     *  parameter of the given method handle {@code mh}, which must be a primitive.
-     *  <p>
-     *  If this fails, throw a suitable {@code WrongMethodTypeException},
-     *  which will prevent the creation of an illegally typed bound
-     *  method handle.
-     */
-    final static Object bindPrimitiveArgument(Object argument, MethodHandle mh, int argnum) {
-        Class<?> ptype = mh.type().parameterType(argnum);
-        Wrapper  wrap = Wrapper.forPrimitiveType(ptype);
-        Object   zero  = wrap.zero();
-        if (zero == null) {
-            // fail
-        } else if (argument == null) {
-            if (ptype != int.class && wrap.isSubwordOrInt())
-                return Integer.valueOf(0);
-            else
-                return zero;
-        } else if (VerifyType.isNullReferenceConversion(argument.getClass(), zero.getClass())) {
-            if (ptype != int.class && wrap.isSubwordOrInt())
-                return Wrapper.INT.wrap(argument);
-            else
-                return argument;
-        }
-        throw badBoundArgumentException(argument, mh, argnum);
-    }
-
-    final static RuntimeException badBoundArgumentException(Object argument, MethodHandle mh, int argnum) {
-        String atype = (argument == null) ? "null" : argument.getClass().toString();
-        return new ClassCastException("cannot bind "+atype+" argument to parameter #"+argnum+" of "+mh.type());
+        throw new InternalError("unexpected type: " + xtype);
     }
 
     @Override
-    String debugString() {
-        return addTypeString(baseName(), this);
+    MethodHandle bindArgument(int pos, char basicType, Object value) {
+        MethodType type = type().dropParameterTypes(pos, pos+1);
+        LambdaForm form = internalForm().bind(1+pos, speciesData());
+        return cloneExtend(type, form, basicType, value);
     }
 
-    /** Component of toString() before the type string. */
-    protected String baseName() {
-        MethodHandle mh = this;
-        while (mh instanceof BoundMethodHandle) {
-            Object info = MethodHandleNatives.getTargetInfo(mh);
-            if (info instanceof MethodHandle) {
-                mh = (MethodHandle) info;
-            } else {
-                String name = null;
-                if (info instanceof MemberName)
-                    name = ((MemberName)info).getName();
-                if (name != null)
-                    return name;
-                else
-                    return noParens(super.toString()); // "invoke", probably
-            }
-            assert(mh != this);
+    @Override
+    MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
+        LambdaForm form = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos+drops));
+        try {
+             return clone(srcType, form);
+         } catch (Throwable t) {
+             throw newInternalError(t);
+         }
+    }
+
+    @Override
+    MethodHandle permuteArguments(MethodType newType, int[] reorder) {
+        try {
+             return clone(newType, form.permuteArguments(1, reorder, basicTypes(newType.parameterList())));
+         } catch (Throwable t) {
+             throw newInternalError(t);
+         }
+    }
+
+    static final String EXTENSION_TYPES = "LIJFD";
+    static final byte INDEX_L = 0, INDEX_I = 1, INDEX_J = 2, INDEX_F = 3, INDEX_D = 4;
+    static byte extensionIndex(char type) {
+        int i = EXTENSION_TYPES.indexOf(type);
+        if (i < 0)  throw new InternalError();
+        return (byte) i;
+    }
+
+    /**
+     * Return the {@link SpeciesData} instance representing this BMH species. All subclasses must provide a
+     * static field containing this value, and they must accordingly implement this method.
+     */
+    protected abstract SpeciesData speciesData();
+
+    @Override
+    final Object internalProperties() {
+        return "/BMH="+internalValues();
+    }
+
+    @Override
+    final Object internalValues() {
+        Object[] boundValues = new Object[speciesData().fieldCount()];
+        for (int i = 0; i < boundValues.length; ++i) {
+            boundValues[i] = arg(i);
         }
-        return noParens(mh.toString());
+        return Arrays.asList(boundValues);
     }
 
-    private static String noParens(String str) {
-        int paren = str.indexOf('(');
-        if (paren >= 0) str = str.substring(0, paren);
-        return str;
+    public final Object arg(int i) {
+        try {
+            switch (speciesData().fieldType(i)) {
+            case 'L': return argL(i);
+            case 'I': return argI(i);
+            case 'F': return argF(i);
+            case 'D': return argD(i);
+            case 'J': return argJ(i);
+            }
+        } catch (Throwable ex) {
+            throw newInternalError(ex);
+        }
+        throw new InternalError("unexpected type: " + speciesData().types+"."+i);
     }
+    public final Object argL(int i) throws Throwable { return          speciesData().getters[i].invokeBasic(this); }
+    public final int    argI(int i) throws Throwable { return (int)    speciesData().getters[i].invokeBasic(this); }
+    public final float  argF(int i) throws Throwable { return (float)  speciesData().getters[i].invokeBasic(this); }
+    public final double argD(int i) throws Throwable { return (double) speciesData().getters[i].invokeBasic(this); }
+    public final long   argJ(int i) throws Throwable { return (long)   speciesData().getters[i].invokeBasic(this); }
+
+    //
+    // cloning API
+    //
+
+    public abstract BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable;
+    public abstract BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable;
+    public abstract BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int    narg) throws Throwable;
+    public abstract BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long   narg) throws Throwable;
+    public abstract BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float  narg) throws Throwable;
+    public abstract BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable;
+
+    // The following is a grossly irregular hack:
+    @Override MethodHandle reinvokerTarget() {
+        try {
+            return (MethodHandle) argL(0);
+        } catch (Throwable ex) {
+            throw newInternalError(ex);
+        }
+    }
+
+    //
+    // concrete BMH classes required to close bootstrap loops
+    //
+
+    private  // make it private to force users to access the enclosing class first
+    static final class Species_L extends BoundMethodHandle {
+        final Object argL0;
+        public Species_L(MethodType mt, LambdaForm lf, Object argL0) {
+            super(mt, lf);
+            this.argL0 = argL0;
+        }
+        // The following is a grossly irregular hack:
+        @Override MethodHandle reinvokerTarget() { return (MethodHandle) argL0; }
+        @Override
+        public SpeciesData speciesData() {
+            return SPECIES_DATA;
+        }
+        public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("L", Species_L.class);
+        @Override
+        public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
+            return new Species_L(mt, lf, argL0);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, narg);
+        }
+    }
+
+/*
+    static final class Species_LL extends BoundMethodHandle {
+        final Object argL0;
+        final Object argL1;
+        public Species_LL(MethodType mt, LambdaForm lf, Object argL0, Object argL1) {
+            super(mt, lf);
+            this.argL0 = argL0;
+            this.argL1 = argL1;
+        }
+        @Override
+        public SpeciesData speciesData() {
+            return SPECIES_DATA;
+        }
+        public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LL", Species_LL.class);
+        @Override
+        public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
+            return new Species_LL(mt, lf, argL0, argL1);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, narg);
+        }
+    }
+
+    static final class Species_JL extends BoundMethodHandle {
+        final long argJ0;
+        final Object argL1;
+        public Species_JL(MethodType mt, LambdaForm lf, long argJ0, Object argL1) {
+            super(mt, lf);
+            this.argJ0 = argJ0;
+            this.argL1 = argL1;
+        }
+        @Override
+        public SpeciesData speciesData() {
+            return SPECIES_DATA;
+        }
+        public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("JL", Species_JL.class);
+        @Override public final long   argJ0() { return argJ0; }
+        @Override public final Object argL1() { return argL1; }
+        @Override
+        public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) throws Throwable {
+            return new Species_JL(mt, lf, argJ0, argL1);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+        }
+        @Override
+        public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) throws Throwable {
+            return (BoundMethodHandle) SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argJ0, argL1, narg);
+        }
+    }
+*/
+
+    //
+    // BMH species meta-data
+    //
+
+    /**
+     * Meta-data wrapper for concrete BMH classes.
+     */
+    static class SpeciesData {
+        final String                             types;
+        final Class<? extends BoundMethodHandle> clazz;
+        // Bootstrapping requires circular relations MH -> BMH -> SpeciesData -> MH
+        // Therefore, we need a non-final link in the chain.  Use array elements.
+        final MethodHandle[]                     constructor;
+        final MethodHandle[]                     getters;
+        final SpeciesData[]                      extensions;
+
+        public int fieldCount() {
+            return types.length();
+        }
+        public char fieldType(int i) {
+            return types.charAt(i);
+        }
+
+        public String toString() {
+            return "SpeciesData["+(isPlaceholder() ? "<placeholder>" : clazz.getSimpleName())+":"+types+"]";
+        }
+
+        /**
+         * Return a {@link LambdaForm.Name} containing a {@link LambdaForm.NamedFunction} that
+         * represents a MH bound to a generic invoker, which in turn forwards to the corresponding
+         * getter.
+         */
+        Name getterName(Name mhName, int i) {
+            MethodHandle mh = getters[i];
+            assert(mh != null) : this+"."+i;
+            return new Name(mh, mhName);
+        }
+
+        static final SpeciesData EMPTY = new SpeciesData("", BoundMethodHandle.class);
+
+        private SpeciesData(String types, Class<? extends BoundMethodHandle> clazz) {
+            this.types = types;
+            this.clazz = clazz;
+            if (!INIT_DONE) {
+                this.constructor = new MethodHandle[1];
+                this.getters = new MethodHandle[types.length()];
+            } else {
+                this.constructor = Factory.makeCtors(clazz, types, null);
+                this.getters = Factory.makeGetters(clazz, types, null);
+            }
+            this.extensions = new SpeciesData[EXTENSION_TYPES.length()];
+        }
+
+        private void initForBootstrap() {
+            assert(!INIT_DONE);
+            if (constructor[0] == null) {
+                Factory.makeCtors(clazz, types, this.constructor);
+                Factory.makeGetters(clazz, types, this.getters);
+            }
+        }
+
+        private SpeciesData(String types) {
+            // Placeholder only.
+            this.types = types;
+            this.clazz = null;
+            this.constructor = null;
+            this.getters = null;
+            this.extensions = null;
+        }
+        private boolean isPlaceholder() { return clazz == null; }
+
+        private static final HashMap<String, SpeciesData> CACHE = new HashMap<>();
+        private static final boolean INIT_DONE;  // set after <clinit> finishes...
+
+        SpeciesData extendWithType(char type) {
+            int i = extensionIndex(type);
+            SpeciesData d = extensions[i];
+            if (d != null)  return d;
+            extensions[i] = d = get(types+type);
+            return d;
+        }
+
+        SpeciesData extendWithIndex(byte index) {
+            SpeciesData d = extensions[index];
+            if (d != null)  return d;
+            extensions[index] = d = get(types+EXTENSION_TYPES.charAt(index));
+            return d;
+        }
+
+        private static SpeciesData get(String types) {
+            // Acquire cache lock for query.
+            SpeciesData d = lookupCache(types);
+            if (!d.isPlaceholder())
+                return d;
+            synchronized (d) {
+                // Use synch. on the placeholder to prevent multiple instantiation of one species.
+                // Creating this class forces a recursive call to getForClass.
+                if (lookupCache(types).isPlaceholder())
+                    Factory.generateConcreteBMHClass(types);
+            }
+            // Reacquire cache lock.
+            d = lookupCache(types);
+            // Class loading must have upgraded the cache.
+            assert(d != null && !d.isPlaceholder());
+            return d;
+        }
+        static SpeciesData getForClass(String types, Class<? extends BoundMethodHandle> clazz) {
+            // clazz is a new class which is initializing its SPECIES_DATA field
+            return updateCache(types, new SpeciesData(types, clazz));
+        }
+        private static synchronized SpeciesData lookupCache(String types) {
+            SpeciesData d = CACHE.get(types);
+            if (d != null)  return d;
+            d = new SpeciesData(types);
+            assert(d.isPlaceholder());
+            CACHE.put(types, d);
+            return d;
+        }
+        private static synchronized SpeciesData updateCache(String types, SpeciesData d) {
+            SpeciesData d2;
+            assert((d2 = CACHE.get(types)) == null || d2.isPlaceholder());
+            assert(!d.isPlaceholder());
+            CACHE.put(types, d);
+            return d;
+        }
+
+        static {
+            // pre-fill the BMH speciesdata cache with BMH's inner classes
+            final Class<BoundMethodHandle> rootCls = BoundMethodHandle.class;
+            SpeciesData d0 = BoundMethodHandle.SPECIES_DATA;  // trigger class init
+            assert(d0 == null || d0 == lookupCache("")) : d0;
+            try {
+                for (Class<?> c : rootCls.getDeclaredClasses()) {
+                    if (rootCls.isAssignableFrom(c)) {
+                        final Class<? extends BoundMethodHandle> cbmh = c.asSubclass(BoundMethodHandle.class);
+                        SpeciesData d = Factory.speciesDataFromConcreteBMHClass(cbmh);
+                        assert(d != null) : cbmh.getName();
+                        assert(d.clazz == cbmh);
+                        assert(d == lookupCache(d.types));
+                    }
+                }
+            } catch (Throwable e) {
+                throw newInternalError(e);
+            }
+
+            for (SpeciesData d : CACHE.values()) {
+                d.initForBootstrap();
+            }
+            // Note:  Do not simplify this, because INIT_DONE must not be
+            // a compile-time constant during bootstrapping.
+            INIT_DONE = Boolean.TRUE;
+        }
+    }
+
+    static SpeciesData getSpeciesData(String types) {
+        return SpeciesData.get(types);
+    }
+
+    /**
+     * Generation of concrete BMH classes.
+     *
+     * A concrete BMH species is fit for binding a number of values adhering to a
+     * given type pattern. Reference types are erased.
+     *
+     * BMH species are cached by type pattern.
+     *
+     * A BMH species has a number of fields with the concrete (possibly erased) types of
+     * bound values. Setters are provided as an API in BMH. Getters are exposed as MHs,
+     * which can be included as names in lambda forms.
+     */
+    static class Factory {
+
+        static final String JLO_SIG  = "Ljava/lang/Object;";
+        static final String JLS_SIG  = "Ljava/lang/String;";
+        static final String JLC_SIG  = "Ljava/lang/Class;";
+        static final String MH       = "java/lang/invoke/MethodHandle";
+        static final String MH_SIG   = "L"+MH+";";
+        static final String BMH      = "java/lang/invoke/BoundMethodHandle";
+        static final String BMH_SIG  = "L"+BMH+";";
+        static final String SPECIES_DATA     = "java/lang/invoke/BoundMethodHandle$SpeciesData";
+        static final String SPECIES_DATA_SIG = "L"+SPECIES_DATA+";";
+
+        static final String SPECIES_PREFIX_NAME = "Species_";
+        static final String SPECIES_PREFIX_PATH = BMH + "$" + SPECIES_PREFIX_NAME;
+
+        static final String BMHSPECIES_DATA_EWI_SIG = "(B)" + SPECIES_DATA_SIG;
+        static final String BMHSPECIES_DATA_GFC_SIG = "(" + JLS_SIG + JLC_SIG + ")" + SPECIES_DATA_SIG;
+        static final String MYSPECIES_DATA_SIG = "()" + SPECIES_DATA_SIG;
+        static final String VOID_SIG   = "()V";
+
+        static final String SIG_INCIPIT = "(Ljava/lang/invoke/MethodType;Ljava/lang/invoke/LambdaForm;";
+
+        static final Class<?>[] TYPES = new Class<?>[] { Object.class, int.class, long.class, float.class, double.class };
+
+        static final String[] E_THROWABLE = new String[] { "java/lang/Throwable" };
+
+        /**
+         * Generate a concrete subclass of BMH for a given combination of bound types.
+         *
+         * A concrete BMH species adheres to the following schema:
+         *
+         * <pre>
+         * class Species_<<types>> extends BoundMethodHandle {
+         *     <<fields>>
+         *     final SpeciesData speciesData() { return SpeciesData.get("<<types>>"); }
+         * }
+         * </pre>
+         *
+         * The {@code <<types>>} signature is precisely the string that is passed to this
+         * method.
+         *
+         * The {@code <<fields>>} section consists of one field definition per character in
+         * the type signature, adhering to the naming schema described in the definition of
+         * {@link #makeFieldName()}.
+         *
+         * For example, a concrete BMH species for two reference and one integral bound values
+         * would have the following shape:
+         *
+         * <pre>
+         * class BoundMethodHandle { ... private static
+         * final class Species_LLI extends BoundMethodHandle {
+         *     final Object argL0;
+         *     final Object argL1;
+         *     final int argI2;
+         *     public Species_LLI(MethodType mt, LambdaForm lf, Object argL0, Object argL1, int argI2) {
+         *         super(mt, lf);
+         *         this.argL0 = argL0;
+         *         this.argL1 = argL1;
+         *         this.argI2 = argI2;
+         *     }
+         *     public final SpeciesData speciesData() { return SPECIES_DATA; }
+         *     public static final SpeciesData SPECIES_DATA = SpeciesData.getForClass("LLI", Species_LLI.class);
+         *     public final BoundMethodHandle clone(MethodType mt, LambdaForm lf) {
+         *         return SPECIES_DATA.constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2);
+         *     }
+         *     public final BoundMethodHandle cloneExtendL(MethodType mt, LambdaForm lf, Object narg) {
+         *         return SPECIES_DATA.extendWithIndex(INDEX_L).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+         *     }
+         *     public final BoundMethodHandle cloneExtendI(MethodType mt, LambdaForm lf, int narg) {
+         *         return SPECIES_DATA.extendWithIndex(INDEX_I).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+         *     }
+         *     public final BoundMethodHandle cloneExtendJ(MethodType mt, LambdaForm lf, long narg) {
+         *         return SPECIES_DATA.extendWithIndex(INDEX_J).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+         *     }
+         *     public final BoundMethodHandle cloneExtendF(MethodType mt, LambdaForm lf, float narg) {
+         *         return SPECIES_DATA.extendWithIndex(INDEX_F).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+         *     }
+         *     public final BoundMethodHandle cloneExtendD(MethodType mt, LambdaForm lf, double narg) {
+         *         return SPECIES_DATA.extendWithIndex(INDEX_D).constructor[0].invokeBasic(mt, lf, argL0, argL1, argI2, narg);
+         *     }
+         * }
+         * </pre>
+         *
+         * @param types the type signature, wherein reference types are erased to 'L'
+         * @return the generated concrete BMH class
+         */
+        static Class<? extends BoundMethodHandle> generateConcreteBMHClass(String types) {
+            final ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+
+            final String className  = SPECIES_PREFIX_PATH + types;
+            final String sourceFile = SPECIES_PREFIX_NAME + types;
+            cw.visit(V1_6, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, className, null, BMH, null);
+            cw.visitSource(sourceFile, null);
+
+            // emit static types and SPECIES_DATA fields
+            cw.visitField(ACC_PUBLIC + ACC_STATIC, "SPECIES_DATA", SPECIES_DATA_SIG, null, null).visitEnd();
+
+            // emit bound argument fields
+            for (int i = 0; i < types.length(); ++i) {
+                final char t = types.charAt(i);
+                final String fieldName = makeFieldName(types, i);
+                final String fieldDesc = t == 'L' ? JLO_SIG : String.valueOf(t);
+                cw.visitField(ACC_FINAL, fieldName, fieldDesc, null, null).visitEnd();
+            }
+
+            MethodVisitor mv;
+
+            // emit constructor
+            mv = cw.visitMethod(ACC_PUBLIC, "<init>", makeSignature(types, true), null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitVarInsn(ALOAD, 2);
+
+            mv.visitMethodInsn(INVOKESPECIAL, BMH, "<init>", makeSignature("", true));
+
+            for (int i = 0, j = 0; i < types.length(); ++i, ++j) {
+                // i counts the arguments, j counts corresponding argument slots
+                char t = types.charAt(i);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitVarInsn(typeLoadOp(t), j + 3); // parameters start at 3
+                mv.visitFieldInsn(PUTFIELD, className, makeFieldName(types, i), typeSig(t));
+                if (t == 'J' || t == 'D') {
+                    ++j; // adjust argument register access
+                }
+            }
+
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            // emit implementation of reinvokerTarget()
+            mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "reinvokerTarget", "()" + MH_SIG, null, null);
+            mv.visitCode();
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETFIELD, className, "argL0", JLO_SIG);
+            mv.visitTypeInsn(CHECKCAST, MH);
+            mv.visitInsn(ARETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            // emit implementation of speciesData()
+            mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "speciesData", MYSPECIES_DATA_SIG, null, null);
+            mv.visitCode();
+            mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
+            mv.visitInsn(ARETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            // emit clone()
+            mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "clone", makeSignature("", false), null, E_THROWABLE);
+            mv.visitCode();
+            // return speciesData().constructor[0].invokeBasic(mt, lf, argL0, ...)
+            // obtain constructor
+            mv.visitVarInsn(ALOAD, 0);
+            mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
+            mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
+            mv.visitInsn(ICONST_0);
+            mv.visitInsn(AALOAD);
+            // load mt, lf
+            mv.visitVarInsn(ALOAD, 1);
+            mv.visitVarInsn(ALOAD, 2);
+            // put fields on the stack
+            emitPushFields(types, className, mv);
+            // finally, invoke the constructor and return
+            mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types, false));
+            mv.visitInsn(ARETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            // for each type, emit cloneExtendT()
+            for (Class<?> c : TYPES) {
+                char t = Wrapper.basicTypeChar(c);
+                mv = cw.visitMethod(ACC_PUBLIC + ACC_FINAL, "cloneExtend" + t, makeSignature(String.valueOf(t), false), null, E_THROWABLE);
+                mv.visitCode();
+                // return SPECIES_DATA.extendWithIndex(extensionIndex(t)).constructor[0].invokeBasic(mt, lf, argL0, ..., narg)
+                // obtain constructor
+                mv.visitFieldInsn(GETSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
+                int iconstInsn = ICONST_0 + extensionIndex(t);
+                assert(iconstInsn <= ICONST_5);
+                mv.visitInsn(iconstInsn);
+                mv.visitMethodInsn(INVOKEVIRTUAL, SPECIES_DATA, "extendWithIndex", BMHSPECIES_DATA_EWI_SIG);
+                mv.visitFieldInsn(GETFIELD, SPECIES_DATA, "constructor", "[" + MH_SIG);
+                mv.visitInsn(ICONST_0);
+                mv.visitInsn(AALOAD);
+                // load mt, lf
+                mv.visitVarInsn(ALOAD, 1);
+                mv.visitVarInsn(ALOAD, 2);
+                // put fields on the stack
+                emitPushFields(types, className, mv);
+                // put narg on stack
+                mv.visitVarInsn(typeLoadOp(t), 3);
+                // finally, invoke the constructor and return
+                mv.visitMethodInsn(INVOKEVIRTUAL, MH, "invokeBasic", makeSignature(types + t, false));
+                mv.visitInsn(ARETURN);
+                mv.visitMaxs(0, 0);
+                mv.visitEnd();
+            }
+
+            // emit class initializer
+            mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "<clinit>", VOID_SIG, null, null);
+            mv.visitCode();
+            mv.visitLdcInsn(types);
+            mv.visitLdcInsn(Type.getObjectType(className));
+            mv.visitMethodInsn(INVOKESTATIC, SPECIES_DATA, "getForClass", BMHSPECIES_DATA_GFC_SIG);
+            mv.visitFieldInsn(PUTSTATIC, className, "SPECIES_DATA", SPECIES_DATA_SIG);
+            mv.visitInsn(RETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+
+            cw.visitEnd();
+
+            // load class
+            final byte[] classFile = cw.toByteArray();
+            InvokerBytecodeGenerator.maybeDump(className, classFile);
+            Class<? extends BoundMethodHandle> bmhClass =
+                //UNSAFE.defineAnonymousClass(BoundMethodHandle.class, classFile, null).asSubclass(BoundMethodHandle.class);
+                UNSAFE.defineClass(className, classFile, 0, classFile.length).asSubclass(BoundMethodHandle.class);
+            UNSAFE.ensureClassInitialized(bmhClass);
+
+            return bmhClass;
+        }
+
+        private static int typeLoadOp(char t) {
+            switch (t) {
+            case 'L': return ALOAD;
+            case 'I': return ILOAD;
+            case 'J': return LLOAD;
+            case 'F': return FLOAD;
+            case 'D': return DLOAD;
+            default : throw new InternalError("unrecognized type " + t);
+            }
+        }
+
+        private static void emitPushFields(String types, String className, MethodVisitor mv) {
+            for (int i = 0; i < types.length(); ++i) {
+                char tc = types.charAt(i);
+                mv.visitVarInsn(ALOAD, 0);
+                mv.visitFieldInsn(GETFIELD, className, makeFieldName(types, i), typeSig(tc));
+            }
+        }
+
+        static String typeSig(char t) {
+            return t == 'L' ? JLO_SIG : String.valueOf(t);
+        }
+
+        //
+        // Getter MH generation.
+        //
+
+        private static MethodHandle makeGetter(Class<?> cbmhClass, String types, int index) {
+            String fieldName = makeFieldName(types, index);
+            Class<?> fieldType = Wrapper.forBasicType(types.charAt(index)).primitiveType();
+            try {
+                return LOOKUP.findGetter(cbmhClass, fieldName, fieldType);
+            } catch (NoSuchFieldException | IllegalAccessException e) {
+                throw newInternalError(e);
+            }
+        }
+
+        static MethodHandle[] makeGetters(Class<?> cbmhClass, String types, MethodHandle[] mhs) {
+            if (mhs == null)  mhs = new MethodHandle[types.length()];
+            for (int i = 0; i < mhs.length; ++i) {
+                mhs[i] = makeGetter(cbmhClass, types, i);
+                assert(mhs[i].internalMemberName().getDeclaringClass() == cbmhClass);
+            }
+            return mhs;
+        }
+
+        static MethodHandle[] makeCtors(Class<? extends BoundMethodHandle> cbmh, String types, MethodHandle mhs[]) {
+            if (mhs == null)  mhs = new MethodHandle[1];
+            mhs[0] = makeCbmhCtor(cbmh, types);
+            return mhs;
+        }
+
+        //
+        // Auxiliary methods.
+        //
+
+        static SpeciesData speciesDataFromConcreteBMHClass(Class<? extends BoundMethodHandle> cbmh) {
+            try {
+                Field F_SPECIES_DATA = cbmh.getDeclaredField("SPECIES_DATA");
+                return (SpeciesData) F_SPECIES_DATA.get(null);
+            } catch (ReflectiveOperationException ex) {
+                throw newInternalError(ex);
+            }
+        }
+
+        /**
+         * Field names in concrete BMHs adhere to this pattern:
+         * arg + type + index
+         * where type is a single character (L, I, J, F, D).
+         */
+        private static String makeFieldName(String types, int index) {
+            assert index >= 0 && index < types.length();
+            return "arg" + types.charAt(index) + index;
+        }
+
+        private static String makeSignature(String types, boolean ctor) {
+            StringBuilder buf = new StringBuilder(SIG_INCIPIT);
+            for (char c : types.toCharArray()) {
+                buf.append(typeSig(c));
+            }
+            return buf.append(')').append(ctor ? "V" : BMH_SIG).toString();
+        }
+
+        static MethodHandle makeCbmhCtor(Class<? extends BoundMethodHandle> cbmh, String types) {
+            try {
+                return linkConstructor(LOOKUP.findConstructor(cbmh, MethodType.fromMethodDescriptorString(makeSignature(types, true), null)));
+            } catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | TypeNotPresentException e) {
+                throw newInternalError(e);
+            }
+        }
+
+        /**
+         * Wrap a constructor call in a {@link LambdaForm}.
+         *
+         * If constructors ({@code <init>} methods) are called in LFs, problems might arise if the LFs
+         * are turned into bytecode, because the call to the allocator is routed through an MH, and the
+         * verifier cannot find a {@code NEW} instruction preceding the {@code INVOKESPECIAL} to
+         * {@code <init>}. To avoid this, we add an indirection by invoking {@code <init>} through
+         * {@link MethodHandle#linkToSpecial}.
+         *
+         * The last {@link LambdaForm#Name Name} in the argument's form is expected to be the {@code void}
+         * result of the {@code <init>} invocation. This entry is replaced.
+         */
+        private static MethodHandle linkConstructor(MethodHandle cmh) {
+            final LambdaForm lf = cmh.form;
+            final int initNameIndex = lf.names.length - 1;
+            final Name initName = lf.names[initNameIndex];
+            final MemberName ctorMN = initName.function.member;
+            final MethodType ctorMT = ctorMN.getInvocationType();
+
+            // obtain function member (call target)
+            // linker method type replaces initial parameter (BMH species) with BMH to avoid naming a species (anonymous class!)
+            final MethodType linkerMT = ctorMT.changeParameterType(0, BoundMethodHandle.class).appendParameterTypes(MemberName.class);
+            MemberName linkerMN = new MemberName(MethodHandle.class, "linkToSpecial", linkerMT, REF_invokeStatic);
+            try {
+                linkerMN = MemberName.getFactory().resolveOrFail(REF_invokeStatic, linkerMN, null, NoSuchMethodException.class);
+                assert(linkerMN.isStatic());
+            } catch (ReflectiveOperationException ex) {
+                throw newInternalError(ex);
+            }
+            // extend arguments array
+            Object[] newArgs = Arrays.copyOf(initName.arguments, initName.arguments.length + 1);
+            newArgs[newArgs.length - 1] = ctorMN;
+            // replace function
+            final NamedFunction nf = new NamedFunction(linkerMN);
+            final Name linkedCtor = new Name(nf, newArgs);
+            linkedCtor.initIndex(initNameIndex);
+            lf.names[initNameIndex] = linkedCtor;
+            return cmh;
+        }
+
+    }
+
+    private static final Lookup LOOKUP = Lookup.IMPL_LOOKUP;
+
+    /**
+     * All subclasses must provide such a value describing their type signature.
+     */
+    static final SpeciesData SPECIES_DATA = SpeciesData.EMPTY;
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/CallSite.java b/jdk/src/share/classes/java/lang/invoke/CallSite.java
index 87bf6f5..5d637b9 100644
--- a/jdk/src/share/classes/java/lang/invoke/CallSite.java
+++ b/jdk/src/share/classes/java/lang/invoke/CallSite.java
@@ -26,7 +26,6 @@
 package java.lang.invoke;
 
 import sun.invoke.empty.Empty;
-import sun.misc.Unsafe;
 import static java.lang.invoke.MethodHandleStatics.*;
 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
 
@@ -87,13 +86,9 @@
 public class CallSite {
     static { MethodHandleImpl.initStatics(); }
 
-    // Fields used only by the JVM.  Do not use or change.
-    private MemberName vmmethod; // supplied by the JVM (ref. to calling method)
-    private int        vmindex;  // supplied by the JVM (BCI within calling method)
-
     // The actual payload of this call site:
     /*package-private*/
-    MethodHandle target;
+    MethodHandle target;    // Note: This field is known to the JVM.  Do not change.
 
     /**
      * Make a blank call site object with the given method type.
@@ -152,24 +147,6 @@
         return target.type();
     }
 
-    /** Called from JVM (or low-level Java code) after the BSM returns the newly created CallSite.
-     *  The parameters are JVM-specific.
-     */
-    void initializeFromJVM(String name,
-                           MethodType type,
-                           MemberName callerMethod,
-                           int        callerBCI) {
-        if (this.vmmethod != null) {
-            // FIXME
-            throw new BootstrapMethodError("call site has already been linked to an invokedynamic instruction");
-        }
-        if (!this.type().equals(type)) {
-            throw wrongTargetType(target, type);
-        }
-        this.vmindex  = callerBCI;
-        this.vmmethod = callerMethod;
-    }
-
     /**
      * Returns the target method of the call site, according to the
      * behavior defined by this call site's specific class.
@@ -234,7 +211,7 @@
     public abstract MethodHandle dynamicInvoker();
 
     /*non-public*/ MethodHandle makeDynamicInvoker() {
-        MethodHandle getTarget = MethodHandleImpl.bindReceiver(GET_TARGET, this);
+        MethodHandle getTarget = GET_TARGET.bindReceiver(this);
         MethodHandle invoker = MethodHandles.exactInvoker(this.type());
         return MethodHandles.foldArguments(invoker, getTarget);
     }
@@ -244,8 +221,8 @@
         try {
             GET_TARGET = IMPL_LOOKUP.
                 findVirtual(CallSite.class, "getTarget", MethodType.methodType(MethodHandle.class));
-        } catch (ReflectiveOperationException ignore) {
-            throw new InternalError();
+        } catch (ReflectiveOperationException e) {
+            throw newInternalError(e);
         }
     }
 
@@ -256,12 +233,10 @@
     }
 
     // unsafe stuff:
-    private static final Unsafe unsafe = Unsafe.getUnsafe();
     private static final long TARGET_OFFSET;
-
     static {
         try {
-            TARGET_OFFSET = unsafe.objectFieldOffset(CallSite.class.getDeclaredField("target"));
+            TARGET_OFFSET = UNSAFE.objectFieldOffset(CallSite.class.getDeclaredField("target"));
         } catch (Exception ex) { throw new Error(ex); }
     }
 
@@ -271,7 +246,7 @@
     }
     /*package-private*/
     MethodHandle getTargetVolatile() {
-        return (MethodHandle) unsafe.getObjectVolatile(this, TARGET_OFFSET);
+        return (MethodHandle) UNSAFE.getObjectVolatile(this, TARGET_OFFSET);
     }
     /*package-private*/
     void setTargetVolatile(MethodHandle newTarget) {
@@ -285,8 +260,7 @@
                              // Extra arguments for BSM, if any:
                              Object info,
                              // Caller information:
-                             MemberName callerMethod, int callerBCI) {
-        Class<?> callerClass = callerMethod.getDeclaringClass();
+                             Class<?> callerClass) {
         Object caller = IMPL_LOOKUP.in(callerClass);
         CallSite site;
         try {
diff --git a/jdk/src/share/classes/java/lang/invoke/CountingMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/CountingMethodHandle.java
deleted file mode 100644
index f8a0c6e..0000000
--- a/jdk/src/share/classes/java/lang/invoke/CountingMethodHandle.java
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (c) 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import static java.lang.invoke.MethodHandleNatives.Constants.*;
-
-/**
- * This method handle is used to optionally provide a count of how
- * many times it was invoked.
- *
- * @author never
- */
-class CountingMethodHandle extends AdapterMethodHandle {
-    private int vmcount;
-
-    private CountingMethodHandle(MethodHandle target) {
-        super(target, target.type(), AdapterMethodHandle.makeConv(OP_RETYPE_ONLY));
-    }
-
-    /** Wrap the incoming MethodHandle in a CountingMethodHandle if they are enabled */
-    static MethodHandle wrap(MethodHandle mh) {
-        if (MethodHandleNatives.COUNT_GWT) {
-            return new CountingMethodHandle(mh);
-        }
-        return mh;
-    }
-}
diff --git a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java
index 13bedb1..2adc8e8 100644
--- a/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java
+++ b/jdk/src/share/classes/java/lang/invoke/DirectMethodHandle.java
@@ -25,29 +25,635 @@
 
 package java.lang.invoke;
 
+import sun.misc.Unsafe;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import sun.invoke.util.VerifyAccess;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.LambdaForm.*;
+import static java.lang.invoke.MethodTypeForm.*;
+import static java.lang.invoke.MethodHandleStatics.*;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.Field;
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.VerifyType;
+import sun.invoke.util.Wrapper;
 
 /**
- * The flavor of method handle which emulates invokespecial or invokestatic.
+ * The flavor of method handle which implements a constant reference
+ * to a class member.
  * @author jrose
  */
 class DirectMethodHandle extends MethodHandle {
-    //inherited oop    vmtarget;    // methodOop or virtual class/interface oop
-    private final int  vmindex;     // method index within class or interface
-    { vmindex = VM_INDEX_UNINITIALIZED; }  // JVM may change this
+    final MemberName member;
 
-    // Constructors in this class *must* be package scoped or private.
-    DirectMethodHandle(MethodType mtype, MemberName m, boolean doDispatch, Class<?> lookupClass) {
-        super(mtype);
-
-        assert(m.isMethod() || !doDispatch && m.isConstructor());
-        if (!m.isResolved())
-            throw new InternalError();
-
-        MethodHandleNatives.init(this, (Object) m, doDispatch, lookupClass);
+    // Constructors and factory methods in this class *must* be package scoped or private.
+    private DirectMethodHandle(MethodType mtype, LambdaForm form, MemberName member) {
+        super(mtype, form);
+        if (!member.isResolved())  throw new InternalError();
+        this.member = member;
     }
 
-    boolean isValid() {
-        return (vmindex != VM_INDEX_UNINITIALIZED);
+    // Factory methods:
+
+    static DirectMethodHandle make(Class<?> receiver, MemberName member) {
+        MethodType mtype = member.getMethodOrFieldType();
+        if (!member.isStatic()) {
+            if (!member.getDeclaringClass().isAssignableFrom(receiver) || member.isConstructor())
+                throw new InternalError(member.toString());
+            mtype = mtype.insertParameterTypes(0, receiver);
+        }
+        if (!member.isField()) {
+            LambdaForm lform = preparedLambdaForm(member);
+            return new DirectMethodHandle(mtype, lform, member);
+        } else {
+            LambdaForm lform = preparedFieldLambdaForm(member);
+            if (member.isStatic()) {
+                long offset = MethodHandleNatives.staticFieldOffset(member);
+                Object base = MethodHandleNatives.staticFieldBase(member);
+                return new StaticAccessor(mtype, lform, member, base, offset);
+            } else {
+                long offset = MethodHandleNatives.objectFieldOffset(member);
+                assert(offset == (int)offset);
+                return new Accessor(mtype, lform, member, (int)offset);
+            }
+        }
+    }
+    static DirectMethodHandle make(MemberName member) {
+        if (member.isConstructor())
+            return makeAllocator(member);
+        return make(member.getDeclaringClass(), member);
+    }
+    static DirectMethodHandle make(Method method) {
+        return make(method.getDeclaringClass(), new MemberName(method));
+    }
+    static DirectMethodHandle make(Field field) {
+        return make(field.getDeclaringClass(), new MemberName(field));
+    }
+    private static DirectMethodHandle makeAllocator(MemberName ctor) {
+        assert(ctor.isConstructor() && ctor.getName().equals("<init>"));
+        Class<?> instanceClass = ctor.getDeclaringClass();
+        ctor = ctor.asConstructor();
+        assert(ctor.isConstructor() && ctor.getReferenceKind() == REF_newInvokeSpecial) : ctor;
+        MethodType mtype = ctor.getMethodType().changeReturnType(instanceClass);
+        LambdaForm lform = preparedLambdaForm(ctor);
+        MemberName init = ctor.asSpecial();
+        assert(init.getMethodType().returnType() == void.class);
+        return new Constructor(mtype, lform, ctor, init, instanceClass);
+    }
+
+    @Override
+    MethodHandle copyWith(MethodType mt, LambdaForm lf) {
+        return new DirectMethodHandle(mt, lf, member);
+    }
+
+    @Override
+    String internalProperties() {
+        return "/DMH="+member.toString();
+    }
+
+    //// Implementation methods.
+    @Override
+    @ForceInline
+    MemberName internalMemberName() {
+        return member;
+    }
+
+    @Override
+    MethodHandle bindArgument(int pos, char basicType, Object value) {
+        // If the member needs dispatching, do so.
+        if (pos == 0 && basicType == 'L') {
+            DirectMethodHandle concrete = maybeRebind(value);
+            if (concrete != null)
+                return concrete.bindReceiver(value);
+        }
+        return super.bindArgument(pos, basicType, value);
+    }
+
+    @Override
+    MethodHandle bindReceiver(Object receiver) {
+        // If the member needs dispatching, do so.
+        DirectMethodHandle concrete = maybeRebind(receiver);
+        if (concrete != null)
+            return concrete.bindReceiver(receiver);
+        return super.bindReceiver(receiver);
+    }
+
+    private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+
+    private DirectMethodHandle maybeRebind(Object receiver) {
+        if (receiver != null) {
+            switch (member.getReferenceKind()) {
+            case REF_invokeInterface:
+            case REF_invokeVirtual:
+                // Pre-dispatch the member.
+                Class<?> concreteClass = receiver.getClass();
+                MemberName concrete = new MemberName(concreteClass, member.getName(), member.getMethodType(), REF_invokeSpecial);
+                concrete = IMPL_NAMES.resolveOrNull(REF_invokeSpecial, concrete, concreteClass);
+                if (concrete != null)
+                    return new DirectMethodHandle(type(), preparedLambdaForm(concrete), concrete);
+                break;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Create a LF which can invoke the given method.
+     * Cache and share this structure among all methods with
+     * the same basicType and refKind.
+     */
+    private static LambdaForm preparedLambdaForm(MemberName m) {
+        assert(m.isInvocable()) : m;  // call preparedFieldLambdaForm instead
+        MethodType mtype = m.getInvocationType().basicType();
+        assert(!m.isMethodHandleInvoke() || "invokeBasic".equals(m.getName())) : m;
+        int which;
+        switch (m.getReferenceKind()) {
+        case REF_invokeVirtual:    which = LF_INVVIRTUAL;    break;
+        case REF_invokeStatic:     which = LF_INVSTATIC;     break;
+        case REF_invokeSpecial:    which = LF_INVSPECIAL;    break;
+        case REF_invokeInterface:  which = LF_INVINTERFACE;  break;
+        case REF_newInvokeSpecial: which = LF_NEWINVSPECIAL; break;
+        default:  throw new InternalError(m.toString());
+        }
+        if (which == LF_INVSTATIC && shouldBeInitialized(m)) {
+            // precompute the barrier-free version:
+            preparedLambdaForm(mtype, which);
+            which = LF_INVSTATIC_INIT;
+        }
+        LambdaForm lform = preparedLambdaForm(mtype, which);
+        maybeCompile(lform, m);
+        assert(lform.methodType().dropParameterTypes(0, 1)
+                .equals(m.getInvocationType().basicType()))
+                : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
+        return lform;
+    }
+
+    private static LambdaForm preparedLambdaForm(MethodType mtype, int which) {
+        LambdaForm lform = mtype.form().cachedLambdaForm(which);
+        if (lform != null)  return lform;
+        lform = makePreparedLambdaForm(mtype, which);
+        return mtype.form().setCachedLambdaForm(which, lform);
+    }
+
+    private static LambdaForm makePreparedLambdaForm(MethodType mtype, int which) {
+        boolean needsInit = (which == LF_INVSTATIC_INIT);
+        boolean doesAlloc = (which == LF_NEWINVSPECIAL);
+        String linkerName, lambdaName;
+        switch (which) {
+        case LF_INVVIRTUAL:    linkerName = "linkToVirtual";    lambdaName = "DMH.invokeVirtual";    break;
+        case LF_INVSTATIC:     linkerName = "linkToStatic";     lambdaName = "DMH.invokeStatic";     break;
+        case LF_INVSTATIC_INIT:linkerName = "linkToStatic";     lambdaName = "DMH.invokeStaticInit"; break;
+        case LF_INVSPECIAL:    linkerName = "linkToSpecial";    lambdaName = "DMH.invokeSpecial";    break;
+        case LF_INVINTERFACE:  linkerName = "linkToInterface";  lambdaName = "DMH.invokeInterface";  break;
+        case LF_NEWINVSPECIAL: linkerName = "linkToSpecial";    lambdaName = "DMH.newInvokeSpecial"; break;
+        default:  throw new InternalError("which="+which);
+        }
+        MethodType mtypeWithArg = mtype.appendParameterTypes(MemberName.class);
+        if (doesAlloc)
+            mtypeWithArg = mtypeWithArg
+                    .insertParameterTypes(0, Object.class)  // insert newly allocated obj
+                    .changeReturnType(void.class);          // <init> returns void
+        MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
+        try {
+            linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+        final int DMH_THIS    = 0;
+        final int ARG_BASE    = 1;
+        final int ARG_LIMIT   = ARG_BASE + mtype.parameterCount();
+        int nameCursor = ARG_LIMIT;
+        final int NEW_OBJ     = (doesAlloc ? nameCursor++ : -1);
+        final int GET_MEMBER  = nameCursor++;
+        final int LINKER_CALL = nameCursor++;
+        Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
+        assert(names.length == nameCursor);
+        if (doesAlloc) {
+            // names = { argx,y,z,... new C, init method }
+            names[NEW_OBJ] = new Name(NF_allocateInstance, names[DMH_THIS]);
+            names[GET_MEMBER] = new Name(NF_constructorMethod, names[DMH_THIS]);
+        } else if (needsInit) {
+            names[GET_MEMBER] = new Name(NF_internalMemberNameEnsureInit, names[DMH_THIS]);
+        } else {
+            names[GET_MEMBER] = new Name(NF_internalMemberName, names[DMH_THIS]);
+        }
+        Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, GET_MEMBER+1, Object[].class);
+        assert(outArgs[outArgs.length-1] == names[GET_MEMBER]);  // look, shifted args!
+        int result = LambdaForm.LAST_RESULT;
+        if (doesAlloc) {
+            assert(outArgs[outArgs.length-2] == names[NEW_OBJ]);  // got to move this one
+            System.arraycopy(outArgs, 0, outArgs, 1, outArgs.length-2);
+            outArgs[0] = names[NEW_OBJ];
+            result = NEW_OBJ;
+        }
+        names[LINKER_CALL] = new Name(linker, outArgs);
+        lambdaName += "_" + LambdaForm.basicTypeSignature(mtype);
+        LambdaForm lform = new LambdaForm(lambdaName, ARG_LIMIT, names, result);
+        // This is a tricky bit of code.  Don't send it through the LF interpreter.
+        lform.compileToBytecode();
+        return lform;
+    }
+
+    private static void maybeCompile(LambdaForm lform, MemberName m) {
+        if (VerifyAccess.isSamePackage(m.getDeclaringClass(), MethodHandle.class))
+            // Help along bootstrapping...
+            lform.compileToBytecode();
+    }
+
+    /** Static wrapper for DirectMethodHandle.internalMemberName. */
+    @ForceInline
+    /*non-public*/ static Object internalMemberName(Object mh) {
+        return ((DirectMethodHandle)mh).member;
+    }
+
+    /** Static wrapper for DirectMethodHandle.internalMemberName.
+     * This one also forces initialization.
+     */
+    /*non-public*/ static Object internalMemberNameEnsureInit(Object mh) {
+        DirectMethodHandle dmh = (DirectMethodHandle)mh;
+        dmh.ensureInitialized();
+        return dmh.member;
+    }
+
+    /*non-public*/ static
+    boolean shouldBeInitialized(MemberName member) {
+        switch (member.getReferenceKind()) {
+        case REF_invokeStatic:
+        case REF_getStatic:
+        case REF_putStatic:
+        case REF_newInvokeSpecial:
+            break;
+        default:
+            // No need to initialize the class on this kind of member.
+            return false;
+        }
+        Class<?> cls = member.getDeclaringClass();
+        if (cls == ValueConversions.class ||
+            cls == MethodHandleImpl.class ||
+            cls == Invokers.class) {
+            // These guys have lots of <clinit> DMH creation but we know
+            // the MHs will not be used until the system is booted.
+            return false;
+        }
+        if (VerifyAccess.isSamePackage(MethodHandle.class, cls) ||
+            VerifyAccess.isSamePackage(ValueConversions.class, cls)) {
+            // It is a system class.  It is probably in the process of
+            // being initialized, but we will help it along just to be safe.
+            if (UNSAFE.shouldBeInitialized(cls)) {
+                UNSAFE.ensureClassInitialized(cls);
+            }
+            return false;
+        }
+        return UNSAFE.shouldBeInitialized(cls);
+    }
+
+    private static class EnsureInitialized extends ClassValue<WeakReference<Thread>> {
+        @Override
+        protected WeakReference<Thread> computeValue(Class<?> type) {
+            UNSAFE.ensureClassInitialized(type);
+            if (UNSAFE.shouldBeInitialized(type))
+                // If the previous call didn't block, this can happen.
+                // We are executing inside <clinit>.
+                return new WeakReference<>(Thread.currentThread());
+            return null;
+        }
+        static final EnsureInitialized INSTANCE = new EnsureInitialized();
+    }
+
+    private void ensureInitialized() {
+        if (checkInitialized(member)) {
+            // The coast is clear.  Delete the <clinit> barrier.
+            if (member.isField())
+                updateForm(preparedFieldLambdaForm(member));
+            else
+                updateForm(preparedLambdaForm(member));
+        }
+    }
+    private static boolean checkInitialized(MemberName member) {
+        Class<?> defc = member.getDeclaringClass();
+        WeakReference<Thread> ref = EnsureInitialized.INSTANCE.get(defc);
+        if (ref == null) {
+            return true;  // the final state
+        }
+        Thread clinitThread = ref.get();
+        // Somebody may still be running defc.<clinit>.
+        if (clinitThread == Thread.currentThread()) {
+            // If anybody is running defc.<clinit>, it is this thread.
+            if (UNSAFE.shouldBeInitialized(defc))
+                // Yes, we are running it; keep the barrier for now.
+                return false;
+        } else {
+            // We are in a random thread.  Block.
+            UNSAFE.ensureClassInitialized(defc);
+        }
+        assert(!UNSAFE.shouldBeInitialized(defc));
+        // put it into the final state
+        EnsureInitialized.INSTANCE.remove(defc);
+        return true;
+    }
+
+    /*non-public*/ static void ensureInitialized(Object mh) {
+        ((DirectMethodHandle)mh).ensureInitialized();
+    }
+
+    /** This subclass handles constructor references. */
+    static class Constructor extends DirectMethodHandle {
+        final MemberName initMethod;
+        final Class<?>   instanceClass;
+
+        private Constructor(MethodType mtype, LambdaForm form, MemberName constructor,
+                            MemberName initMethod, Class<?> instanceClass) {
+            super(mtype, form, constructor);
+            this.initMethod = initMethod;
+            this.instanceClass = instanceClass;
+            assert(initMethod.isResolved());
+        }
+    }
+
+    /*non-public*/ static Object constructorMethod(Object mh) {
+        Constructor dmh = (Constructor)mh;
+        return dmh.initMethod;
+    }
+
+    /*non-public*/ static Object allocateInstance(Object mh) throws InstantiationException {
+        Constructor dmh = (Constructor)mh;
+        return UNSAFE.allocateInstance(dmh.instanceClass);
+    }
+
+    /** This subclass handles non-static field references. */
+    static class Accessor extends DirectMethodHandle {
+        final Class<?> fieldType;
+        final int      fieldOffset;
+        private Accessor(MethodType mtype, LambdaForm form, MemberName member,
+                         int fieldOffset) {
+            super(mtype, form, member);
+            this.fieldType   = member.getFieldType();
+            this.fieldOffset = fieldOffset;
+        }
+
+        @Override Object checkCast(Object obj) {
+            return fieldType.cast(obj);
+        }
+    }
+
+    @ForceInline
+    /*non-public*/ static long fieldOffset(Object accessorObj) {
+        // Note: We return a long because that is what Unsafe.getObject likes.
+        // We store a plain int because it is more compact.
+        return ((Accessor)accessorObj).fieldOffset;
+    }
+
+    @ForceInline
+    /*non-public*/ static Object checkBase(Object obj) {
+        // Note that the object's class has already been verified,
+        // since the parameter type of the Accessor method handle
+        // is either member.getDeclaringClass or a subclass.
+        // This was verified in DirectMethodHandle.make.
+        // Therefore, the only remaining check is for null.
+        // Since this check is *not* guaranteed by Unsafe.getInt
+        // and its siblings, we need to make an explicit one here.
+        obj.getClass();  // maybe throw NPE
+        return obj;
+    }
+
+    /** This subclass handles static field references. */
+    static class StaticAccessor extends DirectMethodHandle {
+        final private Class<?> fieldType;
+        final private Object   staticBase;
+        final private long     staticOffset;
+
+        private StaticAccessor(MethodType mtype, LambdaForm form, MemberName member,
+                               Object staticBase, long staticOffset) {
+            super(mtype, form, member);
+            this.fieldType    = member.getFieldType();
+            this.staticBase   = staticBase;
+            this.staticOffset = staticOffset;
+        }
+
+        @Override Object checkCast(Object obj) {
+            return fieldType.cast(obj);
+        }
+    }
+
+    @ForceInline
+    /*non-public*/ static Object nullCheck(Object obj) {
+        obj.getClass();
+        return obj;
+    }
+
+    @ForceInline
+    /*non-public*/ static Object staticBase(Object accessorObj) {
+        return ((StaticAccessor)accessorObj).staticBase;
+    }
+
+    @ForceInline
+    /*non-public*/ static long staticOffset(Object accessorObj) {
+        return ((StaticAccessor)accessorObj).staticOffset;
+    }
+
+    @ForceInline
+    /*non-public*/ static Object checkCast(Object mh, Object obj) {
+        return ((DirectMethodHandle) mh).checkCast(obj);
+    }
+
+    Object checkCast(Object obj) {
+        return member.getReturnType().cast(obj);
+    }
+
+    // Caching machinery for field accessors:
+    private static byte
+            AF_GETFIELD        = 0,
+            AF_PUTFIELD        = 1,
+            AF_GETSTATIC       = 2,
+            AF_PUTSTATIC       = 3,
+            AF_GETSTATIC_INIT  = 4,
+            AF_PUTSTATIC_INIT  = 5,
+            AF_LIMIT           = 6;
+    // Enumerate the different field kinds using Wrapper,
+    // with an extra case added for checked references.
+    private static int
+            FT_LAST_WRAPPER    = Wrapper.values().length-1,
+            FT_UNCHECKED_REF   = Wrapper.OBJECT.ordinal(),
+            FT_CHECKED_REF     = FT_LAST_WRAPPER+1,
+            FT_LIMIT           = FT_LAST_WRAPPER+2;
+    private static int afIndex(byte formOp, boolean isVolatile, int ftypeKind) {
+        return ((formOp * FT_LIMIT * 2)
+                + (isVolatile ? FT_LIMIT : 0)
+                + ftypeKind);
+    }
+    private static final LambdaForm[] ACCESSOR_FORMS
+            = new LambdaForm[afIndex(AF_LIMIT, false, 0)];
+    private static int ftypeKind(Class<?> ftype) {
+        if (ftype.isPrimitive())
+            return Wrapper.forPrimitiveType(ftype).ordinal();
+        else if (VerifyType.isNullReferenceConversion(Object.class, ftype))
+            return FT_UNCHECKED_REF;
+        else
+            return FT_CHECKED_REF;
+    }
+
+    /**
+     * Create a LF which can access the given field.
+     * Cache and share this structure among all fields with
+     * the same basicType and refKind.
+     */
+    private static LambdaForm preparedFieldLambdaForm(MemberName m) {
+        Class<?> ftype = m.getFieldType();
+        boolean isVolatile = m.isVolatile();
+        byte formOp;
+        switch (m.getReferenceKind()) {
+        case REF_getField:      formOp = AF_GETFIELD;    break;
+        case REF_putField:      formOp = AF_PUTFIELD;    break;
+        case REF_getStatic:     formOp = AF_GETSTATIC;   break;
+        case REF_putStatic:     formOp = AF_PUTSTATIC;   break;
+        default:  throw new InternalError(m.toString());
+        }
+        if (shouldBeInitialized(m)) {
+            // precompute the barrier-free version:
+            preparedFieldLambdaForm(formOp, isVolatile, ftype);
+            assert((AF_GETSTATIC_INIT - AF_GETSTATIC) ==
+                   (AF_PUTSTATIC_INIT - AF_PUTSTATIC));
+            formOp += (AF_GETSTATIC_INIT - AF_GETSTATIC);
+        }
+        LambdaForm lform = preparedFieldLambdaForm(formOp, isVolatile, ftype);
+        maybeCompile(lform, m);
+        assert(lform.methodType().dropParameterTypes(0, 1)
+                .equals(m.getInvocationType().basicType()))
+                : Arrays.asList(m, m.getInvocationType().basicType(), lform, lform.methodType());
+        return lform;
+    }
+    private static LambdaForm preparedFieldLambdaForm(byte formOp, boolean isVolatile, Class<?> ftype) {
+        int afIndex = afIndex(formOp, isVolatile, ftypeKind(ftype));
+        LambdaForm lform = ACCESSOR_FORMS[afIndex];
+        if (lform != null)  return lform;
+        lform = makePreparedFieldLambdaForm(formOp, isVolatile, ftypeKind(ftype));
+        ACCESSOR_FORMS[afIndex] = lform;  // don't bother with a CAS
+        return lform;
+    }
+
+    private static LambdaForm makePreparedFieldLambdaForm(byte formOp, boolean isVolatile, int ftypeKind) {
+        boolean isGetter  = (formOp & 1) == (AF_GETFIELD & 1);
+        boolean isStatic  = (formOp >= AF_GETSTATIC);
+        boolean needsInit = (formOp >= AF_GETSTATIC_INIT);
+        boolean needsCast = (ftypeKind == FT_CHECKED_REF);
+        Wrapper fw = (needsCast ? Wrapper.OBJECT : Wrapper.values()[ftypeKind]);
+        Class<?> ft = fw.primitiveType();
+        assert(ftypeKind(needsCast ? String.class : ft) == ftypeKind);
+        String tname  = fw.primitiveSimpleName();
+        String ctname = Character.toUpperCase(tname.charAt(0)) + tname.substring(1);
+        if (isVolatile)  ctname += "Volatile";
+        String getOrPut = (isGetter ? "get" : "put");
+        String linkerName = (getOrPut + ctname);  // getObject, putIntVolatile, etc.
+        MethodType linkerType;
+        if (isGetter)
+            linkerType = MethodType.methodType(ft, Object.class, long.class);
+        else
+            linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
+        MemberName linker = new MemberName(Unsafe.class, linkerName, linkerType, REF_invokeVirtual);
+        try {
+            linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+
+        // What is the external type of the lambda form?
+        MethodType mtype;
+        if (isGetter)
+            mtype = MethodType.methodType(ft);
+        else
+            mtype = MethodType.methodType(void.class, ft);
+        mtype = mtype.basicType();  // erase short to int, etc.
+        if (!isStatic)
+            mtype = mtype.insertParameterTypes(0, Object.class);
+        final int DMH_THIS  = 0;
+        final int ARG_BASE  = 1;
+        final int ARG_LIMIT = ARG_BASE + mtype.parameterCount();
+        // if this is for non-static access, the base pointer is stored at this index:
+        final int OBJ_BASE  = isStatic ? -1 : ARG_BASE;
+        // if this is for write access, the value to be written is stored at this index:
+        final int SET_VALUE  = isGetter ? -1 : ARG_LIMIT - 1;
+        int nameCursor = ARG_LIMIT;
+        final int F_HOLDER  = (isStatic ? nameCursor++ : -1);  // static base if any
+        final int F_OFFSET  = nameCursor++;  // Either static offset or field offset.
+        final int OBJ_CHECK = (OBJ_BASE >= 0 ? nameCursor++ : -1);
+        final int INIT_BAR  = (needsInit ? nameCursor++ : -1);
+        final int PRE_CAST  = (needsCast && !isGetter ? nameCursor++ : -1);
+        final int LINKER_CALL = nameCursor++;
+        final int POST_CAST = (needsCast && isGetter ? nameCursor++ : -1);
+        final int RESULT    = nameCursor-1;  // either the call or the cast
+        Name[] names = arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
+        if (needsInit)
+            names[INIT_BAR] = new Name(NF_ensureInitialized, names[DMH_THIS]);
+        if (needsCast && !isGetter)
+            names[PRE_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[SET_VALUE]);
+        Object[] outArgs = new Object[1 + linkerType.parameterCount()];
+        assert(outArgs.length == (isGetter ? 3 : 4));
+        outArgs[0] = UNSAFE;
+        if (isStatic) {
+            outArgs[1] = names[F_HOLDER]  = new Name(NF_staticBase, names[DMH_THIS]);
+            outArgs[2] = names[F_OFFSET]  = new Name(NF_staticOffset, names[DMH_THIS]);
+        } else {
+            outArgs[1] = names[OBJ_CHECK] = new Name(NF_checkBase, names[OBJ_BASE]);
+            outArgs[2] = names[F_OFFSET]  = new Name(NF_fieldOffset, names[DMH_THIS]);
+        }
+        if (!isGetter) {
+            outArgs[3] = (needsCast ? names[PRE_CAST] : names[SET_VALUE]);
+        }
+        for (Object a : outArgs)  assert(a != null);
+        names[LINKER_CALL] = new Name(linker, outArgs);
+        if (needsCast && isGetter)
+            names[POST_CAST] = new Name(NF_checkCast, names[DMH_THIS], names[LINKER_CALL]);
+        for (Name n : names)  assert(n != null);
+        String fieldOrStatic = (isStatic ? "Static" : "Field");
+        String lambdaName = (linkerName + fieldOrStatic);  // significant only for debugging
+        if (needsCast)  lambdaName += "Cast";
+        if (needsInit)  lambdaName += "Init";
+        return new LambdaForm(lambdaName, ARG_LIMIT, names, RESULT);
+    }
+
+    private static final NamedFunction
+            NF_internalMemberName,
+            NF_internalMemberNameEnsureInit,
+            NF_ensureInitialized,
+            NF_fieldOffset,
+            NF_checkBase,
+            NF_staticBase,
+            NF_staticOffset,
+            NF_checkCast,
+            NF_allocateInstance,
+            NF_constructorMethod;
+    static {
+        try {
+            NamedFunction nfs[] = {
+                NF_internalMemberName = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("internalMemberName", Object.class)),
+                NF_internalMemberNameEnsureInit = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("internalMemberNameEnsureInit", Object.class)),
+                NF_ensureInitialized = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("ensureInitialized", Object.class)),
+                NF_fieldOffset = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("fieldOffset", Object.class)),
+                NF_checkBase = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("checkBase", Object.class)),
+                NF_staticBase = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("staticBase", Object.class)),
+                NF_staticOffset = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("staticOffset", Object.class)),
+                NF_checkCast = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("checkCast", Object.class, Object.class)),
+                NF_allocateInstance = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("allocateInstance", Object.class)),
+                NF_constructorMethod = new NamedFunction(DirectMethodHandle.class
+                    .getDeclaredMethod("constructorMethod", Object.class))
+            };
+            for (NamedFunction nf : nfs) {
+                // Each nf must be statically invocable or we get tied up in our bootstraps.
+                assert(InvokerBytecodeGenerator.isStaticallyInvocable(nf.member)) : nf;
+                nf.resolve();
+            }
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
     }
 }
diff --git a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c b/jdk/src/share/classes/java/lang/invoke/DontInline.java
similarity index 65%
rename from jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
rename to jdk/src/share/classes/java/lang/invoke/DontInline.java
index 089afbd..1bd969e 100644
--- a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
+++ b/jdk/src/share/classes/java/lang/invoke/DontInline.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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,22 +23,15 @@
  * questions.
  */
 
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
+package java.lang.invoke;
 
-#include "sun_rmi_server_MarshalInputStream.h"
+import java.lang.annotation.*;
 
-/*
- * Class:     sun_rmi_server_MarshalInputStream
- * Method:    latestUserDefinedLoader
- * Signature: ()Ljava/lang/ClassLoader;
- *
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
+/**
+ * Internal marker for some methods in the JSR 292 implementation.
  */
-JNIEXPORT jobject JNICALL
-Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader(JNIEnv *env, jclass cls)
-{
-    return JVM_LatestUserDefinedLoader(env);
+/*non-public*/
+@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+@Retention(RetentionPolicy.RUNTIME)
+@interface DontInline {
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/FilterGeneric.java b/jdk/src/share/classes/java/lang/invoke/FilterGeneric.java
deleted file mode 100644
index 31aa02a..0000000
--- a/jdk/src/share/classes/java/lang/invoke/FilterGeneric.java
+++ /dev/null
@@ -1,4500 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import java.lang.reflect.*;
-import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * These adapters apply arbitrary conversions to arguments
- * on the way to a ultimate target.
- * For simplicity, these are all generically typed.
- * @author jrose
- */
-class FilterGeneric {
-    // type for the incoming call (will be generic)
-    private final MethodType entryType;
-    // prototype adapters (clone and customize for each new target & conversion!)
-    private final Adapter[] adapters;
-
-    /** Compute and cache information common to all filtering adapters
-     *  with the given generic type
-     */
-    FilterGeneric(MethodType entryType) {
-        this.entryType = entryType;
-        int tableSize = Kind.LIMIT.invokerIndex(1 + entryType.parameterCount());
-        this.adapters = new Adapter[tableSize];
-    }
-
-    Adapter getAdapter(Kind kind, int pos) {
-        int index = kind.invokerIndex(pos);
-        Adapter ad = adapters[index];
-        if (ad != null)  return ad;
-        ad = findAdapter(entryType, kind, pos);
-        if (ad == null)
-            ad = buildAdapterFromBytecodes(entryType, kind, pos);
-        adapters[index] = ad;
-        return ad;
-    }
-
-    static {
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
-    }
-
-    Adapter makeInstance(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
-        Adapter ad = getAdapter(kind, pos);
-        return ad.makeInstance(ad.prototypeEntryPoint(), filter, target);
-    }
-
-    /** Build an adapter of the given generic type, which invokes filter
-     *  on the selected incoming argument before passing it to the target.
-     * @param pos the argument to filter
-     * @param filter the function to call on the argument
-     * @param target the target to call with the modified argument list
-     * @return an adapter method handle
-     */
-    public static MethodHandle makeArgumentFilter(int pos, MethodHandle filter, MethodHandle target) {
-        return make(Kind.value, pos, filter, target);
-    }
-
-    /** Build an adapter of the given generic type, which invokes a combiner
-     *  on a selected group of leading arguments.
-     *  The result of the combiner is prepended before all those arguments.
-     * @param combiner the function to call on the selected leading arguments
-     * @param target the target to call with the modified argument list
-     * @return an adapter method handle
-     */
-    public static MethodHandle makeArgumentFolder(MethodHandle combiner, MethodHandle target) {
-        int num = combiner.type().parameterCount();
-        return make(Kind.fold, num, combiner, target);
-    }
-
-    /** Build an adapter of the given generic type, which invokes a filter
-     *  on the incoming arguments, reified as a group.
-     *  The argument may be modified (by side effects in the filter).
-     *  The arguments, possibly modified, are passed on to the target.
-     * @param filter the function to call on the arguments
-     * @param target the target to call with the possibly-modified argument list
-     * @return an adapter method handle
-     */
-    public static MethodHandle makeFlyby(MethodHandle filter, MethodHandle target) {
-        return make(Kind.flyby, 0, filter, target);
-    }
-
-    /** Build an adapter of the given generic type, which invokes a collector
-     *  on the selected incoming argument and all following arguments.
-     *  The result of the collector replaces all those arguments.
-     * @param collector the function to call on the selected trailing arguments
-     * @param target the target to call with the modified argument list
-     * @return an adapter method handle
-     */
-    public static MethodHandle makeArgumentCollector(MethodHandle collector, MethodHandle target) {
-        int pos = target.type().parameterCount() - 1;
-        return make(Kind.collect, pos, collector, target);
-    }
-
-    static MethodHandle make(Kind kind, int pos, MethodHandle filter, MethodHandle target) {
-        FilterGeneric fgen = of(kind, pos, filter.type(), target.type());
-        return fgen.makeInstance(kind, pos, filter, target);
-    }
-
-    /** Return the adapter information for this target and filter type. */
-    static FilterGeneric of(Kind kind, int pos, MethodType filterType, MethodType targetType) {
-        MethodType entryType = entryType(kind, pos, filterType, targetType);
-        if (entryType.generic() != entryType)
-            throw newIllegalArgumentException("must be generic: "+entryType);
-        MethodTypeForm form = entryType.form();
-        FilterGeneric filterGen = form.filterGeneric;
-        if (filterGen == null)
-            form.filterGeneric = filterGen = new FilterGeneric(entryType);
-        return filterGen;
-    }
-
-    public String toString() {
-        return "FilterGeneric/"+entryType;
-    }
-
-    static MethodType targetType(MethodType entryType, Kind kind, int pos, MethodType filterType) {
-        MethodType type = entryType;
-        switch (kind) {
-            case value:
-            case flyby:
-                break;  // no change
-            case fold:
-                type = type.insertParameterTypes(0, filterType.returnType());
-                break;
-            case collect:
-                type = type.dropParameterTypes(pos, type.parameterCount());
-                type = type.insertParameterTypes(pos, filterType.returnType());
-                break;
-            default:
-                throw new InternalError();
-        }
-        return type;
-    }
-
-    static MethodType entryType(Kind kind, int pos, MethodType filterType, MethodType targetType) {
-        MethodType type = targetType;
-        switch (kind) {
-            case value:
-            case flyby:
-                break;  // no change
-            case fold:
-                type = type.dropParameterTypes(0, 1);
-                break;
-            case collect:
-                type = type.dropParameterTypes(pos, pos+1);
-                type = type.insertParameterTypes(pos, filterType.parameterList());
-                break;
-            default:
-                throw new InternalError();
-        }
-        return type;
-    }
-
-    /* Create an adapter that handles spreading calls for the given type. */
-    static Adapter findAdapter(MethodType entryType, Kind kind, int pos) {
-        int argc = entryType.parameterCount();
-        String cname0 = "F"+argc;
-        String cname1 = "F"+argc+kind.key;
-        String[] cnames = { cname0, cname1 };
-        String iname = kind.invokerName(pos);
-        // e.g., F5; invoke_C3
-        for (String cname : cnames) {
-            Class<? extends Adapter> acls = Adapter.findSubClass(cname);
-            if (acls == null)  continue;
-            // see if it has the required invoke method
-            MethodHandle entryPoint = null;
-            try {
-                entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
-            } catch (ReflectiveOperationException ex) {
-            }
-            if (entryPoint == null)  continue;
-            Constructor<? extends Adapter> ctor = null;
-            try {
-                ctor = acls.getDeclaredConstructor(MethodHandle.class);
-            } catch (NoSuchMethodException ex) {
-            } catch (SecurityException ex) {
-            }
-            if (ctor == null)  continue;
-            try {
-                // Produce an instance configured as a prototype.
-                return ctor.newInstance(entryPoint);
-            } catch (IllegalArgumentException ex) {
-            } catch (InvocationTargetException wex) {
-                Throwable ex = wex.getTargetException();
-                if (ex instanceof Error)  throw (Error)ex;
-                if (ex instanceof RuntimeException)  throw (RuntimeException)ex;
-            } catch (InstantiationException ex) {
-            } catch (IllegalAccessException ex) {
-            }
-        }
-        return null;
-    }
-
-    static Adapter buildAdapterFromBytecodes(MethodType entryType, Kind kind, int pos) {
-        throw new UnsupportedOperationException("NYI");
-    }
-
-    /**
-     * This adapter takes some untyped arguments, and returns an untyped result.
-     * Internally, it applies the invoker to the target, which causes the
-     * objects to be unboxed; the result is a raw type in L/I/J/F/D.
-     * This result is passed to convert, which is responsible for
-     * converting the raw result into a boxed object.
-     * The invoker is kept separate from the target because it can be
-     * generated once per type erasure family, and reused across adapters.
-     */
-    static abstract class Adapter extends BoundMethodHandle {
-        protected final MethodHandle filter; // transforms one or more arguments
-        protected final MethodHandle target; // ultimate target
-
-        @Override
-        String debugString() {
-            return addTypeString(target, this);
-        }
-
-        protected boolean isPrototype() { return target == null; }
-        protected Adapter(MethodHandle entryPoint) {
-            this(entryPoint, entryPoint, null);
-            assert(isPrototype());
-        }
-        protected MethodHandle prototypeEntryPoint() {
-            if (!isPrototype())  throw new InternalError();
-            return filter;
-        }
-
-        protected Adapter(MethodHandle entryPoint,
-                          MethodHandle filter, MethodHandle target) {
-            super(entryPoint);
-            this.filter = filter;
-            this.target = target;
-        }
-
-        /** Make a copy of self, with new fields. */
-        protected abstract Adapter makeInstance(MethodHandle entryPoint,
-                MethodHandle filter, MethodHandle target);
-        // { return new ThisType(entryPoint, filter, target); }
-
-        static private final String CLASS_PREFIX; // "java.lang.invoke.FilterGeneric$"
-        static {
-            String aname = Adapter.class.getName();
-            String sname = Adapter.class.getSimpleName();
-            if (!aname.endsWith(sname))  throw new InternalError();
-            CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
-        }
-        /** Find a sibing class of Adapter. */
-        static Class<? extends Adapter> findSubClass(String name) {
-            String cname = Adapter.CLASS_PREFIX + name;
-            try {
-                return Class.forName(cname).asSubclass(Adapter.class);
-            } catch (ClassNotFoundException ex) {
-                return null;
-            } catch (ClassCastException ex) {
-                return null;
-            }
-        }
-    }
-
-    static enum Kind {
-        value('V'),      // filter and replace Nth argument value
-        fold('F'),       // fold first N arguments, prepend result
-        collect('C'),    // collect last N arguments, replace with result
-        flyby('Y'),      // reify entire argument list, filter, pass to target
-        LIMIT('?');
-        static final int COUNT = LIMIT.ordinal();
-
-        final char key;
-        Kind(char key) { this.key = key; }
-        String invokerName(int pos) { return "invoke_"+key+""+pos; }
-        int invokerIndex(int pos) { return pos * COUNT + ordinal(); }
-    }
-
-    /* generated classes follow this pattern:
-    static class F1X extends Adapter {
-        protected F1X(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F1X(MethodHandle e, MethodHandle f, MethodHandle t)
-                        { super(e, f, t); }
-        protected F1X makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
-                        { return new F1X(e, f, t); }
-        protected Object invoke_V0(Object a0) { return target.invokeExact(filter.invokeExact(a0)); }
-        protected Object invoke_F0(Object a0) { return target.invokeExact(filter.invokeExact(), a0); }
-        protected Object invoke_F1(Object a0) { return target.invokeExact(filter.invokeExact(a0), a0); }
-        protected Object invoke_C0(Object a0) { return target.invokeExact(filter.invokeExact(a0)); }
-        protected Object invoke_C1(Object a0) { return target.invokeExact(a0, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0) { Object[] av = { a0 };
-                       filter.invokeExact(av); return target.invokeExact(av[0]); }
-    }
-    static class F2X extends Adapter {
-        protected F2X(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F2X(MethodHandle e, MethodHandle f, MethodHandle t)
-                        { super(e, f, t); }
-        protected F2X makeInstance(MethodHandle e, MethodHandle f, MethodHandle t)
-                        { return new F2X(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0), a1); }
-        protected Object invoke_V1(Object a0, Object a1) { return target.invokeExact(a0, filter.invokeExact(a1)); }
-        protected Object invoke_F0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(), a0, a1); }
-        protected Object invoke_F1(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0), a0, a1); }
-        protected Object invoke_F2(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0, a1), a0, a1); }
-        protected Object invoke_C0(Object a0, Object a1) { return target.invokeExact(filter.invokeExact(a0, a1)); }
-        protected Object invoke_C1(Object a0, Object a1) { return target.invokeExact(a0, filter.invokeExact(a1)); }
-        protected Object invoke_C2(Object a0, Object a1) { return target.invokeExact(a0, a1, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1) { Object[] av = { a0, a1 };
-                       filter.invokeExact(av); return target.invokeExact(av[0], av[1]); }
-    }
-    // */
-
-    // This one is written by hand:
-    static class F0 extends Adapter {
-        protected F0(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F0(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F0 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F0(e, f, t); }
-        protected Object invoke_F0() throws Throwable {
-            return target.invokeExact(filter.invokeExact()); }
-        protected Object invoke_C0() throws Throwable {
-            return target.invokeExact(filter.invokeExact()); }
-        static final Object[] NO_ARGS = { };
-        protected Object invoke_Y0() throws Throwable {
-            filter.invokeExact(NO_ARGS); // make the flyby
-            return target.invokeExact(); }
-    }
-
-/*
-  : SHELL; n=FilterGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -ea -cp . genclasses | sed 's| *[/]/ *$||') >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
-//{{{
-import java.util.*;
-class genclasses {
-    static String[][] TEMPLATES = { {
-        "@for@ N=1..20",
-        "    //@each-cat@",
-        "    static class @cat@ extends Adapter {",
-        "        protected @cat@(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype",
-        "        protected @cat@(MethodHandle e, MethodHandle f, MethodHandle t) {",
-        "            super(e, f, t); }",
-        "        protected @cat@ makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {",
-        "            return new @cat@(e, f, t); }",
-        "        //@each-P@",
-        "        protected Object invoke_V@P@(@Tvav@) throws Throwable {",
-        "            return target.invokeExact(@a0_@@Psp@filter.invokeExact(a@P@)@_aN@); }",
-        "        //@end-P@",
-        "        //@each-P@",
-        "        protected Object invoke_F@P@(@Tvav@) throws Throwable {",
-        "            return target.invokeExact(filter.invokeExact(@a0@),",
-        "                                 @av@); }",
-        "        //@end-P@",
-        "        protected Object invoke_F@N@(@Tvav@) throws Throwable {",
-        "            return target.invokeExact(filter.invokeExact(@av@),",
-        "                                 @av@); }",
-        "        //@each-P@",
-        "        protected Object invoke_C@P@(@Tvav@) throws Throwable {",
-        "            return target.invokeExact(@a0_@filter.invokeExact(a@P@@_aN@)); }",
-        "        //@end-P@",
-        "        protected Object invoke_C@N@(@Tvav@) throws Throwable {",
-        "            return target.invokeExact(@av@, filter.invokeExact()); }",
-        "        protected Object invoke_Y0(@Tvav@) throws Throwable {",
-        "            Object[] av = { @av@ };",
-        "            filter.invokeExact(av); // make the flyby",
-        "            return target.invokeExact(@av[i]@); }",
-        "    }",
-    } };
-    static final String NEWLINE_INDENT = " //\n                                 ";
-    enum VAR {
-        cat, N, P, Tvav, av, a0, a0_, _aN, Psp, av_i_;
-        public final String pattern = "@"+toString().replace('_','.')+"@";
-        public String binding = toString();
-        static void makeBindings(boolean topLevel, int inargs, int pos) {
-            assert(-1 <= pos && pos < inargs);
-            VAR.cat.binding = "F"+inargs;
-            VAR.N.binding = String.valueOf(inargs); // incoming arg count
-            VAR.P.binding = String.valueOf(pos);  // selected arg position
-            String[] av = new String[inargs];
-            String[] Tvav = new String[inargs];
-            String[] av_i_ = new String[inargs];
-            for (int i = 0; i < inargs; i++) {
-                av[i] = arg(i);
-                av_i_[i] = "av["+i+"]";
-                String spc = "";
-                if (i > 0 && i % 4 == 0) spc = NEWLINE_INDENT+(pos>9?" ":"")+"  ";
-                Tvav[i] = spc+param("Object", av[i]);
-            }
-            VAR.av.binding = comma(av);
-            VAR.av_i_.binding = comma(av_i_);
-            VAR.Tvav.binding = comma(Tvav);
-            if (pos >= 0) {
-                VAR.Psp.binding = (pos > 0 && pos % 10 == 0) ? NEWLINE_INDENT : "";
-                String[] a0 = new String[pos];
-                String[] aN = new String[inargs - (pos+1)];
-                for (int i = 0; i < pos; i++) {
-                    String spc = "";
-                    if (i > 0 && i % 10 == 0) spc = NEWLINE_INDENT;
-                    a0[i] = spc+av[i];
-                }
-                VAR.a0.binding = comma(a0);
-                VAR.a0_.binding = comma(a0, ", ");
-                for (int i = pos+1; i < inargs; i++) {
-                    String spc = "";
-                    if (i > 0 && i % 10 == 0) spc = NEWLINE_INDENT;
-                    aN[i - (pos+1)] = spc+av[i];
-                }
-                VAR._aN.binding = comma(", ", aN);
-            }
-        }
-        static String arg(int i) { return "a"+i; }
-        static String param(String t, String a) { return t+" "+a; }
-        static String comma(String[] v) { return comma(v, ""); }
-        static String comma(String[] v, String sep) { return comma("", v, sep); }
-        static String comma(String sep, String[] v) { return comma(sep, v, ""); }
-        static String comma(String sep1, String[] v, String sep2) {
-            if (v.length == 0)  return "";
-            String res = v[0];
-            for (int i = 1; i < v.length; i++)  res += ", "+v[i];
-            return sep1 + res + sep2;
-        }
-        static String transform(String string) {
-            for (VAR var : values())
-                string = string.replaceAll(var.pattern, var.binding);
-            return string;
-        }
-    }
-    static String[] stringsIn(String[] strings, int beg, int end) {
-        return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
-    }
-    static String[] stringsBefore(String[] strings, int pos) {
-        return stringsIn(strings, 0, pos);
-    }
-    static String[] stringsAfter(String[] strings, int pos) {
-        return stringsIn(strings, pos, strings.length);
-    }
-    static int indexAfter(String[] strings, int pos, String tag) {
-        return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
-    }
-    static int indexBefore(String[] strings, int pos, String tag) {
-        for (int i = pos, end = strings.length; ; i++) {
-            if (i == end || strings[i].endsWith(tag))  return i;
-        }
-    }
-    static int MIN_ARITY, MAX_ARITY;
-    public static void main(String... av) {
-        for (String[] template : TEMPLATES) {
-            int forLinesLimit = indexBefore(template, 0, "@each-cat@");
-            String[] forLines = stringsBefore(template, forLinesLimit);
-            template = stringsAfter(template, forLinesLimit);
-            for (String forLine : forLines)
-                expandTemplate(forLine, template);
-        }
-    }
-    static void expandTemplate(String forLine, String[] template) {
-        String[] params = forLine.split("[^0-9]+");
-        if (params[0].length() == 0)  params = stringsAfter(params, 1);
-        System.out.println("//params="+Arrays.asList(params));
-        int pcur = 0;
-        MIN_ARITY = Integer.valueOf(params[pcur++]);
-        MAX_ARITY = Integer.valueOf(params[pcur++]);
-        if (pcur != params.length)  throw new RuntimeException("bad extra param: "+forLine);
-        for (int inargs = MIN_ARITY; inargs <= MAX_ARITY; inargs++) {
-            expandTemplate(template, true, inargs, -1);
-        }
-    }
-    static void expandTemplate(String[] template, boolean topLevel, int inargs, int pos) {
-        VAR.makeBindings(topLevel, inargs, pos);
-        for (int i = 0; i < template.length; i++) {
-            String line = template[i];
-            if (line.endsWith("@each-cat@")) {
-                // ignore
-            } else if (line.endsWith("@each-P@")) {
-                int blockEnd = indexAfter(template, i, "@end-P@");
-                String[] block = stringsIn(template, i+1, blockEnd-1);
-                for (int pos1 = Math.max(0,pos); pos1 < inargs; pos1++)
-                    expandTemplate(block, false, inargs, pos1);
-                VAR.makeBindings(topLevel, inargs, pos);
-                i = blockEnd-1; continue;
-            } else {
-                System.out.println(VAR.transform(line));
-            }
-        }
-    }
-}
-//}}} */
-//params=[1, 20]
-    static class F1 extends Adapter {
-        protected F1(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F1(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F1 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F1(e, f, t); }
-        protected Object invoke_V0(Object a0) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0)); }
-        protected Object invoke_F0(Object a0) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0); }
-        protected Object invoke_F1(Object a0) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0); }
-        protected Object invoke_C0(Object a0) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0)); }
-        protected Object invoke_C1(Object a0) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0) throws Throwable {
-            Object[] av = { a0 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0]); }
-    }
-    static class F2 extends Adapter {
-        protected F2(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F2(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F2 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F2(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1); }
-        protected Object invoke_V1(Object a0, Object a1) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1)); }
-        protected Object invoke_F0(Object a0, Object a1) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1); }
-        protected Object invoke_F1(Object a0, Object a1) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1); }
-        protected Object invoke_F2(Object a0, Object a1) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1); }
-        protected Object invoke_C0(Object a0, Object a1) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1)); }
-        protected Object invoke_C1(Object a0, Object a1) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1)); }
-        protected Object invoke_C2(Object a0, Object a1) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1) throws Throwable {
-            Object[] av = { a0, a1 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1]); }
-    }
-    static class F3 extends Adapter {
-        protected F3(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F3(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F3 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F3(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2) throws Throwable {
-            Object[] av = { a0, a1, a2 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2]); }
-    }
-    static class F4 extends Adapter {
-        protected F4(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F4(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F4 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F4(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            Object[] av = { a0, a1, a2, a3 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3]); }
-    }
-    static class F5 extends Adapter {
-        protected F5(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F5(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F5 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F5(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4]); }
-    }
-    static class F6 extends Adapter {
-        protected F6(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F6(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F6 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F6(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5]); }
-    }
-    static class F7 extends Adapter {
-        protected F7(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F7(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F7 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F7(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6]); }
-    }
-    static class F8 extends Adapter {
-        protected F8(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F8(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F8 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F8(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7]); }
-    }
-    static class F9 extends Adapter {
-        protected F9(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F9(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F9 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F9(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8]); }
-    }
-    static class F10 extends Adapter {
-        protected F10(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F10(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F10 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F10(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9]); }
-    }
-    static class F11 extends Adapter {
-        protected F11(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F11(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F11 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F11(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10]); }
-    }
-    static class F12 extends Adapter {
-        protected F12(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F12(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F12 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F12(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11]); }
-    }
-    static class F13 extends Adapter {
-        protected F13(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F13(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F13 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F13(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11, a12); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11, a12); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11, a12); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11), a12); }
-        protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11, a12)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11, a12)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12)); }
-        protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12]); }
-    }
-    static class F14 extends Adapter {
-        protected F14(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F14(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F14 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F14(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11, a12, a13); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11, a12, a13); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11), a12, a13); }
-        protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12), a13); }
-        protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11, a12, a13)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11, a12, a13)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12, a13)); }
-        protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13)); }
-        protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13]); }
-    }
-    static class F15 extends Adapter {
-        protected F15(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F15(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F15 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F15(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11, a12, a13, a14); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11, a12, a13, a14); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11), a12, a13, a14); }
-        protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12), a13, a14); }
-        protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13), a14); }
-        protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11, a12, a13, a14)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11, a12, a13, a14)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12, a13, a14)); }
-        protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13, a14)); }
-        protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14)); }
-        protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14]); }
-    }
-    static class F16 extends Adapter {
-        protected F16(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F16(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F16 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F16(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11, a12, a13, a14, a15); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11), a12, a13, a14, a15); }
-        protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12), a13, a14, a15); }
-        protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13), a14, a15); }
-        protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14), a15); }
-        protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11, a12, a13, a14, a15)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12, a13, a14, a15)); }
-        protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13, a14, a15)); }
-        protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14, a15)); }
-        protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15)); }
-        protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15]); }
-    }
-    static class F17 extends Adapter {
-        protected F17(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F17(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F17 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F17(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11), a12, a13, a14, a15, a16); }
-        protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12), a13, a14, a15, a16); }
-        protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13), a14, a15, a16); }
-        protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14), a15, a16); }
-        protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15), a16); }
-        protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, filter.invokeExact(a16)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11, a12, a13, a14, a15, a16)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12, a13, a14, a15, a16)); }
-        protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13, a14, a15, a16)); }
-        protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14, a15, a16)); }
-        protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15, a16)); }
-        protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, filter.invokeExact(a16)); }
-        protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16]); }
-    }
-    static class F18 extends Adapter {
-        protected F18(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F18(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F18 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F18(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17); }
-        protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17); }
-        protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17); }
-        protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17); }
-        protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17); }
-        protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17)); }
-        protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17)); }
-        protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17)); }
-        protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17)); }
-        protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17)); }
-        protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17)); }
-        protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17]); }
-    }
-    static class F19 extends Adapter {
-        protected F19(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F19(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F19 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F19(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17, a18); }
-        protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17, a18); }
-        protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17, a18); }
-        protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17, a18); }
-        protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17), a18); }
-        protected Object invoke_V18(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_F19(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17, a18)); }
-        protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17, a18)); }
-        protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17, a18)); }
-        protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17, a18)); }
-        protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17, a18)); }
-        protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18)); }
-        protected Object invoke_C19(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17], av[18]); }
-    }
-    static class F20 extends Adapter {
-        protected F20(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected F20(MethodHandle e, MethodHandle f, MethodHandle t) {
-            super(e, f, t); }
-        protected F20 makeInstance(MethodHandle e, MethodHandle f, MethodHandle t) {
-            return new F20(e, f, t); }
-        protected Object invoke_V0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0), a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1), a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2), a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3), a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4), a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5), a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6), a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7), a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8), a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9),
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 filter.invokeExact(a10), a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11), a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12), a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13), a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_V14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14), a15, a16, a17, a18, a19); }
-        protected Object invoke_V15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15), a16, a17, a18, a19); }
-        protected Object invoke_V16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, filter.invokeExact(a16), a17, a18, a19); }
-        protected Object invoke_V17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17), a18, a19); }
-        protected Object invoke_V18(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18), a19); }
-        protected Object invoke_V19(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact(a19)); }
-        protected Object invoke_F0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F18(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F19(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_F20(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19),
-                                 a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19); }
-        protected Object invoke_C0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(filter.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C1(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, filter.invokeExact(a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C2(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, filter.invokeExact(a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C3(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, filter.invokeExact(a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C4(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, filter.invokeExact(a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C5(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, filter.invokeExact(a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C6(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, filter.invokeExact(a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C7(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, filter.invokeExact(a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C8(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, filter.invokeExact(a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C9(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, filter.invokeExact(a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C10(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, filter.invokeExact(a10, a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C11(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, filter.invokeExact(a11, a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C12(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, filter.invokeExact(a12, a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C13(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, filter.invokeExact(a13, a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C14(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, filter.invokeExact(a14, a15, a16, a17, a18, a19)); }
-        protected Object invoke_C15(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, filter.invokeExact(a15, a16, a17, a18, a19)); }
-        protected Object invoke_C16(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, filter.invokeExact(a16, a17, a18, a19)); }
-        protected Object invoke_C17(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, filter.invokeExact(a17, a18, a19)); }
-        protected Object invoke_C18(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, filter.invokeExact(a18, a19)); }
-        protected Object invoke_C19(Object a0, Object a1, Object a2, Object a3,
-                                    Object a4, Object a5, Object a6, Object a7,
-                                    Object a8, Object a9, Object a10, Object a11,
-                                    Object a12, Object a13, Object a14, Object a15,
-                                    Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9,
-                                 a10, a11, a12, a13, a14, a15, a16, a17, a18, filter.invokeExact(a19)); }
-        protected Object invoke_C20(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, filter.invokeExact()); }
-        protected Object invoke_Y0(Object a0, Object a1, Object a2, Object a3,
-                                   Object a4, Object a5, Object a6, Object a7,
-                                   Object a8, Object a9, Object a10, Object a11,
-                                   Object a12, Object a13, Object a14, Object a15,
-                                   Object a16, Object a17, Object a18, Object a19) throws Throwable {
-            Object[] av = { a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19 };
-            filter.invokeExact(av); // make the flyby
-            return target.invokeExact(av[0], av[1], av[2], av[3], av[4], av[5], av[6], av[7], av[8], av[9], av[10], av[11], av[12], av[13], av[14], av[15], av[16], av[17], av[18], av[19]); }
-    }
-}
diff --git a/jdk/src/share/classes/java/lang/invoke/FilterOneArgument.java b/jdk/src/share/classes/java/lang/invoke/FilterOneArgument.java
deleted file mode 100644
index 2c92f9c..0000000
--- a/jdk/src/share/classes/java/lang/invoke/FilterOneArgument.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * Unary function composition, useful for many small plumbing jobs.
- * The invoke method takes a single reference argument, and returns a reference
- * Internally, it first calls the {@code filter} method on the argument,
- * Making up the difference between the raw method type and the
- * final method type is the responsibility of a JVM-level adapter.
- * @author jrose
- */
-class FilterOneArgument extends BoundMethodHandle {
-    protected final MethodHandle filter;  // Object -> Object
-    protected final MethodHandle target;  // Object -> Object
-
-    @Override
-    String debugString() {
-        return target.toString();
-    }
-
-    protected Object invoke(Object argument) throws Throwable {
-        Object filteredArgument = filter.invokeExact(argument);
-        return target.invokeExact(filteredArgument);
-    }
-
-    private static final MethodHandle INVOKE;
-    static {
-        try {
-            INVOKE =
-                IMPL_LOOKUP.findVirtual(FilterOneArgument.class, "invoke",
-                                        MethodType.genericMethodType(1));
-        } catch (ReflectiveOperationException ex) {
-            throw uncaughtException(ex);
-        }
-    }
-
-    protected FilterOneArgument(MethodHandle filter, MethodHandle target) {
-        super(INVOKE);
-        this.filter = filter;
-        this.target = target;
-    }
-
-    static {
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
-    }
-
-    public static MethodHandle make(MethodHandle filter, MethodHandle target) {
-        if (filter == null)  return target;
-        if (target == null)  return filter;
-        return new FilterOneArgument(filter, target);
-    }
-
-//    MethodHandle make(MethodHandle filter1, MethodHandle filter2, MethodHandle target) {
-//        MethodHandle filter = make(filter1, filter2);
-//        return make(filter, target);
-//    }
-}
diff --git a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c b/jdk/src/share/classes/java/lang/invoke/ForceInline.java
similarity index 65%
copy from jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
copy to jdk/src/share/classes/java/lang/invoke/ForceInline.java
index 089afbd..bbac427 100644
--- a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
+++ b/jdk/src/share/classes/java/lang/invoke/ForceInline.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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,22 +23,15 @@
  * questions.
  */
 
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
+package java.lang.invoke;
 
-#include "sun_rmi_server_MarshalInputStream.h"
+import java.lang.annotation.*;
 
-/*
- * Class:     sun_rmi_server_MarshalInputStream
- * Method:    latestUserDefinedLoader
- * Signature: ()Ljava/lang/ClassLoader;
- *
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
+/**
+ * Internal marker for some methods in the JSR 292 implementation.
  */
-JNIEXPORT jobject JNICALL
-Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader(JNIEnv *env, jclass cls)
-{
-    return JVM_LatestUserDefinedLoader(env);
+/*non-public*/
+@Target({ElementType.METHOD, ElementType.CONSTRUCTOR})
+@Retention(RetentionPolicy.RUNTIME)
+@interface ForceInline {
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/FromGeneric.java b/jdk/src/share/classes/java/lang/invoke/FromGeneric.java
deleted file mode 100644
index b3b63de..0000000
--- a/jdk/src/share/classes/java/lang/invoke/FromGeneric.java
+++ /dev/null
@@ -1,633 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import sun.invoke.util.ValueConversions;
-import sun.invoke.util.Wrapper;
-import java.lang.reflect.*;
-import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * Adapters which mediate between incoming calls which are generic
- * and outgoing calls which are not.  Any call can be represented generically
- * boxing up its arguments, and (on return) unboxing the return value.
- * <p>
- * A call is "generic" (in MethodHandle terms) if its MethodType features
- * only Object arguments.  A non-generic call therefore features
- * primitives and/or reference types other than Object.
- * An adapter has types for its incoming and outgoing calls.
- * The incoming call type is simply determined by the adapter's type
- * (the MethodType it presents to callers).  The outgoing call type
- * is determined by the adapter's target (a MethodHandle that the adapter
- * either binds internally or else takes as a leading argument).
- * (To stretch the term, adapter-like method handles may have multiple
- * targets or be polymorphic across multiple call types.)
- * @author jrose
- */
-class FromGeneric {
-    // type for the outgoing call (may have primitives, etc.)
-    private final MethodType targetType;
-    // type of the outgoing call internal to the adapter
-    private final MethodType internalType;
-    // prototype adapter (clone and customize for each new target!)
-    private final Adapter adapter;
-    // entry point for adapter (Adapter mh, a...) => ...
-    private final MethodHandle entryPoint;
-    // unboxing invoker of type (MH, Object**N) => raw return value
-    // it makes up the difference of internalType => targetType
-    private final MethodHandle unboxingInvoker;
-    // conversion which boxes a the target's raw return value
-    private final MethodHandle returnConversion;
-
-    /** Compute and cache information common to all unboxing adapters
-     *  that can call out to targets of the erasure-family of the given erased type.
-     */
-    private FromGeneric(MethodType targetType) {
-        this.targetType = targetType;
-        MethodType internalType0;
-        // the target invoker will generally need casts on reference arguments
-        Adapter ad = findAdapter(internalType0 = targetType.erase());
-        if (ad != null) {
-            // Immediate hit to exactly the adapter we want,
-            // with no monkeying around with primitive types.
-            this.internalType = internalType0;
-            this.adapter = ad;
-            this.entryPoint = ad.prototypeEntryPoint();
-            this.returnConversion = computeReturnConversion(targetType, internalType0);
-            this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
-            return;
-        }
-
-        // outgoing primitive arguments will be wrapped; unwrap them
-        MethodType primsAsObj = targetType.form().primArgsAsBoxes();
-        MethodType objArgsRawRet = primsAsObj.form().primsAsInts();
-        if (objArgsRawRet != targetType)
-            ad = findAdapter(internalType0 = objArgsRawRet);
-        if (ad == null) {
-            ad = buildAdapterFromBytecodes(internalType0 = targetType);
-        }
-        this.internalType = internalType0;
-        this.adapter = ad;
-        MethodType tepType = targetType.insertParameterTypes(0, adapter.getClass());
-        this.entryPoint = ad.prototypeEntryPoint();
-        this.returnConversion = computeReturnConversion(targetType, internalType0);
-        this.unboxingInvoker = computeUnboxingInvoker(targetType, internalType0);
-    }
-
-    static {
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
-    }
-
-    /**
-     * The typed target will be called according to targetType.
-     * The adapter code will in fact see the raw result from internalType,
-     * and must box it into an object.  Produce a converter for this.
-     */
-    private static MethodHandle computeReturnConversion(
-            MethodType targetType, MethodType internalType) {
-        Class<?> tret = targetType.returnType();
-        Class<?> iret = internalType.returnType();
-        Wrapper wrap = Wrapper.forBasicType(tret);
-        if (!iret.isPrimitive()) {
-            assert(iret == Object.class);
-            return ValueConversions.identity();
-        } else if (wrap.primitiveType() == iret) {
-            return ValueConversions.box(wrap);
-        } else {
-            assert(tret == double.class ? iret == long.class : iret == int.class);
-            return ValueConversions.boxRaw(wrap);
-        }
-    }
-
-    /**
-     * The typed target will need an exact invocation point; provide it here.
-     * The adapter will possibly need to make a slightly different call,
-     * so adapt the invoker.  This way, the logic for making up the
-     * difference between what the adapter can call and what the target
-     * needs can be cached once per type.
-     */
-    private static MethodHandle computeUnboxingInvoker(
-            MethodType targetType, MethodType internalType) {
-        // All the adapters we have here have reference-untyped internal calls.
-        assert(internalType == internalType.erase());
-        MethodHandle invoker = targetType.invokers().exactInvoker();
-        // cast all narrow reference types, unbox all primitive arguments:
-        MethodType fixArgsType = internalType.changeReturnType(targetType.returnType());
-        MethodHandle fixArgs = MethodHandleImpl.convertArguments(
-                                 invoker, Invokers.invokerType(fixArgsType),
-                                 invoker.type(), 0);
-        if (fixArgs == null)
-            throw new InternalError("bad fixArgs");
-        // reinterpret the calling sequence as raw:
-        MethodHandle retyper = AdapterMethodHandle.makeRetypeRaw(
-                                        Invokers.invokerType(internalType), fixArgs);
-        if (retyper == null)
-            throw new InternalError("bad retyper");
-        return retyper;
-    }
-
-    Adapter makeInstance(MethodHandle typedTarget) {
-        MethodType type = typedTarget.type();
-        if (type == targetType) {
-            return adapter.makeInstance(entryPoint, unboxingInvoker, returnConversion, typedTarget);
-        }
-        // my erased-type is not exactly the same as the desired type
-        assert(type.erase() == targetType);  // else we are busted
-        MethodHandle invoker = computeUnboxingInvoker(type, internalType);
-        return adapter.makeInstance(entryPoint, invoker, returnConversion, typedTarget);
-    }
-
-    /** Build an adapter of the given generic type, which invokes typedTarget
-     *  on the incoming arguments, after unboxing as necessary.
-     *  The return value is boxed if necessary.
-     * @param typedTarget the target
-     * @return an adapter method handle
-     */
-    public static MethodHandle make(MethodHandle typedTarget) {
-        MethodType type = typedTarget.type();
-        if (type == type.generic())  return typedTarget;
-        return FromGeneric.of(type).makeInstance(typedTarget);
-    }
-
-    /** Return the adapter information for this type's erasure. */
-    static FromGeneric of(MethodType type) {
-        MethodTypeForm form = type.form();
-        FromGeneric fromGen = form.fromGeneric;
-        if (fromGen == null)
-            form.fromGeneric = fromGen = new FromGeneric(form.erasedType());
-        return fromGen;
-    }
-
-    public String toString() {
-        return "FromGeneric"+targetType;
-    }
-
-    /* Create an adapter that handles spreading calls for the given type. */
-    static Adapter findAdapter(MethodType internalType) {
-        MethodType entryType = internalType.generic();
-        MethodTypeForm form = internalType.form();
-        Class<?> rtype = internalType.returnType();
-        int argc = form.parameterCount();
-        int lac = form.longPrimitiveParameterCount();
-        int iac = form.primitiveParameterCount() - lac;
-        String intsAndLongs = (iac > 0 ? "I"+iac : "")+(lac > 0 ? "J"+lac : "");
-        String rawReturn = String.valueOf(Wrapper.forPrimitiveType(rtype).basicTypeChar());
-        String cname0 = rawReturn + argc;
-        String cname1 = "A"       + argc;
-        String[] cnames = { cname0+intsAndLongs, cname0, cname1+intsAndLongs, cname1 };
-        String iname = "invoke_"+cname0+intsAndLongs;
-        // e.g., D5I2, D5, L5I2, L5; invoke_D5
-        for (String cname : cnames) {
-            Class<? extends Adapter> acls = Adapter.findSubClass(cname);
-            if (acls == null)  continue;
-            // see if it has the required invoke method
-            MethodHandle entryPoint = null;
-            try {
-                entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
-            } catch (ReflectiveOperationException ex) {
-            }
-            if (entryPoint == null)  continue;
-            Constructor<? extends Adapter> ctor = null;
-            try {
-                ctor = acls.getDeclaredConstructor(MethodHandle.class);
-            } catch (NoSuchMethodException ex) {
-            } catch (SecurityException ex) {
-            }
-            if (ctor == null)  continue;
-            try {
-                // Produce an instance configured as a prototype.
-                return ctor.newInstance(entryPoint);
-            } catch (IllegalArgumentException ex) {
-            } catch (InvocationTargetException wex) {
-                Throwable ex = wex.getTargetException();
-                if (ex instanceof Error)  throw (Error)ex;
-                if (ex instanceof RuntimeException)  throw (RuntimeException)ex;
-            } catch (InstantiationException ex) {
-            } catch (IllegalAccessException ex) {
-            }
-        }
-        return null;
-    }
-
-    static Adapter buildAdapterFromBytecodes(MethodType internalType) {
-        throw new UnsupportedOperationException("NYI "+internalType);
-    }
-
-    /**
-     * This adapter takes some untyped arguments, and returns an untyped result.
-     * Internally, it applies the invoker to the target, which causes the
-     * objects to be unboxed; the result is a raw type in L/I/J/F/D.
-     * This result is passed to convert, which is responsible for
-     * converting the raw result into a boxed object.
-     * The invoker is kept separate from the target because it can be
-     * generated once per type erasure family, and reused across adapters.
-     */
-    static abstract class Adapter extends BoundMethodHandle {
-        /*
-         * class X<<R,int N>> extends Adapter {
-         *   (MH, Object**N)=>raw(R) invoker;
-         *   (any**N)=>R target;
-         *   raw(R)=>Object convert;
-         *   Object invoke(Object**N a) = convert(invoker(target, a...))
-         * }
-         */
-        protected final MethodHandle invoker;  // (MH, Object**N) => raw(R)
-        protected final MethodHandle convert;  // raw(R) => Object
-        protected final MethodHandle target;   // (any**N) => R
-
-        @Override
-        String debugString() {
-            return addTypeString(target, this);
-        }
-
-        protected boolean isPrototype() { return target == null; }
-        protected Adapter(MethodHandle entryPoint) {
-            this(entryPoint, null, entryPoint, null);
-            assert(isPrototype());
-        }
-        protected MethodHandle prototypeEntryPoint() {
-            if (!isPrototype())  throw new InternalError();
-            return convert;
-        }
-
-        protected Adapter(MethodHandle entryPoint,
-                          MethodHandle invoker, MethodHandle convert, MethodHandle target) {
-            super(entryPoint);
-            this.invoker = invoker;
-            this.convert = convert;
-            this.target  = target;
-        }
-
-        /** Make a copy of self, with new fields. */
-        protected abstract Adapter makeInstance(MethodHandle entryPoint,
-                MethodHandle invoker, MethodHandle convert, MethodHandle target);
-        // { return new ThisType(entryPoint, convert, target); }
-
-        /// Conversions on the value returned from the target.
-        protected Object convert_L(Object result) throws Throwable { return convert.invokeExact(result); }
-        protected Object convert_I(int    result) throws Throwable { return convert.invokeExact(result); }
-        protected Object convert_J(long   result) throws Throwable { return convert.invokeExact(result); }
-        protected Object convert_F(float  result) throws Throwable { return convert.invokeExact(result); }
-        protected Object convert_D(double result) throws Throwable { return convert.invokeExact(result); }
-
-        static private final String CLASS_PREFIX; // "java.lang.invoke.FromGeneric$"
-        static {
-            String aname = Adapter.class.getName();
-            String sname = Adapter.class.getSimpleName();
-            if (!aname.endsWith(sname))  throw new InternalError();
-            CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
-        }
-        /** Find a sibing class of Adapter. */
-        static Class<? extends Adapter> findSubClass(String name) {
-            String cname = Adapter.CLASS_PREFIX + name;
-            try {
-                return Class.forName(cname).asSubclass(Adapter.class);
-            } catch (ClassNotFoundException ex) {
-                return null;
-            } catch (ClassCastException ex) {
-                return null;
-            }
-        }
-    }
-
-    /* generated classes follow this pattern:
-    static class xA2 extends Adapter {
-        protected xA2(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected xA2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected xA2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new xA2(e, i, c, t); }
-        protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1)); }
-        protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1)); }
-        protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1)); }
-        protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1)); }
-        protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1)); }
-    }
-    // */
-
-/*
-: SHELL; n=FromGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
-//{{{
-import java.util.*;
-class genclasses {
-    static String[] TYPES = { "Object",    "int   ",    "long  ",    "float ",    "double" };
-    static String[] WRAPS = { "         ", "(Integer)", "(Long)   ", "(Float)  ", "(Double) " };
-    static String[] TCHARS = { "L",     "I",      "J",      "F",      "D",     "A" };
-    static String[][] TEMPLATES = { {
-        "@for@ arity=0..10  rcat<=4 nrefs<=99 nints=0   nlongs=0",
-        "    //@each-cat@",
-        "    static class @cat@ extends Adapter {",
-        "        protected @cat@(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype",
-        "        protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
-        "                        { super(e, i, c, t); }",
-        "        protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)",
-        "                        { return new @cat@(e, i, c, t); }",
-        "        //@each-R@",
-        "        protected Object invoke_@catN@(@Tvav@) throws Throwable { return convert_@Rc@((@R@)@W@invoker.invokeExact(target@av@)); }",
-        "        //@end-R@",
-        "    }",
-    } };
-    static final String NEWLINE_INDENT = "\n                ";
-    enum VAR {
-        cat, catN, R, Rc, W, av, Tvav, Ovav;
-        public final String pattern = "@"+toString().replace('_','.')+"@";
-        public String binding;
-        static void makeBindings(boolean topLevel, int rcat, int nrefs, int nints, int nlongs) {
-            int nargs = nrefs + nints + nlongs;
-            if (topLevel)
-                VAR.cat.binding = catstr(ALL_RETURN_TYPES ? TYPES.length : rcat, nrefs, nints, nlongs);
-            VAR.catN.binding = catstr(rcat, nrefs, nints, nlongs);
-            VAR.R.binding = TYPES[rcat];
-            VAR.Rc.binding = TCHARS[rcat];
-            VAR.W.binding = WRAPS[rcat];
-            String[] Tv = new String[nargs];
-            String[] av = new String[nargs];
-            String[] Tvav = new String[nargs];
-            String[] Ovav = new String[nargs];
-            for (int i = 0; i < nargs; i++) {
-                int tcat = (i < nrefs) ? 0 : (i < nrefs + nints) ? 1 : 2;
-                Tv[i] = TYPES[tcat];
-                av[i] = arg(i);
-                Tvav[i] = param(Tv[i], av[i]);
-                Ovav[i] = param("Object", av[i]);
-            }
-            VAR.av.binding = comma(", ", av);
-            VAR.Tvav.binding = comma(Tvav);
-            VAR.Ovav.binding = comma(Ovav);
-        }
-        static String arg(int i) { return "a"+i; }
-        static String param(String t, String a) { return t+" "+a; }
-        static String comma(String[] v) { return comma("", v); }
-        static String comma(String sep, String[] v) {
-            if (v.length == 0)  return "";
-            String res = sep+v[0];
-            for (int i = 1; i < v.length; i++)  res += ", "+v[i];
-            return res;
-        }
-        static String transform(String string) {
-            for (VAR var : values())
-                string = string.replaceAll(var.pattern, var.binding);
-            return string;
-        }
-    }
-    static String[] stringsIn(String[] strings, int beg, int end) {
-        return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
-    }
-    static String[] stringsBefore(String[] strings, int pos) {
-        return stringsIn(strings, 0, pos);
-    }
-    static String[] stringsAfter(String[] strings, int pos) {
-        return stringsIn(strings, pos, strings.length);
-    }
-    static int indexAfter(String[] strings, int pos, String tag) {
-        return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
-    }
-    static int indexBefore(String[] strings, int pos, String tag) {
-        for (int i = pos, end = strings.length; ; i++) {
-            if (i == end || strings[i].endsWith(tag))  return i;
-        }
-    }
-    static int MIN_ARITY, MAX_ARITY, MAX_RCAT, MAX_REFS, MAX_INTS, MAX_LONGS;
-    static boolean ALL_ARG_TYPES, ALL_RETURN_TYPES;
-    static HashSet<String> done = new HashSet<String>();
-    public static void main(String... av) {
-        for (String[] template : TEMPLATES) {
-            int forLinesLimit = indexBefore(template, 0, "@each-cat@");
-            String[] forLines = stringsBefore(template, forLinesLimit);
-            template = stringsAfter(template, forLinesLimit);
-            for (String forLine : forLines)
-                expandTemplate(forLine, template);
-        }
-    }
-    static void expandTemplate(String forLine, String[] template) {
-        String[] params = forLine.split("[^0-9]+");
-        if (params[0].length() == 0)  params = stringsAfter(params, 1);
-        System.out.println("//params="+Arrays.asList(params));
-        int pcur = 0;
-        MIN_ARITY = Integer.valueOf(params[pcur++]);
-        MAX_ARITY = Integer.valueOf(params[pcur++]);
-        MAX_RCAT  = Integer.valueOf(params[pcur++]);
-        MAX_REFS  = Integer.valueOf(params[pcur++]);
-        MAX_INTS  = Integer.valueOf(params[pcur++]);
-        MAX_LONGS = Integer.valueOf(params[pcur++]);
-        if (pcur != params.length)  throw new RuntimeException("bad extra param: "+forLine);
-        if (MAX_RCAT >= TYPES.length)  MAX_RCAT = TYPES.length - 1;
-        ALL_ARG_TYPES = (indexBefore(template, 0, "@each-Tv@") < template.length);
-        ALL_RETURN_TYPES = (indexBefore(template, 0, "@each-R@") < template.length);
-        for (int nargs = MIN_ARITY; nargs <= MAX_ARITY; nargs++) {
-            for (int rcat = 0; rcat <= MAX_RCAT; rcat++) {
-                expandTemplate(template, true, rcat, nargs, 0, 0);
-                if (ALL_ARG_TYPES)  break;
-                expandTemplateForPrims(template, true, rcat, nargs, 1, 1);
-                if (ALL_RETURN_TYPES)  break;
-            }
-        }
-    }
-    static String catstr(int rcat, int nrefs, int nints, int nlongs) {
-        int nargs = nrefs + nints + nlongs;
-        String cat = TCHARS[rcat] + nargs;
-        if (!ALL_ARG_TYPES)  cat += (nints==0?"":"I"+nints)+(nlongs==0?"":"J"+nlongs);
-        return cat;
-    }
-    static void expandTemplateForPrims(String[] template, boolean topLevel, int rcat, int nargs, int minints, int minlongs) {
-        for (int isLong = 0; isLong <= 1; isLong++) {
-            for (int nprims = 1; nprims <= nargs; nprims++) {
-                int nrefs = nargs - nprims;
-                int nints = ((1-isLong) * nprims);
-                int nlongs = (isLong * nprims);
-                expandTemplate(template, topLevel, rcat, nrefs, nints, nlongs);
-            }
-        }
-    }
-    static void expandTemplate(String[] template, boolean topLevel,
-                               int rcat, int nrefs, int nints, int nlongs) {
-        int nargs = nrefs + nints + nlongs;
-        if (nrefs > MAX_REFS || nints > MAX_INTS || nlongs > MAX_LONGS)  return;
-        VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
-        if (topLevel && !done.add(VAR.cat.binding)) {
-            System.out.println("    //repeat "+VAR.cat.binding);
-            return;
-        }
-        for (int i = 0; i < template.length; i++) {
-            String line = template[i];
-            if (line.endsWith("@each-cat@")) {
-                // ignore
-            } else if (line.endsWith("@each-R@")) {
-                int blockEnd = indexAfter(template, i, "@end-R@");
-                String[] block = stringsIn(template, i+1, blockEnd-1);
-                for (int rcat1 = rcat; rcat1 <= MAX_RCAT; rcat1++)
-                    expandTemplate(block, false, rcat1, nrefs, nints, nlongs);
-                VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
-                i = blockEnd-1; continue;
-            } else if (line.endsWith("@each-Tv@")) {
-                int blockEnd = indexAfter(template, i, "@end-Tv@");
-                String[] block = stringsIn(template, i+1, blockEnd-1);
-                expandTemplate(block, false, rcat, nrefs, nints, nlongs);
-                expandTemplateForPrims(block, false, rcat, nargs, nints+1, nlongs+1);
-                VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
-                i = blockEnd-1; continue;
-            } else {
-                System.out.println(VAR.transform(line));
-            }
-        }
-    }
-}
-//}}} */
-//params=[0, 10, 4, 99, 0, 0]
-    static class A0 extends Adapter {
-        protected A0(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A0(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A0(e, i, c, t); }
-        protected Object invoke_L0() throws Throwable { return convert_L((Object)invoker.invokeExact(target)); }
-        protected Object invoke_I0() throws Throwable { return convert_I((int)   invoker.invokeExact(target)); }
-        protected Object invoke_J0() throws Throwable { return convert_J((long)  invoker.invokeExact(target)); }
-        protected Object invoke_F0() throws Throwable { return convert_F((float) invoker.invokeExact(target)); }
-        protected Object invoke_D0() throws Throwable { return convert_D((double)invoker.invokeExact(target)); }
-    }
-    static class A1 extends Adapter {
-        protected A1(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A1(e, i, c, t); }
-        protected Object invoke_L1(Object a0) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0)); }
-        protected Object invoke_I1(Object a0) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0)); }
-        protected Object invoke_J1(Object a0) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0)); }
-        protected Object invoke_F1(Object a0) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0)); }
-        protected Object invoke_D1(Object a0) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0)); }
-    }
-    static class A2 extends Adapter {
-        protected A2(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A2(e, i, c, t); }
-        protected Object invoke_L2(Object a0, Object a1) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1)); }
-        protected Object invoke_I2(Object a0, Object a1) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1)); }
-        protected Object invoke_J2(Object a0, Object a1) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1)); }
-        protected Object invoke_F2(Object a0, Object a1) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1)); }
-        protected Object invoke_D2(Object a0, Object a1) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1)); }
-    }
-    static class A3 extends Adapter {
-        protected A3(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A3(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A3 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A3(e, i, c, t); }
-        protected Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2)); }
-        protected Object invoke_I3(Object a0, Object a1, Object a2) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1, a2)); }
-        protected Object invoke_J3(Object a0, Object a1, Object a2) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1, a2)); }
-        protected Object invoke_F3(Object a0, Object a1, Object a2) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2)); }
-        protected Object invoke_D3(Object a0, Object a1, Object a2) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2)); }
-    }
-    static class A4 extends Adapter {
-        protected A4(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A4(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A4 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A4(e, i, c, t); }
-        protected Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3)); }
-        protected Object invoke_I4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1, a2, a3)); }
-        protected Object invoke_J4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1, a2, a3)); }
-        protected Object invoke_F4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3)); }
-        protected Object invoke_D4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3)); }
-    }
-    static class A5 extends Adapter {
-        protected A5(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A5(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A5 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A5(e, i, c, t); }
-        protected Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
-        protected Object invoke_I5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
-        protected Object invoke_J5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
-        protected Object invoke_F5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
-        protected Object invoke_D5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4)); }
-    }
-    static class A6 extends Adapter {
-        protected A6(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A6(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A6 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A6(e, i, c, t); }
-        protected Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_I6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_J6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_F6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_D6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5)); }
-    }
-    static class A7 extends Adapter {
-        protected A7(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A7(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A7 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A7(e, i, c, t); }
-        protected Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_I7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_J7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_F7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_D7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6)); }
-    }
-    static class A8 extends Adapter {
-        protected A8(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A8(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A8 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A8(e, i, c, t); }
-        protected Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_I8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_J8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_F8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_D8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7)); }
-    }
-    static class A9 extends Adapter {
-        protected A9(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A9(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A9 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A9(e, i, c, t); }
-        protected Object invoke_L9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_I9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_J9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_F9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_D9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-    }
-    static class A10 extends Adapter {
-        protected A10(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A10(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { super(e, i, c, t); }
-        protected A10 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t)
-                        { return new A10(e, i, c, t); }
-        protected Object invoke_L10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_L((Object)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_I10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_I((int)   invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_J10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_J((long)  invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_F10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_F((float) invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_D10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return convert_D((double)invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-    }
-}
diff --git a/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
new file mode 100644
index 0000000..0def847
--- /dev/null
+++ b/jdk/src/share/classes/java/lang/invoke/InvokerBytecodeGenerator.java
@@ -0,0 +1,1072 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import sun.invoke.util.VerifyAccess;
+import java.lang.invoke.LambdaForm.Name;
+import java.lang.invoke.MethodHandles.Lookup;
+
+import sun.invoke.util.Wrapper;
+
+import java.io.*;
+import java.util.*;
+
+import com.sun.xml.internal.ws.org.objectweb.asm.*;
+
+import java.lang.reflect.*;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+import sun.invoke.util.ValueConversions;
+import sun.invoke.util.VerifyType;
+
+/**
+ * Code generation backend for LambdaForm.
+ * <p>
+ * @author John Rose, JSR 292 EG
+ */
+class InvokerBytecodeGenerator {
+    /** Define class names for convenience. */
+    private static final String MH      = "java/lang/invoke/MethodHandle";
+    private static final String BMH     = "java/lang/invoke/BoundMethodHandle";
+    private static final String LF      = "java/lang/invoke/LambdaForm";
+    private static final String LFN     = "java/lang/invoke/LambdaForm$Name";
+    private static final String CLS     = "java/lang/Class";
+    private static final String OBJ     = "java/lang/Object";
+    private static final String OBJARY  = "[Ljava/lang/Object;";
+
+    private static final String LF_SIG  = "L" + LF + ";";
+    private static final String LFN_SIG = "L" + LFN + ";";
+    private static final String LL_SIG  = "(L" + OBJ + ";)L" + OBJ + ";";
+
+    /** Name of its super class*/
+    private static final String superName = LF;
+
+    /** Name of new class */
+    private final String className;
+
+    /** Name of the source file (for stack trace printing). */
+    private final String sourceFile;
+
+    private final LambdaForm lambdaForm;
+    private final String     invokerName;
+    private final MethodType invokerType;
+    private final int[] localsMap;
+
+    /** ASM bytecode generation. */
+    private ClassWriter cw;
+    private MethodVisitor mv;
+
+    private static final MemberName.Factory MEMBERNAME_FACTORY = MemberName.getFactory();
+    private static final Class<?> HOST_CLASS = LambdaForm.class;
+
+    private InvokerBytecodeGenerator(LambdaForm lambdaForm, int localsMapSize,
+                                     String className, String invokerName, MethodType invokerType) {
+        if (invokerName.contains(".")) {
+            int p = invokerName.indexOf(".");
+            className = invokerName.substring(0, p);
+            invokerName = invokerName.substring(p+1);
+        }
+        if (DUMP_CLASS_FILES) {
+            className = makeDumpableClassName(className);
+        }
+        this.className  = superName + "$" + className;
+        this.sourceFile = "LambdaForm$" + className;
+        this.lambdaForm = lambdaForm;
+        this.invokerName = invokerName;
+        this.invokerType = invokerType;
+        this.localsMap = new int[localsMapSize];
+    }
+
+    private InvokerBytecodeGenerator(String className, String invokerName, MethodType invokerType) {
+        this(null, invokerType.parameterCount(),
+             className, invokerName, invokerType);
+        // Create an array to map name indexes to locals indexes.
+        for (int i = 0; i < localsMap.length; i++) {
+            localsMap[i] = invokerType.parameterSlotCount() - invokerType.parameterSlotDepth(i);
+        }
+    }
+
+    private InvokerBytecodeGenerator(String className, LambdaForm form, MethodType invokerType) {
+        this(form, form.names.length,
+             className, form.debugName, invokerType);
+        // Create an array to map name indexes to locals indexes.
+        Name[] names = form.names;
+        for (int i = 0, index = 0; i < localsMap.length; i++) {
+            localsMap[i] = index;
+            index += Wrapper.forBasicType(names[i].type).stackSlots();
+        }
+    }
+
+
+    /** instance counters for dumped classes */
+    private final static HashMap<String,Integer> DUMP_CLASS_FILES_COUNTERS;
+    /** debugging flag for saving generated class files */
+    private final static File DUMP_CLASS_FILES_DIR;
+
+    static {
+        if (DUMP_CLASS_FILES) {
+            DUMP_CLASS_FILES_COUNTERS = new HashMap<>();
+            try {
+                File dumpDir = new File("DUMP_CLASS_FILES");
+                if (!dumpDir.exists()) {
+                    dumpDir.mkdirs();
+                }
+                DUMP_CLASS_FILES_DIR = dumpDir;
+                System.out.println("Dumping class files to "+DUMP_CLASS_FILES_DIR+"/...");
+            } catch (Exception e) {
+                throw newInternalError(e);
+            }
+        } else {
+            DUMP_CLASS_FILES_COUNTERS = null;
+            DUMP_CLASS_FILES_DIR = null;
+        }
+    }
+
+    static void maybeDump(final String className, final byte[] classFile) {
+        if (DUMP_CLASS_FILES) {
+            System.out.println("dump: " + className);
+            java.security.AccessController.doPrivileged(
+            new java.security.PrivilegedAction<Void>() {
+                public Void run() {
+                    try {
+                        String dumpName = className;
+                        //dumpName = dumpName.replace('/', '-');
+                        File dumpFile = new File(DUMP_CLASS_FILES_DIR, dumpName+".class");
+                        dumpFile.getParentFile().mkdirs();
+                        FileOutputStream file = new FileOutputStream(dumpFile);
+                        file.write(classFile);
+                        file.close();
+                        return null;
+                    } catch (IOException ex) {
+                        throw newInternalError(ex);
+                    }
+                }
+            });
+        }
+
+    }
+
+    private static String makeDumpableClassName(String className) {
+        Integer ctr;
+        synchronized (DUMP_CLASS_FILES_COUNTERS) {
+            ctr = DUMP_CLASS_FILES_COUNTERS.get(className);
+            if (ctr == null)  ctr = 0;
+            DUMP_CLASS_FILES_COUNTERS.put(className, ctr+1);
+        }
+        String sfx = ctr.toString();
+        while (sfx.length() < 3)
+            sfx = "0"+sfx;
+        className += sfx;
+        return className;
+    }
+
+    class CpPatch {
+        final int index;
+        final String placeholder;
+        final Object value;
+        CpPatch(int index, String placeholder, Object value) {
+            this.index = index;
+            this.placeholder = placeholder;
+            this.value = value;
+        }
+        public String toString() {
+            return "CpPatch/index="+index+",placeholder="+placeholder+",value="+value;
+        }
+    }
+
+    Map<Object, CpPatch> cpPatches = new HashMap<>();
+
+    int cph = 0;  // for counting constant placeholders
+
+    String constantPlaceholder(Object arg) {
+        String cpPlaceholder = "CONSTANT_PLACEHOLDER_" + cph++;
+        if (DUMP_CLASS_FILES) cpPlaceholder += " <<" + arg.toString() + ">>";  // debugging aid
+        if (cpPatches.containsKey(cpPlaceholder)) {
+            throw new InternalError("observed CP placeholder twice: " + cpPlaceholder);
+        }
+        // insert placeholder in CP and remember the patch
+        int index = cw.newConst((Object) cpPlaceholder);  // TODO check if aready in the constant pool
+        cpPatches.put(cpPlaceholder, new CpPatch(index, cpPlaceholder, arg));
+        return cpPlaceholder;
+    }
+
+    Object[] cpPatches(byte[] classFile) {
+        int size = getConstantPoolSize(classFile);
+        Object[] res = new Object[size];
+        for (CpPatch p : cpPatches.values()) {
+            if (p.index >= size)
+                throw new InternalError("in cpool["+size+"]: "+p+"\n"+Arrays.toString(Arrays.copyOf(classFile, 20)));
+            res[p.index] = p.value;
+        }
+        return res;
+    }
+
+    /**
+     * Extract the number of constant pool entries from a given class file.
+     *
+     * @param classFile the bytes of the class file in question.
+     * @return the number of entries in the constant pool.
+     */
+    private static int getConstantPoolSize(byte[] classFile) {
+        // The first few bytes:
+        // u4 magic;
+        // u2 minor_version;
+        // u2 major_version;
+        // u2 constant_pool_count;
+        return ((classFile[8] & 0xFF) << 8) | (classFile[9] & 0xFF);
+    }
+
+    /**
+     * Extract the MemberName of a newly-defined method.
+     *
+     * @param classFile
+     * @return
+     */
+    private MemberName loadMethod(byte[] classFile) {
+        Class<?> invokerClass = loadAndInitializeInvokerClass(classFile, cpPatches(classFile));
+        return resolveInvokerMember(invokerClass, invokerName, invokerType);
+    }
+
+    /**
+     * Define a given class as anonymous class in the runtime system.
+     *
+     * @param classBytes
+     * @param patches
+     * @return
+     */
+    private static Class<?> loadAndInitializeInvokerClass(byte[] classBytes, Object[] patches) {
+        Class<?> invokerClass = UNSAFE.defineAnonymousClass(HOST_CLASS, classBytes, patches);
+        UNSAFE.ensureClassInitialized(invokerClass);  // Make sure the class is initialized; VM might complain.
+        return invokerClass;
+    }
+
+    /**
+     * TODO
+     *
+     * @param invokerClass
+     * @param name
+     * @param type
+     * @return
+     */
+    private static MemberName resolveInvokerMember(Class<?> invokerClass, String name, MethodType type) {
+        MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic);
+        //System.out.println("resolveInvokerMember => "+member);
+        //for (Method m : invokerClass.getDeclaredMethods())  System.out.println("  "+m);
+        try {
+            member = MEMBERNAME_FACTORY.resolveOrFail(REF_invokeStatic, member, HOST_CLASS, ReflectiveOperationException.class);
+        } catch (ReflectiveOperationException e) {
+            throw newInternalError(e);
+        }
+        //System.out.println("resolveInvokerMember => "+member);
+        return member;
+    }
+
+    /**
+     * Set up class file generation.
+     */
+    private void classFilePrologue() {
+        cw = new ClassWriter(ClassWriter.COMPUTE_MAXS + ClassWriter.COMPUTE_FRAMES);
+        cw.visit(Opcodes.V1_6, Opcodes.ACC_PUBLIC + Opcodes.ACC_FINAL + Opcodes.ACC_SUPER, className, null, superName, null);
+        cw.visitSource(sourceFile, null);
+
+        String invokerDesc = invokerType.toMethodDescriptorString();
+        mv = cw.visitMethod(Opcodes.ACC_STATIC, invokerName, invokerDesc, null, null);
+
+        // Force inlining of this invoker method.
+        mv.visitAnnotation("Ljava/lang/invoke/ForceInline;", true);
+    }
+
+    /**
+     * Tear down class file generation.
+     */
+    private void classFileEpilogue() {
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+    }
+
+    /*
+     * Low-level emit helpers.
+     */
+    private void emitConst(Object con) {
+        if (con == null) {
+            mv.visitInsn(Opcodes.ACONST_NULL);
+            return;
+        }
+        if (con instanceof Integer) {
+            emitIconstInsn((int) con);
+            return;
+        }
+        if (con instanceof Long) {
+            long x = (long) con;
+            if (x == (short) x) {
+                emitIconstInsn((int) x);
+                mv.visitInsn(Opcodes.I2L);
+                return;
+            }
+        }
+        if (con instanceof Float) {
+            float x = (float) con;
+            if (x == (short) x) {
+                emitIconstInsn((int) x);
+                mv.visitInsn(Opcodes.I2F);
+                return;
+            }
+        }
+        if (con instanceof Double) {
+            double x = (double) con;
+            if (x == (short) x) {
+                emitIconstInsn((int) x);
+                mv.visitInsn(Opcodes.I2D);
+                return;
+            }
+        }
+        if (con instanceof Boolean) {
+            emitIconstInsn((boolean) con ? 1 : 0);
+            return;
+        }
+        // fall through:
+        mv.visitLdcInsn(con);
+    }
+
+    private void emitIconstInsn(int i) {
+        int opcode;
+        switch (i) {
+        case 0:  opcode = Opcodes.ICONST_0;  break;
+        case 1:  opcode = Opcodes.ICONST_1;  break;
+        case 2:  opcode = Opcodes.ICONST_2;  break;
+        case 3:  opcode = Opcodes.ICONST_3;  break;
+        case 4:  opcode = Opcodes.ICONST_4;  break;
+        case 5:  opcode = Opcodes.ICONST_5;  break;
+        default:
+            if (i == (byte) i) {
+                mv.visitIntInsn(Opcodes.BIPUSH, i & 0xFF);
+            } else if (i == (short) i) {
+                mv.visitIntInsn(Opcodes.SIPUSH, (char) i);
+            } else {
+                mv.visitLdcInsn(i);
+            }
+            return;
+        }
+        mv.visitInsn(opcode);
+    }
+
+    /*
+     * NOTE: These load/store methods use the localsMap to find the correct index!
+     */
+    private void emitLoadInsn(char type, int index) {
+        int opcode;
+        switch (type) {
+        case 'I':  opcode = Opcodes.ILOAD;  break;
+        case 'J':  opcode = Opcodes.LLOAD;  break;
+        case 'F':  opcode = Opcodes.FLOAD;  break;
+        case 'D':  opcode = Opcodes.DLOAD;  break;
+        case 'L':  opcode = Opcodes.ALOAD;  break;
+        default:
+            throw new InternalError("unknown type: " + type);
+        }
+        mv.visitVarInsn(opcode, localsMap[index]);
+    }
+    private void emitAloadInsn(int index) {
+        emitLoadInsn('L', index);
+    }
+
+    private void emitStoreInsn(char type, int index) {
+        int opcode;
+        switch (type) {
+        case 'I':  opcode = Opcodes.ISTORE;  break;
+        case 'J':  opcode = Opcodes.LSTORE;  break;
+        case 'F':  opcode = Opcodes.FSTORE;  break;
+        case 'D':  opcode = Opcodes.DSTORE;  break;
+        case 'L':  opcode = Opcodes.ASTORE;  break;
+        default:
+            throw new InternalError("unknown type: " + type);
+        }
+        mv.visitVarInsn(opcode, localsMap[index]);
+    }
+    private void emitAstoreInsn(int index) {
+        emitStoreInsn('L', index);
+    }
+
+    /**
+     * Emit a boxing call.
+     *
+     * @param type primitive type class to box.
+     */
+    private void emitBoxing(Class<?> type) {
+        Wrapper wrapper = Wrapper.forPrimitiveType(type);
+        String owner = "java/lang/" + wrapper.wrapperType().getSimpleName();
+        String name  = "valueOf";
+        String desc  = "(" + wrapper.basicTypeChar() + ")L" + owner + ";";
+        mv.visitMethodInsn(Opcodes.INVOKESTATIC, owner, name, desc);
+    }
+
+    /**
+     * Emit an unboxing call (plus preceding checkcast).
+     *
+     * @param type wrapper type class to unbox.
+     */
+    private void emitUnboxing(Class<?> type) {
+        Wrapper wrapper = Wrapper.forWrapperType(type);
+        String owner = "java/lang/" + wrapper.wrapperType().getSimpleName();
+        String name  = wrapper.primitiveSimpleName() + "Value";
+        String desc  = "()" + wrapper.basicTypeChar();
+        mv.visitTypeInsn(Opcodes.CHECKCAST, owner);
+        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, owner, name, desc);
+    }
+
+    /**
+     * Emit an implicit conversion.
+     *
+     * @param ptype type of value present on stack
+     * @param pclass type of value required on stack
+     */
+    private void emitImplicitConversion(char ptype, Class<?> pclass) {
+        switch (ptype) {
+        case 'L':
+            if (VerifyType.isNullConversion(Object.class, pclass))
+                return;
+            if (isStaticallyNameable(pclass)) {
+                mv.visitTypeInsn(Opcodes.CHECKCAST, getInternalName(pclass));
+            } else {
+                mv.visitLdcInsn(constantPlaceholder(pclass));
+                mv.visitTypeInsn(Opcodes.CHECKCAST, CLS);
+                mv.visitInsn(Opcodes.SWAP);
+                mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CLS, "cast", LL_SIG);
+                if (pclass.isArray())
+                    mv.visitTypeInsn(Opcodes.CHECKCAST, OBJARY);
+            }
+            return;
+        case 'I':
+            if (!VerifyType.isNullConversion(int.class, pclass))
+                emitPrimCast(ptype, Wrapper.basicTypeChar(pclass));
+            return;
+        case 'J':
+            assert(pclass == long.class);
+            return;
+        case 'F':
+            assert(pclass == float.class);
+            return;
+        case 'D':
+            assert(pclass == double.class);
+            return;
+        }
+        throw new InternalError("bad implicit conversion: tc="+ptype+": "+pclass);
+    }
+
+    /**
+     * Emits an actual return instruction conforming to the given return type.
+     */
+    private void emitReturnInsn(Class<?> type) {
+        int opcode;
+        switch (Wrapper.basicTypeChar(type)) {
+        case 'I':  opcode = Opcodes.IRETURN;  break;
+        case 'J':  opcode = Opcodes.LRETURN;  break;
+        case 'F':  opcode = Opcodes.FRETURN;  break;
+        case 'D':  opcode = Opcodes.DRETURN;  break;
+        case 'L':  opcode = Opcodes.ARETURN;  break;
+        case 'V':  opcode = Opcodes.RETURN;   break;
+        default:
+            throw new InternalError("unknown return type: " + type);
+        }
+        mv.visitInsn(opcode);
+    }
+
+    private static String getInternalName(Class<?> c) {
+        assert(VerifyAccess.isTypeVisible(c, Object.class));
+        return c.getName().replace('.', '/');
+    }
+
+    /**
+     * Generate customized bytecode for a given LambdaForm.
+     *
+     * @param form
+     * @param invokerType
+     * @return
+     */
+    static MemberName generateCustomizedCode(LambdaForm form, MethodType invokerType) {
+        InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("MH", form, invokerType);
+        return g.loadMethod(g.generateCustomizedCodeBytes());
+    }
+
+    /**
+     * Generate an invoker method for the passed {@link LambdaForm}.
+     */
+    private byte[] generateCustomizedCodeBytes() {
+        classFilePrologue();
+
+        // Suppress this method in backtraces displayed to the user.
+        mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
+
+        // Mark this method as a compiled LambdaForm
+        mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Compiled;", true);
+
+        // iterate over the form's names, generating bytecode instructions for each
+        // start iterating at the first name following the arguments
+        for (int i = lambdaForm.arity; i < lambdaForm.names.length; i++) {
+            Name name = lambdaForm.names[i];
+            MemberName member = name.function.member();
+
+            if (isSelectAlternative(member)) {
+                // selectAlternative idiom
+                // FIXME: make sure this idiom is really present!
+                emitSelectAlternative(name, lambdaForm.names[i + 1]);
+                i++;  // skip MH.invokeBasic of the selectAlternative result
+            } else if (isStaticallyInvocable(member)) {
+                emitStaticInvoke(member, name);
+            } else {
+                emitInvoke(name);
+            }
+
+            // store the result from evaluating to the target name in a local if required
+            // (if this is the last value, i.e., the one that is going to be returned,
+            // avoid store/load/return and just return)
+            if (i == lambdaForm.names.length - 1 && i == lambdaForm.result) {
+                // return value - do nothing
+            } else if (name.type != 'V') {
+                // non-void: actually assign
+                emitStoreInsn(name.type, name.index());
+            }
+        }
+
+        // return statement
+        emitReturn();
+
+        classFileEpilogue();
+        bogusMethod(lambdaForm);
+
+        final byte[] classFile = cw.toByteArray();
+        maybeDump(className, classFile);
+        return classFile;
+    }
+
+    /**
+     * Emit an invoke for the given name.
+     *
+     * @param name
+     */
+    void emitInvoke(Name name) {
+        if (true) {
+            // push receiver
+            MethodHandle target = name.function.resolvedHandle;
+            assert(target != null) : name.exprString();
+            mv.visitLdcInsn(constantPlaceholder(target));
+            mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
+        } else {
+            // load receiver
+            emitAloadInsn(0);
+            mv.visitTypeInsn(Opcodes.CHECKCAST, MH);
+            mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", LF_SIG);
+            mv.visitFieldInsn(Opcodes.GETFIELD, LF, "names", LFN_SIG);
+            // TODO more to come
+        }
+
+        // push arguments
+        for (int i = 0; i < name.arguments.length; i++) {
+            emitPushArgument(name, i);
+        }
+
+        // invocation
+        MethodType type = name.function.methodType();
+        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", type.basicType().toMethodDescriptorString());
+    }
+
+    static private Class<?>[] STATICALLY_INVOCABLE_PACKAGES = {
+        // Sample classes from each package we are willing to bind to statically:
+        java.lang.Object.class,
+        java.util.Arrays.class,
+        sun.misc.Unsafe.class
+        //MethodHandle.class already covered
+    };
+
+    static boolean isStaticallyInvocable(MemberName member) {
+        if (member == null)  return false;
+        if (member.isConstructor())  return false;
+        Class<?> cls = member.getDeclaringClass();
+        if (cls.isArray() || cls.isPrimitive())
+            return false;  // FIXME
+        if (cls.isAnonymousClass() || cls.isLocalClass())
+            return false;  // inner class of some sort
+        if (cls.getClassLoader() != MethodHandle.class.getClassLoader())
+            return false;  // not on BCP
+        if (!member.isPrivate() && VerifyAccess.isSamePackage(MethodHandle.class, cls))
+            return true;   // in java.lang.invoke package
+        if (member.isPublic() && isStaticallyNameable(cls))
+            return true;
+        return false;
+    }
+
+    static boolean isStaticallyNameable(Class<?> cls) {
+        while (cls.isArray())
+            cls = cls.getComponentType();
+        if (cls.isPrimitive())
+            return true;  // int[].class, for example
+        if (cls.getClassLoader() != Object.class.getClassLoader())
+            return false;
+        if (VerifyAccess.isSamePackage(MethodHandle.class, cls))
+            return true;
+        if (!Modifier.isPublic(cls.getModifiers()))
+            return false;
+        for (Class<?> pkgcls : STATICALLY_INVOCABLE_PACKAGES) {
+            if (VerifyAccess.isSamePackage(pkgcls, cls))
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Emit an invoke for the given name, using the MemberName directly.
+     *
+     * @param name
+     */
+    void emitStaticInvoke(MemberName member, Name name) {
+        assert(member.equals(name.function.member()));
+        String cname = getInternalName(member.getDeclaringClass());
+        String mname = member.getName();
+        String mtype;
+        byte refKind = member.getReferenceKind();
+        if (refKind == REF_invokeSpecial) {
+            // in order to pass the verifier, we need to convert this to invokevirtual in all cases
+            assert(member.canBeStaticallyBound()) : member;
+            refKind = REF_invokeVirtual;
+        }
+
+        // push arguments
+        for (int i = 0; i < name.arguments.length; i++) {
+            emitPushArgument(name, i);
+        }
+
+        // invocation
+        if (member.isMethod()) {
+            mtype = member.getMethodType().toMethodDescriptorString();
+            mv.visitMethodInsn(refKindOpcode(refKind), cname, mname, mtype);
+        } else {
+            mtype = MethodType.toFieldDescriptorString(member.getFieldType());
+            mv.visitFieldInsn(refKindOpcode(refKind), cname, mname, mtype);
+        }
+    }
+    int refKindOpcode(byte refKind) {
+        switch (refKind) {
+        case REF_invokeVirtual:      return Opcodes.INVOKEVIRTUAL;
+        case REF_invokeStatic:       return Opcodes.INVOKESTATIC;
+        case REF_invokeSpecial:      return Opcodes.INVOKESPECIAL;
+        case REF_invokeInterface:    return Opcodes.INVOKEINTERFACE;
+        case REF_getField:           return Opcodes.GETFIELD;
+        case REF_putField:           return Opcodes.PUTFIELD;
+        case REF_getStatic:          return Opcodes.GETSTATIC;
+        case REF_putStatic:          return Opcodes.PUTSTATIC;
+        }
+        throw new InternalError("refKind="+refKind);
+    }
+
+    /**
+     * Check if MemberName is a call to MethodHandleImpl.selectAlternative.
+     *
+     * @param member
+     * @return true if member is a call to MethodHandleImpl.selectAlternative
+     */
+    private boolean isSelectAlternative(MemberName member) {
+        return member != null &&
+               member.getDeclaringClass() == MethodHandleImpl.class &&
+               member.getName().equals("selectAlternative");
+    }
+
+    /**
+     * Emit bytecode for the selectAlternative idiom.
+     *
+     * The pattern looks like (Cf. MethodHandleImpl.makeGuardWithTest):
+     *
+     *   Lambda(a0:L,a1:I)=>{
+     *     t2:I=foo.test(a1:I);
+     *     t3:L=MethodHandleImpl.selectAlternative(t2:I,(MethodHandle(int)int),(MethodHandle(int)int));
+     *     t4:I=MethodHandle.invokeBasic(t3:L,a1:I);t4:I}
+     *
+     * @param selectAlternativeName
+     * @param invokeBasicName
+     */
+    private void emitSelectAlternative(Name selectAlternativeName, Name invokeBasicName) {
+        MethodType type = selectAlternativeName.function.methodType();
+
+        Name receiver = (Name) invokeBasicName.arguments[0];
+
+        Label L_fallback = new Label();
+        Label L_done     = new Label();
+
+        // load test result
+        emitPushArgument(selectAlternativeName, 0);
+        mv.visitInsn(Opcodes.ICONST_1);
+
+        // if_icmpne L_fallback
+        mv.visitJumpInsn(Opcodes.IF_ICMPNE, L_fallback);
+
+        // invoke selectAlternativeName.arguments[1]
+        MethodHandle target = (MethodHandle) selectAlternativeName.arguments[1];
+        emitPushArgument(selectAlternativeName, 1);  // get 2nd argument of selectAlternative
+        emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
+        emitInvoke(invokeBasicName);
+
+        // goto L_done
+        mv.visitJumpInsn(Opcodes.GOTO, L_done);
+
+        // L_fallback:
+        mv.visitLabel(L_fallback);
+
+        // invoke selectAlternativeName.arguments[2]
+        MethodHandle fallback = (MethodHandle) selectAlternativeName.arguments[2];
+        emitPushArgument(selectAlternativeName, 2);  // get 3rd argument of selectAlternative
+        emitAstoreInsn(receiver.index());  // store the MH in the receiver slot
+        emitInvoke(invokeBasicName);
+
+        // L_done:
+        mv.visitLabel(L_done);
+    }
+
+    /**
+     *
+     * @param name
+     * @param paramIndex
+     */
+    private void emitPushArgument(Name name, int paramIndex) {
+        Object arg = name.arguments[paramIndex];
+        char ptype = name.function.parameterType(paramIndex);
+        MethodType mtype = name.function.methodType();
+        if (arg instanceof Name) {
+            Name n = (Name) arg;
+            emitLoadInsn(n.type, n.index());
+            emitImplicitConversion(n.type, mtype.parameterType(paramIndex));
+        } else if ((arg == null || arg instanceof String) && ptype == 'L') {
+            emitConst(arg);
+        } else {
+            if (Wrapper.isWrapperType(arg.getClass()) && ptype != 'L') {
+                emitConst(arg);
+            } else {
+                mv.visitLdcInsn(constantPlaceholder(arg));
+                emitImplicitConversion('L', mtype.parameterType(paramIndex));
+            }
+        }
+    }
+
+    /**
+     * Emits a return statement from a LF invoker. If required, the result type is cast to the correct return type.
+     */
+    private void emitReturn() {
+        // return statement
+        if (lambdaForm.result == -1) {
+            // void
+            mv.visitInsn(Opcodes.RETURN);
+        } else {
+            LambdaForm.Name rn = lambdaForm.names[lambdaForm.result];
+            char rtype = Wrapper.basicTypeChar(invokerType.returnType());
+
+            // put return value on the stack if it is not already there
+            if (lambdaForm.result != lambdaForm.names.length - 1) {
+                emitLoadInsn(rn.type, lambdaForm.result);
+            }
+
+            // potentially generate cast
+            // rtype is the return type of the invoker - generated code must conform to this
+            // rn.type is the type of the result Name in the LF
+            if (rtype != rn.type) {
+                // need cast
+                if (rtype == 'L') {
+                    // possibly cast the primitive to the correct type for boxing
+                    char boxedType = Wrapper.forWrapperType(invokerType.returnType()).basicTypeChar();
+                    if (boxedType != rn.type) {
+                        emitPrimCast(rn.type, boxedType);
+                    }
+                    // cast primitive to reference ("boxing")
+                    emitBoxing(invokerType.returnType());
+                } else {
+                    // to-primitive cast
+                    if (rn.type != 'L') {
+                        // prim-to-prim cast
+                        emitPrimCast(rn.type, rtype);
+                    } else {
+                        // ref-to-prim cast ("unboxing")
+                        throw new InternalError("no ref-to-prim (unboxing) casts supported right now");
+                    }
+                }
+            }
+
+            // generate actual return statement
+            emitReturnInsn(invokerType.returnType());
+        }
+    }
+
+    /**
+     * Emit a type conversion bytecode casting from "from" to "to".
+     */
+    private void emitPrimCast(char from, char to) {
+        // Here's how.
+        // -   indicates forbidden
+        // <-> indicates implicit
+        //      to ----> boolean  byte     short    char     int      long     float    double
+        // from boolean    <->        -        -        -        -        -        -        -
+        //      byte        -       <->       i2s      i2c      <->      i2l      i2f      i2d
+        //      short       -       i2b       <->      i2c      <->      i2l      i2f      i2d
+        //      char        -       i2b       i2s      <->      <->      i2l      i2f      i2d
+        //      int         -       i2b       i2s      i2c      <->      i2l      i2f      i2d
+        //      long        -     l2i,i2b   l2i,i2s  l2i,i2c    l2i      <->      l2f      l2d
+        //      float       -     f2i,i2b   f2i,i2s  f2i,i2c    f2i      f2l      <->      f2d
+        //      double      -     d2i,i2b   d2i,i2s  d2i,i2c    d2i      d2l      d2f      <->
+        if (from == to) {
+            // no cast required, should be dead code anyway
+            return;
+        }
+        Wrapper wfrom = Wrapper.forBasicType(from);
+        Wrapper wto   = Wrapper.forBasicType(to);
+        if (wfrom.isSubwordOrInt()) {
+            // cast from {byte,short,char,int} to anything
+            emitI2X(to);
+        } else {
+            // cast from {long,float,double} to anything
+            if (wto.isSubwordOrInt()) {
+                // cast to {byte,short,char,int}
+                emitX2I(from);
+                if (wto.bitWidth() < 32) {
+                    // targets other than int require another conversion
+                    emitI2X(to);
+                }
+            } else {
+                // cast to {long,float,double} - this is verbose
+                boolean error = false;
+                switch (from) {
+                case 'J':
+                         if (to == 'F') { mv.visitInsn(Opcodes.L2F); }
+                    else if (to == 'D') { mv.visitInsn(Opcodes.L2D); }
+                    else error = true;
+                    break;
+                case 'F':
+                         if (to == 'J') { mv.visitInsn(Opcodes.F2L); }
+                    else if (to == 'D') { mv.visitInsn(Opcodes.F2D); }
+                    else error = true;
+                    break;
+                case 'D':
+                         if (to == 'J') { mv.visitInsn(Opcodes.D2L); }
+                    else if (to == 'F') { mv.visitInsn(Opcodes.D2F); }
+                    else error = true;
+                    break;
+                default:
+                    error = true;
+                    break;
+                }
+                if (error) {
+                    throw new IllegalStateException("unhandled prim cast: " + from + "2" + to);
+                }
+            }
+        }
+    }
+
+    private void emitI2X(char type) {
+        switch (type) {
+        case 'B':  mv.visitInsn(Opcodes.I2B);  break;
+        case 'S':  mv.visitInsn(Opcodes.I2S);  break;
+        case 'C':  mv.visitInsn(Opcodes.I2C);  break;
+        case 'I':  /* naught */                break;
+        case 'J':  mv.visitInsn(Opcodes.I2L);  break;
+        case 'F':  mv.visitInsn(Opcodes.I2F);  break;
+        case 'D':  mv.visitInsn(Opcodes.I2D);  break;
+        case 'Z':
+            // For compatibility with ValueConversions and explicitCastArguments:
+            mv.visitInsn(Opcodes.ICONST_1);
+            mv.visitInsn(Opcodes.IAND);
+            break;
+        default:   throw new InternalError("unknown type: " + type);
+        }
+    }
+
+    private void emitX2I(char type) {
+        switch (type) {
+        case 'J':  mv.visitInsn(Opcodes.L2I);  break;
+        case 'F':  mv.visitInsn(Opcodes.F2I);  break;
+        case 'D':  mv.visitInsn(Opcodes.D2I);  break;
+        default:   throw new InternalError("unknown type: " + type);
+        }
+    }
+
+    private static String basicTypeCharSignature(String prefix, MethodType type) {
+        StringBuilder buf = new StringBuilder(prefix);
+        for (Class<?> ptype : type.parameterList())
+            buf.append(Wrapper.forBasicType(ptype).basicTypeChar());
+        buf.append('_').append(Wrapper.forBasicType(type.returnType()).basicTypeChar());
+        return buf.toString();
+    }
+
+    /**
+     * Generate bytecode for a LambdaForm.vmentry which calls interpretWithArguments.
+     *
+     * @param sig
+     * @return
+     */
+    static MemberName generateLambdaFormInterpreterEntryPoint(String sig) {
+        assert(LambdaForm.isValidSignature(sig));
+        //System.out.println("generateExactInvoker "+sig);
+        // compute method type
+        // first parameter and return type
+        char tret = LambdaForm.signatureReturn(sig);
+        MethodType type = MethodType.methodType(LambdaForm.typeClass(tret), MethodHandle.class);
+        // other parameter types
+        int arity = LambdaForm.signatureArity(sig);
+        for (int i = 1; i < arity; i++) {
+            type = type.appendParameterTypes(LambdaForm.typeClass(sig.charAt(i)));
+        }
+        InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("LFI", "interpret_"+tret, type);
+        return g.loadMethod(g.generateLambdaFormInterpreterEntryPointBytes());
+    }
+
+    private byte[] generateLambdaFormInterpreterEntryPointBytes() {
+        classFilePrologue();
+
+        // Suppress this method in backtraces displayed to the user.
+        mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
+
+        // create parameter array
+        emitIconstInsn(invokerType.parameterCount());
+        mv.visitTypeInsn(Opcodes.ANEWARRAY, "java/lang/Object");
+
+        // fill parameter array
+        for (int i = 0; i < invokerType.parameterCount(); i++) {
+            Class<?> ptype = invokerType.parameterType(i);
+            mv.visitInsn(Opcodes.DUP);
+            emitIconstInsn(i);
+            emitLoadInsn(Wrapper.basicTypeChar(ptype), i);
+            // box if primitive type
+            if (ptype.isPrimitive()) {
+                emitBoxing(ptype);
+            }
+            mv.visitInsn(Opcodes.AASTORE);
+        }
+        // invoke
+        emitAloadInsn(0);
+        mv.visitFieldInsn(Opcodes.GETFIELD, MH, "form", "Ljava/lang/invoke/LambdaForm;");
+        mv.visitInsn(Opcodes.SWAP);  // swap form and array; avoid local variable
+        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, LF, "interpretWithArguments", "([Ljava/lang/Object;)Ljava/lang/Object;");
+
+        // maybe unbox
+        Class<?> rtype = invokerType.returnType();
+        if (rtype.isPrimitive() && rtype != void.class) {
+            emitUnboxing(Wrapper.asWrapperType(rtype));
+        }
+
+        // return statement
+        emitReturnInsn(rtype);
+
+        classFileEpilogue();
+        bogusMethod(invokerType);
+
+        final byte[] classFile = cw.toByteArray();
+        maybeDump(className, classFile);
+        return classFile;
+    }
+
+    /**
+     * Generate bytecode for a NamedFunction invoker.
+     *
+     * @param srcType
+     * @param dstType
+     * @return
+     */
+    static MemberName generateNamedFunctionInvoker(MethodTypeForm typeForm) {
+        MethodType invokerType = LambdaForm.NamedFunction.INVOKER_METHOD_TYPE;
+        String invokerName = basicTypeCharSignature("invoke_", typeForm.erasedType());
+        InvokerBytecodeGenerator g = new InvokerBytecodeGenerator("NFI", invokerName, invokerType);
+        return g.loadMethod(g.generateNamedFunctionInvokerImpl(typeForm));
+    }
+
+    static int nfi = 0;
+
+    private byte[] generateNamedFunctionInvokerImpl(MethodTypeForm typeForm) {
+        MethodType dstType = typeForm.erasedType();
+        classFilePrologue();
+
+        // Suppress this method in backtraces displayed to the user.
+        mv.visitAnnotation("Ljava/lang/invoke/LambdaForm$Hidden;", true);
+
+        // Load receiver
+        emitAloadInsn(0);
+
+        // Load arguments from array
+        for (int i = 0; i < dstType.parameterCount(); i++) {
+            emitAloadInsn(1);
+            emitIconstInsn(i);
+            mv.visitInsn(Opcodes.AALOAD);
+
+            // Maybe unbox
+            Class<?> dptype = dstType.parameterType(i);
+            if (dptype.isPrimitive()) {
+                Class<?> sptype = dstType.basicType().wrap().parameterType(i);
+                Wrapper dstWrapper = Wrapper.forBasicType(dptype);
+                Wrapper srcWrapper = dstWrapper.isSubwordOrInt() ? Wrapper.INT : dstWrapper;  // narrow subword from int
+                emitUnboxing(srcWrapper.wrapperType());
+                emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar());
+            }
+        }
+
+        // Invoke
+        String targetDesc = dstType.basicType().toMethodDescriptorString();
+        mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, MH, "invokeBasic", targetDesc);
+
+        // Box primitive types
+        Class<?> rtype = dstType.returnType();
+        if (rtype != void.class && rtype.isPrimitive()) {
+            Wrapper srcWrapper = Wrapper.forBasicType(rtype);
+            Wrapper dstWrapper = srcWrapper.isSubwordOrInt() ? Wrapper.INT : srcWrapper;  // widen subword to int
+            // boolean casts not allowed
+            emitPrimCast(srcWrapper.basicTypeChar(), dstWrapper.basicTypeChar());
+            emitBoxing(dstWrapper.primitiveType());
+        }
+
+        // If the return type is void we return a null reference.
+        if (rtype == void.class) {
+            mv.visitInsn(Opcodes.ACONST_NULL);
+        }
+        emitReturnInsn(Object.class);  // NOTE: NamedFunction invokers always return a reference value.
+
+        classFileEpilogue();
+        bogusMethod(dstType);
+
+        final byte[] classFile = cw.toByteArray();
+        maybeDump(className, classFile);
+        return classFile;
+    }
+
+    /**
+     * Emit a bogus method that just loads some string constants. This is to get the constants into the constant pool
+     * for debugging purposes.
+     */
+    private void bogusMethod(Object... os) {
+        if (DUMP_CLASS_FILES) {
+            mv = cw.visitMethod(Opcodes.ACC_STATIC, "dummy", "()V", null, null);
+            for (Object o : os) {
+                mv.visitLdcInsn(o.toString());
+                mv.visitInsn(Opcodes.POP);
+            }
+            mv.visitInsn(Opcodes.RETURN);
+            mv.visitMaxs(0, 0);
+            mv.visitEnd();
+        }
+    }
+}
diff --git a/jdk/src/share/classes/java/lang/invoke/Invokers.java b/jdk/src/share/classes/java/lang/invoke/Invokers.java
index 24b7d3e..0e40396 100644
--- a/jdk/src/share/classes/java/lang/invoke/Invokers.java
+++ b/jdk/src/share/classes/java/lang/invoke/Invokers.java
@@ -25,8 +25,12 @@
 
 package java.lang.invoke;
 
+import java.util.Arrays;
 import sun.invoke.empty.Empty;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
+import static java.lang.invoke.LambdaForm.*;
 
 /**
  * Construction and caching of often-used invokers.
@@ -36,11 +40,15 @@
     // exact type (sans leading taget MH) for the outgoing call
     private final MethodType targetType;
 
+    // FIXME: Get rid of the invokers that are not useful.
+
     // exact invoker for the outgoing call
     private /*lazy*/ MethodHandle exactInvoker;
 
     // erased (partially untyped but with primitives) invoker for the outgoing call
+    // FIXME: get rid of
     private /*lazy*/ MethodHandle erasedInvoker;
+    // FIXME: get rid of
     /*lazy*/ MethodHandle erasedInvokerWithDrops;  // for InvokeGeneric
 
     // general invoker for the outgoing call
@@ -63,14 +71,23 @@
         this.spreadInvokers = new MethodHandle[targetType.parameterCount()+1];
     }
 
-    /*non-public*/ static MethodType invokerType(MethodType targetType) {
-        return targetType.insertParameterTypes(0, MethodHandle.class);
-    }
-
     /*non-public*/ MethodHandle exactInvoker() {
         MethodHandle invoker = exactInvoker;
         if (invoker != null)  return invoker;
-        invoker = lookupInvoker("invokeExact");
+        MethodType mtype = targetType;
+        MethodType invokerType = mtype.invokerType();
+        LambdaForm lform;
+        final int MTYPE_ARG_APPENDED = 1;  // argument count for appended mtype value
+        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - MTYPE_ARG_APPENDED) {
+            lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_INVOKER);
+            invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
+        } else {
+            // At maximum arity, we cannot afford an extra mtype argument,
+            // so build a fully customized (non-cached) invoker form.
+            lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_INVOKER);
+            invoker = SimpleMethodHandle.make(invokerType, lform);
+        }
+        assert(checkInvoker(invoker));
         exactInvoker = invoker;
         return invoker;
     }
@@ -78,29 +95,61 @@
     /*non-public*/ MethodHandle generalInvoker() {
         MethodHandle invoker = generalInvoker;
         if (invoker != null)  return invoker;
-        invoker = lookupInvoker("invoke");
+        MethodType mtype = targetType;
+        MethodType invokerType = mtype.invokerType();
+        LambdaForm lform;
+        final int MTYPE_ARG_APPENDED = 1;  // argument count for appended mtype value
+        assert(GENERIC_INVOKER_SLOP >= MTYPE_ARG_APPENDED);
+        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY - GENERIC_INVOKER_SLOP) {
+            prepareForGenericCall(mtype);
+            lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_INVOKER);
+            invoker = BoundMethodHandle.bindSingle(invokerType, lform, mtype);
+        } else {
+            // At maximum arity, we cannot afford an extra mtype argument,
+            // so build a fully customized (non-cached) invoker form.
+            lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_INVOKER);
+            invoker = SimpleMethodHandle.make(invokerType, lform);
+        }
+        assert(checkInvoker(invoker));
         generalInvoker = invoker;
         return invoker;
     }
 
-    private MethodHandle lookupInvoker(String name) {
-        MethodHandle invoker;
-        try {
-            invoker = IMPL_LOOKUP.findVirtual(MethodHandle.class, name, targetType);
-        } catch (ReflectiveOperationException ex) {
-            throw new InternalError("JVM cannot find invoker for "+targetType);
-        }
-        assert(invokerType(targetType) == invoker.type());
-        assert(!invoker.isVarargsCollector());
+    /*non-public*/ MethodHandle makeBasicInvoker() {
+        MethodHandle invoker = DirectMethodHandle.make(invokeBasicMethod(targetType));
+        assert(targetType == targetType.basicType());
+        // Note:  This is not cached here.  It is cached by the calling MethodTypeForm.
+        assert(checkInvoker(invoker));
         return invoker;
     }
 
+    static MemberName invokeBasicMethod(MethodType type) {
+        type = type.basicType();
+        String name = "invokeBasic";
+        try {
+            //Lookup.findVirtual(MethodHandle.class, name, type);
+            return IMPL_LOOKUP.resolveOrFail(REF_invokeVirtual, MethodHandle.class, name, type);
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError("JVM cannot find invoker for "+type, ex);
+        }
+    }
+
+    private boolean checkInvoker(MethodHandle invoker) {
+        assert(targetType.invokerType().equals(invoker.type()))
+                : java.util.Arrays.asList(targetType, targetType.invokerType(), invoker);
+        assert(invoker.internalMemberName() == null ||
+               invoker.internalMemberName().getMethodType().equals(targetType));
+        assert(!invoker.isVarargsCollector());
+        return true;
+    }
+
+    // FIXME: get rid of
     /*non-public*/ MethodHandle erasedInvoker() {
         MethodHandle xinvoker = exactInvoker();
         MethodHandle invoker = erasedInvoker;
         if (invoker != null)  return invoker;
         MethodType erasedType = targetType.erase();
-        invoker = xinvoker.asType(invokerType(erasedType));
+        invoker = xinvoker.asType(erasedType.invokerType());
         erasedInvoker = invoker;
         return invoker;
     }
@@ -108,9 +157,31 @@
     /*non-public*/ MethodHandle spreadInvoker(int leadingArgCount) {
         MethodHandle vaInvoker = spreadInvokers[leadingArgCount];
         if (vaInvoker != null)  return vaInvoker;
-        MethodHandle gInvoker = generalInvoker();
         int spreadArgCount = targetType.parameterCount() - leadingArgCount;
-        vaInvoker = gInvoker.asSpreader(Object[].class, spreadArgCount);
+        MethodType spreadInvokerType = targetType
+            .replaceParameterTypes(leadingArgCount, targetType.parameterCount(), Object[].class);
+        if (targetType.parameterSlotCount() <= MethodType.MAX_MH_INVOKER_ARITY) {
+            // Factor sinvoker.invoke(mh, a) into ginvoker.asSpreader().invoke(mh, a)
+            // where ginvoker.invoke(mh, a*) => mh.invoke(a*).
+            MethodHandle genInvoker = generalInvoker();
+            vaInvoker = genInvoker.asSpreader(Object[].class, spreadArgCount);
+        } else {
+            // Cannot build a general invoker here of type ginvoker.invoke(mh, a*[254]).
+            // Instead, factor sinvoker.invoke(mh, a) into ainvoker.invoke(filter(mh), a)
+            // where filter(mh) == mh.asSpreader(Object[], spreadArgCount)
+            MethodHandle arrayInvoker = MethodHandles.exactInvoker(spreadInvokerType);
+            MethodHandle makeSpreader;
+            try {
+                makeSpreader = IMPL_LOOKUP
+                    .findVirtual(MethodHandle.class, "asSpreader",
+                        MethodType.methodType(MethodHandle.class, Class.class, int.class));
+            } catch (ReflectiveOperationException ex) {
+                throw newInternalError(ex);
+            }
+            makeSpreader = MethodHandles.insertArguments(makeSpreader, 1, Object[].class, spreadArgCount);
+            vaInvoker = MethodHandles.filterArgument(arrayInvoker, 0, makeSpreader);
+        }
+        assert(vaInvoker.type().equals(spreadInvokerType.invokerType()));
         spreadInvokers[leadingArgCount] = vaInvoker;
         return vaInvoker;
     }
@@ -118,7 +189,7 @@
     /*non-public*/ MethodHandle varargsInvoker() {
         MethodHandle vaInvoker = varargsInvoker;
         if (vaInvoker != null)  return vaInvoker;
-        vaInvoker = spreadInvoker(0).asType(invokerType(MethodType.genericMethodType(0, true)));
+        vaInvoker = spreadInvoker(0).asType(MethodType.genericMethodType(0, true).invokerType());
         varargsInvoker = vaInvoker;
         return vaInvoker;
     }
@@ -137,16 +208,18 @@
             uninitializedCallSite = invoker;
             return invoker;
         }
-        if (THROW_UCS == null) {
+        invoker = THROW_UCS;
+        if (invoker == null) {
             try {
-                THROW_UCS = IMPL_LOOKUP
+                THROW_UCS = invoker = IMPL_LOOKUP
                     .findStatic(CallSite.class, "uninitializedCallSite",
                                 MethodType.methodType(Empty.class));
             } catch (ReflectiveOperationException ex) {
-                throw new RuntimeException(ex);
+                throw newInternalError(ex);
             }
         }
-        invoker = AdapterMethodHandle.makeRetypeRaw(targetType, THROW_UCS);
+        invoker = MethodHandles.explicitCastArguments(invoker, MethodType.methodType(targetType.returnType()));
+        invoker = invoker.dropArguments(targetType, 0, targetType.parameterCount());
         assert(invoker.type().equals(targetType));
         uninitializedCallSite = invoker;
         return invoker;
@@ -155,4 +228,236 @@
     public String toString() {
         return "Invokers"+targetType;
     }
+
+    static MemberName exactInvokerMethod(MethodType mtype, Object[] appendixResult) {
+        LambdaForm lform;
+        final int MTYPE_ARG_APPENDED = 1;  // argument count for appended mtype value
+        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - MTYPE_ARG_APPENDED) {
+            lform = invokeForm(mtype, false, MethodTypeForm.LF_EX_LINKER);
+            appendixResult[0] = mtype;
+        } else {
+            lform = invokeForm(mtype, true, MethodTypeForm.LF_EX_LINKER);
+        }
+        return lform.vmentry;
+    }
+
+    static MemberName genericInvokerMethod(MethodType mtype, Object[] appendixResult) {
+        LambdaForm lform;
+        final int MTYPE_ARG_APPENDED = 1;  // argument count for appended mtype value
+        if (mtype.parameterSlotCount() <= MethodType.MAX_MH_ARITY - (MTYPE_ARG_APPENDED + GENERIC_INVOKER_SLOP)) {
+            lform = invokeForm(mtype, false, MethodTypeForm.LF_GEN_LINKER);
+            appendixResult[0] = mtype;
+            prepareForGenericCall(mtype);
+        } else {
+            lform = invokeForm(mtype, true, MethodTypeForm.LF_GEN_LINKER);
+        }
+        return lform.vmentry;
+    }
+
+    private static LambdaForm invokeForm(MethodType mtype, boolean customized, int which) {
+        boolean isCached;
+        if (!customized) {
+            mtype = mtype.basicType();  // normalize Z to I, String to Object, etc.
+            isCached = true;
+        } else {
+            isCached = false;  // maybe cache if mtype == mtype.basicType()
+        }
+        boolean isLinker, isGeneric;
+        String debugName;
+        switch (which) {
+        case MethodTypeForm.LF_EX_LINKER:   isLinker = true;  isGeneric = false; debugName = "invokeExact_MT"; break;
+        case MethodTypeForm.LF_EX_INVOKER:  isLinker = false; isGeneric = false; debugName = "exactInvoker"; break;
+        case MethodTypeForm.LF_GEN_LINKER:  isLinker = true;  isGeneric = true;  debugName = "invoke_MT"; break;
+        case MethodTypeForm.LF_GEN_INVOKER: isLinker = false; isGeneric = true;  debugName = "invoker"; break;
+        default: throw new InternalError();
+        }
+        LambdaForm lform;
+        if (isCached) {
+            lform = mtype.form().cachedLambdaForm(which);
+            if (lform != null)  return lform;
+        }
+        // exactInvokerForm (Object,Object)Object
+        //   link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
+        final int THIS_MH      = 0;
+        final int CALL_MH      = THIS_MH + (isLinker ? 0 : 1);
+        final int ARG_BASE     = CALL_MH + 1;
+        final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
+        final int INARG_LIMIT  = OUTARG_LIMIT + (isLinker && !customized ? 1 : 0);
+        int nameCursor = OUTARG_LIMIT;
+        final int MTYPE_ARG    = customized ? -1 : nameCursor++;  // might be last in-argument
+        final int CHECK_TYPE   = nameCursor++;
+        final int LINKER_CALL  = nameCursor++;
+        MethodType invokerFormType = mtype.invokerType();
+        if (isLinker) {
+            if (!customized)
+                invokerFormType = invokerFormType.appendParameterTypes(MemberName.class);
+        } else {
+            invokerFormType = invokerFormType.invokerType();
+        }
+        Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
+        assert(names.length == nameCursor)
+                : Arrays.asList(mtype, customized, which, nameCursor, names.length);
+        if (MTYPE_ARG >= INARG_LIMIT) {
+            assert(names[MTYPE_ARG] == null);
+            names[MTYPE_ARG] = BoundMethodHandle.getSpeciesData("L").getterName(names[THIS_MH], 0);
+            // else if isLinker, then MTYPE is passed in from the caller (e.g., the JVM)
+        }
+
+        // Make the final call.  If isGeneric, then prepend the result of type checking.
+        MethodType outCallType;
+        Object[] outArgs;
+        Object mtypeArg = (customized ? mtype : names[MTYPE_ARG]);
+        if (!isGeneric) {
+            names[CHECK_TYPE] = new Name(NF_checkExactType, names[CALL_MH], mtypeArg);
+            // mh.invokeExact(a*):R => checkExactType(mh, TYPEOF(a*:R)); mh.invokeBasic(a*)
+            outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
+            outCallType = mtype;
+        } else if (customized) {
+            names[CHECK_TYPE] = new Name(NF_asType, names[CALL_MH], mtypeArg);
+            // mh.invokeGeneric(a*):R =>
+            //  let mt=TYPEOF(a*:R), tmh=asType(mh, mt);
+            //    tmh.invokeBasic(a*)
+            outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT, Object[].class);
+            outCallType = mtype;
+        } else {
+            names[CHECK_TYPE] = new Name(NF_checkGenericType, names[CALL_MH], mtypeArg);
+            // mh.invokeGeneric(a*):R =>
+            //  let mt=TYPEOF(a*:R), gamh=checkGenericType(mh, mt);
+            //    gamh.invokeBasic(mt, mh, a*)
+            final int PREPEND_GAMH = 0, PREPEND_MT = 1, PREPEND_COUNT = 2;
+            assert(GENERIC_INVOKER_SLOP == PREPEND_COUNT);
+            outArgs = Arrays.copyOfRange(names, CALL_MH, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
+            // prepend arguments:
+            System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
+            outArgs[PREPEND_GAMH] = names[CHECK_TYPE];
+            outArgs[PREPEND_MT] = mtypeArg;
+            outCallType = mtype.insertParameterTypes(0, MethodType.class, MethodHandle.class);
+        }
+        names[LINKER_CALL] = new Name(invokeBasicMethod(outCallType), outArgs);
+        lform = new LambdaForm(debugName, INARG_LIMIT, names);
+        if (isLinker)
+            lform.compileToBytecode();  // JVM needs a real methodOop
+        if (isCached)
+            lform = mtype.form().setCachedLambdaForm(which, lform);
+        return lform;
+    }
+    private static final int GENERIC_INVOKER_SLOP = 2;  // used elsewhere to avoid arity problems
+
+    /*non-public*/ static
+    WrongMethodTypeException newWrongMethodTypeException(MethodType actual, MethodType expected) {
+        // FIXME: merge with JVM logic for throwing WMTE
+        return new WrongMethodTypeException("expected "+expected+" but found "+actual);
+    }
+
+    /** Static definition of MethodHandle.invokeExact checking code. */
+    /*non-public*/ static
+    @ForceInline
+    void checkExactType(Object mhObj, Object expectedObj) {
+        MethodHandle mh = (MethodHandle) mhObj;
+        MethodType expected = (MethodType) expectedObj;
+        MethodType actual = mh.type();
+        if (actual != expected)
+            throw newWrongMethodTypeException(expected, actual);
+    }
+
+    /** Static definition of MethodHandle.invokeGeneric checking code. */
+    /*non-public*/ static
+    @ForceInline
+    Object checkGenericType(Object mhObj, Object expectedObj) {
+        MethodHandle mh = (MethodHandle) mhObj;
+        MethodType expected = (MethodType) expectedObj;
+        //MethodType actual = mh.type();
+        MethodHandle gamh = expected.form().genericInvoker;
+        if (gamh != null)  return gamh;
+        return prepareForGenericCall(expected);
+    }
+
+    /**
+     * Returns an adapter GA for invoking a MH with type adjustments.
+     * The MethodType of the generic invocation site is prepended to MH
+     * and its arguments as follows:
+     * {@code (R)MH.invoke(A*) => GA.invokeBasic(TYPEOF<A*,R>, MH, A*)}
+     */
+    /*non-public*/ static MethodHandle prepareForGenericCall(MethodType mtype) {
+        // force any needed adapters to be preconstructed
+        MethodTypeForm form = mtype.form();
+        MethodHandle gamh = form.genericInvoker;
+        if (gamh != null)  return gamh;
+        try {
+            // Trigger adapter creation.
+            gamh = InvokeGeneric.generalInvokerOf(form.erasedType);
+            form.genericInvoker = gamh;
+            return gamh;
+        } catch (Exception ex) {
+            throw newInternalError("Exception while resolving inexact invoke", ex);
+        }
+    }
+
+    static MemberName linkToCallSiteMethod(MethodType mtype) {
+        LambdaForm lform = callSiteForm(mtype);
+        return lform.vmentry;
+    }
+
+    private static LambdaForm callSiteForm(MethodType mtype) {
+        mtype = mtype.basicType();  // normalize Z to I, String to Object, etc.
+        LambdaForm lform = mtype.form().cachedLambdaForm(MethodTypeForm.LF_CS_LINKER);
+        if (lform != null)  return lform;
+        // exactInvokerForm (Object,Object)Object
+        //   link with java.lang.invoke.MethodHandle.invokeBasic(MethodHandle,Object,Object)Object/invokeSpecial
+        final int ARG_BASE     = 0;
+        final int OUTARG_LIMIT = ARG_BASE + mtype.parameterCount();
+        final int INARG_LIMIT  = OUTARG_LIMIT + 1;
+        int nameCursor = OUTARG_LIMIT;
+        final int CSITE_ARG    = nameCursor++;  // the last in-argument
+        final int CALL_MH      = nameCursor++;  // result of getTarget
+        final int LINKER_CALL  = nameCursor++;
+        MethodType invokerFormType = mtype.appendParameterTypes(CallSite.class);
+        Name[] names = arguments(nameCursor - INARG_LIMIT, invokerFormType);
+        assert(names.length == nameCursor);
+        assert(names[CSITE_ARG] != null);
+        names[CALL_MH] = new Name(NF_getCallSiteTarget, names[CSITE_ARG]);
+        // (site.)invokedynamic(a*):R => mh = site.getTarget(); mh.invokeBasic(a*)
+        final int PREPEND_MH = 0, PREPEND_COUNT = 1;
+        Object[] outArgs = Arrays.copyOfRange(names, ARG_BASE, OUTARG_LIMIT + PREPEND_COUNT, Object[].class);
+        // prepend MH argument:
+        System.arraycopy(outArgs, 0, outArgs, PREPEND_COUNT, outArgs.length - PREPEND_COUNT);
+        outArgs[PREPEND_MH] = names[CALL_MH];
+        names[LINKER_CALL] = new Name(invokeBasicMethod(mtype), outArgs);
+        lform = new LambdaForm("linkToCallSite", INARG_LIMIT, names);
+        lform.compileToBytecode();  // JVM needs a real methodOop
+        lform = mtype.form().setCachedLambdaForm(MethodTypeForm.LF_CS_LINKER, lform);
+        return lform;
+    }
+
+    /** Static definition of MethodHandle.invokeGeneric checking code. */
+    /*non-public*/ static
+    @ForceInline
+    Object getCallSiteTarget(Object site) {
+        return ((CallSite)site).getTarget();
+    }
+
+    // Local constant functions:
+    private static final NamedFunction NF_checkExactType;
+    private static final NamedFunction NF_checkGenericType;
+    private static final NamedFunction NF_asType;
+    private static final NamedFunction NF_getCallSiteTarget;
+    static {
+        try {
+            NF_checkExactType = new NamedFunction(Invokers.class
+                    .getDeclaredMethod("checkExactType", Object.class, Object.class));
+            NF_checkGenericType = new NamedFunction(Invokers.class
+                    .getDeclaredMethod("checkGenericType", Object.class, Object.class));
+            NF_asType = new NamedFunction(MethodHandle.class
+                    .getDeclaredMethod("asType", MethodType.class));
+            NF_getCallSiteTarget = new NamedFunction(Invokers.class
+                    .getDeclaredMethod("getCallSiteTarget", Object.class));
+            NF_checkExactType.resolve();
+            NF_checkGenericType.resolve();
+            NF_getCallSiteTarget.resolve();
+            // bound
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+    }
+
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/LambdaForm.java b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java
new file mode 100644
index 0000000..f1da243
--- /dev/null
+++ b/jdk/src/share/classes/java/lang/invoke/LambdaForm.java
@@ -0,0 +1,1623 @@
+/*
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import java.lang.annotation.*;
+import java.lang.reflect.Method;
+import java.util.Map;
+import java.util.List;
+import java.util.Arrays;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.concurrent.ConcurrentHashMap;
+import sun.invoke.util.Wrapper;
+import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import java.lang.reflect.Field;
+import java.util.Objects;
+
+/**
+ * The symbolic, non-executable form of a method handle's invocation semantics.
+ * It consists of a series of names.
+ * The first N (N=arity) names are parameters,
+ * while any remaining names are temporary values.
+ * Each temporary specifies the application of a function to some arguments.
+ * The functions are method handles, while the arguments are mixes of
+ * constant values and local names.
+ * The result of the lambda is defined as one of the names, often the last one.
+ * <p>
+ * Here is an approximate grammar:
+ * <pre>
+ * LambdaForm = "(" ArgName* ")=>{" TempName* Result "}"
+ * ArgName = "a" N ":" T
+ * TempName = "t" N ":" T "=" Function "(" Argument* ");"
+ * Function = ConstantValue
+ * Argument = NameRef | ConstantValue
+ * Result = NameRef | "void"
+ * NameRef = "a" N | "t" N
+ * N = (any whole number)
+ * T = "L" | "I" | "J" | "F" | "D" | "V"
+ * </pre>
+ * Names are numbered consecutively from left to right starting at zero.
+ * (The letters are merely a taste of syntax sugar.)
+ * Thus, the first temporary (if any) is always numbered N (where N=arity).
+ * Every occurrence of a name reference in an argument list must refer to
+ * a name previously defined within the same lambda.
+ * A lambda has a void result if and only if its result index is -1.
+ * If a temporary has the type "V", it cannot be the subject of a NameRef,
+ * even though possesses a number.
+ * Note that all reference types are erased to "L", which stands for {@code Object).
+ * All subword types (boolean, byte, short, char) are erased to "I" which is {@code int}.
+ * The other types stand for the usual primitive types.
+ * <p>
+ * Function invocation closely follows the static rules of the Java verifier.
+ * Arguments and return values must exactly match when their "Name" types are
+ * considered.
+ * Conversions are allowed only if they do not change the erased type.
+ * <ul>
+ * <li>L = Object: casts are used freely to convert into and out of reference types
+ * <li>I = int: subword types are forcibly narrowed when passed as arguments (see {@code explicitCastArguments})
+ * <li>J = long: no implicit conversions
+ * <li>F = float: no implicit conversions
+ * <li>D = double: no implicit conversions
+ * <li>V = void: a function result may be void if and only if its Name is of type "V"
+ * </ul>
+ * Although implicit conversions are not allowed, explicit ones can easily be
+ * encoded by using temporary expressions which call type-transformed identity functions.
+ * <p>
+ * Examples:
+ * <pre>
+ * (a0:J)=>{ a0 }
+ *     == identity(long)
+ * (a0:I)=>{ t1:V = System.out#println(a0); void }
+ *     == System.out#println(int)
+ * (a0:L)=>{ t1:V = System.out#println(a0); a0 }
+ *     == identity, with printing side-effect
+ * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
+ *                 t3:L = BoundMethodHandle#target(a0);
+ *                 t4:L = MethodHandle#invoke(t3, t2, a1); t4 }
+ *     == general invoker for unary insertArgument combination
+ * (a0:L, a1:L)=>{ t2:L = FilterMethodHandle#filter(a0);
+ *                 t3:L = MethodHandle#invoke(t2, a1);
+ *                 t4:L = FilterMethodHandle#target(a0);
+ *                 t5:L = MethodHandle#invoke(t4, t3); t5 }
+ *     == general invoker for unary filterArgument combination
+ * (a0:L, a1:L)=>{ ...(same as previous example)...
+ *                 t5:L = MethodHandle#invoke(t4, t3, a1); t5 }
+ *     == general invoker for unary/unary foldArgument combination
+ * (a0:L, a1:I)=>{ t2:I = identity(long).asType((int)->long)(a1); t2 }
+ *     == invoker for identity method handle which performs i2l
+ * (a0:L, a1:L)=>{ t2:L = BoundMethodHandle#argument(a0);
+ *                 t3:L = Class#cast(t2,a1); t3 }
+ *     == invoker for identity method handle which performs cast
+ * </pre>
+ * <p>
+ * @author John Rose, JSR 292 EG
+ */
+class LambdaForm {
+    final int arity;
+    final int result;
+    final Name[] names;
+    final String debugName;
+    MemberName vmentry;   // low-level behavior, or null if not yet prepared
+    private boolean isCompiled;
+
+    // Caches for common structural transforms:
+    LambdaForm[] bindCache;
+
+    public static final int VOID_RESULT = -1, LAST_RESULT = -2;
+
+    LambdaForm(String debugName,
+               int arity, Name[] names, int result) {
+        assert(namesOK(arity, names));
+        this.arity = arity;
+        this.result = fixResult(result, names);
+        this.names = names.clone();
+        this.debugName = debugName;
+        normalize();
+    }
+
+    LambdaForm(String debugName,
+               int arity, Name[] names) {
+        this(debugName,
+             arity, names, LAST_RESULT);
+    }
+
+    LambdaForm(String debugName,
+               Name[] formals, Name[] temps, Name result) {
+        this(debugName,
+             formals.length, buildNames(formals, temps, result), LAST_RESULT);
+    }
+
+    private static Name[] buildNames(Name[] formals, Name[] temps, Name result) {
+        int arity = formals.length;
+        int length = arity + temps.length + (result == null ? 0 : 1);
+        Name[] names = Arrays.copyOf(formals, length);
+        System.arraycopy(temps, 0, names, arity, temps.length);
+        if (result != null)
+            names[length - 1] = result;
+        return names;
+    }
+
+    private LambdaForm(String sig) {
+        // Make a blank lambda form, which returns a constant zero or null.
+        // It is used as a template for managing the invocation of similar forms that are non-empty.
+        // Called only from getPreparedForm.
+        assert(isValidSignature(sig));
+        this.arity = signatureArity(sig);
+        this.result = (signatureReturn(sig) == 'V' ? -1 : arity);
+        this.names = buildEmptyNames(arity, sig);
+        this.debugName = "LF.zero";
+        assert(nameRefsAreLegal());
+        assert(isEmpty());
+        assert(sig.equals(basicTypeSignature()));
+    }
+
+    private static Name[] buildEmptyNames(int arity, String basicTypeSignature) {
+        assert(isValidSignature(basicTypeSignature));
+        int resultPos = arity + 1;  // skip '_'
+        if (arity < 0 || basicTypeSignature.length() != resultPos+1)
+            throw new IllegalArgumentException("bad arity for "+basicTypeSignature);
+        int numRes = (basicTypeSignature.charAt(resultPos) == 'V' ? 0 : 1);
+        Name[] names = arguments(numRes, basicTypeSignature.substring(0, arity));
+        for (int i = 0; i < numRes; i++) {
+            names[arity + i] = constantZero(arity + i, basicTypeSignature.charAt(resultPos + i));
+        }
+        return names;
+    }
+
+    private static int fixResult(int result, Name[] names) {
+        if (result >= 0) {
+            if (names[result].type == 'V')
+                return -1;
+        } else if (result == LAST_RESULT) {
+            return names.length - 1;
+        }
+        return result;
+    }
+
+    private static boolean namesOK(int arity, Name[] names) {
+        for (int i = 0; i < names.length; i++) {
+            Name n = names[i];
+            assert(n != null) : "n is null";
+            if (i < arity)
+                assert( n.isParam()) : n + " is not param at " + i;
+            else
+                assert(!n.isParam()) : n + " is param at " + i;
+        }
+        return true;
+    }
+
+    /** Renumber and/or replace params so that they are interned and canonically numbered. */
+    private void normalize() {
+        Name[] oldNames = null;
+        int changesStart = 0;
+        for (int i = 0; i < names.length; i++) {
+            Name n = names[i];
+            if (!n.initIndex(i)) {
+                if (oldNames == null) {
+                    oldNames = names.clone();
+                    changesStart = i;
+                }
+                names[i] = n.cloneWithIndex(i);
+            }
+        }
+        if (oldNames != null) {
+            int startFixing = arity;
+            if (startFixing <= changesStart)
+                startFixing = changesStart+1;
+            for (int i = startFixing; i < names.length; i++) {
+                Name fixed = names[i].replaceNames(oldNames, names, changesStart, i);
+                names[i] = fixed.newIndex(i);
+            }
+        }
+        assert(nameRefsAreLegal());
+        int maxInterned = Math.min(arity, INTERNED_ARGUMENT_LIMIT);
+        boolean needIntern = false;
+        for (int i = 0; i < maxInterned; i++) {
+            Name n = names[i], n2 = internArgument(n);
+            if (n != n2) {
+                names[i] = n2;
+                needIntern = true;
+            }
+        }
+        if (needIntern) {
+            for (int i = arity; i < names.length; i++) {
+                names[i].internArguments();
+            }
+            assert(nameRefsAreLegal());
+        }
+    }
+
+    /**
+     * Check that all embedded Name references are localizable to this lambda,
+     * and are properly ordered after their corresponding definitions.
+     * <p>
+     * Note that a Name can be local to multiple lambdas, as long as
+     * it possesses the same index in each use site.
+     * This allows Name references to be freely reused to construct
+     * fresh lambdas, without confusion.
+     */
+    private boolean nameRefsAreLegal() {
+        assert(arity >= 0 && arity <= names.length);
+        assert(result >= -1 && result < names.length);
+        // Do all names possess an index consistent with their local definition order?
+        for (int i = 0; i < arity; i++) {
+            Name n = names[i];
+            assert(n.index() == i) : Arrays.asList(n.index(), i);
+            assert(n.isParam());
+        }
+        // Also, do all local name references
+        for (int i = arity; i < names.length; i++) {
+            Name n = names[i];
+            assert(n.index() == i);
+            for (Object arg : n.arguments) {
+                if (arg instanceof Name) {
+                    Name n2 = (Name) arg;
+                    int i2 = n2.index;
+                    assert(0 <= i2 && i2 < names.length) : n.debugString() + ": 0 <= i2 && i2 < names.length: 0 <= " + i2 + " < " + names.length;
+                    assert(names[i2] == n2) : Arrays.asList("-1-", i, "-2-", n.debugString(), "-3-", i2, "-4-", n2.debugString(), "-5-", names[i2].debugString(), "-6-", this);
+                    assert(i2 < i);  // ref must come after def!
+                }
+            }
+        }
+        return true;
+    }
+
+    /** Invoke this form on the given arguments. */
+    // final Object invoke(Object... args) throws Throwable {
+    //     // NYI: fit this into the fast path?
+    //     return interpretWithArguments(args);
+    // }
+
+    /** Report the return type. */
+    char returnType() {
+        if (result < 0)  return 'V';
+        Name n = names[result];
+        return n.type;
+    }
+
+    /** Report the N-th argument type. */
+    char parameterType(int n) {
+        assert(n < arity);
+        return names[n].type;
+    }
+
+    /** Report the arity. */
+    int arity() {
+        return arity;
+    }
+
+    /** Return the method type corresponding to my basic type signature. */
+    MethodType methodType() {
+        return signatureType(basicTypeSignature());
+    }
+    /** Return ABC_Z, where the ABC are parameter type characters, and Z is the return type character. */
+    final String basicTypeSignature() {
+        StringBuilder buf = new StringBuilder(arity() + 3);
+        for (int i = 0, a = arity(); i < a; i++)
+            buf.append(parameterType(i));
+        return buf.append('_').append(returnType()).toString();
+    }
+    static int signatureArity(String sig) {
+        assert(isValidSignature(sig));
+        return sig.indexOf('_');
+    }
+    static char signatureReturn(String sig) {
+        return sig.charAt(signatureArity(sig)+1);
+    }
+    static boolean isValidSignature(String sig) {
+        int arity = sig.indexOf('_');
+        if (arity < 0)  return false;  // must be of the form *_*
+        int siglen = sig.length();
+        if (siglen != arity + 2)  return false;  // *_X
+        for (int i = 0; i < siglen; i++) {
+            if (i == arity)  continue;  // skip '_'
+            char c = sig.charAt(i);
+            if (c == 'V')
+                return (i == siglen - 1 && arity == siglen - 2);
+            if (ALL_TYPES.indexOf(c) < 0)  return false; // must be [LIJFD]
+        }
+        return true;  // [LIJFD]*_[LIJFDV]
+    }
+    static Class<?> typeClass(char t) {
+        switch (t) {
+        case 'I': return int.class;
+        case 'J': return long.class;
+        case 'F': return float.class;
+        case 'D': return double.class;
+        case 'L': return Object.class;
+        case 'V': return void.class;
+        default: assert false;
+        }
+        return null;
+    }
+    static MethodType signatureType(String sig) {
+        Class<?>[] ptypes = new Class<?>[signatureArity(sig)];
+        for (int i = 0; i < ptypes.length; i++)
+            ptypes[i] = typeClass(sig.charAt(i));
+        Class<?> rtype = typeClass(signatureReturn(sig));
+        return MethodType.methodType(rtype, ptypes);
+    }
+
+    /*
+     * Code generation issues:
+     *
+     * Compiled LFs should be reusable in general.
+     * The biggest issue is how to decide when to pull a name into
+     * the bytecode, versus loading a reified form from the MH data.
+     *
+     * For example, an asType wrapper may require execution of a cast
+     * after a call to a MH.  The target type of the cast can be placed
+     * as a constant in the LF itself.  This will force the cast type
+     * to be compiled into the bytecodes and native code for the MH.
+     * Or, the target type of the cast can be erased in the LF, and
+     * loaded from the MH data.  (Later on, if the MH as a whole is
+     * inlined, the data will flow into the inlined instance of the LF,
+     * as a constant, and the end result will be an optimal cast.)
+     *
+     * This erasure of cast types can be done with any use of
+     * reference types.  It can also be done with whole method
+     * handles.  Erasing a method handle might leave behind
+     * LF code that executes correctly for any MH of a given
+     * type, and load the required MH from the enclosing MH's data.
+     * Or, the erasure might even erase the expected MT.
+     *
+     * Also, for direct MHs, the MemberName of the target
+     * could be erased, and loaded from the containing direct MH.
+     * As a simple case, a LF for all int-valued non-static
+     * field getters would perform a cast on its input argument
+     * (to non-constant base type derived from the MemberName)
+     * and load an integer value from the input object
+     * (at a non-constant offset also derived from the MemberName).
+     * Such MN-erased LFs would be inlinable back to optimized
+     * code, whenever a constant enclosing DMH is available
+     * to supply a constant MN from its data.
+     *
+     * The main problem here is to keep LFs reasonably generic,
+     * while ensuring that hot spots will inline good instances.
+     * "Reasonably generic" means that we don't end up with
+     * repeated versions of bytecode or machine code that do
+     * not differ in their optimized form.  Repeated versions
+     * of machine would have the undesirable overheads of
+     * (a) redundant compilation work and (b) extra I$ pressure.
+     * To control repeated versions, we need to be ready to
+     * erase details from LFs and move them into MH data,
+     * whevener those details are not relevant to significant
+     * optimization.  "Significant" means optimization of
+     * code that is actually hot.
+     *
+     * Achieving this may require dynamic splitting of MHs, by replacing
+     * a generic LF with a more specialized one, on the same MH,
+     * if (a) the MH is frequently executed and (b) the MH cannot
+     * be inlined into a containing caller, such as an invokedynamic.
+     *
+     * Compiled LFs that are no longer used should be GC-able.
+     * If they contain non-BCP references, they should be properly
+     * interlinked with the class loader(s) that their embedded types
+     * depend on.  This probably means that reusable compiled LFs
+     * will be tabulated (indexed) on relevant class loaders,
+     * or else that the tables that cache them will have weak links.
+     */
+
+    /**
+     * Make this LF directly executable, as part of a MethodHandle.
+     * Invariant:  Every MH which is invoked must prepare its LF
+     * before invocation.
+     * (In principle, the JVM could do this very lazily,
+     * as a sort of pre-invocation linkage step.)
+     */
+    public void prepare() {
+        if (COMPILE_THRESHOLD == 0) {
+            compileToBytecode();
+        }
+        if (this.vmentry != null) {
+            // already prepared (e.g., a primitive DMH invoker form)
+            return;
+        }
+        LambdaForm prep = getPreparedForm(basicTypeSignature());
+        this.vmentry = prep.vmentry;
+        // TO DO: Maybe add invokeGeneric, invokeWithArguments
+    }
+
+    /** Generate optimizable bytecode for this form. */
+    MemberName compileToBytecode() {
+        MethodType invokerType = methodType();
+        assert(vmentry == null || vmentry.getMethodType().basicType().equals(invokerType));
+        if (vmentry != null && isCompiled) {
+            return vmentry;  // already compiled somehow
+        }
+        try {
+            vmentry = InvokerBytecodeGenerator.generateCustomizedCode(this, invokerType);
+            if (TRACE_INTERPRETER)
+                traceInterpreter("compileToBytecode", this);
+            isCompiled = true;
+            return vmentry;
+        } catch (Error | Exception ex) {
+            throw newInternalError(this.toString(), ex);
+        }
+    }
+
+    private static final ConcurrentHashMap<String,LambdaForm> PREPARED_FORMS;
+    static {
+        int   capacity   = 512;    // expect many distinct signatures over time
+        float loadFactor = 0.75f;  // normal default
+        int   writers    = 1;
+        PREPARED_FORMS = new ConcurrentHashMap<>(capacity, loadFactor, writers);
+    }
+
+    private static Map<String,LambdaForm> computeInitialPreparedForms() {
+        // Find all predefined invokers and associate them with canonical empty lambda forms.
+        HashMap<String,LambdaForm> forms = new HashMap<>();
+        for (MemberName m : MemberName.getFactory().getMethods(LambdaForm.class, false, null, null, null)) {
+            if (!m.isStatic() || !m.isPackage())  continue;
+            MethodType mt = m.getMethodType();
+            if (mt.parameterCount() > 0 &&
+                mt.parameterType(0) == MethodHandle.class &&
+                m.getName().startsWith("interpret_")) {
+                String sig = basicTypeSignature(mt);
+                assert(m.getName().equals("interpret" + sig.substring(sig.indexOf('_'))));
+                LambdaForm form = new LambdaForm(sig);
+                form.vmentry = m;
+                mt.form().setCachedLambdaForm(MethodTypeForm.LF_COUNTER, form);
+                // FIXME: get rid of PREPARED_FORMS; use MethodTypeForm cache only
+                forms.put(sig, form);
+            }
+        }
+        //System.out.println("computeInitialPreparedForms => "+forms);
+        return forms;
+    }
+
+    // Set this false to disable use of the interpret_L methods defined in this file.
+    private static final boolean USE_PREDEFINED_INTERPRET_METHODS = true;
+
+    // The following are predefined exact invokers.  The system must build
+    // a separate invoker for each distinct signature.
+    static Object interpret_L(MethodHandle mh) throws Throwable {
+        Object[] av = {mh};
+        String sig = null;
+        assert(argumentTypesMatch(sig = "L_L", av));
+        Object res = mh.form.interpretWithArguments(av);
+        assert(returnTypesMatch(sig, av, res));
+        return res;
+    }
+    static Object interpret_L(MethodHandle mh, Object x1) throws Throwable {
+        Object[] av = {mh, x1};
+        String sig = null;
+        assert(argumentTypesMatch(sig = "LL_L", av));
+        Object res = mh.form.interpretWithArguments(av);
+        assert(returnTypesMatch(sig, av, res));
+        return res;
+    }
+    static Object interpret_L(MethodHandle mh, Object x1, Object x2) throws Throwable {
+        Object[] av = {mh, x1, x2};
+        String sig = null;
+        assert(argumentTypesMatch(sig = "LLL_L", av));
+        Object res = mh.form.interpretWithArguments(av);
+        assert(returnTypesMatch(sig, av, res));
+        return res;
+    }
+    private static LambdaForm getPreparedForm(String sig) {
+        MethodType mtype = signatureType(sig);
+        //LambdaForm prep = PREPARED_FORMS.get(sig);
+        LambdaForm prep =  mtype.form().cachedLambdaForm(MethodTypeForm.LF_INTERPRET);
+        if (prep != null)  return prep;
+        assert(isValidSignature(sig));
+        prep = new LambdaForm(sig);
+        prep.vmentry = InvokerBytecodeGenerator.generateLambdaFormInterpreterEntryPoint(sig);
+        //LambdaForm prep2 = PREPARED_FORMS.putIfAbsent(sig.intern(), prep);
+        return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_INTERPRET, prep);
+    }
+
+    // The next few routines are called only from assert expressions
+    // They verify that the built-in invokers process the correct raw data types.
+    private static boolean argumentTypesMatch(String sig, Object[] av) {
+        int arity = signatureArity(sig);
+        assert(av.length == arity) : "av.length == arity: av.length=" + av.length + ", arity=" + arity;
+        assert(av[0] instanceof MethodHandle) : "av[0] not instace of MethodHandle: " + av[0];
+        MethodHandle mh = (MethodHandle) av[0];
+        MethodType mt = mh.type();
+        assert(mt.parameterCount() == arity-1);
+        for (int i = 0; i < av.length; i++) {
+            Class<?> pt = (i == 0 ? MethodHandle.class : mt.parameterType(i-1));
+            assert(valueMatches(sig.charAt(i), pt, av[i]));
+        }
+        return true;
+    }
+    private static boolean valueMatches(char tc, Class<?> type, Object x) {
+        // The following line is needed because (...)void method handles can use non-void invokers
+        if (type == void.class)  tc = 'V';   // can drop any kind of value
+        assert tc == basicType(type) : tc + " == basicType(" + type + ")=" + basicType(type);
+        switch (tc) {
+        case 'I': assert checkInt(type, x)   : "checkInt(" + type + "," + x +")";   break;
+        case 'J': assert x instanceof Long   : "instanceof Long: " + x;             break;
+        case 'F': assert x instanceof Float  : "instanceof Float: " + x;            break;
+        case 'D': assert x instanceof Double : "instanceof Double: " + x;           break;
+        case 'L': assert checkRef(type, x)   : "checkRef(" + type + "," + x + ")";  break;
+        case 'V': break;  // allow anything here; will be dropped
+        default:  assert(false);
+        }
+        return true;
+    }
+    private static boolean returnTypesMatch(String sig, Object[] av, Object res) {
+        MethodHandle mh = (MethodHandle) av[0];
+        return valueMatches(signatureReturn(sig), mh.type().returnType(), res);
+    }
+    private static boolean checkInt(Class<?> type, Object x) {
+        assert(x instanceof Integer);
+        if (type == int.class)  return true;
+        Wrapper w = Wrapper.forBasicType(type);
+        assert(w.isSubwordOrInt());
+        Object x1 = Wrapper.INT.wrap(w.wrap(x));
+        return x.equals(x1);
+    }
+    private static boolean checkRef(Class<?> type, Object x) {
+        assert(!type.isPrimitive());
+        if (x == null)  return true;
+        if (type.isInterface())  return true;
+        return type.isInstance(x);
+    }
+
+    /** If the invocation count hits the threshold we spin bytecodes and call that subsequently. */
+    private static final int COMPILE_THRESHOLD;
+    static {
+        if (MethodHandleStatics.COMPILE_THRESHOLD != null)
+            COMPILE_THRESHOLD = MethodHandleStatics.COMPILE_THRESHOLD;
+        else
+            COMPILE_THRESHOLD = 30;  // default value
+    }
+    private int invocationCounter = 0;
+
+    @Hidden
+    /** Interpretively invoke this form on the given arguments. */
+    Object interpretWithArguments(Object... argumentValues) throws Throwable {
+        if (TRACE_INTERPRETER)
+            return interpretWithArgumentsTracing(argumentValues);
+        checkInvocationCounter();
+        assert(arityCheck(argumentValues));
+        Object[] values = Arrays.copyOf(argumentValues, names.length);
+        for (int i = argumentValues.length; i < values.length; i++) {
+            values[i] = interpretName(names[i], values);
+        }
+        return (result < 0) ? null : values[result];
+    }
+
+    @Hidden
+    /** Evaluate a single Name within this form, applying its function to its arguments. */
+    Object interpretName(Name name, Object[] values) throws Throwable {
+        if (TRACE_INTERPRETER)
+            traceInterpreter("| interpretName", name.debugString(), (Object[]) null);
+        Object[] arguments = Arrays.copyOf(name.arguments, name.arguments.length, Object[].class);
+        for (int i = 0; i < arguments.length; i++) {
+            Object a = arguments[i];
+            if (a instanceof Name) {
+                int i2 = ((Name)a).index();
+                assert(names[i2] == a);
+                a = values[i2];
+                arguments[i] = a;
+            }
+        }
+        return name.function.invokeWithArguments(arguments);
+    }
+
+    private void checkInvocationCounter() {
+        if (COMPILE_THRESHOLD != 0 &&
+            invocationCounter < COMPILE_THRESHOLD) {
+            invocationCounter++;  // benign race
+            if (invocationCounter >= COMPILE_THRESHOLD) {
+                // Replace vmentry with a bytecode version of this LF.
+                compileToBytecode();
+            }
+        }
+    }
+    Object interpretWithArgumentsTracing(Object... argumentValues) throws Throwable {
+        traceInterpreter("[ interpretWithArguments", this, argumentValues);
+        if (invocationCounter < COMPILE_THRESHOLD) {
+            int ctr = invocationCounter++;  // benign race
+            traceInterpreter("| invocationCounter", ctr);
+            if (invocationCounter >= COMPILE_THRESHOLD) {
+                compileToBytecode();
+            }
+        }
+        Object rval;
+        try {
+            assert(arityCheck(argumentValues));
+            Object[] values = Arrays.copyOf(argumentValues, names.length);
+            for (int i = argumentValues.length; i < values.length; i++) {
+                values[i] = interpretName(names[i], values);
+            }
+            rval = (result < 0) ? null : values[result];
+        } catch (Throwable ex) {
+            traceInterpreter("] throw =>", ex);
+            throw ex;
+        }
+        traceInterpreter("] return =>", rval);
+        return rval;
+    }
+
+    //** This transform is applied (statically) to every name.function. */
+    /*
+    private static MethodHandle eraseSubwordTypes(MethodHandle mh) {
+        MethodType mt = mh.type();
+        if (mt.hasPrimitives()) {
+            mt = mt.changeReturnType(eraseSubwordType(mt.returnType()));
+            for (int i = 0; i < mt.parameterCount(); i++) {
+                mt = mt.changeParameterType(i, eraseSubwordType(mt.parameterType(i)));
+            }
+            mh = MethodHandles.explicitCastArguments(mh, mt);
+        }
+        return mh;
+    }
+    private static Class<?> eraseSubwordType(Class<?> type) {
+        if (!type.isPrimitive())  return type;
+        if (type == int.class)  return type;
+        Wrapper w = Wrapper.forPrimitiveType(type);
+        if (w.isSubwordOrInt())  return int.class;
+        return type;
+    }
+    */
+
+    static void traceInterpreter(String event, Object obj, Object... args) {
+        if (!TRACE_INTERPRETER)  return;
+        System.out.println("LFI: "+event+" "+(obj != null ? obj : "")+(args != null && args.length != 0 ? Arrays.asList(args) : ""));
+    }
+    static void traceInterpreter(String event, Object obj) {
+        traceInterpreter(event, obj, (Object[])null);
+    }
+    private boolean arityCheck(Object[] argumentValues) {
+        assert(argumentValues.length == arity) : arity+"!="+Arrays.asList(argumentValues)+".length";
+        // also check that the leading (receiver) argument is somehow bound to this LF:
+        assert(argumentValues[0] instanceof MethodHandle) : "not MH: " + argumentValues[0];
+        assert(((MethodHandle)argumentValues[0]).internalForm() == this);
+        // note:  argument #0 could also be an interface wrapper, in the future
+        return true;
+    }
+
+    private boolean isEmpty() {
+        if (result < 0)
+            return (names.length == arity);
+        else if (result == arity && names.length == arity + 1)
+            return names[arity].isConstantZero();
+        else
+            return false;
+    }
+
+    public String toString() {
+        StringBuilder buf = new StringBuilder(debugName+"=Lambda(");
+        for (int i = 0; i < names.length; i++) {
+            if (i == arity)  buf.append(")=>{");
+            Name n = names[i];
+            if (i >= arity)  buf.append("\n    ");
+            buf.append(n);
+            if (i < arity) {
+                if (i+1 < arity)  buf.append(",");
+                continue;
+            }
+            buf.append("=").append(n.exprString());
+            buf.append(";");
+        }
+        buf.append(result < 0 ? "void" : names[result]).append("}");
+        if (TRACE_INTERPRETER) {
+            // Extra verbosity:
+            buf.append(":").append(basicTypeSignature());
+            buf.append("/").append(vmentry);
+        }
+        return buf.toString();
+    }
+
+    /**
+     * Apply immediate binding for a Name in this form indicated by its position relative to the form.
+     * The first parameter to a LambdaForm, a0:L, always represents the form's method handle, so 0 is not
+     * accepted as valid.
+     */
+    LambdaForm bindImmediate(int pos, char basicType, Object value) {
+        // must be an argument, and the types must match
+        assert pos > 0 && pos < arity && names[pos].type == basicType && Name.typesMatch(basicType, value);
+
+        int arity2 = arity - 1;
+        Name[] names2 = new Name[names.length - 1];
+        for (int r = 0, w = 0; r < names.length; ++r, ++w) { // (r)ead from names, (w)rite to names2
+            Name n = names[r];
+            if (n.isParam()) {
+                if (n.index == pos) {
+                    // do not copy over the argument that is to be replaced with a literal,
+                    // but adjust the write index
+                    --w;
+                } else {
+                    names2[w] = new Name(w, n.type);
+                }
+            } else {
+                Object[] arguments2 = new Object[n.arguments.length];
+                for (int i = 0; i < n.arguments.length; ++i) {
+                    Object arg = n.arguments[i];
+                    if (arg instanceof Name) {
+                        int ni = ((Name) arg).index;
+                        if (ni == pos) {
+                            arguments2[i] = value;
+                        } else if (ni < pos) {
+                            // replacement position not yet passed
+                            arguments2[i] = names2[ni];
+                        } else {
+                            // replacement position passed
+                            arguments2[i] = names2[ni - 1];
+                        }
+                    } else {
+                        arguments2[i] = arg;
+                    }
+                }
+                names2[w] = new Name(n.function, arguments2);
+                names2[w].initIndex(w);
+            }
+        }
+
+        int result2 = result == -1 ? -1 : result - 1;
+        return new LambdaForm(debugName, arity2, names2, result2);
+    }
+
+    LambdaForm bind(int namePos, BoundMethodHandle.SpeciesData oldData) {
+        Name name = names[namePos];
+        BoundMethodHandle.SpeciesData newData = oldData.extendWithType(name.type);
+        return bind(name, newData.getterName(names[0], oldData.fieldCount()), oldData, newData);
+    }
+    LambdaForm bind(Name name, Name binding,
+                    BoundMethodHandle.SpeciesData oldData,
+                    BoundMethodHandle.SpeciesData newData) {
+        int pos = name.index;
+        assert(name.isParam());
+        assert(!binding.isParam());
+        assert(name.type == binding.type);
+        assert(0 <= pos && pos < arity && names[pos] == name);
+        assert(binding.function.memberDeclaringClassOrNull() == newData.clazz);
+        assert(oldData.getters.length == newData.getters.length-1);
+        if (bindCache != null) {
+            LambdaForm form = bindCache[pos];
+            if (form != null) {
+                assert(form.contains(binding)) : "form << " + form + " >> does not contain binding << " + binding + " >>";
+                return form;
+            }
+        } else {
+            bindCache = new LambdaForm[arity];
+        }
+        assert(nameRefsAreLegal());
+        int arity2 = arity-1;
+        Name[] names2 = names.clone();
+        names2[pos] = binding;  // we might move this in a moment
+
+        // The newly created LF will run with a different BMH.
+        // Switch over any pre-existing BMH field references to the new BMH class.
+        int firstOldRef = -1;
+        for (int i = 0; i < names2.length; i++) {
+            Name n = names[i];
+            if (n.function != null &&
+                n.function.memberDeclaringClassOrNull() == oldData.clazz) {
+                MethodHandle oldGetter = n.function.resolvedHandle;
+                MethodHandle newGetter = null;
+                for (int j = 0; j < oldData.getters.length; j++) {
+                    if (oldGetter == oldData.getters[j])
+                        newGetter =  newData.getters[j];
+                }
+                if (newGetter != null) {
+                    if (firstOldRef < 0)  firstOldRef = i;
+                    Name n2 = new Name(newGetter, n.arguments);
+                    names2[i] = n2;
+                }
+            }
+        }
+
+        // Walk over the new list of names once, in forward order.
+        // Replace references to 'name' with 'binding'.
+        // Replace data structure references to the old BMH species with the new.
+        // This might cause a ripple effect, but it will settle in one pass.
+        assert(firstOldRef < 0 || firstOldRef > pos);
+        for (int i = pos+1; i < names2.length; i++) {
+            if (i <= arity2)  continue;
+            names2[i] = names2[i].replaceNames(names, names2, pos, i);
+        }
+
+        //  (a0, a1, name=a2, a3, a4)  =>  (a0, a1, a3, a4, binding)
+        int insPos = pos;
+        for (; insPos+1 < names2.length; insPos++) {
+            Name n = names2[insPos+1];
+            if (n.isSiblingBindingBefore(binding)) {
+                names2[insPos] = n;
+            } else {
+                break;
+            }
+        }
+        names2[insPos] = binding;
+
+        // Since we moved some stuff, maybe update the result reference:
+        int result2 = result;
+        if (result2 == pos)
+            result2 = insPos;
+        else if (result2 > pos && result2 <= insPos)
+            result2 -= 1;
+
+        return bindCache[pos] = new LambdaForm(debugName, arity2, names2, result2);
+    }
+
+    boolean contains(Name name) {
+        int pos = name.index();
+        if (pos >= 0) {
+            return pos < names.length && name.equals(names[pos]);
+        }
+        for (int i = arity; i < names.length; i++) {
+            if (name.equals(names[i]))
+                return true;
+        }
+        return false;
+    }
+
+    LambdaForm addArguments(int pos, char... types) {
+        assert(pos <= arity);
+        int length = names.length;
+        int inTypes = types.length;
+        Name[] names2 = Arrays.copyOf(names, length + inTypes);
+        int arity2 = arity + inTypes;
+        int result2 = result;
+        if (result2 >= arity)
+            result2 += inTypes;
+        // names array has MH in slot 0; skip it.
+        int argpos = pos + 1;
+        // Note:  The LF constructor will rename names2[argpos...].
+        // Make space for new arguments (shift temporaries).
+        System.arraycopy(names, argpos, names2, argpos + inTypes, length - argpos);
+        for (int i = 0; i < inTypes; i++) {
+            names2[argpos + i] = new Name(types[i]);
+        }
+        return new LambdaForm(debugName, arity2, names2, result2);
+    }
+
+    LambdaForm addArguments(int pos, List<Class<?>> types) {
+        char[] basicTypes = new char[types.size()];
+        for (int i = 0; i < basicTypes.length; i++)
+            basicTypes[i] = basicType(types.get(i));
+        return addArguments(pos, basicTypes);
+    }
+
+    LambdaForm permuteArguments(int skip, int[] reorder, char[] types) {
+        // Note:  When inArg = reorder[outArg], outArg is fed by a copy of inArg.
+        // The types are the types of the new (incoming) arguments.
+        int length = names.length;
+        int inTypes = types.length;
+        int outArgs = reorder.length;
+        assert(skip+outArgs == arity);
+        assert(permutedTypesMatch(reorder, types, names, skip));
+        int pos = 0;
+        // skip trivial first part of reordering:
+        while (pos < outArgs && reorder[pos] == pos)  pos += 1;
+        Name[] names2 = new Name[length - outArgs + inTypes];
+        System.arraycopy(names, 0, names2, 0, skip+pos);
+        // copy the body:
+        int bodyLength = length - arity;
+        System.arraycopy(names, skip+outArgs, names2, skip+inTypes, bodyLength);
+        int arity2 = names2.length - bodyLength;
+        int result2 = result;
+        if (result2 >= 0) {
+            if (result2 < skip+outArgs) {
+                // return the corresponding inArg
+                result2 = reorder[result2-skip];
+            } else {
+                result2 = result2 - outArgs + inTypes;
+            }
+        }
+        // rework names in the body:
+        for (int j = pos; j < outArgs; j++) {
+            Name n = names[skip+j];
+            int i = reorder[j];
+            // replace names[skip+j] by names2[skip+i]
+            Name n2 = names2[skip+i];
+            if (n2 == null)
+                names2[skip+i] = n2 = new Name(types[i]);
+            else
+                assert(n2.type == types[i]);
+            for (int k = arity2; k < names2.length; k++) {
+                names2[k] = names2[k].replaceName(n, n2);
+            }
+        }
+        // some names are unused, but must be filled in
+        for (int i = skip+pos; i < arity2; i++) {
+            if (names2[i] == null)
+                names2[i] = argument(i, types[i - skip]);
+        }
+        for (int j = arity; j < names.length; j++) {
+            int i = j - arity + arity2;
+            // replace names2[i] by names[j]
+            Name n = names[j];
+            Name n2 = names2[i];
+            if (n != n2) {
+                for (int k = i+1; k < names2.length; k++) {
+                    names2[k] = names2[k].replaceName(n, n2);
+                }
+            }
+        }
+        return new LambdaForm(debugName, arity2, names2, result2);
+    }
+
+    static boolean permutedTypesMatch(int[] reorder, char[] types, Name[] names, int skip) {
+        int inTypes = types.length;
+        int outArgs = reorder.length;
+        for (int i = 0; i < outArgs; i++) {
+            assert(names[skip+i].isParam());
+            assert(names[skip+i].type == types[reorder[i]]);
+        }
+        return true;
+    }
+
+    static class NamedFunction {
+        final MemberName member;
+        MethodHandle resolvedHandle;
+        MethodHandle invoker;
+
+        NamedFunction(MethodHandle resolvedHandle) {
+            this(resolvedHandle.internalMemberName(), resolvedHandle);
+        }
+        NamedFunction(MemberName member, MethodHandle resolvedHandle) {
+            this.member = member;
+            //resolvedHandle = eraseSubwordTypes(resolvedHandle);
+            this.resolvedHandle = resolvedHandle;
+        }
+
+        // The next 3 constructors are used to break circular dependencies on MH.invokeStatic, etc.
+        // Any LambdaForm containing such a member is not interpretable.
+        // This is OK, since all such LFs are prepared with special primitive vmentry points.
+        // And even without the resolvedHandle, the name can still be compiled and optimized.
+        NamedFunction(Method method) {
+            this(new MemberName(method));
+        }
+        NamedFunction(Field field) {
+            this(new MemberName(field));
+        }
+        NamedFunction(MemberName member) {
+            this.member = member;
+            this.resolvedHandle = null;
+        }
+
+        MethodHandle resolvedHandle() {
+            if (resolvedHandle == null)  resolve();
+            return resolvedHandle;
+        }
+
+        void resolve() {
+            resolvedHandle = DirectMethodHandle.make(member);
+        }
+
+        @Override
+        public boolean equals(Object other) {
+            if (this == other) return true;
+            if (other == null) return false;
+            if (!(other instanceof NamedFunction)) return false;
+            NamedFunction that = (NamedFunction) other;
+            return this.member != null && this.member.equals(that.member);
+        }
+
+        @Override
+        public int hashCode() {
+            if (member != null)
+                return member.hashCode();
+            return super.hashCode();
+        }
+
+        // Put the predefined NamedFunction invokers into the table.
+        static void initializeInvokers() {
+            for (MemberName m : MemberName.getFactory().getMethods(NamedFunction.class, false, null, null, null)) {
+                if (!m.isStatic() || !m.isPackage())  continue;
+                MethodType type = m.getMethodType();
+                if (type.equals(INVOKER_METHOD_TYPE) &&
+                    m.getName().startsWith("invoke_")) {
+                    String sig = m.getName().substring("invoke_".length());
+                    int arity = LambdaForm.signatureArity(sig);
+                    MethodType srcType = MethodType.genericMethodType(arity);
+                    if (LambdaForm.signatureReturn(sig) == 'V')
+                        srcType = srcType.changeReturnType(void.class);
+                    MethodTypeForm typeForm = srcType.form();
+                    typeForm.namedFunctionInvoker = DirectMethodHandle.make(m);
+                }
+            }
+        }
+
+        // The following are predefined NamedFunction invokers.  The system must build
+        // a separate invoker for each distinct signature.
+        /** void return type invokers. */
+        @Hidden
+        static Object invoke__V(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 0);
+            mh.invokeBasic();
+            return null;
+        }
+        @Hidden
+        static Object invoke_L_V(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 1);
+            mh.invokeBasic(a[0]);
+            return null;
+        }
+        @Hidden
+        static Object invoke_LL_V(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 2);
+            mh.invokeBasic(a[0], a[1]);
+            return null;
+        }
+        @Hidden
+        static Object invoke_LLL_V(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 3);
+            mh.invokeBasic(a[0], a[1], a[2]);
+            return null;
+        }
+        @Hidden
+        static Object invoke_LLLL_V(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 4);
+            mh.invokeBasic(a[0], a[1], a[2], a[3]);
+            return null;
+        }
+        @Hidden
+        static Object invoke_LLLLL_V(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 5);
+            mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
+            return null;
+        }
+        /** Object return type invokers. */
+        @Hidden
+        static Object invoke__L(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 0);
+            return mh.invokeBasic();
+        }
+        @Hidden
+        static Object invoke_L_L(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 1);
+            return mh.invokeBasic(a[0]);
+        }
+        @Hidden
+        static Object invoke_LL_L(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 2);
+            return mh.invokeBasic(a[0], a[1]);
+        }
+        @Hidden
+        static Object invoke_LLL_L(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 3);
+            return mh.invokeBasic(a[0], a[1], a[2]);
+        }
+        @Hidden
+        static Object invoke_LLLL_L(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 4);
+            return mh.invokeBasic(a[0], a[1], a[2], a[3]);
+        }
+        @Hidden
+        static Object invoke_LLLLL_L(MethodHandle mh, Object[] a) throws Throwable {
+            assert(a.length == 5);
+            return mh.invokeBasic(a[0], a[1], a[2], a[3], a[4]);
+        }
+
+        static final MethodType INVOKER_METHOD_TYPE =
+            MethodType.methodType(Object.class, MethodHandle.class, Object[].class);
+
+        private static MethodHandle computeInvoker(MethodTypeForm typeForm) {
+            MethodHandle mh = typeForm.namedFunctionInvoker;
+            if (mh != null)  return mh;
+            MemberName invoker = InvokerBytecodeGenerator.generateNamedFunctionInvoker(typeForm);  // this could take a while
+            mh = DirectMethodHandle.make(invoker);
+            MethodHandle mh2 = typeForm.namedFunctionInvoker;
+            if (mh2 != null)  return mh2;  // benign race
+            if (!mh.type().equals(INVOKER_METHOD_TYPE))
+                throw new InternalError(mh.debugString());
+            return typeForm.namedFunctionInvoker = mh;
+        }
+
+        @Hidden
+        Object invokeWithArguments(Object... arguments) throws Throwable {
+            // If we have a cached invoker, call it right away.
+            // NOTE: The invoker always returns a reference value.
+            if (TRACE_INTERPRETER)  return invokeWithArgumentsTracing(arguments);
+            assert(checkArgumentTypes(arguments, methodType()));
+            return invoker().invokeBasic(resolvedHandle(), arguments);
+        }
+
+        @Hidden
+        Object invokeWithArgumentsTracing(Object[] arguments) throws Throwable {
+            Object rval;
+            try {
+                traceInterpreter("[ call", this, arguments);
+                if (invoker == null) {
+                    traceInterpreter("| getInvoker", this);
+                    invoker();
+                }
+                if (resolvedHandle == null) {
+                    traceInterpreter("| resolve", this);
+                    resolvedHandle();
+                }
+                assert(checkArgumentTypes(arguments, methodType()));
+                rval = invoker().invokeBasic(resolvedHandle(), arguments);
+            } catch (Throwable ex) {
+                traceInterpreter("] throw =>", ex);
+                throw ex;
+            }
+            traceInterpreter("] return =>", rval);
+            return rval;
+        }
+
+        private MethodHandle invoker() {
+            if (invoker != null)  return invoker;
+            // Get an invoker and cache it.
+            return invoker = computeInvoker(methodType().form());
+        }
+
+        private static boolean checkArgumentTypes(Object[] arguments, MethodType methodType) {
+            if (true)  return true;  // FIXME
+            MethodType dstType = methodType.form().erasedType();
+            MethodType srcType = dstType.basicType().wrap();
+            Class<?>[] ptypes = new Class<?>[arguments.length];
+            for (int i = 0; i < arguments.length; i++) {
+                Object arg = arguments[i];
+                Class<?> ptype = arg == null ? Object.class : arg.getClass();
+                // If the dest. type is a primitive we keep the
+                // argument type.
+                ptypes[i] = dstType.parameterType(i).isPrimitive() ? ptype : Object.class;
+            }
+            MethodType argType = MethodType.methodType(srcType.returnType(), ptypes).wrap();
+            assert(argType.isConvertibleTo(srcType)) : "wrong argument types: cannot convert " + argType + " to " + srcType;
+            return true;
+        }
+
+        String basicTypeSignature() {
+            //return LambdaForm.basicTypeSignature(resolvedHandle.type());
+            return LambdaForm.basicTypeSignature(methodType());
+        }
+
+        MethodType methodType() {
+            if (resolvedHandle != null)
+                return resolvedHandle.type();
+            else
+                // only for certain internal LFs during bootstrapping
+                return member.getInvocationType();
+        }
+
+        MemberName member() {
+            assert(assertMemberIsConsistent());
+            return member;
+        }
+
+        // Called only from assert.
+        private boolean assertMemberIsConsistent() {
+            if (resolvedHandle instanceof DirectMethodHandle) {
+                MemberName m = resolvedHandle.internalMemberName();
+                assert(m.equals(member));
+            }
+            return true;
+        }
+
+        Class<?> memberDeclaringClassOrNull() {
+            return (member == null) ? null : member.getDeclaringClass();
+        }
+
+        char returnType() {
+            return basicType(methodType().returnType());
+        }
+
+        char parameterType(int n) {
+            return basicType(methodType().parameterType(n));
+        }
+
+        int arity() {
+            //int siglen = member.getMethodType().parameterCount();
+            //if (!member.isStatic())  siglen += 1;
+            //return siglen;
+            return methodType().parameterCount();
+        }
+
+        public String toString() {
+            if (member == null)  return resolvedHandle.toString();
+            return member.getDeclaringClass().getSimpleName()+"."+member.getName();
+        }
+    }
+
+    void resolve() {
+        for (Name n : names) n.resolve();
+    }
+
+    public static char basicType(Class<?> type) {
+        char c = Wrapper.basicTypeChar(type);
+        if ("ZBSC".indexOf(c) >= 0)  c = 'I';
+        assert("LIJFDV".indexOf(c) >= 0);
+        return c;
+    }
+    public static char[] basicTypes(List<Class<?>> types) {
+        char[] btypes = new char[types.size()];
+        for (int i = 0; i < btypes.length; i++) {
+            btypes[i] = basicType(types.get(i));
+        }
+        return btypes;
+    }
+    public static String basicTypeSignature(MethodType type) {
+        char[] sig = new char[type.parameterCount() + 2];
+        int sigp = 0;
+        for (Class<?> pt : type.parameterList()) {
+            sig[sigp++] = basicType(pt);
+        }
+        sig[sigp++] = '_';
+        sig[sigp++] = basicType(type.returnType());
+        assert(sigp == sig.length);
+        return String.valueOf(sig);
+    }
+
+    static final class Name {
+        final char type;
+        private short index;
+        final NamedFunction function;
+        final Object[] arguments;
+
+        private Name(int index, char type, NamedFunction function, Object[] arguments) {
+            this.index = (short)index;
+            this.type = type;
+            this.function = function;
+            this.arguments = arguments;
+            assert(this.index == index);
+        }
+        Name(MethodHandle function, Object... arguments) {
+            this(new NamedFunction(function), arguments);
+        }
+        Name(MemberName function, Object... arguments) {
+            this(new NamedFunction(function), arguments);
+        }
+        Name(NamedFunction function, Object... arguments) {
+            this(-1, function.returnType(), function, arguments = arguments.clone());
+            assert(arguments.length == function.arity()) : "arity mismatch: arguments.length=" + arguments.length + " == function.arity()=" + function.arity() + " in " + debugString();
+            for (int i = 0; i < arguments.length; i++)
+                assert(typesMatch(function.parameterType(i), arguments[i])) : "types don't match: function.parameterType(" + i + ")=" + function.parameterType(i) + ", arguments[" + i + "]=" + arguments[i] + " in " + debugString();
+        }
+        Name(int index, char type) {
+            this(index, type, null, null);
+        }
+        Name(char type) {
+            this(-1, type);
+        }
+
+        char type() { return type; }
+        int index() { return index; }
+        boolean initIndex(int i) {
+            if (index != i) {
+                if (index != -1)  return false;
+                index = (short)i;
+            }
+            return true;
+        }
+
+
+        void resolve() {
+            if (function != null)
+                function.resolve();
+        }
+
+        Name newIndex(int i) {
+            if (initIndex(i))  return this;
+            return cloneWithIndex(i);
+        }
+        Name cloneWithIndex(int i) {
+            Object[] newArguments = (arguments == null) ? null : arguments.clone();
+            return new Name(i, type, function, newArguments);
+        }
+        Name replaceName(Name oldName, Name newName) {  // FIXME: use replaceNames uniformly
+            if (oldName == newName)  return this;
+            @SuppressWarnings("LocalVariableHidesMemberVariable")
+            Object[] arguments = this.arguments;
+            if (arguments == null)  return this;
+            boolean replaced = false;
+            for (int j = 0; j < arguments.length; j++) {
+                if (arguments[j] == oldName) {
+                    if (!replaced) {
+                        replaced = true;
+                        arguments = arguments.clone();
+                    }
+                    arguments[j] = newName;
+                }
+            }
+            if (!replaced)  return this;
+            return new Name(function, arguments);
+        }
+        Name replaceNames(Name[] oldNames, Name[] newNames, int start, int end) {
+            @SuppressWarnings("LocalVariableHidesMemberVariable")
+            Object[] arguments = this.arguments;
+            boolean replaced = false;
+        eachArg:
+            for (int j = 0; j < arguments.length; j++) {
+                if (arguments[j] instanceof Name) {
+                    Name n = (Name) arguments[j];
+                    int check = n.index;
+                    // harmless check to see if the thing is already in newNames:
+                    if (check >= 0 && check < newNames.length && n == newNames[check])
+                        continue eachArg;
+                    // n might not have the correct index: n != oldNames[n.index].
+                    for (int i = start; i < end; i++) {
+                        if (n == oldNames[i]) {
+                            if (n == newNames[i])
+                                continue eachArg;
+                            if (!replaced) {
+                                replaced = true;
+                                arguments = arguments.clone();
+                            }
+                            arguments[j] = newNames[i];
+                            continue eachArg;
+                        }
+                    }
+                }
+            }
+            if (!replaced)  return this;
+            return new Name(function, arguments);
+        }
+        void internArguments() {
+            @SuppressWarnings("LocalVariableHidesMemberVariable")
+            Object[] arguments = this.arguments;
+            for (int j = 0; j < arguments.length; j++) {
+                if (arguments[j] instanceof Name) {
+                    Name n = (Name) arguments[j];
+                    if (n.isParam() && n.index < INTERNED_ARGUMENT_LIMIT)
+                        arguments[j] = internArgument(n);
+                }
+            }
+        }
+        boolean isParam() {
+            return function == null;
+        }
+        boolean isConstantZero() {
+            return !isParam() && arguments.length == 0 && function.equals(constantZero(0, type).function);
+        }
+
+        public String toString() {
+            return (isParam()?"a":"t")+(index >= 0 ? index : System.identityHashCode(this))+":"+type;
+        }
+        public String debugString() {
+            String s = toString();
+            return (function == null) ? s : s + "=" + exprString();
+        }
+        public String exprString() {
+            if (function == null)  return "null";
+            StringBuilder buf = new StringBuilder(function.toString());
+            buf.append("(");
+            String cma = "";
+            for (Object a : arguments) {
+                buf.append(cma); cma = ",";
+                if (a instanceof Name || a instanceof Integer)
+                    buf.append(a);
+                else
+                    buf.append("(").append(a).append(")");
+            }
+            buf.append(")");
+            return buf.toString();
+        }
+
+        private static boolean typesMatch(char parameterType, Object object) {
+            if (object instanceof Name) {
+                return ((Name)object).type == parameterType;
+            }
+            switch (parameterType) {
+                case 'I':  return object instanceof Integer;
+                case 'J':  return object instanceof Long;
+                case 'F':  return object instanceof Float;
+                case 'D':  return object instanceof Double;
+            }
+            assert(parameterType == 'L');
+            return true;
+        }
+
+        /**
+         * Does this Name precede the given binding node in some canonical order?
+         * This predicate is used to order data bindings (via insertion sort)
+         * with some stability.
+         * @param binding
+         * @return
+         */
+        boolean isSiblingBindingBefore(Name binding) {
+            assert(!binding.isParam());
+            if (isParam())  return true;
+            if (function.equals(binding.function) &&
+                arguments.length == binding.arguments.length) {
+                boolean sawInt = false;
+                for (int i = 0; i < arguments.length; i++) {
+                    Object a1 = arguments[i];
+                    Object a2 = binding.arguments[i];
+                    if (!a1.equals(a2)) {
+                        if (a1 instanceof Integer && a2 instanceof Integer) {
+                            if (sawInt)  continue;
+                            sawInt = true;
+                            if ((int)a1 < (int)a2)  continue;  // still might be true
+                        }
+                        return false;
+                    }
+                }
+                return sawInt;
+            }
+            return false;
+        }
+
+        public boolean equals(Name that) {
+            if (this == that)  return true;
+            if (isParam())
+                // each parameter is a unique atom
+                return false;  // this != that
+            return
+                //this.index == that.index &&
+                this.type == that.type &&
+                this.function.equals(that.function) &&
+                Arrays.equals(this.arguments, that.arguments);
+        }
+        @Override
+        public boolean equals(Object x) {
+            return x instanceof Name && equals((Name)x);
+        }
+        @Override
+        public int hashCode() {
+            if (isParam())
+                return index | (type << 8);
+            return function.hashCode() ^ Arrays.hashCode(arguments);
+        }
+    }
+
+    static Name argument(int which, char type) {
+        int tn = ALL_TYPES.indexOf(type);
+        if (tn < 0 || which >= INTERNED_ARGUMENT_LIMIT)
+            return new Name(which, type);
+        return INTERNED_ARGUMENTS[tn][which];
+    }
+    static Name internArgument(Name n) {
+        assert(n.isParam()) : "not param: " + n;
+        assert(n.index < INTERNED_ARGUMENT_LIMIT);
+        return argument(n.index, n.type);
+    }
+    static Name[] arguments(int extra, String types) {
+        int length = types.length();
+        Name[] names = new Name[length + extra];
+        for (int i = 0; i < length; i++)
+            names[i] = argument(i, types.charAt(i));
+        return names;
+    }
+    static Name[] arguments(int extra, char... types) {
+        int length = types.length;
+        Name[] names = new Name[length + extra];
+        for (int i = 0; i < length; i++)
+            names[i] = argument(i, types[i]);
+        return names;
+    }
+    static Name[] arguments(int extra, List<Class<?>> types) {
+        int length = types.size();
+        Name[] names = new Name[length + extra];
+        for (int i = 0; i < length; i++)
+            names[i] = argument(i, basicType(types.get(i)));
+        return names;
+    }
+    static Name[] arguments(int extra, Class<?>... types) {
+        int length = types.length;
+        Name[] names = new Name[length + extra];
+        for (int i = 0; i < length; i++)
+            names[i] = argument(i, basicType(types[i]));
+        return names;
+    }
+    static Name[] arguments(int extra, MethodType types) {
+        int length = types.parameterCount();
+        Name[] names = new Name[length + extra];
+        for (int i = 0; i < length; i++)
+            names[i] = argument(i, basicType(types.parameterType(i)));
+        return names;
+    }
+    static final String ALL_TYPES = "LIJFD";  // omit V, not an argument type
+    static final int INTERNED_ARGUMENT_LIMIT = 10;
+    private static final Name[][] INTERNED_ARGUMENTS
+            = new Name[ALL_TYPES.length()][INTERNED_ARGUMENT_LIMIT];
+    static {
+        for (int tn = 0; tn < ALL_TYPES.length(); tn++) {
+            for (int i = 0; i < INTERNED_ARGUMENTS[tn].length; i++) {
+                char type = ALL_TYPES.charAt(tn);
+                INTERNED_ARGUMENTS[tn][i] = new Name(i, type);
+            }
+        }
+    }
+
+    private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
+
+    static Name constantZero(int which, char type) {
+        return CONSTANT_ZERO[ALL_TYPES.indexOf(type)].newIndex(which);
+    }
+    private static final Name[] CONSTANT_ZERO
+            = new Name[ALL_TYPES.length()];
+    static {
+        for (int tn = 0; tn < ALL_TYPES.length(); tn++) {
+            char bt = ALL_TYPES.charAt(tn);
+            Wrapper wrap = Wrapper.forBasicType(bt);
+            MemberName zmem = new MemberName(LambdaForm.class, "zero"+bt, MethodType.methodType(wrap.primitiveType()), REF_invokeStatic);
+            try {
+                zmem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zmem, null, NoSuchMethodException.class);
+            } catch (IllegalAccessException|NoSuchMethodException ex) {
+                throw newInternalError(ex);
+            }
+            NamedFunction zcon = new NamedFunction(zmem);
+            Name n = new Name(zcon).newIndex(0);
+            assert(n.type == ALL_TYPES.charAt(tn));
+            CONSTANT_ZERO[tn] = n;
+            assert(n.isConstantZero());
+        }
+    }
+
+    // Avoid appealing to ValueConversions at bootstrap time:
+    private static int zeroI() { return 0; }
+    private static long zeroJ() { return 0; }
+    private static float zeroF() { return 0; }
+    private static double zeroD() { return 0; }
+    private static Object zeroL() { return null; }
+
+    // Put this last, so that previous static inits can run before.
+    static {
+        if (USE_PREDEFINED_INTERPRET_METHODS)
+            PREPARED_FORMS.putAll(computeInitialPreparedForms());
+    }
+
+    /**
+     * Internal marker for byte-compiled LambdaForms.
+     */
+    /*non-public*/
+    @Target(ElementType.METHOD)
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Compiled {
+    }
+
+    /**
+     * Internal marker for LambdaForm interpreter frames.
+     */
+    /*non-public*/
+    @Target(ElementType.METHOD)
+    @Retention(RetentionPolicy.RUNTIME)
+    @interface Hidden {
+    }
+
+
+/*
+    // Smoke-test for the invokers used in this file.
+    static void testMethodHandleLinkers() throws Throwable {
+        MemberName.Factory lookup = MemberName.getFactory();
+        MemberName asList_MN = new MemberName(Arrays.class, "asList",
+                                              MethodType.methodType(List.class, Object[].class),
+                                              REF_invokeStatic);
+        //MethodHandleNatives.resolve(asList_MN, null);
+        asList_MN = lookup.resolveOrFail(asList_MN, REF_invokeStatic, null, NoSuchMethodException.class);
+        System.out.println("about to call "+asList_MN);
+        Object[] abc = { "a", "bc" };
+        List<?> lst = (List<?>) MethodHandle.linkToStatic(abc, asList_MN);
+        System.out.println("lst="+lst);
+        MemberName toString_MN = new MemberName(Object.class.getMethod("toString"));
+        String s1 = (String) MethodHandle.linkToVirtual(lst, toString_MN);
+        toString_MN = new MemberName(Object.class.getMethod("toString"), true);
+        String s2 = (String) MethodHandle.linkToSpecial(lst, toString_MN);
+        System.out.println("[s1,s2,lst]="+Arrays.asList(s1, s2, lst.toString()));
+        MemberName toArray_MN = new MemberName(List.class.getMethod("toArray"));
+        Object[] arr = (Object[]) MethodHandle.linkToInterface(lst, toArray_MN);
+        System.out.println("toArray="+Arrays.toString(arr));
+    }
+    static { try { testMethodHandleLinkers(); } catch (Throwable ex) { throw new RuntimeException(ex); } }
+    // Requires these definitions in MethodHandle:
+    static final native Object linkToStatic(Object x1, MemberName mn) throws Throwable;
+    static final native Object linkToVirtual(Object x1, MemberName mn) throws Throwable;
+    static final native Object linkToSpecial(Object x1, MemberName mn) throws Throwable;
+    static final native Object linkToInterface(Object x1, MemberName mn) throws Throwable;
+ */
+
+    static { NamedFunction.initializeInvokers(); }
+}
diff --git a/jdk/src/share/classes/java/lang/invoke/MemberName.java b/jdk/src/share/classes/java/lang/invoke/MemberName.java
index 088c568..e2bd9b0 100644
--- a/jdk/src/share/classes/java/lang/invoke/MemberName.java
+++ b/jdk/src/share/classes/java/lang/invoke/MemberName.java
@@ -26,6 +26,8 @@
 package java.lang.invoke;
 
 import sun.invoke.util.BytecodeDescriptor;
+import sun.invoke.util.VerifyAccess;
+
 import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
@@ -38,6 +40,7 @@
 import java.util.List;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
 import static java.lang.invoke.MethodHandleStatics.*;
+import java.util.Objects;
 
 /**
  * A {@code MemberName} is a compact symbolic datum which fully characterizes
@@ -71,19 +74,14 @@
     private String     name;        // may be null if not yet materialized
     private Object     type;        // may be null if not yet materialized
     private int        flags;       // modifier bits; see reflect.Modifier
-
-    private Object     vmtarget;    // VM-specific target value
-    private int        vmindex;     // method index within class or interface
-
-    { vmindex = VM_INDEX_UNINITIALIZED; }
+    //@Injected JVM_Method* vmtarget;
+    //@Injected int         vmindex;
+    private Object     resolution;  // if null, this guy is resolved
 
     /** Return the declaring class of this member.
      *  In the case of a bare name and type, the declaring class will be null.
      */
     public Class<?> getDeclaringClass() {
-        if (clazz == null && isResolved()) {
-            expandFromVM();
-        }
         return clazz;
     }
 
@@ -105,6 +103,16 @@
         return name;
     }
 
+    public MethodType getMethodOrFieldType() {
+        if (isInvocable())
+            return getMethodType();
+        if (isGetter())
+            return MethodType.methodType(getFieldType());
+        if (isSetter())
+            return MethodType.methodType(void.class, getFieldType());
+        throw new InternalError("not a method or field: "+this);
+    }
+
     /** Return the declared type of this member, which
      *  must be a method or constructor.
      */
@@ -140,9 +148,11 @@
      *  a reference to declaring class.  For static methods, it is the same as the declared type.
      */
     public MethodType getInvocationType() {
-        MethodType itype = getMethodType();
+        MethodType itype = getMethodOrFieldType();
+        if (isConstructor() && getReferenceKind() == REF_newInvokeSpecial)
+            return itype.changeReturnType(clazz);
         if (!isStatic())
-            itype = itype.insertParameterTypes(0, clazz);
+            return itype.insertParameterTypes(0, clazz);
         return itype;
     }
 
@@ -208,9 +218,92 @@
         return (flags & RECOGNIZED_MODIFIERS);
     }
 
-    private void setFlags(int flags) {
-        this.flags = flags;
-        assert(testAnyFlags(ALL_KINDS));
+    /** Return the reference kind of this member, or zero if none.
+     */
+    public byte getReferenceKind() {
+        return (byte) ((flags >>> MN_REFERENCE_KIND_SHIFT) & MN_REFERENCE_KIND_MASK);
+    }
+    private boolean referenceKindIsConsistent() {
+        byte refKind = getReferenceKind();
+        if (refKind == REF_NONE)  return isType();
+        if (isField()) {
+            assert(staticIsConsistent());
+            assert(MethodHandleNatives.refKindIsField(refKind));
+        } else if (isConstructor()) {
+            assert(refKind == REF_newInvokeSpecial || refKind == REF_invokeSpecial);
+        } else if (isMethod()) {
+            assert(staticIsConsistent());
+            assert(MethodHandleNatives.refKindIsMethod(refKind));
+            if (clazz.isInterface())
+                assert(refKind == REF_invokeInterface ||
+                       refKind == REF_invokeVirtual && isObjectPublicMethod());
+        } else {
+            assert(false);
+        }
+        return true;
+    }
+    private boolean isObjectPublicMethod() {
+        if (clazz == Object.class)  return true;
+        MethodType mtype = getMethodType();
+        if (name.equals("toString") && mtype.returnType() == String.class && mtype.parameterCount() == 0)
+            return true;
+        if (name.equals("hashCode") && mtype.returnType() == int.class && mtype.parameterCount() == 0)
+            return true;
+        if (name.equals("equals") && mtype.returnType() == boolean.class && mtype.parameterCount() == 1 && mtype.parameterType(0) == Object.class)
+            return true;
+        return false;
+    }
+    /*non-public*/ boolean referenceKindIsConsistentWith(int originalRefKind) {
+        int refKind = getReferenceKind();
+        if (refKind == originalRefKind)  return true;
+        switch (originalRefKind) {
+        case REF_invokeInterface:
+            // Looking up an interface method, can get (e.g.) Object.hashCode
+            assert(refKind == REF_invokeVirtual ||
+                   refKind == REF_invokeSpecial) : this;
+            return true;
+        case REF_invokeVirtual:
+        case REF_newInvokeSpecial:
+            // Looked up a virtual, can get (e.g.) final String.hashCode.
+            assert(refKind == REF_invokeSpecial) : this;
+            return true;
+        }
+        assert(false) : this;
+        return true;
+    }
+    private boolean staticIsConsistent() {
+        byte refKind = getReferenceKind();
+        return MethodHandleNatives.refKindIsStatic(refKind) == isStatic() || getModifiers() == 0;
+    }
+    private boolean vminfoIsConsistent() {
+        byte refKind = getReferenceKind();
+        assert(isResolved());  // else don't call
+        Object vminfo = MethodHandleNatives.getMemberVMInfo(this);
+        assert(vminfo instanceof Object[]);
+        long vmindex = (Long) ((Object[])vminfo)[0];
+        Object vmtarget = ((Object[])vminfo)[1];
+        if (MethodHandleNatives.refKindIsField(refKind)) {
+            assert(vmindex >= 0) : vmindex + ":" + this;
+            assert(vmtarget instanceof Class);
+        } else {
+            if (MethodHandleNatives.refKindDoesDispatch(refKind))
+                assert(vmindex >= 0) : vmindex + ":" + this;
+            else
+                assert(vmindex < 0) : vmindex;
+            assert(vmtarget instanceof MemberName) : vmtarget + " in " + this;
+        }
+        return true;
+    }
+
+    private MemberName changeReferenceKind(byte refKind, byte oldKind) {
+        assert(getReferenceKind() == oldKind);
+        assert(MethodHandleNatives.refKindIsValid(refKind));
+        flags += (((int)refKind - oldKind) << MN_REFERENCE_KIND_SHIFT);
+//        if (isConstructor() && refKind != REF_newInvokeSpecial)
+//            flags += (IS_METHOD - IS_CONSTRUCTOR);
+//        else if (refKind == REF_newInvokeSpecial && isMethod())
+//            flags += (IS_CONSTRUCTOR - IS_METHOD);
+        return this;
     }
 
     private boolean testFlags(int mask, int value) {
@@ -223,6 +316,17 @@
         return !testFlags(mask, 0);
     }
 
+    /** Utility method to query if this member is a method handle invocation (invoke or invokeExact). */
+    public boolean isMethodHandleInvoke() {
+        final int bits = Modifier.NATIVE | Modifier.FINAL;
+        final int negs = Modifier.STATIC;
+        if (testFlags(bits | negs, bits) &&
+            clazz == MethodHandle.class) {
+            return name.equals("invoke") || name.equals("invokeExact");
+        }
+        return false;
+    }
+
     /** Utility method to query the modifier flags of this member. */
     public boolean isStatic() {
         return Modifier.isStatic(flags);
@@ -243,10 +347,22 @@
     public boolean isFinal() {
         return Modifier.isFinal(flags);
     }
+    /** Utility method to query whether this member or its defining class is final. */
+    public boolean canBeStaticallyBound() {
+        return Modifier.isFinal(flags | clazz.getModifiers());
+    }
+    /** Utility method to query the modifier flags of this member. */
+    public boolean isVolatile() {
+        return Modifier.isVolatile(flags);
+    }
     /** Utility method to query the modifier flags of this member. */
     public boolean isAbstract() {
         return Modifier.isAbstract(flags);
     }
+    /** Utility method to query the modifier flags of this member. */
+    public boolean isNative() {
+        return Modifier.isNative(flags);
+    }
     // let the rest (native, volatile, transient, etc.) be tested via Modifier.isFoo
 
     // unofficial modifier flags, used by HotSpot:
@@ -279,15 +395,12 @@
             IS_CONSTRUCTOR = MN_IS_CONSTRUCTOR, // constructor
             IS_FIELD       = MN_IS_FIELD,       // field
             IS_TYPE        = MN_IS_TYPE;        // nested type
-    static final int  // for MethodHandleNatives.getMembers
-            SEARCH_SUPERCLASSES = MN_SEARCH_SUPERCLASSES,
-            SEARCH_INTERFACES   = MN_SEARCH_INTERFACES;
 
     static final int ALL_ACCESS = Modifier.PUBLIC | Modifier.PRIVATE | Modifier.PROTECTED;
     static final int ALL_KINDS = IS_METHOD | IS_CONSTRUCTOR | IS_FIELD | IS_TYPE;
     static final int IS_INVOCABLE = IS_METHOD | IS_CONSTRUCTOR;
     static final int IS_FIELD_OR_METHOD = IS_METHOD | IS_FIELD;
-    static final int SEARCH_ALL_SUPERS = SEARCH_SUPERCLASSES | SEARCH_INTERFACES;
+    static final int SEARCH_ALL_SUPERS = MN_SEARCH_SUPERCLASSES | MN_SEARCH_INTERFACES;
 
     /** Utility method to query whether this member is a method or constructor. */
     public boolean isInvocable() {
@@ -318,6 +431,12 @@
         return !testAnyFlags(ALL_ACCESS);
     }
 
+    /** Utility method to query whether this member is accessible from a given lookup class. */
+    public boolean isAccessibleFrom(Class<?> lookupClass) {
+        return VerifyAccess.isMemberAccessible(this.getDeclaringClass(), this.getDeclaringClass(), flags,
+                                               lookupClass, ALL_ACCESS|MethodHandles.Lookup.PACKAGE);
+    }
+
     /** Initialize a query.   It is not resolved. */
     private void init(Class<?> defClass, String name, Object type, int flags) {
         // defining class is allowed to be null (for a naked name/type pair)
@@ -327,8 +446,10 @@
         this.clazz = defClass;
         this.name = name;
         this.type = type;
-        setFlags(flags);
-        assert(!isResolved());
+        this.flags = flags;
+        assert(testAnyFlags(ALL_KINDS));
+        assert(this.resolution == null);  // nobody should have touched this yet
+        //assert(referenceKindIsConsistent());  // do this after resolution
     }
 
     private void expandFromVM() {
@@ -339,39 +460,94 @@
     }
 
     // Capturing information from the Core Reflection API:
-    private static int flagsMods(int flags, int mods) {
+    private static int flagsMods(int flags, int mods, byte refKind) {
         assert((flags & RECOGNIZED_MODIFIERS) == 0);
         assert((mods & ~RECOGNIZED_MODIFIERS) == 0);
-        return flags | mods;
+        assert((refKind & ~MN_REFERENCE_KIND_MASK) == 0);
+        return flags | mods | (refKind << MN_REFERENCE_KIND_SHIFT);
     }
     /** Create a name for the given reflected method.  The resulting name will be in a resolved state. */
     public MemberName(Method m) {
-        Object[] typeInfo = { m.getReturnType(), m.getParameterTypes() };
-        init(m.getDeclaringClass(), m.getName(), typeInfo, flagsMods(IS_METHOD, m.getModifiers()));
+        this(m, false);
+    }
+    @SuppressWarnings("LeakingThisInConstructor")
+    public MemberName(Method m, boolean wantSpecial) {
+        m.getClass();  // NPE check
         // fill in vmtarget, vmindex while we have m in hand:
         MethodHandleNatives.init(this, m);
-        assert(isResolved());
+        assert(isResolved() && this.clazz != null);
+        this.name = m.getName();
+        if (this.type == null)
+            this.type = new Object[] { m.getReturnType(), m.getParameterTypes() };
+        if (wantSpecial) {
+            if (getReferenceKind() == REF_invokeVirtual)
+                changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
+        }
+    }
+    public MemberName asSpecial() {
+        switch (getReferenceKind()) {
+        case REF_invokeSpecial:     return this;
+        case REF_invokeVirtual:     return clone().changeReferenceKind(REF_invokeSpecial, REF_invokeVirtual);
+        case REF_newInvokeSpecial:  return clone().changeReferenceKind(REF_invokeSpecial, REF_newInvokeSpecial);
+        }
+        throw new IllegalArgumentException(this.toString());
+    }
+    public MemberName asConstructor() {
+        switch (getReferenceKind()) {
+        case REF_invokeSpecial:     return clone().changeReferenceKind(REF_newInvokeSpecial, REF_invokeSpecial);
+        case REF_newInvokeSpecial:  return this;
+        }
+        throw new IllegalArgumentException(this.toString());
     }
     /** Create a name for the given reflected constructor.  The resulting name will be in a resolved state. */
-    public MemberName(Constructor ctor) {
-        Object[] typeInfo = { void.class, ctor.getParameterTypes() };
-        init(ctor.getDeclaringClass(), CONSTRUCTOR_NAME, typeInfo, flagsMods(IS_CONSTRUCTOR, ctor.getModifiers()));
+    @SuppressWarnings("LeakingThisInConstructor")
+    public MemberName(Constructor<?> ctor) {
+        ctor.getClass();  // NPE check
         // fill in vmtarget, vmindex while we have ctor in hand:
         MethodHandleNatives.init(this, ctor);
-        assert(isResolved());
+        assert(isResolved() && this.clazz != null);
+        this.name = CONSTRUCTOR_NAME;
+        if (this.type == null)
+            this.type = new Object[] { void.class, ctor.getParameterTypes() };
     }
-    /** Create a name for the given reflected field.  The resulting name will be in a resolved state. */
+    /** Create a name for the given reflected field.  The resulting name will be in a resolved state.
+     */
     public MemberName(Field fld) {
-        init(fld.getDeclaringClass(), fld.getName(), fld.getType(), flagsMods(IS_FIELD, fld.getModifiers()));
+        this(fld, false);
+    }
+    @SuppressWarnings("LeakingThisInConstructor")
+    public MemberName(Field fld, boolean makeSetter) {
+        fld.getClass();  // NPE check
         // fill in vmtarget, vmindex while we have fld in hand:
         MethodHandleNatives.init(this, fld);
-        assert(isResolved());
+        assert(isResolved() && this.clazz != null);
+        this.name = fld.getName();
+        this.type = fld.getType();
+        assert((REF_putStatic - REF_getStatic) == (REF_putField - REF_getField));
+        byte refKind = this.getReferenceKind();
+        assert(refKind == (isStatic() ? REF_getStatic : REF_getField));
+        if (makeSetter) {
+            changeReferenceKind((byte)(refKind + (REF_putStatic - REF_getStatic)), refKind);
+        }
+    }
+    public boolean isGetter() {
+        return MethodHandleNatives.refKindIsGetter(getReferenceKind());
+    }
+    public boolean isSetter() {
+        return MethodHandleNatives.refKindIsSetter(getReferenceKind());
+    }
+    public MemberName asSetter() {
+        byte refKind = getReferenceKind();
+        assert(MethodHandleNatives.refKindIsGetter(refKind));
+        assert((REF_putStatic - REF_getStatic) == (REF_putField - REF_getField));
+        byte setterRefKind = (byte)(refKind + (REF_putField - REF_getField));
+        return clone().changeReferenceKind(setterRefKind, refKind);
     }
     /** Create a name for the given class.  The resulting name will be in a resolved state. */
     public MemberName(Class<?> type) {
-        init(type.getDeclaringClass(), type.getSimpleName(), type, flagsMods(IS_TYPE, type.getModifiers()));
-        vmindex = 0;  // isResolved
-        assert(isResolved());
+        init(type.getDeclaringClass(), type.getSimpleName(), type,
+                flagsMods(IS_TYPE, type.getModifiers(), REF_NONE));
+        initResolved(true);
     }
 
     // bare-bones constructor; the JVM will fill it in
@@ -382,45 +558,93 @@
         try {
             return (MemberName) super.clone();
         } catch (CloneNotSupportedException ex) {
-            throw new InternalError();
+            throw newInternalError(ex);
         }
      }
 
-    // %%% define equals/hashcode?
+    /** Get the definition of this member name.
+     *  This may be in a super-class of the declaring class of this member.
+     */
+    public MemberName getDefinition() {
+        if (!isResolved())  throw new IllegalStateException("must be resolved: "+this);
+        if (isType())  return this;
+        MemberName res = this.clone();
+        res.clazz = null;
+        res.type = null;
+        res.name = null;
+        res.resolution = res;
+        res.expandFromVM();
+        assert(res.getName().equals(this.getName()));
+        return res;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(clazz, flags, name, getType());
+    }
+    @Override
+    public boolean equals(Object that) {
+        return (that instanceof MemberName && this.equals((MemberName)that));
+    }
+
+    /** Decide if two member names have exactly the same symbolic content.
+     *  Does not take into account any actual class members, so even if
+     *  two member names resolve to the same actual member, they may
+     *  be distinct references.
+     */
+    public boolean equals(MemberName that) {
+        if (this == that)  return true;
+        if (that == null)  return false;
+        return this.clazz == that.clazz
+                && this.flags == that.flags
+                && Objects.equals(this.name, that.name)
+                && Objects.equals(this.getType(), that.getType());
+    }
 
     // Construction from symbolic parts, for queries:
-    /** Create a field or type name from the given components:  Declaring class, name, type, modifiers.
+    /** Create a field or type name from the given components:  Declaring class, name, type, reference kind.
      *  The declaring class may be supplied as null if this is to be a bare name and type.
      *  The resulting name will in an unresolved state.
      */
-    public MemberName(Class<?> defClass, String name, Class<?> type, int modifiers) {
-        init(defClass, name, type, IS_FIELD | (modifiers & RECOGNIZED_MODIFIERS));
+    public MemberName(Class<?> defClass, String name, Class<?> type, byte refKind) {
+        init(defClass, name, type, flagsMods(IS_FIELD, 0, refKind));
+        initResolved(false);
     }
     /** Create a field or type name from the given components:  Declaring class, name, type.
      *  The declaring class may be supplied as null if this is to be a bare name and type.
      *  The modifier flags default to zero.
      *  The resulting name will in an unresolved state.
      */
-    public MemberName(Class<?> defClass, String name, Class<?> type) {
-        this(defClass, name, type, 0);
+    public MemberName(Class<?> defClass, String name, Class<?> type, Void unused) {
+        this(defClass, name, type, REF_NONE);
+        initResolved(false);
     }
     /** Create a method or constructor name from the given components:  Declaring class, name, type, modifiers.
      *  It will be a constructor if and only if the name is {@code "&lt;init&gt;"}.
      *  The declaring class may be supplied as null if this is to be a bare name and type.
+     *  The last argument is optional, a boolean which requests REF_invokeSpecial.
      *  The resulting name will in an unresolved state.
      */
-    public MemberName(Class<?> defClass, String name, MethodType type, int modifiers) {
-        int flagBit = (name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
-        init(defClass, name, type, flagBit | (modifiers & RECOGNIZED_MODIFIERS));
+    public MemberName(Class<?> defClass, String name, MethodType type, byte refKind) {
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
+        int flags = (name != null && name.equals(CONSTRUCTOR_NAME) ? IS_CONSTRUCTOR : IS_METHOD);
+        init(defClass, name, type, flagsMods(flags, 0, refKind));
+        initResolved(false);
     }
-    /** Create a method or constructor name from the given components:  Declaring class, name, type, modifiers.
-     *  It will be a constructor if and only if the name is {@code "&lt;init&gt;"}.
-     *  The declaring class may be supplied as null if this is to be a bare name and type.
-     *  The modifier flags default to zero.
-     *  The resulting name will in an unresolved state.
+//    /** Create a method or constructor name from the given components:  Declaring class, name, type, modifiers.
+//     *  It will be a constructor if and only if the name is {@code "&lt;init&gt;"}.
+//     *  The declaring class may be supplied as null if this is to be a bare name and type.
+//     *  The modifier flags default to zero.
+//     *  The resulting name will in an unresolved state.
+//     */
+//    public MemberName(Class<?> defClass, String name, MethodType type, Void unused) {
+//        this(defClass, name, type, REF_NONE);
+//    }
+
+    /** Query whether this member name is resolved to a non-static, non-final method.
      */
-    public MemberName(Class<?> defClass, String name, MethodType type) {
-        this(defClass, name, type, 0);
+    public boolean hasReceiverTypeDispatch() {
+        return MethodHandleNatives.refKindDoesDispatch(getReferenceKind());
     }
 
     /** Query whether this member name is resolved.
@@ -429,15 +653,38 @@
      *  (Document?)
      */
     public boolean isResolved() {
-        return (vmindex != VM_INDEX_UNINITIALIZED);
+        return resolution == null;
     }
 
-    /** Query whether this member name is resolved to a non-static, non-final method.
-     */
-    public boolean hasReceiverTypeDispatch() {
-        return (isMethod() && getVMIndex() >= 0);
+    private void initResolved(boolean isResolved) {
+        assert(this.resolution == null);  // not initialized yet!
+        if (!isResolved)
+            this.resolution = this;
+        assert(isResolved() == isResolved);
     }
 
+    void checkForTypeAlias() {
+        if (isInvocable()) {
+            MethodType type;
+            if (this.type instanceof MethodType)
+                type = (MethodType) this.type;
+            else
+                this.type = type = getMethodType();
+            if (type.erase() == type)  return;
+            if (VerifyAccess.isTypeVisible(type, clazz))  return;
+            throw new LinkageError("bad method type alias: "+type+" not visible from "+clazz);
+        } else {
+            Class<?> type;
+            if (this.type instanceof Class<?>)
+                type = (Class<?>) this.type;
+            else
+                this.type = type = getFieldType();
+            if (VerifyAccess.isTypeVisible(type, clazz))  return;
+            throw new LinkageError("bad field type alias: "+type+" not visible from "+clazz);
+        }
+    }
+
+
     /** Produce a string form of this member name.
      *  For types, it is simply the type's own string (as reported by {@code toString}).
      *  For fields, it is {@code "DeclaringClass.name/type"}.
@@ -445,6 +692,7 @@
      *  If the declaring class is null, the prefix {@code "DeclaringClass."} is omitted.
      *  If the member is unresolved, a prefix {@code "*."} is prepended.
      */
+    @SuppressWarnings("LocalVariableHidesMemberVariable")
     @Override
     public String toString() {
         if (isType())
@@ -464,22 +712,12 @@
         } else {
             buf.append(type == null ? "(*)*" : getName(type));
         }
-        /*
-        buf.append('/');
-        // key: Public, private, pRotected, sTatic, Final, sYnchronized,
-        // transient/Varargs, native, (interface), abstract, sTrict, sYnthetic,
-        // (annotation), Enum, (unused)
-        final String FIELD_MOD_CHARS  = "PprTF?vt????Y?E?";
-        final String METHOD_MOD_CHARS = "PprTFybVn?atY???";
-        String modChars = (isInvocable() ? METHOD_MOD_CHARS : FIELD_MOD_CHARS);
-        for (int i = 0; i < modChars.length(); i++) {
-            if ((flags & (1 << i)) != 0) {
-                char mc = modChars.charAt(i);
-                if (mc != '?')
-                    buf.append(mc);
-            }
+        byte refKind = getReferenceKind();
+        if (refKind != REF_NONE) {
+            buf.append('/');
+            buf.append(MethodHandleNatives.refKindName(refKind));
         }
-         */
+        //buf.append("#").append(System.identityHashCode(this));
         return buf.toString();
     }
     private static String getName(Object obj) {
@@ -488,19 +726,6 @@
         return String.valueOf(obj);
     }
 
-    // Queries to the JVM:
-    /** Document? */
-    /*non-public*/ int getVMIndex() {
-        if (!isResolved())
-            throw newIllegalStateException("not resolved", this);
-        return vmindex;
-    }
-//    /*non-public*/ Object getVMTarget() {
-//        if (!isResolved())
-//            throw newIllegalStateException("not resolved", this);
-//        return vmtarget;
-//    }
-
     public IllegalAccessException makeAccessException(String message, Object from) {
         message = message + ": "+ toString();
         if (from != null)  message += ", from " + from;
@@ -518,14 +743,19 @@
     }
     public ReflectiveOperationException makeAccessException() {
         String message = message() + ": "+ toString();
-        if (isResolved())
-            return new IllegalAccessException(message);
+        ReflectiveOperationException ex;
+        if (isResolved() || !(resolution instanceof NoSuchMethodError ||
+                              resolution instanceof NoSuchFieldError))
+            ex = new IllegalAccessException(message);
         else if (isConstructor())
-            return new NoSuchMethodException(message);
+            ex = new NoSuchMethodException(message);
         else if (isMethod())
-            return new NoSuchMethodException(message);
+            ex = new NoSuchMethodException(message);
         else
-            return new NoSuchFieldException(message);
+            ex = new NoSuchFieldException(message);
+        if (resolution instanceof Throwable)
+            ex.initCause((Throwable) resolution);
+        return ex;
     }
 
     /** Actually making a query requires an access check. */
@@ -539,7 +769,7 @@
         private Factory() { } // singleton pattern
         static Factory INSTANCE = new Factory();
 
-        private static int ALLOWED_FLAGS = SEARCH_ALL_SUPERS | ALL_KINDS;
+        private static int ALLOWED_FLAGS = ALL_KINDS;
 
         /// Queries
         List<MemberName> getMembers(Class<?> defc,
@@ -573,14 +803,14 @@
                 // JVM returned to us with an intentional overflow!
                 totalCount += buf.length;
                 int excess = bufCount - buf.length;
-                if (bufs == null)  bufs = new ArrayList<MemberName[]>(1);
+                if (bufs == null)  bufs = new ArrayList<>(1);
                 bufs.add(buf);
                 int len2 = buf.length;
                 len2 = Math.max(len2, excess);
                 len2 = Math.max(len2, totalCount / 4);
                 buf = newMemberBuffer(Math.min(BUF_MAX, len2));
             }
-            ArrayList<MemberName> result = new ArrayList<MemberName>(totalCount);
+            ArrayList<MemberName> result = new ArrayList<>(totalCount);
             if (bufs != null) {
                 for (MemberName[] buf0 : bufs) {
                     Collections.addAll(result, buf0);
@@ -599,43 +829,29 @@
             }
             return result;
         }
-        boolean resolveInPlace(MemberName m, boolean searchSupers, Class<?> lookupClass) {
-            if (m.name == null || m.type == null) {  // find unique non-overloaded name
-                Class<?> defc = m.getDeclaringClass();
-                List<MemberName> choices = null;
-                if (m.isMethod())
-                    choices = getMethods(defc, searchSupers, m.name, (MethodType) m.type, lookupClass);
-                else if (m.isConstructor())
-                    choices = getConstructors(defc, lookupClass);
-                else if (m.isField())
-                    choices = getFields(defc, searchSupers, m.name, (Class<?>) m.type, lookupClass);
-                //System.out.println("resolving "+m+" to "+choices);
-                if (choices == null || choices.size() != 1)
-                    return false;
-                if (m.name == null)  m.name = choices.get(0).name;
-                if (m.type == null)  m.type = choices.get(0).type;
-            }
-            MethodHandleNatives.resolve(m, lookupClass);
-            if (m.isResolved())  return true;
-            int matchFlags = m.flags | (searchSupers ? SEARCH_ALL_SUPERS : 0);
-            String matchSig = m.getSignature();
-            MemberName[] buf = { m };
-            int n = MethodHandleNatives.getMembers(m.getDeclaringClass(),
-                    m.getName(), matchSig, matchFlags, lookupClass, 0, buf);
-            if (n != 1)  return false;
-            return m.isResolved();
-        }
         /** Produce a resolved version of the given member.
          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
          *  Access checking is performed on behalf of the given {@code lookupClass}.
          *  If lookup fails or access is not permitted, null is returned.
          *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
          */
-        public MemberName resolveOrNull(MemberName m, boolean searchSupers, Class<?> lookupClass) {
-            MemberName result = m.clone();
-            if (resolveInPlace(result, searchSupers, lookupClass))
-                return result;
-            return null;
+        private MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass) {
+            MemberName m = ref.clone();  // JVM will side-effect the ref
+            assert(refKind == m.getReferenceKind());
+            try {
+                m = MethodHandleNatives.resolve(m, lookupClass);
+                m.checkForTypeAlias();
+                m.resolution = null;
+            } catch (LinkageError ex) {
+                // JVM reports that the "bytecode behavior" would get an error
+                assert(!m.isResolved());
+                m.resolution = ex;
+                return m;
+            }
+            assert(m.referenceKindIsConsistent());
+            m.initResolved(true);
+            assert(m.vminfoIsConsistent());
+            return m;
         }
         /** Produce a resolved version of the given member.
          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
@@ -645,16 +861,29 @@
          */
         public
         <NoSuchMemberException extends ReflectiveOperationException>
-        MemberName resolveOrFail(MemberName m, boolean searchSupers, Class<?> lookupClass,
+        MemberName resolveOrFail(byte refKind, MemberName m, Class<?> lookupClass,
                                  Class<NoSuchMemberException> nsmClass)
                 throws IllegalAccessException, NoSuchMemberException {
-            MemberName result = resolveOrNull(m, searchSupers, lookupClass);
-            if (result != null)
+            MemberName result = resolve(refKind, m, lookupClass);
+            if (result.isResolved())
                 return result;
-            ReflectiveOperationException ex = m.makeAccessException();
+            ReflectiveOperationException ex = result.makeAccessException();
             if (ex instanceof IllegalAccessException)  throw (IllegalAccessException) ex;
             throw nsmClass.cast(ex);
         }
+        /** Produce a resolved version of the given member.
+         *  Super types are searched (for inherited members) if {@code searchSupers} is true.
+         *  Access checking is performed on behalf of the given {@code lookupClass}.
+         *  If lookup fails or access is not permitted, return null.
+         *  Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
+         */
+        public
+        MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass) {
+            MemberName result = resolve(refKind, m, lookupClass);
+            if (result.isResolved())
+                return result;
+            return null;
+        }
         /** Return a list of all methods defined by the given class.
          *  Super types are searched (for inherited members) if {@code searchSupers} is true.
          *  Access checking is performed on behalf of the given {@code lookupClass}.
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java
index 3eda73a..2a6b8c1 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandle.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandle.java
@@ -26,9 +26,13 @@
 package java.lang.invoke;
 
 
-import java.util.ArrayList;
-import sun.invoke.util.ValueConversions;
+import java.util.*;
+import sun.invoke.util.*;
+import sun.misc.Unsafe;
+
 import static java.lang.invoke.MethodHandleStatics.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * A method handle is a typed, directly executable reference to an underlying method,
@@ -208,8 +212,8 @@
  * refers directly to an associated {@code CONSTANT_Methodref},
  * {@code CONSTANT_InterfaceMethodref}, or {@code CONSTANT_Fieldref}
  * constant pool entry.
- * (For more details on method handle constants,
- * see the <a href="package-summary.html#mhcon">package summary</a>.)
+ * (For full details on method handle constants,
+ * see sections 4.4.8 and 5.4.3.5 of the Java Virtual Machine Specification.)
  * <p>
  * Method handles produced by lookups or constant loads from methods or
  * constructors with the variable arity modifier bit ({@code 0x0080})
@@ -224,6 +228,19 @@
  * (E.g., if a non-static method handle is obtained via {@code ldc},
  * the type of the receiver is the class named in the constant pool entry.)
  * <p>
+ * Method handle constants are subject to the same link-time access checks
+ * their corresponding bytecode instructions, and the {@code ldc} instruction
+ * will throw corresponding linkage errors if the bytecode behaviors would
+ * throw such errors.
+ * <p>
+ * As a corollary of this, access to protected members is restricted
+ * to receivers only of the accessing class, or one of its subclasses,
+ * and the accessing class must in turn be a subclass (or package sibling)
+ * of the protected member's defining class.
+ * If a method reference refers to a protected non-static method or field
+ * of a class outside the current package, the receiver argument will
+ * be narrowed to the type of the accessing class.
+ * <p>
  * When a method handle to a virtual method is invoked, the method is
  * always looked up in the receiver (that is, the first argument).
  * <p>
@@ -275,7 +292,7 @@
  * generates a single invokevirtual instruction with
  * the symbolic type descriptor indicated in the following comment.
  * In these examples, the helper method {@code assertEquals} is assumed to
- * be a method which calls {@link Objects.equals java.util.Objects#equals}
+ * be a method which calls {@link java.util.Objects#equals(Object,Object) Objects.equals }
  * on its arguments, and asserts that the result is true.
  *
  * <h3>Exceptions</h3>
@@ -390,39 +407,8 @@
  * @author John Rose, JSR 292 EG
  */
 public abstract class MethodHandle {
-    // { JVM internals:
-
-    private byte       vmentry;    // adapter stub or method entry point
-    //private int      vmslots;    // optionally, hoist type.form.vmslots
-    /*non-public*/ Object vmtarget;   // VM-specific, class-specific target value
-
-    // TO DO:  vmtarget should be invisible to Java, since the JVM puts internal
-    // managed pointers into it.  Making it visible exposes it to debuggers,
-    // which can cause errors when they treat the pointer as an Object.
-
-    // These two dummy fields are present to force 'I' and 'J' signatures
-    // into this class's constant pool, so they can be transferred
-    // to vmentry when this class is loaded.
-    static final int  INT_FIELD = 0;
-    static final long LONG_FIELD = 0;
-
-    // vmentry (a void* field) is used *only* by the JVM.
-    // The JVM adjusts its type to int or long depending on system wordsize.
-    // Since it is statically typed as neither int nor long, it is impossible
-    // to use this field from Java bytecode.  (Please don't try to, either.)
-
-    // The vmentry is an assembly-language stub which is jumped to
-    // immediately after the method type is verified.
-    // For a direct MH, this stub loads the vmtarget's entry point
-    // and jumps to it.
-
-    // } End of JVM internals.
-
     static { MethodHandleImpl.initStatics(); }
 
-    // interface MethodHandle<R throws X extends Exception,A...>
-    // { MethodType<R throws X,A...> type(); public R invokeExact(A...) throws X; }
-
     /**
      * Internal marker interface which distinguishes (to the Java compiler)
      * those methods which are <a href="MethodHandle.html#sigpoly">signature polymorphic</a>.
@@ -431,7 +417,9 @@
     @java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
     @interface PolymorphicSignature { }
 
-    private MethodType type;
+    private final MethodType type;
+    /*private*/ final LambdaForm form;
+    // form is not private so that invokers can easily fetch it
 
     /**
      * Reports the type of this method handle.
@@ -448,9 +436,13 @@
      * the {@code java.lang.invoke} package.
      */
     // @param type type (permanently assigned) of the new method handle
-    /*non-public*/ MethodHandle(MethodType type) {
-        type.getClass();  // elicit NPE
+    /*non-public*/ MethodHandle(MethodType type, LambdaForm form) {
+        type.getClass();  // explicit NPE
+        form.getClass();  // explicit NPE
         this.type = type;
+        this.form = form;
+
+        form.prepare();  // TO DO:  Try to delay this step until just before invocation.
     }
 
     /**
@@ -506,6 +498,46 @@
     public final native @PolymorphicSignature Object invoke(Object... args) throws Throwable;
 
     /**
+     * Private method for trusted invocation of a method handle respecting simplified signatures.
+     * Type mismatches will not throw {@code WrongMethodTypeException}, but could crash the JVM.
+     * <p>
+     * The caller signature is restricted to the following basic types:
+     * Object, int, long, float, double, and void return.
+     * <p>
+     * The caller is responsible for maintaining type correctness by ensuring
+     * that the each outgoing argument value is a member of the range of the corresponding
+     * callee argument type.
+     * (The caller should therefore issue appropriate casts and integer narrowing
+     * operations on outgoing argument values.)
+     * The caller can assume that the incoming result value is part of the range
+     * of the callee's return type.
+     */
+    /*non-public*/ final native @PolymorphicSignature Object invokeBasic(Object... args) throws Throwable;
+
+    /*non-public*/ static native @PolymorphicSignature Object linkToVirtual(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeStatic}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     */
+    /*non-public*/ static native @PolymorphicSignature Object linkToStatic(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeSpecial}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     */
+    /*non-public*/ static native @PolymorphicSignature Object linkToSpecial(Object... args) throws Throwable;
+
+    /**
+     * Private method for trusted invocation of a MemberName of kind {@code REF_invokeInterface}.
+     * The caller signature is restricted to basic types as with {@code invokeBasic}.
+     * The trailing (not leading) argument must be a MemberName.
+     */
+    /*non-public*/ static native @PolymorphicSignature Object linkToInterface(Object... args) throws Throwable;
+
+    /**
      * Performs a variable arity invocation, passing the arguments in the given array
      * to the method handle, as if via an inexact {@link #invoke invoke} from a call site
      * which mentions only the type {@code Object}, and whose arity is the length
@@ -557,6 +589,7 @@
      */
     public Object invokeWithArguments(Object... arguments) throws Throwable {
         int argc = arguments == null ? 0 : arguments.length;
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
         MethodType type = type();
         if (type.parameterCount() != argc || isVarargsCollector()) {
             // simulate invoke
@@ -690,7 +723,7 @@
         if (!type.isConvertibleTo(newType)) {
             throw new WrongMethodTypeException("cannot convert "+this+" to "+newType);
         }
-        return MethodHandleImpl.convertArguments(this, newType, 1);
+        return convertArguments(newType);
     }
 
     /**
@@ -772,7 +805,8 @@
      */
     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
         asSpreaderChecks(arrayType, arrayLength);
-        return MethodHandleImpl.spreadArguments(this, arrayType, arrayLength);
+        int spreadArgPos = type.parameterCount() - arrayLength;
+        return MethodHandleImpl.makeSpreadArguments(this, arrayType, spreadArgPos, arrayLength);
     }
 
     private void asSpreaderChecks(Class<?> arrayType, int arrayLength) {
@@ -790,7 +824,7 @@
                 }
             }
             if (sawProblem) {
-                ArrayList<Class<?>> ptypes = new ArrayList<Class<?>>(type().parameterList());
+                ArrayList<Class<?>> ptypes = new ArrayList<>(type().parameterList());
                 for (int i = nargs - arrayLength; i < nargs; i++) {
                     ptypes.set(i, arrayElement);
                 }
@@ -885,8 +919,12 @@
      */
     public MethodHandle asCollector(Class<?> arrayType, int arrayLength) {
         asCollectorChecks(arrayType, arrayLength);
+        int collectArgPos = type().parameterCount()-1;
+        MethodHandle target = this;
+        if (arrayType != type().parameterType(collectArgPos))
+            target = convertArguments(type().changeParameterType(collectArgPos, arrayType));
         MethodHandle collector = ValueConversions.varargsArray(arrayType, arrayLength);
-        return MethodHandleImpl.collectArguments(this, type.parameterCount()-1, collector);
+        return MethodHandles.collectArguments(target, collectArgPos, collector);
     }
 
     // private API: return true if last param exactly matches arrayType
@@ -1056,7 +1094,7 @@
         boolean lastMatch = asCollectorChecks(arrayType, 0);
         if (isVarargsCollector() && lastMatch)
             return this;
-        return AdapterMethodHandle.makeVarargsCollector(this, arrayType);
+        return MethodHandleImpl.makeVarargsCollector(this, arrayType);
     }
 
     /**
@@ -1155,14 +1193,13 @@
      */
     public MethodHandle bindTo(Object x) {
         Class<?> ptype;
-        if (type().parameterCount() == 0 ||
-            (ptype = type().parameterType(0)).isPrimitive())
+        @SuppressWarnings("LocalVariableHidesMemberVariable")
+        MethodType type = type();
+        if (type.parameterCount() == 0 ||
+            (ptype = type.parameterType(0)).isPrimitive())
             throw newIllegalArgumentException("no leading reference parameter", x);
-        x = MethodHandles.checkValue(ptype, x);
-        // Cf. MethodHandles.insertArguments for the following logic:
-        MethodHandle bmh = MethodHandleImpl.bindReceiver(this, x);
-        if (bmh != null)  return bmh;
-        return MethodHandleImpl.bindArgument(this, 0, x);
+        x = ptype.cast(x);  // throw CCE if needed
+        return bindReceiver(x);
     }
 
     /**
@@ -1183,11 +1220,184 @@
     @Override
     public String toString() {
         if (DEBUG_METHOD_HANDLE_NAMES)  return debugString();
+        return standardString();
+    }
+    String standardString() {
         return "MethodHandle"+type;
     }
+    String debugString() {
+        return standardString()+"/LF="+internalForm()+internalProperties();
+    }
+
+    //// Implementation methods.
+    //// Sub-classes can override these default implementations.
+    //// All these methods assume arguments are already validated.
+
+    // Other transforms to do:  convert, explicitCast, permute, drop, filter, fold, GWT, catch
+
+    /*non-public*/
+    MethodHandle setVarargs(MemberName member) throws IllegalAccessException {
+        if (!member.isVarargs())  return this;
+        int argc = type().parameterCount();
+        if (argc != 0) {
+            Class<?> arrayType = type().parameterType(argc-1);
+            if (arrayType.isArray()) {
+                return MethodHandleImpl.makeVarargsCollector(this, arrayType);
+            }
+        }
+        throw member.makeAccessException("cannot make variable arity", null);
+    }
+    /*non-public*/
+    MethodHandle viewAsType(MethodType newType) {
+        // No actual conversions, just a new view of the same method.
+        if (!type.isViewableAs(newType))
+            throw new InternalError();
+        return MethodHandleImpl.makePairwiseConvert(this, newType, 0);
+    }
+
+    // Decoding
+
+    /*non-public*/
+    LambdaForm internalForm() {
+        return form;
+    }
 
     /*non-public*/
-    String debugString() {
-        return getNameString(this);
+    MemberName internalMemberName() {
+        return null;  // DMH returns DMH.member
+    }
+
+    /*non-public*/
+    Object internalValues() {
+        return null;
+    }
+
+    /*non-public*/
+    Object internalProperties() {
+        // Override to something like "/FOO=bar"
+        return "";
+    }
+
+    //// Method handle implementation methods.
+    //// Sub-classes can override these default implementations.
+    //// All these methods assume arguments are already validated.
+
+    /*non-public*/ MethodHandle convertArguments(MethodType newType) {
+        // Override this if it can be improved.
+        return MethodHandleImpl.makePairwiseConvert(this, newType, 1);
+    }
+
+    /*non-public*/
+    MethodHandle bindArgument(int pos, char basicType, Object value) {
+        // Override this if it can be improved.
+        return rebind().bindArgument(pos, basicType, value);
+    }
+
+    /*non-public*/
+    MethodHandle bindReceiver(Object receiver) {
+        // Override this if it can be improved.
+        return bindArgument(0, 'L', receiver);
+    }
+
+    /*non-public*/
+    MethodHandle bindImmediate(int pos, char basicType, Object value) {
+        // Bind an immediate value to a position in the arguments.
+        // This means, elide the respective argument,
+        // and replace all references to it in NamedFunction args with the specified value.
+
+        // CURRENT RESTRICTIONS
+        // * only for pos 0 and UNSAFE (position is adjusted in MHImpl to make API usable for others)
+        assert pos == 0 && basicType == 'L' && value instanceof Unsafe;
+        MethodType type2 = type.dropParameterTypes(pos, pos + 1); // adjustment: ignore receiver!
+        LambdaForm form2 = form.bindImmediate(pos + 1, basicType, value); // adjust pos to form-relative pos
+        return copyWith(type2, form2);
+    }
+
+    /*non-public*/
+    MethodHandle copyWith(MethodType mt, LambdaForm lf) {
+        throw new InternalError("copyWith: " + this.getClass());
+    }
+
+    /*non-public*/
+    MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
+        // Override this if it can be improved.
+        return rebind().dropArguments(srcType, pos, drops);
+    }
+
+    /*non-public*/
+    MethodHandle permuteArguments(MethodType newType, int[] reorder) {
+        // Override this if it can be improved.
+        return rebind().permuteArguments(newType, reorder);
+    }
+
+    /*non-public*/
+    MethodHandle rebind() {
+        // Bind 'this' into a new invoker, of the known class BMH.
+        MethodType type2 = type();
+        LambdaForm form2 = reinvokerForm(type2.basicType());
+        // form2 = lambda (bmh, arg*) { thismh = bmh[0]; invokeBasic(thismh, arg*) }
+        return BoundMethodHandle.bindSingle(type2, form2, this);
+    }
+
+    /*non-public*/
+    MethodHandle reinvokerTarget() {
+        throw new InternalError("not a reinvoker MH: "+this.getClass().getName()+": "+this);
+    }
+
+    /** Create a LF which simply reinvokes a target of the given basic type.
+     *  The target MH must override {@link #reinvokerTarget} to provide the target.
+     */
+    static LambdaForm reinvokerForm(MethodType mtype) {
+        mtype = mtype.basicType();
+        LambdaForm reinvoker = mtype.form().cachedLambdaForm(MethodTypeForm.LF_REINVOKE);
+        if (reinvoker != null)  return reinvoker;
+        MethodHandle MH_invokeBasic = MethodHandles.basicInvoker(mtype);
+        final int THIS_BMH    = 0;
+        final int ARG_BASE    = 1;
+        final int ARG_LIMIT   = ARG_BASE + mtype.parameterCount();
+        int nameCursor = ARG_LIMIT;
+        final int NEXT_MH     = nameCursor++;
+        final int REINVOKE    = nameCursor++;
+        LambdaForm.Name[] names = LambdaForm.arguments(nameCursor - ARG_LIMIT, mtype.invokerType());
+        names[NEXT_MH] = new LambdaForm.Name(NF_reinvokerTarget, names[THIS_BMH]);
+        Object[] targetArgs = Arrays.copyOfRange(names, THIS_BMH, ARG_LIMIT, Object[].class);
+        targetArgs[0] = names[NEXT_MH];  // overwrite this MH with next MH
+        names[REINVOKE] = new LambdaForm.Name(MH_invokeBasic, targetArgs);
+        return mtype.form().setCachedLambdaForm(MethodTypeForm.LF_REINVOKE, new LambdaForm("BMH.reinvoke", ARG_LIMIT, names));
+    }
+
+    private static final LambdaForm.NamedFunction NF_reinvokerTarget;
+    static {
+        try {
+            NF_reinvokerTarget = new LambdaForm.NamedFunction(MethodHandle.class
+                .getDeclaredMethod("reinvokerTarget"));
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+    }
+
+    /**
+     * Replace the old lambda form of this method handle with a new one.
+     * The new one must be functionally equivalent to the old one.
+     * Threads may continue running the old form indefinitely,
+     * but it is likely that the new one will be preferred for new executions.
+     * Use with discretion.
+     * @param newForm
+     */
+    /*non-public*/
+    void updateForm(LambdaForm newForm) {
+        if (form == newForm)  return;
+        // ISSUE: Should we have a memory fence here?
+        UNSAFE.putObject(this, FORM_OFFSET, newForm);
+        this.form.prepare();  // as in MethodHandle.<init>
+    }
+
+    private static final long FORM_OFFSET;
+    static {
+        try {
+            FORM_OFFSET = UNSAFE.objectFieldOffset(MethodHandle.class.getDeclaredField("form"));
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
     }
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
index aeb1b67..2c061be 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleImpl.java
@@ -29,14 +29,13 @@
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.HashMap;
-import java.util.List;
 import sun.invoke.empty.Empty;
 import sun.invoke.util.ValueConversions;
 import sun.invoke.util.VerifyType;
 import sun.invoke.util.Wrapper;
 import sun.misc.Unsafe;
+import static java.lang.invoke.LambdaForm.*;
 import static java.lang.invoke.MethodHandleStatics.*;
 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
 
@@ -47,992 +46,496 @@
 /*non-public*/ abstract class MethodHandleImpl {
     /// Factory methods to create method handles:
 
-    private static final MemberName.Factory LOOKUP = MemberName.Factory.INSTANCE;
-
     static void initStatics() {
-        // Trigger preceding sequence.
+        // Trigger selected static initializations.
+        MemberName.Factory.INSTANCE.getClass();
     }
 
-    /** Look up a given method.
-     * Callable only from sun.invoke and related packages.
-     * <p>
-     * The resulting method handle type will be of the given type,
-     * with a receiver type {@code rcvc} prepended if the member is not static.
-     * <p>
-     * Access checks are made as of the given lookup class.
-     * In particular, if the method is protected and {@code defc} is in a
-     * different package from the lookup class, then {@code rcvc} must be
-     * the lookup class or a subclass.
-     * @param token Proof that the lookup class has access to this package.
-     * @param member Resolved method or constructor to call.
-     * @param name Name of the desired method.
-     * @param rcvc Receiver type of desired non-static method (else null)
-     * @param doDispatch whether the method handle will test the receiver type
-     * @param lookupClass access-check relative to this class
-     * @return a direct handle to the matching method
-     * @throws IllegalAccessException if the given method cannot be accessed by the lookup class
-     */
-    static
-    MethodHandle findMethod(MemberName method,
-                            boolean doDispatch, Class<?> lookupClass) throws IllegalAccessException {
-        MethodType mtype = method.getMethodType();
-        if (!method.isStatic()) {
-            // adjust the advertised receiver type to be exactly the one requested
-            // (in the case of invokespecial, this will be the calling class)
-            Class<?> recvType = method.getDeclaringClass();
-            mtype = mtype.insertParameterTypes(0, recvType);
+    static MethodHandle makeArrayElementAccessor(Class<?> arrayClass, boolean isSetter) {
+        if (!arrayClass.isArray())
+            throw newIllegalArgumentException("not an array: "+arrayClass);
+        MethodHandle accessor = ArrayAccessor.getAccessor(arrayClass, isSetter);
+        MethodType srcType = accessor.type().erase();
+        MethodType lambdaType = srcType.invokerType();
+        Name[] names = arguments(1, lambdaType);
+        Name[] args  = Arrays.copyOfRange(names, 1, 1 + srcType.parameterCount());
+        names[names.length - 1] = new Name(accessor.asType(srcType), (Object[]) args);
+        LambdaForm form = new LambdaForm("getElement", lambdaType.parameterCount(), names);
+        MethodHandle mh = SimpleMethodHandle.make(srcType, form);
+        if (ArrayAccessor.needCast(arrayClass)) {
+            mh = mh.bindTo(arrayClass);
         }
-        DirectMethodHandle mh = new DirectMethodHandle(mtype, method, doDispatch, lookupClass);
-        if (!mh.isValid())
-            throw method.makeAccessException("no direct method handle", lookupClass);
-        assert(mh.type() == mtype);
-        if (!method.isVarargs())
-            return mh;
-        int argc = mtype.parameterCount();
-        if (argc != 0) {
-            Class<?> arrayType = mtype.parameterType(argc-1);
-            if (arrayType.isArray())
-                return AdapterMethodHandle.makeVarargsCollector(mh, arrayType);
-        }
-        throw method.makeAccessException("cannot make variable arity", null);
-    }
-
-    static
-    MethodHandle makeAllocator(MethodHandle rawConstructor) {
-        MethodType rawConType = rawConstructor.type();
-        Class<?> allocateClass = rawConType.parameterType(0);
-        // Wrap the raw (unsafe) constructor with the allocation of a suitable object.
-        if (AdapterMethodHandle.canCollectArguments(rawConType, MethodType.methodType(allocateClass), 0, true)) {
-            // allocator(arg...)
-            // [fold]=> cookedConstructor(obj=allocate(C), arg...)
-            // [dup,collect]=> identity(obj, void=rawConstructor(obj, arg...))
-            MethodHandle returner = MethodHandles.identity(allocateClass);
-            MethodType ctype = rawConType.insertParameterTypes(0, allocateClass).changeReturnType(allocateClass);
-            MethodHandle  cookedConstructor = AdapterMethodHandle.makeCollectArguments(returner, rawConstructor, 1, false);
-            assert(cookedConstructor.type().equals(ctype));
-            ctype = ctype.dropParameterTypes(0, 1);
-            cookedConstructor = AdapterMethodHandle.makeCollectArguments(cookedConstructor, returner, 0, true);
-            MethodHandle allocator = new AllocateObject(allocateClass);
-            // allocate() => new C(void)
-            assert(allocator.type().equals(MethodType.methodType(allocateClass)));
-            ctype = ctype.dropParameterTypes(0, 1);
-            MethodHandle fold = foldArguments(cookedConstructor, ctype, 0, allocator);
-            return fold;
-        }
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-        MethodHandle allocator
-            = AllocateObject.make(allocateClass, rawConstructor);
-        assert(allocator.type()
-               .equals(rawConType.dropParameterTypes(0, 1).changeReturnType(rawConType.parameterType(0))));
-        return allocator;
-    }
-
-    static final class AllocateObject<C> extends BoundMethodHandle {
-        private static final Unsafe unsafe = Unsafe.getUnsafe();
-
-        private final Class<C> allocateClass;
-        private final MethodHandle rawConstructor;
-
-        private AllocateObject(MethodHandle invoker,
-                               Class<C> allocateClass, MethodHandle rawConstructor) {
-            super(invoker);
-            this.allocateClass = allocateClass;
-            this.rawConstructor = rawConstructor;
-            assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-        }
-        // for allocation only:
-        private AllocateObject(Class<C> allocateClass) {
-            super(ALLOCATE.asType(MethodType.methodType(allocateClass, AllocateObject.class)));
-            this.allocateClass = allocateClass;
-            this.rawConstructor = null;
-        }
-        static MethodHandle make(Class<?> allocateClass, MethodHandle rawConstructor) {
-            assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-            MethodType rawConType = rawConstructor.type();
-            assert(rawConType.parameterType(0) == allocateClass);
-            MethodType newType = rawConType.dropParameterTypes(0, 1).changeReturnType(allocateClass);
-            int nargs = rawConType.parameterCount() - 1;
-            if (nargs < INVOKES.length) {
-                MethodHandle invoke = INVOKES[nargs];
-                MethodType conType = CON_TYPES[nargs];
-                MethodHandle gcon = convertArguments(rawConstructor, conType, rawConType, 0);
-                if (gcon == null)  return null;
-                MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
-                assert(galloc.type() == newType.generic());
-                return convertArguments(galloc, newType, galloc.type(), 0);
-            } else {
-                MethodHandle invoke = VARARGS_INVOKE;
-                MethodType conType = CON_TYPES[nargs];
-                MethodHandle gcon = spreadArgumentsFromPos(rawConstructor, conType, 1);
-                if (gcon == null)  return null;
-                MethodHandle galloc = new AllocateObject(invoke, allocateClass, gcon);
-                return collectArguments(galloc, newType, 1, null);
-            }
-        }
-        @Override
-        String debugString() {
-            return addTypeString(allocateClass.getSimpleName(), this);
-        }
-        @SuppressWarnings("unchecked")
-        private C allocate() throws InstantiationException {
-            return (C) unsafe.allocateInstance(allocateClass);
-        }
-        private C invoke_V(Object... av) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, av);
-            return obj;
-        }
-        private C invoke_L0() throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj);
-            return obj;
-        }
-        private C invoke_L1(Object a0) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, a0);
-            return obj;
-        }
-        private C invoke_L2(Object a0, Object a1) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, a0, a1);
-            return obj;
-        }
-        private C invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, a0, a1, a2);
-            return obj;
-        }
-        private C invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3);
-            return obj;
-        }
-        private C invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4);
-            return obj;
-        }
-        private C invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5);
-            return obj;
-        }
-        private C invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5, a6);
-            return obj;
-        }
-        private C invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            C obj = allocate();
-            rawConstructor.invokeExact((Object)obj, a0, a1, a2, a3, a4, a5, a6, a7);
-            return obj;
-        }
-        static MethodHandle[] makeInvokes() {
-            ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>();
-            MethodHandles.Lookup lookup = IMPL_LOOKUP;
-            for (;;) {
-                int nargs = invokes.size();
-                String name = "invoke_L"+nargs;
-                MethodHandle invoke = null;
-                try {
-                    invoke = lookup.findVirtual(AllocateObject.class, name, MethodType.genericMethodType(nargs));
-                } catch (ReflectiveOperationException ex) {
-                }
-                if (invoke == null)  break;
-                invokes.add(invoke);
-            }
-            assert(invokes.size() == 9);  // current number of methods
-            return invokes.toArray(new MethodHandle[0]);
-        };
-        static final MethodHandle[] INVOKES = makeInvokes();
-        // For testing use this:
-        //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
-        static final MethodHandle VARARGS_INVOKE;
-        static final MethodHandle ALLOCATE;
-        static {
-            try {
-                VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "invoke_V", MethodType.genericMethodType(0, true));
-                ALLOCATE = IMPL_LOOKUP.findVirtual(AllocateObject.class, "allocate", MethodType.genericMethodType(0));
-            } catch (ReflectiveOperationException ex) {
-                throw uncaughtException(ex);
-            }
-        }
-        // Corresponding generic constructor types:
-        static final MethodType[] CON_TYPES = new MethodType[INVOKES.length];
-        static {
-            for (int i = 0; i < INVOKES.length; i++)
-                CON_TYPES[i] = makeConType(INVOKES[i]);
-        }
-        static final MethodType VARARGS_CON_TYPE = makeConType(VARARGS_INVOKE);
-        static MethodType makeConType(MethodHandle invoke) {
-            MethodType invType = invoke.type();
-            return invType.changeParameterType(0, Object.class).changeReturnType(void.class);
-        }
-    }
-
-    static
-    MethodHandle accessField(MemberName member, boolean isSetter,
-                             Class<?> lookupClass) {
-        // Use sun. misc.Unsafe to dig up the dirt on the field.
-        MethodHandle mh = new FieldAccessor(member, isSetter);
+        mh = mh.asType(ArrayAccessor.correctType(arrayClass, isSetter));
         return mh;
     }
 
-    static
-    MethodHandle accessArrayElement(Class<?> arrayClass, boolean isSetter) {
-        if (!arrayClass.isArray())
-            throw newIllegalArgumentException("not an array: "+arrayClass);
-        Class<?> elemClass = arrayClass.getComponentType();
-        MethodHandle[] mhs = FieldAccessor.ARRAY_CACHE.get(elemClass);
-        if (mhs == null) {
-            if (!FieldAccessor.doCache(elemClass))
-                return FieldAccessor.ahandle(arrayClass, isSetter);
-            mhs = new MethodHandle[] {
-                FieldAccessor.ahandle(arrayClass, false),
-                FieldAccessor.ahandle(arrayClass, true)
-            };
-            if (mhs[0].type().parameterType(0) == Class.class) {
-                mhs[0] = mhs[0].bindTo(elemClass);
-                mhs[1] = mhs[1].bindTo(elemClass);
-            }
-            synchronized (FieldAccessor.ARRAY_CACHE) {}  // memory barrier
-            FieldAccessor.ARRAY_CACHE.put(elemClass, mhs);
-        }
-        return mhs[isSetter ? 1 : 0];
-    }
-
-    static final class FieldAccessor<C,V> extends BoundMethodHandle {
-        private static final Unsafe unsafe = Unsafe.getUnsafe();
-        final Object base;  // for static refs only
-        final long offset;
-        final String name;
-
-        FieldAccessor(MemberName field, boolean isSetter) {
-            super(fhandle(field.getDeclaringClass(), field.getFieldType(), isSetter, field.isStatic()));
-            this.offset = (long) field.getVMIndex();
-            this.name = field.getName();
-            this.base = staticBase(field);
-        }
-        @Override
-        String debugString() { return addTypeString(name, this); }
-
-        int getFieldI(C obj) { return unsafe.getInt(obj, offset); }
-        void setFieldI(C obj, int x) { unsafe.putInt(obj, offset, x); }
-        long getFieldJ(C obj) { return unsafe.getLong(obj, offset); }
-        void setFieldJ(C obj, long x) { unsafe.putLong(obj, offset, x); }
-        float getFieldF(C obj) { return unsafe.getFloat(obj, offset); }
-        void setFieldF(C obj, float x) { unsafe.putFloat(obj, offset, x); }
-        double getFieldD(C obj) { return unsafe.getDouble(obj, offset); }
-        void setFieldD(C obj, double x) { unsafe.putDouble(obj, offset, x); }
-        boolean getFieldZ(C obj) { return unsafe.getBoolean(obj, offset); }
-        void setFieldZ(C obj, boolean x) { unsafe.putBoolean(obj, offset, x); }
-        byte getFieldB(C obj) { return unsafe.getByte(obj, offset); }
-        void setFieldB(C obj, byte x) { unsafe.putByte(obj, offset, x); }
-        short getFieldS(C obj) { return unsafe.getShort(obj, offset); }
-        void setFieldS(C obj, short x) { unsafe.putShort(obj, offset, x); }
-        char getFieldC(C obj) { return unsafe.getChar(obj, offset); }
-        void setFieldC(C obj, char x) { unsafe.putChar(obj, offset, x); }
-        @SuppressWarnings("unchecked")
-        V getFieldL(C obj) { return (V) unsafe.getObject(obj, offset); }
-        @SuppressWarnings("unchecked")
-        void setFieldL(C obj, V x) { unsafe.putObject(obj, offset, x); }
-        // cast (V) is OK here, since we wrap convertArguments around the MH.
-
-        static Object staticBase(final MemberName field) {
-            if (!field.isStatic())  return null;
-            return AccessController.doPrivileged(new PrivilegedAction<Object>() {
-                    public Object run() {
-                        try {
-                            Class c = field.getDeclaringClass();
-                            // FIXME:  Should not have to create 'f' to get this value.
-                            java.lang.reflect.Field f = c.getDeclaredField(field.getName());
-                            return unsafe.staticFieldBase(f);
-                        } catch (NoSuchFieldException ee) {
-                            throw uncaughtException(ee);
-                        }
-                    }
-                });
-        }
-
-        int getStaticI() { return unsafe.getInt(base, offset); }
-        void setStaticI(int x) { unsafe.putInt(base, offset, x); }
-        long getStaticJ() { return unsafe.getLong(base, offset); }
-        void setStaticJ(long x) { unsafe.putLong(base, offset, x); }
-        float getStaticF() { return unsafe.getFloat(base, offset); }
-        void setStaticF(float x) { unsafe.putFloat(base, offset, x); }
-        double getStaticD() { return unsafe.getDouble(base, offset); }
-        void setStaticD(double x) { unsafe.putDouble(base, offset, x); }
-        boolean getStaticZ() { return unsafe.getBoolean(base, offset); }
-        void setStaticZ(boolean x) { unsafe.putBoolean(base, offset, x); }
-        byte getStaticB() { return unsafe.getByte(base, offset); }
-        void setStaticB(byte x) { unsafe.putByte(base, offset, x); }
-        short getStaticS() { return unsafe.getShort(base, offset); }
-        void setStaticS(short x) { unsafe.putShort(base, offset, x); }
-        char getStaticC() { return unsafe.getChar(base, offset); }
-        void setStaticC(char x) { unsafe.putChar(base, offset, x); }
-        V getStaticL() { return (V) unsafe.getObject(base, offset); }
-        void setStaticL(V x) { unsafe.putObject(base, offset, x); }
-
-        static String fname(Class<?> vclass, boolean isSetter, boolean isStatic) {
-            String stem;
-            if (!isStatic)
-                stem = (!isSetter ? "getField" : "setField");
-            else
-                stem = (!isSetter ? "getStatic" : "setStatic");
-            return stem + Wrapper.basicTypeChar(vclass);
-        }
-        static MethodType ftype(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) {
-            MethodType type;
-            if (!isStatic) {
-                if (!isSetter)
-                    return MethodType.methodType(vclass, cclass);
-                else
-                    return MethodType.methodType(void.class, cclass, vclass);
-            } else {
-                if (!isSetter)
-                    return MethodType.methodType(vclass);
-                else
-                    return MethodType.methodType(void.class, vclass);
-            }
-        }
-        static MethodHandle fhandle(Class<?> cclass, Class<?> vclass, boolean isSetter, boolean isStatic) {
-            String name = FieldAccessor.fname(vclass, isSetter, isStatic);
-            if (cclass.isPrimitive())  throw newIllegalArgumentException("primitive "+cclass);
-            Class<?> ecclass = Object.class;  //erase this type
-            Class<?> evclass = vclass;
-            if (!evclass.isPrimitive())  evclass = Object.class;
-            MethodType type = FieldAccessor.ftype(ecclass, evclass, isSetter, isStatic);
-            MethodHandle mh;
-            try {
-                mh = IMPL_LOOKUP.findVirtual(FieldAccessor.class, name, type);
-            } catch (ReflectiveOperationException ex) {
-                throw uncaughtException(ex);
-            }
-            if (evclass != vclass || (!isStatic && ecclass != cclass)) {
-                MethodType strongType = FieldAccessor.ftype(cclass, vclass, isSetter, isStatic);
-                strongType = strongType.insertParameterTypes(0, FieldAccessor.class);
-                mh = convertArguments(mh, strongType, 0);
-            }
-            return mh;
-        }
-
+    static final class ArrayAccessor {
         /// Support for array element access
-        static final HashMap<Class<?>, MethodHandle[]> ARRAY_CACHE =
-                new HashMap<Class<?>, MethodHandle[]>();
-        // FIXME: Cache on the classes themselves, not here.
-        static boolean doCache(Class<?> elemClass) {
-            if (elemClass.isPrimitive())  return true;
-            ClassLoader cl = elemClass.getClassLoader();
-            return cl == null || cl == ClassLoader.getSystemClassLoader();
-        }
-        static int getElementI(int[] a, int i) { return a[i]; }
-        static void setElementI(int[] a, int i, int x) { a[i] = x; }
-        static long getElementJ(long[] a, int i) { return a[i]; }
-        static void setElementJ(long[] a, int i, long x) { a[i] = x; }
-        static float getElementF(float[] a, int i) { return a[i]; }
-        static void setElementF(float[] a, int i, float x) { a[i] = x; }
-        static double getElementD(double[] a, int i) { return a[i]; }
-        static void setElementD(double[] a, int i, double x) { a[i] = x; }
-        static boolean getElementZ(boolean[] a, int i) { return a[i]; }
-        static void setElementZ(boolean[] a, int i, boolean x) { a[i] = x; }
-        static byte getElementB(byte[] a, int i) { return a[i]; }
-        static void setElementB(byte[] a, int i, byte x) { a[i] = x; }
-        static short getElementS(short[] a, int i) { return a[i]; }
-        static void setElementS(short[] a, int i, short x) { a[i] = x; }
-        static char getElementC(char[] a, int i) { return a[i]; }
-        static void setElementC(char[] a, int i, char x) { a[i] = x; }
-        static Object getElementL(Object[] a, int i) { return a[i]; }
-        static void setElementL(Object[] a, int i, Object x) { a[i] = x; }
-        static <V> V getElementL(Class<V[]> aclass, V[] a, int i) { return aclass.cast(a)[i]; }
-        static <V> void setElementL(Class<V[]> aclass, V[] a, int i, V x) { aclass.cast(a)[i] = x; }
+        static final HashMap<Class<?>, MethodHandle> GETTER_CACHE = new HashMap<>();  // TODO use it
+        static final HashMap<Class<?>, MethodHandle> SETTER_CACHE = new HashMap<>();  // TODO use it
 
-        static String aname(Class<?> aclass, boolean isSetter) {
-            Class<?> vclass = aclass.getComponentType();
-            if (vclass == null)  throw new IllegalArgumentException();
-            return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(vclass);
+        static int     getElementI(int[]     a, int i)            { return              a[i]; }
+        static long    getElementJ(long[]    a, int i)            { return              a[i]; }
+        static float   getElementF(float[]   a, int i)            { return              a[i]; }
+        static double  getElementD(double[]  a, int i)            { return              a[i]; }
+        static boolean getElementZ(boolean[] a, int i)            { return              a[i]; }
+        static byte    getElementB(byte[]    a, int i)            { return              a[i]; }
+        static short   getElementS(short[]   a, int i)            { return              a[i]; }
+        static char    getElementC(char[]    a, int i)            { return              a[i]; }
+        static Object  getElementL(Object[]  a, int i)            { return              a[i]; }
+
+        static void    setElementI(int[]     a, int i, int     x) {              a[i] = x; }
+        static void    setElementJ(long[]    a, int i, long    x) {              a[i] = x; }
+        static void    setElementF(float[]   a, int i, float   x) {              a[i] = x; }
+        static void    setElementD(double[]  a, int i, double  x) {              a[i] = x; }
+        static void    setElementZ(boolean[] a, int i, boolean x) {              a[i] = x; }
+        static void    setElementB(byte[]    a, int i, byte    x) {              a[i] = x; }
+        static void    setElementS(short[]   a, int i, short   x) {              a[i] = x; }
+        static void    setElementC(char[]    a, int i, char    x) {              a[i] = x; }
+        static void    setElementL(Object[]  a, int i, Object  x) {              a[i] = x; }
+
+        static Object  getElementL(Class<?> arrayClass, Object[] a, int i)           { arrayClass.cast(a); return a[i]; }
+        static void    setElementL(Class<?> arrayClass, Object[] a, int i, Object x) { arrayClass.cast(a); a[i] = x; }
+
+        // Weakly typed wrappers of Object[] accessors:
+        static Object  getElementL(Object    a, int i)            { return getElementL((Object[])a, i); }
+        static void    setElementL(Object    a, int i, Object  x) {        setElementL((Object[]) a, i, x); }
+        static Object  getElementL(Object   arrayClass, Object a, int i)             { return getElementL((Class<?>) arrayClass, (Object[])a, i); }
+        static void    setElementL(Object   arrayClass, Object a, int i, Object x)   {        setElementL((Class<?>) arrayClass, (Object[])a, i, x); }
+
+        static boolean needCast(Class<?> arrayClass) {
+            Class<?> elemClass = arrayClass.getComponentType();
+            return !elemClass.isPrimitive() && elemClass != Object.class;
         }
-        static MethodType atype(Class<?> aclass, boolean isSetter) {
-            Class<?> vclass = aclass.getComponentType();
-            if (!isSetter)
-                return MethodType.methodType(vclass, aclass, int.class);
-            else
-                return MethodType.methodType(void.class, aclass, int.class, vclass);
+        static String name(Class<?> arrayClass, boolean isSetter) {
+            Class<?> elemClass = arrayClass.getComponentType();
+            if (elemClass == null)  throw new IllegalArgumentException();
+            return (!isSetter ? "getElement" : "setElement") + Wrapper.basicTypeChar(elemClass);
         }
-        static MethodHandle ahandle(Class<?> aclass, boolean isSetter) {
-            Class<?> vclass = aclass.getComponentType();
-            String name = FieldAccessor.aname(aclass, isSetter);
-            Class<?> caclass = null;
-            if (!vclass.isPrimitive() && vclass != Object.class) {
-                caclass = aclass;
-                aclass = Object[].class;
-                vclass = Object.class;
+        static final boolean USE_WEAKLY_TYPED_ARRAY_ACCESSORS = false;  // FIXME: decide
+        static MethodType type(Class<?> arrayClass, boolean isSetter) {
+            Class<?> elemClass = arrayClass.getComponentType();
+            Class<?> arrayArgClass = arrayClass;
+            if (!elemClass.isPrimitive()) {
+                arrayArgClass = Object[].class;
+                if (USE_WEAKLY_TYPED_ARRAY_ACCESSORS)
+                    arrayArgClass = Object.class;
             }
-            MethodType type = FieldAccessor.atype(aclass, isSetter);
-            if (caclass != null)
-                type = type.insertParameterTypes(0, Class.class);
-            MethodHandle mh;
+            if (!needCast(arrayClass)) {
+                return !isSetter ?
+                    MethodType.methodType(elemClass,  arrayArgClass, int.class) :
+                    MethodType.methodType(void.class, arrayArgClass, int.class, elemClass);
+            } else {
+                Class<?> classArgClass = Class.class;
+                if (USE_WEAKLY_TYPED_ARRAY_ACCESSORS)
+                    classArgClass = Object.class;
+                return !isSetter ?
+                    MethodType.methodType(Object.class, classArgClass, arrayArgClass, int.class) :
+                    MethodType.methodType(void.class,   classArgClass, arrayArgClass, int.class, Object.class);
+            }
+        }
+        static MethodType correctType(Class<?> arrayClass, boolean isSetter) {
+            Class<?> elemClass = arrayClass.getComponentType();
+            return !isSetter ?
+                    MethodType.methodType(elemClass,  arrayClass, int.class) :
+                    MethodType.methodType(void.class, arrayClass, int.class, elemClass);
+        }
+        static MethodHandle getAccessor(Class<?> arrayClass, boolean isSetter) {
+            String     name = name(arrayClass, isSetter);
+            MethodType type = type(arrayClass, isSetter);
             try {
-                mh = IMPL_LOOKUP.findStatic(FieldAccessor.class, name, type);
+                return IMPL_LOOKUP.findStatic(ArrayAccessor.class, name, type);
             } catch (ReflectiveOperationException ex) {
                 throw uncaughtException(ex);
             }
-            if (caclass != null) {
-                MethodType strongType = FieldAccessor.atype(caclass, isSetter);
-                mh = mh.bindTo(caclass);
-                mh = convertArguments(mh, strongType, 0);
-            }
-            return mh;
         }
     }
 
-    /** Bind a predetermined first argument to the given direct method handle.
-     * Callable only from MethodHandles.
-     * @param token Proof that the caller has access to this package.
-     * @param target Any direct method handle.
-     * @param receiver Receiver (or first static method argument) to pre-bind.
-     * @return a BoundMethodHandle for the given DirectMethodHandle, or null if it does not exist
+    /**
+     * Create a JVM-level adapter method handle to conform the given method
+     * handle to the similar newType, using only pairwise argument conversions.
+     * For each argument, convert incoming argument to the exact type needed.
+     * The argument conversions allowed are casting, boxing and unboxing,
+     * integral widening or narrowing, and floating point widening or narrowing.
+     * @param srcType required call type
+     * @param target original method handle
+     * @param level which strength of conversion is allowed
+     * @return an adapter to the original handle with the desired new type,
+     *          or the original target if the types are already identical
+     *          or null if the adaptation cannot be made
      */
-    static
-    MethodHandle bindReceiver(MethodHandle target, Object receiver) {
-        if (receiver == null)  return null;
-        if (target instanceof AdapterMethodHandle &&
-            ((AdapterMethodHandle)target).conversionOp() == MethodHandleNatives.Constants.OP_RETYPE_ONLY
-            ) {
-            Object info = MethodHandleNatives.getTargetInfo(target);
-            if (info instanceof DirectMethodHandle) {
-                DirectMethodHandle dmh = (DirectMethodHandle) info;
-                if (dmh.type().parameterType(0).isAssignableFrom(receiver.getClass())) {
-                    MethodHandle bmh = new BoundMethodHandle(dmh, receiver, 0);
-                    MethodType newType = target.type().dropParameterTypes(0, 1);
-                    return convertArguments(bmh, newType, bmh.type(), 0);
+    static MethodHandle makePairwiseConvert(MethodHandle target, MethodType srcType, int level) {
+        assert(level >= 0 && level <= 2);
+        MethodType dstType = target.type();
+        assert(dstType.parameterCount() == target.type().parameterCount());
+        if (srcType == dstType)
+            return target;
+
+        // Calculate extra arguments (temporaries) required in the names array.
+        // FIXME: Use an ArrayList<Name>.  Some arguments require more than one conversion step.
+        final int INARG_COUNT = srcType.parameterCount();
+        int conversions = 0;
+        boolean[] needConv = new boolean[1+INARG_COUNT];
+        for (int i = 0; i <= INARG_COUNT; i++) {
+            Class<?> src = (i == INARG_COUNT) ? dstType.returnType() : srcType.parameterType(i);
+            Class<?> dst = (i == INARG_COUNT) ? srcType.returnType() : dstType.parameterType(i);
+            if (!VerifyType.isNullConversion(src, dst) ||
+                level <= 1 && dst.isInterface() && !dst.isAssignableFrom(src)) {
+                needConv[i] = true;
+                conversions++;
+            }
+        }
+        boolean retConv = needConv[INARG_COUNT];
+
+        final int IN_MH         = 0;
+        final int INARG_BASE    = 1;
+        final int INARG_LIMIT   = INARG_BASE + INARG_COUNT;
+        final int NAME_LIMIT    = INARG_LIMIT + conversions + 1;
+        final int RETURN_CONV   = (!retConv ? -1         : NAME_LIMIT - 1);
+        final int OUT_CALL      = (!retConv ? NAME_LIMIT : RETURN_CONV) - 1;
+
+        // Now build a LambdaForm.
+        MethodType lambdaType = srcType.basicType().invokerType();
+        Name[] names = arguments(NAME_LIMIT - INARG_LIMIT, lambdaType);
+
+        // Collect the arguments to the outgoing call, maybe with conversions:
+        final int OUTARG_BASE = 0;  // target MH is Name.function, name Name.arguments[0]
+        Object[] outArgs = new Object[OUTARG_BASE + INARG_COUNT];
+
+        int nameCursor = INARG_LIMIT;
+        for (int i = 0; i < INARG_COUNT; i++) {
+            Class<?> src = srcType.parameterType(i);
+            Class<?> dst = dstType.parameterType(i);
+
+            if (!needConv[i]) {
+                // do nothing: difference is trivial
+                outArgs[OUTARG_BASE + i] = names[INARG_BASE + i];
+                continue;
+            }
+
+            // Tricky case analysis follows.
+            MethodHandle fn = null;
+            if (src.isPrimitive()) {
+                if (dst.isPrimitive()) {
+                    fn = ValueConversions.convertPrimitive(src, dst);
+                } else {
+                    Wrapper w = Wrapper.forPrimitiveType(src);
+                    MethodHandle boxMethod = ValueConversions.box(w);
+                    if (dst == w.wrapperType())
+                        fn = boxMethod;
+                    else
+                        fn = boxMethod.asType(MethodType.methodType(dst, src));
                 }
-            }
-        }
-        if (target instanceof DirectMethodHandle)
-            return new BoundMethodHandle((DirectMethodHandle)target, receiver, 0);
-        return null;   // let caller try something else
-    }
-
-    /** Bind a predetermined argument to the given arbitrary method handle.
-     * Callable only from MethodHandles.
-     * @param token Proof that the caller has access to this package.
-     * @param target Any method handle.
-     * @param receiver Argument (which can be a boxed primitive) to pre-bind.
-     * @return a suitable BoundMethodHandle
-     */
-    static
-    MethodHandle bindArgument(MethodHandle target, int argnum, Object receiver) {
-        return new BoundMethodHandle(target, receiver, argnum);
-    }
-
-    static MethodHandle permuteArguments(MethodHandle target,
-                                                MethodType newType,
-                                                MethodType oldType,
-                                                int[] permutationOrNull) {
-        assert(oldType.parameterCount() == target.type().parameterCount());
-        int outargs = oldType.parameterCount(), inargs = newType.parameterCount();
-        if (permutationOrNull.length != outargs)
-            throw newIllegalArgumentException("wrong number of arguments in permutation");
-        // Make the individual outgoing argument types match up first.
-        Class<?>[] callTypeArgs = new Class<?>[outargs];
-        for (int i = 0; i < outargs; i++)
-            callTypeArgs[i] = newType.parameterType(permutationOrNull[i]);
-        MethodType callType = MethodType.methodType(oldType.returnType(), callTypeArgs);
-        target = convertArguments(target, callType, oldType, 0);
-        assert(target != null);
-        oldType = target.type();
-        List<Integer> goal = new ArrayList<Integer>();  // i*TOKEN
-        List<Integer> state = new ArrayList<Integer>(); // i*TOKEN
-        List<Integer> drops = new ArrayList<Integer>(); // not tokens
-        List<Integer> dups = new ArrayList<Integer>();  // not tokens
-        final int TOKEN = 10; // to mark items which are symbolic only
-        // state represents the argument values coming into target
-        for (int i = 0; i < outargs; i++) {
-            state.add(permutationOrNull[i] * TOKEN);
-        }
-        // goal represents the desired state
-        for (int i = 0; i < inargs; i++) {
-            if (state.contains(i * TOKEN)) {
-                goal.add(i * TOKEN);
             } else {
-                // adapter must initially drop all unused arguments
-                drops.add(i);
-            }
-        }
-        // detect duplications
-        while (state.size() > goal.size()) {
-            for (int i2 = 0; i2 < state.size(); i2++) {
-                int arg1 = state.get(i2);
-                int i1 = state.indexOf(arg1);
-                if (i1 != i2) {
-                    // found duplicate occurrence at i2
-                    int arg2 = (inargs++) * TOKEN;
-                    state.set(i2, arg2);
-                    dups.add(goal.indexOf(arg1));
-                    goal.add(arg2);
-                }
-            }
-        }
-        assert(state.size() == goal.size());
-        int size = goal.size();
-        while (!state.equals(goal)) {
-            // Look for a maximal sequence of adjacent misplaced arguments,
-            // and try to rotate them into place.
-            int bestRotArg = -10 * TOKEN, bestRotLen = 0;
-            int thisRotArg = -10 * TOKEN, thisRotLen = 0;
-            for (int i = 0; i < size; i++) {
-                int arg = state.get(i);
-                // Does this argument match the current run?
-                if (arg == thisRotArg + TOKEN) {
-                    thisRotArg = arg;
-                    thisRotLen += 1;
-                    if (bestRotLen < thisRotLen) {
-                        bestRotLen = thisRotLen;
-                        bestRotArg = thisRotArg;
+                if (dst.isPrimitive()) {
+                    // Caller has boxed a primitive.  Unbox it for the target.
+                    Wrapper w = Wrapper.forPrimitiveType(dst);
+                    if (level == 0 || VerifyType.isNullConversion(src, w.wrapperType())) {
+                        fn = ValueConversions.unbox(dst);
+                    } else if (src == Object.class || !Wrapper.isWrapperType(src)) {
+                        // Examples:  Object->int, Number->int, Comparable->int; Byte->int, Character->int
+                        // must include additional conversions
+                        // src must be examined at runtime, to detect Byte, Character, etc.
+                        MethodHandle unboxMethod = (level == 1
+                                                    ? ValueConversions.unbox(dst)
+                                                    : ValueConversions.unboxCast(dst));
+                        fn = unboxMethod;
+                    } else {
+                        // Example: Byte->int
+                        // Do this by reformulating the problem to Byte->byte.
+                        Class<?> srcPrim = Wrapper.forWrapperType(src).primitiveType();
+                        MethodHandle unbox = ValueConversions.unbox(srcPrim);
+                        // Compose the two conversions.  FIXME:  should make two Names for this job
+                        fn = unbox.asType(MethodType.methodType(dst, src));
                     }
                 } else {
-                    // The old sequence (if any) stops here.
-                    thisRotLen = 0;
-                    thisRotArg = -10 * TOKEN;
-                    // But maybe a new one starts here also.
-                    int wantArg = goal.get(i);
-                    final int MAX_ARG_ROTATION = AdapterMethodHandle.MAX_ARG_ROTATION;
-                    if (arg != wantArg &&
-                        arg >= wantArg - TOKEN * MAX_ARG_ROTATION &&
-                        arg <= wantArg + TOKEN * MAX_ARG_ROTATION) {
-                        thisRotArg = arg;
-                        thisRotLen = 1;
-                    }
+                    // Simple reference conversion.
+                    // Note:  Do not check for a class hierarchy relation
+                    // between src and dst.  In all cases a 'null' argument
+                    // will pass the cast conversion.
+                    fn = ValueConversions.cast(dst);
                 }
             }
-            if (bestRotLen >= 2) {
-                // Do a rotation if it can improve argument positioning
-                // by at least 2 arguments.  This is not always optimal,
-                // but it seems to catch common cases.
-                int dstEnd = state.indexOf(bestRotArg);
-                int srcEnd = goal.indexOf(bestRotArg);
-                int rotBy = dstEnd - srcEnd;
-                int dstBeg = dstEnd - (bestRotLen - 1);
-                int srcBeg = srcEnd - (bestRotLen - 1);
-                assert((dstEnd | dstBeg | srcEnd | srcBeg) >= 0); // no negs
-                // Make a span which covers both source and destination.
-                int rotBeg = Math.min(dstBeg, srcBeg);
-                int rotEnd = Math.max(dstEnd, srcEnd);
-                int score = 0;
-                for (int i = rotBeg; i <= rotEnd; i++) {
-                    if ((int)state.get(i) != (int)goal.get(i))
-                        score += 1;
-                }
-                List<Integer> rotSpan = state.subList(rotBeg, rotEnd+1);
-                Collections.rotate(rotSpan, -rotBy);  // reverse direction
-                for (int i = rotBeg; i <= rotEnd; i++) {
-                    if ((int)state.get(i) != (int)goal.get(i))
-                        score -= 1;
-                }
-                if (score >= 2) {
-                    // Improved at least two argument positions.  Do it.
-                    List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
-                    Collections.rotate(ptypes.subList(rotBeg, rotEnd+1), -rotBy);
-                    MethodType rotType = MethodType.methodType(oldType.returnType(), ptypes);
-                    MethodHandle nextTarget
-                            = AdapterMethodHandle.makeRotateArguments(rotType, target,
-                                    rotBeg, rotSpan.size(), rotBy);
-                    if (nextTarget != null) {
-                        //System.out.println("Rot: "+rotSpan+" by "+rotBy);
-                        target = nextTarget;
-                        oldType = rotType;
-                        continue;
-                    }
-                }
-                // Else de-rotate, and drop through to the swap-fest.
-                Collections.rotate(rotSpan, rotBy);
-            }
+            Name conv = new Name(fn, names[INARG_BASE + i]);
+            assert(names[nameCursor] == null);
+            names[nameCursor++] = conv;
+            assert(outArgs[OUTARG_BASE + i] == null);
+            outArgs[OUTARG_BASE + i] = conv;
+        }
 
-            // Now swap like the wind!
-            List<Class<?>> ptypes = Arrays.asList(oldType.parameterArray());
-            for (int i = 0; i < size; i++) {
-                // What argument do I want here?
-                int arg = goal.get(i);
-                if (arg != state.get(i)) {
-                    // Where is it now?
-                    int j = state.indexOf(arg);
-                    Collections.swap(ptypes, i, j);
-                    MethodType swapType = MethodType.methodType(oldType.returnType(), ptypes);
-                    target = AdapterMethodHandle.makeSwapArguments(swapType, target, i, j);
-                    if (target == null)  throw newIllegalArgumentException("cannot swap");
-                    assert(target.type() == swapType);
-                    oldType = swapType;
-                    Collections.swap(state, i, j);
-                }
-            }
-            // One pass of swapping must finish the job.
-            assert(state.equals(goal));
-        }
-        while (!dups.isEmpty()) {
-            // Grab a contiguous trailing sequence of dups.
-            int grab = dups.size() - 1;
-            int dupArgPos = dups.get(grab), dupArgCount = 1;
-            while (grab - 1 >= 0) {
-                int dup0 = dups.get(grab - 1);
-                if (dup0 != dupArgPos - 1)  break;
-                dupArgPos -= 1;
-                dupArgCount += 1;
-                grab -= 1;
-            }
-            //if (dupArgCount > 1)  System.out.println("Dup: "+dups.subList(grab, dups.size()));
-            dups.subList(grab, dups.size()).clear();
-            // In the new target type drop that many args from the tail:
-            List<Class<?>> ptypes = oldType.parameterList();
-            ptypes = ptypes.subList(0, ptypes.size() - dupArgCount);
-            MethodType dupType = MethodType.methodType(oldType.returnType(), ptypes);
-            target = AdapterMethodHandle.makeDupArguments(dupType, target, dupArgPos, dupArgCount);
-            if (target == null)
-                throw newIllegalArgumentException("cannot dup");
-            oldType = target.type();
-        }
-        while (!drops.isEmpty()) {
-            // Grab a contiguous initial sequence of drops.
-            int dropArgPos = drops.get(0), dropArgCount = 1;
-            while (dropArgCount < drops.size()) {
-                int drop1 = drops.get(dropArgCount);
-                if (drop1 != dropArgPos + dropArgCount)  break;
-                dropArgCount += 1;
-            }
-            //if (dropArgCount > 1)  System.out.println("Drop: "+drops.subList(0, dropArgCount));
-            drops.subList(0, dropArgCount).clear();
-            List<Class<?>> dropTypes = newType.parameterList()
-                    .subList(dropArgPos, dropArgPos + dropArgCount);
-            MethodType dropType = oldType.insertParameterTypes(dropArgPos, dropTypes);
-            target = AdapterMethodHandle.makeDropArguments(dropType, target, dropArgPos, dropArgCount);
-            if (target == null)  throw newIllegalArgumentException("cannot drop");
-            oldType = target.type();
-        }
-        target = convertArguments(target, newType, oldType, 0);
-        assert(target != null);
-        return target;
-    }
+        // Build argument array for the call.
+        assert(nameCursor == OUT_CALL);
+        names[OUT_CALL] = new Name(target, outArgs);
 
-    /*non-public*/ static
-    MethodHandle convertArguments(MethodHandle target, MethodType newType, int level) {
-        MethodType oldType = target.type();
-        if (oldType.equals(newType))
-            return target;
-        assert(level > 1 || oldType.isConvertibleTo(newType));
-        MethodHandle retFilter = null;
-        Class<?> oldRT = oldType.returnType();
-        Class<?> newRT = newType.returnType();
-        if (!VerifyType.isNullConversion(oldRT, newRT)) {
-            if (oldRT == void.class) {
-                Wrapper wrap = newRT.isPrimitive() ? Wrapper.forPrimitiveType(newRT) : Wrapper.OBJECT;
-                retFilter = ValueConversions.zeroConstantFunction(wrap);
-            } else {
-                retFilter = MethodHandles.identity(newRT);
-                retFilter = convertArguments(retFilter, retFilter.type().changeParameterType(0, oldRT), level);
-            }
-            newType = newType.changeReturnType(oldRT);
-        }
-        MethodHandle res = null;
-        Exception ex = null;
-        try {
-            res = convertArguments(target, newType, oldType, level);
-        } catch (IllegalArgumentException ex1) {
-            ex = ex1;
-        }
-        if (res == null) {
-            WrongMethodTypeException wmt = new WrongMethodTypeException("cannot convert to "+newType+": "+target);
-            wmt.initCause(ex);
-            throw wmt;
-        }
-        if (retFilter != null)
-            res = MethodHandles.filterReturnValue(res, retFilter);
-        return res;
-    }
-
-    static MethodHandle convertArguments(MethodHandle target,
-                                                MethodType newType,
-                                                MethodType oldType,
-                                                int level) {
-        assert(oldType.parameterCount() == target.type().parameterCount());
-        if (newType == oldType)
-            return target;
-        if (oldType.parameterCount() != newType.parameterCount())
-            throw newIllegalArgumentException("mismatched parameter count", oldType, newType);
-        MethodHandle res = AdapterMethodHandle.makePairwiseConvert(newType, target, level);
-        if (res != null)
-            return res;
-        // We can come here in the case of target(int)void => (Object)void,
-        // because the unboxing logic for Object => int is complex.
-        int argc = oldType.parameterCount();
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-        // The JVM can't do it directly, so fill in the gap with a Java adapter.
-        // TO DO: figure out what to put here from case-by-case experience
-        // Use a heavier method:  Convert all the arguments to Object,
-        // then back to the desired types.  We might have to use Java-based
-        // method handles to do this.
-        MethodType objType = MethodType.genericMethodType(argc);
-        MethodHandle objTarget = AdapterMethodHandle.makePairwiseConvert(objType, target, level);
-        if (objTarget == null)
-            objTarget = FromGeneric.make(target);
-        res = AdapterMethodHandle.makePairwiseConvert(newType, objTarget, level);
-        if (res != null)
-            return res;
-        return ToGeneric.make(newType, objTarget);
-    }
-
-    static MethodHandle spreadArguments(MethodHandle target, Class<?> arrayType, int arrayLength) {
-        MethodType oldType = target.type();
-        int nargs = oldType.parameterCount();
-        int keepPosArgs = nargs - arrayLength;
-        MethodType newType = oldType
-                .dropParameterTypes(keepPosArgs, nargs)
-                .insertParameterTypes(keepPosArgs, arrayType);
-        return spreadArguments(target, newType, keepPosArgs, arrayType, arrayLength);
-    }
-    // called internally only
-    static MethodHandle spreadArgumentsFromPos(MethodHandle target, MethodType newType, int spreadArgPos) {
-        int arrayLength = target.type().parameterCount() - spreadArgPos;
-        return spreadArguments(target, newType, spreadArgPos, Object[].class, arrayLength);
-    }
-    static MethodHandle spreadArguments(MethodHandle target,
-                                               MethodType newType,
-                                               int spreadArgPos,
-                                               Class<?> arrayType,
-                                               int arrayLength) {
-        // TO DO: maybe allow the restarg to be Object and implicitly cast to Object[]
-        MethodType oldType = target.type();
-        // spread the last argument of newType to oldType
-        assert(arrayLength == oldType.parameterCount() - spreadArgPos);
-        assert(newType.parameterType(spreadArgPos) == arrayType);
-        return AdapterMethodHandle.makeSpreadArguments(newType, target, arrayType, spreadArgPos, arrayLength);
-    }
-
-    static MethodHandle collectArguments(MethodHandle target,
-                                                int collectArg,
-                                                MethodHandle collector) {
-        MethodType type = target.type();
-        Class<?> collectType = collector.type().returnType();
-        assert(collectType != void.class);  // else use foldArguments
-        if (collectType != type.parameterType(collectArg))
-            target = target.asType(type.changeParameterType(collectArg, collectType));
-        MethodType newType = type
-                .dropParameterTypes(collectArg, collectArg+1)
-                .insertParameterTypes(collectArg, collector.type().parameterArray());
-        return collectArguments(target, newType, collectArg, collector);
-    }
-    static MethodHandle collectArguments(MethodHandle target,
-                                                MethodType newType,
-                                                int collectArg,
-                                                MethodHandle collector) {
-        MethodType oldType = target.type();     // (a...,c)=>r
-        //         newType                      // (a..., b...)=>r
-        MethodType colType = collector.type();  // (b...)=>c
-        //         oldType                      // (a..., b...)=>r
-        assert(newType.parameterCount() == collectArg + colType.parameterCount());
-        assert(oldType.parameterCount() == collectArg + 1);
-        MethodHandle result = null;
-        if (AdapterMethodHandle.canCollectArguments(oldType, colType, collectArg, false)) {
-            result = AdapterMethodHandle.makeCollectArguments(target, collector, collectArg, false);
-        }
-        if (result == null) {
-            assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-            MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, 0);
-            MethodHandle gcollector = convertArguments(collector, colType.generic(), colType, 0);
-            if (gtarget == null || gcollector == null)  return null;
-            MethodHandle gresult = FilterGeneric.makeArgumentCollector(gcollector, gtarget);
-            result = convertArguments(gresult, newType, gresult.type(), 0);
-        }
-        return result;
-    }
-
-    static MethodHandle filterArgument(MethodHandle target,
-                                       int pos,
-                                       MethodHandle filter) {
-        MethodType ttype = target.type();
-        MethodType ftype = filter.type();
-        assert(ftype.parameterCount() == 1);
-        MethodHandle result = null;
-        if (AdapterMethodHandle.canCollectArguments(ttype, ftype, pos, false)) {
-            result = AdapterMethodHandle.makeCollectArguments(target, filter, pos, false);
-            if (result != null)  return result;
-        }
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-        MethodType rtype = ttype.changeParameterType(pos, ftype.parameterType(0));
-        MethodType gttype = ttype.generic();
-        if (ttype != gttype) {
-            target = convertArguments(target, gttype, ttype, 0);
-            ttype = gttype;
-        }
-        MethodType gftype = ftype.generic();
-        if (ftype != gftype) {
-            filter = convertArguments(filter, gftype, ftype, 0);
-            ftype = gftype;
-        }
-        if (ftype == ttype) {
-            // simple unary case
-            result = FilterOneArgument.make(filter, target);
+        if (RETURN_CONV < 0) {
+            assert(OUT_CALL == names.length-1);
         } else {
-            result = FilterGeneric.makeArgumentFilter(pos, filter, target);
-        }
-        if (result.type() != rtype)
-            result = result.asType(rtype);
-        return result;
-    }
-
-    static MethodHandle foldArguments(MethodHandle target,
-                                      MethodType newType,
-                                      int foldPos,
-                                      MethodHandle combiner) {
-        MethodType oldType = target.type();
-        MethodType ctype = combiner.type();
-        if (AdapterMethodHandle.canCollectArguments(oldType, ctype, foldPos, true)) {
-            MethodHandle res = AdapterMethodHandle.makeCollectArguments(target, combiner, foldPos, true);
-            if (res != null)  return res;
-        }
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-        if (foldPos != 0)  return null;
-        MethodHandle gtarget = convertArguments(target, oldType.generic(), oldType, 0);
-        MethodHandle gcombiner = convertArguments(combiner, ctype.generic(), ctype, 0);
-        if (ctype.returnType() == void.class) {
-            gtarget = dropArguments(gtarget, oldType.generic().insertParameterTypes(foldPos, Object.class), foldPos);
-        }
-        if (gtarget == null || gcombiner == null)  return null;
-        MethodHandle gresult = FilterGeneric.makeArgumentFolder(gcombiner, gtarget);
-        return convertArguments(gresult, newType, gresult.type(), 0);
-    }
-
-    static
-    MethodHandle dropArguments(MethodHandle target,
-                               MethodType newType, int argnum) {
-        int drops = newType.parameterCount() - target.type().parameterCount();
-        MethodHandle res = AdapterMethodHandle.makeDropArguments(newType, target, argnum, drops);
-        if (res != null)
-            return res;
-        throw new UnsupportedOperationException("NYI");
-    }
-
-    private static class GuardWithTest extends BoundMethodHandle {
-        private final MethodHandle test, target, fallback;
-        private GuardWithTest(MethodHandle invoker,
-                              MethodHandle test, MethodHandle target, MethodHandle fallback) {
-            super(invoker);
-            this.test = test;
-            this.target = target;
-            this.fallback = fallback;
-        }
-        static boolean preferRicochetFrame(MethodType type) {
-            return true;  // always use RF if available
-        }
-        static MethodHandle make(MethodHandle test, MethodHandle target, MethodHandle fallback) {
-            MethodType type = target.type();
-            int nargs = type.parameterCount();
-            if (nargs < INVOKES.length) {
-                if (preferRicochetFrame(type))
-                    assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-                MethodHandle invoke = INVOKES[nargs];
-                MethodType gtype = type.generic();
-                assert(invoke.type().dropParameterTypes(0,1) == gtype);
-                // Note: convertArguments(...2) avoids interface casts present in convertArguments(...0)
-                MethodHandle gtest = convertArguments(test, gtype.changeReturnType(boolean.class), test.type(), 2);
-                MethodHandle gtarget = convertArguments(target, gtype, type, 2);
-                MethodHandle gfallback = convertArguments(fallback, gtype, type, 2);
-                if (gtest == null || gtarget == null || gfallback == null)  return null;
-                MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback);
-                return convertArguments(gguard, type, gtype, 2);
+            Class<?> needReturn = srcType.returnType();
+            Class<?> haveReturn = dstType.returnType();
+            MethodHandle fn;
+            Object[] arg = { names[OUT_CALL] };
+            if (haveReturn == void.class) {
+                // synthesize a zero value for the given void
+                Object zero = Wrapper.forBasicType(needReturn).zero();
+                fn = MethodHandles.constant(needReturn, zero);
+                arg = new Object[0];  // don't pass names[OUT_CALL] to conversion
             } else {
-                assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this code is deprecated
-                MethodHandle invoke = VARARGS_INVOKE;
-                MethodType gtype = MethodType.genericMethodType(1);
-                assert(invoke.type().dropParameterTypes(0,1) == gtype);
-                MethodHandle gtest = spreadArgumentsFromPos(test, gtype.changeReturnType(boolean.class), 0);
-                MethodHandle gtarget = spreadArgumentsFromPos(target, gtype, 0);
-                MethodHandle gfallback = spreadArgumentsFromPos(fallback, gtype, 0);
-                MethodHandle gguard = new GuardWithTest(invoke, gtest, gtarget, gfallback);
-                if (gtest == null || gtarget == null || gfallback == null)  return null;
-                return collectArguments(gguard, type, 0, null);
+                MethodHandle identity = MethodHandles.identity(needReturn);
+                MethodType needConversion = identity.type().changeParameterType(0, haveReturn);
+                fn = makePairwiseConvert(identity, needConversion, level);
             }
+            assert(names[RETURN_CONV] == null);
+            names[RETURN_CONV] = new Name(fn, arg);
+            assert(RETURN_CONV == names.length-1);
         }
+
+        LambdaForm form = new LambdaForm("convert", lambdaType.parameterCount(), names);
+        return SimpleMethodHandle.make(srcType, form);
+    }
+
+    static MethodHandle makeReferenceIdentity(Class<?> refType) {
+        MethodType lambdaType = MethodType.genericMethodType(1).invokerType();
+        Name[] names = arguments(1, lambdaType);
+        names[names.length - 1] = new Name(ValueConversions.identity(), names[1]);
+        LambdaForm form = new LambdaForm("identity", lambdaType.parameterCount(), names);
+        return SimpleMethodHandle.make(MethodType.methodType(refType, refType), form);
+    }
+
+    static MethodHandle makeVarargsCollector(MethodHandle target, Class<?> arrayType) {
+        MethodType type = target.type();
+        int last = type.parameterCount() - 1;
+        if (type.parameterType(last) != arrayType)
+            target = target.asType(type.changeParameterType(last, arrayType));
+        target = target.asFixedArity();  // make sure this attribute is turned off
+        return new AsVarargsCollector(target, target.type(), arrayType);
+    }
+
+    static class AsVarargsCollector extends MethodHandle {
+        MethodHandle target;
+        final Class<?> arrayType;
+        MethodHandle cache;
+
+        AsVarargsCollector(MethodHandle target, MethodType type, Class<?> arrayType) {
+            super(type, reinvokerForm(type));
+            this.target = target;
+            this.arrayType = arrayType;
+            this.cache = target.asCollector(arrayType, 0);
+        }
+
+        @Override MethodHandle reinvokerTarget() { return target; }
+
         @Override
-        String debugString() {
-            return addTypeString(target, this);
+        public boolean isVarargsCollector() {
+            return true;
         }
-        private Object invoke_V(Object... av) throws Throwable {
-            if ((boolean) test.invokeExact(av))
-                return target.invokeExact(av);
-            return fallback.invokeExact(av);
+
+        @Override
+        public MethodHandle asFixedArity() {
+            return target;
         }
-        private Object invoke_L0() throws Throwable {
-            if ((boolean) test.invokeExact())
-                return target.invokeExact();
-            return fallback.invokeExact();
-        }
-        private Object invoke_L1(Object a0) throws Throwable {
-            if ((boolean) test.invokeExact(a0))
-                return target.invokeExact(a0);
-            return fallback.invokeExact(a0);
-        }
-        private Object invoke_L2(Object a0, Object a1) throws Throwable {
-            if ((boolean) test.invokeExact(a0, a1))
-                return target.invokeExact(a0, a1);
-            return fallback.invokeExact(a0, a1);
-        }
-        private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
-            if ((boolean) test.invokeExact(a0, a1, a2))
-                return target.invokeExact(a0, a1, a2);
-            return fallback.invokeExact(a0, a1, a2);
-        }
-        private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
-            if ((boolean) test.invokeExact(a0, a1, a2, a3))
-                return target.invokeExact(a0, a1, a2, a3);
-            return fallback.invokeExact(a0, a1, a2, a3);
-        }
-        private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
-            if ((boolean) test.invokeExact(a0, a1, a2, a3, a4))
-                return target.invokeExact(a0, a1, a2, a3, a4);
-            return fallback.invokeExact(a0, a1, a2, a3, a4);
-        }
-        private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
-            if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5))
-                return target.invokeExact(a0, a1, a2, a3, a4, a5);
-            return fallback.invokeExact(a0, a1, a2, a3, a4, a5);
-        }
-        private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
-            if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5, a6))
-                return target.invokeExact(a0, a1, a2, a3, a4, a5, a6);
-            return fallback.invokeExact(a0, a1, a2, a3, a4, a5, a6);
-        }
-        private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
-            if ((boolean) test.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7))
-                return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7);
-            return fallback.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7);
-        }
-        static MethodHandle[] makeInvokes() {
-            ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>();
-            MethodHandles.Lookup lookup = IMPL_LOOKUP;
-            for (;;) {
-                int nargs = invokes.size();
-                String name = "invoke_L"+nargs;
-                MethodHandle invoke = null;
-                try {
-                    invoke = lookup.findVirtual(GuardWithTest.class, name, MethodType.genericMethodType(nargs));
-                } catch (ReflectiveOperationException ex) {
-                }
-                if (invoke == null)  break;
-                invokes.add(invoke);
+
+        @Override
+        public MethodHandle asType(MethodType newType) {
+            MethodType type = this.type();
+            int collectArg = type.parameterCount() - 1;
+            int newArity = newType.parameterCount();
+            if (newArity == collectArg+1 &&
+                type.parameterType(collectArg).isAssignableFrom(newType.parameterType(collectArg))) {
+                // if arity and trailing parameter are compatible, do normal thing
+                return asFixedArity().asType(newType);
             }
-            assert(invokes.size() == 9);  // current number of methods
-            return invokes.toArray(new MethodHandle[0]);
-        };
-        static final MethodHandle[] INVOKES = makeInvokes();
-        // For testing use this:
-        //static final MethodHandle[] INVOKES = Arrays.copyOf(makeInvokes(), 2);
-        static final MethodHandle VARARGS_INVOKE;
-        static {
+            // check cache
+            if (cache.type().parameterCount() == newArity)
+                return cache.asType(newType);
+            // build and cache a collector
+            int arrayLength = newArity - collectArg;
+            MethodHandle collector;
             try {
-                VARARGS_INVOKE = IMPL_LOOKUP.findVirtual(GuardWithTest.class, "invoke_V", MethodType.genericMethodType(0, true));
-            } catch (ReflectiveOperationException ex) {
-                throw uncaughtException(ex);
+                collector = asFixedArity().asCollector(arrayType, arrayLength);
+                assert(collector.type().parameterCount() == newArity) : "newArity="+newArity+" but collector="+collector;
+            } catch (IllegalArgumentException ex) {
+                throw new WrongMethodTypeException("cannot build collector", ex);
+            }
+            cache = collector;
+            return collector.asType(newType);
+        }
+
+        @Override
+        MethodHandle setVarargs(MemberName member) {
+            if (member.isVarargs())  return this;
+            return asFixedArity();
+        }
+
+        @Override
+        MethodHandle viewAsType(MethodType newType) {
+            MethodHandle mh = super.viewAsType(newType);
+            // put back the varargs bit:
+            MethodType type = mh.type();
+            int arity = type.parameterCount();
+            return mh.asVarargsCollector(type.parameterType(arity-1));
+        }
+
+        @Override
+        MemberName internalMemberName() {
+            return asFixedArity().internalMemberName();
+        }
+
+
+        @Override
+        MethodHandle bindArgument(int pos, char basicType, Object value) {
+            return asFixedArity().bindArgument(pos, basicType, value);
+        }
+
+        @Override
+        MethodHandle bindReceiver(Object receiver) {
+            return asFixedArity().bindReceiver(receiver);
+        }
+
+        @Override
+        MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
+            return asFixedArity().dropArguments(srcType, pos, drops);
+        }
+
+        @Override
+        MethodHandle permuteArguments(MethodType newType, int[] reorder) {
+            return asFixedArity().permuteArguments(newType, reorder);
+        }
+    }
+
+    /** Factory method:  Spread selected argument. */
+    static MethodHandle makeSpreadArguments(MethodHandle target,
+                                            Class<?> spreadArgType, int spreadArgPos, int spreadArgCount) {
+        MethodType targetType = target.type();
+
+        for (int i = 0; i < spreadArgCount; i++) {
+            Class<?> arg = VerifyType.spreadArgElementType(spreadArgType, i);
+            if (arg == null)  arg = Object.class;
+            targetType = targetType.changeParameterType(spreadArgPos + i, arg);
+        }
+        target = target.asType(targetType);
+
+        MethodType srcType = targetType
+                .replaceParameterTypes(spreadArgPos, spreadArgPos + spreadArgCount, spreadArgType);
+        // Now build a LambdaForm.
+        MethodType lambdaType = srcType.invokerType();
+        Name[] names = arguments(spreadArgCount + 2, lambdaType);
+        int nameCursor = lambdaType.parameterCount();
+        int[] indexes = new int[targetType.parameterCount()];
+
+        for (int i = 0, argIndex = 1; i < targetType.parameterCount() + 1; i++, argIndex++) {
+            Class<?> src = lambdaType.parameterType(i);
+            if (i == spreadArgPos) {
+                // Spread the array.
+                MethodHandle aload = MethodHandles.arrayElementGetter(spreadArgType);
+                Name array = names[argIndex];
+                names[nameCursor++] = new Name(NF_checkSpreadArgument, array, spreadArgCount);
+                for (int j = 0; j < spreadArgCount; i++, j++) {
+                    indexes[i] = nameCursor;
+                    names[nameCursor++] = new Name(aload, array, j);
+                }
+            } else if (i < indexes.length) {
+                indexes[i] = argIndex;
             }
         }
+        assert(nameCursor == names.length-1);  // leave room for the final call
+
+        // Build argument array for the call.
+        Name[] targetArgs = new Name[targetType.parameterCount()];
+        for (int i = 0; i < targetType.parameterCount(); i++) {
+            int idx = indexes[i];
+            targetArgs[i] = names[idx];
+        }
+        names[names.length - 1] = new Name(target, (Object[]) targetArgs);
+
+        LambdaForm form = new LambdaForm("spread", lambdaType.parameterCount(), names);
+        return SimpleMethodHandle.make(srcType, form);
+    }
+
+    static void checkSpreadArgument(Object av, int n) {
+        // FIXME: regression test for bug 7141637 erroneously expects an NPE, and other tests may expect IAE
+        // but the actual exception raised by an arity mismatch should be WMTE
+        final boolean RAISE_RANDOM_EXCEPTIONS = true;  // FIXME: delete in JSR 292 M1
+        if (av == null) {
+            if (n == 0)  return;
+            int len;
+            if (RAISE_RANDOM_EXCEPTIONS)
+                len = ((Object[])av).length;  // throw NPE; but delete this after tests are fixed
+        } else if (av instanceof Object[]) {
+            int len = ((Object[])av).length;
+            if (len == n)  return;
+        } else {
+            int len = java.lang.reflect.Array.getLength(av);
+            if (len == n)  return;
+        }
+        // fall through to error:
+        if (RAISE_RANDOM_EXCEPTIONS)
+            throw newIllegalArgumentException("Array is not of length "+n);
+        throw new WrongMethodTypeException("Array is not of length "+n);
+    }
+
+    private static final NamedFunction NF_checkSpreadArgument;
+    static {
+        try {
+            NF_checkSpreadArgument = new NamedFunction(MethodHandleImpl.class
+                    .getDeclaredMethod("checkSpreadArgument", Object.class, int.class));
+            NF_checkSpreadArgument.resolve();
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+    }
+
+    /** Factory method:  Collect or filter selected argument(s). */
+    static MethodHandle makeCollectArguments(MethodHandle target,
+                MethodHandle collector, int collectArgPos, boolean retainOriginalArgs) {
+        MethodType targetType = target.type();          // (a..., c, [b...])=>r
+        MethodType collectorType = collector.type();    // (b...)=>c
+        int collectArgCount = collectorType.parameterCount();
+        Class<?> collectValType = collectorType.returnType();
+        int collectValCount = (collectValType == void.class ? 0 : 1);
+        MethodType srcType = targetType                 // (a..., [b...])=>r
+                .dropParameterTypes(collectArgPos, collectArgPos+collectValCount);
+        if (!retainOriginalArgs) {                      // (a..., b...)=>r
+            srcType = srcType.insertParameterTypes(collectArgPos, collectorType.parameterList());
+        }
+        // in  arglist: [0: ...keep1 | cpos: collect...  | cpos+cacount: keep2... ]
+        // out arglist: [0: ...keep1 | cpos: collectVal? | cpos+cvcount: keep2... ]
+        // out(retain): [0: ...keep1 | cpos: cV? coll... | cpos+cvc+cac: keep2... ]
+
+        // Now build a LambdaForm.
+        MethodType lambdaType = srcType.invokerType();
+        Name[] names = arguments(2, lambdaType);
+        final int collectNamePos = names.length - 2;
+        final int targetNamePos  = names.length - 1;
+
+        Name[] collectorArgs = Arrays.copyOfRange(names, 1 + collectArgPos, 1 + collectArgPos + collectArgCount);
+        names[collectNamePos] = new Name(collector, (Object[]) collectorArgs);
+
+        // Build argument array for the target.
+        // Incoming LF args to copy are: [ (mh) headArgs collectArgs tailArgs ].
+        // Output argument array is [ headArgs (collectVal)? (collectArgs)? tailArgs ].
+        Name[] targetArgs = new Name[targetType.parameterCount()];
+        int inputArgPos  = 1;  // incoming LF args to copy to target
+        int targetArgPos = 0;  // fill pointer for targetArgs
+        int chunk = collectArgPos;  // |headArgs|
+        System.arraycopy(names, inputArgPos, targetArgs, targetArgPos, chunk);
+        inputArgPos  += chunk;
+        targetArgPos += chunk;
+        if (collectValType != void.class) {
+            targetArgs[targetArgPos++] = names[collectNamePos];
+        }
+        chunk = collectArgCount;
+        if (retainOriginalArgs) {
+            System.arraycopy(names, inputArgPos, targetArgs, targetArgPos, chunk);
+            targetArgPos += chunk;   // optionally pass on the collected chunk
+        }
+        inputArgPos += chunk;
+        chunk = targetArgs.length - targetArgPos;  // all the rest
+        System.arraycopy(names, inputArgPos, targetArgs, targetArgPos, chunk);
+        assert(inputArgPos + chunk == collectNamePos);  // use of rest of input args also
+        names[targetNamePos] = new Name(target, (Object[]) targetArgs);
+
+        LambdaForm form = new LambdaForm("collect", lambdaType.parameterCount(), names);
+        return SimpleMethodHandle.make(srcType, form);
     }
 
     static
@@ -1057,50 +560,42 @@
     MethodHandle makeGuardWithTest(MethodHandle test,
                                    MethodHandle target,
                                    MethodHandle fallback) {
-        // gwt(arg...)
-        // [fold]=> continueAfterTest(z=test(arg...), arg...)
-        // [filter]=> (tf=select(z))(arg...)
-        //    where select(z) = select(z, t, f).bindTo(t, f) => z ? t f
-        // [tailcall]=> tf(arg...)
-        assert(test.type().returnType() == boolean.class);
-        MethodType targetType = target.type();
-        MethodType foldTargetType = targetType.insertParameterTypes(0, boolean.class);
-        if (AdapterMethodHandle.canCollectArguments(foldTargetType, test.type(), 0, true)
-            && GuardWithTest.preferRicochetFrame(targetType)) {
-            // working backwards, as usual:
-            assert(target.type().equals(fallback.type()));
-            MethodHandle tailcall = MethodHandles.exactInvoker(target.type());
-            MethodHandle select = selectAlternative();
-            select = bindArgument(select, 2, CountingMethodHandle.wrap(fallback));
-            select = bindArgument(select, 1, CountingMethodHandle.wrap(target));
-            // select(z: boolean) => (z ? target : fallback)
-            MethodHandle filter = filterArgument(tailcall, 0, select);
-            assert(filter.type().parameterType(0) == boolean.class);
-            MethodHandle fold = foldArguments(filter, filter.type().dropParameterTypes(0, 1), 0, test);
-            return fold;
-        }
-        return GuardWithTest.make(test, target, fallback);
+        MethodType basicType = target.type().basicType();
+        MethodHandle invokeBasic = MethodHandles.basicInvoker(basicType);
+        int arity = basicType.parameterCount();
+        int extraNames = 3;
+        MethodType lambdaType = basicType.invokerType();
+        Name[] names = arguments(extraNames, lambdaType);
+
+        Object[] testArgs   = Arrays.copyOfRange(names, 1, 1 + arity, Object[].class);
+        Object[] targetArgs = Arrays.copyOfRange(names, 0, 1 + arity, Object[].class);
+
+        // call test
+        names[arity + 1] = new Name(test, testArgs);
+
+        // call selectAlternative
+        Object[] selectArgs = { names[arity + 1], target, fallback };
+        names[arity + 2] = new Name(MethodHandleImpl.selectAlternative(), selectArgs);
+        targetArgs[0] = names[arity + 2];
+
+        // call target or fallback
+        names[arity + 3] = new Name(new NamedFunction(invokeBasic), targetArgs);
+
+        LambdaForm form = new LambdaForm("guard", lambdaType.parameterCount(), names);
+        return SimpleMethodHandle.make(target.type(), form);
     }
 
-    private static class GuardWithCatch extends BoundMethodHandle {
+    private static class GuardWithCatch {
         private final MethodHandle target;
         private final Class<? extends Throwable> exType;
         private final MethodHandle catcher;
-        GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
-            this(INVOKES[target.type().parameterCount()], target, exType, catcher);
-        }
         // FIXME: Build the control flow out of foldArguments.
-        GuardWithCatch(MethodHandle invoker,
-                       MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
-            super(invoker);
+        GuardWithCatch(MethodHandle target, Class<? extends Throwable> exType, MethodHandle catcher) {
             this.target = target;
             this.exType = exType;
             this.catcher = catcher;
         }
-        @Override
-        String debugString() {
-            return addTypeString(target, this);
-        }
+        @LambdaForm.Hidden
         private Object invoke_V(Object... av) throws Throwable {
             try {
                 return target.invokeExact(av);
@@ -1109,6 +604,7 @@
                 return catcher.invokeExact(t, av);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L0() throws Throwable {
             try {
                 return target.invokeExact();
@@ -1117,6 +613,7 @@
                 return catcher.invokeExact(t);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L1(Object a0) throws Throwable {
             try {
                 return target.invokeExact(a0);
@@ -1125,6 +622,7 @@
                 return catcher.invokeExact(t, a0);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L2(Object a0, Object a1) throws Throwable {
             try {
                 return target.invokeExact(a0, a1);
@@ -1133,6 +631,7 @@
                 return catcher.invokeExact(t, a0, a1);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L3(Object a0, Object a1, Object a2) throws Throwable {
             try {
                 return target.invokeExact(a0, a1, a2);
@@ -1141,6 +640,7 @@
                 return catcher.invokeExact(t, a0, a1, a2);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L4(Object a0, Object a1, Object a2, Object a3) throws Throwable {
             try {
                 return target.invokeExact(a0, a1, a2, a3);
@@ -1149,6 +649,7 @@
                 return catcher.invokeExact(t, a0, a1, a2, a3);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable {
             try {
                 return target.invokeExact(a0, a1, a2, a3, a4);
@@ -1157,6 +658,7 @@
                 return catcher.invokeExact(t, a0, a1, a2, a3, a4);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable {
             try {
                 return target.invokeExact(a0, a1, a2, a3, a4, a5);
@@ -1165,6 +667,7 @@
                 return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable {
             try {
                 return target.invokeExact(a0, a1, a2, a3, a4, a5, a6);
@@ -1173,6 +676,7 @@
                 return catcher.invokeExact(t, a0, a1, a2, a3, a4, a5, a6);
             }
         }
+        @LambdaForm.Hidden
         private Object invoke_L8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable {
             try {
                 return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7);
@@ -1182,7 +686,7 @@
             }
         }
         static MethodHandle[] makeInvokes() {
-            ArrayList<MethodHandle> invokes = new ArrayList<MethodHandle>();
+            ArrayList<MethodHandle> invokes = new ArrayList<>();
             MethodHandles.Lookup lookup = IMPL_LOOKUP;
             for (;;) {
                 int nargs = invokes.size();
@@ -1223,42 +727,62 @@
             MethodType gtype = type.generic();
             MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
             // Note: convertArguments(...2) avoids interface casts present in convertArguments(...0)
-            MethodHandle gtarget = convertArguments(target, gtype, type, 2);
-            MethodHandle gcatcher = convertArguments(catcher, gcatchType, ctype, 2);
-            MethodHandle gguard = new GuardWithCatch(gtarget, exType, gcatcher);
-            if (gtarget == null || gcatcher == null || gguard == null)  return null;
-            return convertArguments(gguard, type, gtype, 2);
+            MethodHandle gtarget = makePairwiseConvert(target, gtype, 2);
+            MethodHandle gcatcher = makePairwiseConvert(catcher, gcatchType, 2);
+            GuardWithCatch gguard = new GuardWithCatch(gtarget, exType, gcatcher);
+            if (gtarget == null || gcatcher == null)  throw new InternalError();
+            MethodHandle ginvoker = GuardWithCatch.INVOKES[nargs].bindReceiver(gguard);
+            return makePairwiseConvert(ginvoker, type, 2);
         } else {
-            MethodType gtype = MethodType.genericMethodType(0, true);
-            MethodType gcatchType = gtype.insertParameterTypes(0, Throwable.class);
-            MethodHandle gtarget = spreadArgumentsFromPos(target, gtype, 0);
+            MethodHandle gtarget = makeSpreadArguments(target, Object[].class, 0, nargs);
             catcher = catcher.asType(ctype.changeParameterType(0, Throwable.class));
-            MethodHandle gcatcher = spreadArgumentsFromPos(catcher, gcatchType, 1);
-            MethodHandle gguard = new GuardWithCatch(GuardWithCatch.VARARGS_INVOKE, gtarget, exType, gcatcher);
-            if (gtarget == null || gcatcher == null || gguard == null)  return null;
-            return collectArguments(gguard, type, 0, ValueConversions.varargsArray(nargs)).asType(type);
+            MethodHandle gcatcher = makeSpreadArguments(catcher, Object[].class, 1, nargs);
+            GuardWithCatch gguard = new GuardWithCatch(gtarget, exType, gcatcher);
+            if (gtarget == null || gcatcher == null)  throw new InternalError();
+            MethodHandle ginvoker = GuardWithCatch.VARARGS_INVOKE.bindReceiver(gguard);
+            return makeCollectArguments(ginvoker, ValueConversions.varargsArray(nargs), 0, false);
         }
     }
 
     static
     MethodHandle throwException(MethodType type) {
-        return AdapterMethodHandle.makeRetypeRaw(type, throwException());
+        assert(Throwable.class.isAssignableFrom(type.parameterType(0)));
+        int arity = type.parameterCount();
+        if (arity > 1) {
+            return throwException(type.dropParameterTypes(1, arity)).dropArguments(type, 1, arity-1);
+        }
+        return makePairwiseConvert(throwException(), type, 2);
     }
 
     static MethodHandle THROW_EXCEPTION;
     static MethodHandle throwException() {
-        if (THROW_EXCEPTION != null)  return THROW_EXCEPTION;
+        MethodHandle mh = THROW_EXCEPTION;
+        if (mh != null)  return mh;
         try {
-            THROW_EXCEPTION
+            mh
             = IMPL_LOOKUP.findStatic(MethodHandleImpl.class, "throwException",
                     MethodType.methodType(Empty.class, Throwable.class));
         } catch (ReflectiveOperationException ex) {
             throw new RuntimeException(ex);
         }
-        return THROW_EXCEPTION;
+        THROW_EXCEPTION = mh;
+        return mh;
     }
     static <T extends Throwable> Empty throwException(T t) throws T { throw t; }
 
+    static MethodHandle FAKE_METHOD_HANDLE_INVOKE;
+    static
+    MethodHandle fakeMethodHandleInvoke(MemberName method) {
+        MethodType type = method.getInvocationType();
+        assert(type.equals(MethodType.methodType(Object.class, Object[].class)));
+        MethodHandle mh = FAKE_METHOD_HANDLE_INVOKE;
+        if (mh != null)  return mh;
+        mh = throwException(type.insertParameterTypes(0, UnsupportedOperationException.class));
+        mh = mh.bindTo(new UnsupportedOperationException("cannot reflectively invoke MethodHandle"));
+        FAKE_METHOD_HANDLE_INVOKE = mh;
+        return mh;
+    }
+
     /**
      * Create an alias for the method handle which, when called,
      * appears to be called from the same class loader and protection domain
@@ -1305,7 +829,7 @@
                 if (tramp.getClassLoader() == BindCaller.class.getClassLoader())
                     throw new RuntimeException(tramp.getName()+" class loader");
             } catch (Throwable ex) {
-                throw new InternalError(ex.toString());
+                throw newInternalError(ex);
             }
             C_Trampoline = tramp;
         }
@@ -1341,7 +865,7 @@
                 MethodHandle vamh = prepareForInvoker(MH_checkCallerClass);
                 Object ok = bccInvoker.invokeExact(vamh, new Object[]{hostClass, bcc});
             } catch (Throwable ex) {
-                throw new InternalError(ex.toString());
+                throw newInternalError(ex);
             }
             return bccInvoker;
         }
@@ -1357,7 +881,9 @@
             MethodType mt = mh.type();
             int arity = mt.parameterCount();
             MethodHandle vamh = mh.asType(mt.generic());
+            vamh.internalForm().compileToBytecode();  // eliminate LFI stack frames
             vamh = vamh.asSpreader(Object[].class, arity);
+            vamh.internalForm().compileToBytecode();  // eliminate LFI stack frames
             return vamh;
         }
 
@@ -1376,7 +902,7 @@
                                 MethodType.methodType(boolean.class, Class.class, Class.class));
                 assert((boolean) MH_checkCallerClass.invokeExact(THIS_CLASS, THIS_CLASS));
             } catch (Throwable ex) {
-                throw new InternalError(ex.toString());
+                throw newInternalError(ex);
             }
         }
 
@@ -1407,7 +933,7 @@
                             }
                             values[0] = bytes;
                         } catch (java.io.IOException ex) {
-                            throw new InternalError(ex.toString());
+                            throw newInternalError(ex);
                         }
                         return null;
                     }
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java
new file mode 100644
index 0000000..b73dd63
--- /dev/null
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleInfo.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+import java.lang.invoke.MethodHandleNatives.Constants;
+
+//Not yet public: public
+class MethodHandleInfo {
+   public static final int
+       REF_NONE                    = Constants.REF_NONE,
+       REF_getField                = Constants.REF_getField,
+       REF_getStatic               = Constants.REF_getStatic,
+       REF_putField                = Constants.REF_putField,
+       REF_putStatic               = Constants.REF_putStatic,
+       REF_invokeVirtual           = Constants.REF_invokeVirtual,
+       REF_invokeStatic            = Constants.REF_invokeStatic,
+       REF_invokeSpecial           = Constants.REF_invokeSpecial,
+       REF_newInvokeSpecial        = Constants.REF_newInvokeSpecial,
+       REF_invokeInterface         = Constants.REF_invokeInterface;
+
+   private final Class<?> declaringClass;
+   private final String name;
+   private final MethodType methodType;
+   private final int referenceKind;
+
+   public MethodHandleInfo(MethodHandle mh) throws ReflectiveOperationException {
+       MemberName mn = mh.internalMemberName();
+       this.declaringClass = mn.getDeclaringClass();
+       this.name = mn.getName();
+       this.methodType = mn.getMethodType();
+       this.referenceKind = mn.getReferenceKind();
+   }
+
+   public Class<?> getDeclaringClass() {
+       return declaringClass;
+   }
+
+   public String getName() {
+       return name;
+   }
+
+   public MethodType getMethodType() {
+       return methodType;
+   }
+
+   public int getReferenceKind() {
+       return referenceKind;
+   }
+}
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
index c77eeb5..06a9ba2 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleNatives.java
@@ -29,6 +29,7 @@
 import java.lang.reflect.AccessibleObject;
 import java.lang.reflect.Field;
 import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import static java.lang.invoke.MethodHandleStatics.*;
 import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
 
 /**
@@ -41,76 +42,28 @@
 
     private MethodHandleNatives() { } // static only
 
-    /// MethodName support
+    /// MemberName support
 
     static native void init(MemberName self, Object ref);
     static native void expand(MemberName self);
-    static native void resolve(MemberName self, Class<?> caller);
+    static native MemberName resolve(MemberName self, Class<?> caller) throws LinkageError;
     static native int getMembers(Class<?> defc, String matchName, String matchSig,
             int matchFlags, Class<?> caller, int skip, MemberName[] results);
 
+    /// Field layout queries parallel to sun.misc.Unsafe:
+    static native long objectFieldOffset(MemberName self);  // e.g., returns vmindex
+    static native long staticFieldOffset(MemberName self);  // e.g., returns vmindex
+    static native Object staticFieldBase(MemberName self);  // e.g., returns clazz
+    static native Object getMemberVMInfo(MemberName self);  // returns {vmindex,vmtarget}
+
     /// MethodHandle support
 
-    /** Initialize the method handle to adapt the call. */
-    static native void init(AdapterMethodHandle self, MethodHandle target, int argnum);
-    /** Initialize the method handle to call the correct method, directly. */
-    static native void init(BoundMethodHandle self, Object target, int argnum);
-    /** Initialize the method handle to call as if by an invoke* instruction. */
-    static native void init(DirectMethodHandle self, Object ref, boolean doDispatch, Class<?> caller);
-
-    /** Initialize a method type, once per form. */
-    static native void init(MethodType self);
-
-    /** Fetch the vmtarget field.
-     *  It will be sanitized as necessary to avoid exposing non-Java references.
-     *  This routine is for debugging and reflection.
-     */
-    static native Object getTarget(MethodHandle self, int format);
-
-    /** Fetch the name of the handled method, if available.
-     *  This routine is for debugging and reflection.
-     */
-    static MemberName getMethodName(MethodHandle self) {
-        return (MemberName) getTarget(self, ETF_METHOD_NAME);
-    }
-
-    /** Fetch the reflective version of the handled method, if available.
-     */
-    static AccessibleObject getTargetMethod(MethodHandle self) {
-        return (AccessibleObject) getTarget(self, ETF_REFLECT_METHOD);
-    }
-
-    /** Fetch the target of this method handle.
-     *  If it directly targets a method, return a MemberName for the method.
-     *  If it is chained to another method handle, return that handle.
-     */
-    static Object getTargetInfo(MethodHandle self) {
-        return getTarget(self, ETF_HANDLE_OR_METHOD_NAME);
-    }
-
-    static Object[] makeTarget(Class<?> defc, String name, String sig, int mods, Class<?> refc) {
-        return new Object[] { defc, name, sig, mods, refc };
-    }
-
     /** Fetch MH-related JVM parameter.
      *  which=0 retrieves MethodHandlePushLimit
      *  which=1 retrieves stack slot push size (in address units)
      */
     static native int getConstant(int which);
 
-    /** Java copy of MethodHandlePushLimit in range 2..255. */
-    static final int JVM_PUSH_LIMIT;
-    /** JVM stack motion (in words) after one slot is pushed, usually -1.
-     */
-    static final int JVM_STACK_MOVE_UNIT;
-
-    /** Which conv-ops are implemented by the JVM? */
-    static final int CONV_OP_IMPLEMENTED_MASK;
-    /** Derived mode flag.  Only false on some old JVM implementations. */
-    static final boolean HAVE_RICOCHET_FRAMES;
-
-    static final int OP_ROT_ARGS_DOWN_LIMIT_BIAS;
-
     static final boolean COUNT_GWT;
 
     /// CallSite support
@@ -122,17 +75,11 @@
     private static native void registerNatives();
     static {
         registerNatives();
-        int k;
-        JVM_PUSH_LIMIT              = getConstant(Constants.GC_JVM_PUSH_LIMIT);
-        JVM_STACK_MOVE_UNIT         = getConstant(Constants.GC_JVM_STACK_MOVE_UNIT);
-        k                           = getConstant(Constants.GC_CONV_OP_IMPLEMENTED_MASK);
-        CONV_OP_IMPLEMENTED_MASK    = (k != 0) ? k : DEFAULT_CONV_OP_IMPLEMENTED_MASK;
-        k                           = getConstant(Constants.GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS);
-        OP_ROT_ARGS_DOWN_LIMIT_BIAS = (k != 0) ? (byte)k : -1;
-        HAVE_RICOCHET_FRAMES        = (CONV_OP_IMPLEMENTED_MASK & (1<<OP_COLLECT_ARGS)) != 0;
         COUNT_GWT                   = getConstant(Constants.GC_COUNT_GWT) != 0;
-        //sun.reflect.Reflection.registerMethodsToFilter(MethodHandleImpl.class, "init");
-    }
+
+        // The JVM calls MethodHandleNatives.<clinit>.  Cascade the <clinit> calls as needed:
+        MethodHandleImpl.initStatics();
+}
 
     // All compile-time constants go here.
     // There is an opportunity to check them against the JVM's idea of them.
@@ -140,16 +87,8 @@
         Constants() { } // static only
         // MethodHandleImpl
         static final int // for getConstant
-                GC_JVM_PUSH_LIMIT = 0,
-                GC_JVM_STACK_MOVE_UNIT = 1,
-                GC_CONV_OP_IMPLEMENTED_MASK = 2,
-                GC_OP_ROT_ARGS_DOWN_LIMIT_BIAS = 3,
-                GC_COUNT_GWT = 4;
-        static final int
-                ETF_HANDLE_OR_METHOD_NAME = 0, // all available data (immediate MH or method)
-                ETF_DIRECT_HANDLE         = 1, // ultimate method handle (will be a DMH, may be self)
-                ETF_METHOD_NAME           = 2, // ultimate method as MemberName
-                ETF_REFLECT_METHOD        = 3; // ultimate method as java.lang.reflect object (sans refClass)
+                GC_COUNT_GWT = 4,
+                GC_LAMBDA_SUPPORT = 5;
 
         // MemberName
         // The JVM uses values of -2 and above for vtable indexes.
@@ -162,65 +101,11 @@
                 MN_IS_CONSTRUCTOR      = 0x00020000, // constructor
                 MN_IS_FIELD            = 0x00040000, // field
                 MN_IS_TYPE             = 0x00080000, // nested type
-                MN_SEARCH_SUPERCLASSES = 0x00100000, // for MHN.getMembers
-                MN_SEARCH_INTERFACES   = 0x00200000, // for MHN.getMembers
-                VM_INDEX_UNINITIALIZED = -99;
-
-        // BoundMethodHandle
-        /** Constants for decoding the vmargslot field, which contains 2 values. */
-        static final int
-            ARG_SLOT_PUSH_SHIFT = 16,
-            ARG_SLOT_MASK = (1<<ARG_SLOT_PUSH_SHIFT)-1;
-
-        // AdapterMethodHandle
-        /** Conversions recognized by the JVM.
-         *  They must align with the constants in java.lang.invoke.AdapterMethodHandle,
-         *  in the JVM file hotspot/src/share/vm/classfile/javaClasses.hpp.
-         */
-        static final int
-            OP_RETYPE_ONLY   = 0x0, // no argument changes; straight retype
-            OP_RETYPE_RAW    = 0x1, // straight retype, trusted (void->int, Object->T)
-            OP_CHECK_CAST    = 0x2, // ref-to-ref conversion; requires a Class argument
-            OP_PRIM_TO_PRIM  = 0x3, // converts from one primitive to another
-            OP_REF_TO_PRIM   = 0x4, // unboxes a wrapper to produce a primitive
-            OP_PRIM_TO_REF   = 0x5, // boxes a primitive into a wrapper
-            OP_SWAP_ARGS     = 0x6, // swap arguments (vminfo is 2nd arg)
-            OP_ROT_ARGS      = 0x7, // rotate arguments (vminfo is displaced arg)
-            OP_DUP_ARGS      = 0x8, // duplicates one or more arguments (at TOS)
-            OP_DROP_ARGS     = 0x9, // remove one or more argument slots
-            OP_COLLECT_ARGS  = 0xA, // combine arguments using an auxiliary function
-            OP_SPREAD_ARGS   = 0xB, // expand in place a varargs array (of known size)
-            OP_FOLD_ARGS     = 0xC, // combine but do not remove arguments; prepend result
-            //OP_UNUSED_13   = 0xD, // unused code, perhaps for reified argument lists
-            CONV_OP_LIMIT    = 0xE; // limit of CONV_OP enumeration
-        /** Shift and mask values for decoding the AMH.conversion field.
-         *  These numbers are shared with the JVM for creating AMHs.
-         */
-        static final int
-            CONV_OP_MASK     = 0xF00, // this nybble contains the conversion op field
-            CONV_TYPE_MASK   = 0x0F,  // fits T_ADDRESS and below
-            CONV_VMINFO_MASK = 0x0FF, // LSB is reserved for JVM use
-            CONV_VMINFO_SHIFT     =  0, // position of bits in CONV_VMINFO_MASK
-            CONV_OP_SHIFT         =  8, // position of bits in CONV_OP_MASK
-            CONV_DEST_TYPE_SHIFT  = 12, // byte 2 has the adapter BasicType (if needed)
-            CONV_SRC_TYPE_SHIFT   = 16, // byte 2 has the source BasicType (if needed)
-            CONV_STACK_MOVE_SHIFT = 20, // high 12 bits give signed SP change
-            CONV_STACK_MOVE_MASK  = (1 << (32 - CONV_STACK_MOVE_SHIFT)) - 1;
-
-        /** Which conv-ops are implemented by the JVM? */
-        static final int DEFAULT_CONV_OP_IMPLEMENTED_MASK =
-                // Value to use if the corresponding JVM query fails.
-                ((1<<OP_RETYPE_ONLY)
-                |(1<<OP_RETYPE_RAW)
-                |(1<<OP_CHECK_CAST)
-                |(1<<OP_PRIM_TO_PRIM)
-                |(1<<OP_REF_TO_PRIM)
-                |(1<<OP_SWAP_ARGS)
-                |(1<<OP_ROT_ARGS)
-                |(1<<OP_DUP_ARGS)
-                |(1<<OP_DROP_ARGS)
-                //|(1<<OP_SPREAD_ARGS)
-                );
+                MN_REFERENCE_KIND_SHIFT = 24, // refKind
+                MN_REFERENCE_KIND_MASK = 0x0F000000 >> MN_REFERENCE_KIND_SHIFT,
+                // The SEARCH_* bits are not for MN.flags but for the matchFlags argument of MHN.getMembers:
+                MN_SEARCH_SUPERCLASSES = 0x00100000,
+                MN_SEARCH_INTERFACES   = 0x00200000;
 
         /**
          * Basic types as encoded in the JVM.  These code values are not
@@ -243,9 +128,54 @@
             T_ILLEGAL  = 99;
 
         /**
+         * Constant pool entry types.
+         */
+        static final byte
+            CONSTANT_Utf8                = 1,
+            CONSTANT_Integer             = 3,
+            CONSTANT_Float               = 4,
+            CONSTANT_Long                = 5,
+            CONSTANT_Double              = 6,
+            CONSTANT_Class               = 7,
+            CONSTANT_String              = 8,
+            CONSTANT_Fieldref            = 9,
+            CONSTANT_Methodref           = 10,
+            CONSTANT_InterfaceMethodref  = 11,
+            CONSTANT_NameAndType         = 12,
+            CONSTANT_MethodHandle        = 15,  // JSR 292
+            CONSTANT_MethodType          = 16,  // JSR 292
+            CONSTANT_InvokeDynamic       = 18,
+            CONSTANT_LIMIT               = 19;   // Limit to tags found in classfiles
+
+        /**
+         * Access modifier flags.
+         */
+        static final char
+            ACC_PUBLIC                 = 0x0001,
+            ACC_PRIVATE                = 0x0002,
+            ACC_PROTECTED              = 0x0004,
+            ACC_STATIC                 = 0x0008,
+            ACC_FINAL                  = 0x0010,
+            ACC_SYNCHRONIZED           = 0x0020,
+            ACC_VOLATILE               = 0x0040,
+            ACC_TRANSIENT              = 0x0080,
+            ACC_NATIVE                 = 0x0100,
+            ACC_INTERFACE              = 0x0200,
+            ACC_ABSTRACT               = 0x0400,
+            ACC_STRICT                 = 0x0800,
+            ACC_SYNTHETIC              = 0x1000,
+            ACC_ANNOTATION             = 0x2000,
+            ACC_ENUM                   = 0x4000,
+            // aliases:
+            ACC_SUPER                  = ACC_SYNCHRONIZED,
+            ACC_BRIDGE                 = ACC_VOLATILE,
+            ACC_VARARGS                = ACC_TRANSIENT;
+
+        /**
          * Constant pool reference-kind codes, as used by CONSTANT_MethodHandle CP entries.
          */
-        static final int
+        static final byte
+            REF_NONE                    = 0,  // null value
             REF_getField                = 1,
             REF_getStatic               = 2,
             REF_putField                = 3,
@@ -254,9 +184,67 @@
             REF_invokeStatic            = 6,
             REF_invokeSpecial           = 7,
             REF_newInvokeSpecial        = 8,
-            REF_invokeInterface         = 9;
+            REF_invokeInterface         = 9,
+            REF_LIMIT                  = 10;
     }
 
+    static boolean refKindIsValid(int refKind) {
+        return (refKind > REF_NONE && refKind < REF_LIMIT);
+    }
+    static boolean refKindIsField(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind <= REF_putStatic);
+    }
+    static boolean refKindIsGetter(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind <= REF_getStatic);
+    }
+    static boolean refKindIsSetter(byte refKind) {
+        return refKindIsField(refKind) && !refKindIsGetter(refKind);
+    }
+    static boolean refKindIsMethod(byte refKind) {
+        return !refKindIsField(refKind) && (refKind != REF_newInvokeSpecial);
+    }
+    static boolean refKindHasReceiver(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind & 1) != 0;
+    }
+    static boolean refKindIsStatic(byte refKind) {
+        return !refKindHasReceiver(refKind) && (refKind != REF_newInvokeSpecial);
+    }
+    static boolean refKindDoesDispatch(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return (refKind == REF_invokeVirtual ||
+                refKind == REF_invokeInterface);
+    }
+    static {
+        final int HR_MASK = ((1 << REF_getField) |
+                             (1 << REF_putField) |
+                             (1 << REF_invokeVirtual) |
+                             (1 << REF_invokeSpecial) |
+                             (1 << REF_invokeInterface)
+                            );
+        for (byte refKind = REF_NONE+1; refKind < REF_LIMIT; refKind++) {
+            assert(refKindHasReceiver(refKind) == (((1<<refKind) & HR_MASK) != 0)) : refKind;
+        }
+    }
+    static String refKindName(byte refKind) {
+        assert(refKindIsValid(refKind));
+        return REFERENCE_KIND_NAME[refKind];
+    }
+    private static String[] REFERENCE_KIND_NAME = {
+            null,
+            "getField",
+            "getStatic",
+            "putField",
+            "putStatic",
+            "invokeVirtual",
+            "invokeStatic",
+            "invokeSpecial",
+            "newInvokeSpecial",
+            "invokeInterface"
+    };
+
     private static native int getNamedCon(int which, Object[] name);
     static boolean verifyConstants() {
         Object[] box = { null };
@@ -275,16 +263,11 @@
                     continue;
                 }
                 throw new InternalError(err);
-            } catch (Exception ex) {
-                if (ex instanceof NoSuchFieldException) {
-                    String err = (name+": JVM has "+vmval+" which Java does not define");
-                    // ignore exotic ops the JVM cares about; we just wont issue them
-                    if (name.startsWith("OP_") || name.startsWith("GC_")) {
-                        System.err.println("warning: "+err);
-                        continue;
-                    }
-                }
-                throw new InternalError(name+": access failed, got "+ex);
+            } catch (NoSuchFieldException | IllegalAccessException ex) {
+                String err = (name+": JVM has "+vmval+" which Java does not define");
+                // ignore exotic ops the JVM cares about; we just wont issue them
+                //System.err.println("warning: "+err);
+                continue;
             }
         }
         return true;
@@ -299,18 +282,21 @@
     /**
      * The JVM is linking an invokedynamic instruction.  Create a reified call site for it.
      */
-    static CallSite makeDynamicCallSite(MethodHandle bootstrapMethod,
-                                        String name, MethodType type,
-                                        Object info,
-                                        MemberName callerMethod, int callerBCI) {
-        return CallSite.makeSite(bootstrapMethod, name, type, info, callerMethod, callerBCI);
-    }
-
-    /**
-     * Called by the JVM to check the length of a spread array.
-     */
-    static void checkSpreadArgument(Object av, int n) {
-        MethodHandleStatics.checkSpreadArgument(av, n);
+    static MemberName linkCallSite(Object callerObj,
+                                   Object bootstrapMethodObj,
+                                   Object nameObj, Object typeObj,
+                                   Object staticArguments,
+                                   Object[] appendixResult) {
+        MethodHandle bootstrapMethod = (MethodHandle)bootstrapMethodObj;
+        Class<?> caller = (Class<?>)callerObj;
+        String name = nameObj.toString().intern();
+        MethodType type = (MethodType)typeObj;
+        appendixResult[0] = CallSite.makeSite(bootstrapMethod,
+                                              name,
+                                              type,
+                                              staticArguments,
+                                              caller);
+        return Invokers.linkToCallSiteMethod(type);
     }
 
     /**
@@ -321,71 +307,78 @@
     }
 
     /**
-     * The JVM wants to use a MethodType with inexact invoke.  Give the runtime fair warning.
+     * The JVM wants to link a call site that requires a dynamic type check.
+     * Name is a type-checking invoker, invokeExact or invoke.
+     * Return a JVM method (MemberName) to handle the invoking.
+     * The method assumes the following arguments on the stack:
+     * 0: the method handle being invoked
+     * 1-N: the arguments to the method handle invocation
+     * N+1: an implicitly added type argument (the given MethodType)
      */
-    static void notifyGenericMethodType(MethodType type) {
-        type.form().notifyGenericMethodType();
+    static MemberName linkMethod(Class<?> callerClass, int refKind,
+                                 Class<?> defc, String name, Object type,
+                                 Object[] appendixResult) {
+        if (!TRACE_METHOD_LINKAGE)
+            return linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+        return linkMethodTracing(callerClass, refKind, defc, name, type, appendixResult);
+    }
+    static MemberName linkMethodImpl(Class<?> callerClass, int refKind,
+                                     Class<?> defc, String name, Object type,
+                                     Object[] appendixResult) {
+        try {
+            if (defc == MethodHandle.class && refKind == REF_invokeVirtual) {
+                switch (name) {
+                case "invoke":
+                    return Invokers.genericInvokerMethod(fixMethodType(callerClass, type), appendixResult);
+                case "invokeExact":
+                    return Invokers.exactInvokerMethod(fixMethodType(callerClass, type), appendixResult);
+                }
+            }
+        } catch (Throwable ex) {
+            if (ex instanceof LinkageError)
+                throw (LinkageError) ex;
+            else
+                throw new LinkageError(ex.getMessage(), ex);
+        }
+        throw new LinkageError("no such method "+defc.getName()+"."+name+type);
+    }
+    private static MethodType fixMethodType(Class<?> callerClass, Object type) {
+        if (type instanceof MethodType)
+            return (MethodType) type;
+        else
+            return MethodType.fromMethodDescriptorString((String)type, callerClass.getClassLoader());
+    }
+    // Tracing logic:
+    static MemberName linkMethodTracing(Class<?> callerClass, int refKind,
+                                        Class<?> defc, String name, Object type,
+                                        Object[] appendixResult) {
+        System.out.println("linkMethod "+defc.getName()+"."+
+                           name+type+"/"+Integer.toHexString(refKind));
+        try {
+            MemberName res = linkMethodImpl(callerClass, refKind, defc, name, type, appendixResult);
+            System.out.println("linkMethod => "+res+" + "+appendixResult[0]);
+            return res;
+        } catch (Throwable ex) {
+            System.out.println("linkMethod => throw "+ex);
+            throw ex;
+        }
     }
 
-    /**
-     * The JVM wants to raise an exception.  Here's the path.
-     */
-    static void raiseException(int code, Object actual, Object required) {
-        String message = null;
-        switch (code) {
-        case 190: // arraylength
-            try {
-                String reqLength = "";
-                if (required instanceof AdapterMethodHandle) {
-                    int conv = ((AdapterMethodHandle)required).getConversion();
-                    int spChange = AdapterMethodHandle.extractStackMove(conv);
-                    reqLength = " of length "+(spChange+1);
-                }
-                int actualLength = actual == null ? 0 : java.lang.reflect.Array.getLength(actual);
-                message = "required array"+reqLength+", but encountered wrong length "+actualLength;
-                break;
-            } catch (IllegalArgumentException ex) {
-            }
-            required = Object[].class;  // should have been an array
-            code = 192; // checkcast
-            break;
-        case 191: // athrow
-            // JVM is asking us to wrap an exception which happened during resolving
-            if (required == BootstrapMethodError.class) {
-                throw new BootstrapMethodError((Throwable) actual);
-            }
-            break;
-        }
-        // disregard the identity of the actual object, if it is not a class:
-        if (message == null) {
-            if (!(actual instanceof Class) && !(actual instanceof MethodType))
-                actual = actual.getClass();
-           if (actual != null)
-               message = "required "+required+" but encountered "+actual;
-           else
-               message = "required "+required;
-        }
-        switch (code) {
-        case 190: // arraylength
-            throw new ArrayIndexOutOfBoundsException(message);
-        case 50: //_aaload
-            throw new ClassCastException(message);
-        case 192: // checkcast
-            throw new ClassCastException(message);
-        default:
-            throw new InternalError("unexpected code "+code+": "+message);
-        }
-    }
 
     /**
      * The JVM is resolving a CONSTANT_MethodHandle CP entry.  And it wants our help.
      * It will make an up-call to this method.  (Do not change the name or signature.)
+     * The type argument is a Class for field requests and a MethodType for non-fields.
+     * <p>
+     * Recent versions of the JVM may also pass a resolved MemberName for the type.
+     * In that case, the name is ignored and may be null.
      */
     static MethodHandle linkMethodHandleConstant(Class<?> callerClass, int refKind,
                                                  Class<?> defc, String name, Object type) {
         try {
             Lookup lookup = IMPL_LOOKUP.in(callerClass);
-            return lookup.linkMethodHandleConstant(refKind, defc, name, type);
+            assert(refKindIsValid(refKind));
+            return lookup.linkMethodHandleConstant((byte) refKind, defc, name, type);
         } catch (ReflectiveOperationException ex) {
             Error err = new IncompatibleClassChangeError();
             err.initCause(ex);
@@ -394,15 +387,6 @@
     }
 
     /**
-     * This assertion marks code which was written before ricochet frames were implemented.
-     * Such code will go away when the ports catch up.
-     */
-    static boolean workaroundWithoutRicochetFrames() {
-        assert(!HAVE_RICOCHET_FRAMES) : "this code should not be executed if `-XX:+UseRicochetFrames is enabled";
-        return true;
-    }
-
-    /**
      * Is this method a caller-sensitive method?
      * I.e., does it call Reflection.getCallerClass or a similer method
      * to ask about the identity of its caller?
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java
index 82fde2a..8e06823 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleProxies.java
@@ -150,7 +150,7 @@
         }
         return intfc.cast(Proxy.newProxyInstance(
                 intfc.getClassLoader(),
-                new Class[]{ intfc, WrapperInstance.class },
+                new Class<?>[]{ intfc, WrapperInstance.class },
                 new InvocationHandler() {
                     private Object getArg(String name) {
                         if ((Object)name == "getWrapperInstanceTarget")  return target;
@@ -165,7 +165,7 @@
                         if (method.getDeclaringClass() == WrapperInstance.class)
                             return getArg(method.getName());
                         if (isObjectMethod(method))
-                            return callObjectMethod(this, method, args);
+                            return callObjectMethod(proxy, method, args);
                         throw new InternalError("bad proxy method: "+method);
                     }
                 }));
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java b/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java
index 6dae737..4e01050 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandleStatics.java
@@ -27,6 +27,7 @@
 
 import java.security.AccessController;
 import java.security.PrivilegedAction;
+import sun.misc.Unsafe;
 
 /**
  * This class consists exclusively of static names internal to the
@@ -38,16 +39,30 @@
 
     private MethodHandleStatics() { }  // do not instantiate
 
+    static final Unsafe UNSAFE = Unsafe.getUnsafe();
+
     static final boolean DEBUG_METHOD_HANDLE_NAMES;
+    static final boolean DUMP_CLASS_FILES;
+    static final boolean TRACE_INTERPRETER;
+    static final boolean TRACE_METHOD_LINKAGE;
+    static final Integer COMPILE_THRESHOLD;
     static {
-        final Object[] values = { false };
+        final Object[] values = { false, false, false, false, null };
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
                 public Void run() {
                     values[0] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DEBUG_NAMES");
+                    values[1] = Boolean.getBoolean("java.lang.invoke.MethodHandle.DUMP_CLASS_FILES");
+                    values[2] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_INTERPRETER");
+                    values[3] = Boolean.getBoolean("java.lang.invoke.MethodHandle.TRACE_METHOD_LINKAGE");
+                    values[4] = Integer.getInteger("java.lang.invoke.MethodHandle.COMPILE_THRESHOLD");
                     return null;
                 }
             });
         DEBUG_METHOD_HANDLE_NAMES = (Boolean) values[0];
+        DUMP_CLASS_FILES          = (Boolean) values[1];
+        TRACE_INTERPRETER         = (Boolean) values[2];
+        TRACE_METHOD_LINKAGE      = (Boolean) values[3];
+        COMPILE_THRESHOLD         = (Integer) values[4];
     }
 
     /*non-public*/ static String getNameString(MethodHandle target, MethodType type) {
@@ -55,7 +70,7 @@
             type = target.type();
         MemberName name = null;
         if (target != null)
-            name = MethodHandleNatives.getMethodName(target);
+            name = target.internalMemberName();
         if (name == null)
             return "invoke" + type;
         return name.getName() + type;
@@ -77,21 +92,17 @@
         return str + target.type();
     }
 
-    static void checkSpreadArgument(Object av, int n) {
-        if (av == null) {
-            if (n == 0)  return;
-        } else if (av instanceof Object[]) {
-            int len = ((Object[])av).length;
-            if (len == n)  return;
-        } else {
-            int len = java.lang.reflect.Array.getLength(av);
-            if (len == n)  return;
-        }
-        // fall through to error:
-        throw newIllegalArgumentException("Array is not of length "+n);
-    }
-
     // handy shared exception makers (they simplify the common case code)
+    /*non-public*/ static InternalError newInternalError(String message, Throwable cause) {
+        InternalError e = new InternalError(message);
+        e.initCause(cause);
+        return e;
+    }
+    /*non-public*/ static InternalError newInternalError(Throwable cause) {
+        InternalError e = new InternalError();
+        e.initCause(cause);
+        return e;
+    }
     /*non-public*/ static RuntimeException newIllegalStateException(String message) {
         return new IllegalStateException(message);
     }
@@ -108,9 +119,10 @@
         return new IllegalArgumentException(message(message, obj, obj2));
     }
     /*non-public*/ static Error uncaughtException(Throwable ex) {
-        Error err = new InternalError("uncaught exception");
-        err.initCause(ex);
-        return err;
+        throw newInternalError("uncaught exception", ex);
+    }
+    static Error NYI() {
+        throw new AssertionError("NYI");
     }
     private static String message(String message, Object obj) {
         if (obj != null)  message = message + ": " + obj;
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
index cac66b1..ecf4ee6 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodHandles.java
@@ -26,7 +26,6 @@
 package java.lang.invoke;
 
 import java.lang.reflect.*;
-import sun.invoke.WrapperInstance;
 import sun.invoke.util.ValueConversions;
 import sun.invoke.util.VerifyAccess;
 import sun.invoke.util.Wrapper;
@@ -174,6 +173,8 @@
      * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
      * The formal parameter {@code this} stands for the self-reference of type {@code C};
      * if it is present, it is always the leading argument to the method handle invocation.
+     * (In the case of some {@code protected} members, {@code this} may be
+     * restricted in type to the lookup class; see below.)
      * The name {@code arg} stands for all the other method handle arguments.
      * In the code examples for the Core Reflection API, the name {@code thisOrNull}
      * stands for a null reference if the accessed method or field is static,
@@ -244,6 +245,18 @@
      * is exactly equivalent to executing the compiled and resolved call to {@code M}.
      * The same point is true of fields and constructors.
      * <p>
+     * If the desired member is {@code protected}, the usual JVM rules apply,
+     * including the requirement that the lookup class must be either be in the
+     * same package as the desired member, or must inherit that member.
+     * (See the Java Virtual Machine Specification, sections 4.9.2, 5.4.3.5, and 6.4.)
+     * In addition, if the desired member is a non-static field or method
+     * in a different package, the resulting method handle may only be applied
+     * to objects of the lookup class or one of its subclasses.
+     * This requirement is enforced by narrowing the type of the leading
+     * {@code this} parameter from {@code C}
+     * (which will necessarily be a superclass of the lookup class)
+     * to the lookup class itself.
+     * <p>
      * In some cases, access between nested classes is obtained by the Java compiler by creating
      * an wrapper method to access a private method of another class
      * in the same top-level declaration.
@@ -582,21 +595,9 @@
          */
         public
         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            MemberName method = resolveOrFail(refc, name, type, true);
+            MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
             checkSecurityManager(refc, method);  // stack walk magic: do not refactor
-            return accessStatic(refc, method);
-        }
-        private
-        MethodHandle accessStatic(Class<?> refc, MemberName method) throws IllegalAccessException {
-            checkMethod(refc, method, true);
-            MethodHandle mh = MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
-            mh = maybeBindCaller(method, mh);
-            return mh;
-        }
-        private
-        MethodHandle resolveStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            MemberName method = resolveOrFail(refc, name, type, true);
-            return accessStatic(refc, method);
+            return getDirectMethod(REF_invokeStatic, refc, method);
         }
 
         /**
@@ -611,6 +612,11 @@
          * (The dispatching action is identical with that performed by an
          * {@code invokevirtual} or {@code invokeinterface} instruction.)
          * <p>
+         * The first argument will be of type {@code refc} if the lookup
+         * class has full privileges to access the member.  Otherwise
+         * the member must be {@code protected} and the first argument
+         * will be restricted in type to the lookup class.
+         * <p>
          * The returned method handle will have
          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
          * the method's variable arity modifier bit ({@code 0x0080}) is set.
@@ -638,19 +644,22 @@
          * @throws NullPointerException if any argument is null
          */
         public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            MemberName method = resolveOrFail(refc, name, type, false);
+            if (refc == MethodHandle.class) {
+                MethodHandle mh = findVirtualForMH(name, type);
+                if (mh != null)  return mh;
+            }
+            byte refKind = (refc.isInterface() ? REF_invokeInterface : REF_invokeVirtual);
+            MemberName method = resolveOrFail(refKind, refc, name, type);
             checkSecurityManager(refc, method);  // stack walk magic: do not refactor
-            return accessVirtual(refc, method);
+            return getDirectMethod(refKind, refc, method);
         }
-        private MethodHandle resolveVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            MemberName method = resolveOrFail(refc, name, type, false);
-            return accessVirtual(refc, method);
-        }
-        private MethodHandle accessVirtual(Class<?> refc, MemberName method) throws IllegalAccessException {
-            checkMethod(refc, method, false);
-            MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
-            mh = maybeBindCaller(method, mh);
-            return restrictProtectedReceiver(method, mh);
+        private MethodHandle findVirtualForMH(String name, MethodType type) {
+            // these names require special lookups because of the implicit MethodType argument
+            if ("invoke".equals(name))
+                return invoker(type);
+            if ("invokeExact".equals(name))
+                return exactInvoker(type);
+            return null;
         }
 
         /**
@@ -681,37 +690,9 @@
          */
         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             String name = "<init>";
-            MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
+            MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
             checkSecurityManager(refc, ctor);  // stack walk magic: do not refactor
-            return accessConstructor(refc, ctor);
-        }
-        private MethodHandle accessConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
-            assert(ctor.isConstructor());
-            checkAccess(refc, ctor);
-            MethodHandle rawMH = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
-            MethodHandle allocMH = MethodHandleImpl.makeAllocator(rawMH);
-            assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
-            return fixVarargs(allocMH, rawMH);
-        }
-        private MethodHandle resolveConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            String name = "<init>";
-            MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
-            return accessConstructor(refc, ctor);
-        }
-
-        /** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
-        private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
-            boolean va1 = mh.isVarargsCollector();
-            boolean va2 = matchMH.isVarargsCollector();
-            if (va1 == va2) {
-                return mh;
-            } else if (va2) {
-                MethodType type = mh.type();
-                int arity = type.parameterCount();
-                return mh.asVarargsCollector(type.parameterType(arity-1));
-            } else {
-                return mh.asFixedArity();
-            }
+            return getDirectConstructor(refc, ctor);
         }
 
         /**
@@ -751,22 +732,10 @@
         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
             checkSpecialCaller(specialCaller);
-            MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
+            Lookup specialLookup = this.in(specialCaller);
+            MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
             checkSecurityManager(refc, method);  // stack walk magic: do not refactor
-            return accessSpecial(refc, method, specialCaller);
-        }
-        private MethodHandle accessSpecial(Class<?> refc, MemberName method,
-                                           Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
-            checkMethod(refc, method, false);
-            MethodHandle mh = MethodHandleImpl.findMethod(method, false, specialCaller);
-            mh = maybeBindCaller(method, mh);
-            return restrictReceiver(method, mh, specialCaller);
-        }
-        private MethodHandle resolveSpecial(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
-            Class<?> specialCaller = lookupClass();
-            checkSpecialCaller(specialCaller);
-            MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
-            return accessSpecial(refc, method, specialCaller);
+            return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method);
         }
 
         /**
@@ -787,13 +756,9 @@
          * @throws NullPointerException if any argument is null
          */
         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, false);
+            MemberName field = resolveOrFail(REF_getField, refc, name, type);
             checkSecurityManager(refc, field);  // stack walk magic: do not refactor
-            return makeAccessor(refc, field, false, false, 0);
-        }
-        private MethodHandle resolveGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, false);
-            return makeAccessor(refc, field, false, false, 0);
+            return getDirectField(REF_getField, refc, field);
         }
 
         /**
@@ -814,13 +779,9 @@
          * @throws NullPointerException if any argument is null
          */
         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, false);
+            MemberName field = resolveOrFail(REF_putField, refc, name, type);
             checkSecurityManager(refc, field);  // stack walk magic: do not refactor
-            return makeAccessor(refc, field, false, true, 0);
-        }
-        private MethodHandle resolveSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, false);
-            return makeAccessor(refc, field, false, true, 0);
+            return getDirectField(REF_putField, refc, field);
         }
 
         /**
@@ -840,13 +801,9 @@
          * @throws NullPointerException if any argument is null
          */
         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, true);
+            MemberName field = resolveOrFail(REF_getStatic, refc, name, type);
             checkSecurityManager(refc, field);  // stack walk magic: do not refactor
-            return makeAccessor(refc, field, false, false, 1);
-        }
-        private MethodHandle resolveStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, true);
-            return makeAccessor(refc, field, false, false, 1);
+            return getDirectField(REF_getStatic, refc, field);
         }
 
         /**
@@ -866,13 +823,9 @@
          * @throws NullPointerException if any argument is null
          */
         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, true);
+            MemberName field = resolveOrFail(REF_putStatic, refc, name, type);
             checkSecurityManager(refc, field);  // stack walk magic: do not refactor
-            return makeAccessor(refc, field, false, true, 1);
-        }
-        private MethodHandle resolveStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
-            MemberName field = resolveOrFail(refc, name, type, true);
-            return makeAccessor(refc, field, false, true, 1);
+            return getDirectField(REF_putStatic, refc, field);
         }
 
         /**
@@ -923,16 +876,10 @@
          */
         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             Class<? extends Object> refc = receiver.getClass(); // may get NPE
-            MemberName method = resolveOrFail(refc, name, type, false);
+            MemberName method = resolveOrFail(REF_invokeSpecial, refc, name, type);
             checkSecurityManager(refc, method);  // stack walk magic: do not refactor
-            checkMethod(refc, method, false);
-            MethodHandle dmh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
-            MethodHandle bcmh = maybeBindCaller(method, dmh);
-            if (bcmh != dmh)  return fixVarargs(bcmh.bindTo(receiver), dmh);
-            MethodHandle bmh = MethodHandleImpl.bindReceiver(dmh, receiver);
-            if (bmh == null)
-                throw method.makeAccessException("no access", this);
-            return fixVarargs(bmh, dmh);
+            MethodHandle mh = getDirectMethodNoRestrict(REF_invokeSpecial, refc, method);
+            return mh.bindReceiver(receiver).setVarargs(method);
         }
 
         /**
@@ -958,13 +905,12 @@
          */
         public MethodHandle unreflect(Method m) throws IllegalAccessException {
             MemberName method = new MemberName(m);
+            byte refKind = method.getReferenceKind();
+            if (refKind == REF_invokeSpecial)
+                refKind = REF_invokeVirtual;
             assert(method.isMethod());
-            if (m.isAccessible())
-                return MethodHandleImpl.findMethod(method, true, /*no lookupClass*/ null);
-            checkMethod(method.getDeclaringClass(), method, method.isStatic());
-            MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
-            mh = maybeBindCaller(method, mh);
-            return restrictProtectedReceiver(method, mh);
+            Lookup lookup = m.isAccessible() ? IMPL_LOOKUP : this;
+            return lookup.getDirectMethod(refKind, method.getDeclaringClass(), method);
         }
 
         /**
@@ -990,13 +936,11 @@
          */
         public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
             checkSpecialCaller(specialCaller);
-            MemberName method = new MemberName(m);
+            Lookup specialLookup = this.in(specialCaller);
+            MemberName method = new MemberName(m, true);
             assert(method.isMethod());
             // ignore m.isAccessible:  this is a new kind of access
-            checkMethod(m.getDeclaringClass(), method, false);
-            MethodHandle mh = MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
-            mh = maybeBindCaller(method, mh);
-            return restrictReceiver(method, mh, specialCaller);
+            return specialLookup.getDirectMethod(REF_invokeSpecial, method.getDeclaringClass(), method);
         }
 
         /**
@@ -1020,19 +964,12 @@
          *                                is set and {@code asVarargsCollector} fails
          * @throws NullPointerException if the argument is null
          */
+        @SuppressWarnings("rawtypes")  // Will be Constructor<?> after JSR 292 MR
         public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
             MemberName ctor = new MemberName(c);
             assert(ctor.isConstructor());
-            MethodHandle rawCtor;
-            if (c.isAccessible()) {
-                rawCtor = MethodHandleImpl.findMethod(ctor, false, /*no lookupClass*/ null);
-            } else {
-                checkAccess(c.getDeclaringClass(), ctor);
-                rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
-            }
-            assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
-            MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
-            return fixVarargs(allocator, rawCtor);
+            Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
+            return lookup.getDirectConstructor(ctor.getDeclaringClass(), ctor);
         }
 
         /**
@@ -1050,7 +987,15 @@
          * @throws NullPointerException if the argument is null
          */
         public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
-            return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false, -1);
+            return unreflectField(f, false);
+        }
+        private MethodHandle unreflectField(Field f, boolean isSetter) throws IllegalAccessException {
+            MemberName field = new MemberName(f, isSetter);
+            assert(isSetter
+                    ? MethodHandleNatives.refKindIsSetter(field.getReferenceKind())
+                    : MethodHandleNatives.refKindIsGetter(field.getReferenceKind()));
+            Lookup lookup = f.isAccessible() ? IMPL_LOOKUP : this;
+            return lookup.getDirectField(field.getReferenceKind(), f.getDeclaringClass(), field);
         }
 
         /**
@@ -1068,33 +1013,22 @@
          * @throws NullPointerException if the argument is null
          */
         public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
-            return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true, -1);
+            return unreflectField(f, true);
         }
 
         /// Helper methods, all package-private.
 
-        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoSuchFieldException, IllegalAccessException {
+        MemberName resolveOrFail(byte refKind, Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
             name.getClass(); type.getClass();  // NPE
-            int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
+            return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
                                             NoSuchFieldException.class);
         }
 
-        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoSuchMethodException, IllegalAccessException {
+        MemberName resolveOrFail(byte refKind, Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
             checkSymbolicClass(refc);  // do this before attempting to resolve
             name.getClass(); type.getClass();  // NPE
-            int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
-                                            NoSuchMethodException.class);
-        }
-
-        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic,
-                                 boolean searchSupers, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
-            checkSymbolicClass(refc);  // do this before attempting to resolve
-            name.getClass(); type.getClass();  // NPE
-            int mods = (isStatic ? Modifier.STATIC : 0);
-            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller,
+            return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
                                             NoSuchMethodException.class);
         }
 
@@ -1150,7 +1084,8 @@
             // SecurityManager.checkMemberAccess [0]
         }
 
-        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
+        void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
+            boolean wantStatic = (refKind == REF_invokeStatic);
             String message;
             if (m.isConstructor())
                 message = "expected a method, not a constructor";
@@ -1159,26 +1094,43 @@
             else if (wantStatic != m.isStatic())
                 message = wantStatic ? "expected a static method" : "expected a non-static method";
             else
-                { checkAccess(refc, m); return; }
+                { checkAccess(refKind, refc, m); return; }
             throw m.makeAccessException(message, this);
         }
 
-        void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException {
+        void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
+            boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
+            String message;
+            if (wantStatic != m.isStatic())
+                message = wantStatic ? "expected a static field" : "expected a non-static field";
+            else
+                { checkAccess(refKind, refc, m); return; }
+            throw m.makeAccessException(message, this);
+        }
+
+        void checkAccess(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
+            assert(m.referenceKindIsConsistentWith(refKind) &&
+                   MethodHandleNatives.refKindIsValid(refKind) &&
+                   (MethodHandleNatives.refKindIsField(refKind) == m.isField()));
             int allowedModes = this.allowedModes;
             if (allowedModes == TRUSTED)  return;
             int mods = m.getModifiers();
+            if (Modifier.isFinal(mods) &&
+                    MethodHandleNatives.refKindIsSetter(refKind))
+                throw m.makeAccessException("unexpected set of a final field", this);
             if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
                 return;  // common case
             int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
-            if ((requestedModes & allowedModes) != 0
-                && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
-                                                   mods, lookupClass(), allowedModes))
-                return;
-            if (((requestedModes & ~allowedModes) & PROTECTED) != 0
-                && (allowedModes & PACKAGE) != 0
-                && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
+            if ((requestedModes & allowedModes) != 0) {
+                if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
+                                                    mods, lookupClass(), allowedModes))
+                    return;
+            } else {
                 // Protected members can also be checked as if they were package-private.
-                return;
+                if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
+                        && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
+                    return;
+            }
             throw m.makeAccessException(accessFailedMessage(refc, m), this);
         }
 
@@ -1207,7 +1159,8 @@
 
         private static final boolean ALLOW_NESTMATE_ACCESS = false;
 
-        void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
+        private void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
+            int allowedModes = this.allowedModes;
             if (allowedModes == TRUSTED)  return;
             if ((allowedModes & PRIVATE) == 0
                 || (specialCaller != lookupClass()
@@ -1217,7 +1170,7 @@
                     makeAccessException("no private access for invokespecial", this);
         }
 
-        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
+        private boolean restrictProtectedReceiver(MemberName method) {
             // The accessing class only has the right to use a protected member
             // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
             if (!method.isProtected() || method.isStatic()
@@ -1226,21 +1179,44 @@
                 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
                 || (ALLOW_NESTMATE_ACCESS &&
                     VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
-                return mh;
-            else
-                return restrictReceiver(method, mh, lookupClass());
+                return false;
+            return true;
         }
-        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
+        private MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
             assert(!method.isStatic());
-            Class<?> defc = method.getDeclaringClass();  // receiver type of mh is too wide
-            if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
+            // receiver type of mh is too wide; narrow to caller
+            if (!method.getDeclaringClass().isAssignableFrom(caller)) {
                 throw method.makeAccessException("caller class must be a subclass below the method", caller);
             }
             MethodType rawType = mh.type();
             if (rawType.parameterType(0) == caller)  return mh;
             MethodType narrowType = rawType.changeParameterType(0, caller);
-            MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, 0);
-            return fixVarargs(narrowMH, mh);
+            return mh.viewAsType(narrowType);
+        }
+
+        private MethodHandle getDirectMethod(byte refKind, Class<?> refc, MemberName method) throws IllegalAccessException {
+            return getDirectMethodCommon(refKind, refc, method,
+                    (refKind == REF_invokeSpecial ||
+                        (MethodHandleNatives.refKindHasReceiver(refKind) &&
+                            restrictProtectedReceiver(method))));
+        }
+        private MethodHandle getDirectMethodNoRestrict(byte refKind, Class<?> refc, MemberName method) throws IllegalAccessException {
+            return getDirectMethodCommon(refKind, refc, method, false);
+        }
+        private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
+                                                   boolean doRestrict) throws IllegalAccessException {
+            checkMethod(refKind, refc, method);
+            if (method.isMethodHandleInvoke())
+                return fakeMethodHandleInvoke(method);
+            MethodHandle mh = DirectMethodHandle.make(refc, method);
+            mh = maybeBindCaller(method, mh);
+            mh = mh.setVarargs(method);
+            if (doRestrict)
+                mh = restrictReceiver(method, mh, lookupClass());
+            return mh;
+        }
+        private MethodHandle fakeMethodHandleInvoke(MemberName method) {
+            return throwException(method.getReturnType(), UnsupportedOperationException.class);
         }
         private MethodHandle maybeBindCaller(MemberName method, MethodHandle mh) throws IllegalAccessException {
             if (allowedModes == TRUSTED || !MethodHandleNatives.isCallerSensitive(method))
@@ -1249,39 +1225,48 @@
             if ((allowedModes & PRIVATE) == 0)  // caller must use full-power lookup
                 hostClass = null;
             MethodHandle cbmh = MethodHandleImpl.bindCaller(mh, hostClass);
-            cbmh = fixVarargs(cbmh, mh);  // in JDK 7 version, varargs happens earlier and must be repaired
+            // Note: caller will apply varargs after this step happens.
             return cbmh;
         }
-
-        MethodHandle makeAccessor(Class<?> refc, MemberName field,
-                                  boolean trusted, boolean isSetter,
-                                  int checkStatic) throws IllegalAccessException {
-            assert(field.isField());
-            if (checkStatic >= 0 && (checkStatic != 0) != field.isStatic())
-                throw field.makeAccessException((checkStatic != 0)
-                                                ? "expected a static field"
-                                                : "expected a non-static field", this);
-            if (trusted)
-                return MethodHandleImpl.accessField(field, isSetter, /*no lookupClass*/ null);
-            checkAccess(refc, field);
-            MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
-            return restrictProtectedReceiver(field, mh);
+        private MethodHandle getDirectField(byte refKind, Class<?> refc, MemberName field) throws IllegalAccessException {
+            checkField(refKind, refc, field);
+            MethodHandle mh = DirectMethodHandle.make(refc, field);
+            boolean doRestrict = (MethodHandleNatives.refKindHasReceiver(refKind) &&
+                                    restrictProtectedReceiver(field));
+            if (doRestrict)
+                mh = restrictReceiver(field, mh, lookupClass());
+            return mh;
+        }
+        private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
+            assert(ctor.isConstructor());
+            checkAccess(REF_newInvokeSpecial, refc, ctor);
+            assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
+            return DirectMethodHandle.make(ctor).setVarargs(ctor);
         }
 
         /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
          */
         /*non-public*/
-        MethodHandle linkMethodHandleConstant(int refKind, Class<?> defc, String name, Object type) throws ReflectiveOperationException {
-            switch (refKind) {
-            case REF_getField:          return resolveGetter(       defc, name, (Class<?>)   type );
-            case REF_getStatic:         return resolveStaticGetter( defc, name, (Class<?>)   type );
-            case REF_putField:          return resolveSetter(       defc, name, (Class<?>)   type );
-            case REF_putStatic:         return resolveStaticSetter( defc, name, (Class<?>)   type );
-            case REF_invokeVirtual:     return resolveVirtual(      defc, name, (MethodType) type );
-            case REF_invokeStatic:      return resolveStatic(       defc, name, (MethodType) type );
-            case REF_invokeSpecial:     return resolveSpecial(      defc, name, (MethodType) type );
-            case REF_newInvokeSpecial:  return resolveConstructor(  defc,       (MethodType) type );
-            case REF_invokeInterface:   return resolveVirtual(      defc, name, (MethodType) type );
+        MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type) throws ReflectiveOperationException {
+            MemberName resolved = null;
+            if (type instanceof MemberName) {
+                resolved = (MemberName) type;
+                if (!resolved.isResolved())  throw new InternalError("unresolved MemberName");
+                assert(name == null || name.equals(resolved.getName()));
+            }
+            if (MethodHandleNatives.refKindIsField(refKind)) {
+                MemberName field = (resolved != null) ? resolved
+                        : resolveOrFail(refKind, defc, name, (Class<?>) type);
+                return getDirectField(refKind, defc, field);
+            } else if (MethodHandleNatives.refKindIsMethod(refKind)) {
+                MemberName method = (resolved != null) ? resolved
+                        : resolveOrFail(refKind, defc, name, (MethodType) type);
+                return getDirectMethod(refKind, defc, method);
+            } else if (refKind == REF_newInvokeSpecial) {
+                assert(name == null || name.equals("<init>"));
+                MemberName ctor = (resolved != null) ? resolved
+                        : resolveOrFail(REF_newInvokeSpecial, defc, name, (MethodType) type);
+                return getDirectConstructor(defc, ctor);
             }
             // oops
             throw new ReflectiveOperationException("bad MethodHandle constant #"+refKind+" "+name+" : "+type);
@@ -1300,7 +1285,7 @@
      */
     public static
     MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
-        return MethodHandleImpl.accessArrayElement(arrayClass, false);
+        return MethodHandleImpl.makeArrayElementAccessor(arrayClass, false);
     }
 
     /**
@@ -1314,7 +1299,7 @@
      */
     public static
     MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
-        return MethodHandleImpl.accessArrayElement(arrayClass, true);
+        return MethodHandleImpl.makeArrayElementAccessor(arrayClass, true);
     }
 
     /// method handle invocation (reflective style)
@@ -1441,78 +1426,12 @@
         return type.invokers().generalInvoker();
     }
 
-    /**
-     * Perform value checking, exactly as if for an adapted method handle.
-     * It is assumed that the given value is either null, of type T0,
-     * or (if T0 is primitive) of the wrapper class corresponding to T0.
-     * The following checks and conversions are made:
-     * <ul>
-     * <li>If T0 and T1 are references, then a cast to T1 is applied.
-     *     (The types do not need to be related in any particular way.)
-     * <li>If T0 and T1 are primitives, then a widening or narrowing
-     *     conversion is applied, if one exists.
-     * <li>If T0 is a primitive and T1 a reference, and
-     *     T0 has a wrapper class TW, a boxing conversion to TW is applied,
-     *     possibly followed by a reference conversion.
-     *     T1 must be TW or a supertype.
-     * <li>If T0 is a reference and T1 a primitive, and
-     *     T1 has a wrapper class TW, an unboxing conversion is applied,
-     *     possibly preceded by a reference conversion.
-     *     T0 must be TW or a supertype.
-     * <li>If T1 is void, the return value is discarded
-     * <li>If T0 is void and T1 a reference, a null value is introduced.
-     * <li>If T0 is void and T1 a primitive, a zero value is introduced.
-     * </ul>
-     * If the value is discarded, null will be returned.
-     * @param valueType
-     * @param value
-     * @return the value, converted if necessary
-     * @throws java.lang.ClassCastException if a cast fails
-     */
-    // FIXME: This is used in just one place.  Refactor away.
-    static
-    <T0, T1> T1 checkValue(Class<T0> t0, Class<T1> t1, Object value)
-       throws ClassCastException
-    {
-        if (t0 == t1) {
-            // no conversion needed; just reassert the same type
-            if (t0.isPrimitive())
-                return Wrapper.asPrimitiveType(t1).cast(value);
-            else
-                return Wrapper.OBJECT.convert(value, t1);
-        }
-        boolean prim0 = t0.isPrimitive(), prim1 = t1.isPrimitive();
-        if (!prim0) {
-            // check contract with caller
-            Wrapper.OBJECT.convert(value, t0);
-            if (!prim1) {
-                return Wrapper.OBJECT.convert(value, t1);
-            }
-            // convert reference to primitive by unboxing
-            Wrapper w1 = Wrapper.forPrimitiveType(t1);
-            return w1.convert(value, t1);
-        }
-        // check contract with caller:
-        Wrapper.asWrapperType(t0).cast(value);
-        Wrapper w1 = Wrapper.forPrimitiveType(t1);
-        return w1.convert(value, t1);
+    static /*non-public*/
+    MethodHandle basicInvoker(MethodType type) {
+        return type.form().basicInvoker();
     }
 
-    // FIXME: Delete this.  It is used only for insertArguments & bindTo.
-    // Replace by a more standard check.
-    static
-    Object checkValue(Class<?> T1, Object value)
-       throws ClassCastException
-    {
-        Class<?> T0;
-        if (value == null)
-            T0 = Object.class;
-        else
-            T0 = value.getClass();
-        return checkValue(T0, T1, value);
-    }
-
-    /// method handle modification (creation from other method handles)
+     /// method handle modification (creation from other method handles)
 
     /**
      * Produces a method handle which adapts the type of the
@@ -1560,7 +1479,10 @@
      */
     public static
     MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
-        return MethodHandleImpl.convertArguments(target, newType, 2);
+        if (!target.type().isCastableTo(newType)) {
+            throw new WrongMethodTypeException("cannot explicitly cast "+target+" to "+newType);
+        }
+        return MethodHandleImpl.makePairwiseConvert(target, newType, 2);
     }
 
     /**
@@ -1624,11 +1546,8 @@
      */
     public static
     MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
-        MethodType oldType = target.type();
-        checkReorder(reorder, newType, oldType);
-        return MethodHandleImpl.permuteArguments(target,
-                                                 newType, oldType,
-                                                 reorder);
+        checkReorder(reorder, newType, target.type());
+        return target.permuteArguments(newType, reorder);
     }
 
     private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
@@ -1697,8 +1616,7 @@
         else if (type.isPrimitive())
             return ValueConversions.identity(Wrapper.forPrimitiveType(type));
         else
-            return AdapterMethodHandle.makeRetypeRaw(
-                    MethodType.methodType(type, type), ValueConversions.identity());
+            return MethodHandleImpl.makeReferenceIdentity(type);
     }
 
     /**
@@ -1744,18 +1662,26 @@
         MethodHandle result = target;
         for (int i = 0; i < insCount; i++) {
             Object value = values[i];
-            Class<?> valueType = oldType.parameterType(pos+i);
-            value = checkValue(valueType, value);
-            if (pos == 0 && !valueType.isPrimitive()) {
-                // At least for now, make bound method handles a special case.
-                MethodHandle bmh = MethodHandleImpl.bindReceiver(result, value);
-                if (bmh != null) {
-                    result = bmh;
-                    continue;
+            Class<?> ptype = oldType.parameterType(pos+i);
+            if (ptype.isPrimitive()) {
+                char btype = 'I';
+                Wrapper w = Wrapper.forPrimitiveType(ptype);
+                switch (w) {
+                case LONG:    btype = 'J'; break;
+                case FLOAT:   btype = 'F'; break;
+                case DOUBLE:  btype = 'D'; break;
                 }
-                // else fall through to general adapter machinery
+                // perform unboxing and/or primitive conversion
+                value = w.convert(value, ptype);
+                result = result.bindArgument(pos, btype, value);
+                continue;
             }
-            result = MethodHandleImpl.bindArgument(result, pos, value);
+            value = ptype.cast(value);  // throw CCE if needed
+            if (pos == 0) {
+                result = result.bindReceiver(value);
+            } else {
+                result = result.bindArgument(pos, 'L', value);
+            }
         }
         return result;
     }
@@ -1805,16 +1731,17 @@
     public static
     MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
         MethodType oldType = target.type();  // get NPE
-        if (valueTypes.size() == 0)  return target;
+        int dropped = valueTypes.size();
+        MethodType.checkSlotCount(dropped);
+        if (dropped == 0)  return target;
         int outargs = oldType.parameterCount();
-        int inargs  = outargs + valueTypes.size();
+        int inargs  = outargs + dropped;
         if (pos < 0 || pos >= inargs)
             throw newIllegalArgumentException("no argument type to remove");
-        ArrayList<Class<?>> ptypes =
-                new ArrayList<Class<?>>(oldType.parameterList());
+        ArrayList<Class<?>> ptypes = new ArrayList<>(oldType.parameterList());
         ptypes.addAll(pos, valueTypes);
         MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
-        return MethodHandleImpl.dropArguments(target, newType, pos);
+        return target.dropArguments(newType, pos, dropped);
     }
 
     /**
@@ -1958,7 +1885,18 @@
         if (filterType.parameterCount() != 1
             || filterType.returnType() != targetType.parameterType(pos))
             throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
-        return MethodHandleImpl.filterArgument(target, pos, filter);
+        return MethodHandleImpl.makeCollectArguments(target, filter, pos, false);
+    }
+
+    // FIXME: Make this public in M1.
+    /*non-public*/ static
+    MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle collector) {
+        MethodType targetType = target.type();
+        MethodType filterType = collector.type();
+        if (filterType.returnType() != void.class &&
+            filterType.returnType() != targetType.parameterType(pos))
+            throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
+        return MethodHandleImpl.makeCollectArguments(target, collector, pos, false);
     }
 
     /**
@@ -2030,18 +1968,7 @@
             throw newIllegalArgumentException("target and filter types do not match", target, filter);
         // result = fold( lambda(retval, arg...) { filter(retval) },
         //                lambda(        arg...) { target(arg...) } )
-        MethodType newType = targetType.changeReturnType(filterType.returnType());
-        MethodHandle result = null;
-        if (AdapterMethodHandle.canCollectArguments(filterType, targetType, 0, false)) {
-            result = AdapterMethodHandle.makeCollectArguments(filter, target, 0, false);
-            if (result != null)  return result;
-        }
-        // FIXME: Too many nodes here.
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
-        MethodHandle returner = dropArguments(filter, filterValues, targetType.parameterList());
-        result = foldArguments(returner, target);
-        assert(result.type().equals(newType));
-        return result;
+        return MethodHandleImpl.makeCollectArguments(filter, target, 0, false);
     }
 
     /**
@@ -2139,9 +2066,7 @@
         if (!ok)
             throw misMatchedTypes("target and combiner types", targetType, combinerType);
         MethodType newType = targetType.dropParameterTypes(foldPos, afterInsertPos);
-        MethodHandle res = MethodHandleImpl.foldArguments(target, newType, foldPos, combiner);
-        if (res == null)  throw newIllegalArgumentException("cannot fold from "+newType+" to " +targetType);
-        return res;
+        return MethodHandleImpl.makeCollectArguments(target, combiner, foldPos, true);
     }
 
     /**
@@ -2282,6 +2207,8 @@
      */
     public static
     MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
+        if (!Throwable.class.isAssignableFrom(exType))
+            throw new ClassCastException(exType.getName());
         return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
     }
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodType.java b/jdk/src/share/classes/java/lang/invoke/MethodType.java
index adb2d77..c690dad 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodType.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodType.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,12 +26,14 @@
 package java.lang.invoke;
 
 import sun.invoke.util.Wrapper;
+import java.lang.ref.WeakReference;
+import java.lang.ref.ReferenceQueue;
 import java.util.Arrays;
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
 import sun.invoke.util.BytecodeDescriptor;
 import static java.lang.invoke.MethodHandleStatics.*;
+import sun.invoke.util.VerifyType;
 
 /**
  * A method type represents the arguments and return type accepted and
@@ -107,6 +109,38 @@
     /*trusted*/ Class<?> rtype() { return rtype; }
     /*trusted*/ Class<?>[] ptypes() { return ptypes; }
 
+    void setForm(MethodTypeForm f) { form = f; }
+
+    /** This number, mandated by the JVM spec as 255,
+     *  is the maximum number of <em>slots</em>
+     *  that any Java method can receive in its argument list.
+     *  It limits both JVM signatures and method type objects.
+     *  The longest possible invocation will look like
+     *  {@code staticMethod(arg1, arg2, ..., arg255)} or
+     *  {@code x.virtualMethod(arg1, arg2, ..., arg254)}.
+     */
+    /*non-public*/ static final int MAX_JVM_ARITY = 255;  // this is mandated by the JVM spec.
+
+    /** This number is the maximum arity of a method handle, 254.
+     *  It is derived from the absolute JVM-imposed arity by subtracting one,
+     *  which is the slot occupied by the method handle itself at the
+     *  beginning of the argument list used to invoke the method handle.
+     *  The longest possible invocation will look like
+     *  {@code mh.invoke(arg1, arg2, ..., arg254)}.
+     */
+    // Issue:  Should we allow MH.invokeWithArguments to go to the full 255?
+    /*non-public*/ static final int MAX_MH_ARITY = MAX_JVM_ARITY-1;  // deduct one for mh receiver
+
+    /** This number is the maximum arity of a method handle invoker, 253.
+     *  It is derived from the absolute JVM-imposed arity by subtracting two,
+     *  which are the slots occupied by invoke method handle, and the the
+     *  target method handle, which are both at the beginning of the argument
+     *  list used to invoke the target method handle.
+     *  The longest possible invocation will look like
+     *  {@code invokermh.invoke(targetmh, arg1, arg2, ..., arg253)}.
+     */
+    /*non-public*/ static final int MAX_MH_INVOKER_ARITY = MAX_MH_ARITY-1;  // deduct one more for invoker
+
     private static void checkRtype(Class<?> rtype) {
         rtype.equals(rtype);  // null check
     }
@@ -126,8 +160,10 @@
         checkSlotCount(ptypes.length + slots);
         return slots;
     }
-    private static void checkSlotCount(int count) {
-        if ((count & 0xFF) != count)
+    static void checkSlotCount(int count) {
+        assert((MAX_JVM_ARITY & (MAX_JVM_ARITY+1)) == 0);
+        // MAX_JVM_ARITY must be power of 2 minus 1 for following code trick to work:
+        if ((count & MAX_JVM_ARITY) != count)
             throw newIllegalArgumentException("bad parameter count "+count);
     }
     private static IndexOutOfBoundsException newIndexOutOfBoundsException(Object num) {
@@ -135,8 +171,7 @@
         return new IndexOutOfBoundsException(num.toString());
     }
 
-    static final HashMap<MethodType,MethodType> internTable
-            = new HashMap<MethodType, MethodType>();
+    static final WeakInternSet internTable = new WeakInternSet();
 
     static final Class<?>[] NO_PTYPES = {};
 
@@ -238,31 +273,17 @@
             ptypes = NO_PTYPES; trusted = true;
         }
         MethodType mt1 = new MethodType(rtype, ptypes);
-        MethodType mt0;
-        synchronized (internTable) {
-            mt0 = internTable.get(mt1);
-            if (mt0 != null)
-                return mt0;
-        }
+        MethodType mt0 = internTable.get(mt1);
+        if (mt0 != null)
+            return mt0;
         if (!trusted)
             // defensively copy the array passed in by the user
             mt1 = new MethodType(rtype, ptypes.clone());
         // promote the object to the Real Thing, and reprobe
         MethodTypeForm form = MethodTypeForm.findForm(mt1);
         mt1.form = form;
-        if (form.erasedType == mt1) {
-            // This is a principal (erased) type; show it to the JVM.
-            MethodHandleNatives.init(mt1);
-        }
-        synchronized (internTable) {
-            mt0 = internTable.get(mt1);
-            if (mt0 != null)
-                return mt0;
-            internTable.put(mt1, mt1);
-        }
-        return mt1;
+        return internTable.add(mt1);
     }
-
     private static final MethodType[] objectOnlyTypes = new MethodType[20];
 
     /**
@@ -394,6 +415,32 @@
         return insertParameterTypes(parameterCount(), ptypesToInsert);
     }
 
+     /**
+     * Finds or creates a method type with modified parameter types.
+     * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
+     * @param start  the position (zero-based) of the first replaced parameter type(s)
+     * @param end    the position (zero-based) after the last replaced parameter type(s)
+     * @param ptypesToInsert zero or more new parameter types to insert into the parameter list
+     * @return the same type, except with the selected parameter(s) replaced
+     * @throws IndexOutOfBoundsException if {@code start} is negative or greater than {@code parameterCount()}
+     *                                  or if {@code end} is negative or greater than {@code parameterCount()}
+     *                                  or if {@code start} is greater than {@code end}
+     * @throws IllegalArgumentException if any element of {@code ptypesToInsert} is {@code void.class}
+     *                                  or if the resulting method type would have more than 255 parameter slots
+     * @throws NullPointerException if {@code ptypesToInsert} or any of its elements is null
+     */
+    /*non-public*/ MethodType replaceParameterTypes(int start, int end, Class<?>... ptypesToInsert) {
+        if (start == end)
+            return insertParameterTypes(start, ptypesToInsert);
+        int len = ptypes.length;
+        if (!(0 <= start && start <= end && end <= len))
+            throw newIndexOutOfBoundsException("start="+start+" end="+end);
+        int ilen = ptypesToInsert.length;
+        if (ilen == 0)
+            return dropParameterTypes(start, end);
+        return dropParameterTypes(start, end).insertParameterTypes(start, ptypesToInsert);
+    }
+
     /**
      * Finds or creates a method type with some parameter types omitted.
      * Convenience method for {@link #methodType(java.lang.Class, java.lang.Class[]) methodType}.
@@ -474,6 +521,23 @@
     }
 
     /**
+     * Erases all reference types to {@code Object}, and all subword types to {@code int}.
+     * This is the reduced type polymorphism used by private methods
+     * such as {@link MethodHandle#invokeBasic invokeBasic}.
+     * @return a version of the original type with all reference and subword types replaced
+     */
+    /*non-public*/ MethodType basicType() {
+        return form.basicType();
+    }
+
+    /**
+     * @return a version of the original type with MethodHandle prepended as the first argument
+     */
+    /*non-public*/ MethodType invokerType() {
+        return insertParameterTypes(0, MethodHandle.class);
+    }
+
+    /**
      * Converts all types, both reference and primitive, to {@code Object}.
      * Convenience method for {@link #genericMethodType(int) genericMethodType}.
      * The expression {@code type.wrap().erase()} produces the same value
@@ -567,6 +631,11 @@
         return Collections.unmodifiableList(Arrays.asList(ptypes));
     }
 
+    /*non-public*/ Class<?> lastParameterType() {
+        int len = ptypes.length;
+        return len == 0 ? void.class : ptypes[len-1];
+    }
+
     /**
      * Presents the parameter types as an array (a convenience method).
      * Changes to the array will not result in changes to the type.
@@ -636,6 +705,26 @@
 
 
     /*non-public*/
+    boolean isViewableAs(MethodType newType) {
+        if (!VerifyType.isNullConversion(returnType(), newType.returnType()))
+            return false;
+        int argc = parameterCount();
+        if (argc != newType.parameterCount())
+            return false;
+        for (int i = 0; i < argc; i++) {
+            if (!VerifyType.isNullConversion(newType.parameterType(i), parameterType(i)))
+                return false;
+        }
+        return true;
+    }
+    /*non-public*/
+    boolean isCastableTo(MethodType newType) {
+        int argc = parameterCount();
+        if (argc != newType.parameterCount())
+            return false;
+        return true;
+    }
+    /*non-public*/
     boolean isConvertibleTo(MethodType newType) {
         if (!canConvert(returnType(), newType.returnType()))
             return false;
@@ -818,6 +907,10 @@
         return BytecodeDescriptor.unparse(this);
     }
 
+    /*non-public*/ static String toFieldDescriptorString(Class<?> cls) {
+        return BytecodeDescriptor.unparse(cls);
+    }
+
     /// Serialization.
 
     /**
@@ -890,18 +983,17 @@
         // store them into the implementation-specific final fields.
         checkRtype(rtype);
         checkPtypes(ptypes);
-        unsafe.putObject(this, rtypeOffset, rtype);
-        unsafe.putObject(this, ptypesOffset, ptypes);
+        UNSAFE.putObject(this, rtypeOffset, rtype);
+        UNSAFE.putObject(this, ptypesOffset, ptypes);
     }
 
     // Support for resetting final fields while deserializing
-    private static final sun.misc.Unsafe unsafe = sun.misc.Unsafe.getUnsafe();
     private static final long rtypeOffset, ptypesOffset;
     static {
         try {
-            rtypeOffset = unsafe.objectFieldOffset
+            rtypeOffset = UNSAFE.objectFieldOffset
                 (MethodType.class.getDeclaredField("rtype"));
-            ptypesOffset = unsafe.objectFieldOffset
+            ptypesOffset = UNSAFE.objectFieldOffset
                 (MethodType.class.getDeclaredField("ptypes"));
         } catch (Exception ex) {
             throw new Error(ex);
@@ -919,4 +1011,269 @@
         // Verify all operands, and make sure ptypes is unshared:
         return methodType(rtype, ptypes);
     }
+
+    /**
+     * Weak intern set based on implementation of the <tt>HashSet</tt> and
+     * <tt>WeakHashMap</tt>, with <em>weak values</em>.  Note: <tt>null</tt>
+     * values will yield <tt>NullPointerException</tt>
+     * Refer to implementation of WeakInternSet for details.
+     *
+     * @see         java.util.HashMap
+     * @see         java.util.HashSet
+     * @see         java.util.WeakHashMap
+     * @see         java.lang.ref.WeakReference
+     */
+    private static class WeakInternSet {
+        // The default initial capacity -- MUST be a power of two.
+        private static final int DEFAULT_INITIAL_CAPACITY = 16;
+
+        // The maximum capacity, used if a higher value is implicitly specified
+        // by either of the constructors with arguments.
+        // MUST be a power of two <= 1<<30.
+        private static final int MAXIMUM_CAPACITY = 1 << 30;
+
+        // The load factor used when none specified in constructor.
+        private static final float DEFAULT_LOAD_FACTOR = 0.75f;
+
+        // The table, resized as necessary. Length MUST Always be a power of two.
+        private Entry[] table;
+
+        // The number of entries contained in this set.
+        private int size;
+
+        // The next size value at which to resize (capacity * load factor).
+        private int threshold;
+
+        // The load factor for the hash table.
+        private final float loadFactor;
+
+        // Reference queue for cleared WeakEntries
+        private final ReferenceQueue<Object> queue = new ReferenceQueue<>();
+
+        private Entry[] newTable(int n) {
+            return new Entry[n];
+        }
+
+        /**
+         * Constructs a new, empty <tt>WeakInternSet</tt> with the default initial
+         * capacity (16) and load factor (0.75).
+         */
+        WeakInternSet() {
+            this.loadFactor = DEFAULT_LOAD_FACTOR;
+            threshold = DEFAULT_INITIAL_CAPACITY;
+            table = newTable(DEFAULT_INITIAL_CAPACITY);
+        }
+
+        /**
+         * Applies a supplemental hash function to a given hashCode, which
+         * defends against poor quality hash functions.  This is critical
+         * because hashing uses power-of-two length hash tables, that
+         * otherwise encounter collisions for hashCodes that do not differ
+         * in lower bits.
+         * @param h preliminary hash code value
+         * @return supplemental hash code value
+         */
+        private static int hash(int h) {
+            // This function ensures that hashCodes that differ only by
+            // constant multiples at each bit position have a bounded
+            // number of collisions (approximately 8 at default load factor).
+            h ^= (h >>> 20) ^ (h >>> 12);
+            return h ^ (h >>> 7) ^ (h >>> 4);
+        }
+
+        /**
+         * Checks for equality of non-null reference x and possibly-null y.  By
+         * default uses Object.equals.
+         * @param x first object to compare
+         * @param y second object to compare
+         * @return <tt>true</tt> if objects are equal
+         */
+        private static boolean eq(Object x, Object y) {
+            return x == y || x.equals(y);
+        }
+
+        /**
+         * Returns index for hash code h.
+         * @param h      raw hash code
+         * @param length length of table (power of 2)
+         * @return index in table
+         */
+        private static int indexFor(int h, int length) {
+            return h & (length-1);
+        }
+
+        /**
+         * Expunges stale entries from the table.
+         */
+        private void expungeStaleEntries() {
+            for (Object x; (x = queue.poll()) != null; ) {
+                synchronized (queue) {
+                    Entry entry = (Entry) x;
+                    int i = indexFor(entry.hash, table.length);
+                    Entry prev = table[i];
+                    Entry p = prev;
+                    while (p != null) {
+                        Entry next = p.next;
+                        if (p == entry) {
+                            if (prev == entry)
+                                table[i] = next;
+                            else
+                                prev.next = next;
+                            entry.next = null;
+                            size--;
+                            break;
+                        }
+                        prev = p;
+                        p = next;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Returns the table after first expunging stale entries.
+         * @return an expunged hash table
+         */
+        private Entry[] getTable() {
+            expungeStaleEntries();
+            return table;
+        }
+
+        /**
+         * Returns the entry to which the specified value is mapped,
+         * or {@code null} if this set contains no entry for the value.
+         *
+         * <p>More formally, if this set contains an entry for value
+         * {@code entry} to a value {@code value} such that
+         * {@code entry.equals(value)}, then this method returns {@code entry};
+         * otherwise it returns {@code null}.
+         *
+         * @param value value to search for in set
+         * @return interned value if in set, otherwise <tt>null</tt>
+         */
+        synchronized MethodType get(MethodType value) {
+            int h = hash(value.hashCode());
+            Entry[] tab = getTable();
+            int index = indexFor(h, tab.length);
+            Entry e = tab[index];
+            MethodType g;
+            while (e != null) {
+                if (e.hash == h && eq(value, g = e.get()))
+                    return g;
+                e = e.next;
+            }
+            return null;
+        }
+
+        /**
+         * Attempts to add the specified value to the set and returns same value.
+         * If the set previously contained an entry for this value, the old
+         * value is left untouched and returned as the result.
+         *
+         * @param value value to be added
+         * @return the previous entry associated with <tt>value</tt>, or
+         *         <tt>value</tt> if there was no previous entry found
+         */
+        synchronized MethodType add(MethodType value) {
+            int h = hash(value.hashCode());
+            Entry[] tab = getTable();
+            int i = indexFor(h, tab.length);
+            MethodType g;
+            for (Entry e = tab[i]; e != null; e = e.next) {
+                if (h == e.hash && eq(value, g = e.get())) {
+                    return g;
+                }
+            }
+            Entry e = tab[i];
+            tab[i] = new Entry(value, queue, h, e);
+            if (++size >= threshold)
+                resize(tab.length * 2);
+            return value;
+        }
+
+        /**
+         * Rehashes the contents of this set into a new array with a
+         * larger capacity.  This method is called automatically when the
+         * number of keys in this set reaches its threshold.
+         *
+         * If current capacity is MAXIMUM_CAPACITY, this method does not
+         * resize the set, but sets threshold to Integer.MAX_VALUE.
+         * This has the effect of preventing future calls.
+         *
+         * @param newCapacity the new capacity, MUST be a power of two;
+         *        must be greater than current capacity unless current
+         *        capacity is MAXIMUM_CAPACITY (in which case value
+         *        is irrelevant)
+         */
+        private void resize(int newCapacity) {
+            Entry[] oldTable = getTable();
+            int oldCapacity = oldTable.length;
+            if (oldCapacity == MAXIMUM_CAPACITY) {
+                threshold = Integer.MAX_VALUE;
+                return;
+            }
+
+            Entry[] newTable = newTable(newCapacity);
+            transfer(oldTable, newTable);
+            table = newTable;
+
+            /*
+             * If ignoring null elements and processing ref queue caused massive
+             * shrinkage, then restore old table.  This should be rare, but avoids
+             * unbounded expansion of garbage-filled tables.
+             */
+            if (size >= threshold / 2) {
+                threshold = (int)(newCapacity * loadFactor);
+            } else {
+                expungeStaleEntries();
+                transfer(newTable, oldTable);
+                table = oldTable;
+            }
+        }
+
+        /**
+         * Transfers all entries from src to dest tables
+         * @param src  original table
+         * @param dest new table
+         */
+        private void transfer(Entry[] src, Entry[] dest) {
+            for (int j = 0; j < src.length; ++j) {
+                Entry e = src[j];
+                src[j] = null;
+                while (e != null) {
+                    Entry next = e.next;
+                    MethodType key = e.get();
+                    if (key == null) {
+                        e.next = null;  // Help GC
+                        size--;
+                    } else {
+                        int i = indexFor(e.hash, dest.length);
+                        e.next = dest[i];
+                        dest[i] = e;
+                    }
+                    e = next;
+                }
+            }
+        }
+
+        /**
+         * The entries in this hash table extend WeakReference, using its main ref
+         * field as the key.
+         */
+        private static class Entry extends WeakReference<MethodType> {
+            final int hash;
+            Entry next;
+
+            /**
+             * Creates new entry.
+             */
+            Entry(MethodType key,
+                  ReferenceQueue<Object> queue,
+                  int hash, Entry next) {
+                super(key, queue);
+                this.hash  = hash;
+                this.next  = next;
+            }
+        }
+    }
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java
index 817dca7..83ccc1a 100644
--- a/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java
+++ b/jdk/src/share/classes/java/lang/invoke/MethodTypeForm.java
@@ -27,6 +27,7 @@
 
 import sun.invoke.util.Wrapper;
 import static java.lang.invoke.MethodHandleStatics.*;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
 
 /**
  * Shared information for a group of method types, which differ
@@ -41,31 +42,70 @@
  * No more than half of these are likely to be loaded at once.
  * @author John Rose
  */
-class MethodTypeForm {
+final class MethodTypeForm {
     final int[] argToSlotTable, slotToArgTable;
     final long argCounts;               // packed slot & value counts
     final long primCounts;              // packed prim & double counts
     final int vmslots;                  // total number of parameter slots
-    private Object vmlayout;            // vm-specific information for calls
     final MethodType erasedType;        // the canonical erasure
-
-    /*lazy*/ MethodType primsAsBoxes;   // replace prims by wrappers
-    /*lazy*/ MethodType primArgsAsBoxes; // wrap args only; make raw return
-    /*lazy*/ MethodType primsAsInts;    // replace prims by int/long
-    /*lazy*/ MethodType primsAsLongs;   // replace prims by long
-    /*lazy*/ MethodType primsAtEnd;     // reorder primitives to the end
+    final MethodType basicType;         // the canonical erasure, with primitives simplified
 
     // Cached adapter information:
-    /*lazy*/ ToGeneric   toGeneric;     // convert cs. with prims to w/o
-    /*lazy*/ FromGeneric fromGeneric;   // convert cs. w/o prims to with
-    /*lazy*/ SpreadGeneric[] spreadGeneric; // expand one argument to many
-    /*lazy*/ FilterGeneric filterGeneric; // convert argument(s) on the fly
-    /*lazy*/ MethodHandle genericInvoker; // hook for inexact invoke
+    /*lazy*/ MethodHandle genericInvoker; // JVM hook for inexact invoke
+    /*lazy*/ MethodHandle basicInvoker;   // cached instance of MH.invokeBasic
+    /*lazy*/ MethodHandle namedFunctionInvoker; // cached helper for LF.NamedFunction
+
+    // Cached lambda form information, for basic types only:
+    final LambdaForm[] lambdaForms;
+    // Indexes into lambdaForms:
+    static final int
+            LF_INVVIRTUAL     =  0,  // DMH invokeVirtual
+            LF_INVSTATIC      =  1,
+            LF_INVSPECIAL     =  2,
+            LF_NEWINVSPECIAL  =  3,
+            LF_INVINTERFACE   =  4,
+            LF_INVSTATIC_INIT =  5,  // DMH invokeStatic with <clinit> barrier
+            LF_INTERPRET      =  6,  // LF interpreter
+            LF_COUNTER        =  7,  // CMH wrapper
+            LF_REINVOKE       =  8,  // other wrapper
+            LF_EX_LINKER      =  9,  // invokeExact_MT
+            LF_EX_INVOKER     = 10,  // invokeExact MH
+            LF_GEN_LINKER     = 11,
+            LF_GEN_INVOKER    = 12,
+            LF_CS_LINKER      = 13,  // linkToCallSite_CS
+            LF_LIMIT          = 14;
 
     public MethodType erasedType() {
         return erasedType;
     }
 
+    public MethodType basicType() {
+        return basicType;
+    }
+
+    public LambdaForm cachedLambdaForm(int which) {
+        return lambdaForms[which];
+    }
+
+    public LambdaForm setCachedLambdaForm(int which, LambdaForm form) {
+        // Should we perform some sort of CAS, to avoid racy duplication?
+        return lambdaForms[which] = form;
+    }
+
+    public MethodHandle basicInvoker() {
+        assert(erasedType == basicType) : "erasedType: " + erasedType + " != basicType: " + basicType;  // primitives must be flattened also
+        MethodHandle invoker = basicInvoker;
+        if (invoker != null)  return invoker;
+        invoker = basicType.invokers().makeBasicInvoker();
+        basicInvoker = invoker;
+        return invoker;
+    }
+
+    /**
+     * Build an MTF for a given type, which must have all references erased to Object.
+     * This MTF will stand for that type and all un-erased variations.
+     * Eagerly compute some basic properties of the type, common to all variations.
+     */
     protected MethodTypeForm(MethodType erasedType) {
         this.erasedType = erasedType;
 
@@ -79,26 +119,41 @@
 
         // Walk the argument types, looking for primitives.
         int pac = 0, lac = 0, prc = 0, lrc = 0;
-        Class<?> epts[] = ptypes;
+        Class<?>[] epts = ptypes;
+        Class<?>[] bpts = epts;
         for (int i = 0; i < epts.length; i++) {
             Class<?> pt = epts[i];
             if (pt != Object.class) {
-                assert(pt.isPrimitive());
                 ++pac;
-                if (hasTwoArgSlots(pt))  ++lac;
+                Wrapper w = Wrapper.forPrimitiveType(pt);
+                if (w.isDoubleWord())  ++lac;
+                if (w.isSubwordOrInt() && pt != int.class) {
+                    if (bpts == epts)
+                        bpts = bpts.clone();
+                    bpts[i] = int.class;
+                }
             }
         }
         pslotCount += lac;                  // #slots = #args + #longs
         Class<?> rt = erasedType.returnType();
+        Class<?> bt = rt;
         if (rt != Object.class) {
             ++prc;          // even void.class counts as a prim here
-            if (hasTwoArgSlots(rt))  ++lrc;
+            Wrapper w = Wrapper.forPrimitiveType(rt);
+            if (w.isDoubleWord())  ++lrc;
+            if (w.isSubwordOrInt() && rt != int.class)
+                bt = int.class;
             // adjust #slots, #args
             if (rt == void.class)
                 rtypeCount = rslotCount = 0;
             else
                 rslotCount += lrc;
         }
+        if (epts == bpts && bt == rt) {
+            this.basicType = erasedType;
+        } else {
+            this.basicType = MethodType.makeImpl(bt, bpts, true);
+        }
         if (lac != 0) {
             int slot = ptypeCount + lac;
             slotToArgTab = new int[slot+1];
@@ -106,7 +161,8 @@
             argToSlotTab[0] = slot;  // argument "-1" is past end of slots
             for (int i = 0; i < epts.length; i++) {
                 Class<?> pt = epts[i];
-                if (hasTwoArgSlots(pt))  --slot;
+                Wrapper w = Wrapper.forBasicType(pt);
+                if (w.isDoubleWord())  --slot;
                 --slot;
                 slotToArgTab[slot] = i+1; // "+1" see argSlotToParameter note
                 argToSlotTab[1+i]  = slot;
@@ -134,164 +190,13 @@
         // send a few bits down to the JVM:
         this.vmslots = parameterSlotCount();
 
-        // short circuit some no-op canonicalizations:
-        if (!hasPrimitives()) {
-            primsAsBoxes = erasedType;
-            primArgsAsBoxes = erasedType;
-            primsAsInts  = erasedType;
-            primsAsLongs = erasedType;
-            primsAtEnd   = erasedType;
+        if (basicType == erasedType) {
+            lambdaForms = new LambdaForm[LF_LIMIT];
+        } else {
+            lambdaForms = null;  // could be basicType.form().lambdaForms;
         }
     }
 
-    /** Turn all primitive types to corresponding wrapper types.
-     */
-    public MethodType primsAsBoxes() {
-        MethodType ct = primsAsBoxes;
-        if (ct != null)  return ct;
-        MethodType t = erasedType;
-        ct = canonicalize(erasedType, WRAP, WRAP);
-        if (ct == null)  ct = t;  // no prims to box
-        return primsAsBoxes = ct;
-    }
-
-    /** Turn all primitive argument types to corresponding wrapper types.
-     *  Subword and void return types are promoted to int.
-     */
-    public MethodType primArgsAsBoxes() {
-        MethodType ct = primArgsAsBoxes;
-        if (ct != null)  return ct;
-        MethodType t = erasedType;
-        ct = canonicalize(erasedType, RAW_RETURN, WRAP);
-        if (ct == null)  ct = t;  // no prims to box
-        return primArgsAsBoxes = ct;
-    }
-
-    /** Turn all primitive types to either int or long.
-     *  Floating point return types are not changed, because
-     *  they may require special calling sequences.
-     *  A void return value is turned to int.
-     */
-    public MethodType primsAsInts() {
-        MethodType ct = primsAsInts;
-        if (ct != null)  return ct;
-        MethodType t = erasedType;
-        ct = canonicalize(t, RAW_RETURN, INTS);
-        if (ct == null)  ct = t;  // no prims to int-ify
-        return primsAsInts = ct;
-    }
-
-    /** Turn all primitive types to either int or long.
-     *  Floating point return types are not changed, because
-     *  they may require special calling sequences.
-     *  A void return value is turned to int.
-     */
-    public MethodType primsAsLongs() {
-        MethodType ct = primsAsLongs;
-        if (ct != null)  return ct;
-        MethodType t = erasedType;
-        ct = canonicalize(t, RAW_RETURN, LONGS);
-        if (ct == null)  ct = t;  // no prims to int-ify
-        return primsAsLongs = ct;
-    }
-
-    /** Stably sort parameters into 3 buckets: ref, int, long. */
-    public MethodType primsAtEnd() {
-        MethodType ct = primsAtEnd;
-        if (ct != null)  return ct;
-        MethodType t = erasedType;
-
-        int pac = primitiveParameterCount();
-        if (pac == 0)
-            return primsAtEnd = t;
-
-        int argc = parameterCount();
-        int lac = longPrimitiveParameterCount();
-        if (pac == argc && (lac == 0 || lac == argc))
-            return primsAtEnd = t;
-
-        // known to have a mix of 2 or 3 of ref, int, long
-        int[] reorder = primsAtEndOrder(t);
-        ct = reorderParameters(t, reorder, null);
-        //System.out.println("t="+t+" / reorder="+java.util.Arrays.toString(reorder)+" => "+ct);
-        return primsAtEnd = ct;
-    }
-
-    /** Compute a new ordering of parameters so that all references
-     *  are before all ints or longs, and all ints are before all longs.
-     *  For this ordering, doubles count as longs, and all other primitive
-     *  values count as ints.
-     *  As a special case, if the parameters are already in the specified
-     *  order, this method returns a null reference, rather than an array
-     *  specifying a null permutation.
-     *  <p>
-     *  For example, the type {@code (int,boolean,int,Object,String)void}
-     *  produces the order {@code {3,4,0,1,2}}, the type
-     *  {@code (long,int,String)void} produces {@code {2,1,2}}, and
-     *  the type {@code (Object,int)Object} produces {@code null}.
-     */
-    public static int[] primsAtEndOrder(MethodType mt) {
-        MethodTypeForm form = mt.form();
-        if (form.primsAtEnd == form.erasedType)
-            // quick check shows no reordering is necessary
-            return null;
-
-        int argc = form.parameterCount();
-        int[] paramOrder = new int[argc];
-
-        // 3-way bucket sort:
-        int pac = form.primitiveParameterCount();
-        int lac = form.longPrimitiveParameterCount();
-        int rfill = 0, ifill = argc - pac, lfill = argc - lac;
-
-        Class<?>[] ptypes = mt.ptypes();
-        boolean changed = false;
-        for (int i = 0; i < ptypes.length; i++) {
-            Class<?> pt = ptypes[i];
-            int ord;
-            if (!pt.isPrimitive())             ord = rfill++;
-            else if (!hasTwoArgSlots(pt))      ord = ifill++;
-            else                               ord = lfill++;
-            if (ord != i)  changed = true;
-            assert(paramOrder[ord] == 0);
-            paramOrder[ord] = i;
-        }
-        assert(rfill == argc - pac && ifill == argc - lac && lfill == argc);
-        if (!changed) {
-            form.primsAtEnd = form.erasedType;
-            return null;
-        }
-        return paramOrder;
-    }
-
-    /** Put the existing parameters of mt into a new order, given by newParamOrder.
-     *  The third argument is logically appended to mt.parameterArray,
-     *  so that elements of newParamOrder can index either pre-existing or
-     *  new parameter types.
-     */
-    public static MethodType reorderParameters(MethodType mt, int[] newParamOrder, Class<?>[] moreParams) {
-        if (newParamOrder == null)  return mt;  // no-op reordering
-        Class<?>[] ptypes = mt.ptypes();
-        Class<?>[] ntypes = new Class<?>[newParamOrder.length];
-        int maxParam = ptypes.length + (moreParams == null ? 0 : moreParams.length);
-        boolean changed = (ntypes.length != ptypes.length);
-        for (int i = 0; i < newParamOrder.length; i++) {
-            int param = newParamOrder[i];
-            if (param != i)  changed = true;
-            Class<?> nt;
-            if (param < ptypes.length)   nt = ptypes[param];
-            else if (param == maxParam)  nt = mt.returnType();
-            else                         nt = moreParams[param - ptypes.length];
-            ntypes[i] = nt;
-        }
-        if (!changed)  return mt;
-        return MethodType.makeImpl(mt.returnType(), ntypes, true);
-    }
-
-    private static boolean hasTwoArgSlots(Class<?> type) {
-        return type == long.class || type == double.class;
-    }
-
     private static long pack(int a, int b, int c, int d) {
         assert(((a|b|c|d) & ~0xFFFF) == 0);
         long hw = ((a << 16) | b), lw = ((c << 16) | d);
@@ -329,11 +234,11 @@
     public boolean hasPrimitives() {
         return primCounts != 0;
     }
-//    public boolean hasNonVoidPrimitives() {
-//        if (primCounts == 0)  return false;
-//        if (primitiveParameterCount() != 0)  return true;
-//        return (primitiveReturnCount() != 0 && returnCount() != 0);
-//    }
+    public boolean hasNonVoidPrimitives() {
+        if (primCounts == 0)  return false;
+        if (primitiveParameterCount() != 0)  return true;
+        return (primitiveReturnCount() != 0 && returnCount() != 0);
+    }
     public boolean hasLongPrimitives() {
         return (longPrimitiveParameterCount() | longPrimitiveReturnCount()) != 0;
     }
@@ -459,18 +364,6 @@
         return cs;
     }
 
-    /*non-public*/ void notifyGenericMethodType() {
-        if (genericInvoker != null)  return;
-        try {
-            // Trigger adapter creation.
-            genericInvoker = InvokeGeneric.generalInvokerOf(erasedType);
-        } catch (Exception ex) {
-            Error err = new InternalError("Exception while resolving inexact invoke");
-            err.initCause(ex);
-            throw err;
-        }
-    }
-
     @Override
     public String toString() {
         return "Form"+erasedType;
diff --git a/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java b/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java
new file mode 100644
index 0000000..1cd6daf
--- /dev/null
+++ b/jdk/src/share/classes/java/lang/invoke/SimpleMethodHandle.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright (c) 2008, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package java.lang.invoke;
+
+import static java.lang.invoke.LambdaForm.*;
+import static java.lang.invoke.MethodHandleNatives.Constants.*;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * A method handle whose behavior is determined only by its LambdaForm.
+ * @author jrose
+ */
+final class SimpleMethodHandle extends MethodHandle {
+    private SimpleMethodHandle(MethodType type, LambdaForm form) {
+        super(type, form);
+    }
+
+    /*non-public*/ static SimpleMethodHandle make(MethodType type, LambdaForm form) {
+        return new SimpleMethodHandle(type, form);
+    }
+
+    @Override
+    MethodHandle bindArgument(int pos, char basicType, Object value) {
+        MethodType type2 = type().dropParameterTypes(pos, pos+1);
+        LambdaForm form2 = internalForm().bind(1+pos, BoundMethodHandle.SpeciesData.EMPTY);
+        return BoundMethodHandle.bindSingle(type2, form2, basicType, value);
+    }
+
+    @Override
+    MethodHandle dropArguments(MethodType srcType, int pos, int drops) {
+        LambdaForm newForm = internalForm().addArguments(pos, srcType.parameterList().subList(pos, pos+drops));
+        return new SimpleMethodHandle(srcType, newForm);
+    }
+
+    @Override
+    MethodHandle permuteArguments(MethodType newType, int[] reorder) {
+        LambdaForm form2 = internalForm().permuteArguments(1, reorder, basicTypes(newType.parameterList()));
+        return new SimpleMethodHandle(newType, form2);
+    }
+
+    @Override
+    MethodHandle copyWith(MethodType mt, LambdaForm lf) {
+        return new SimpleMethodHandle(mt, lf);
+    }
+
+}
diff --git a/jdk/src/share/classes/java/lang/invoke/SpreadGeneric.java b/jdk/src/share/classes/java/lang/invoke/SpreadGeneric.java
deleted file mode 100644
index e2d385e..0000000
--- a/jdk/src/share/classes/java/lang/invoke/SpreadGeneric.java
+++ /dev/null
@@ -1,682 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import sun.invoke.util.ValueConversions;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * Generic spread adapter.
- * Expands a final argument into multiple (zero or more) arguments, keeping the others the same.
- * @author jrose
- */
-class SpreadGeneric {
-    // type for the outgoing call
-    private final MethodType targetType;
-    // number of arguments to spread
-    private final int spreadCount;
-    // prototype adapter (clone and customize for each new target!)
-    private final Adapter adapter;
-    // entry point for adapter (Adapter mh, a...) => ...
-    private final MethodHandle entryPoint;
-
-    /** Compute and cache information common to all spreading adapters
-     *  that accept calls of the given (generic) type.
-     */
-    private SpreadGeneric(MethodType targetType, int spreadCount) {
-        assert(targetType == targetType.generic());
-        this.targetType = targetType;
-        this.spreadCount = spreadCount;
-        // the target invoker will generally need casts on reference arguments
-        MethodHandle[] ep = { null };
-        Adapter ad = findAdapter(this, ep);
-        if (ad != null) {
-            this.adapter = ad;
-            this.entryPoint = ep[0];
-            return;
-        }
-        this.adapter = buildAdapterFromBytecodes(targetType, spreadCount, ep);
-        this.entryPoint = ep[0];
-    }
-
-    static {
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
-    }
-
-    /** From targetType remove the last spreadCount arguments, and instead
-     *  append a simple Object argument.
-     */
-    static MethodType preSpreadType(MethodType targetType, int spreadCount) {
-        @SuppressWarnings("unchecked")
-        ArrayList<Class<?>> params = new ArrayList(targetType.parameterList());
-        int outargs = params.size();
-        params.subList(outargs - spreadCount, outargs).clear();
-        params.add(Object.class);
-        return MethodType.methodType(targetType.returnType(), params);
-    }
-
-    MethodHandle makeInstance(MethodHandle target) {
-        MethodType type = target.type();
-        if (type != targetType) {
-            throw new UnsupportedOperationException("NYI type="+type);
-        }
-        return adapter.makeInstance(this, target);
-    }
-
-    /** Build an adapter of the given generic type, which invokes typedTarget
-     *  on the incoming arguments, after unboxing as necessary.
-     *  The return value is boxed if necessary.
-     * @param genericType  the required type of the result
-     * @param typedTarget the target
-     * @return an adapter method handle
-     */
-    public static MethodHandle make(MethodHandle target, int spreadCount) {
-        MethodType type = target.type();
-        MethodType gtype = type.generic();
-        if (type == gtype) {
-            return SpreadGeneric.of(type, spreadCount).makeInstance(target);
-        } else {
-            MethodHandle gtarget = FromGeneric.make(target);
-            assert(gtarget.type() == gtype);
-            MethodHandle gspread = SpreadGeneric.of(gtype, spreadCount).makeInstance(gtarget);
-            return ToGeneric.make(preSpreadType(type, spreadCount), gspread);
-        }
-    }
-
-    /** Return the adapter information for this type's erasure. */
-    static SpreadGeneric of(MethodType targetType, int spreadCount) {
-        if (targetType != targetType.generic())
-            throw new UnsupportedOperationException("NYI type="+targetType);
-        MethodTypeForm form = targetType.form();
-        int outcount = form.parameterCount();
-        assert(spreadCount <= outcount);
-        SpreadGeneric[] spreadGens = form.spreadGeneric;
-        if (spreadGens == null)
-            form.spreadGeneric = spreadGens = new SpreadGeneric[outcount+1];
-        SpreadGeneric spreadGen = spreadGens[spreadCount];
-        if (spreadGen == null)
-            spreadGens[spreadCount] = spreadGen = new SpreadGeneric(form.erasedType(), spreadCount);
-        return spreadGen;
-    }
-
-    String debugString() {
-        return getClass().getSimpleName()+targetType+"["+spreadCount+"]";
-    }
-
-    // This mini-api is called from an Adapter to manage the spread.
-    /** A check/coercion that happens once before any selections. */
-    protected Object check(Object av, int n) {
-        checkSpreadArgument(av, n);
-        return av;
-    }
-
-    /** The selection operator for spreading; note that it takes Object not Object[]. */
-    protected Object select(Object av, int n) {
-        return ((Object[])av)[n];
-    }
-    /*
-    protected int select_I(Object av, int n) {
-        // maybe return ((int[])select)[n]
-        throw new UnsupportedOperationException("subclass resp.");
-    }
-    protected int select_J(Object av, int n) {
-        // maybe return ((long[])select)[n]
-        throw new UnsupportedOperationException("subclass resp.");
-    }
-    // */
-
-    /* Create an adapter that handles spreading calls for the given type. */
-    static Adapter findAdapter(SpreadGeneric outer, MethodHandle[] ep) {
-        MethodType targetType = outer.targetType;
-        int spreadCount = outer.spreadCount;
-        int outargs = targetType.parameterCount();
-        int inargs = outargs - spreadCount;
-        if (inargs < 0)  return null;
-        MethodType entryType = MethodType.genericMethodType(inargs + 1); // 1 for av
-        String cname1 = "S" + outargs;
-        String[] cnames = { cname1 };
-        String iname = "invoke_S"+spreadCount;
-        // e.g., D5I2, D5, L5I2, L5; invoke_D5
-        for (String cname : cnames) {
-            Class<? extends Adapter> acls = Adapter.findSubClass(cname);
-            if (acls == null)  continue;
-            // see if it has the required invoke method
-            MethodHandle entryPoint = null;
-            try {
-                entryPoint = IMPL_LOOKUP.findSpecial(acls, iname, entryType, acls);
-            } catch (ReflectiveOperationException ex) {
-            }
-            if (entryPoint == null)  continue;
-            Constructor<? extends Adapter> ctor = null;
-            try {
-                ctor = acls.getDeclaredConstructor(SpreadGeneric.class);
-            } catch (NoSuchMethodException ex) {
-            } catch (SecurityException ex) {
-            }
-            if (ctor == null)  continue;
-            try {
-                // Produce an instance configured as a prototype.
-                Adapter ad = ctor.newInstance(outer);
-                ep[0] = entryPoint;
-                return ad;
-            } catch (IllegalArgumentException ex) {
-            } catch (InvocationTargetException wex) {
-                Throwable ex = wex.getTargetException();
-                if (ex instanceof Error)  throw (Error)ex;
-                if (ex instanceof RuntimeException)  throw (RuntimeException)ex;
-            } catch (InstantiationException ex) {
-            } catch (IllegalAccessException ex) {
-            }
-        }
-        return null;
-    }
-
-    static Adapter buildAdapterFromBytecodes(MethodType targetType,
-            int spreadCount, MethodHandle[] ep) {
-        throw new UnsupportedOperationException("NYI");
-    }
-
-    /**
-     * This adapter takes some untyped arguments, and returns an untyped result.
-     * Internally, it applies the invoker to the target, which causes the
-     * objects to be unboxed; the result is a raw type in L/I/J/F/D.
-     * This result is passed to convert, which is responsible for
-     * converting the raw result into a boxed object.
-     * The invoker is kept separate from the target because it can be
-     * generated once per type erasure family, and reused across adapters.
-     */
-    static abstract class Adapter extends BoundMethodHandle {
-        /*
-         * class X<<R,int M,int N>> extends Adapter {
-         *   (Object**N)=>R target;
-         *   static int S = N-M;
-         *   Object invoke(Object**M a, Object v) = target(a..., v[0]...v[S-1]);
-         * }
-         */
-        protected final SpreadGeneric outer;
-        protected final MethodHandle target;   // (any**N) => R
-
-        @Override
-        String debugString() {
-            return addTypeString(target, this);
-        }
-
-        static final MethodHandle NO_ENTRY = ValueConversions.identity();
-
-        protected boolean isPrototype() { return target == null; }
-        protected Adapter(SpreadGeneric outer) {
-            super(NO_ENTRY);
-            this.outer = outer;
-            this.target = null;
-            assert(isPrototype());
-        }
-
-        protected Adapter(SpreadGeneric outer, MethodHandle target) {
-            super(outer.entryPoint);
-            this.outer = outer;
-            this.target = target;
-        }
-
-        /** Make a copy of self, with new fields. */
-        protected abstract Adapter makeInstance(SpreadGeneric outer, MethodHandle target);
-        // { return new ThisType(outer, target); }
-
-        protected Object check(Object av, int n) {
-            return outer.check(av, n);
-        }
-        protected Object select(Object av, int n) {
-            return outer.select(av, n);
-        }
-
-        static private final String CLASS_PREFIX; // "java.lang.invoke.SpreadGeneric$"
-        static {
-            String aname = Adapter.class.getName();
-            String sname = Adapter.class.getSimpleName();
-            if (!aname.endsWith(sname))  throw new InternalError();
-            CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
-        }
-        /** Find a sibing class of Adapter. */
-        static Class<? extends Adapter> findSubClass(String name) {
-            String cname = Adapter.CLASS_PREFIX + name;
-            try {
-                return Class.forName(cname).asSubclass(Adapter.class);
-            } catch (ClassNotFoundException ex) {
-                return null;
-            } catch (ClassCastException ex) {
-                return null;
-            }
-        }
-    }
-
-    /* generated classes follow this pattern:
-    static class xS2 extends Adapter {
-        protected xS2(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected xS2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected xS2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new xS2(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av,0);
-             return target.invokeExact(a0, a1)); }
-        protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av,1);
-             return target.invokeExact(a0,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av,1);
-             return target.invokeExact(
-                super.select(av,0), super.select(av,1)); }
-    }
-    // */
-
-/*
-: SHELL; n=SpreadGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
-//{{{
-import java.util.*;
-class genclasses {
-    static String[][] TEMPLATES = { {
-        "@for@ N=0..10",
-        "    //@each-cat@",
-        "    static class @cat@ extends Adapter {",
-        "        protected @cat@(SpreadGeneric outer) { super(outer); }  // to build prototype",
-        "        protected @cat@(SpreadGeneric outer, MethodHandle t) { super(outer, t); }",
-        "        protected @cat@ makeInstance(SpreadGeneric outer, MethodHandle t) { return new @cat@(outer, t); }",
-        "        protected Object invoke_S0(@Tvav,@Object av) throws Throwable { av = super.check(av, 0);",
-        "            return target.invokeExact(@av@); }",
-        "        //@each-S@",
-        "        protected Object invoke_S@S@(@Tvav,@Object av) throws Throwable { av = super.check(av, @S@);",
-        "            return target.invokeExact(@av,@@sv@); }",
-        "        //@end-S@",
-        "    }",
-    } };
-    static final String NEWLINE_INDENT = "\n                ";
-    enum VAR {
-        cat, N, S, av, av_, Tvav_, sv;
-        public final String pattern = "@"+toString().replace('_','.')+"@";
-        public String binding = toString();
-        static void makeBindings(boolean topLevel, int outargs, int spread) {
-            int inargs = outargs - spread;
-            VAR.cat.binding = "S"+outargs;
-            VAR.N.binding = String.valueOf(outargs); // outgoing arg count
-            VAR.S.binding = String.valueOf(spread);  // spread count
-            String[] av = new String[inargs];
-            String[] Tvav = new String[inargs];
-            for (int i = 0; i < inargs; i++) {
-                av[i] = arg(i);
-                Tvav[i] = param("Object", av[i]);
-            }
-            VAR.av.binding = comma(av);
-            VAR.av_.binding = comma(av, ", ");
-            VAR.Tvav_.binding = comma(Tvav, ", ");
-            String[] sv = new String[spread];
-            for (int i = 0; i < spread; i++) {
-                String spc = "";
-                if (i % 4 == 0) spc = NEWLINE_INDENT;
-                sv[i] = spc+"super.select(av,"+i+")";
-            }
-            VAR.sv.binding = comma(sv);
-        }
-        static String arg(int i) { return "a"+i; }
-        static String param(String t, String a) { return t+" "+a; }
-        static String comma(String[] v) { return comma(v, ""); }
-        static String comma(String[] v, String sep) {
-            if (v.length == 0)  return "";
-            String res = v[0];
-            for (int i = 1; i < v.length; i++)  res += ", "+v[i];
-            return res + sep;
-        }
-        static String transform(String string) {
-            for (VAR var : values())
-                string = string.replaceAll(var.pattern, var.binding);
-            return string;
-        }
-    }
-    static String[] stringsIn(String[] strings, int beg, int end) {
-        return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
-    }
-    static String[] stringsBefore(String[] strings, int pos) {
-        return stringsIn(strings, 0, pos);
-    }
-    static String[] stringsAfter(String[] strings, int pos) {
-        return stringsIn(strings, pos, strings.length);
-    }
-    static int indexAfter(String[] strings, int pos, String tag) {
-        return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
-    }
-    static int indexBefore(String[] strings, int pos, String tag) {
-        for (int i = pos, end = strings.length; ; i++) {
-            if (i == end || strings[i].endsWith(tag))  return i;
-        }
-    }
-    static int MIN_ARITY, MAX_ARITY;
-    public static void main(String... av) {
-        for (String[] template : TEMPLATES) {
-            int forLinesLimit = indexBefore(template, 0, "@each-cat@");
-            String[] forLines = stringsBefore(template, forLinesLimit);
-            template = stringsAfter(template, forLinesLimit);
-            for (String forLine : forLines)
-                expandTemplate(forLine, template);
-        }
-    }
-    static void expandTemplate(String forLine, String[] template) {
-        String[] params = forLine.split("[^0-9]+");
-        if (params[0].length() == 0)  params = stringsAfter(params, 1);
-        System.out.println("//params="+Arrays.asList(params));
-        int pcur = 0;
-        MIN_ARITY = Integer.valueOf(params[pcur++]);
-        MAX_ARITY = Integer.valueOf(params[pcur++]);
-        if (pcur != params.length)  throw new RuntimeException("bad extra param: "+forLine);
-        for (int outargs = MIN_ARITY; outargs <= MAX_ARITY; outargs++) {
-            expandTemplate(template, true, outargs, 0);
-        }
-    }
-    static void expandTemplate(String[] template, boolean topLevel, int outargs, int spread) {
-        VAR.makeBindings(topLevel, outargs, spread);
-        for (int i = 0; i < template.length; i++) {
-            String line = template[i];
-            if (line.endsWith("@each-cat@")) {
-                // ignore
-            } else if (line.endsWith("@each-S@")) {
-                int blockEnd = indexAfter(template, i, "@end-S@");
-                String[] block = stringsIn(template, i+1, blockEnd-1);
-                for (int spread1 = spread+1; spread1 <= outargs; spread1++)
-                    expandTemplate(block, false, outargs, spread1);
-                VAR.makeBindings(topLevel, outargs, spread);
-                i = blockEnd-1; continue;
-            } else {
-                System.out.println(VAR.transform(line));
-            }
-        }
-    }
-}
-//}}} */
-//params=[0, 10]
-    static class S0 extends Adapter {
-        protected S0(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S0(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S0 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S0(outer, t); }
-        protected Object invoke_S0(Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(); }
-    }
-    static class S1 extends Adapter {
-        protected S1(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S1(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S1 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S1(outer, t); }
-        protected Object invoke_S0(Object a0, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0); }
-        protected Object invoke_S1(Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(
-                super.select(av,0)); }
-    }
-    static class S2 extends Adapter {
-        protected S2(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S2(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S2 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S2(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1); }
-        protected Object invoke_S1(Object a0, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1)); }
-    }
-    static class S3 extends Adapter {
-        protected S3(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S3(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S3 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S3(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1, a2); }
-        protected Object invoke_S1(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0, a1,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(a0,
-                super.select(av,0), super.select(av,1)); }
-        protected Object invoke_S3(Object av) throws Throwable { av = super.check(av, 3);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1), super.select(av,2)); }
-    }
-    static class S4 extends Adapter {
-        protected S4(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S4(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S4 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S4(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1, a2, a3); }
-        protected Object invoke_S1(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0, a1, a2,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(a0, a1,
-                super.select(av,0), super.select(av,1)); }
-        protected Object invoke_S3(Object a0, Object av) throws Throwable { av = super.check(av, 3);
-            return target.invokeExact(a0,
-                super.select(av,0), super.select(av,1), super.select(av,2)); }
-        protected Object invoke_S4(Object av) throws Throwable { av = super.check(av, 4);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
-    }
-    static class S5 extends Adapter {
-        protected S5(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S5(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S5 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S5(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1, a2, a3, a4); }
-        protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0, a1, a2, a3,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(a0, a1, a2,
-                super.select(av,0), super.select(av,1)); }
-        protected Object invoke_S3(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 3);
-            return target.invokeExact(a0, a1,
-                super.select(av,0), super.select(av,1), super.select(av,2)); }
-        protected Object invoke_S4(Object a0, Object av) throws Throwable { av = super.check(av, 4);
-            return target.invokeExact(a0,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
-        protected Object invoke_S5(Object av) throws Throwable { av = super.check(av, 5);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4)); }
-    }
-    static class S6 extends Adapter {
-        protected S6(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S6(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S6 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S6(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0, a1, a2, a3, a4,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(a0, a1, a2, a3,
-                super.select(av,0), super.select(av,1)); }
-        protected Object invoke_S3(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 3);
-            return target.invokeExact(a0, a1, a2,
-                super.select(av,0), super.select(av,1), super.select(av,2)); }
-        protected Object invoke_S4(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 4);
-            return target.invokeExact(a0, a1,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
-        protected Object invoke_S5(Object a0, Object av) throws Throwable { av = super.check(av, 5);
-            return target.invokeExact(a0,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4)); }
-        protected Object invoke_S6(Object av) throws Throwable { av = super.check(av, 6);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5)); }
-    }
-    static class S7 extends Adapter {
-        protected S7(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S7(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S7 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S7(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(a0, a1, a2, a3, a4,
-                super.select(av,0), super.select(av,1)); }
-        protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 3);
-            return target.invokeExact(a0, a1, a2, a3,
-                super.select(av,0), super.select(av,1), super.select(av,2)); }
-        protected Object invoke_S4(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 4);
-            return target.invokeExact(a0, a1, a2,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
-        protected Object invoke_S5(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 5);
-            return target.invokeExact(a0, a1,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4)); }
-        protected Object invoke_S6(Object a0, Object av) throws Throwable { av = super.check(av, 6);
-            return target.invokeExact(a0,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5)); }
-        protected Object invoke_S7(Object av) throws Throwable { av = super.check(av, 7);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6)); }
-    }
-    static class S8 extends Adapter {
-        protected S8(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S8(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S8 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S8(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5,
-                super.select(av,0), super.select(av,1)); }
-        protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 3);
-            return target.invokeExact(a0, a1, a2, a3, a4,
-                super.select(av,0), super.select(av,1), super.select(av,2)); }
-        protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 4);
-            return target.invokeExact(a0, a1, a2, a3,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
-        protected Object invoke_S5(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 5);
-            return target.invokeExact(a0, a1, a2,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4)); }
-        protected Object invoke_S6(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 6);
-            return target.invokeExact(a0, a1,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5)); }
-        protected Object invoke_S7(Object a0, Object av) throws Throwable { av = super.check(av, 7);
-            return target.invokeExact(a0,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6)); }
-        protected Object invoke_S8(Object av) throws Throwable { av = super.check(av, 8);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
-    }
-    static class S9 extends Adapter {
-        protected S9(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S9(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S9 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S9(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
-                super.select(av,0), super.select(av,1)); }
-        protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 3);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5,
-                super.select(av,0), super.select(av,1), super.select(av,2)); }
-        protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 4);
-            return target.invokeExact(a0, a1, a2, a3, a4,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
-        protected Object invoke_S5(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 5);
-            return target.invokeExact(a0, a1, a2, a3,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4)); }
-        protected Object invoke_S6(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 6);
-            return target.invokeExact(a0, a1, a2,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5)); }
-        protected Object invoke_S7(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 7);
-            return target.invokeExact(a0, a1,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6)); }
-        protected Object invoke_S8(Object a0, Object av) throws Throwable { av = super.check(av, 8);
-            return target.invokeExact(a0,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
-        protected Object invoke_S9(Object av) throws Throwable { av = super.check(av, 9);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
-                super.select(av,8)); }
-    }
-    static class S10 extends Adapter {
-        protected S10(SpreadGeneric outer) { super(outer); }  // to build prototype
-        protected S10(SpreadGeneric outer, MethodHandle t) { super(outer, t); }
-        protected S10 makeInstance(SpreadGeneric outer, MethodHandle t) { return new S10(outer, t); }
-        protected Object invoke_S0(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9, Object av) throws Throwable { av = super.check(av, 0);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_S1(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object av) throws Throwable { av = super.check(av, 1);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7, a8,
-                super.select(av,0)); }
-        protected Object invoke_S2(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object av) throws Throwable { av = super.check(av, 2);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6, a7,
-                super.select(av,0), super.select(av,1)); }
-        protected Object invoke_S3(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object av) throws Throwable { av = super.check(av, 3);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5, a6,
-                super.select(av,0), super.select(av,1), super.select(av,2)); }
-        protected Object invoke_S4(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object av) throws Throwable { av = super.check(av, 4);
-            return target.invokeExact(a0, a1, a2, a3, a4, a5,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3)); }
-        protected Object invoke_S5(Object a0, Object a1, Object a2, Object a3, Object a4, Object av) throws Throwable { av = super.check(av, 5);
-            return target.invokeExact(a0, a1, a2, a3, a4,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4)); }
-        protected Object invoke_S6(Object a0, Object a1, Object a2, Object a3, Object av) throws Throwable { av = super.check(av, 6);
-            return target.invokeExact(a0, a1, a2, a3,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5)); }
-        protected Object invoke_S7(Object a0, Object a1, Object a2, Object av) throws Throwable { av = super.check(av, 7);
-            return target.invokeExact(a0, a1, a2,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6)); }
-        protected Object invoke_S8(Object a0, Object a1, Object av) throws Throwable { av = super.check(av, 8);
-            return target.invokeExact(a0, a1,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7)); }
-        protected Object invoke_S9(Object a0, Object av) throws Throwable { av = super.check(av, 9);
-            return target.invokeExact(a0,
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
-                super.select(av,8)); }
-        protected Object invoke_S10(Object av) throws Throwable { av = super.check(av, 10);
-            return target.invokeExact(
-                super.select(av,0), super.select(av,1), super.select(av,2), super.select(av,3),
-                super.select(av,4), super.select(av,5), super.select(av,6), super.select(av,7),
-                super.select(av,8), super.select(av,9)); }
-    }
-}
diff --git a/jdk/src/share/classes/java/lang/invoke/ToGeneric.java b/jdk/src/share/classes/java/lang/invoke/ToGeneric.java
deleted file mode 100644
index e3e6f9d..0000000
--- a/jdk/src/share/classes/java/lang/invoke/ToGeneric.java
+++ /dev/null
@@ -1,1066 +0,0 @@
-/*
- * Copyright (c) 2008, 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
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package java.lang.invoke;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import sun.invoke.util.ValueConversions;
-import sun.invoke.util.Wrapper;
-import static java.lang.invoke.MethodHandleStatics.*;
-import static java.lang.invoke.MethodHandles.Lookup.IMPL_LOOKUP;
-
-/**
- * Adapters which mediate between incoming calls which are not generic
- * and outgoing calls which are.  Any call can be represented generically
- * boxing up its arguments, and (on return) unboxing the return value.
- * <p>
- * A call is "generic" (in MethodHandle terms) if its MethodType features
- * only Object arguments.  A non-generic call therefore features
- * primitives and/or reference types other than Object.
- * An adapter has types for its incoming and outgoing calls.
- * The incoming call type is simply determined by the adapter's type
- * (the MethodType it presents to callers).  The outgoing call type
- * is determined by the adapter's target (a MethodHandle that the adapter
- * either binds internally or else takes as a leading argument).
- * (To stretch the term, adapter-like method handles may have multiple
- * targets or be polymorphic across multiple call types.)
- * @author jrose
- */
-class ToGeneric {
-    // type for the incoming call (may be erased)
-    private final MethodType entryType;
-    // incoming type with primitives moved to the end and turned to int/long
-    private final MethodType rawEntryType;
-    // adapter for the erased type
-    private final Adapter adapter;
-    // entry point for adapter (Adapter mh, a...) => ...
-    private final MethodHandle entryPoint;
-    // permutation of arguments for primsAtEndType
-    private final int[] primsAtEndOrder;
-    // optional final argument list conversions (at least, invokes the target)
-    private final MethodHandle invoker;
-    // conversion which unboxes a primitive return value
-    private final MethodHandle returnConversion;
-
-    /** Compute and cache information common to all generifying (boxing) adapters
-     *  that implement members of the erasure-family of the given erased type.
-     */
-    private ToGeneric(MethodType entryType) {
-        assert(entryType.erase() == entryType); // for now
-        // incoming call will first "forget" all reference types except Object
-        this.entryType = entryType;
-        MethodHandle invoker0 = entryType.generic().invokers().exactInvoker();
-        MethodType rawEntryTypeInit;
-        Adapter ad = findAdapter(rawEntryTypeInit = entryType);
-        if (ad != null) {
-            // Immediate hit to exactly the adapter we want,
-            // with no monkeying around with primitive types.
-            this.returnConversion = computeReturnConversion(entryType, rawEntryTypeInit, false);
-            this.rawEntryType = rawEntryTypeInit;
-            this.adapter = ad;
-            this.entryPoint = ad.prototypeEntryPoint();
-            this.primsAtEndOrder = null;
-            this.invoker = invoker0;
-            return;
-        }
-
-        // next, it will reorder primitives after references
-        MethodType primsAtEnd = entryType.form().primsAtEnd();
-        // at the same time, it will "forget" all primitive types except int/long
-        this.primsAtEndOrder = MethodTypeForm.primsAtEndOrder(entryType);
-        if (primsAtEndOrder != null) {
-            // reordering is required; build on top of a simpler ToGeneric
-            ToGeneric va2 = ToGeneric.of(primsAtEnd);
-            this.adapter = va2.adapter;
-            if (true) throw new UnsupportedOperationException("NYI: primitive parameters must follow references; entryType = "+entryType);
-            this.entryPoint = MethodHandleImpl.permuteArguments(
-                    va2.entryPoint, primsAtEnd, entryType, primsAtEndOrder);
-            // example: for entryType of (int,Object,Object), the reordered
-            // type is (Object,Object,int) and the order is {1,2,0},
-            // and putPAE is (mh,int0,obj1,obj2) => mh.invokeExact(obj1,obj2,int0)
-            return;
-        }
-
-        // after any needed argument reordering, it will reinterpret
-        // primitive arguments according to their "raw" types int/long
-        MethodType intsAtEnd = primsAtEnd.form().primsAsInts();
-        ad = findAdapter(rawEntryTypeInit = intsAtEnd);
-        MethodHandle rawEntryPoint;
-        if (ad != null) {
-            rawEntryPoint = ad.prototypeEntryPoint();
-        } else {
-            // Perhaps the adapter is available only for longs.
-            // If so, we can use it, but there will have to be a little
-            // more stack motion on each call.
-            MethodType longsAtEnd = primsAtEnd.form().primsAsLongs();
-            ad = findAdapter(rawEntryTypeInit = longsAtEnd);
-            if (ad != null) {
-                MethodType eptWithLongs = longsAtEnd.insertParameterTypes(0, ad.getClass());
-                MethodType eptWithInts  =  intsAtEnd.insertParameterTypes(0, ad.getClass());
-                rawEntryPoint = ad.prototypeEntryPoint();
-                MethodType midType = eptWithLongs;  // will change longs to ints
-                for (int i = 0, nargs = midType.parameterCount(); i < nargs; i++) {
-                    if (midType.parameterType(i) != eptWithInts.parameterType(i)) {
-                        assert(midType.parameterType(i) == long.class);
-                        assert(eptWithInts.parameterType(i) == int.class);
-                        MethodType nextType = midType.changeParameterType(i, int.class);
-                        rawEntryPoint = MethodHandleImpl.convertArguments(
-                                rawEntryPoint, nextType, midType, 0);
-                        midType = nextType;
-                    }
-                }
-                assert(midType == eptWithInts);
-            } else {
-                // If there is no statically compiled adapter,
-                // build one by means of dynamic bytecode generation.
-                ad = buildAdapterFromBytecodes(rawEntryTypeInit = intsAtEnd);
-                rawEntryPoint = ad.prototypeEntryPoint();
-            }
-        }
-        MethodType tepType = entryType.insertParameterTypes(0, ad.getClass());
-        this.entryPoint =
-            AdapterMethodHandle.makeRetypeRaw(tepType, rawEntryPoint);
-        if (this.entryPoint == null)
-            throw new UnsupportedOperationException("cannot retype to "+entryType
-                    +" from "+rawEntryPoint.type().dropParameterTypes(0, 1));
-        this.returnConversion = computeReturnConversion(entryType, rawEntryTypeInit, false);
-        this.rawEntryType = rawEntryTypeInit;
-        this.adapter = ad;
-        this.invoker = makeRawArgumentFilter(invoker0, rawEntryTypeInit, entryType);
-    }
-
-    static {
-        assert(MethodHandleNatives.workaroundWithoutRicochetFrames());  // this class is deprecated
-    }
-
-    /** A generic argument list will be created by a call of type 'raw'.
-     *  The values need to be reboxed for to match 'cooked'.
-     *  Do this on the fly.
-     */
-    // TO DO: Use a generic argument converter in a different file
-    static MethodHandle makeRawArgumentFilter(MethodHandle invoker,
-            MethodType raw, MethodType cooked) {
-        MethodHandle filteredInvoker = null;
-        for (int i = 0, nargs = raw.parameterCount(); i < nargs; i++) {
-            Class<?> src = raw.parameterType(i);
-            Class<?> dst = cooked.parameterType(i);
-            if (src == dst)  continue;
-            assert(src.isPrimitive() && dst.isPrimitive());
-            if (filteredInvoker == null) {
-                filteredInvoker =
-                        AdapterMethodHandle.makeCheckCast(
-                            invoker.type().generic(), invoker, 0, MethodHandle.class);
-                if (filteredInvoker == null)  throw new UnsupportedOperationException("NYI");
-            }
-            MethodHandle reboxer = ValueConversions.rebox(dst);
-            filteredInvoker = FilterGeneric.makeArgumentFilter(1+i, reboxer, filteredInvoker);
-            if (filteredInvoker == null)  throw new InternalError();
-        }
-        if (filteredInvoker == null)  return invoker;
-        return AdapterMethodHandle.makeRetypeOnly(invoker.type(), filteredInvoker);
-    }
-
-    /**
-     * Caller will be expecting a result from a call to {@code type},
-     * while the internal adapter entry point is rawEntryType.
-     * Also, the internal target method will be returning a boxed value,
-     * as an untyped object.
-     * <p>
-     * Produce a value converter which will be typed to convert from
-     * {@code Object} to the return value of {@code rawEntryType}, and will
-     * in fact ensure that the value is compatible with the return type of
-     * {@code type}.
-     */
-    private static MethodHandle computeReturnConversion(
-            MethodType type, MethodType rawEntryType, boolean mustCast) {
-        Class<?> tret = type.returnType();
-        Class<?> rret = rawEntryType.returnType();
-        if (mustCast || !tret.isPrimitive()) {
-            assert(!tret.isPrimitive());
-            assert(!rret.isPrimitive());
-            if (rret == Object.class && !mustCast)
-                return null;
-            return ValueConversions.cast(tret);
-        } else if (tret == rret) {
-            return ValueConversions.unbox(tret);
-        } else {
-            assert(rret.isPrimitive());
-            assert(tret == double.class ? rret == long.class : rret == int.class);
-            return ValueConversions.unboxRaw(tret);
-        }
-    }
-
-    Adapter makeInstance(MethodType type, MethodHandle genericTarget) {
-        genericTarget.getClass();  // check for NPE
-        MethodHandle convert = returnConversion;
-        if (primsAtEndOrder != null)
-            // reorder arguments passed to genericTarget, if primsAtEndOrder
-            throw new UnsupportedOperationException("NYI");
-        if (type == entryType) {
-            if (convert == null)  convert = ValueConversions.identity();
-            return adapter.makeInstance(entryPoint, invoker, convert, genericTarget);
-        }
-        // my erased-type is not exactly the same as the desired type
-        assert(type.erase() == entryType);  // else we are busted
-        if (convert == null)
-            convert = computeReturnConversion(type, rawEntryType, true);
-        // retype erased reference arguments (the cast makes it safe to do this)
-        MethodType tepType = type.insertParameterTypes(0, adapter.getClass());
-        MethodHandle typedEntryPoint =
-            AdapterMethodHandle.makeRetypeRaw(tepType, entryPoint);
-        return adapter.makeInstance(typedEntryPoint, invoker, convert, genericTarget);
-    }
-
-    /** Build an adapter of the given type, which invokes genericTarget
-     *  on the incoming arguments, after boxing as necessary.
-     *  The return value is unboxed if necessary.
-     * @param type  the required type of the
-     * @param genericTarget the target, which must accept and return only Object values
-     * @return an adapter method handle
-     */
-    public static MethodHandle make(MethodType type, MethodHandle genericTarget) {
-        MethodType gtype = genericTarget.type();
-        if (type.generic() != gtype)
-            throw newIllegalArgumentException("type must be generic");
-        if (type == gtype)  return genericTarget;
-        return ToGeneric.of(type).makeInstance(type, genericTarget);
-    }
-
-    /** Return the adapter information for this type's erasure. */
-    static ToGeneric of(MethodType type) {
-        MethodTypeForm form = type.form();
-        ToGeneric toGen = form.toGeneric;
-        if (toGen == null)
-            form.toGeneric = toGen = new ToGeneric(form.erasedType());
-        return toGen;
-    }
-
-    String debugString() {
-        return "ToGeneric"+entryType
-                +(primsAtEndOrder!=null?"[reorder]":"");
-    }
-
-    /* Create an adapter for the given incoming call type. */
-    static Adapter findAdapter(MethodType entryPointType) {
-        MethodTypeForm form = entryPointType.form();
-        Class<?> rtype = entryPointType.returnType();
-        int argc = form.parameterCount();
-        int lac = form.longPrimitiveParameterCount();
-        int iac = form.primitiveParameterCount() - lac;
-        String intsAndLongs = (iac > 0 ? "I"+iac : "")+(lac > 0 ? "J"+lac : "");
-        String rawReturn = String.valueOf(Wrapper.forPrimitiveType(rtype).basicTypeChar());
-        String iname0 = "invoke_"+rawReturn;
-        String iname1 = "invoke";
-        String[] inames = { iname0, iname1 };
-        String cname0 = rawReturn + argc;
-        String cname1 = "A"       + argc;
-        String[] cnames = { cname1, cname1+intsAndLongs, cname0, cname0+intsAndLongs };
-        // e.g., D5I2, D5, L5I2, L5
-        for (String cname : cnames) {
-            Class<? extends Adapter> acls = Adapter.findSubClass(cname);
-            if (acls == null)  continue;
-            // see if it has the required invoke method
-            for (String iname : inames) {
-                MethodHandle entryPoint = null;
-                try {
-                    entryPoint = IMPL_LOOKUP.
-                                    findSpecial(acls, iname, entryPointType, acls);
-                } catch (ReflectiveOperationException ex) {
-                }
-                if (entryPoint == null)  continue;
-                Constructor<? extends Adapter> ctor = null;
-                try {
-                    // Prototype builder:
-                    ctor = acls.getDeclaredConstructor(MethodHandle.class);
-                } catch (NoSuchMethodException ex) {
-                } catch (SecurityException ex) {
-                }
-                if (ctor == null)  continue;
-                try {
-                    return ctor.newInstance(entryPoint);
-                } catch (IllegalArgumentException ex) {
-                } catch (InvocationTargetException wex) {
-                    Throwable ex = wex.getTargetException();
-                    if (ex instanceof Error)  throw (Error)ex;
-                    if (ex instanceof RuntimeException)  throw (RuntimeException)ex;
-                } catch (InstantiationException ex) {
-                } catch (IllegalAccessException ex) {
-                }
-            }
-        }
-        return null;
-    }
-
-    static Adapter buildAdapterFromBytecodes(MethodType entryPointType) {
-        throw new UnsupportedOperationException("NYI: "+entryPointType);
-    }
-
-    /**
-     * The invoke method takes some particular but unconstrained spread
-     * of raw argument types, and returns a raw return type (in L/I/J/F/D).
-     * Internally, it converts the incoming arguments uniformly into objects.
-     * This series of objects is then passed to the {@code target} method,
-     * which returns a result object.  This result is finally converted,
-     * via another method handle {@code convert}, which is responsible for
-     * converting the object result into the raw return value.
-     */
-    static abstract class Adapter extends BoundMethodHandle {
-        /*
-         * class X<<R,A...>> extends Adapter {
-         *   Object...=>Object target;
-         *   Object=>R convert;
-         *   R invoke(A... a...) = convert(invoker(target, a...)))
-         * }
-         */
-        protected final MethodHandle invoker;  // (MH, Object...) -> Object
-        protected final MethodHandle target;   // Object... -> Object
-        protected final MethodHandle convert;  // Object -> R
-
-        @Override
-        String debugString() {
-            return target == null ? "prototype:"+convert : addTypeString(target, this);
-        }
-
-        protected boolean isPrototype() { return target == null; }
-        /* Prototype constructor. */
-        protected Adapter(MethodHandle entryPoint) {
-            super(entryPoint);
-            this.invoker = null;
-            this.convert = entryPoint;
-            this.target = null;
-            assert(isPrototype());
-        }
-        protected MethodHandle prototypeEntryPoint() {
-            if (!isPrototype())  throw new InternalError();
-            return convert;
-        }
-
-        protected Adapter(MethodHandle entryPoint, MethodHandle invoker, MethodHandle convert, MethodHandle target) {
-            super(entryPoint);
-            this.invoker = invoker;
-            this.convert = convert;
-            this.target = target;
-        }
-
-        /** Make a copy of self, with new fields. */
-        protected abstract Adapter makeInstance(MethodHandle entryPoint,
-                MethodHandle invoker, MethodHandle convert, MethodHandle target);
-        // { return new ThisType(entryPoint, convert, target); }
-
-        // Code to run when the arguments (<= 4) have all been boxed.
-        protected Object target()               throws Throwable { return invoker.invokeExact(target); }
-        protected Object target(Object a0)      throws Throwable { return invoker.invokeExact(target, a0); }
-        protected Object target(Object a0, Object a1)
-                                                throws Throwable { return invoker.invokeExact(target, a0, a1); }
-        protected Object target(Object a0, Object a1, Object a2)
-                                                throws Throwable { return invoker.invokeExact(target, a0, a1, a2); }
-        protected Object target(Object a0, Object a1, Object a2, Object a3)
-                                                throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3); }
-        /*
-        protected Object target_0(Object... av) throws Throwable { return invoker.invokeExact(target, av); }
-        protected Object target_1(Object a0, Object... av)
-                                                throws Throwable { return invoker.invokeExact(target, a0, (Object)av); }
-        protected Object target_2(Object a0, Object a1, Object... av)
-                                                throws Throwable { return invoker.invokeExact(target, a0, a1, (Object)av); }
-        protected Object target_3(Object a0, Object a1, Object a2, Object... av)
-                                                throws Throwable { return invoker.invokeExact(target, a0, a1, a2, (Object)av); }
-        protected Object target_4(Object a0, Object a1, Object a2, Object a3, Object... av)
-                                                throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, (Object)av); }
-        // */
-        // (For more than 4 arguments, generate the code in the adapter itself.)
-
-        // Code to run when the generic target has finished and produced a value.
-        protected Object return_L(Object res) throws Throwable { return (Object)convert.invokeExact(res); }
-        protected int    return_I(Object res) throws Throwable { return (int)   convert.invokeExact(res); }
-        protected long   return_J(Object res) throws Throwable { return (long)  convert.invokeExact(res); }
-        protected float  return_F(Object res) throws Throwable { return (float) convert.invokeExact(res); }
-        protected double return_D(Object res) throws Throwable { return (double)convert.invokeExact(res); }
-
-        static private final String CLASS_PREFIX; // "java.lang.invoke.ToGeneric$"
-        static {
-            String aname = Adapter.class.getName();
-            String sname = Adapter.class.getSimpleName();
-            if (!aname.endsWith(sname))  throw new InternalError();
-            CLASS_PREFIX = aname.substring(0, aname.length() - sname.length());
-        }
-        /** Find a sibing class of Adapter. */
-        static Class<? extends Adapter> findSubClass(String name) {
-            String cname = Adapter.CLASS_PREFIX + name;
-            try {
-                return Class.forName(cname).asSubclass(Adapter.class);
-            } catch (ClassNotFoundException ex) {
-                return null;
-            } catch (ClassCastException ex) {
-                return null;
-            }
-        }
-    }
-
-    /* generated classes follow this pattern:
-    static class A1 extends Adapter {
-        protected A1(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
-        protected Object target(Object a0)   throws Throwable { return invoker.invokeExact(target, a0); }
-        protected Object targetA1(Object a0) throws Throwable { return target(a0); }
-        protected Object targetA1(int    a0) throws Throwable { return target(a0); }
-        protected Object targetA1(long   a0) throws Throwable { return target(a0); }
-        protected Object invoke_L(Object a0) throws Throwable { return return_L(targetA1(a0)); }
-        protected int    invoke_I(Object a0) throws Throwable { return return_I(targetA1(a0)); }
-        protected long   invoke_J(Object a0) throws Throwable { return return_J(targetA1(a0)); }
-        protected float  invoke_F(Object a0) throws Throwable { return return_F(targetA1(a0)); }
-        protected double invoke_D(Object a0) throws Throwable { return return_D(targetA1(a0)); }
-        protected Object invoke_L(int    a0) throws Throwable { return return_L(targetA1(a0)); }
-        protected int    invoke_I(int    a0) throws Throwable { return return_I(targetA1(a0)); }
-        protected long   invoke_J(int    a0) throws Throwable { return return_J(targetA1(a0)); }
-        protected float  invoke_F(int    a0) throws Throwable { return return_F(targetA1(a0)); }
-        protected double invoke_D(int    a0) throws Throwable { return return_D(targetA1(a0)); }
-        protected Object invoke_L(long   a0) throws Throwable { return return_L(targetA1(a0)); }
-        protected int    invoke_I(long   a0) throws Throwable { return return_I(targetA1(a0)); }
-        protected long   invoke_J(long   a0) throws Throwable { return return_J(targetA1(a0)); }
-        protected float  invoke_F(long   a0) throws Throwable { return return_F(targetA1(a0)); }
-        protected double invoke_D(long   a0) throws Throwable { return return_D(targetA1(a0)); }
-    }
-    // */
-
-/*
-: SHELL; n=ToGeneric; cp -p $n.java $n.java-; sed < $n.java- > $n.java+ -e '/{{*{{/,/}}*}}/w /tmp/genclasses.java' -e '/}}*}}/q'; (cd /tmp; javac -d . genclasses.java; java -cp . genclasses) >> $n.java+; echo '}' >> $n.java+; mv $n.java+ $n.java; mv $n.java- $n.java~
-//{{{
-import java.util.*;
-class genclasses {
-    static String[] TYPES = { "Object", "int   ", "long  ", "float ", "double" };
-    static String[] TCHARS = { "L",     "I",      "J",      "F",      "D",     "A" };
-    static String[][] TEMPLATES = { {
-        "@for@ arity=0..3   rcat<=4 nrefs<=99 nints<=99 nlongs<=99",
-        "@for@ arity=4..4   rcat<=4 nrefs<=99 nints<=99 nlongs<=99",
-        "@for@ arity=5..5   rcat<=2 nrefs<=99 nints<=99 nlongs<=99",
-        "@for@ arity=6..10  rcat<=2 nrefs<=99 nints=0   nlongs<=99",
-        "    //@each-cat@",
-        "    static class @cat@ extends Adapter {",
-        "        protected @cat@(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype",
-        "        protected @cat@(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }",
-        "        protected @cat@ makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new @cat@(e, i, c, t); }",
-        "        protected Object target(@Ovav@)   throws Throwable { return invoker.invokeExact(target@comma@@av@); }",
-        "        //@each-Tv@",
-        "        protected Object target@cat@(@Tvav@) throws Throwable { return target(@av@); }",
-        "        //@end-Tv@",
-        "        //@each-Tv@",
-        "        //@each-R@",
-        "        protected @R@ invoke_@Rc@(@Tvav@) throws Throwable { return return_@Rc@(target@cat@(@av@)); }",
-        "        //@end-R@",
-        "        //@end-Tv@",
-        "    }",
-    } };
-    enum VAR {
-        cat, R, Rc, Tv, av, comma, Tvav, Ovav;
-        public final String pattern = "@"+toString().replace('_','.')+"@";
-        public String binding;
-        static void makeBindings(boolean topLevel, int rcat, int nrefs, int nints, int nlongs) {
-            int nargs = nrefs + nints + nlongs;
-            if (topLevel)
-                VAR.cat.binding = catstr(ALL_RETURN_TYPES ? TYPES.length : rcat, nrefs, nints, nlongs);
-            VAR.R.binding = TYPES[rcat];
-            VAR.Rc.binding = TCHARS[rcat];
-            String[] Tv = new String[nargs];
-            String[] av = new String[nargs];
-            String[] Tvav = new String[nargs];
-            String[] Ovav = new String[nargs];
-            for (int i = 0; i < nargs; i++) {
-                int tcat = (i < nrefs) ? 0 : (i < nrefs + nints) ? 1 : 2;
-                Tv[i] = TYPES[tcat];
-                av[i] = arg(i);
-                Tvav[i] = param(Tv[i], av[i]);
-                Ovav[i] = param("Object", av[i]);
-            }
-            VAR.Tv.binding = comma(Tv);
-            VAR.av.binding = comma(av);
-            VAR.comma.binding = (av.length == 0 ? "" : ", ");
-            VAR.Tvav.binding = comma(Tvav);
-            VAR.Ovav.binding = comma(Ovav);
-        }
-        static String arg(int i) { return "a"+i; }
-        static String param(String t, String a) { return t+" "+a; }
-        static String comma(String[] v) { return comma("", v); }
-        static String comma(String sep, String[] v) {
-            if (v.length == 0)  return "";
-            String res = sep+v[0];
-            for (int i = 1; i < v.length; i++)  res += ", "+v[i];
-            return res;
-        }
-        static String transform(String string) {
-            for (VAR var : values())
-                string = string.replaceAll(var.pattern, var.binding);
-            return string;
-        }
-    }
-    static String[] stringsIn(String[] strings, int beg, int end) {
-        return Arrays.copyOfRange(strings, beg, Math.min(end, strings.length));
-    }
-    static String[] stringsBefore(String[] strings, int pos) {
-        return stringsIn(strings, 0, pos);
-    }
-    static String[] stringsAfter(String[] strings, int pos) {
-        return stringsIn(strings, pos, strings.length);
-    }
-    static int indexAfter(String[] strings, int pos, String tag) {
-        return Math.min(indexBefore(strings, pos, tag) + 1, strings.length);
-    }
-    static int indexBefore(String[] strings, int pos, String tag) {
-        for (int i = pos, end = strings.length; ; i++) {
-            if (i == end || strings[i].endsWith(tag))  return i;
-        }
-    }
-    static int MIN_ARITY, MAX_ARITY, MAX_RCAT, MAX_REFS, MAX_INTS, MAX_LONGS;
-    static boolean ALL_ARG_TYPES, ALL_RETURN_TYPES;
-    static HashSet<String> done = new HashSet<String>();
-    public static void main(String... av) {
-        for (String[] template : TEMPLATES) {
-            int forLinesLimit = indexBefore(template, 0, "@each-cat@");
-            String[] forLines = stringsBefore(template, forLinesLimit);
-            template = stringsAfter(template, forLinesLimit);
-            for (String forLine : forLines)
-                expandTemplate(forLine, template);
-        }
-    }
-    static void expandTemplate(String forLine, String[] template) {
-        String[] params = forLine.split("[^0-9]+");
-        if (params[0].length() == 0)  params = stringsAfter(params, 1);
-        System.out.println("//params="+Arrays.asList(params));
-        int pcur = 0;
-        MIN_ARITY = Integer.valueOf(params[pcur++]);
-        MAX_ARITY = Integer.valueOf(params[pcur++]);
-        MAX_RCAT  = Integer.valueOf(params[pcur++]);
-        MAX_REFS  = Integer.valueOf(params[pcur++]);
-        MAX_INTS  = Integer.valueOf(params[pcur++]);
-        MAX_LONGS = Integer.valueOf(params[pcur++]);
-        if (pcur != params.length)  throw new RuntimeException("bad extra param: "+forLine);
-        if (MAX_RCAT >= TYPES.length)  MAX_RCAT = TYPES.length - 1;
-        ALL_ARG_TYPES = (indexBefore(template, 0, "@each-Tv@") < template.length);
-        ALL_RETURN_TYPES = (indexBefore(template, 0, "@each-R@") < template.length);
-        for (int nargs = MIN_ARITY; nargs <= MAX_ARITY; nargs++) {
-            for (int rcat = 0; rcat <= MAX_RCAT; rcat++) {
-                expandTemplate(template, true, rcat, nargs, 0, 0);
-                if (ALL_ARG_TYPES)  break;
-                expandTemplateForPrims(template, true, rcat, nargs, 1, 1);
-                if (ALL_RETURN_TYPES)  break;
-            }
-        }
-    }
-    static String catstr(int rcat, int nrefs, int nints, int nlongs) {
-        int nargs = nrefs + nints + nlongs;
-        String cat = TCHARS[rcat] + nargs;
-        if (!ALL_ARG_TYPES)  cat += (nints==0?"":"I"+nints)+(nlongs==0?"":"J"+nlongs);
-        return cat;
-    }
-    static void expandTemplateForPrims(String[] template, boolean topLevel, int rcat, int nargs, int minints, int minlongs) {
-        for (int isLong = 0; isLong <= 1; isLong++) {
-            for (int nprims = 1; nprims <= nargs; nprims++) {
-                int nrefs = nargs - nprims;
-                int nints = ((1-isLong) * nprims);
-                int nlongs = (isLong * nprims);
-                expandTemplate(template, topLevel, rcat, nrefs, nints, nlongs);
-            }
-        }
-    }
-    static void expandTemplate(String[] template, boolean topLevel,
-                               int rcat, int nrefs, int nints, int nlongs) {
-        int nargs = nrefs + nints + nlongs;
-        if (nrefs > MAX_REFS || nints > MAX_INTS || nlongs > MAX_LONGS)  return;
-        VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
-        if (topLevel && !done.add(VAR.cat.binding)) {
-            System.out.println("    //repeat "+VAR.cat.binding);
-            return;
-        }
-        for (int i = 0; i < template.length; i++) {
-            String line = template[i];
-            if (line.endsWith("@each-cat@")) {
-                // ignore
-            } else if (line.endsWith("@each-R@")) {
-                int blockEnd = indexAfter(template, i, "@end-R@");
-                String[] block = stringsIn(template, i+1, blockEnd-1);
-                for (int rcat1 = rcat; rcat1 <= MAX_RCAT; rcat1++)
-                    expandTemplate(block, false, rcat1, nrefs, nints, nlongs);
-                VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
-                i = blockEnd-1; continue;
-            } else if (line.endsWith("@each-Tv@")) {
-                int blockEnd = indexAfter(template, i, "@end-Tv@");
-                String[] block = stringsIn(template, i+1, blockEnd-1);
-                expandTemplate(block, false, rcat, nrefs, nints, nlongs);
-                expandTemplateForPrims(block, false, rcat, nargs, nints+1, nlongs+1);
-                VAR.makeBindings(topLevel, rcat, nrefs, nints, nlongs);
-                i = blockEnd-1; continue;
-            } else {
-                System.out.println(VAR.transform(line));
-            }
-        }
-    }
-}
-//}}} */
-//params=[0, 3, 4, 99, 99, 99]
-    static class A0 extends Adapter {
-        protected A0(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A0(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A0 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A0(e, i, c, t); }
-        protected Object target()   throws Throwable { return invoker.invokeExact(target); }
-        protected Object targetA0() throws Throwable { return target(); }
-        protected Object invoke_L() throws Throwable { return return_L(targetA0()); }
-        protected int    invoke_I() throws Throwable { return return_I(targetA0()); }
-        protected long   invoke_J() throws Throwable { return return_J(targetA0()); }
-        protected float  invoke_F() throws Throwable { return return_F(targetA0()); }
-        protected double invoke_D() throws Throwable { return return_D(targetA0()); }
-    }
-    static class A1 extends Adapter {
-        protected A1(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A1(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A1 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A1(e, i, c, t); }
-        protected Object target(Object a0)   throws Throwable { return invoker.invokeExact(target, a0); }
-        protected Object targetA1(Object a0) throws Throwable { return target(a0); }
-        protected Object targetA1(int    a0) throws Throwable { return target(a0); }
-        protected Object targetA1(long   a0) throws Throwable { return target(a0); }
-        protected Object invoke_L(Object a0) throws Throwable { return return_L(targetA1(a0)); }
-        protected int    invoke_I(Object a0) throws Throwable { return return_I(targetA1(a0)); }
-        protected long   invoke_J(Object a0) throws Throwable { return return_J(targetA1(a0)); }
-        protected float  invoke_F(Object a0) throws Throwable { return return_F(targetA1(a0)); }
-        protected double invoke_D(Object a0) throws Throwable { return return_D(targetA1(a0)); }
-        protected Object invoke_L(int    a0) throws Throwable { return return_L(targetA1(a0)); }
-        protected int    invoke_I(int    a0) throws Throwable { return return_I(targetA1(a0)); }
-        protected long   invoke_J(int    a0) throws Throwable { return return_J(targetA1(a0)); }
-        protected float  invoke_F(int    a0) throws Throwable { return return_F(targetA1(a0)); }
-        protected double invoke_D(int    a0) throws Throwable { return return_D(targetA1(a0)); }
-        protected Object invoke_L(long   a0) throws Throwable { return return_L(targetA1(a0)); }
-        protected int    invoke_I(long   a0) throws Throwable { return return_I(targetA1(a0)); }
-        protected long   invoke_J(long   a0) throws Throwable { return return_J(targetA1(a0)); }
-        protected float  invoke_F(long   a0) throws Throwable { return return_F(targetA1(a0)); }
-        protected double invoke_D(long   a0) throws Throwable { return return_D(targetA1(a0)); }
-    }
-    static class A2 extends Adapter {
-        protected A2(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A2(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A2 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A2(e, i, c, t); }
-        protected Object target(Object a0, Object a1)   throws Throwable { return invoker.invokeExact(target, a0, a1); }
-        protected Object targetA2(Object a0, Object a1) throws Throwable { return target(a0, a1); }
-        protected Object targetA2(Object a0, int    a1) throws Throwable { return target(a0, a1); }
-        protected Object targetA2(int    a0, int    a1) throws Throwable { return target(a0, a1); }
-        protected Object targetA2(Object a0, long   a1) throws Throwable { return target(a0, a1); }
-        protected Object targetA2(long   a0, long   a1) throws Throwable { return target(a0, a1); }
-        protected Object invoke_L(Object a0, Object a1) throws Throwable { return return_L(targetA2(a0, a1)); }
-        protected int    invoke_I(Object a0, Object a1) throws Throwable { return return_I(targetA2(a0, a1)); }
-        protected long   invoke_J(Object a0, Object a1) throws Throwable { return return_J(targetA2(a0, a1)); }
-        protected float  invoke_F(Object a0, Object a1) throws Throwable { return return_F(targetA2(a0, a1)); }
-        protected double invoke_D(Object a0, Object a1) throws Throwable { return return_D(targetA2(a0, a1)); }
-        protected Object invoke_L(Object a0, int    a1) throws Throwable { return return_L(targetA2(a0, a1)); }
-        protected int    invoke_I(Object a0, int    a1) throws Throwable { return return_I(targetA2(a0, a1)); }
-        protected long   invoke_J(Object a0, int    a1) throws Throwable { return return_J(targetA2(a0, a1)); }
-        protected float  invoke_F(Object a0, int    a1) throws Throwable { return return_F(targetA2(a0, a1)); }
-        protected double invoke_D(Object a0, int    a1) throws Throwable { return return_D(targetA2(a0, a1)); }
-        protected Object invoke_L(int    a0, int    a1) throws Throwable { return return_L(targetA2(a0, a1)); }
-        protected int    invoke_I(int    a0, int    a1) throws Throwable { return return_I(targetA2(a0, a1)); }
-        protected long   invoke_J(int    a0, int    a1) throws Throwable { return return_J(targetA2(a0, a1)); }
-        protected float  invoke_F(int    a0, int    a1) throws Throwable { return return_F(targetA2(a0, a1)); }
-        protected double invoke_D(int    a0, int    a1) throws Throwable { return return_D(targetA2(a0, a1)); }
-        protected Object invoke_L(Object a0, long   a1) throws Throwable { return return_L(targetA2(a0, a1)); }
-        protected int    invoke_I(Object a0, long   a1) throws Throwable { return return_I(targetA2(a0, a1)); }
-        protected long   invoke_J(Object a0, long   a1) throws Throwable { return return_J(targetA2(a0, a1)); }
-        protected float  invoke_F(Object a0, long   a1) throws Throwable { return return_F(targetA2(a0, a1)); }
-        protected double invoke_D(Object a0, long   a1) throws Throwable { return return_D(targetA2(a0, a1)); }
-        protected Object invoke_L(long   a0, long   a1) throws Throwable { return return_L(targetA2(a0, a1)); }
-        protected int    invoke_I(long   a0, long   a1) throws Throwable { return return_I(targetA2(a0, a1)); }
-        protected long   invoke_J(long   a0, long   a1) throws Throwable { return return_J(targetA2(a0, a1)); }
-        protected float  invoke_F(long   a0, long   a1) throws Throwable { return return_F(targetA2(a0, a1)); }
-        protected double invoke_D(long   a0, long   a1) throws Throwable { return return_D(targetA2(a0, a1)); }
-    }
-    static class A3 extends Adapter {
-        protected A3(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A3(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A3 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A3(e, i, c, t); }
-        protected Object target(Object a0, Object a1, Object a2)   throws Throwable { return invoker.invokeExact(target, a0, a1, a2); }
-        protected Object targetA3(Object a0, Object a1, Object a2) throws Throwable { return target(a0, a1, a2); }
-        protected Object targetA3(Object a0, Object a1, int    a2) throws Throwable { return target(a0, a1, a2); }
-        protected Object targetA3(Object a0, int    a1, int    a2) throws Throwable { return target(a0, a1, a2); }
-        protected Object targetA3(int    a0, int    a1, int    a2) throws Throwable { return target(a0, a1, a2); }
-        protected Object targetA3(Object a0, Object a1, long   a2) throws Throwable { return target(a0, a1, a2); }
-        protected Object targetA3(Object a0, long   a1, long   a2) throws Throwable { return target(a0, a1, a2); }
-        protected Object targetA3(long   a0, long   a1, long   a2) throws Throwable { return target(a0, a1, a2); }
-        protected Object invoke_L(Object a0, Object a1, Object a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
-        protected float  invoke_F(Object a0, Object a1, Object a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
-        protected double invoke_D(Object a0, Object a1, Object a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
-        protected Object invoke_L(Object a0, Object a1, int    a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
-        protected int    invoke_I(Object a0, Object a1, int    a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
-        protected long   invoke_J(Object a0, Object a1, int    a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
-        protected float  invoke_F(Object a0, Object a1, int    a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
-        protected double invoke_D(Object a0, Object a1, int    a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
-        protected Object invoke_L(Object a0, int    a1, int    a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
-        protected int    invoke_I(Object a0, int    a1, int    a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
-        protected long   invoke_J(Object a0, int    a1, int    a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
-        protected float  invoke_F(Object a0, int    a1, int    a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
-        protected double invoke_D(Object a0, int    a1, int    a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
-        protected Object invoke_L(int    a0, int    a1, int    a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
-        protected int    invoke_I(int    a0, int    a1, int    a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
-        protected long   invoke_J(int    a0, int    a1, int    a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
-        protected float  invoke_F(int    a0, int    a1, int    a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
-        protected double invoke_D(int    a0, int    a1, int    a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
-        protected Object invoke_L(Object a0, Object a1, long   a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
-        protected int    invoke_I(Object a0, Object a1, long   a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
-        protected long   invoke_J(Object a0, Object a1, long   a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
-        protected float  invoke_F(Object a0, Object a1, long   a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
-        protected double invoke_D(Object a0, Object a1, long   a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
-        protected Object invoke_L(Object a0, long   a1, long   a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
-        protected int    invoke_I(Object a0, long   a1, long   a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
-        protected long   invoke_J(Object a0, long   a1, long   a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
-        protected float  invoke_F(Object a0, long   a1, long   a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
-        protected double invoke_D(Object a0, long   a1, long   a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
-        protected Object invoke_L(long   a0, long   a1, long   a2) throws Throwable { return return_L(targetA3(a0, a1, a2)); }
-        protected int    invoke_I(long   a0, long   a1, long   a2) throws Throwable { return return_I(targetA3(a0, a1, a2)); }
-        protected long   invoke_J(long   a0, long   a1, long   a2) throws Throwable { return return_J(targetA3(a0, a1, a2)); }
-        protected float  invoke_F(long   a0, long   a1, long   a2) throws Throwable { return return_F(targetA3(a0, a1, a2)); }
-        protected double invoke_D(long   a0, long   a1, long   a2) throws Throwable { return return_D(targetA3(a0, a1, a2)); }
-    }
-//params=[4, 4, 4, 99, 99, 99]
-    static class A4 extends Adapter {
-        protected A4(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A4(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A4 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A4(e, i, c, t); }
-        protected Object target(Object a0, Object a1, Object a2, Object a3)   throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3); }
-        protected Object targetA4(Object a0, Object a1, Object a2, Object a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object targetA4(Object a0, Object a1, Object a2, int    a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object targetA4(Object a0, Object a1, int    a2, int    a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object targetA4(Object a0, int    a1, int    a2, int    a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object targetA4(int    a0, int    a1, int    a2, int    a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object targetA4(Object a0, Object a1, Object a2, long   a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object targetA4(Object a0, Object a1, long   a2, long   a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object targetA4(Object a0, long   a1, long   a2, long   a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object targetA4(long   a0, long   a1, long   a2, long   a3) throws Throwable { return target(a0, a1, a2, a3); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(Object a0, Object a1, Object a2, Object a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, int    a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, int    a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, int    a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(Object a0, Object a1, Object a2, int    a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(Object a0, Object a1, Object a2, int    a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-        protected Object invoke_L(Object a0, Object a1, int    a2, int    a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(Object a0, Object a1, int    a2, int    a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(Object a0, Object a1, int    a2, int    a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(Object a0, Object a1, int    a2, int    a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(Object a0, Object a1, int    a2, int    a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-        protected Object invoke_L(Object a0, int    a1, int    a2, int    a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(Object a0, int    a1, int    a2, int    a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(Object a0, int    a1, int    a2, int    a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(Object a0, int    a1, int    a2, int    a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(Object a0, int    a1, int    a2, int    a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-        protected Object invoke_L(int    a0, int    a1, int    a2, int    a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(int    a0, int    a1, int    a2, int    a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(int    a0, int    a1, int    a2, int    a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(int    a0, int    a1, int    a2, int    a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(int    a0, int    a1, int    a2, int    a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, long   a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, long   a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, long   a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(Object a0, Object a1, Object a2, long   a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(Object a0, Object a1, Object a2, long   a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-        protected Object invoke_L(Object a0, Object a1, long   a2, long   a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(Object a0, Object a1, long   a2, long   a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(Object a0, Object a1, long   a2, long   a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(Object a0, Object a1, long   a2, long   a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(Object a0, Object a1, long   a2, long   a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-        protected Object invoke_L(Object a0, long   a1, long   a2, long   a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(Object a0, long   a1, long   a2, long   a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(Object a0, long   a1, long   a2, long   a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(Object a0, long   a1, long   a2, long   a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(Object a0, long   a1, long   a2, long   a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-        protected Object invoke_L(long   a0, long   a1, long   a2, long   a3) throws Throwable { return return_L(targetA4(a0, a1, a2, a3)); }
-        protected int    invoke_I(long   a0, long   a1, long   a2, long   a3) throws Throwable { return return_I(targetA4(a0, a1, a2, a3)); }
-        protected long   invoke_J(long   a0, long   a1, long   a2, long   a3) throws Throwable { return return_J(targetA4(a0, a1, a2, a3)); }
-        protected float  invoke_F(long   a0, long   a1, long   a2, long   a3) throws Throwable { return return_F(targetA4(a0, a1, a2, a3)); }
-        protected double invoke_D(long   a0, long   a1, long   a2, long   a3) throws Throwable { return return_D(targetA4(a0, a1, a2, a3)); }
-    }
-//params=[5, 5, 2, 99, 99, 99]
-    static class A5 extends Adapter {
-        protected A5(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A5(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A5 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A5(e, i, c, t); }
-        protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4)   throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, Object a1, Object a2, Object a3, int    a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, Object a1, Object a2, int    a3, int    a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, Object a1, int    a2, int    a3, int    a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, int    a1, int    a2, int    a3, int    a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(int    a0, int    a1, int    a2, int    a3, int    a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, Object a1, Object a2, Object a3, long   a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, Object a1, Object a2, long   a3, long   a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, Object a1, long   a2, long   a3, long   a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(Object a0, long   a1, long   a2, long   a3, long   a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object targetA5(long   a0, long   a1, long   a2, long   a3, long   a4) throws Throwable { return target(a0, a1, a2, a3, a4); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, int    a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, int    a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, int    a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, int    a3, int    a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, int    a3, int    a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, int    a3, int    a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(Object a0, Object a1, int    a2, int    a3, int    a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, Object a1, int    a2, int    a3, int    a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, Object a1, int    a2, int    a3, int    a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(Object a0, int    a1, int    a2, int    a3, int    a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, int    a1, int    a2, int    a3, int    a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, int    a1, int    a2, int    a3, int    a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(int    a0, int    a1, int    a2, int    a3, int    a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(int    a0, int    a1, int    a2, int    a3, int    a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(int    a0, int    a1, int    a2, int    a3, int    a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long   a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, long   a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, long   a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, long   a3, long   a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, long   a3, long   a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, long   a3, long   a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(Object a0, Object a1, long   a2, long   a3, long   a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, Object a1, long   a2, long   a3, long   a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, Object a1, long   a2, long   a3, long   a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(Object a0, long   a1, long   a2, long   a3, long   a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(Object a0, long   a1, long   a2, long   a3, long   a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(Object a0, long   a1, long   a2, long   a3, long   a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-        protected Object invoke_L(long   a0, long   a1, long   a2, long   a3, long   a4) throws Throwable { return return_L(targetA5(a0, a1, a2, a3, a4)); }
-        protected int    invoke_I(long   a0, long   a1, long   a2, long   a3, long   a4) throws Throwable { return return_I(targetA5(a0, a1, a2, a3, a4)); }
-        protected long   invoke_J(long   a0, long   a1, long   a2, long   a3, long   a4) throws Throwable { return return_J(targetA5(a0, a1, a2, a3, a4)); }
-    }
-//params=[6, 10, 2, 99, 0, 99]
-    static class A6 extends Adapter {
-        protected A6(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A6(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A6 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A6(e, i, c, t); }
-        protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5)   throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5); }
-        protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
-        protected Object targetA6(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
-        protected Object targetA6(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
-        protected Object targetA6(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
-        protected Object targetA6(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
-        protected Object targetA6(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
-        protected Object targetA6(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return target(a0, a1, a2, a3, a4, a5); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_L(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected int    invoke_I(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected long   invoke_J(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_L(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected int    invoke_I(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected long   invoke_J(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected Object invoke_L(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_L(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected int    invoke_I(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_I(targetA6(a0, a1, a2, a3, a4, a5)); }
-        protected long   invoke_J(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5) throws Throwable { return return_J(targetA6(a0, a1, a2, a3, a4, a5)); }
-    }
-    static class A7 extends Adapter {
-        protected A7(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A7(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A7 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A7(e, i, c, t); }
-        protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6)   throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6); }
-        protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object targetA7(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object targetA7(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object targetA7(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object targetA7(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object targetA7(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object targetA7(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_L(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected int    invoke_I(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected long   invoke_J(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_L(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected int    invoke_I(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected long   invoke_J(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected Object invoke_L(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_L(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected int    invoke_I(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_I(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-        protected long   invoke_J(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6) throws Throwable { return return_J(targetA7(a0, a1, a2, a3, a4, a5, a6)); }
-    }
-    static class A8 extends Adapter {
-        protected A8(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A8(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A8 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A8(e, i, c, t); }
-        protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7)   throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object targetA8(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_L(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_L(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected Object invoke_L(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_L(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected int    invoke_I(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_I(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-        protected long   invoke_J(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7) throws Throwable { return return_J(targetA8(a0, a1, a2, a3, a4, a5, a6, a7)); }
-    }
-    static class A9 extends Adapter {
-        protected A9(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A9(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A9 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A9(e, i, c, t); }
-        protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8)   throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object targetA9(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected Object invoke_L(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_L(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected int    invoke_I(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_I(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-        protected long   invoke_J(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8) throws Throwable { return return_J(targetA9(a0, a1, a2, a3, a4, a5, a6, a7, a8)); }
-    }
-    static class A10 extends Adapter {
-        protected A10(MethodHandle entryPoint) { super(entryPoint); }  // to build prototype
-        protected A10(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { super(e, i, c, t); }
-        protected A10 makeInstance(MethodHandle e, MethodHandle i, MethodHandle c, MethodHandle t) { return new A10(e, i, c, t); }
-        protected Object target(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9)   throws Throwable { return invoker.invokeExact(target, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object targetA10(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return target(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, Object a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, Object a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, Object a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, Object a6, long   a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, Object a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, Object a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, Object a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, Object a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, Object a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(Object a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected Object invoke_L(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_L(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected int    invoke_I(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_I(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-        protected long   invoke_J(long   a0, long   a1, long   a2, long   a3, long   a4, long   a5, long   a6, long   a7, long   a8, long   a9) throws Throwable { return return_J(targetA10(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9)); }
-    }
-}
diff --git a/jdk/src/share/classes/java/lang/invoke/WrongMethodTypeException.java b/jdk/src/share/classes/java/lang/invoke/WrongMethodTypeException.java
index 7d538dc..dba07d9 100644
--- a/jdk/src/share/classes/java/lang/invoke/WrongMethodTypeException.java
+++ b/jdk/src/share/classes/java/lang/invoke/WrongMethodTypeException.java
@@ -59,4 +59,27 @@
     public WrongMethodTypeException(String s) {
         super(s);
     }
+
+    /**
+     * Constructs a {@code WrongMethodTypeException} with the specified
+     * detail message and cause.
+     *
+     * @param s the detail message.
+     * @param cause the cause of the exception, or null.
+     */
+    //FIXME: make this public in MR1
+    /*non-public*/ WrongMethodTypeException(String s, Throwable cause) {
+        super(s, cause);
+    }
+
+    /**
+     * Constructs a {@code WrongMethodTypeException} with the specified
+     * cause.
+     *
+     * @param cause the cause of the exception, or null.
+     */
+    //FIXME: make this public in MR1
+    /*non-public*/ WrongMethodTypeException(Throwable cause) {
+        super(cause);
+    }
 }
diff --git a/jdk/src/share/classes/java/lang/invoke/package-info.java b/jdk/src/share/classes/java/lang/invoke/package-info.java
index 193c768..79c68ae 100644
--- a/jdk/src/share/classes/java/lang/invoke/package-info.java
+++ b/jdk/src/share/classes/java/lang/invoke/package-info.java
@@ -191,6 +191,13 @@
  * (If a string constant were passed instead, by badly generated code, that cast would then fail,
  * resulting in a {@code BootstrapMethodError}.)
  * <p>
+ * Note that, as a consequence of the above rules, the bootstrap method may accept a primitive
+ * argument, if it can be represented by a constant pool entry.
+ * However, arguments of type {@code boolean}, {@code byte}, {@code short}, or {@code char}
+ * cannot be created for bootstrap methods, since such constants cannot be directly
+ * represented in the constant pool, and the invocation of the bootstrap method will
+ * not perform the necessary narrowing primitive conversions.
+ * <p>
  * Extra bootstrap method arguments are intended to allow language implementors
  * to safely and compactly encode metadata.
  * In principle, the name and extra arguments are redundant,
diff --git a/jdk/src/share/classes/java/net/HttpCookie.java b/jdk/src/share/classes/java/net/HttpCookie.java
index e0588f4..a1a3e8e 100644
--- a/jdk/src/share/classes/java/net/HttpCookie.java
+++ b/jdk/src/share/classes/java/net/HttpCookie.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,6 +30,8 @@
 import java.util.NoSuchElementException;
 import java.text.SimpleDateFormat;
 import java.util.TimeZone;
+import java.util.Calendar;
+import java.util.GregorianCalendar;
 import java.util.Date;
 
 import java.lang.NullPointerException;  // for javadoc
@@ -105,7 +107,10 @@
     private final static String[] COOKIE_DATE_FORMATS = {
         "EEE',' dd-MMM-yyyy HH:mm:ss 'GMT'",
         "EEE',' dd MMM yyyy HH:mm:ss 'GMT'",
-        "EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
+        "EEE MMM dd yyyy HH:mm:ss 'GMT'Z",
+        "EEE',' dd-MMM-yy HH:mm:ss 'GMT'",
+        "EEE',' dd MMM yy HH:mm:ss 'GMT'",
+        "EEE MMM dd yy HH:mm:ss 'GMT'Z"
     };
 
     //
@@ -1125,12 +1130,29 @@
      *                          time and the time specified by dateString
      */
     private long expiryDate2DeltaSeconds(String dateString) {
+        Calendar cal = new GregorianCalendar(GMT);
         for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
-            SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i], Locale.US);
+            SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i],
+                                                       Locale.US);
+            cal.set(1970, 0, 1, 0, 0, 0);
             df.setTimeZone(GMT);
+            df.setLenient(false);
+            df.set2DigitYearStart(cal.getTime());
             try {
-                Date date = df.parse(dateString);
-                return (date.getTime() - whenCreated) / 1000;
+                cal.setTime(df.parse(dateString));
+                if (!COOKIE_DATE_FORMATS[i].contains("yyyy")) {
+                    // 2-digit years following the standard set
+                    // out it rfc 6265
+                    int year = cal.get(Calendar.YEAR);
+                    year %= 100;
+                    if (year < 70) {
+                        year += 2000;
+                    } else {
+                        year += 1900;
+                    }
+                    cal.set(Calendar.YEAR, year);
+                }
+                return (cal.getTimeInMillis() - whenCreated) / 1000;
             } catch (Exception e) {
                 // Ignore, try the next date format
             }
@@ -1139,7 +1161,6 @@
     }
 
 
-
     /*
      * try to guess the cookie version through set-cookie header string
      */
diff --git a/jdk/src/share/classes/java/net/InMemoryCookieStore.java b/jdk/src/share/classes/java/net/InMemoryCookieStore.java
index 6676d97..e885cdd 100644
--- a/jdk/src/share/classes/java/net/InMemoryCookieStore.java
+++ b/jdk/src/share/classes/java/net/InMemoryCookieStore.java
@@ -91,8 +91,10 @@
                 if (cookie.getDomain() != null) {
                     addIndex(domainIndex, cookie.getDomain(), cookie);
                 }
-                // add it to uri index, too
-                addIndex(uriIndex, getEffectiveURI(uri), cookie);
+                if (uri != null) {
+                    // add it to uri index, too
+                    addIndex(uriIndex, getEffectiveURI(uri), cookie);
+                }
             }
         } finally {
             lock.unlock();
diff --git a/jdk/src/share/classes/java/net/SocketInputStream.java b/jdk/src/share/classes/java/net/SocketInputStream.java
index 219cf0a..6845b9c 100644
--- a/jdk/src/share/classes/java/net/SocketInputStream.java
+++ b/jdk/src/share/classes/java/net/SocketInputStream.java
@@ -30,6 +30,7 @@
 import java.io.IOException;
 import java.nio.channels.FileChannel;
 
+import sun.misc.IoTrace;
 import sun.net.ConnectionResetException;
 
 /**
@@ -122,7 +123,7 @@
     }
 
     int read(byte b[], int off, int length, int timeout) throws IOException {
-        int n;
+        int n = 0;
 
         // EOF already encountered
         if (eof) {
@@ -144,6 +145,7 @@
 
         boolean gotReset = false;
 
+        Object traceContext = IoTrace.socketReadBegin(impl.address, impl.port, timeout);
         // acquire file descriptor and do the read
         FileDescriptor fd = impl.acquireFD();
         try {
@@ -155,6 +157,7 @@
             gotReset = true;
         } finally {
             impl.releaseFD();
+            IoTrace.socketReadEnd(traceContext, n > 0 ? n : 0);
         }
 
         /*
@@ -162,6 +165,7 @@
          * buffered on the socket
          */
         if (gotReset) {
+            traceContext = IoTrace.socketReadBegin(impl.address, impl.port, timeout);
             impl.setConnectionResetPending();
             impl.acquireFD();
             try {
@@ -172,6 +176,7 @@
             } catch (ConnectionResetException rstExc) {
             } finally {
                 impl.releaseFD();
+                IoTrace.socketReadEnd(traceContext, n > 0 ? n : 0);
             }
         }
 
diff --git a/jdk/src/share/classes/java/net/SocketOutputStream.java b/jdk/src/share/classes/java/net/SocketOutputStream.java
index 06e234e..130bfdc 100644
--- a/jdk/src/share/classes/java/net/SocketOutputStream.java
+++ b/jdk/src/share/classes/java/net/SocketOutputStream.java
@@ -30,6 +30,8 @@
 import java.io.IOException;
 import java.nio.channels.FileChannel;
 
+import sun.misc.IoTrace;
+
 /**
  * This stream extends FileOutputStream to implement a
  * SocketOutputStream. Note that this class should <b>NOT</b> be
@@ -104,9 +106,12 @@
             throw new ArrayIndexOutOfBoundsException();
         }
 
+        Object traceContext = IoTrace.socketWriteBegin(impl.address, impl.port);
+        int bytesWritten = 0;
         FileDescriptor fd = impl.acquireFD();
         try {
             socketWrite0(fd, b, off, len);
+            bytesWritten = len;
         } catch (SocketException se) {
             if (se instanceof sun.net.ConnectionResetException) {
                 impl.setConnectionResetPending();
@@ -119,6 +124,7 @@
             }
         } finally {
             impl.releaseFD();
+            IoTrace.socketWriteEnd(traceContext, bytesWritten);
         }
     }
 
diff --git a/jdk/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java b/jdk/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
index 81b3ae1..1389003 100644
--- a/jdk/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
+++ b/jdk/src/share/classes/java/nio/channels/spi/AbstractSelectableChannel.java
@@ -90,27 +90,26 @@
     // -- Utility methods for the key set --
 
     private void addKey(SelectionKey k) {
-        synchronized (keyLock) {
-            int i = 0;
-            if ((keys != null) && (keyCount < keys.length)) {
-                // Find empty element of key array
-                for (i = 0; i < keys.length; i++)
-                    if (keys[i] == null)
-                        break;
-            } else if (keys == null) {
-                keys =  new SelectionKey[3];
-            } else {
-                // Grow key array
-                int n = keys.length * 2;
-                SelectionKey[] ks =  new SelectionKey[n];
-                for (i = 0; i < keys.length; i++)
-                    ks[i] = keys[i];
-                keys = ks;
-                i = keyCount;
-            }
-            keys[i] = k;
-            keyCount++;
+        assert Thread.holdsLock(keyLock);
+        int i = 0;
+        if ((keys != null) && (keyCount < keys.length)) {
+            // Find empty element of key array
+            for (i = 0; i < keys.length; i++)
+                if (keys[i] == null)
+                    break;
+        } else if (keys == null) {
+            keys =  new SelectionKey[3];
+        } else {
+            // Grow key array
+            int n = keys.length * 2;
+            SelectionKey[] ks =  new SelectionKey[n];
+            for (i = 0; i < keys.length; i++)
+                ks[i] = keys[i];
+            keys = ks;
+            i = keyCount;
         }
+        keys[i] = k;
+        keyCount++;
     }
 
     private SelectionKey findKey(Selector sel) {
@@ -190,11 +189,11 @@
                                        Object att)
         throws ClosedChannelException
     {
-        if (!isOpen())
-            throw new ClosedChannelException();
-        if ((ops & ~validOps()) != 0)
-            throw new IllegalArgumentException();
         synchronized (regLock) {
+            if (!isOpen())
+                throw new ClosedChannelException();
+            if ((ops & ~validOps()) != 0)
+                throw new IllegalArgumentException();
             if (blocking)
                 throw new IllegalBlockingModeException();
             SelectionKey k = findKey(sel);
@@ -204,8 +203,12 @@
             }
             if (k == null) {
                 // New registration
-                k = ((AbstractSelector)sel).register(this, ops, att);
-                addKey(k);
+                synchronized (keyLock) {
+                    if (!isOpen())
+                        throw new ClosedChannelException();
+                    k = ((AbstractSelector)sel).register(this, ops, att);
+                    addKey(k);
+                }
             }
             return k;
         }
@@ -275,9 +278,9 @@
     public final SelectableChannel configureBlocking(boolean block)
         throws IOException
     {
-        if (!isOpen())
-            throw new ClosedChannelException();
         synchronized (regLock) {
+            if (!isOpen())
+                throw new ClosedChannelException();
             if (blocking == block)
                 return this;
             if (block && haveValidKeys())
diff --git a/jdk/src/share/classes/java/security/Signature.java b/jdk/src/share/classes/java/security/Signature.java
index b92a16b..59cc0d4 100644
--- a/jdk/src/share/classes/java/security/Signature.java
+++ b/jdk/src/share/classes/java/security/Signature.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -658,7 +658,7 @@
         throws SignatureException {
         if (state == VERIFY) {
             if ((signature == null) || (offset < 0) || (length < 0) ||
-                (offset + length > signature.length)) {
+                (length > signature.length - offset)) {
                 throw new IllegalArgumentException("Bad arguments");
             }
 
diff --git a/jdk/src/share/classes/java/text/DateFormatSymbols.java b/jdk/src/share/classes/java/text/DateFormatSymbols.java
index 2eeb07e..2bce118 100644
--- a/jdk/src/share/classes/java/text/DateFormatSymbols.java
+++ b/jdk/src/share/classes/java/text/DateFormatSymbols.java
@@ -647,6 +647,8 @@
     private static final ConcurrentMap<Locale, SoftReference<DateFormatSymbols>> cachedInstances
         = new ConcurrentHashMap<Locale, SoftReference<DateFormatSymbols>>(3);
 
+    private transient int lastZoneIndex = 0;
+
     private void initializeData(Locale desiredLocale) {
         locale = desiredLocale;
 
@@ -692,12 +694,24 @@
      * the given time zone ID can't be located in the DateFormatSymbols object.
      * @see java.util.SimpleTimeZone
      */
-    final int getZoneIndex(String ID)
-    {
+    final int getZoneIndex(String ID) {
         String[][] zoneStrings = getZoneStringsWrapper();
-        for (int index=0; index<zoneStrings.length; index++)
-        {
-            if (ID.equals(zoneStrings[index][0])) return index;
+
+        /*
+         * getZoneIndex has been re-written for performance reasons. instead of
+         * traversing the zoneStrings array every time, we cache the last used zone
+         * index
+         */
+        if (lastZoneIndex < zoneStrings.length && ID.equals(zoneStrings[lastZoneIndex][0])) {
+            return lastZoneIndex;
+        }
+
+        /* slow path, search entire list */
+        for (int index = 0; index < zoneStrings.length; index++) {
+            if (ID.equals(zoneStrings[index][0])) {
+                lastZoneIndex = index;
+                return index;
+            }
         }
 
         return -1;
diff --git a/jdk/src/share/classes/java/util/AbstractCollection.java b/jdk/src/share/classes/java/util/AbstractCollection.java
index 2ae70f7..a32d411 100644
--- a/jdk/src/share/classes/java/util/AbstractCollection.java
+++ b/jdk/src/share/classes/java/util/AbstractCollection.java
@@ -180,13 +180,21 @@
 
         for (int i = 0; i < r.length; i++) {
             if (! it.hasNext()) { // fewer elements than expected
-                if (a != r)
+                if (a == r) {
+                    r[i] = null; // null-terminate
+                } else if (a.length < i) {
                     return Arrays.copyOf(r, i);
-                r[i] = null; // null-terminate
-                return r;
+                } else {
+                    System.arraycopy(r, 0, a, 0, i);
+                    if (a.length > i) {
+                        a[i] = null;
+                    }
+                }
+                return a;
             }
             r[i] = (T)it.next();
         }
+        // more elements than expected
         return it.hasNext() ? finishToArray(r, it) : r;
     }
 
diff --git a/jdk/src/share/classes/java/util/Hashtable.java b/jdk/src/share/classes/java/util/Hashtable.java
index 3858601..df8bae5 100644
--- a/jdk/src/share/classes/java/util/Hashtable.java
+++ b/jdk/src/share/classes/java/util/Hashtable.java
@@ -1114,7 +1114,7 @@
         }
 
         public int hashCode() {
-            return hash ^ value.hashCode();
+            return (Objects.hashCode(key) ^ Objects.hashCode(value));
         }
 
         public String toString() {
diff --git a/jdk/src/share/classes/java/util/WeakHashMap.java b/jdk/src/share/classes/java/util/WeakHashMap.java
index c59b4cd..3a8737d 100644
--- a/jdk/src/share/classes/java/util/WeakHashMap.java
+++ b/jdk/src/share/classes/java/util/WeakHashMap.java
@@ -90,7 +90,8 @@
  * from being discarded.  Note that a value object may refer indirectly to its
  * key via the <tt>WeakHashMap</tt> itself; that is, a value object may
  * strongly refer to some other key object whose associated value object, in
- * turn, strongly refers to the key of the first value object.  One way
+ * turn, strongly refers to the key of the first value object.  If the values
+ * in the map do not rely on the map holding strong references to them, one way
  * to deal with this is to wrap values themselves within
  * <tt>WeakReferences</tt> before
  * inserting, as in: <tt>m.put(key, new WeakReference(value))</tt>,
diff --git a/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java b/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java
index 83dbb4d..c20efa7 100644
--- a/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java
+++ b/jdk/src/share/classes/java/util/concurrent/PriorityBlockingQueue.java
@@ -35,7 +35,8 @@
 
 package java.util.concurrent;
 
-import java.util.concurrent.locks.*;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.ReentrantLock;
 import java.util.*;
 
 /**
@@ -110,7 +111,7 @@
      * java.util.PriorityQueue operations within a lock, as was done
      * in a previous version of this class. To maintain
      * interoperability, a plain PriorityQueue is still used during
-     * serialization, which maintains compatibility at the espense of
+     * serialization, which maintains compatibility at the expense of
      * transiently doubling overhead.
      */
 
@@ -307,14 +308,13 @@
     /**
      * Mechanics for poll().  Call only while holding lock.
      */
-    private E extract() {
-        E result;
+    private E dequeue() {
         int n = size - 1;
         if (n < 0)
-            result = null;
+            return null;
         else {
             Object[] array = queue;
-            result = (E) array[0];
+            E result = (E) array[0];
             E x = (E) array[n];
             array[n] = null;
             Comparator<? super E> cmp = comparator;
@@ -323,8 +323,8 @@
             else
                 siftDownUsingComparator(0, x, array, n, cmp);
             size = n;
+            return result;
         }
-        return result;
     }
 
     /**
@@ -381,39 +381,43 @@
      */
     private static <T> void siftDownComparable(int k, T x, Object[] array,
                                                int n) {
-        Comparable<? super T> key = (Comparable<? super T>)x;
-        int half = n >>> 1;           // loop while a non-leaf
-        while (k < half) {
-            int child = (k << 1) + 1; // assume left child is least
-            Object c = array[child];
-            int right = child + 1;
-            if (right < n &&
-                ((Comparable<? super T>) c).compareTo((T) array[right]) > 0)
-                c = array[child = right];
-            if (key.compareTo((T) c) <= 0)
-                break;
-            array[k] = c;
-            k = child;
+        if (n > 0) {
+            Comparable<? super T> key = (Comparable<? super T>)x;
+            int half = n >>> 1;           // loop while a non-leaf
+            while (k < half) {
+                int child = (k << 1) + 1; // assume left child is least
+                Object c = array[child];
+                int right = child + 1;
+                if (right < n &&
+                    ((Comparable<? super T>) c).compareTo((T) array[right]) > 0)
+                    c = array[child = right];
+                if (key.compareTo((T) c) <= 0)
+                    break;
+                array[k] = c;
+                k = child;
+            }
+            array[k] = key;
         }
-        array[k] = key;
     }
 
     private static <T> void siftDownUsingComparator(int k, T x, Object[] array,
                                                     int n,
                                                     Comparator<? super T> cmp) {
-        int half = n >>> 1;
-        while (k < half) {
-            int child = (k << 1) + 1;
-            Object c = array[child];
-            int right = child + 1;
-            if (right < n && cmp.compare((T) c, (T) array[right]) > 0)
-                c = array[child = right];
-            if (cmp.compare(x, (T) c) <= 0)
-                break;
-            array[k] = c;
-            k = child;
+        if (n > 0) {
+            int half = n >>> 1;
+            while (k < half) {
+                int child = (k << 1) + 1;
+                Object c = array[child];
+                int right = child + 1;
+                if (right < n && cmp.compare((T) c, (T) array[right]) > 0)
+                    c = array[child = right];
+                if (cmp.compare(x, (T) c) <= 0)
+                    break;
+                array[k] = c;
+                k = child;
+            }
+            array[k] = x;
         }
-        array[k] = x;
     }
 
     /**
@@ -519,13 +523,11 @@
     public E poll() {
         final ReentrantLock lock = this.lock;
         lock.lock();
-        E result;
         try {
-            result = extract();
+            return dequeue();
         } finally {
             lock.unlock();
         }
-        return result;
     }
 
     public E take() throws InterruptedException {
@@ -533,7 +535,7 @@
         lock.lockInterruptibly();
         E result;
         try {
-            while ( (result = extract()) == null)
+            while ( (result = dequeue()) == null)
                 notEmpty.await();
         } finally {
             lock.unlock();
@@ -547,7 +549,7 @@
         lock.lockInterruptibly();
         E result;
         try {
-            while ( (result = extract()) == null && nanos > 0)
+            while ( (result = dequeue()) == null && nanos > 0)
                 nanos = notEmpty.awaitNanos(nanos);
         } finally {
             lock.unlock();
@@ -558,13 +560,11 @@
     public E peek() {
         final ReentrantLock lock = this.lock;
         lock.lock();
-        E result;
         try {
-            result = size > 0 ? (E) queue[0] : null;
+            return (size == 0) ? null : (E) queue[0];
         } finally {
             lock.unlock();
         }
-        return result;
     }
 
     /**
@@ -648,32 +648,28 @@
      * @return {@code true} if this queue changed as a result of the call
      */
     public boolean remove(Object o) {
-        boolean removed = false;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             int i = indexOf(o);
-            if (i != -1) {
-                removeAt(i);
-                removed = true;
-            }
+            if (i == -1)
+                return false;
+            removeAt(i);
+            return true;
         } finally {
             lock.unlock();
         }
-        return removed;
     }
 
-
     /**
      * Identity-based version for use in Itr.remove
      */
-    private void removeEQ(Object o) {
+    void removeEQ(Object o) {
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
             Object[] array = queue;
-            int n = size;
-            for (int i = 0; i < n; i++) {
+            for (int i = 0, n = size; i < n; i++) {
                 if (o == array[i]) {
                     removeAt(i);
                     break;
@@ -693,15 +689,13 @@
      * @return {@code true} if this queue contains the specified element
      */
     public boolean contains(Object o) {
-        int index;
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            index = indexOf(o);
+            return indexOf(o) != -1;
         } finally {
             lock.unlock();
         }
-        return index != -1;
     }
 
     /**
@@ -727,7 +721,6 @@
         }
     }
 
-
     public String toString() {
         final ReentrantLock lock = this.lock;
         lock.lock();
@@ -738,7 +731,7 @@
             StringBuilder sb = new StringBuilder();
             sb.append('[');
             for (int i = 0; i < n; ++i) {
-                E e = (E)queue[i];
+                Object e = queue[i];
                 sb.append(e == this ? "(this Collection)" : e);
                 if (i != n - 1)
                     sb.append(',').append(' ');
@@ -756,23 +749,7 @@
      * @throws IllegalArgumentException      {@inheritDoc}
      */
     public int drainTo(Collection<? super E> c) {
-        if (c == null)
-            throw new NullPointerException();
-        if (c == this)
-            throw new IllegalArgumentException();
-        final ReentrantLock lock = this.lock;
-        lock.lock();
-        try {
-            int n = 0;
-            E e;
-            while ( (e = extract()) != null) {
-                c.add(e);
-                ++n;
-            }
-            return n;
-        } finally {
-            lock.unlock();
-        }
+        return drainTo(c, Integer.MAX_VALUE);
     }
 
     /**
@@ -791,11 +768,10 @@
         final ReentrantLock lock = this.lock;
         lock.lock();
         try {
-            int n = 0;
-            E e;
-            while (n < maxElements && (e = extract()) != null) {
-                c.add(e);
-                ++n;
+            int n = Math.min(size, maxElements);
+            for (int i = 0; i < n; i++) {
+                c.add((E) queue[0]); // In this order, in case add() throws.
+                dequeue();
             }
             return n;
         } finally {
@@ -843,8 +819,7 @@
      * The following code can be used to dump the queue into a newly
      * allocated array of {@code String}:
      *
-     * <pre>
-     *     String[] y = x.toArray(new String[0]);</pre>
+     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
      *
      * Note that {@code toArray(new Object[0])} is identical in function to
      * {@code toArray()}.
@@ -897,7 +872,7 @@
      */
     final class Itr implements Iterator<E> {
         final Object[] array; // Array of all elements
-        int cursor;           // index of next element to return;
+        int cursor;           // index of next element to return
         int lastRet;          // index of last element, or -1 if no such
 
         Itr(Object[] array) {
@@ -925,17 +900,18 @@
     }
 
     /**
-     * Saves the state to a stream (that is, serializes it).  For
-     * compatibility with previous version of this class,
-     * elements are first copied to a java.util.PriorityQueue,
-     * which is then serialized.
+     * Saves this queue to a stream (that is, serializes it).
+     *
+     * For compatibility with previous version of this class, elements
+     * are first copied to a java.util.PriorityQueue, which is then
+     * serialized.
      */
     private void writeObject(java.io.ObjectOutputStream s)
         throws java.io.IOException {
         lock.lock();
         try {
-            int n = size; // avoid zero capacity argument
-            q = new PriorityQueue<E>(n == 0 ? 1 : n, comparator);
+            // avoid zero capacity argument
+            q = new PriorityQueue<E>(Math.max(size, 1), comparator);
             q.addAll(this);
             s.defaultWriteObject();
         } finally {
@@ -945,10 +921,7 @@
     }
 
     /**
-     * Reconstitutes the {@code PriorityBlockingQueue} instance from a stream
-     * (that is, deserializes it).
-     *
-     * @param s the stream
+     * Reconstitutes this queue from a stream (that is, deserializes it).
      */
     private void readObject(java.io.ObjectInputStream s)
         throws java.io.IOException, ClassNotFoundException {
diff --git a/jdk/src/share/classes/java/util/zip/Deflater.java b/jdk/src/share/classes/java/util/zip/Deflater.java
index 0f001df..e5e9b27 100644
--- a/jdk/src/share/classes/java/util/zip/Deflater.java
+++ b/jdk/src/share/classes/java/util/zip/Deflater.java
@@ -79,6 +79,8 @@
     private int level, strategy;
     private boolean setParams;
     private boolean finish, finished;
+    private long bytesRead;
+    private long bytesWritten;
 
     /**
      * Compression method for the deflate algorithm (the only one currently
@@ -423,8 +425,13 @@
         synchronized (zsRef) {
             ensureOpen();
             if (flush == NO_FLUSH || flush == SYNC_FLUSH ||
-                flush == FULL_FLUSH)
-                return deflateBytes(zsRef.address(), b, off, len, flush);
+                flush == FULL_FLUSH) {
+                int thisLen = this.len;
+                int n = deflateBytes(zsRef.address(), b, off, len, flush);
+                bytesWritten += n;
+                bytesRead += (thisLen - this.len);
+                return n;
+            }
             throw new IllegalArgumentException();
         }
     }
@@ -462,7 +469,7 @@
     public long getBytesRead() {
         synchronized (zsRef) {
             ensureOpen();
-            return getBytesRead(zsRef.address());
+            return bytesRead;
         }
     }
 
@@ -488,7 +495,7 @@
     public long getBytesWritten() {
         synchronized (zsRef) {
             ensureOpen();
-            return getBytesWritten(zsRef.address());
+            return bytesWritten;
         }
     }
 
@@ -503,6 +510,7 @@
             finish = false;
             finished = false;
             off = len = 0;
+            bytesRead = bytesWritten = 0;
         }
     }
 
@@ -543,8 +551,6 @@
     private native int deflateBytes(long addr, byte[] b, int off, int len,
                                     int flush);
     private native static int getAdler(long addr);
-    private native static long getBytesRead(long addr);
-    private native static long getBytesWritten(long addr);
     private native static void reset(long addr);
     private native static void end(long addr);
 }
diff --git a/jdk/src/share/classes/java/util/zip/Inflater.java b/jdk/src/share/classes/java/util/zip/Inflater.java
index 1206be7..9a7976c 100644
--- a/jdk/src/share/classes/java/util/zip/Inflater.java
+++ b/jdk/src/share/classes/java/util/zip/Inflater.java
@@ -78,6 +78,8 @@
     private int off, len;
     private boolean finished;
     private boolean needDict;
+    private long bytesRead;
+    private long bytesWritten;
 
     private static final byte[] defaultBuf = new byte[0];
 
@@ -253,7 +255,11 @@
         }
         synchronized (zsRef) {
             ensureOpen();
-            return inflateBytes(zsRef.address(), b, off, len);
+            int thisLen = this.len;
+            int n = inflateBytes(zsRef.address(), b, off, len);
+            bytesWritten += n;
+            bytesRead += (thisLen - this.len);
+            return n;
         }
     }
 
@@ -307,7 +313,7 @@
     public long getBytesRead() {
         synchronized (zsRef) {
             ensureOpen();
-            return getBytesRead(zsRef.address());
+            return bytesRead;
         }
     }
 
@@ -333,7 +339,7 @@
     public long getBytesWritten() {
         synchronized (zsRef) {
             ensureOpen();
-            return getBytesWritten(zsRef.address());
+            return bytesWritten;
         }
     }
 
@@ -348,6 +354,7 @@
             finished = false;
             needDict = false;
             off = len = 0;
+            bytesRead = bytesWritten = 0;
         }
     }
 
@@ -395,8 +402,6 @@
     private native int inflateBytes(long addr, byte[] b, int off, int len)
             throws DataFormatException;
     private native static int getAdler(long addr);
-    private native static long getBytesRead(long addr);
-    private native static long getBytesWritten(long addr);
     private native static void reset(long addr);
     private native static void end(long addr);
 }
diff --git a/jdk/src/share/classes/javax/swing/JColorChooser.java b/jdk/src/share/classes/javax/swing/JColorChooser.java
index 05270e6..07a7279 100644
--- a/jdk/src/share/classes/javax/swing/JColorChooser.java
+++ b/jdk/src/share/classes/javax/swing/JColorChooser.java
@@ -182,6 +182,7 @@
             dialog = new ColorChooserDialog((Dialog)window, title, modal, c, chooserPane,
                                             okListener, cancelListener);
         }
+        dialog.getAccessibleContext().setAccessibleDescription(title);
         return dialog;
     }
 
@@ -647,6 +648,7 @@
         buttonPane.setLayout(new FlowLayout(FlowLayout.CENTER));
         JButton okButton = new JButton(okString);
         getRootPane().setDefaultButton(okButton);
+        okButton.getAccessibleContext().setAccessibleDescription(okString);
         okButton.setActionCommand("OK");
         okButton.addActionListener(new ActionListener() {
             public void actionPerformed(ActionEvent e) {
@@ -659,6 +661,7 @@
         buttonPane.add(okButton);
 
         cancelButton = new JButton(cancelString);
+        cancelButton.getAccessibleContext().setAccessibleDescription(cancelString);
 
         // The following few lines are used to register esc to close the dialog
         Action cancelKeyAction = new AbstractAction() {
@@ -688,6 +691,7 @@
         buttonPane.add(cancelButton);
 
         JButton resetButton = new JButton(resetString);
+        resetButton.getAccessibleContext().setAccessibleDescription(resetString);
         resetButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                reset();
diff --git a/jdk/src/share/classes/javax/swing/JComponent.java b/jdk/src/share/classes/javax/swing/JComponent.java
index 3a9d168..f7ebe9f 100644
--- a/jdk/src/share/classes/javax/swing/JComponent.java
+++ b/jdk/src/share/classes/javax/swing/JComponent.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -2636,17 +2636,16 @@
      *    attribute: visualUpdate true
      */
     public void setVisible(boolean aFlag) {
-        if(aFlag != isVisible()) {
+        if (aFlag != isVisible()) {
             super.setVisible(aFlag);
-            Container parent = getParent();
-            if(parent != null) {
-                Rectangle r = getBounds();
-                parent.repaint(r.x,r.y,r.width,r.height);
+            if (aFlag) {
+                Container parent = getParent();
+                if (parent != null) {
+                    Rectangle r = getBounds();
+                    parent.repaint(r.x, r.y, r.width, r.height);
+                }
+                revalidate();
             }
-            // Some (all should) LayoutManagers do not consider components
-            // that are not visible. As such we need to revalidate when the
-            // visible bit changes.
-            revalidate();
         }
     }
 
@@ -5564,4 +5563,22 @@
         ",preferredSize=" + preferredSizeString;
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    @Deprecated
+    public void hide() {
+        boolean showing = isShowing();
+        super.hide();
+        if (showing) {
+            Container parent = getParent();
+            if (parent != null) {
+                Rectangle r = getBounds();
+                parent.repaint(r.x, r.y, r.width, r.height);
+            }
+            revalidate();
+        }
+    }
+
 }
diff --git a/jdk/src/share/classes/javax/swing/JTable.java b/jdk/src/share/classes/javax/swing/JTable.java
index 386b2a4..4a8df60 100644
--- a/jdk/src/share/classes/javax/swing/JTable.java
+++ b/jdk/src/share/classes/javax/swing/JTable.java
@@ -5468,7 +5468,7 @@
                 if (constructor.getDeclaringClass() == String.class) {
                     value = s;
                 }
-                super.stopCellEditing();
+                return super.stopCellEditing();
             }
 
             try {
@@ -8588,7 +8588,7 @@
              *    <code>null</code> if this object is not on the screen
              */
             public Point getLocationOnScreen() {
-                if (parent != null) {
+                if (parent != null && parent.isShowing()) {
                     Point parentLocation = parent.getLocationOnScreen();
                     Point componentLocation = getLocation();
                     componentLocation.translate(parentLocation.x, parentLocation.y);
@@ -9389,7 +9389,7 @@
              *    <code>null</code> if this object is not on the screen
              */
             public Point getLocationOnScreen() {
-                if (parent != null) {
+                if (parent != null && parent.isShowing()) {
                     Point parentLocation = parent.getLocationOnScreen();
                     Point componentLocation = getLocation();
                     componentLocation.translate(parentLocation.x, parentLocation.y);
diff --git a/jdk/src/share/classes/javax/swing/JViewport.java b/jdk/src/share/classes/javax/swing/JViewport.java
index 51975d7..c2ea60b 100644
--- a/jdk/src/share/classes/javax/swing/JViewport.java
+++ b/jdk/src/share/classes/javax/swing/JViewport.java
@@ -1586,10 +1586,18 @@
         int bdx = blitToX - blitFromX;
         int bdy = blitToY - blitFromY;
 
+        Composite oldComposite = null;
         // Shift the scrolled region
+        if (g instanceof Graphics2D) {
+            Graphics2D g2d = (Graphics2D) g;
+            oldComposite = g2d.getComposite();
+            g2d.setComposite(AlphaComposite.Src);
+        }
         rm.copyArea(this, g, blitFromX, blitFromY, blitW, blitH, bdx, bdy,
                     false);
-
+        if (oldComposite != null) {
+            ((Graphics2D) g).setComposite(oldComposite);
+        }
         // Paint the newly exposed region.
         int x = view.getX();
         int y = view.getY();
diff --git a/jdk/src/share/classes/javax/swing/RepaintManager.java b/jdk/src/share/classes/javax/swing/RepaintManager.java
index 5a6e15e..b9b81b7 100644
--- a/jdk/src/share/classes/javax/swing/RepaintManager.java
+++ b/jdk/src/share/classes/javax/swing/RepaintManager.java
@@ -119,6 +119,11 @@
     // Whether or not a VolatileImage should be used for double-buffered painting
     static boolean volatileImageBufferEnabled = true;
     /**
+     * Type of VolatileImage which should be used for double-buffered
+     * painting.
+     */
+    private static final int volatileBufferType;
+    /**
      * Value of the system property awt.nativeDoubleBuffering.
      */
     private static boolean nativeDoubleBuffering;
@@ -204,6 +209,13 @@
             ((SunGraphicsEnvironment)ge).addDisplayChangedListener(
                     new DisplayChangedHandler());
         }
+        Toolkit tk = Toolkit.getDefaultToolkit();
+        if ((tk instanceof SunToolkit)
+                && ((SunToolkit) tk).isSwingBackbufferTranslucencySupported()) {
+            volatileBufferType = Transparency.TRANSLUCENT;
+        } else {
+            volatileBufferType = Transparency.OPAQUE;
+        }
     }
 
     /**
@@ -985,7 +997,8 @@
             if (image != null) {
                 image.flush();
             }
-            image = config.createCompatibleVolatileImage(width, height);
+            image = config.createCompatibleVolatileImage(width, height,
+                                                         volatileBufferType);
             volatileMap.put(config, image);
         }
         return image;
@@ -1479,9 +1492,26 @@
                     for(y=clipY, maxy = clipY + clipH; y < maxy ; y += bh) {
                         osg.translate(-x, -y);
                         osg.setClip(x,y,bw,bh);
+                        if (volatileBufferType != Transparency.OPAQUE
+                                && osg instanceof Graphics2D) {
+                            final Graphics2D g2d = (Graphics2D) osg;
+                            final Color oldBg = g2d.getBackground();
+                            g2d.setBackground(c.getBackground());
+                            g2d.clearRect(x, y, bw, bh);
+                            g2d.setBackground(oldBg);
+                        }
                         c.paintToOffscreen(osg, x, y, bw, bh, maxx, maxy);
                         g.setClip(x, y, bw, bh);
-                        g.drawImage(image, x, y, c);
+                        if (volatileBufferType != Transparency.OPAQUE
+                                && g instanceof Graphics2D) {
+                            final Graphics2D g2d = (Graphics2D) g;
+                            final Composite oldComposite = g2d.getComposite();
+                            g2d.setComposite(AlphaComposite.Src);
+                            g2d.drawImage(image, x, y, c);
+                            g2d.setComposite(oldComposite);
+                        } else {
+                            g.drawImage(image, x, y, c);
+                        }
                         osg.translate(x, y);
                     }
                 }
diff --git a/jdk/src/share/classes/javax/swing/TimerQueue.java b/jdk/src/share/classes/javax/swing/TimerQueue.java
index 463ff47..a6791d6 100644
--- a/jdk/src/share/classes/javax/swing/TimerQueue.java
+++ b/jdk/src/share/classes/javax/swing/TimerQueue.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -187,6 +187,9 @@
                                 addTimer(delayedTimer);
                             }
                         }
+
+                        // Allow run other threads on systems without kernel threads
+                        timer.getLock().newCondition().awaitNanos(1);
                     } catch (SecurityException ignore) {
                     } finally {
                         timer.getLock().unlock();
diff --git a/jdk/src/share/classes/javax/swing/ToolTipManager.java b/jdk/src/share/classes/javax/swing/ToolTipManager.java
index fd0953d..1bb26e2 100644
--- a/jdk/src/share/classes/javax/swing/ToolTipManager.java
+++ b/jdk/src/share/classes/javax/swing/ToolTipManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -217,6 +217,25 @@
         return exitTimer.getInitialDelay();
     }
 
+    // Returns GraphicsConfiguration instance that toFind belongs to or null
+    // if drawing point is set to a point beyond visible screen area (e.g.
+    // Point(20000, 20000))
+    private GraphicsConfiguration getDrawingGC(Point toFind) {
+        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        GraphicsDevice devices[] = env.getScreenDevices();
+        for (GraphicsDevice device : devices) {
+            GraphicsConfiguration configs[] = device.getConfigurations();
+            for (GraphicsConfiguration config : configs) {
+                Rectangle rect = config.getBounds();
+                if (rect.contains(toFind)) {
+                    return config;
+                }
+            }
+        }
+
+        return null;
+    }
+
     void showTipWindow() {
         if(insideComponent == null || !insideComponent.isShowing())
             return;
@@ -231,9 +250,25 @@
         if (enabled) {
             Dimension size;
             Point screenLocation = insideComponent.getLocationOnScreen();
-            Point location = new Point();
-            GraphicsConfiguration gc;
-            gc = insideComponent.getGraphicsConfiguration();
+            Point location;
+
+            Point toFind;
+            if (preferredLocation != null) {
+                toFind = new Point(screenLocation.x + preferredLocation.x,
+                        screenLocation.y + preferredLocation.y);
+            } else {
+                toFind = mouseEvent.getLocationOnScreen();
+            }
+
+            GraphicsConfiguration gc = getDrawingGC(toFind);
+            if (gc == null) {
+                toFind = mouseEvent.getLocationOnScreen();
+                gc = getDrawingGC(toFind);
+                if (gc == null) {
+                    gc = insideComponent.getGraphicsConfiguration();
+                }
+            }
+
             Rectangle sBounds = gc.getBounds();
             Insets screenInsets = Toolkit.getDefaultToolkit()
                                              .getScreenInsets(gc);
@@ -253,14 +288,13 @@
             size = tip.getPreferredSize();
 
             if(preferredLocation != null) {
-                location.x = screenLocation.x + preferredLocation.x;
-                location.y = screenLocation.y + preferredLocation.y;
+                location = toFind;
         if (!leftToRight) {
             location.x -= size.width;
         }
             } else {
-                location.x = screenLocation.x + mouseEvent.getX();
-                location.y = screenLocation.y + mouseEvent.getY() + 20;
+                location = new Point(screenLocation.x + mouseEvent.getX(),
+                        screenLocation.y + mouseEvent.getY() + 20);
         if (!leftToRight) {
             if(location.x - size.width>=0) {
                 location.x -= size.width;
diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java
index 12f6bc2..37e7135 100644
--- a/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java
+++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorChooserPanel.java
@@ -135,6 +135,7 @@
         String label = this.model.getText(this, "HexCode"); // NON-NLS: suffix
         boolean visible = label != null;
         this.text.setVisible(visible);
+        this.text.getAccessibleContext().setAccessibleDescription(label);
         this.label.setVisible(visible);
         if (visible) {
             this.label.setText(label);
diff --git a/jdk/src/share/classes/javax/swing/colorchooser/ColorPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/ColorPanel.java
index 1070d1f..b1f992a 100644
--- a/jdk/src/share/classes/javax/swing/colorchooser/ColorPanel.java
+++ b/jdk/src/share/classes/javax/swing/colorchooser/ColorPanel.java
@@ -37,6 +37,7 @@
 import javax.swing.JPanel;
 import javax.swing.JRadioButton;
 import javax.swing.border.EmptyBorder;
+import javax.swing.JSpinner.DefaultEditor;
 
 final class ColorPanel extends JPanel implements ActionListener {
 
@@ -119,17 +120,26 @@
         int count = this.model.getCount();
         this.spinners[4].setVisible(count > 4);
         for (int i = 0; i < count; i++) {
+            String text = this.model.getLabel(this, i);
             Object object = this.spinners[i].getLabel();
             if (object instanceof JRadioButton) {
                 JRadioButton button = (JRadioButton) object;
-                button.setText(this.model.getLabel(this, i));
+                button.setText(text);
+                button.getAccessibleContext().setAccessibleDescription(text);
             }
             else if (object instanceof JLabel) {
                 JLabel label = (JLabel) object;
-                label.setText(this.model.getLabel(this, i));
+                label.setText(text);
             }
             this.spinners[i].setRange(this.model.getMinimum(i), this.model.getMaximum(i));
             this.spinners[i].setValue(this.values[i]);
+            this.spinners[i].getSlider().getAccessibleContext().setAccessibleName(text);
+            this.spinners[i].getSpinner().getAccessibleContext().setAccessibleName(text);
+            DefaultEditor editor = (DefaultEditor) this.spinners[i].getSpinner().getEditor();
+            editor.getTextField().getAccessibleContext().setAccessibleName(text);
+            this.spinners[i].getSlider().getAccessibleContext().setAccessibleDescription(text);
+            this.spinners[i].getSpinner().getAccessibleContext().setAccessibleDescription(text);
+            editor.getTextField().getAccessibleContext().setAccessibleDescription(text);
         }
     }
 
diff --git a/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java b/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java
index a0227dd..564a085 100644
--- a/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java
+++ b/jdk/src/share/classes/javax/swing/colorchooser/DefaultSwatchChooserPanel.java
@@ -57,6 +57,8 @@
     RecentSwatchPanel recentSwatchPanel;
     MouseListener mainSwatchListener;
     MouseListener recentSwatchListener;
+    private KeyListener mainSwatchKeyListener;
+    private KeyListener recentSwatchKeyListener;
 
     public DefaultSwatchChooserPanel() {
         super();
@@ -151,10 +153,14 @@
         recentSwatchPanel.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY,
                                             recentStr);
 
+        mainSwatchKeyListener = new MainSwatchKeyListener();
         mainSwatchListener = new MainSwatchListener();
         swatchPanel.addMouseListener(mainSwatchListener);
+        swatchPanel.addKeyListener(mainSwatchKeyListener);
         recentSwatchListener = new RecentSwatchListener();
+        recentSwatchKeyListener = new RecentSwatchKeyListener();
         recentSwatchPanel.addMouseListener(recentSwatchListener);
+        recentSwatchPanel.addKeyListener(recentSwatchKeyListener);
 
         JPanel mainHolder = new JPanel(new BorderLayout());
         Border border = new CompoundBorder( new LineBorder(Color.black),
@@ -196,11 +202,17 @@
     public void uninstallChooserPanel(JColorChooser enclosingChooser) {
         super.uninstallChooserPanel(enclosingChooser);
         swatchPanel.removeMouseListener(mainSwatchListener);
+        swatchPanel.removeKeyListener(mainSwatchKeyListener);
         recentSwatchPanel.removeMouseListener(recentSwatchListener);
+        recentSwatchPanel.removeKeyListener(recentSwatchKeyListener);
+
         swatchPanel = null;
         recentSwatchPanel = null;
         mainSwatchListener = null;
+        mainSwatchKeyListener = null;
         recentSwatchListener = null;
+        recentSwatchKeyListener = null;
+
         removeAll();  // strip out all the sub-components
     }
 
@@ -209,11 +221,32 @@
     }
 
 
+    private class RecentSwatchKeyListener extends KeyAdapter {
+        public void keyPressed(KeyEvent e) {
+            if (KeyEvent.VK_SPACE == e.getKeyCode()) {
+                Color color = recentSwatchPanel.getSelectedColor();
+                setSelectedColor(color);
+            }
+        }
+    }
+
+    private class MainSwatchKeyListener extends KeyAdapter {
+        public void keyPressed(KeyEvent e) {
+            if (KeyEvent.VK_SPACE == e.getKeyCode()) {
+                Color color = swatchPanel.getSelectedColor();
+                setSelectedColor(color);
+                recentSwatchPanel.setMostRecentColor(color);
+            }
+        }
+    }
+
     class RecentSwatchListener extends MouseAdapter implements Serializable {
         public void mousePressed(MouseEvent e) {
             if (isEnabled()) {
                 Color color = recentSwatchPanel.getColorForLocation(e.getX(), e.getY());
+                recentSwatchPanel.setSelectedColorFromLocation(e.getX(), e.getY());
                 setSelectedColor(color);
+                recentSwatchPanel.requestFocusInWindow();
             }
         }
     }
@@ -223,7 +256,9 @@
             if (isEnabled()) {
                 Color color = swatchPanel.getColorForLocation(e.getX(), e.getY());
                 setSelectedColor(color);
+                swatchPanel.setSelectedColorFromLocation(e.getX(), e.getY());
                 recentSwatchPanel.setMostRecentColor(color);
+                swatchPanel.requestFocusInWindow();
             }
         }
     }
@@ -239,18 +274,81 @@
     protected Dimension numSwatches;
     protected Dimension gap;
 
+    private int selRow;
+    private int selCol;
+
     public SwatchPanel() {
         initValues();
         initColors();
         setToolTipText(""); // register for events
         setOpaque(true);
         setBackground(Color.white);
-        setRequestFocusEnabled(false);
+        setFocusable(true);
         setInheritsPopupMenu(true);
+
+        addFocusListener(new FocusAdapter() {
+            public void focusGained(FocusEvent e) {
+                repaint();
+            }
+
+            public void focusLost(FocusEvent e) {
+                repaint();
+            }
+        });
+
+        addKeyListener(new KeyAdapter() {
+            public void keyPressed(KeyEvent e) {
+                int typed = e.getKeyCode();
+                switch (typed) {
+                    case KeyEvent.VK_UP:
+                        if (selRow > 0) {
+                            selRow--;
+                            repaint();
+                        }
+                        break;
+                    case KeyEvent.VK_DOWN:
+                        if (selRow < numSwatches.height - 1) {
+                            selRow++;
+                            repaint();
+                        }
+                        break;
+                    case KeyEvent.VK_LEFT:
+                        if (selCol > 0 && SwatchPanel.this.getComponentOrientation().isLeftToRight()) {
+                            selCol--;
+                            repaint();
+                        } else if (selCol < numSwatches.width - 1
+                                && !SwatchPanel.this.getComponentOrientation().isLeftToRight()) {
+                            selCol++;
+                            repaint();
+                        }
+                        break;
+                    case KeyEvent.VK_RIGHT:
+                        if (selCol < numSwatches.width - 1
+                                && SwatchPanel.this.getComponentOrientation().isLeftToRight()) {
+                            selCol++;
+                            repaint();
+                        } else if (selCol > 0 && !SwatchPanel.this.getComponentOrientation().isLeftToRight()) {
+                            selCol--;
+                            repaint();
+                        }
+                        break;
+                    case KeyEvent.VK_HOME:
+                        selCol = 0;
+                        selRow = 0;
+                        repaint();
+                        break;
+                    case KeyEvent.VK_END:
+                        selCol = numSwatches.width - 1;
+                        selRow = numSwatches.height - 1;
+                        repaint();
+                        break;
+                }
+            }
+        });
     }
 
-    public boolean isFocusTraversable() {
-        return false;
+    public Color getSelectedColor() {
+        return getColorForCell(selCol, selRow);
     }
 
     protected void initValues() {
@@ -263,11 +361,10 @@
          for (int row = 0; row < numSwatches.height; row++) {
             int y = row * (swatchSize.height + gap.height);
             for (int column = 0; column < numSwatches.width; column++) {
-
-              g.setColor( getColorForCell(column, row) );
+                Color c = getColorForCell(column, row);
+                g.setColor(c);
                 int x;
-                if ((!this.getComponentOrientation().isLeftToRight()) &&
-                    (this instanceof RecentSwatchPanel)) {
+                if (!this.getComponentOrientation().isLeftToRight()) {
                     x = (numSwatches.width - column - 1) * (swatchSize.width + gap.width);
                 } else {
                     x = column * (swatchSize.width + gap.width);
@@ -276,6 +373,20 @@
                 g.setColor(Color.black);
                 g.drawLine( x+swatchSize.width-1, y, x+swatchSize.width-1, y+swatchSize.height-1);
                 g.drawLine( x, y+swatchSize.height-1, x+swatchSize.width-1, y+swatchSize.height-1);
+
+                if (selRow == row && selCol == column && this.isFocusOwner()) {
+                    Color c2 = new Color(c.getRed() < 125 ? 255 : 0,
+                            c.getGreen() < 125 ? 255 : 0,
+                            c.getBlue() < 125 ? 255 : 0);
+                    g.setColor(c2);
+
+                    g.drawLine(x, y, x + swatchSize.width - 1, y);
+                    g.drawLine(x, y, x, y + swatchSize.height - 1);
+                    g.drawLine(x + swatchSize.width - 1, y, x + swatchSize.width - 1, y + swatchSize.height - 1);
+                    g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y + swatchSize.height - 1);
+                    g.drawLine(x, y, x + swatchSize.width - 1, y + swatchSize.height - 1);
+                    g.drawLine(x, y + swatchSize.height - 1, x + swatchSize.width - 1, y);
+                }
             }
          }
     }
@@ -296,10 +407,19 @@
         return color.getRed()+", "+ color.getGreen() + ", " + color.getBlue();
     }
 
+    public void setSelectedColorFromLocation(int x, int y) {
+        if (!this.getComponentOrientation().isLeftToRight()) {
+            selCol = numSwatches.width - x / (swatchSize.width + gap.width) - 1;
+        } else {
+            selCol = x / (swatchSize.width + gap.width);
+        }
+        selRow = y / (swatchSize.height + gap.height);
+        repaint();
+    }
+
     public Color getColorForLocation( int x, int y ) {
         int column;
-        if ((!this.getComponentOrientation().isLeftToRight()) &&
-            (this instanceof RecentSwatchPanel)) {
+        if (!this.getComponentOrientation().isLeftToRight()) {
             column = numSwatches.width - x / (swatchSize.width + gap.width) - 1;
         } else {
             column = x / (swatchSize.width + gap.width);
diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java
index 8d01287..944048f 100644
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicColorChooserUI.java
@@ -94,6 +94,7 @@
         tabbedPane = new JTabbedPane();
         tabbedPane.setName("ColorChooser.tabPane");
         tabbedPane.setInheritsPopupMenu(true);
+        tabbedPane.getAccessibleContext().setAccessibleDescription(tabbedPane.getName());
         singlePanel = new JPanel(new CenterLayout());
         singlePanel.setName("ColorChooser.panel");
         singlePanel.setInheritsPopupMenu(true);
diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java
index 3d80e12..a9b3d263 100644
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTabbedPaneUI.java
@@ -875,6 +875,8 @@
                 int availTextWidth = tabScroller.croppedEdge.getCropline() -
                         (textRect.x - tabRect.x) - tabScroller.croppedEdge.getCroppedSideWidth();
                 clippedTitle = SwingUtilities2.clipStringIfNecessary(null, metrics, title, availTextWidth);
+            } else if (!scrollableTabLayoutEnabled() && isHorizontalTabPlacement()) {
+                clippedTitle = SwingUtilities2.clipStringIfNecessary(null, metrics, title, textRect.width);
             }
 
             paintText(g, tabPlacement, font, metrics,
diff --git a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
index f74edaf..497c0d6 100644
--- a/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
+++ b/jdk/src/share/classes/javax/swing/plaf/basic/BasicTreeUI.java
@@ -1941,6 +1941,9 @@
                     for(int counter = beginRow + 1; counter <= endRow; counter++) {
                             testRect = getPathBounds(tree,
                                     getPathForRow(tree, counter));
+                        if (testRect == null) {
+                            return;
+                        }
                         if((testRect.y + testRect.height) > maxY)
                                 counter = endRow;
                             }
@@ -2069,7 +2072,7 @@
                 treeState.invalidatePathBounds(oldPath);
                 updateSize();
             }
-            else {
+            else if (editingBounds != null) {
                 editingBounds.x = 0;
                 editingBounds.width = tree.getSize().width;
                 tree.repaint(editingBounds);
@@ -2114,6 +2117,9 @@
                        tree.isPathSelected(path), tree.isExpanded(path),
                        treeModel.isLeaf(path.getLastPathComponent()), row);
                 Rectangle           nodeBounds = getPathBounds(tree, path);
+                if (nodeBounds == null) {
+                    return false;
+                }
 
                 editingRow = row;
 
@@ -2134,6 +2140,9 @@
                     // To make sure x/y are updated correctly, fetch
                     // the bounds again.
                     nodeBounds = getPathBounds(tree, path);
+                    if (nodeBounds == null) {
+                        return false;
+                    }
                 }
                 else
                     editorHasDifferentSize = false;
@@ -3570,7 +3579,7 @@
             if(pressedPath != null) {
                 Rectangle bounds = getPathBounds(tree, pressedPath);
 
-                if(e.getY() >= (bounds.y + bounds.height)) {
+                if (bounds == null || e.getY() >= (bounds.y + bounds.height)) {
                     return;
                 }
 
@@ -3832,6 +3841,10 @@
 
                     // And repaint
                     Rectangle newMinBounds = getPathBounds(tree, minPath);
+                    if (minBounds == null || newMinBounds == null) {
+                        return;
+                    }
+
                     if (indices.length == 1 &&
                             newMinBounds.height == minBounds.height) {
                         tree.repaint(0, minBounds.y, tree.getWidth(),
@@ -4466,27 +4479,28 @@
                     }
                 }
                 Rectangle            newRect = ui.getPathBounds(tree, newPath);
+                if (newRect != null) {
+                    newRect.x = visRect.x;
+                    newRect.width = visRect.width;
+                    if(direction == -1) {
+                        newRect.height = visRect.height;
+                    }
+                    else {
+                        newRect.y -= (visRect.height - newRect.height);
+                        newRect.height = visRect.height;
+                    }
 
-                newRect.x = visRect.x;
-                newRect.width = visRect.width;
-                if(direction == -1) {
-                    newRect.height = visRect.height;
+                    if(addToSelection) {
+                        ui.extendSelection(newPath);
+                    }
+                    else if(changeSelection) {
+                        tree.setSelectionPath(newPath);
+                    }
+                    else {
+                        ui.setLeadSelectionPath(newPath, true);
+                    }
+                    tree.scrollRectToVisible(newRect);
                 }
-                else {
-                    newRect.y -= (visRect.height - newRect.height);
-                    newRect.height = visRect.height;
-                }
-
-                if(addToSelection) {
-                    ui.extendSelection(newPath);
-                }
-                else if(changeSelection) {
-                    tree.setSelectionPath(newPath);
-                }
-                else {
-                    ui.setLeadSelectionPath(newPath, true);
-                }
-                tree.scrollRectToVisible(newRect);
             }
         }
 
diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java
index b3d3847..27c5195 100644
--- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java
+++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java
@@ -461,16 +461,16 @@
 
         Locale l = fc.getLocale();
 
-        lookInLabelMnemonic = UIManager.getInt("FileChooser.lookInLabelMnemonic");
+        lookInLabelMnemonic = getMnemonic("FileChooser.lookInLabelMnemonic", l);
         lookInLabelText = UIManager.getString("FileChooser.lookInLabelText",l);
         saveInLabelText = UIManager.getString("FileChooser.saveInLabelText",l);
 
-        fileNameLabelMnemonic = UIManager.getInt("FileChooser.fileNameLabelMnemonic");
+        fileNameLabelMnemonic = getMnemonic("FileChooser.fileNameLabelMnemonic", l);
         fileNameLabelText = UIManager.getString("FileChooser.fileNameLabelText",l);
-        folderNameLabelMnemonic = UIManager.getInt("FileChooser.folderNameLabelMnemonic");
+        folderNameLabelMnemonic = getMnemonic("FileChooser.folderNameLabelMnemonic", l);
         folderNameLabelText = UIManager.getString("FileChooser.folderNameLabelText",l);
 
-        filesOfTypeLabelMnemonic = UIManager.getInt("FileChooser.filesOfTypeLabelMnemonic");
+        filesOfTypeLabelMnemonic = getMnemonic("FileChooser.filesOfTypeLabelMnemonic", l);
         filesOfTypeLabelText = UIManager.getString("FileChooser.filesOfTypeLabelText",l);
 
         upFolderToolTipText =  UIManager.getString("FileChooser.upFolderToolTipText",l);
@@ -489,6 +489,10 @@
         detailsViewButtonAccessibleName = UIManager.getString("FileChooser.detailsViewButtonAccessibleName",l);
     }
 
+    private Integer getMnemonic(String key, Locale l) {
+        return SwingUtilities2.getUIDefaultsInt(key, l);
+    }
+
     protected void installListeners(JFileChooser fc) {
         super.installListeners(fc);
         ActionMap actionMap = getActionMap();
diff --git a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java
index 0667541..90a4df1 100644
--- a/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java
+++ b/jdk/src/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java
@@ -844,9 +844,6 @@
             "FileChooser.newFolderIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getFileChooserNewFolderIcon"),
             "FileChooser.upFolderIcon", new SwingLazyValue("javax.swing.plaf.metal.MetalIconFactory", "getFileChooserUpFolderIcon"),
 
-            "FileChooser.lookInLabelMnemonic", new Integer(KeyEvent.VK_I),
-            "FileChooser.fileNameLabelMnemonic", new Integer(KeyEvent.VK_N),
-            "FileChooser.filesOfTypeLabelMnemonic", new Integer(KeyEvent.VK_T),
             "FileChooser.usesSingleFilePane", Boolean.TRUE,
             "FileChooser.ancestorInputMap",
                new UIDefaults.LazyInputMap(new Object[] {
diff --git a/jdk/src/share/classes/javax/swing/text/DefaultCaret.java b/jdk/src/share/classes/javax/swing/text/DefaultCaret.java
index 22c5803..eb18d69 100644
--- a/jdk/src/share/classes/javax/swing/text/DefaultCaret.java
+++ b/jdk/src/share/classes/javax/swing/text/DefaultCaret.java
@@ -403,6 +403,10 @@
      * @see MouseListener#mouseClicked
      */
     public void mouseClicked(MouseEvent e) {
+        if (getComponent() == null) {
+            return;
+        }
+
         int nclicks = SwingUtilities2.getAdjustedClickCount(getComponent(), e);
 
         if (! e.isConsumed()) {
@@ -1326,7 +1330,7 @@
         if ( ! SwingUtilities2.canCurrentEventAccessSystemClipboard() ) {
             return;
         }
-        if (this.dot != this.mark && component != null) {
+        if (this.dot != this.mark && component != null && component.hasFocus()) {
             Clipboard clip = getSystemSelection();
             if (clip != null) {
                 String selectedText;
diff --git a/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java b/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java
index eeb8329..bd0cebc 100644
--- a/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java
+++ b/jdk/src/share/classes/javax/swing/text/html/parser/Parser.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -952,7 +952,7 @@
                         ch = readCh();
                         break;
                 }
-                char data[] = {mapNumericReference((char) n)};
+                char data[] = mapNumericReference(n);
                 return data;
             }
             addString('#');
@@ -1021,7 +1021,7 @@
     }
 
     /**
-     * Converts numeric character reference to Unicode character.
+     * Converts numeric character reference to char array.
      *
      * Normally the code in a reference should be always converted
      * to the Unicode character with the same code, but due to
@@ -1030,13 +1030,21 @@
      * to displayable characters with other codes.
      *
      * @param c the code of numeric character reference.
-     * @return the character corresponding to the reference code.
+     * @return a char array corresponding to the reference code.
      */
-    private char mapNumericReference(char c) {
-        if (c < 130 || c > 159) {
-            return c;
+    private char[] mapNumericReference(int c) {
+        char[] data;
+        if (c >= 0xffff) { // outside unicode BMP.
+            try {
+                data = Character.toChars(c);
+            } catch (IllegalArgumentException e) {
+                data = new char[0];
+            }
+        } else {
+            data = new char[1];
+            data[0] = (c < 130 || c > 159) ? (char) c : cp1252Map[c - 130];
         }
-        return cp1252Map[c - 130];
+        return data;
     }
 
     /**
diff --git a/jdk/src/share/classes/sun/awt/HToolkit.java b/jdk/src/share/classes/sun/awt/HToolkit.java
index edadb84..5721767 100644
--- a/jdk/src/share/classes/sun/awt/HToolkit.java
+++ b/jdk/src/share/classes/sun/awt/HToolkit.java
@@ -44,6 +44,14 @@
 public class HToolkit extends SunToolkit
     implements ComponentFactory {
 
+    private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
+        public void setCurrentFocusedWindow(Window win) {}
+        public Window getCurrentFocusedWindow() { return null; }
+        public void setCurrentFocusOwner(Component comp) {}
+        public Component getCurrentFocusOwner() { return null; }
+        public void clearGlobalFocusOwner(Window activeWindow) {}
+    };
+
     public HToolkit() {
     }
 
@@ -152,15 +160,9 @@
         throw new HeadlessException();
     }
 
-    public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+    public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
         // See 6833019.
-        return
-            new KeyboardFocusManagerPeer() {
-                public Window getCurrentFocusedWindow() { return null; }
-                public void setCurrentFocusOwner(Component comp) {}
-                public Component getCurrentFocusOwner() { return null; }
-                public void clearGlobalFocusOwner(Window activeWindow) {}
-            };
+        return kfmPeer;
     }
 
     public TrayIconPeer createTrayIcon(TrayIcon target)
diff --git a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java
index 8dc8a19..6dd4032 100644
--- a/jdk/src/share/classes/sun/awt/HeadlessToolkit.java
+++ b/jdk/src/share/classes/sun/awt/HeadlessToolkit.java
@@ -30,22 +30,25 @@
 import java.awt.dnd.peer.DragSourceContextPeer;
 import java.awt.event.*;
 import java.awt.im.InputMethodHighlight;
-import java.awt.im.spi.InputMethodDescriptor;
 import java.awt.image.*;
 import java.awt.datatransfer.Clipboard;
 import java.awt.peer.*;
 import java.beans.PropertyChangeListener;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
 import java.net.URL;
 import java.util.Map;
 import java.util.Properties;
-import sun.awt.im.InputContext;
-import sun.awt.image.ImageRepresentation;
 
 public class HeadlessToolkit extends Toolkit
     implements ComponentFactory, KeyboardFocusManagerPeerProvider {
 
+    private static final KeyboardFocusManagerPeer kfmPeer = new KeyboardFocusManagerPeer() {
+        public void setCurrentFocusedWindow(Window win) {}
+        public Window getCurrentFocusedWindow() { return null; }
+        public void setCurrentFocusOwner(Component comp) {}
+        public Component getCurrentFocusOwner() { return null; }
+        public void clearGlobalFocusOwner(Window activeWindow) {}
+    };
+
     private Toolkit tk;
     private ComponentFactory componentFactory;
 
@@ -179,15 +182,9 @@
         throw new HeadlessException();
     }
 
-    public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+    public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
         // See 6833019.
-        return
-            new KeyboardFocusManagerPeer() {
-                public Window getCurrentFocusedWindow() { return null; }
-                public void setCurrentFocusOwner(Component comp) {}
-                public Component getCurrentFocusOwner() { return null; }
-                public void clearGlobalFocusOwner(Window activeWindow) {}
-            };
+        return kfmPeer;
     }
 
     public TrayIconPeer createTrayIcon(TrayIcon target)
diff --git a/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java b/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java
index dd9ae67..647663c 100644
--- a/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java
+++ b/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java
@@ -53,12 +53,6 @@
     public static final int SNFH_SUCCESS_HANDLED = 1;
     public static final int SNFH_SUCCESS_PROCEED = 2;
 
-    protected KeyboardFocusManager manager;
-
-    public KeyboardFocusManagerPeerImpl(KeyboardFocusManager manager) {
-        this.manager = manager;
-    }
-
     @Override
     public void clearGlobalFocusOwner(Window activeWindow) {
         if (activeWindow != null) {
diff --git a/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerProvider.java b/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerProvider.java
index 3548eaf..9d4ac6d 100644
--- a/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerProvider.java
+++ b/jdk/src/share/classes/sun/awt/KeyboardFocusManagerPeerProvider.java
@@ -25,20 +25,19 @@
 
 package sun.awt;
 
-import java.awt.KeyboardFocusManager;
 import java.awt.peer.KeyboardFocusManagerPeer;
 
 /**
  * {@link KeyboardFocusManagerPeerProvider} is required to be implemented by
  * the currently used {@link java.awt.Toolkit} instance. In order to initialize
- * {@link java.awt.KeyboardFocusManager}, an instance of {@link KeyboardFocusManagerPeer}
- * is needed. To create that instance, the {@link #createKeyboardFocusManagerPeer}
+ * {@link java.awt.KeyboardFocusManager}, a singleton instance of {@link KeyboardFocusManagerPeer}
+ * is needed. To obtain that instance, the {@link #getKeyboardFocusManagerPeer}
  * method of the current toolkit is called.
  */
 public interface KeyboardFocusManagerPeerProvider {
 
     /**
-     * Creates a KeyboardFocusManagerPeer for the specified KeyboardFocusManager.
+     * Gets a singleton KeyboardFocusManagerPeer instance.
      */
-    KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager);
+    KeyboardFocusManagerPeer getKeyboardFocusManagerPeer();
 }
diff --git a/jdk/src/share/classes/sun/awt/SunToolkit.java b/jdk/src/share/classes/sun/awt/SunToolkit.java
index 9000995..eb52eb9 100644
--- a/jdk/src/share/classes/sun/awt/SunToolkit.java
+++ b/jdk/src/share/classes/sun/awt/SunToolkit.java
@@ -196,7 +196,7 @@
     public abstract RobotPeer createRobot(Robot target, GraphicsDevice screen)
         throws AWTException;
 
-    public abstract KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+    public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
         throws HeadlessException;
 
     /**
@@ -1912,6 +1912,13 @@
     }
 
     /**
+     * Returns true if swing backbuffer should be translucent.
+     */
+    public boolean isSwingBackbufferTranslucencySupported() {
+        return false;
+    }
+
+    /**
      * Returns whether or not a containing top level window for the passed
      * component is
      * {@link GraphicsDevice.WindowTranslucency#PERPIXEL_TRANSLUCENT PERPIXEL_TRANSLUCENT}.
diff --git a/jdk/src/share/classes/sun/awt/im/InputContext.java b/jdk/src/share/classes/sun/awt/im/InputContext.java
index 226b7f9..c1332eb 100644
--- a/jdk/src/share/classes/sun/awt/im/InputContext.java
+++ b/jdk/src/share/classes/sun/awt/im/InputContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -785,7 +785,7 @@
     public void disableNativeIM() {
         InputMethod inputMethod = getInputMethod();
         if (inputMethod != null && inputMethod instanceof InputMethodAdapter) {
-            ((InputMethodAdapter)inputMethod).disableInputMethod();
+            ((InputMethodAdapter)inputMethod).stopListening();
         }
     }
 
diff --git a/jdk/src/share/classes/sun/awt/im/InputMethodAdapter.java b/jdk/src/share/classes/sun/awt/im/InputMethodAdapter.java
index 0b5b028..dfc3179 100644
--- a/jdk/src/share/classes/sun/awt/im/InputMethodAdapter.java
+++ b/jdk/src/share/classes/sun/awt/im/InputMethodAdapter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -79,7 +79,6 @@
 
     /**
      * Informs the input method adapter not to listen to the native events.
-     * This method is called when a Java input method is active.
      */
     protected void stopListening() {
         // ignore - adapters can override if needed
diff --git a/jdk/src/share/classes/sun/awt/image/VolatileSurfaceManager.java b/jdk/src/share/classes/sun/awt/image/VolatileSurfaceManager.java
index 95dc697..aa43f19 100644
--- a/jdk/src/share/classes/sun/awt/image/VolatileSurfaceManager.java
+++ b/jdk/src/share/classes/sun/awt/image/VolatileSurfaceManager.java
@@ -333,11 +333,12 @@
             // using a SurfaceData that was created in a different
             // display mode.
             sdBackup = null;
-            sdCurrent = getBackupSurface();
             // Now, invalidate the old hardware-based SurfaceData
+            // Note that getBackupSurface may set sdAccel to null so we have to invalidate it before
             SurfaceData oldData = sdAccel;
             sdAccel = null;
             oldData.invalidate();
+            sdCurrent = getBackupSurface();
         }
         // Update graphicsConfig for the vImg in case it changed due to
         // this display change event
diff --git a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java
index 9179785..0f5521f 100644
--- a/jdk/src/share/classes/sun/invoke/util/ValueConversions.java
+++ b/jdk/src/share/classes/sun/invoke/util/ValueConversions.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -44,6 +44,7 @@
     static {
         final Object[] values = { 255 };
         AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                @Override
                 public Void run() {
                     values[0] = Integer.getInteger(THIS_CLASS.getName()+".MAX_ARITY", 255);
                     return null;
@@ -55,9 +56,9 @@
     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
 
     private static EnumMap<Wrapper, MethodHandle>[] newWrapperCaches(int n) {
-        @SuppressWarnings("unchecked")
+        @SuppressWarnings("unchecked")  // generic array creation
         EnumMap<Wrapper, MethodHandle>[] caches
-                = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap[n];  // unchecked warning expected here
+                = (EnumMap<Wrapper, MethodHandle>[]) new EnumMap<?,?>[n];
         for (int i = 0; i < n; i++)
             caches[i] = new EnumMap<>(Wrapper.class);
         return caches;
@@ -118,42 +119,15 @@
         return primitiveConversion(Wrapper.DOUBLE, x, cast).doubleValue();
     }
 
-    /// Converting references to "raw" values.
-    /// A raw primitive value is always an int or long.
-
-    static int unboxByteRaw(Object x, boolean cast) {
-        return unboxByte(x, cast);
-    }
-
-    static int unboxShortRaw(Object x, boolean cast) {
-        return unboxShort(x, cast);
-    }
-
-    static int unboxBooleanRaw(Object x, boolean cast) {
-        return unboxBoolean(x, cast) ? 1 : 0;
-    }
-
-    static int unboxCharacterRaw(Object x, boolean cast) {
-        return unboxCharacter(x, cast);
-    }
-
-    static int unboxFloatRaw(Object x, boolean cast) {
-        return Float.floatToIntBits(unboxFloat(x, cast));
-    }
-
-    static long unboxDoubleRaw(Object x, boolean cast) {
-        return Double.doubleToRawLongBits(unboxDouble(x, cast));
-    }
-
-    private static MethodType unboxType(Wrapper wrap, boolean raw) {
-        return MethodType.methodType(rawWrapper(wrap, raw).primitiveType(), Object.class, boolean.class);
+    private static MethodType unboxType(Wrapper wrap) {
+        return MethodType.methodType(wrap.primitiveType(), Object.class, boolean.class);
     }
 
     private static final EnumMap<Wrapper, MethodHandle>[]
-            UNBOX_CONVERSIONS = newWrapperCaches(4);
+            UNBOX_CONVERSIONS = newWrapperCaches(2);
 
-    private static MethodHandle unbox(Wrapper wrap, boolean raw, boolean cast) {
-        EnumMap<Wrapper, MethodHandle> cache = UNBOX_CONVERSIONS[(cast?1:0)+(raw?2:0)];
+    private static MethodHandle unbox(Wrapper wrap, boolean cast) {
+        EnumMap<Wrapper, MethodHandle> cache = UNBOX_CONVERSIONS[(cast?1:0)];
         MethodHandle mh = cache.get(wrap);
         if (mh != null) {
             return mh;
@@ -163,19 +137,15 @@
             case OBJECT:
                 mh = IDENTITY; break;
             case VOID:
-                mh = raw ? ALWAYS_ZERO : IGNORE; break;
-            case INT: case LONG:
-                // these guys don't need separate raw channels
-                if (raw)  mh = unbox(wrap, false, cast);
-                break;
+                mh = IGNORE; break;
         }
         if (mh != null) {
             cache.put(wrap, mh);
             return mh;
         }
         // look up the method
-        String name = "unbox" + wrap.simpleName() + (raw ? "Raw" : "");
-        MethodType type = unboxType(wrap, raw);
+        String name = "unbox" + wrap.wrapperSimpleName();
+        MethodType type = unboxType(wrap);
         try {
             mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
         } catch (ReflectiveOperationException ex) {
@@ -187,35 +157,33 @@
             return mh;
         }
         throw new IllegalArgumentException("cannot find unbox adapter for " + wrap
-                + (cast ? " (cast)" : "") + (raw ? " (raw)" : ""));
+                + (cast ? " (cast)" : ""));
     }
 
     public static MethodHandle unboxCast(Wrapper type) {
-        return unbox(type, false, true);
-    }
-
-    public static MethodHandle unboxRaw(Wrapper type) {
-        return unbox(type, true, false);
+        return unbox(type, true);
     }
 
     public static MethodHandle unbox(Class<?> type) {
-        return unbox(Wrapper.forPrimitiveType(type), false, false);
+        return unbox(Wrapper.forPrimitiveType(type), false);
     }
 
     public static MethodHandle unboxCast(Class<?> type) {
-        return unbox(Wrapper.forPrimitiveType(type), false, true);
-    }
-
-    public static MethodHandle unboxRaw(Class<?> type) {
-        return unbox(Wrapper.forPrimitiveType(type), true, false);
+        return unbox(Wrapper.forPrimitiveType(type), true);
     }
 
     static private final Integer ZERO_INT = 0, ONE_INT = 1;
 
     /// Primitive conversions
+    /**
+     * Produce a Number which represents the given value {@code x}
+     * according to the primitive type of the given wrapper {@code wrap}.
+     * Caller must invoke intValue, byteValue, longValue (etc.) on the result
+     * to retrieve the desired primitive value.
+     */
     public static Number primitiveConversion(Wrapper wrap, Object x, boolean cast) {
         // Maybe merge this code with Wrapper.convert/cast.
-        Number res = null;
+        Number res;
         if (x == null) {
             if (!cast)  return null;
             return ZERO_INT;
@@ -237,6 +205,27 @@
         return res;
     }
 
+    /**
+     * The JVM verifier allows boolean, byte, short, or char to widen to int.
+     * Support exactly this conversion, from a boxed value type Boolean,
+     * Byte, Short, Character, or Integer.
+     */
+    public static int widenSubword(Object x) {
+        if (x instanceof Integer)
+            return (int) x;
+        else if (x instanceof Boolean)
+            return fromBoolean((boolean) x);
+        else if (x instanceof Character)
+            return (char) x;
+        else if (x instanceof Short)
+            return (short) x;
+        else if (x instanceof Byte)
+            return (byte) x;
+        else
+            // Fail with a ClassCastException.
+            return (int) x;
+    }
+
     /// Converting primitives to references
 
     static Integer boxInteger(int x) {
@@ -271,53 +260,17 @@
         return x;
     }
 
-    /// Converting raw primitives to references
-
-    static Byte boxByteRaw(int x) {
-        return boxByte((byte)x);
-    }
-
-    static Short boxShortRaw(int x) {
-        return boxShort((short)x);
-    }
-
-    static Boolean boxBooleanRaw(int x) {
-        return boxBoolean(x != 0);
-    }
-
-    static Character boxCharacterRaw(int x) {
-        return boxCharacter((char)x);
-    }
-
-    static Float boxFloatRaw(int x) {
-        return boxFloat(Float.intBitsToFloat(x));
-    }
-
-    static Double boxDoubleRaw(long x) {
-        return boxDouble(Double.longBitsToDouble(x));
-    }
-
-    // a raw void value is (arbitrarily) a garbage int
-    static Void boxVoidRaw(int x) {
-        return null;
-    }
-
-    private static MethodType boxType(Wrapper wrap, boolean raw) {
+    private static MethodType boxType(Wrapper wrap) {
         // be exact, since return casts are hard to compose
         Class<?> boxType = wrap.wrapperType();
-        return MethodType.methodType(boxType, rawWrapper(wrap, raw).primitiveType());
-    }
-
-    private static Wrapper rawWrapper(Wrapper wrap, boolean raw) {
-        if (raw)  return wrap.isDoubleWord() ? Wrapper.LONG : Wrapper.INT;
-        return wrap;
+        return MethodType.methodType(boxType, wrap.primitiveType());
     }
 
     private static final EnumMap<Wrapper, MethodHandle>[]
-            BOX_CONVERSIONS = newWrapperCaches(4);
+            BOX_CONVERSIONS = newWrapperCaches(2);
 
-    private static MethodHandle box(Wrapper wrap, boolean exact, boolean raw) {
-        EnumMap<Wrapper, MethodHandle> cache = BOX_CONVERSIONS[(exact?1:0)+(raw?2:0)];
+    private static MethodHandle box(Wrapper wrap, boolean exact) {
+        EnumMap<Wrapper, MethodHandle> cache = BOX_CONVERSIONS[(exact?1:0)];
         MethodHandle mh = cache.get(wrap);
         if (mh != null) {
             return mh;
@@ -327,11 +280,7 @@
             case OBJECT:
                 mh = IDENTITY; break;
             case VOID:
-                if (!raw)  mh = ZERO_OBJECT;
-                break;
-            case INT: case LONG:
-                // these guys don't need separate raw channels
-                if (raw)  mh = box(wrap, exact, false);
+                mh = ZERO_OBJECT;
                 break;
         }
         if (mh != null) {
@@ -339,8 +288,8 @@
             return mh;
         }
         // look up the method
-        String name = "box" + wrap.simpleName() + (raw ? "Raw" : "");
-        MethodType type = boxType(wrap, raw);
+        String name = "box" + wrap.wrapperSimpleName();
+        MethodType type = boxType(wrap);
         if (exact) {
             try {
                 mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
@@ -348,171 +297,35 @@
                 mh = null;
             }
         } else {
-            mh = box(wrap, !exact, raw).asType(type.erase());
+            mh = box(wrap, !exact).asType(type.erase());
         }
         if (mh != null) {
             cache.put(wrap, mh);
             return mh;
         }
         throw new IllegalArgumentException("cannot find box adapter for "
-                + wrap + (exact ? " (exact)" : "") + (raw ? " (raw)" : ""));
+                + wrap + (exact ? " (exact)" : ""));
     }
 
     public static MethodHandle box(Class<?> type) {
         boolean exact = false;
         // e.g., boxShort(short)Short if exact,
         // e.g., boxShort(short)Object if !exact
-        return box(Wrapper.forPrimitiveType(type), exact, false);
-    }
-
-    public static MethodHandle boxRaw(Class<?> type) {
-        boolean exact = false;
-        // e.g., boxShortRaw(int)Short if exact
-        // e.g., boxShortRaw(int)Object if !exact
-        return box(Wrapper.forPrimitiveType(type), exact, true);
+        return box(Wrapper.forPrimitiveType(type), exact);
     }
 
     public static MethodHandle box(Wrapper type) {
         boolean exact = false;
-        return box(type, exact, false);
-    }
-
-    public static MethodHandle boxRaw(Wrapper type) {
-        boolean exact = false;
-        return box(type, exact, true);
-    }
-
-    /// Kludges for when raw values get accidentally boxed.
-
-    static int unboxRawInteger(Object x) {
-        if (x instanceof Integer)
-            return (int) x;
-        else
-            return (int) unboxLong(x, false);
-    }
-
-    static Integer reboxRawInteger(Object x) {
-        if (x instanceof Integer)
-            return (Integer) x;
-        else
-            return (int) unboxLong(x, false);
-    }
-
-    static Byte reboxRawByte(Object x) {
-        if (x instanceof Byte)  return (Byte) x;
-        return boxByteRaw(unboxRawInteger(x));
-    }
-
-    static Short reboxRawShort(Object x) {
-        if (x instanceof Short)  return (Short) x;
-        return boxShortRaw(unboxRawInteger(x));
-    }
-
-    static Boolean reboxRawBoolean(Object x) {
-        if (x instanceof Boolean)  return (Boolean) x;
-        return boxBooleanRaw(unboxRawInteger(x));
-    }
-
-    static Character reboxRawCharacter(Object x) {
-        if (x instanceof Character)  return (Character) x;
-        return boxCharacterRaw(unboxRawInteger(x));
-    }
-
-    static Float reboxRawFloat(Object x) {
-        if (x instanceof Float)  return (Float) x;
-        return boxFloatRaw(unboxRawInteger(x));
-    }
-
-    static Long reboxRawLong(Object x) {
-        return (Long) x;  //never a rebox
-    }
-
-    static Double reboxRawDouble(Object x) {
-        if (x instanceof Double)  return (Double) x;
-        return boxDoubleRaw(unboxLong(x, true));
-    }
-
-    private static MethodType reboxType(Wrapper wrap) {
-        Class<?> boxType = wrap.wrapperType();
-        return MethodType.methodType(boxType, Object.class);
-    }
-
-    private static final EnumMap<Wrapper, MethodHandle>[]
-            REBOX_CONVERSIONS = newWrapperCaches(1);
-
-    /**
-     * Because we normalize primitive types to reduce the number of signatures,
-     * primitives are sometimes manipulated under an "erased" type,
-     * either int (for types other than long/double) or long (for all types).
-     * When the erased primitive value is then boxed into an Integer or Long,
-     * the final boxed primitive is sometimes required.  This transformation
-     * is called a "rebox".  It takes an Integer or Long and produces some
-     * other boxed value, typed (inexactly) as an Object
-     */
-    public static MethodHandle rebox(Wrapper wrap) {
-        EnumMap<Wrapper, MethodHandle> cache = REBOX_CONVERSIONS[0];
-        MethodHandle mh = cache.get(wrap);
-        if (mh != null) {
-            return mh;
-        }
-        // slow path
-        switch (wrap) {
-            case OBJECT:
-                mh = IDENTITY; break;
-            case VOID:
-                throw new IllegalArgumentException("cannot rebox a void");
-        }
-        if (mh != null) {
-            cache.put(wrap, mh);
-            return mh;
-        }
-        // look up the method
-        String name = "reboxRaw" + wrap.simpleName();
-        MethodType type = reboxType(wrap);
-        try {
-            mh = IMPL_LOOKUP.findStatic(THIS_CLASS, name, type);
-            mh = mh.asType(IDENTITY.type());
-        } catch (ReflectiveOperationException ex) {
-            mh = null;
-        }
-        if (mh != null) {
-            cache.put(wrap, mh);
-            return mh;
-        }
-        throw new IllegalArgumentException("cannot find rebox adapter for " + wrap);
-    }
-
-    public static MethodHandle rebox(Class<?> type) {
-        return rebox(Wrapper.forPrimitiveType(type));
-    }
-
-    /// Width-changing conversions between int and long.
-
-    static long widenInt(int x) {
-        return (long) x;
-    }
-
-    static Long widenBoxedInt(Integer x) {
-        return (long)(int)x;
-    }
-
-    static int narrowLong(long x) {
-        return (int) x;
-    }
-
-    static Integer narrowBoxedLong(Long x) {
-        return (int)(long) x;
+        return box(type, exact);
     }
 
     /// Constant functions
 
     static void ignore(Object x) {
         // no value to return; this is an unbox of null
-        return;
     }
 
     static void empty() {
-        return;
     }
 
     static Object zeroObject() {
@@ -553,7 +366,7 @@
             case OBJECT:
             case INT: case LONG: case FLOAT: case DOUBLE:
                 try {
-                    mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "zero"+wrap.simpleName(), type);
+                    mh = IMPL_LOOKUP.findStatic(THIS_CLASS, "zero"+wrap.wrapperSimpleName(), type);
                 } catch (ReflectiveOperationException ex) {
                     mh = null;
                 }
@@ -564,12 +377,9 @@
             return mh;
         }
 
-        // use the raw method
-        Wrapper rawWrap = wrap.rawPrimitive();
-        if (mh == null && rawWrap != wrap) {
-            mh = MethodHandles.explicitCastArguments(zeroConstantFunction(rawWrap), type);
-        }
-        if (mh != null) {
+        // use zeroInt and cast the result
+        if (wrap.isSubwordOrInt() && wrap != Wrapper.INT) {
+            mh = MethodHandles.explicitCastArguments(zeroConstantFunction(Wrapper.INT), type);
             cache.put(wrap, mh);
             return mh;
         }
@@ -579,24 +389,6 @@
     /// Converting references to references.
 
     /**
-     * Value-killing function.
-     * @param x an arbitrary reference value
-     * @return a null
-     */
-    static Object alwaysNull(Object x) {
-        return null;
-    }
-
-    /**
-     * Value-killing function.
-     * @param x an arbitrary reference value
-     * @return a zero
-     */
-    static int alwaysZero(Object x) {
-        return 0;
-    }
-
-    /**
      * Identity function.
      * @param x an arbitrary reference value
      * @return the same value x
@@ -605,6 +397,10 @@
         return x;
     }
 
+    static <T> T[] identity(T[] x) {
+        return x;
+    }
+
     /**
      * Identity function on ints.
      * @param x an arbitrary int value
@@ -657,33 +453,33 @@
         return t.cast(x);
     }
 
-    private static final MethodHandle IDENTITY, IDENTITY_I, IDENTITY_J, CAST_REFERENCE, ALWAYS_NULL, ALWAYS_ZERO, ZERO_OBJECT, IGNORE, EMPTY, NEW_ARRAY;
+    private static final MethodHandle IDENTITY, CAST_REFERENCE, ZERO_OBJECT, IGNORE, EMPTY,
+            ARRAY_IDENTITY, FILL_NEW_TYPED_ARRAY, FILL_NEW_ARRAY;
     static {
         try {
             MethodType idType = MethodType.genericMethodType(1);
             MethodType castType = idType.insertParameterTypes(0, Class.class);
-            MethodType alwaysZeroType = idType.changeReturnType(int.class);
             MethodType ignoreType = idType.changeReturnType(void.class);
             MethodType zeroObjectType = MethodType.genericMethodType(0);
             IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", idType);
-            IDENTITY_I = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(int.class, int.class));
-            IDENTITY_J = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(long.class, long.class));
             //CAST_REFERENCE = IMPL_LOOKUP.findVirtual(Class.class, "cast", idType);
             CAST_REFERENCE = IMPL_LOOKUP.findStatic(THIS_CLASS, "castReference", castType);
-            ALWAYS_NULL = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysNull", idType);
-            ALWAYS_ZERO = IMPL_LOOKUP.findStatic(THIS_CLASS, "alwaysZero", alwaysZeroType);
             ZERO_OBJECT = IMPL_LOOKUP.findStatic(THIS_CLASS, "zeroObject", zeroObjectType);
             IGNORE = IMPL_LOOKUP.findStatic(THIS_CLASS, "ignore", ignoreType);
             EMPTY = IMPL_LOOKUP.findStatic(THIS_CLASS, "empty", ignoreType.dropParameterTypes(0, 1));
-            NEW_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "newArray", MethodType.methodType(Object[].class, int.class));
+            ARRAY_IDENTITY = IMPL_LOOKUP.findStatic(THIS_CLASS, "identity", MethodType.methodType(Object[].class, Object[].class));
+            FILL_NEW_ARRAY = IMPL_LOOKUP
+                    .findStatic(THIS_CLASS, "fillNewArray",
+                          MethodType.methodType(Object[].class, Integer.class, Object[].class));
+            FILL_NEW_TYPED_ARRAY = IMPL_LOOKUP
+                    .findStatic(THIS_CLASS, "fillNewTypedArray",
+                          MethodType.methodType(Object[].class, Object[].class, Integer.class, Object[].class));
         } catch (NoSuchMethodException | IllegalAccessException ex) {
-            Error err = new InternalError("uncaught exception");
-            err.initCause(ex);
-            throw err;
+            throw newInternalError("uncaught exception", ex);
         }
     }
 
-    // Varargs methods need to be in a separately initialized class, to bootstrapping problems.
+    // Varargs methods need to be in a separately initialized class, to avoid bootstrapping problems.
     static class LazyStatics {
         private static final MethodHandle COPY_AS_REFERENCE_ARRAY, COPY_AS_PRIMITIVE_ARRAY, MAKE_LIST;
         static {
@@ -693,42 +489,74 @@
                 COPY_AS_PRIMITIVE_ARRAY = IMPL_LOOKUP.findStatic(THIS_CLASS, "copyAsPrimitiveArray", MethodType.methodType(Object.class, Wrapper.class, Object[].class));
                 MAKE_LIST = IMPL_LOOKUP.findStatic(THIS_CLASS, "makeList", MethodType.methodType(List.class, Object[].class));
             } catch (ReflectiveOperationException ex) {
-                Error err = new InternalError("uncaught exception");
-                err.initCause(ex);
-                throw err;
+                throw newInternalError("uncaught exception", ex);
             }
         }
     }
 
+    static MethodHandle collectArguments(MethodHandle mh, int pos, MethodHandle collector) {
+        // FIXME: API needs public MHs.collectArguments.
+        // Should be:
+        //   return MethodHandles.collectArguments(mh, 0, collector);
+        // The rest of this code is a workaround for not having that API.
+        if (COLLECT_ARGUMENTS != null) {
+            try {
+                return (MethodHandle)
+                    COLLECT_ARGUMENTS.invokeExact(mh, pos, collector);
+            } catch (Throwable ex) {
+                if (ex instanceof RuntimeException)
+                    throw (RuntimeException) ex;
+                if (ex instanceof Error)
+                    throw (Error) ex;
+                throw new Error(ex.getMessage(), ex);
+            }
+        }
+        // Emulate MHs.collectArguments using fold + drop.
+        // This is slightly inefficient.
+        // More seriously, it can put a MH over the 255-argument limit.
+        mh = MethodHandles.dropArguments(mh, 1, collector.type().parameterList());
+        mh = MethodHandles.foldArguments(mh, collector);
+        return mh;
+    }
+    private static final MethodHandle COLLECT_ARGUMENTS;
+    static {
+        MethodHandle mh = null;
+        try {
+            final java.lang.reflect.Method m = MethodHandles.class
+                .getDeclaredMethod("collectArguments",
+                    MethodHandle.class, int.class, MethodHandle.class);
+            AccessController.doPrivileged(new PrivilegedAction<Void>() {
+                    @Override
+                    public Void run() {
+                        m.setAccessible(true);
+                        return null;
+                    }
+                });
+            mh = IMPL_LOOKUP.unreflect(m);
+        } catch (ReflectiveOperationException ex) {
+            throw newInternalError(ex);
+        }
+        COLLECT_ARGUMENTS = mh;
+    }
+
     private static final EnumMap<Wrapper, MethodHandle>[] WRAPPER_CASTS
-            = newWrapperCaches(2);
+            = newWrapperCaches(1);
 
     /** Return a method that casts its sole argument (an Object) to the given type
-     *  and returns it as the given type (if exact is true), or as plain Object (if erase is true).
+     *  and returns it as the given type.
      */
     public static MethodHandle cast(Class<?> type) {
-        boolean exact = false;
         if (type.isPrimitive())  throw new IllegalArgumentException("cannot cast primitive type "+type);
-        MethodHandle mh = null;
+        MethodHandle mh;
         Wrapper wrap = null;
         EnumMap<Wrapper, MethodHandle> cache = null;
         if (Wrapper.isWrapperType(type)) {
             wrap = Wrapper.forWrapperType(type);
-            cache = WRAPPER_CASTS[exact?1:0];
+            cache = WRAPPER_CASTS[0];
             mh = cache.get(wrap);
             if (mh != null)  return mh;
         }
-        if (VerifyType.isNullReferenceConversion(Object.class, type))
-            mh = IDENTITY;
-        else if (VerifyType.isNullType(type))
-            mh = ALWAYS_NULL;
-        else
-            mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
-        if (exact) {
-            MethodType xmt = MethodType.methodType(type, Object.class);
-            mh = MethodHandles.explicitCastArguments(mh, xmt);
-            //mh = AdapterMethodHandle.makeRetypeRaw(IMPL_TOKEN, xmt, mh);
-        }
+        mh = MethodHandles.insertArguments(CAST_REFERENCE, 0, type);
         if (cache != null)
             cache.put(wrap, mh);
         return mh;
@@ -739,8 +567,10 @@
     }
 
     public static MethodHandle identity(Class<?> type) {
-        // This stuff has been moved into MethodHandles:
-        return MethodHandles.identity(type);
+        if (!type.isPrimitive())
+            // Reference identity has been moved into MethodHandles:
+            return MethodHandles.identity(type);
+        return identity(Wrapper.findPrimitiveType(type));
     }
 
     public static MethodHandle identity(Wrapper wrap) {
@@ -773,95 +603,203 @@
         throw new IllegalArgumentException("cannot find identity for " + wrap);
     }
 
-    /// Float/non-float conversions.
+    /// Primitive conversions.
+    // These are supported directly by the JVM, usually by a single instruction.
+    // In the case of narrowing to a subword, there may be a pair of instructions.
+    // In the case of booleans, there may be a helper routine to manage a 1-bit value.
+    // This is the full 8x8 matrix (minus the diagonal).
 
-    static float doubleToFloat(double x) {
+    // narrow double to all other types:
+    static float doubleToFloat(double x) {  // bytecode: d2f
         return (float) x;
     }
-    static double floatToDouble(float x) {
-        return x;
-    }
-
-    // narrow double to integral type
-    static long doubleToLong(double x) {
+    static long doubleToLong(double x) {  // bytecode: d2l
         return (long) x;
     }
-    static int doubleToInt(double x) {
+    static int doubleToInt(double x) {  // bytecode: d2i
         return (int) x;
     }
-    static short doubleToShort(double x) {
+    static short doubleToShort(double x) {  // bytecodes: d2i, i2s
         return (short) x;
     }
-    static char doubleToChar(double x) {
+    static char doubleToChar(double x) {  // bytecodes: d2i, i2c
         return (char) x;
     }
-    static byte doubleToByte(double x) {
+    static byte doubleToByte(double x) {  // bytecodes: d2i, i2b
         return (byte) x;
     }
     static boolean doubleToBoolean(double x) {
         return toBoolean((byte) x);
     }
 
-    // narrow float to integral type
-    static long floatToLong(float x) {
+    // widen float:
+    static double floatToDouble(float x) {  // bytecode: f2d
+        return x;
+    }
+    // narrow float:
+    static long floatToLong(float x) {  // bytecode: f2l
         return (long) x;
     }
-    static int floatToInt(float x) {
+    static int floatToInt(float x) {  // bytecode: f2i
         return (int) x;
     }
-    static short floatToShort(float x) {
+    static short floatToShort(float x) {  // bytecodes: f2i, i2s
         return (short) x;
     }
-    static char floatToChar(float x) {
+    static char floatToChar(float x) {  // bytecodes: f2i, i2c
         return (char) x;
     }
-    static byte floatToByte(float x) {
+    static byte floatToByte(float x) {  // bytecodes: f2i, i2b
         return (byte) x;
     }
     static boolean floatToBoolean(float x) {
         return toBoolean((byte) x);
     }
 
-    // widen integral type to double
-    static double longToDouble(long x) {
+    // widen long:
+    static double longToDouble(long x) {  // bytecode: l2d
         return x;
     }
-    static double intToDouble(int x) {
+    static float longToFloat(long x) {  // bytecode: l2f
         return x;
     }
-    static double shortToDouble(short x) {
-        return x;
+    // narrow long:
+    static int longToInt(long x) {  // bytecode: l2i
+        return (int) x;
     }
-    static double charToDouble(char x) {
-        return x;
+    static short longToShort(long x) {  // bytecodes: f2i, i2s
+        return (short) x;
     }
-    static double byteToDouble(byte x) {
-        return x;
+    static char longToChar(long x) {  // bytecodes: f2i, i2c
+        return (char) x;
     }
-    static double booleanToDouble(boolean x) {
-        return fromBoolean(x);
+    static byte longToByte(long x) {  // bytecodes: f2i, i2b
+        return (byte) x;
+    }
+    static boolean longToBoolean(long x) {
+        return toBoolean((byte) x);
     }
 
-    // widen integral type to float
-    static float longToFloat(long x) {
+    // widen int:
+    static double intToDouble(int x) {  // bytecode: i2d
         return x;
     }
-    static float intToFloat(int x) {
+    static float intToFloat(int x) {  // bytecode: i2f
         return x;
     }
-    static float shortToFloat(short x) {
+    static long intToLong(int x) {  // bytecode: i2l
         return x;
     }
-    static float charToFloat(char x) {
+    // narrow int:
+    static short intToShort(int x) {  // bytecode: i2s
+        return (short) x;
+    }
+    static char intToChar(int x) {  // bytecode: i2c
+        return (char) x;
+    }
+    static byte intToByte(int x) {  // bytecode: i2b
+        return (byte) x;
+    }
+    static boolean intToBoolean(int x) {
+        return toBoolean((byte) x);
+    }
+
+    // widen short:
+    static double shortToDouble(short x) {  // bytecode: i2d (implicit 's2i')
         return x;
     }
-    static float byteToFloat(byte x) {
+    static float shortToFloat(short x) {  // bytecode: i2f (implicit 's2i')
         return x;
     }
+    static long shortToLong(short x) {  // bytecode: i2l (implicit 's2i')
+        return x;
+    }
+    static int shortToInt(short x) {  // (implicit 's2i')
+        return x;
+    }
+    // narrow short:
+    static char shortToChar(short x) {  // bytecode: i2c (implicit 's2i')
+        return (char)x;
+    }
+    static byte shortToByte(short x) {  // bytecode: i2b (implicit 's2i')
+        return (byte)x;
+    }
+    static boolean shortToBoolean(short x) {
+        return toBoolean((byte) x);
+    }
+
+    // widen char:
+    static double charToDouble(char x) {  // bytecode: i2d (implicit 'c2i')
+        return x;
+    }
+    static float charToFloat(char x) {  // bytecode: i2f (implicit 'c2i')
+        return x;
+    }
+    static long charToLong(char x) {  // bytecode: i2l (implicit 'c2i')
+        return x;
+    }
+    static int charToInt(char x) {  // (implicit 'c2i')
+        return x;
+    }
+    // narrow char:
+    static short charToShort(char x) {  // bytecode: i2s (implicit 'c2i')
+        return (short)x;
+    }
+    static byte charToByte(char x) {  // bytecode: i2b (implicit 'c2i')
+        return (byte)x;
+    }
+    static boolean charToBoolean(char x) {
+        return toBoolean((byte) x);
+    }
+
+    // widen byte:
+    static double byteToDouble(byte x) {  // bytecode: i2d (implicit 'b2i')
+        return x;
+    }
+    static float byteToFloat(byte x) {  // bytecode: i2f (implicit 'b2i')
+        return x;
+    }
+    static long byteToLong(byte x) {  // bytecode: i2l (implicit 'b2i')
+        return x;
+    }
+    static int byteToInt(byte x) {  // (implicit 'b2i')
+        return x;
+    }
+    static short byteToShort(byte x) {  // bytecode: i2s (implicit 'b2i')
+        return (short)x;
+    }
+    static char byteToChar(byte x) {  // bytecode: i2b (implicit 'b2i')
+        return (char)x;
+    }
+    // narrow byte to boolean:
+    static boolean byteToBoolean(byte x) {
+        return toBoolean(x);
+    }
+
+    // widen boolean to all types:
+    static double booleanToDouble(boolean x) {
+        return fromBoolean(x);
+    }
     static float booleanToFloat(boolean x) {
         return fromBoolean(x);
     }
+    static long booleanToLong(boolean x) {
+        return fromBoolean(x);
+    }
+    static int booleanToInt(boolean x) {
+        return fromBoolean(x);
+    }
+    static short booleanToShort(boolean x) {
+        return fromBoolean(x);
+    }
+    static char booleanToChar(boolean x) {
+        return (char)fromBoolean(x);
+    }
+    static byte booleanToByte(boolean x) {
+        return fromBoolean(x);
+    }
 
+    // helpers to force boolean into the conversion scheme:
     static boolean toBoolean(byte x) {
         // see javadoc for MethodHandles.explicitCastArguments
         return ((x & 1) != 0);
@@ -872,62 +810,48 @@
     }
 
     private static final EnumMap<Wrapper, MethodHandle>[]
-            CONVERT_FLOAT_FUNCTIONS = newWrapperCaches(4);
+            CONVERT_PRIMITIVE_FUNCTIONS = newWrapperCaches(Wrapper.values().length);
 
-    static MethodHandle convertFloatFunction(Wrapper wrap, boolean toFloat, boolean doubleSize) {
-        EnumMap<Wrapper, MethodHandle> cache = CONVERT_FLOAT_FUNCTIONS[(toFloat?1:0)+(doubleSize?2:0)];
-        MethodHandle mh = cache.get(wrap);
+    public static MethodHandle convertPrimitive(Wrapper wsrc, Wrapper wdst) {
+        EnumMap<Wrapper, MethodHandle> cache = CONVERT_PRIMITIVE_FUNCTIONS[wsrc.ordinal()];
+        MethodHandle mh = cache.get(wdst);
         if (mh != null) {
             return mh;
         }
         // slow path
-        Wrapper fwrap = (doubleSize ? Wrapper.DOUBLE : Wrapper.FLOAT);
-        Class<?> fix = wrap.primitiveType();
-        Class<?> flt = (doubleSize ? double.class : float.class);
-        Class<?> src = toFloat ? fix : flt;
-        Class<?> dst = toFloat ? flt : fix;
-        if (src == dst)  return identity(wrap);
-        MethodType type = MethodType.methodType(dst, src);
-        switch (wrap) {
-            case VOID:
-                mh = toFloat ? zeroConstantFunction(fwrap) : MethodHandles.dropArguments(EMPTY, 0, flt);
-                break;
-            case OBJECT:
-                mh = toFloat ? unbox(flt) : box(flt);
-                break;
-            default:
-                try {
-                    mh = IMPL_LOOKUP.findStatic(THIS_CLASS, src.getSimpleName()+"To"+capitalize(dst.getSimpleName()), type);
-                } catch (ReflectiveOperationException ex) {
-                    mh = null;
-                }
-                break;
+        Class<?> src = wsrc.primitiveType();
+        Class<?> dst = wdst.primitiveType();
+        MethodType type = src == void.class ? MethodType.methodType(dst) : MethodType.methodType(dst, src);
+        if (wsrc == wdst) {
+            mh = identity(src);
+        } else if (wsrc == Wrapper.VOID) {
+            mh = zeroConstantFunction(wdst);
+        } else if (wdst == Wrapper.VOID) {
+            mh = MethodHandles.dropArguments(EMPTY, 0, src);  // Defer back to MethodHandles.
+        } else if (wsrc == Wrapper.OBJECT) {
+            mh = unboxCast(dst);
+        } else if (wdst == Wrapper.OBJECT) {
+            mh = box(src);
+        } else {
+            assert(src.isPrimitive() && dst.isPrimitive());
+            try {
+                mh = IMPL_LOOKUP.findStatic(THIS_CLASS, src.getSimpleName()+"To"+capitalize(dst.getSimpleName()), type);
+            } catch (ReflectiveOperationException ex) {
+                mh = null;
+            }
         }
         if (mh != null) {
             assert(mh.type() == type) : mh;
-            cache.put(wrap, mh);
+            cache.put(wdst, mh);
             return mh;
         }
 
-        throw new IllegalArgumentException("cannot find float conversion constant for " +
+        throw new IllegalArgumentException("cannot find primitive conversion function for " +
                                            src.getSimpleName()+" -> "+dst.getSimpleName());
     }
 
-    public static MethodHandle convertFromFloat(Class<?> fixType) {
-        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
-        return convertFloatFunction(wrap, false, false);
-    }
-    public static MethodHandle convertFromDouble(Class<?> fixType) {
-        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
-        return convertFloatFunction(wrap, false, true);
-    }
-    public static MethodHandle convertToFloat(Class<?> fixType) {
-        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
-        return convertFloatFunction(wrap, true, false);
-    }
-    public static MethodHandle convertToDouble(Class<?> fixType) {
-        Wrapper wrap = Wrapper.forPrimitiveType(fixType);
-        return convertFloatFunction(wrap, true, true);
+    public static MethodHandle convertPrimitive(Class<?> src, Class<?> dst) {
+        return convertPrimitive(Wrapper.forPrimitiveType(src), Wrapper.forPrimitiveType(dst));
     }
 
     private static String capitalize(String x) {
@@ -1020,37 +944,47 @@
     }
     private static final MethodHandle[] ARRAYS = makeArrays();
 
-    // mh-fill versions of the above:
-    private static Object[] newArray(int len) { return new Object[len]; }
+    // filling versions of the above:
+    // using Integer len instead of int len and no varargs to avoid bootstrapping problems
+    private static Object[] fillNewArray(Integer len, Object[] /*not ...*/ args) {
+        Object[] a = new Object[len];
+        fillWithArguments(a, 0, args);
+        return a;
+    }
+    private static Object[] fillNewTypedArray(Object[] example, Integer len, Object[] /*not ...*/ args) {
+        Object[] a = Arrays.copyOf(example, len);
+        fillWithArguments(a, 0, args);
+        return a;
+    }
     private static void fillWithArguments(Object[] a, int pos, Object... args) {
         System.arraycopy(args, 0, a, pos, args.length);
     }
     // using Integer pos instead of int pos to avoid bootstrapping problems
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0)
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0)
                 { fillWithArguments(a, pos, a0); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1)
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1)
                 { fillWithArguments(a, pos, a0, a1); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2)
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2)
                 { fillWithArguments(a, pos, a0, a1, a2); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3)
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3)
                 { fillWithArguments(a, pos, a0, a1, a2, a3); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
                                   Object a4)
                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
                                   Object a4, Object a5)
                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
                                   Object a4, Object a5, Object a6)
                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
                                   Object a4, Object a5, Object a6, Object a7)
                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
                                   Object a4, Object a5, Object a6, Object a7,
                                   Object a8)
                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8); return a; }
-    private static Object[] fillArray(Object[] a, Integer pos, Object a0, Object a1, Object a2, Object a3,
+    private static Object[] fillArray(Integer pos, Object[] a, Object a0, Object a1, Object a2, Object a3,
                                   Object a4, Object a5, Object a6, Object a7,
                                   Object a8, Object a9)
                 { fillWithArguments(a, pos, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); return a; }
@@ -1058,7 +992,7 @@
         ArrayList<MethodHandle> mhs = new ArrayList<>();
         mhs.add(null);  // there is no empty fill; at least a0 is required
         for (;;) {
-            MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Object[].class, Integer.class);
+            MethodHandle mh = findCollector("fillArray", mhs.size(), Object[].class, Integer.class, Object[].class);
             if (mh == null)  break;
             mhs.add(mh);
         }
@@ -1084,69 +1018,95 @@
         if (mh != null)  return mh;
         mh = findCollector("array", nargs, Object[].class);
         if (mh != null)  return ARRAYS[nargs] = mh;
-        MethodHandle producer = filler(0);  // identity function produces result
-        return ARRAYS[nargs] = buildVarargsArray(producer, nargs);
+        mh = buildVarargsArray(FILL_NEW_ARRAY, ARRAY_IDENTITY, nargs);
+        assert(assertCorrectArity(mh, nargs));
+        return ARRAYS[nargs] = mh;
     }
 
-    private static MethodHandle buildVarargsArray(MethodHandle producer, int nargs) {
+    private static boolean assertCorrectArity(MethodHandle mh, int arity) {
+        assert(mh.type().parameterCount() == arity) : "arity != "+arity+": "+mh;
+        return true;
+    }
+
+    private static MethodHandle buildVarargsArray(MethodHandle newArray, MethodHandle finisher, int nargs) {
         // Build up the result mh as a sequence of fills like this:
-        //   producer(fill(fill(fill(newArray(23),0,x1..x10),10,x11..x20),20,x21..x23))
+        //   finisher(fill(fill(newArrayWA(23,x1..x10),10,x11..x20),20,x21..x23))
         // The various fill(_,10*I,___*[J]) are reusable.
-        MethodHandle filler = filler(nargs);
-        MethodHandle mh = producer;
-        mh = MethodHandles.dropArguments(mh, 1, filler.type().parameterList());
-        mh = MethodHandles.foldArguments(mh, filler);
-        mh = MethodHandles.foldArguments(mh, buildNewArray(nargs));
+        int leftLen = Math.min(nargs, LEFT_ARGS);  // absorb some arguments immediately
+        int rightLen = nargs - leftLen;
+        MethodHandle leftCollector = newArray.bindTo(nargs);
+        leftCollector = leftCollector.asCollector(Object[].class, leftLen);
+        MethodHandle mh = finisher;
+        if (rightLen > 0) {
+            MethodHandle rightFiller = fillToRight(LEFT_ARGS + rightLen);
+            if (mh == ARRAY_IDENTITY)
+                mh = rightFiller;
+            else
+                mh = collectArguments(mh, 0, rightFiller);
+        }
+        if (mh == ARRAY_IDENTITY)
+            mh = leftCollector;
+        else
+            mh = collectArguments(mh, 0, leftCollector);
         return mh;
     }
 
-    private static MethodHandle buildNewArray(int nargs) {
-        return MethodHandles.insertArguments(NEW_ARRAY, 0, (int) nargs);
-    }
-
-    private static final MethodHandle[] FILLERS = new MethodHandle[MAX_ARITY+1];
-    // filler(N).invoke(a, arg0..arg[N-1]) fills a[0]..a[N-1]
-    private static MethodHandle filler(int nargs) {
-        MethodHandle filler = FILLERS[nargs];
+    private static final int LEFT_ARGS = (FILL_ARRAYS.length - 1);
+    private static final MethodHandle[] FILL_ARRAY_TO_RIGHT = new MethodHandle[MAX_ARITY+1];
+    /** fill_array_to_right(N).invoke(a, argL..arg[N-1])
+     *  fills a[L]..a[N-1] with corresponding arguments,
+     *  and then returns a.  The value L is a global constant (LEFT_ARGS).
+     */
+    private static MethodHandle fillToRight(int nargs) {
+        MethodHandle filler = FILL_ARRAY_TO_RIGHT[nargs];
         if (filler != null)  return filler;
-        return FILLERS[nargs] = buildFiller(nargs);
+        filler = buildFiller(nargs);
+        assert(assertCorrectArity(filler, nargs - LEFT_ARGS + 1));
+        return FILL_ARRAY_TO_RIGHT[nargs] = filler;
     }
     private static MethodHandle buildFiller(int nargs) {
-        if (nargs == 0)
-            return MethodHandles.identity(Object[].class);
-        final int CHUNK = (FILL_ARRAYS.length - 1);
+        if (nargs <= LEFT_ARGS)
+            return ARRAY_IDENTITY;  // no args to fill; return the array unchanged
+        // we need room for both mh and a in mh.invoke(a, arg*[nargs])
+        final int CHUNK = LEFT_ARGS;
         int rightLen = nargs % CHUNK;
-        int leftLen = nargs - rightLen;
+        int midLen = nargs - rightLen;
         if (rightLen == 0) {
-            leftLen = nargs - (rightLen = CHUNK);
-            if (FILLERS[leftLen] == null) {
+            midLen = nargs - (rightLen = CHUNK);
+            if (FILL_ARRAY_TO_RIGHT[midLen] == null) {
                 // build some precursors from left to right
-                for (int j = 0; j < leftLen; j += CHUNK)  filler(j);
+                for (int j = LEFT_ARGS % CHUNK; j < midLen; j += CHUNK)
+                    if (j > LEFT_ARGS)  fillToRight(j);
             }
         }
-        MethodHandle leftFill = filler(leftLen);  // recursive fill
-        MethodHandle rightFill = FILL_ARRAYS[rightLen];
-        rightFill = MethodHandles.insertArguments(rightFill, 1, (int) leftLen);  // [leftLen..nargs-1]
+        if (midLen < LEFT_ARGS) rightLen = nargs - (midLen = LEFT_ARGS);
+        assert(rightLen > 0);
+        MethodHandle midFill = fillToRight(midLen);  // recursive fill
+        MethodHandle rightFill = FILL_ARRAYS[rightLen].bindTo(midLen);  // [midLen..nargs-1]
+        assert(midFill.type().parameterCount()   == 1 + midLen - LEFT_ARGS);
+        assert(rightFill.type().parameterCount() == 1 + rightLen);
 
-        // Combine the two fills: right(left(newArray(nargs), x1..x20), x21..x23)
-        MethodHandle mh = filler(0);  // identity function produces result
-        mh = MethodHandles.dropArguments(mh, 1, rightFill.type().parameterList());
-        mh = MethodHandles.foldArguments(mh, rightFill);
-        if (leftLen > 0) {
-            mh = MethodHandles.dropArguments(mh, 1, leftFill.type().parameterList());
-            mh = MethodHandles.foldArguments(mh, leftFill);
-        }
-        return mh;
+        // Combine the two fills:
+        //   right(mid(a, x10..x19), x20..x23)
+        // The final product will look like this:
+        //   right(mid(newArrayLeft(24, x0..x9), x10..x19), x20..x23)
+        if (midLen == LEFT_ARGS)
+            return rightFill;
+        else
+            return collectArguments(rightFill, 0, midFill);
     }
 
     // Type-polymorphic version of varargs maker.
     private static final ClassValue<MethodHandle[]> TYPED_COLLECTORS
         = new ClassValue<MethodHandle[]>() {
+            @Override
             protected MethodHandle[] computeValue(Class<?> type) {
                 return new MethodHandle[256];
             }
     };
 
+    static final int MAX_JVM_ARITY = 255;  // limit imposed by the JVM
+
     /** Return a method handle that takes the indicated number of
      *  typed arguments and returns an array of them.
      *  The type argument is the array type.
@@ -1155,16 +1115,36 @@
         Class<?> elemType = arrayType.getComponentType();
         if (elemType == null)  throw new IllegalArgumentException("not an array: "+arrayType);
         // FIXME: Need more special casing and caching here.
+        if (nargs >= MAX_JVM_ARITY/2 - 1) {
+            int slots = nargs;
+            final int MAX_ARRAY_SLOTS = MAX_JVM_ARITY - 1;  // 1 for receiver MH
+            if (arrayType == double[].class || arrayType == long[].class)
+                slots *= 2;
+            if (slots > MAX_ARRAY_SLOTS)
+                throw new IllegalArgumentException("too many arguments: "+arrayType.getSimpleName()+", length "+nargs);
+        }
         if (elemType == Object.class)
             return varargsArray(nargs);
         // other cases:  primitive arrays, subtypes of Object[]
         MethodHandle cache[] = TYPED_COLLECTORS.get(elemType);
         MethodHandle mh = nargs < cache.length ? cache[nargs] : null;
         if (mh != null)  return mh;
-        MethodHandle producer = buildArrayProducer(arrayType);
-        mh = buildVarargsArray(producer, nargs);
+        if (elemType.isPrimitive()) {
+            MethodHandle builder = FILL_NEW_ARRAY;
+            MethodHandle producer = buildArrayProducer(arrayType);
+            mh = buildVarargsArray(builder, producer, nargs);
+        } else {
+            @SuppressWarnings("unchecked")
+            Class<? extends Object[]> objArrayType = (Class<? extends Object[]>) arrayType;
+            Object[] example = Arrays.copyOf(NO_ARGS_ARRAY, 0, objArrayType);
+            MethodHandle builder = FILL_NEW_TYPED_ARRAY.bindTo(example);
+            MethodHandle producer = ARRAY_IDENTITY;
+            mh = buildVarargsArray(builder, producer, nargs);
+        }
         mh = mh.asType(MethodType.methodType(arrayType, Collections.<Class<?>>nCopies(nargs, elemType)));
-        cache[nargs] = mh;
+        assert(assertCorrectArity(mh, nargs));
+        if (nargs < cache.length)
+            cache[nargs] = mh;
         return mh;
     }
 
@@ -1234,4 +1214,16 @@
     private static MethodHandle buildVarargsList(int nargs) {
         return MethodHandles.filterReturnValue(varargsArray(nargs), LazyStatics.MAKE_LIST);
     }
+
+    // handy shared exception makers (they simplify the common case code)
+    private static InternalError newInternalError(String message, Throwable cause) {
+        InternalError e = new InternalError(message);
+        e.initCause(cause);
+        return e;
+    }
+    private static InternalError newInternalError(Throwable cause) {
+        InternalError e = new InternalError();
+        e.initCause(cause);
+        return e;
+    }
 }
diff --git a/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java
index bf946a8..28436d7 100644
--- a/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java
+++ b/jdk/src/share/classes/sun/invoke/util/VerifyAccess.java
@@ -169,6 +169,46 @@
     }
 
     /**
+     * Decide if the given method type, attributed to a member or symbolic
+     * reference of a given reference class, is really visible to that class.
+     * @param type the supposed type of a member or symbolic reference of refc
+     * @param refc
+     */
+    public static boolean isTypeVisible(Class<?> type, Class<?> refc) {
+        if (type == refc)  return true;  // easy check
+        while (type.isArray())  type = type.getComponentType();
+        if (type.isPrimitive() || type == Object.class)  return true;
+        ClassLoader parent = type.getClassLoader();
+        if (parent == null)  return true;
+        ClassLoader child  = refc.getClassLoader();
+        if (child == null)  return false;
+        if (parent == child || loadersAreRelated(parent, child, true))
+            return true;
+        // Do it the hard way:  Look up the type name from the refc loader.
+        try {
+            Class<?> res = child.loadClass(type.getName());
+            return (type == res);
+        } catch (ClassNotFoundException ex) {
+            return false;
+        }
+    }
+
+    /**
+     * Decide if the given method type, attributed to a member or symbolic
+     * reference of a given reference class, is really visible to that class.
+     * @param type the supposed type of a member or symbolic reference of refc
+     * @param refc
+     */
+    public static boolean isTypeVisible(java.lang.invoke.MethodType type, Class<?> refc) {
+        for (int n = -1, max = type.parameterCount(); n < max; n++) {
+            Class<?> ptype = (n < 0 ? type.returnType() : type.parameterType(n));
+            if (!isTypeVisible(ptype, refc))
+                return false;
+        }
+        return true;
+    }
+
+    /**
      * Test if two classes have the same class loader and package qualifier.
      * @param class1
      * @param class2
diff --git a/jdk/src/share/classes/sun/invoke/util/VerifyType.java b/jdk/src/share/classes/sun/invoke/util/VerifyType.java
index 2970135..8f9f6a3 100644
--- a/jdk/src/share/classes/sun/invoke/util/VerifyType.java
+++ b/jdk/src/share/classes/sun/invoke/util/VerifyType.java
@@ -122,8 +122,6 @@
         return isNullConversion(recv.returnType(), call.returnType());
     }
 
-    //TO DO: isRawConversion
-
     /**
      * Determine if the JVM verifier allows a value of type call to be
      * passed to a formal parameter (or return variable) of type recv.
@@ -188,40 +186,6 @@
         return -1;
     }
 
-    public static int canPassRaw(Class<?> src, Class<?> dst) {
-        if (dst.isPrimitive()) {
-            if (dst == void.class)
-                // As above, return anything to a caller expecting void.
-                return 1;
-            if (src == void.class)
-                // Special permission for raw conversions: allow a void
-                // to be captured as a garbage int.
-                // Caller promises that the actual value will be disregarded.
-                return dst == int.class ? 1 : 0;
-            if (isNullType(src))
-                // Special permission for raw conversions: allow a null
-                // to be reinterpreted as anything.  For objects, it is safe,
-                // and for primitives you get a garbage value (probably zero).
-                return 1;
-            if (!src.isPrimitive())
-                return 0;
-            Wrapper sw = Wrapper.forPrimitiveType(src);
-            Wrapper dw = Wrapper.forPrimitiveType(dst);
-            if (sw.stackSlots() == dw.stackSlots())
-                return 1;  // can do a reinterpret-cast on a stacked primitive
-            if (sw.isSubwordOrInt() && dw == Wrapper.VOID)
-                return 1;  // can drop an outgoing int value
-            return 0;
-        } else if (src.isPrimitive()) {
-            return 0;
-        }
-
-        // Both references.
-        if (isNullReferenceConversion(src, dst))
-            return 1;
-        return -1;
-    }
-
     public static boolean isSpreadArgType(Class<?> spreadArg) {
         return spreadArg.isArray();
     }
diff --git a/jdk/src/share/classes/sun/invoke/util/Wrapper.java b/jdk/src/share/classes/sun/invoke/util/Wrapper.java
index f1344bd..d80d315 100644
--- a/jdk/src/share/classes/sun/invoke/util/Wrapper.java
+++ b/jdk/src/share/classes/sun/invoke/util/Wrapper.java
@@ -31,7 +31,7 @@
     BYTE(Byte.class, byte.class, 'B', (Byte)(byte)0, new byte[0], Format.signed(8)),
     SHORT(Short.class, short.class, 'S', (Short)(short)0, new short[0], Format.signed(16)),
     CHAR(Character.class, char.class, 'C', (Character)(char)0, new char[0], Format.unsigned(16)),
-    INT(Integer.class, int.class, 'I', (Integer)(int)0, new int[0], Format.signed(32)),
+    INT(Integer.class, int.class, 'I', (Integer)/*(int)*/0, new int[0], Format.signed(32)),
     LONG(Long.class, long.class, 'J', (Long)(long)0, new long[0], Format.signed(64)),
     FLOAT(Float.class, float.class, 'F', (Float)(float)0, new float[0], Format.floating(32)),
     DOUBLE(Double.class, double.class, 'D', (Double)(double)0, new double[0], Format.floating(64)),
@@ -47,7 +47,8 @@
     private final Object   zero;
     private final Object   emptyArray;
     private final int      format;
-    private final String   simpleName;
+    private final String   wrapperSimpleName;
+    private final String   primitiveSimpleName;
 
     private Wrapper(Class<?> wtype, Class<?> ptype, char tchar, Object zero, Object emptyArray, int format) {
         this.wrapperType = wtype;
@@ -56,12 +57,13 @@
         this.zero = zero;
         this.emptyArray = emptyArray;
         this.format = format;
-        this.simpleName = wtype.getSimpleName();
+        this.wrapperSimpleName = wtype.getSimpleName();
+        this.primitiveSimpleName = ptype.getSimpleName();
     }
 
     /** For debugging, give the details of this wrapper. */
     public String detailString() {
-        return simpleName+
+        return wrapperSimpleName+
                 java.util.Arrays.asList(wrapperType, primitiveType,
                 basicTypeChar, zero,
                 "0x"+Integer.toHexString(format));
@@ -418,7 +420,11 @@
 
     /** What is the simple name of the wrapper type?
      */
-    public String simpleName() { return simpleName; }
+    public String wrapperSimpleName() { return wrapperSimpleName; }
+
+    /** What is the simple name of the primitive type?
+     */
+    public String primitiveSimpleName() { return primitiveSimpleName; }
 
 //    /** Wrap a value in the given type, which may be either a primitive or wrapper type.
 //     *  Performs standard primitive conversions, including truncation and float conversions.
@@ -456,26 +462,31 @@
             // If the target type is an interface, perform no runtime check.
             // (This loophole is safe, and is allowed by the JVM verifier.)
             // If the target type is a primitive, change it to a wrapper.
+            assert(!type.isPrimitive());
+            if (!type.isInterface())
+                type.cast(x);
             @SuppressWarnings("unchecked")
             T result = (T) x;  // unchecked warning is expected here
             return result;
         }
         Class<T> wtype = wrapperType(type);
         if (wtype.isInstance(x)) {
-            @SuppressWarnings("unchecked")
-            T result = (T) x;  // unchecked warning is expected here
-            return result;
+            return wtype.cast(x);
         }
-        Class<?> sourceType = x.getClass();  // throw NPE if x is null
         if (!isCast) {
+            Class<?> sourceType = x.getClass();  // throw NPE if x is null
             Wrapper source = findWrapperType(sourceType);
             if (source == null || !this.isConvertibleFrom(source)) {
                 throw newClassCastException(wtype, sourceType);
             }
+        } else if (x == null) {
+            @SuppressWarnings("unchecked")
+            T z = (T) zero;
+            return z;
         }
         @SuppressWarnings("unchecked")
         T result = (T) wrap(x);  // unchecked warning is expected here
-        assert result.getClass() == wtype;
+        assert (result == null ? Void.class : result.getClass()) == wtype;
         return result;
     }
 
@@ -523,7 +534,7 @@
             case 'S': return Short.valueOf((short) xn.intValue());
             case 'B': return Byte.valueOf((byte) xn.intValue());
             case 'C': return Character.valueOf((char) xn.intValue());
-            case 'Z': return Boolean.valueOf(boolValue(xn.longValue()));
+            case 'Z': return Boolean.valueOf(boolValue(xn.byteValue()));
         }
         throw new InternalError("bad wrapper");
     }
@@ -539,79 +550,18 @@
         switch (basicTypeChar) {
             case 'L': throw newIllegalArgumentException("cannot wrap to object type");
             case 'V': return null;
-            case 'I': return Integer.valueOf((int)x);
+            case 'I': return Integer.valueOf(x);
             case 'J': return Long.valueOf(x);
             case 'F': return Float.valueOf(x);
             case 'D': return Double.valueOf(x);
             case 'S': return Short.valueOf((short) x);
             case 'B': return Byte.valueOf((byte) x);
             case 'C': return Character.valueOf((char) x);
-            case 'Z': return Boolean.valueOf(boolValue(x));
+            case 'Z': return Boolean.valueOf(boolValue((byte) x));
         }
         throw new InternalError("bad wrapper");
     }
 
-    /** Wrap a value (a long or smaller value) in this wrapper's type.
-     * Does not perform floating point conversion.
-     * Produces a {@code Long} for {@code OBJECT}, although the exact type
-     * of the operand is not known.
-     * Returns null for {@code VOID}.
-     */
-    public Object wrapRaw(long x) {
-        switch (basicTypeChar) {
-            case 'F':  return Float.valueOf(Float.intBitsToFloat((int)x));
-            case 'D':  return Double.valueOf(Double.longBitsToDouble(x));
-            case 'L':  // same as 'J':
-            case 'J':  return (Long) x;
-        }
-        // Other wrapping operations are just the same, given that the
-        // operand is already promoted to an int.
-        return wrap((int)x);
-    }
-
-    /** Produce bitwise value which encodes the given wrapped value.
-     * Does not perform floating point conversion.
-     * Returns zero for {@code VOID}.
-     */
-    public long unwrapRaw(Object x) {
-        switch (basicTypeChar) {
-            case 'F':  return Float.floatToRawIntBits((Float) x);
-            case 'D':  return Double.doubleToRawLongBits((Double) x);
-
-            case 'L': throw newIllegalArgumentException("cannot unwrap from sobject type");
-            case 'V': return 0;
-            case 'I': return (int)(Integer) x;
-            case 'J': return (long)(Long) x;
-            case 'S': return (short)(Short) x;
-            case 'B': return (byte)(Byte) x;
-            case 'C': return (char)(Character) x;
-            case 'Z': return (boolean)(Boolean) x ? 1 : 0;
-        }
-        throw new InternalError("bad wrapper");
-    }
-
-    /** Report what primitive type holds this guy's raw value. */
-    public Class<?> rawPrimitiveType() {
-        return rawPrimitive().primitiveType();
-    }
-
-    /** Report, as a wrapper, what primitive type holds this guy's raw value.
-     *  Returns self for INT, LONG, OBJECT; returns LONG for DOUBLE,
-     *  else returns INT.
-     */
-    public Wrapper rawPrimitive() {
-        switch (basicTypeChar) {
-            case 'S': case 'B':
-            case 'C': case 'Z':
-            case 'V':
-            case 'F':
-                return INT;
-            case 'D':
-                return LONG;
-        }
-        return this;
-    }
-
     private static Number numberValue(Object x) {
         if (x instanceof Number)     return (Number)x;
         if (x instanceof Character)  return (int)(Character)x;
@@ -620,7 +570,10 @@
         return (Number)x;
     }
 
-    private static boolean boolValue(long bits) {
+    // Parameter type of boolValue must be byte, because
+    // MethodHandles.explicitCastArguments defines boolean
+    // conversion as first converting to byte.
+    private static boolean boolValue(byte bits) {
         bits &= 1;  // simple 31-bit zero extension
         return (bits != 0);
     }
diff --git a/jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java b/jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java
index 9e6113e..f6ecd8a 100644
--- a/jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java
+++ b/jdk/src/share/classes/sun/java2d/opengl/OGLBlitLoops.java
@@ -25,6 +25,7 @@
 
 package sun.java2d.opengl;
 
+import java.awt.AlphaComposite;
 import java.awt.Composite;
 import java.awt.Transparency;
 import java.awt.geom.AffineTransform;
@@ -96,6 +97,8 @@
                                CompositeType.AnyAlpha,
                                blitIntArgbPreToSurface),
 
+            new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLSurface),
+
             new OGLSwToSurfaceScale(SurfaceType.IntRgb,
                                     OGLSurfaceData.PF_INT_RGB),
             new OGLSwToSurfaceScale(SurfaceType.IntRgbx,
@@ -172,6 +175,9 @@
             new OGLGeneralBlit(OGLSurfaceData.OpenGLTexture,
                                CompositeType.SrcNoEa,
                                blitIntArgbPreToTexture),
+
+            new OGLAnyCompositeBlit(OGLSurfaceData.OpenGLTexture),
+
         };
         GraphicsPrimitiveMgr.register(primitives);
     }
@@ -760,3 +766,49 @@
         }
     }
 }
+
+class OGLAnyCompositeBlit extends Blit {
+    private WeakReference<SurfaceData> dstTmp;
+
+    public OGLAnyCompositeBlit(SurfaceType dstType) {
+        super(SurfaceType.Any, CompositeType.Any, dstType);
+    }
+    public synchronized void Blit(SurfaceData src, SurfaceData dst,
+                                  Composite comp, Region clip,
+                                  int sx, int sy, int dx, int dy,
+                                  int w, int h)
+    {
+        Blit convertdst = Blit.getFromCache(dst.getSurfaceType(),
+                                            CompositeType.SrcNoEa,
+                                            SurfaceType.IntArgbPre);
+
+        SurfaceData cachedDst = null;
+
+        if (dstTmp != null) {
+            // use cached intermediate surface, if available
+            cachedDst = dstTmp.get();
+        }
+
+        // convert source to IntArgbPre
+        SurfaceData dstBuffer = convertFrom(convertdst, dst, dx, dy, w, h,
+                          cachedDst, BufferedImage.TYPE_INT_ARGB_PRE);
+
+        Blit performop = Blit.getFromCache(src.getSurfaceType(),
+                CompositeType.Any, dstBuffer.getSurfaceType());
+
+        performop.Blit(src, dstBuffer, comp, clip,
+                       sx, sy, 0, 0, w, h);
+
+        if (dstBuffer != cachedDst) {
+            // cache the intermediate surface
+            dstTmp = new WeakReference(dstBuffer);
+        }
+
+        // now blit the buffer back to the destination
+        convertdst = Blit.getFromCache(dstBuffer.getSurfaceType(),
+                                            CompositeType.SrcNoEa,
+                                            dst.getSurfaceType());
+        convertdst.Blit(dstBuffer, dst, AlphaComposite.Src,
+                 clip, 0, 0, dx, dy, w, h);
+    }
+}
diff --git a/jdk/src/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java b/jdk/src/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java
index 755044e..a2dfd5b 100644
--- a/jdk/src/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java
+++ b/jdk/src/share/classes/sun/java2d/opengl/OGLSurfaceDataProxy.java
@@ -76,6 +76,7 @@
                                         CompositeType comp,
                                         Color bgColor)
     {
-        return (bgColor == null || transparency == Transparency.OPAQUE);
+        return comp.isDerivedFrom(CompositeType.AnyAlpha) &&
+               (bgColor == null || transparency == Transparency.OPAQUE);
     }
 }
diff --git a/jdk/src/share/classes/sun/management/Agent.java b/jdk/src/share/classes/sun/management/Agent.java
index 2606de1..8ba53a2 100644
--- a/jdk/src/share/classes/sun/management/Agent.java
+++ b/jdk/src/share/classes/sun/management/Agent.java
@@ -168,7 +168,10 @@
 
         // management properties can be overridden by system properties
         // which take precedence
-        configProps.putAll(System.getProperties());
+        Properties sysProps = System.getProperties();
+        synchronized(sysProps){
+            configProps.putAll(sysProps);
+        }
 
         // if user specifies config file into command line for either
         // jcmd utilities or attach command it overrides properties set in
@@ -264,7 +267,10 @@
 
         // management properties can be overridden by system properties
         // which take precedence
-        props.putAll(System.getProperties());
+        Properties sysProps = System.getProperties();
+        synchronized(sysProps){
+            props.putAll(sysProps);
+        }
 
         return props;
    }
diff --git a/jdk/src/share/classes/sun/misc/IoTrace.java b/jdk/src/share/classes/sun/misc/IoTrace.java
new file mode 100644
index 0000000..980b813
--- /dev/null
+++ b/jdk/src/share/classes/sun/misc/IoTrace.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.misc;
+
+import java.net.InetAddress;
+
+/**
+ * Utility class used to identify trace points for I/O calls.
+ * <p>
+ * To use this class, a diagnostic tool must redefine this class with a version
+ * that contains calls to the the diagnostic tool. This implementation will then
+ * receive callbacks when file and socket operations are performed. The reason
+ * for requiring a redefine of the class is to avoid any overhead caused by the
+ * instrumentation.
+ * <p>
+ * The xxBegin() methods return a "context". This can be any Object. This
+ * context will be passed to the corresponding xxEnd() method. This way, an
+ * implementation can correlate the beginning of an operation with the end.
+ * <p>
+ * It is possible for a xxEnd() method to be called with a null handle. This
+ * happens if tracing was started between the call to xxBegin() and xxEnd(), in
+ * which case xxBegin() would not have been called. It is the implementation's
+ * responsibility to not throw an exception in this case.
+ * <p>
+ * Only blocking I/O operations are identified with this facility.
+ * <p>
+ * <b>Warning</b>
+ * <p>
+ * These methods are called from sensitive points in the I/O subsystem. Great
+ * care must be taken to not interfere with ongoing operations or cause
+ * deadlocks. In particular:
+ * <ul>
+ * <li>Implementations must not throw exceptions since this will cause
+ * disruptions to the I/O operations.
+ * <li>Implementations must not do I/O operations since this will lead to an
+ * endless loop.
+ * <li>Since the hooks may be called while holding low-level locks in the I/O
+ * subsystem, implementations must be careful with synchronization or
+ * interaction with other threads to avoid deadlocks in the VM.
+ * </ul>
+ */
+public final class IoTrace {
+    private IoTrace() {
+    }
+
+    /**
+     * Called before data is read from a socket.
+     *
+     * @param address
+     *            the remote address the socket is bound to
+     * @param port
+     *            the remote port the socket is bound to
+     * @param timeout
+     *            the SO_TIMEOUT value of the socket (in milliseconds) or 0 if
+     *            there is no timeout set
+     * @return a context object
+     */
+    public static Object socketReadBegin(InetAddress address, int port,
+            int timeout) {
+        return null;
+    }
+
+    /**
+     * Called after data is read from the socket.
+     *
+     * @param context
+     *            the context returned by the previous call to socketReadBegin()
+     * @param bytesRead
+     *            the number of bytes read from the socket, 0 if there was an
+     *            error reading from the socket
+     */
+    public static void socketReadEnd(Object context, long bytesRead) {
+    }
+
+    /**
+     * Called before data is written to a socket.
+     *
+     * @param address
+     *            the remote address the socket is bound to
+     * @param port
+     *            the remote port the socket is bound to
+     * @return a context object
+     */
+    public static Object socketWriteBegin(InetAddress address, int port) {
+        return null;
+    }
+
+    /**
+     * Called after data is written to a socket.
+     *
+     * @param context
+     *            the context returned by the previous call to
+     *            socketWriteBegin()
+     * @param bytesWritten
+     *            the number of bytes written to the socket, 0 if there was an
+     *            error writing to the socket
+     */
+    public static void socketWriteEnd(Object context, long bytesWritten) {
+    }
+
+    /**
+     * Called before data is read from a file.
+     *
+     * @param path
+     *            the path of the file
+     * @return a context object
+     */
+    public static Object fileReadBegin(String path) {
+        return null;
+    }
+
+    /**
+     * Called after data is read from a file.
+     *
+     * @param context
+     *            the context returned by the previous call to fileReadBegin()
+     * @param bytesRead
+     *            the number of bytes written to the file, 0 if there was an
+     *            error writing to the file
+     */
+    public static void fileReadEnd(Object context, long bytesRead) {
+    }
+
+    /**
+     * Called before data is written to a file.
+     *
+     * @param path
+     *            the path of the file
+     * @return a context object
+     */
+    public static Object fileWriteBegin(String path) {
+        return null;
+    }
+
+    /**
+     * Called after data is written to a file.
+     *
+     * @param context
+     *            the context returned by the previous call to fileReadBegin()
+     * @param bytesWritten
+     *            the number of bytes written to the file, 0 if there was an
+     *            error writing to the file
+     */
+    public static void fileWriteEnd(Object context, long bytesWritten) {
+    }
+}
diff --git a/jdk/src/share/classes/sun/misc/Unsafe.java b/jdk/src/share/classes/sun/misc/Unsafe.java
index dba1628..fac7c6d 100644
--- a/jdk/src/share/classes/sun/misc/Unsafe.java
+++ b/jdk/src/share/classes/sun/misc/Unsafe.java
@@ -678,6 +678,14 @@
     public native Object staticFieldBase(Field f);
 
     /**
+     * Detect if the given class may need to be initialized. This is often
+     * needed in conjunction with obtaining the static field base of a
+     * class.
+     * @return false only if a call to {@code ensureClassInitialized} would have no effect
+     */
+    public native boolean shouldBeInitialized(Class<?> c);
+
+    /**
      * Ensure the given class has been initialized. This is often
      * needed in conjunction with obtaining the static field base of a
      * class.
diff --git a/jdk/src/share/classes/sun/misc/VM.java b/jdk/src/share/classes/sun/misc/VM.java
index bcec901..e1fb584 100644
--- a/jdk/src/share/classes/sun/misc/VM.java
+++ b/jdk/src/share/classes/sun/misc/VM.java
@@ -371,6 +371,12 @@
     private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010;
     private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020;
 
+    /*
+     * Returns the first non-null class loader up the execution stack,
+     * or null if only code from the null class loader is on the stack.
+     */
+    public static native ClassLoader latestUserDefinedLoader();
+
     static {
         initialize();
     }
diff --git a/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java
index d7aa358..f1a2bf7 100644
--- a/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java
+++ b/jdk/src/share/classes/sun/net/spi/DefaultProxySelector.java
@@ -346,5 +346,5 @@
     }
 
     private native static boolean init();
-    private native Proxy getSystemProxy(String protocol, String host);
+    private synchronized native Proxy getSystemProxy(String protocol, String host);
 }
diff --git a/jdk/src/share/classes/sun/net/www/MessageHeader.java b/jdk/src/share/classes/sun/net/www/MessageHeader.java
index e4eed18..0237a85 100644
--- a/jdk/src/share/classes/sun/net/www/MessageHeader.java
+++ b/jdk/src/share/classes/sun/net/www/MessageHeader.java
@@ -148,7 +148,7 @@
         for (int i=0; i<nkeys; i++) {
             if (k.equalsIgnoreCase(keys[i])
                     && values[i] != null && values[i].length() > 5
-                    && values[i].substring(0, 5).equalsIgnoreCase("NTLM ")) {
+                    && values[i].regionMatches(true, 0, "NTLM ", 0, 5)) {
                 found = true;
                 break;
             }
diff --git a/jdk/src/share/classes/sun/net/www/http/HttpClient.java b/jdk/src/share/classes/sun/net/www/http/HttpClient.java
index 54bf3a1..5f5f9ab 100644
--- a/jdk/src/share/classes/sun/net/www/http/HttpClient.java
+++ b/jdk/src/share/classes/sun/net/www/http/HttpClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2012, 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
@@ -36,6 +36,7 @@
 import sun.net.www.ParseUtil;
 import sun.net.www.protocol.http.HttpURLConnection;
 import sun.util.logging.PlatformLogger;
+import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*;
 
 /**
  * @author Herb Jellinek
@@ -244,16 +245,17 @@
      */
     public static HttpClient New(URL url)
     throws IOException {
-        return HttpClient.New(url, Proxy.NO_PROXY, -1, true);
+        return HttpClient.New(url, Proxy.NO_PROXY, -1, true, null);
     }
 
     public static HttpClient New(URL url, boolean useCache)
         throws IOException {
-        return HttpClient.New(url, Proxy.NO_PROXY, -1, useCache);
+        return HttpClient.New(url, Proxy.NO_PROXY, -1, useCache, null);
     }
 
-    public static HttpClient New(URL url, Proxy p, int to, boolean useCache)
-        throws IOException {
+    public static HttpClient New(URL url, Proxy p, int to, boolean useCache,
+        HttpURLConnection httpuc) throws IOException
+    {
         if (p == null) {
             p = Proxy.NO_PROXY;
         }
@@ -261,6 +263,13 @@
         /* see if one's already around */
         if (useCache) {
             ret = kac.get(url, null);
+            if (ret != null && httpuc != null &&
+                httpuc.streaming() &&
+                httpuc.getRequestMethod() == "POST") {
+                if (!ret.available())
+                    ret = null;
+            }
+
             if (ret != null) {
                 if ((ret.proxy != null && ret.proxy.equals(p)) ||
                     (ret.proxy == null && p == null)) {
@@ -268,6 +277,8 @@
                         ret.cachedHttpClient = true;
                         assert ret.inCache;
                         ret.inCache = false;
+                        if (httpuc != null && ret.needsTunneling())
+                            httpuc.setTunnelState(TUNNELING);
                         PlatformLogger logger = HttpURLConnection.getHttpLogger();
                         if (logger.isLoggable(PlatformLogger.FINEST)) {
                             logger.finest("KeepAlive stream retrieved from the cache, " + ret);
@@ -302,20 +313,25 @@
         return ret;
     }
 
-    public static HttpClient New(URL url, Proxy p, int to) throws IOException {
-        return New(url, p, to, true);
+    public static HttpClient New(URL url, Proxy p, int to,
+        HttpURLConnection httpuc) throws IOException
+    {
+        return New(url, p, to, true, httpuc);
     }
 
     public static HttpClient New(URL url, String proxyHost, int proxyPort,
                                  boolean useCache)
         throws IOException {
-        return New(url, newHttpProxy(proxyHost, proxyPort, "http"), -1, useCache);
+        return New(url, newHttpProxy(proxyHost, proxyPort, "http"),
+            -1, useCache, null);
     }
 
     public static HttpClient New(URL url, String proxyHost, int proxyPort,
-                                 boolean useCache, int to)
+                                 boolean useCache, int to,
+                                 HttpURLConnection httpuc)
         throws IOException {
-        return New(url, newHttpProxy(proxyHost, proxyPort, "http"), to, useCache);
+        return New(url, newHttpProxy(proxyHost, proxyPort, "http"),
+            to, useCache, httpuc);
     }
 
     /* return it to the cache as still usable, if:
@@ -344,6 +360,34 @@
         }
     }
 
+    protected synchronized boolean available() throws IOException {
+        boolean available = true;
+        int old = serverSocket.getSoTimeout();
+        serverSocket.setSoTimeout(1);
+        BufferedInputStream tmpbuf =
+            new BufferedInputStream(serverSocket.getInputStream());
+
+        PlatformLogger logger = HttpURLConnection.getHttpLogger();
+        try {
+            int r = tmpbuf.read();
+            if (r == -1) {
+                if (logger.isLoggable(PlatformLogger.FINEST)) {
+                    logger.finest("HttpClient.available(): " +
+                        "read returned -1: not available");
+                }
+                available = false;
+            }
+        } catch (SocketTimeoutException e) {
+            if (logger.isLoggable(PlatformLogger.FINEST)) {
+                logger.finest("HttpClient.available(): " +
+                    "SocketTimeout: its available");
+            }
+        } finally {
+            serverSocket.setSoTimeout(old);
+        }
+        return available;
+    }
+
     protected synchronized void putInKeepAliveCache() {
         if (inCache) {
             assert false : "Duplicate put to keep alive cache";
diff --git a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
index e3feff3..c749b14 100644
--- a/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
+++ b/jdk/src/share/classes/sun/net/www/protocol/http/HttpURLConnection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1995, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1995, 2012, 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
@@ -349,7 +349,7 @@
     private HttpClient reuseClient = null;
 
     /* Tunnel states */
-    enum TunnelState {
+    public enum TunnelState {
         /* No tunnel */
         NONE,
 
@@ -660,7 +660,7 @@
      */
     protected void setNewClient (URL url, boolean useCache)
         throws IOException {
-        http = HttpClient.New(url, null, -1, useCache, connectTimeout);
+        http = HttpClient.New(url, null, -1, useCache, connectTimeout, this);
         http.setReadTimeout(readTimeout);
     }
 
@@ -701,7 +701,8 @@
                                            String proxyHost, int proxyPort,
                                            boolean useCache)
         throws IOException {
-        http = HttpClient.New (url, proxyHost, proxyPort, useCache, connectTimeout);
+        http = HttpClient.New (url, proxyHost, proxyPort, useCache,
+            connectTimeout, this);
         http.setReadTimeout(readTimeout);
     }
 
@@ -992,14 +993,14 @@
     // subclass HttpsClient will overwrite & return an instance of HttpsClient
     protected HttpClient getNewHttpClient(URL url, Proxy p, int connectTimeout)
         throws IOException {
-        return HttpClient.New(url, p, connectTimeout);
+        return HttpClient.New(url, p, connectTimeout, this);
     }
 
     // subclass HttpsClient will overwrite & return an instance of HttpsClient
     protected HttpClient getNewHttpClient(URL url, Proxy p,
                                           int connectTimeout, boolean useCache)
         throws IOException {
-        return HttpClient.New(url, p, connectTimeout, useCache);
+        return HttpClient.New(url, p, connectTimeout, useCache, this);
     }
 
     private void expect100Continue() throws IOException {
@@ -1142,7 +1143,7 @@
         }
     }
 
-    private boolean streaming () {
+    public boolean streaming () {
         return (fixedContentLength != -1) || (fixedContentLengthLong != -1) ||
                (chunkLength != -1);
     }
@@ -1748,7 +1749,7 @@
      *
      * @param  the state
      */
-    void setTunnelState(TunnelState tunnelState) {
+    public void setTunnelState(TunnelState tunnelState) {
         this.tunnelState = tunnelState;
     }
 
diff --git a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
index 6d36794..24da9e3 100644
--- a/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/DatagramChannelImpl.java
@@ -749,7 +749,8 @@
                     if (sm != null)
                         sm.checkConnect(isa.getAddress().getHostAddress(),
                                         isa.getPort());
-                    disconnect0(fd);
+                    boolean isIPv6 = (family == StandardProtocolFamily.INET6);
+                    disconnect0(fd, isIPv6);
                     remoteAddress = null;
                     state = ST_UNCONNECTED;
 
@@ -1084,7 +1085,7 @@
 
     private static native void initIDs();
 
-    private static native void disconnect0(FileDescriptor fd)
+    private static native void disconnect0(FileDescriptor fd, boolean isIPv6)
         throws IOException;
 
     private native int receive0(FileDescriptor fd, long address, int len,
diff --git a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
index 32381a5..5c1908d 100644
--- a/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/FileChannelImpl.java
@@ -34,6 +34,7 @@
 import java.util.List;
 import java.security.AccessController;
 import sun.misc.Cleaner;
+import sun.misc.IoTrace;
 import sun.security.action.GetPropertyAction;
 
 public class FileChannelImpl
@@ -56,13 +57,16 @@
     // Required to prevent finalization of creating stream (immutable)
     private final Object parent;
 
+    // The path of the referenced file (null if the parent stream is created with a file descriptor)
+    private final String path;
+
     // Thread-safe set of IDs of native threads, for signalling
     private final NativeThreadSet threads = new NativeThreadSet(2);
 
     // Lock for operations involving position and size
     private final Object positionLock = new Object();
 
-    private FileChannelImpl(FileDescriptor fd, boolean readable,
+    private FileChannelImpl(FileDescriptor fd, String path, boolean readable,
                             boolean writable, boolean append, Object parent)
     {
         this.fd = fd;
@@ -70,23 +74,24 @@
         this.writable = writable;
         this.append = append;
         this.parent = parent;
+        this.path = path;
         this.nd = new FileDispatcherImpl(append);
     }
 
     // Used by FileInputStream.getChannel() and RandomAccessFile.getChannel()
-    public static FileChannel open(FileDescriptor fd,
+    public static FileChannel open(FileDescriptor fd, String path,
                                    boolean readable, boolean writable,
                                    Object parent)
     {
-        return new FileChannelImpl(fd, readable, writable, false, parent);
+        return new FileChannelImpl(fd, path, readable, writable, false, parent);
     }
 
     // Used by FileOutputStream.getChannel
-    public static FileChannel open(FileDescriptor fd,
+    public static FileChannel open(FileDescriptor fd, String path,
                                    boolean readable, boolean writable,
                                    boolean append, Object parent)
     {
-        return new FileChannelImpl(fd, readable, writable, append, parent);
+        return new FileChannelImpl(fd, path, readable, writable, append, parent);
     }
 
     private void ensureOpen() throws IOException {
@@ -134,6 +139,7 @@
         synchronized (positionLock) {
             int n = 0;
             int ti = -1;
+            Object traceContext = IoTrace.fileReadBegin(path);
             try {
                 begin();
                 ti = threads.add();
@@ -145,6 +151,7 @@
                 return IOStatus.normalize(n);
             } finally {
                 threads.remove(ti);
+                IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0);
                 end(n > 0);
                 assert IOStatus.check(n);
             }
@@ -162,6 +169,7 @@
         synchronized (positionLock) {
             long n = 0;
             int ti = -1;
+            Object traceContext = IoTrace.fileReadBegin(path);
             try {
                 begin();
                 ti = threads.add();
@@ -173,6 +181,7 @@
                 return IOStatus.normalize(n);
             } finally {
                 threads.remove(ti);
+                IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0);
                 end(n > 0);
                 assert IOStatus.check(n);
             }
@@ -186,6 +195,7 @@
         synchronized (positionLock) {
             int n = 0;
             int ti = -1;
+            Object traceContext = IoTrace.fileWriteBegin(path);
             try {
                 begin();
                 ti = threads.add();
@@ -198,6 +208,7 @@
             } finally {
                 threads.remove(ti);
                 end(n > 0);
+                IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0);
                 assert IOStatus.check(n);
             }
         }
@@ -214,6 +225,7 @@
         synchronized (positionLock) {
             long n = 0;
             int ti = -1;
+            Object traceContext = IoTrace.fileWriteBegin(path);
             try {
                 begin();
                 ti = threads.add();
@@ -225,6 +237,7 @@
                 return IOStatus.normalize(n);
             } finally {
                 threads.remove(ti);
+                IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0);
                 end(n > 0);
                 assert IOStatus.check(n);
             }
@@ -665,6 +678,7 @@
         ensureOpen();
         int n = 0;
         int ti = -1;
+        Object traceContext = IoTrace.fileReadBegin(path);
         try {
             begin();
             ti = threads.add();
@@ -676,6 +690,7 @@
             return IOStatus.normalize(n);
         } finally {
             threads.remove(ti);
+            IoTrace.fileReadEnd(traceContext, n > 0 ? n : 0);
             end(n > 0);
             assert IOStatus.check(n);
         }
@@ -691,6 +706,7 @@
         ensureOpen();
         int n = 0;
         int ti = -1;
+        Object traceContext = IoTrace.fileWriteBegin(path);
         try {
             begin();
             ti = threads.add();
@@ -703,6 +719,7 @@
         } finally {
             threads.remove(ti);
             end(n > 0);
+            IoTrace.fileWriteEnd(traceContext, n > 0 ? n : 0);
             assert IOStatus.check(n);
         }
     }
diff --git a/jdk/src/share/classes/sun/nio/ch/IOUtil.java b/jdk/src/share/classes/sun/nio/ch/IOUtil.java
index 8645888..5a6fa71 100644
--- a/jdk/src/share/classes/sun/nio/ch/IOUtil.java
+++ b/jdk/src/share/classes/sun/nio/ch/IOUtil.java
@@ -344,6 +344,8 @@
 
     static native int iovMax();
 
+    static native int fdLimit();
+
     static native void initIDs();
 
     static {
diff --git a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java
index aa4f172..5d7fa99 100644
--- a/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java
+++ b/jdk/src/share/classes/sun/nio/ch/SocketAdaptor.java
@@ -34,6 +34,8 @@
 import java.security.PrivilegedExceptionAction;
 import java.util.*;
 
+import sun.misc.IoTrace;
+
 
 // Make a socket channel look like a socket.
 //
@@ -204,8 +206,9 @@
                 SelectionKey sk = null;
                 Selector sel = null;
                 sc.configureBlocking(false);
+                int n = 0;
+                Object traceContext = IoTrace.socketReadBegin(getInetAddress(), getPort(), timeout);
                 try {
-                    int n;
                     if ((n = sc.read(bb)) != 0)
                         return n;
                     sel = Util.getTemporarySelector(sc);
@@ -226,6 +229,7 @@
                             throw new SocketTimeoutException();
                     }
                 } finally {
+                    IoTrace.socketReadEnd(traceContext, n > 0 ? n : 0);
                     if (sk != null)
                         sk.cancel();
                     if (sc.isOpen())
diff --git a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
index f0f7255..59a81ba 100644
--- a/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
+++ b/jdk/src/share/classes/sun/nio/ch/SocketChannelImpl.java
@@ -33,7 +33,7 @@
 import java.nio.channels.spi.*;
 import java.util.*;
 import sun.net.NetHooks;
-
+import sun.misc.IoTrace;
 
 /**
  * An implementation of SocketChannels
@@ -80,8 +80,8 @@
     private int state = ST_UNINITIALIZED;
 
     // Binding
-    private SocketAddress localAddress;
-    private SocketAddress remoteAddress;
+    private InetSocketAddress localAddress;
+    private InetSocketAddress remoteAddress;
 
     // Input/Output open
     private boolean isInputOpen = true;
@@ -278,6 +278,11 @@
         synchronized (readLock) {
             if (!ensureReadOpen())
                 return -1;
+            Object traceContext = null;
+            if (isBlocking()) {
+                traceContext = IoTrace.socketReadBegin(remoteAddress.getAddress(),
+                                                      remoteAddress.getPort(), 0);
+            }
             int n = 0;
             try {
 
@@ -367,6 +372,11 @@
 
             } finally {
                 readerCleanup();        // Clear reader thread
+
+                if (isBlocking()) {
+                    IoTrace.socketReadEnd(traceContext, n > 0 ? n : 0);
+                }
+
                 // The end method, which is defined in our superclass
                 // AbstractInterruptibleChannel, resets the interruption
                 // machinery.  If its argument is true then it returns
@@ -407,6 +417,11 @@
             if (!ensureReadOpen())
                 return -1;
             long n = 0;
+            Object traceContext = null;
+            if (isBlocking()) {
+                traceContext = IoTrace.socketReadBegin(remoteAddress.getAddress(),
+                                                      remoteAddress.getPort(), 0);
+            }
             try {
                 begin();
                 synchronized (stateLock) {
@@ -423,6 +438,9 @@
                 }
             } finally {
                 readerCleanup();
+                if (isBlocking()) {
+                    IoTrace.socketReadEnd(traceContext, n > 0 ? n : 0);
+                }
                 end(n > 0 || (n == IOStatus.UNAVAILABLE));
                 synchronized (stateLock) {
                     if ((n <= 0) && (!isInputOpen))
@@ -439,6 +457,10 @@
         synchronized (writeLock) {
             ensureWriteOpen();
             int n = 0;
+            Object traceContext =
+                IoTrace.socketWriteBegin(remoteAddress.getAddress(),
+                                         remoteAddress.getPort());
+
             try {
                 begin();
                 synchronized (stateLock) {
@@ -454,6 +476,7 @@
                 }
             } finally {
                 writerCleanup();
+                IoTrace.socketWriteEnd(traceContext, n > 0 ? n : 0);
                 end(n > 0 || (n == IOStatus.UNAVAILABLE));
                 synchronized (stateLock) {
                     if ((n <= 0) && (!isOutputOpen))
@@ -472,6 +495,9 @@
         synchronized (writeLock) {
             ensureWriteOpen();
             long n = 0;
+            Object traceContext =
+                IoTrace.socketWriteBegin(remoteAddress.getAddress(),
+                                         remoteAddress.getPort());
             try {
                 begin();
                 synchronized (stateLock) {
@@ -487,6 +513,7 @@
                 }
             } finally {
                 writerCleanup();
+                IoTrace.socketWriteEnd(traceContext, n > 0 ? n : 0);
                 end((n > 0) || (n == IOStatus.UNAVAILABLE));
                 synchronized (stateLock) {
                     if ((n <= 0) && (!isOutputOpen))
diff --git a/jdk/src/share/classes/sun/print/PSPrinterJob.java b/jdk/src/share/classes/sun/print/PSPrinterJob.java
index bd92706..5344ba8 100644
--- a/jdk/src/share/classes/sun/print/PSPrinterJob.java
+++ b/jdk/src/share/classes/sun/print/PSPrinterJob.java
@@ -68,14 +68,18 @@
 
 import java.io.BufferedInputStream;
 import java.io.BufferedOutputStream;
+import java.io.BufferedReader;
 import java.io.CharConversionException;
 import java.io.File;
 import java.io.InputStream;
+import java.io.InputStreamReader;
 import java.io.IOException;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 
 import java.util.ArrayList;
 import java.util.Enumeration;
@@ -674,15 +678,38 @@
     private class PrinterSpooler implements java.security.PrivilegedAction {
         PrinterException pex;
 
+        private void handleProcessFailure(final Process failedProcess,
+                final String[] execCmd, final int result) throws IOException {
+            try (StringWriter sw = new StringWriter();
+                    PrintWriter pw = new PrintWriter(sw)) {
+                pw.append("error=").append(Integer.toString(result));
+                pw.append(" running:");
+                for (String arg: execCmd) {
+                    pw.append(" '").append(arg).append("'");
+                }
+                try (InputStream is = failedProcess.getErrorStream();
+                        InputStreamReader isr = new InputStreamReader(is);
+                        BufferedReader br = new BufferedReader(isr)) {
+                    while (br.ready()) {
+                        pw.println();
+                        pw.append("\t\t").append(br.readLine());
+                    }
+                } finally {
+                    pw.flush();
+                    throw new IOException(sw.toString());
+                }
+            }
+        }
+
         public Object run() {
+            if (spoolFile == null || !spoolFile.exists()) {
+               pex = new PrinterException("No spool file");
+               return null;
+            }
             try {
                 /**
                  * Spool to the printer.
                  */
-                if (spoolFile == null || !spoolFile.exists()) {
-                   pex = new PrinterException("No spool file");
-                   return null;
-                }
                 String fileName = spoolFile.getAbsolutePath();
                 String execCmd[] = printExecCmd(mDestination, mOptions,
                                mNoJobSheet, getJobNameInt(),
@@ -690,12 +717,16 @@
 
                 Process process = Runtime.getRuntime().exec(execCmd);
                 process.waitFor();
-                spoolFile.delete();
-
+                final int result = process.exitValue();
+                if (0 != result) {
+                    handleProcessFailure(process, execCmd, result);
+                }
             } catch (IOException ex) {
                 pex = new PrinterIOException(ex);
             } catch (InterruptedException ie) {
                 pex = new PrinterException(ie.toString());
+            } finally {
+                spoolFile.delete();
             }
             return null;
         }
diff --git a/jdk/src/share/classes/sun/rmi/log/ReliableLog.java b/jdk/src/share/classes/sun/rmi/log/ReliableLog.java
index fe512c2..a247514 100644
--- a/jdk/src/share/classes/sun/rmi/log/ReliableLog.java
+++ b/jdk/src/share/classes/sun/rmi/log/ReliableLog.java
@@ -344,10 +344,9 @@
                                return ClassLoader.getSystemClassLoader();
                             }
                         });
-                Class cl = loader.loadClass(logClassName);
-                if (LogFile.class.isAssignableFrom(cl)) {
-                    return cl.getConstructor(String.class, String.class);
-                }
+                Class<? extends LogFile> cl =
+                    loader.loadClass(logClassName).asSubclass(LogFile.class);
+                return cl.getConstructor(String.class, String.class);
             } catch (Exception e) {
                 System.err.println("Exception occurred:");
                 e.printStackTrace();
@@ -595,10 +594,10 @@
         } else {
             name = versionFile;
         }
-        DataOutputStream out =
-            new DataOutputStream(new FileOutputStream(fName(name)));
-        writeInt(out, version);
-        out.close();
+        try (FileOutputStream fos = new FileOutputStream(fName(name));
+             DataOutputStream out = new DataOutputStream(fos)) {
+            writeInt(out, version);
+        }
     }
 
     /**
@@ -629,11 +628,9 @@
      * @exception IOException If an I/O error has occurred.
      */
     private int readVersion(String name) throws IOException {
-        DataInputStream in = new DataInputStream(new FileInputStream(name));
-        try {
+        try (DataInputStream in = new DataInputStream
+                (new FileInputStream(name))) {
             return in.readInt();
-        } finally {
-            in.close();
         }
     }
 
diff --git a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java
index 8089846..e086f79c 100644
--- a/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java
+++ b/jdk/src/share/classes/sun/rmi/registry/RegistryImpl.java
@@ -77,9 +77,9 @@
     /* indicate compatibility with JDK 1.1.x version of class */
     private static final long serialVersionUID = 4666870661827494597L;
     private Hashtable<String, Remote> bindings
-        = new Hashtable<String, Remote>(101);
+        = new Hashtable<>(101);
     private static Hashtable<InetAddress, InetAddress> allowedAccessCache
-        = new Hashtable<InetAddress, InetAddress>(3);
+        = new Hashtable<>(3);
     private static RegistryImpl registry;
     private static ObjID id = new ObjID(ObjID.REGISTRY_ID);
 
@@ -194,9 +194,9 @@
         synchronized (bindings) {
             int i = bindings.size();
             names = new String[i];
-            Enumeration enum_ = bindings.keys();
+            Enumeration<String> enum_ = bindings.keys();
             while ((--i) >= 0)
-                names[i] = (String)enum_.nextElement();
+                names[i] = enum_.nextElement();
         }
         return names;
     }
diff --git a/jdk/src/share/classes/sun/rmi/rmic/BatchEnvironment.java b/jdk/src/share/classes/sun/rmi/rmic/BatchEnvironment.java
index 3eff0bb..396d54d 100644
--- a/jdk/src/share/classes/sun/rmi/rmic/BatchEnvironment.java
+++ b/jdk/src/share/classes/sun/rmi/rmic/BatchEnvironment.java
@@ -160,7 +160,7 @@
     }
 
     /** list of generated source files created in this environment */
-    private Vector generatedFiles = new Vector();
+    private Vector<File> generatedFiles = new Vector<>();
 
     /**
      * Remember a generated source file generated so that it
@@ -177,9 +177,9 @@
      */
     public void deleteGeneratedFiles() {
         synchronized(generatedFiles) {
-            Enumeration enumeration = generatedFiles.elements();
+            Enumeration<File> enumeration = generatedFiles.elements();
             while (enumeration.hasMoreElements()) {
-                File file = (File) enumeration.nextElement();
+                File file = enumeration.nextElement();
                 file.delete();
             }
             generatedFiles.removeAllElements();
diff --git a/jdk/src/share/classes/sun/rmi/rmic/Main.java b/jdk/src/share/classes/sun/rmi/rmic/Main.java
index 562e389..23bdfce 100644
--- a/jdk/src/share/classes/sun/rmi/rmic/Main.java
+++ b/jdk/src/share/classes/sun/rmi/rmic/Main.java
@@ -73,14 +73,15 @@
     File destDir;
     int flags;
     long tm;
-    Vector classes;
+    Vector<String> classes;
     boolean nowrite;
     boolean nocompile;
     boolean keepGenerated;
     boolean status;
     String[] generatorArgs;
-    Vector generators;
-    Class environmentClass = BatchEnvironment.class;
+    Vector<Generator> generators;
+    Class<? extends BatchEnvironment> environmentClass =
+        BatchEnvironment.class;
     boolean iiopGeneration = false;
 
     /**
@@ -183,7 +184,7 @@
         destDir = null;
         flags = F_WARNINGS;
         tm = System.currentTimeMillis();
-        classes = new Vector();
+        classes = new Vector<>();
         nowrite = false;
         nocompile = false;
         keepGenerated = false;
@@ -191,7 +192,7 @@
         if (generatorArgs == null) {
             return false;
         }
-        generators = new Vector();
+        generators = new Vector<>();
 
         // Pre-process command line for @file arguments
         try {
@@ -411,7 +412,7 @@
 
         // Get the environment required by this generator...
 
-        Class envClass = BatchEnvironment.class;
+        Class<?> envClass = BatchEnvironment.class;
         String env = getString("generator.env." + arg);
         if (env != null) {
             try {
@@ -423,7 +424,7 @@
 
                     // Yes, so switch to the new one...
 
-                    environmentClass = envClass;
+                    environmentClass = envClass.asSubclass(BatchEnvironment.class);
 
                 } else {
 
@@ -495,8 +496,9 @@
         try {
             Class[] ctorArgTypes = {OutputStream.class,ClassPath.class,Main.class};
             Object[] ctorArgs = {out,classPath,this};
-            Constructor constructor = environmentClass.getConstructor(ctorArgTypes);
-            result = (BatchEnvironment) constructor.newInstance(ctorArgs);
+            Constructor<? extends BatchEnvironment> constructor =
+                environmentClass.getConstructor(ctorArgTypes);
+            result =  constructor.newInstance(ctorArgs);
             result.reset();
         }
         catch (Exception e) {
@@ -530,7 +532,7 @@
              */
             for (int i = classes.size()-1; i >= 0; i-- ) {
                 Identifier implClassName =
-                    Identifier.lookup((String)classes.elementAt(i));
+                    Identifier.lookup(classes.elementAt(i));
 
                 /*
                  * Fix bugid 4049354: support using '.' as an inner class
@@ -558,7 +560,7 @@
                 try {
                     ClassDefinition def = decl.getClassDefinition(env);
                     for (int j = 0; j < generators.size(); j++) {
-                        Generator gen = (Generator)generators.elementAt(j);
+                        Generator gen = generators.elementAt(j);
                         gen.generate(env, def, destDir);
                     }
                 } catch (ClassNotFound ex) {
@@ -673,7 +675,7 @@
 
         do {
             done = true;
-            for (Enumeration e = env.getClasses() ; e.hasMoreElements() ; ) {
+            for (Enumeration<?> e = env.getClasses() ; e.hasMoreElements() ; ) {
                 ClassDeclaration c = (ClassDeclaration)e.nextElement();
                 done = compileClass(c,buf,env);
             }
@@ -682,7 +684,9 @@
 
     /*
      * Compile a single class.
+     * Fallthrough is intentional
      */
+    @SuppressWarnings("fallthrough")
     public boolean compileClass (ClassDeclaration c,
                                  ByteArrayOutputStream buf,
                                  BatchEnvironment env)
@@ -879,6 +883,6 @@
         args[1] = (arg1 != null ? arg1.toString() : "null");
         args[2] = (arg2 != null ? arg2.toString() : "null");
 
-        return java.text.MessageFormat.format(format, args);
+        return java.text.MessageFormat.format(format, (Object[]) args);
     }
 }
diff --git a/jdk/src/share/classes/sun/rmi/rmic/RMIGenerator.java b/jdk/src/share/classes/sun/rmi/rmic/RMIGenerator.java
index 043ca87..4839036 100644
--- a/jdk/src/share/classes/sun/rmi/rmic/RMIGenerator.java
+++ b/jdk/src/share/classes/sun/rmi/rmic/RMIGenerator.java
@@ -61,7 +61,7 @@
  */
 public class RMIGenerator implements RMIConstants, Generator {
 
-    private static final Hashtable versionOptions = new Hashtable();
+    private static final Hashtable<String, Integer> versionOptions = new Hashtable<>();
     static {
         versionOptions.put("-v1.1", new Integer(STUB_VERSION_1_1));
         versionOptions.put("-vcompat", new Integer(STUB_VERSION_FAT));
@@ -96,7 +96,7 @@
                         return false;
                     }
                     explicitVersion = arg;
-                    version = ((Integer) versionOptions.get(arg)).intValue();
+                    version = versionOptions.get(arg);
                     argv[i] = null;
                 }
             }
@@ -519,7 +519,7 @@
          * follows a previous catch of it or of one of its superclasses.
          * The following method invocation takes care of these details.
          */
-        Vector catchList = computeUniqueCatchList(exceptions);
+        Vector<ClassDefinition> catchList = computeUniqueCatchList(exceptions);
 
         /*
          * If we need to catch any particular exceptions (i.e. this method
@@ -615,10 +615,10 @@
          * UnexpectedException, and end the try block.
          */
         if (catchList.size() > 0) {
-            for (Enumeration enumeration = catchList.elements();
+            for (Enumeration<ClassDefinition> enumeration = catchList.elements();
                  enumeration.hasMoreElements();)
             {
-                ClassDefinition def = (ClassDefinition) enumeration.nextElement();
+                ClassDefinition def = enumeration.nextElement();
                 p.pOlnI("} catch (" + def.getName() + " e) {");
                 p.pln("throw e;");
             }
@@ -650,8 +650,8 @@
      * of its superclasses is in the throws clause of the method, indicating
      * that no exceptions need to be caught.
      */
-    private Vector computeUniqueCatchList(ClassDeclaration[] exceptions) {
-        Vector uniqueList = new Vector();       // unique exceptions to catch
+    private Vector<ClassDefinition> computeUniqueCatchList(ClassDeclaration[] exceptions) {
+        Vector<ClassDefinition> uniqueList = new Vector<>();       // unique exceptions to catch
 
         uniqueList.addElement(defRuntimeException);
         uniqueList.addElement(defRemoteException);
@@ -682,8 +682,7 @@
                  * exceptions that need to be caught:
                  */
                 for (int j = 0; j < uniqueList.size();) {
-                    ClassDefinition def =
-                        (ClassDefinition) uniqueList.elementAt(j);
+                    ClassDefinition def = uniqueList.elementAt(j);
                     if (def.superClassOf(env, decl)) {
                         /*
                          * If a superclass of this exception is already on
diff --git a/jdk/src/share/classes/sun/rmi/rmic/newrmic/Main.java b/jdk/src/share/classes/sun/rmi/rmic/newrmic/Main.java
index d802136..1e59be4 100644
--- a/jdk/src/share/classes/sun/rmi/rmic/newrmic/Main.java
+++ b/jdk/src/share/classes/sun/rmi/rmic/newrmic/Main.java
@@ -455,7 +455,7 @@
         BatchEnvironment env;
         try {
             Constructor<? extends BatchEnvironment> cons =
-                batch.envClass.getConstructor(new Class[] { RootDoc.class });
+                batch.envClass.getConstructor(new Class<?>[] { RootDoc.class });
             env = cons.newInstance(rootDoc);
         } catch (NoSuchMethodException e) {
             throw new AssertionError(e);
diff --git a/jdk/src/share/classes/sun/rmi/rmic/newrmic/Resources.java b/jdk/src/share/classes/sun/rmi/rmic/newrmic/Resources.java
index f8ea7fc..6b3ba17 100644
--- a/jdk/src/share/classes/sun/rmi/rmic/newrmic/Resources.java
+++ b/jdk/src/share/classes/sun/rmi/rmic/newrmic/Resources.java
@@ -69,7 +69,7 @@
             format = "missing resource key: key = \"" + key + "\", " +
                 "arguments = \"{0}\", \"{1}\", \"{2}\"";
         }
-        return MessageFormat.format(format, args);
+        return MessageFormat.format(format, (Object[]) args);
     }
 
     /**
diff --git a/jdk/src/share/classes/sun/rmi/server/ActivatableRef.java b/jdk/src/share/classes/sun/rmi/server/ActivatableRef.java
index 9364e0d0..29a3529 100644
--- a/jdk/src/share/classes/sun/rmi/server/ActivatableRef.java
+++ b/jdk/src/share/classes/sun/rmi/server/ActivatableRef.java
@@ -80,7 +80,7 @@
         String className = desc.getClassName();
 
         try {
-            Class cl =
+            Class<?> cl =
                 RMIClassLoader.loadClass(desc.getLocation(), className);
             RemoteRef clientRef = new ActivatableRef(id, null);
             return Util.createProxy(cl, clientRef, false);
@@ -373,8 +373,8 @@
         if (className.equals("")) return;
 
         try {
-            Class refClass = Class.forName(RemoteRef.packagePrefix + "." +
-                                           className);
+            Class<?> refClass = Class.forName(RemoteRef.packagePrefix + "." +
+                                              className);
             ref = (RemoteRef)refClass.newInstance();
             ref.readExternal(in);
         } catch (InstantiationException e) {
diff --git a/jdk/src/share/classes/sun/rmi/server/Activation.java b/jdk/src/share/classes/sun/rmi/server/Activation.java
index dbccbe1..bdcf724 100644
--- a/jdk/src/share/classes/sun/rmi/server/Activation.java
+++ b/jdk/src/share/classes/sun/rmi/server/Activation.java
@@ -139,7 +139,6 @@
 
     /** indicate compatibility with JDK 1.2 version of class */
     private static final long serialVersionUID = 2921265612698155191L;
-
     private static final byte MAJOR_VERSION = 1;
     private static final byte MINOR_VERSION = 0;
 
@@ -299,6 +298,7 @@
     private static class SystemRegistryImpl extends RegistryImpl {
 
         private static final String NAME = ActivationSystem.class.getName();
+        private static final long serialVersionUID = 4877330021609408794L;
         private final ActivationSystem systemStub;
 
         SystemRegistryImpl(int port,
@@ -805,9 +805,8 @@
         ActivationGroupDesc desc = null;
         ActivationGroupID groupID = null;
         long incarnation = 0;
-        Map<ActivationID,ObjectEntry> objects =
-            new HashMap<ActivationID,ObjectEntry>();
-        Set<ActivationID> restartSet = new HashSet<ActivationID>();
+        Map<ActivationID,ObjectEntry> objects = new HashMap<>();
+        Set<ActivationID> restartSet = new HashSet<>();
 
         transient ActivationInstantiator group = null;
         transient int status = NORMAL;
@@ -1058,6 +1057,11 @@
             }
         }
 
+       /*
+        * Fallthrough from TERMINATE to TERMINATING
+        * is intentional
+        */
+        @SuppressWarnings("fallthrough")
         private void await() {
             while (true) {
                 switch (status) {
@@ -1229,14 +1233,13 @@
                     PipeWriter.plugTogetherPair
                         (child.getInputStream(), System.out,
                          child.getErrorStream(), System.err);
-
-                    MarshalOutputStream out =
-                        new MarshalOutputStream(child.getOutputStream());
-                    out.writeObject(id);
-                    out.writeObject(desc);
-                    out.writeLong(incarnation);
-                    out.flush();
-                    out.close();
+                    try (MarshalOutputStream out =
+                            new MarshalOutputStream(child.getOutputStream())) {
+                        out.writeObject(id);
+                        out.writeObject(desc);
+                        out.writeLong(incarnation);
+                        out.flush();
+                    }
 
 
                 } catch (IOException e) {
@@ -1353,7 +1356,7 @@
         cmdenv = desc.getCommandEnvironment();
 
         // argv is the literal command to exec
-        List<String> argv = new ArrayList<String>();
+        List<String> argv = new ArrayList<>();
 
         // Command name/path
         argv.add((cmdenv != null && cmdenv.getCommandPath() != null)
@@ -1958,7 +1961,7 @@
             }
 
             String log = null;
-            List<String> childArgs = new ArrayList<String>();
+            List<String> childArgs = new ArrayList<>();
 
             /*
              * Parse arguments
@@ -2032,8 +2035,7 @@
                 }
 
                 try {
-                    Class<?> execPolicyClass =
-                        RMIClassLoader.loadClass(execPolicyClassName);
+                    Class<?> execPolicyClass = getRMIClass(execPolicyClassName);
                     execPolicy = execPolicyClass.newInstance();
                     execPolicyMethod =
                         execPolicyClass.getMethod("checkExecCommand",
@@ -2124,6 +2126,10 @@
         }
     }
 
+    @SuppressWarnings("deprecation")
+    private static Class<?> getRMIClass(String execPolicyClassName) throws Exception  {
+        return RMIClassLoader.loadClass(execPolicyClassName);
+    }
     /*
      * Dijkstra semaphore operations to limit the number of subprocesses
      * rmid attempts to make at once.
diff --git a/jdk/src/share/classes/sun/rmi/server/ActivationGroupImpl.java b/jdk/src/share/classes/sun/rmi/server/ActivationGroupImpl.java
index 1ee26a5..dd89d51 100644
--- a/jdk/src/share/classes/sun/rmi/server/ActivationGroupImpl.java
+++ b/jdk/src/share/classes/sun/rmi/server/ActivationGroupImpl.java
@@ -66,10 +66,10 @@
 
     /** maps persistent IDs to activated remote objects */
     private final Hashtable<ActivationID,ActiveEntry> active =
-        new Hashtable<ActivationID,ActiveEntry>();
+        new Hashtable<>();
     private boolean groupInactive = false;
     private final ActivationGroupID groupID;
-    private final List<ActivationID> lockedIDs = new ArrayList<ActivationID>();
+    private final List<ActivationID> lockedIDs = new ArrayList<>();
 
     /**
      * Creates a default activation group implementation.
@@ -296,14 +296,9 @@
             active.put(id, entry);
             return entry.mobj;
 
-        } catch (NoSuchMethodException e) {
-            /* user forgot to provide activatable constructor? */
-            throw new ActivationException
-                ("Activatable object must provide an activation"+
-                 " constructor", e);
-
-        } catch (NoSuchMethodError e) {
-            /* code recompiled and user forgot to provide
+        } catch (NoSuchMethodException | NoSuchMethodError e) {
+            /* user forgot to provide activatable constructor?
+             * or code recompiled and user forgot to provide
              *  activatable constructor?
              */
             throw new ActivationException
diff --git a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java
index 52d9ee5..40c2573 100644
--- a/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java
+++ b/jdk/src/share/classes/sun/rmi/server/LoaderHandler.java
@@ -112,11 +112,11 @@
      * garbage collected.
      */
     private static final HashMap<LoaderKey, LoaderEntry> loaderTable
-        = new HashMap<LoaderKey, LoaderEntry>(5);
+        = new HashMap<>(5);
 
     /** reference queue for cleared class loader entries */
     private static final ReferenceQueue<Loader> refQueue
-        = new ReferenceQueue<Loader>();
+        = new ReferenceQueue<>();
 
     /*
      * Disallow anyone from creating one of these.
@@ -149,8 +149,8 @@
      * but first try to resolve the named class through the given
      * "default loader".
      */
-    public static Class loadClass(String codebase, String name,
-                                  ClassLoader defaultLoader)
+    public static Class<?> loadClass(String codebase, String name,
+                                     ClassLoader defaultLoader)
         throws MalformedURLException, ClassNotFoundException
     {
         if (loaderLog.isLoggable(Log.BRIEF)) {
@@ -170,7 +170,7 @@
 
         if (defaultLoader != null) {
             try {
-                Class c = Class.forName(name, false, defaultLoader);
+                Class<?> c = Class.forName(name, false, defaultLoader);
                 if (loaderLog.isLoggable(Log.VERBOSE)) {
                     loaderLog.log(Log.VERBOSE,
                         "class \"" + name + "\" found via defaultLoader, " +
@@ -189,7 +189,7 @@
      * a class) that RMI will use to annotate the call stream when
      * marshalling objects of the given class.
      */
-    public static String getClassAnnotation(Class cl) {
+    public static String getClassAnnotation(Class<?> cl) {
         String name = cl.getName();
 
         /*
@@ -261,15 +261,13 @@
 
                     annotation = urlsToPath(urls);
                 }
-            } catch (SecurityException e) {
+            } catch (SecurityException | IOException e) {
                 /*
-                 * If access was denied to the knowledge of the class
-                 * loader's URLs, fall back to the default behavior.
-                 */
-            } catch (IOException e) {
-                /*
-                 * This shouldn't happen, although it is declared to be
-                 * thrown by openConnection() and getPermission().  If it
+                 * SecurityException: If access was denied to the knowledge of
+                 * the class loader's URLs, fall back to the default behavior.
+                 *
+                 * IOException: This shouldn't happen, although it is declared
+                 * to be thrown by openConnection() and getPermission().  If it
                  * does happen, forget about this class loader's URLs and
                  * fall back to the default behavior.
                  */
@@ -358,7 +356,7 @@
      * Load a class from the RMI class loader corresponding to the given
      * codebase URL path in the current execution context.
      */
-    private static Class loadClass(URL[] urls, String name)
+    private static Class<?> loadClass(URL[] urls, String name)
         throws ClassNotFoundException
     {
         ClassLoader parent = getRMIContextClassLoader();
@@ -375,7 +373,7 @@
         SecurityManager sm = System.getSecurityManager();
         if (sm == null) {
             try {
-                Class c = Class.forName(name, false, parent);
+                Class<?> c = Class.forName(name, false, parent);
                 if (loaderLog.isLoggable(Log.VERBOSE)) {
                     loaderLog.log(Log.VERBOSE,
                         "class \"" + name + "\" found via " +
@@ -424,7 +422,7 @@
                  * resolved without the security-offending codebase anyway;
                  * if so, return successfully (see bugids 4191926 & 4349670).
                  */
-                Class c = Class.forName(name, false, parent);
+                Class<?> c = Class.forName(name, false, parent);
                 if (loaderLog.isLoggable(Log.VERBOSE)) {
                     loaderLog.log(Log.VERBOSE,
                         "class \"" + name + "\" found via " +
@@ -450,7 +448,7 @@
         }
 
         try {
-            Class c = Class.forName(name, false, loader);
+            Class<?> c = Class.forName(name, false, loader);
             if (loaderLog.isLoggable(Log.VERBOSE)) {
                 loaderLog.log(Log.VERBOSE,
                     "class \"" + name + "\" " + "found via codebase, " +
@@ -472,8 +470,8 @@
      * implement interface classes named by the given array of
      * interface names.
      */
-    public static Class loadProxyClass(String codebase, String[] interfaces,
-                                       ClassLoader defaultLoader)
+    public static Class<?> loadProxyClass(String codebase, String[] interfaces,
+                                          ClassLoader defaultLoader)
         throws MalformedURLException, ClassNotFoundException
     {
         if (loaderLog.isLoggable(Log.BRIEF)) {
@@ -537,7 +535,7 @@
         SecurityManager sm = System.getSecurityManager();
         if (sm == null) {
             try {
-                Class c = loadProxyClass(interfaces, defaultLoader, parent,
+                Class<?> c = loadProxyClass(interfaces, defaultLoader, parent,
                                          false);
                 if (loaderLog.isLoggable(Log.VERBOSE)) {
                     loaderLog.log(Log.VERBOSE,
@@ -584,8 +582,8 @@
                  * resolved without the security-offending codebase anyway;
                  * if so, return successfully (see bugids 4191926 & 4349670).
                  */
-                Class c = loadProxyClass(interfaces, defaultLoader, parent,
-                                         false);
+                Class<?> c = loadProxyClass(interfaces, defaultLoader, parent,
+                                            false);
                 if (loaderLog.isLoggable(Log.VERBOSE)) {
                     loaderLog.log(Log.VERBOSE,
                         "(access to codebase denied) " +
@@ -608,7 +606,7 @@
         }
 
         try {
-            Class c = loadProxyClass(interfaces, defaultLoader, loader, true);
+            Class<?> c = loadProxyClass(interfaces, defaultLoader, loader, true);
             if (loaderLog.isLoggable(Log.VERBOSE)) {
                 loaderLog.log(Log.VERBOSE,
                               "proxy class defined by " + c.getClassLoader());
@@ -629,14 +627,14 @@
      * class will implement classes which are named in the supplied
      * interfaceNames.
      */
-    private static Class loadProxyClass(String[] interfaceNames,
-                                        ClassLoader defaultLoader,
-                                        ClassLoader codebaseLoader,
-                                        boolean preferCodebase)
+    private static Class<?> loadProxyClass(String[] interfaceNames,
+                                           ClassLoader defaultLoader,
+                                           ClassLoader codebaseLoader,
+                                           boolean preferCodebase)
         throws ClassNotFoundException
     {
         ClassLoader proxyLoader = null;
-        Class[] classObjs = new Class[interfaceNames.length];
+        Class<?>[] classObjs = new Class<?>[interfaceNames.length];
         boolean[] nonpublic = { false };
 
       defaultLoaderCase:
@@ -692,7 +690,7 @@
      * Define a proxy class in the given class loader.  The proxy
      * class will implement the given interfaces Classes.
      */
-    private static Class loadProxyClass(ClassLoader loader, Class[] interfaces)
+    private static Class<?> loadProxyClass(ClassLoader loader, Class[] interfaces)
         throws ClassNotFoundException
     {
         try {
@@ -727,7 +725,7 @@
         ClassLoader nonpublicLoader = null;
 
         for (int i = 0; i < interfaces.length; i++) {
-            Class cl =
+            Class<?> cl =
                 (classObjs[i] = Class.forName(interfaces[i], false, loader));
 
             if (!Modifier.isPublic(cl.getModifiers())) {
@@ -778,7 +776,7 @@
 
     /** map from weak(key=string) to [URL[], soft(key)] */
     private static final Map<String, Object[]> pathToURLsCache
-        = new WeakHashMap<String, Object[]>(5);
+        = new WeakHashMap<>(5);
 
     /**
      * Convert an array of URL objects into a corresponding string
@@ -1171,9 +1169,9 @@
         private void checkPermissions() {
             SecurityManager sm = System.getSecurityManager();
             if (sm != null) {           // should never be null?
-                Enumeration enum_ = permissions.elements();
+                Enumeration<Permission> enum_ = permissions.elements();
                 while (enum_.hasMoreElements()) {
-                    sm.checkPermission((Permission) enum_.nextElement());
+                    sm.checkPermission(enum_.nextElement());
                 }
             }
         }
diff --git a/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java b/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java
index b67e72b..daa0f72 100644
--- a/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java
+++ b/jdk/src/share/classes/sun/rmi/server/MarshalInputStream.java
@@ -65,14 +65,14 @@
 
     /** table to hold sun classes to which access is explicitly permitted */
     protected static Map<String, Class<?>> permittedSunClasses
-        = new HashMap<String, Class<?>>(3);
+        = new HashMap<>(3);
 
     /** if true, don't try superclass first in resolveClass() */
     private boolean skipDefaultResolveClass = false;
 
     /** callbacks to make when done() called: maps Object to Runnable */
     private final Map<Object, Runnable> doneCallbacks
-        = new HashMap<Object, Runnable>(3);
+        = new HashMap<>(3);
 
     /**
      * if true, load classes (if not available locally) only from the
@@ -110,14 +110,6 @@
     }
 
     /**
-     * Load the "rmi" native library.
-     */
-    static {
-        java.security.AccessController.doPrivileged(
-            new sun.security.action.LoadLibraryAction("rmi"));
-    }
-
-    /**
      * Create a new MarshalInputStream object.
      */
     public MarshalInputStream(InputStream in)
@@ -176,7 +168,7 @@
      * from which to load the specified class.
      * It will find, load, and return the class.
      */
-    protected Class resolveClass(ObjectStreamClass classDesc)
+    protected Class<?> resolveClass(ObjectStreamClass classDesc)
         throws IOException, ClassNotFoundException
     {
         /*
@@ -238,7 +230,7 @@
      * resolveProxyClass is extended to acquire (if present) the location
      * to determine the class loader to define the proxy class in.
      */
-    protected Class resolveProxyClass(String[] interfaces)
+    protected Class<?> resolveProxyClass(String[] interfaces)
         throws IOException, ClassNotFoundException
     {
         /*
@@ -262,13 +254,15 @@
      * Returns the first non-null class loader up the execution stack, or null
      * if only code from the null class loader is on the stack.
      */
-    private static native ClassLoader latestUserDefinedLoader();
+    private static ClassLoader latestUserDefinedLoader() {
+        return sun.misc.VM.latestUserDefinedLoader();
+    }
 
     /**
      * Fix for 4179055: Need to assist resolving sun stubs; resolve
      * class locally if it is a "permitted" sun class
      */
-    private Class checkSunClass(String className, AccessControlException e)
+    private Class<?> checkSunClass(String className, AccessControlException e)
         throws AccessControlException
     {
         // ensure that we are giving out a stub for the correct reason
diff --git a/jdk/src/share/classes/sun/rmi/server/UnicastRef.java b/jdk/src/share/classes/sun/rmi/server/UnicastRef.java
index b928cfb..c2f1df1 100644
--- a/jdk/src/share/classes/sun/rmi/server/UnicastRef.java
+++ b/jdk/src/share/classes/sun/rmi/server/UnicastRef.java
@@ -65,6 +65,7 @@
         Log.getLog("sun.rmi.client.call", "RMI",
                    AccessController.doPrivileged(
                        new GetBooleanAction("sun.rmi.client.logCalls")));
+    private static final long serialVersionUID = 8258372400816541186L;
 
     protected LiveRef ref;
 
diff --git a/jdk/src/share/classes/sun/rmi/server/UnicastRef2.java b/jdk/src/share/classes/sun/rmi/server/UnicastRef2.java
index c2abc1f..2facc1e 100644
--- a/jdk/src/share/classes/sun/rmi/server/UnicastRef2.java
+++ b/jdk/src/share/classes/sun/rmi/server/UnicastRef2.java
@@ -36,6 +36,7 @@
  * implementation of javax.management.remote.rmi.RMIConnector.
  **/
 public class UnicastRef2 extends UnicastRef {
+    private static final long serialVersionUID = 1829537514995881838L;
 
     /**
      * Create a new (empty) Unicast remote reference.
diff --git a/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java b/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java
index fe199a2..5213742 100644
--- a/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java
+++ b/jdk/src/share/classes/sun/rmi/server/UnicastServerRef.java
@@ -189,7 +189,7 @@
                                boolean permanent)
         throws RemoteException
     {
-        Class implClass = impl.getClass();
+        Class<?> implClass = impl.getClass();
         Remote stub;
 
         try {
@@ -327,7 +327,7 @@
             // marshal return value
             try {
                 ObjectOutput out = call.getResultStream(true);
-                Class rtype = method.getReturnType();
+                Class<?> rtype = method.getReturnType();
                 if (rtype != void.class) {
                     marshalValue(rtype, result, out);
                 }
@@ -537,7 +537,7 @@
         HashToMethod_Maps() {}
 
         protected Map<Long,Method> computeValue(Class<?> remoteClass) {
-            Map<Long,Method> map = new HashMap<Long,Method>();
+            Map<Long,Method> map = new HashMap<>();
             for (Class<?> cl = remoteClass;
                  cl != null;
                  cl = cl.getSuperclass())
diff --git a/jdk/src/share/classes/sun/rmi/server/Util.java b/jdk/src/share/classes/sun/rmi/server/Util.java
index c3b6b4a..2cf01ff 100644
--- a/jdk/src/share/classes/sun/rmi/server/Util.java
+++ b/jdk/src/share/classes/sun/rmi/server/Util.java
@@ -119,12 +119,12 @@
      * @throws StubNotFoundException if problem locating/creating stub or
      * creating the dynamic proxy instance
      **/
-    public static Remote createProxy(Class implClass,
+    public static Remote createProxy(Class<?> implClass,
                                      RemoteRef clientRef,
                                      boolean forceStubUse)
         throws StubNotFoundException
     {
-        Class remoteClass;
+        Class<?> remoteClass;
 
         try {
             remoteClass = getRemoteClass(implClass);
@@ -162,7 +162,7 @@
      *
      * @param remoteClass the class to obtain remote interfaces from
      */
-    private static boolean stubClassExists(Class remoteClass) {
+    private static boolean stubClassExists(Class<?> remoteClass) {
         if (!withoutStubs.containsKey(remoteClass)) {
             try {
                 Class.forName(remoteClass.getName() + "_Stub",
@@ -182,11 +182,11 @@
      * @throws ClassNotFoundException if no class is found to have a
      * remote interface
      */
-    private static Class getRemoteClass(Class cl)
+    private static Class<?> getRemoteClass(Class<?> cl)
         throws ClassNotFoundException
     {
         while (cl != null) {
-            Class[] interfaces = cl.getInterfaces();
+            Class<?>[] interfaces = cl.getInterfaces();
             for (int i = interfaces.length -1; i >= 0; i--) {
                 if (Remote.class.isAssignableFrom(interfaces[i]))
                     return cl;          // this class implements remote object
@@ -206,8 +206,8 @@
      *          any illegal remote interfaces
      * @throws  NullPointerException if remoteClass is null
      */
-    private static Class[] getRemoteInterfaces(Class remoteClass) {
-        ArrayList<Class<?>> list = new ArrayList<Class<?>>();
+    private static Class<?>[] getRemoteInterfaces(Class<?> remoteClass) {
+        ArrayList<Class<?>> list = new ArrayList<>();
         getRemoteInterfaces(list, remoteClass);
         return list.toArray(new Class<?>[list.size()]);
     }
@@ -220,15 +220,15 @@
      *          any illegal remote interfaces
      * @throws  NullPointerException if the specified class or list is null
      */
-    private static void getRemoteInterfaces(ArrayList<Class<?>> list, Class cl) {
-        Class superclass = cl.getSuperclass();
+    private static void getRemoteInterfaces(ArrayList<Class<?>> list, Class<?> cl) {
+        Class<?> superclass = cl.getSuperclass();
         if (superclass != null) {
             getRemoteInterfaces(list, superclass);
         }
 
-        Class[] interfaces = cl.getInterfaces();
+        Class<?>[] interfaces = cl.getInterfaces();
         for (int i = 0; i < interfaces.length; i++) {
-            Class intf = interfaces[i];
+            Class<?> intf = interfaces[i];
             /*
              * If it is a remote interface (if it extends from
              * java.rmi.Remote) and is not already in the list,
@@ -272,7 +272,7 @@
      * the stub class is initiated from class loader of the specified class
      * (which may be the bootstrap class loader).
      **/
-    private static RemoteStub createStub(Class remoteClass, RemoteRef ref)
+    private static RemoteStub createStub(Class<?> remoteClass, RemoteRef ref)
         throws StubNotFoundException
     {
         String stubname = remoteClass.getName() + "_Stub";
@@ -285,7 +285,7 @@
         try {
             Class<?> stubcl =
                 Class.forName(stubname, false, remoteClass.getClassLoader());
-            Constructor cons = stubcl.getConstructor(stubConsParamTypes);
+            Constructor<?> cons = stubcl.getConstructor(stubConsParamTypes);
             return (RemoteStub) cons.newInstance(new Object[] { ref });
 
         } catch (ClassNotFoundException e) {
@@ -315,7 +315,7 @@
     static Skeleton createSkeleton(Remote object)
         throws SkeletonNotFoundException
     {
-        Class cl;
+        Class<?> cl;
         try {
             cl = getRemoteClass(object.getClass());
         } catch (ClassNotFoundException ex ) {
@@ -327,7 +327,7 @@
         // now try to load the skeleton based ont he name of the class
         String skelname = cl.getName() + "_Skel";
         try {
-            Class skelcl = Class.forName(skelname, false, cl.getClassLoader());
+            Class<?> skelcl = Class.forName(skelname, false, cl.getClassLoader());
 
             return (Skeleton)skelcl.newInstance();
         } catch (ClassNotFoundException ex) {
@@ -391,12 +391,12 @@
     private static String getMethodNameAndDescriptor(Method m) {
         StringBuffer desc = new StringBuffer(m.getName());
         desc.append('(');
-        Class[] paramTypes = m.getParameterTypes();
+        Class<?>[] paramTypes = m.getParameterTypes();
         for (int i = 0; i < paramTypes.length; i++) {
             desc.append(getTypeDescriptor(paramTypes[i]));
         }
         desc.append(')');
-        Class returnType = m.getReturnType();
+        Class<?> returnType = m.getReturnType();
         if (returnType == void.class) { // optimization: handle void here
             desc.append('V');
         } else {
@@ -409,7 +409,7 @@
      * Get the descriptor of a particular type, as appropriate for either
      * a parameter or return type in a method descriptor.
      */
-    private static String getTypeDescriptor(Class type) {
+    private static String getTypeDescriptor(Class<?> type) {
         if (type.isPrimitive()) {
             if (type == int.class) {
                 return "I";
@@ -454,7 +454,7 @@
      * top-level type (and perhaps other enclosing types), the
      * separator will be '$', etc.
      **/
-    public static String getUnqualifiedName(Class c) {
+    public static String getUnqualifiedName(Class<?> c) {
         String binaryName = c.getName();
         return binaryName.substring(binaryName.lastIndexOf('.') + 1);
     }
diff --git a/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java b/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java
index 1aff576..734e4ff 100644
--- a/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java
+++ b/jdk/src/share/classes/sun/rmi/server/WeakClassHashMap.java
@@ -46,8 +46,7 @@
  **/
 public abstract class WeakClassHashMap<V> {
 
-    private Map<Class<?>,ValueCell<V>> internalMap =
-        new WeakHashMap<Class<?>,ValueCell<V>>();
+    private Map<Class<?>,ValueCell<V>> internalMap = new WeakHashMap<>();
 
     protected WeakClassHashMap() { }
 
diff --git a/jdk/src/share/classes/sun/rmi/transport/ConnectionInputStream.java b/jdk/src/share/classes/sun/rmi/transport/ConnectionInputStream.java
index f79482b..2c2a81f 100644
--- a/jdk/src/share/classes/sun/rmi/transport/ConnectionInputStream.java
+++ b/jdk/src/share/classes/sun/rmi/transport/ConnectionInputStream.java
@@ -43,7 +43,7 @@
     private boolean dgcAckNeeded = false;
 
     /** Hashtable mapping Endpoints to lists of LiveRefs to register */
-    private Map incomingRefTable = new HashMap(5);
+    private Map<Endpoint, List<LiveRef>> incomingRefTable = new HashMap<>(5);
 
     /** identifier for gc ack*/
     private UID ackID;
@@ -70,10 +70,10 @@
         Endpoint ep = ref.getEndpoint();
 
         // check whether endpoint is already in the hashtable
-        List refList = (List) incomingRefTable.get(ep);
+        List<LiveRef> refList = incomingRefTable.get(ep);
 
         if (refList == null) {
-            refList = new ArrayList();
+            refList = new ArrayList<LiveRef>();
             incomingRefTable.put(ep, refList);
         }
 
@@ -89,13 +89,9 @@
      */
     void registerRefs() throws IOException {
         if (!incomingRefTable.isEmpty()) {
-            Set entrySet = incomingRefTable.entrySet();
-            Iterator iter = entrySet.iterator();
-            while (iter.hasNext()) {
-                Map.Entry entry = (Map.Entry) iter.next();
-                Endpoint ep = (Endpoint) entry.getKey();
-                List refList = (List) entry.getValue();
-                DGCClient.registerRefs(ep, refList);
+            for (Map.Entry<Endpoint, List<LiveRef>> entry :
+                     incomingRefTable.entrySet()) {
+                DGCClient.registerRefs(entry.getKey(), entry.getValue());
             }
         }
     }
diff --git a/jdk/src/share/classes/sun/rmi/transport/DGCAckHandler.java b/jdk/src/share/classes/sun/rmi/transport/DGCAckHandler.java
index 2735457..7c757dd 100644
--- a/jdk/src/share/classes/sun/rmi/transport/DGCAckHandler.java
+++ b/jdk/src/share/classes/sun/rmi/transport/DGCAckHandler.java
@@ -78,7 +78,7 @@
         Collections.synchronizedMap(new HashMap<UID,DGCAckHandler>());
 
     private final UID id;
-    private List<Object> objList = new ArrayList<Object>(); // null if released
+    private List<Object> objList = new ArrayList<>(); // null if released
     private Future<?> task = null;
 
     /**
diff --git a/jdk/src/share/classes/sun/rmi/transport/DGCClient.java b/jdk/src/share/classes/sun/rmi/transport/DGCClient.java
index 039935c..c6e3266 100644
--- a/jdk/src/share/classes/sun/rmi/transport/DGCClient.java
+++ b/jdk/src/share/classes/sun/rmi/transport/DGCClient.java
@@ -125,7 +125,7 @@
      * All of the LiveRefs in the list must be for remote objects at the
      * given endpoint.
      */
-    static void registerRefs(Endpoint ep, List refs) {
+    static void registerRefs(Endpoint ep, List<LiveRef> refs) {
         /*
          * Look up the given endpoint and register the refs with it.
          * The retrieved entry may get removed from the global endpoint
@@ -176,9 +176,9 @@
         private DGC dgc;
 
         /** table of refs held for endpoint: maps LiveRef to RefEntry */
-        private Map refTable = new HashMap(5);
+        private Map<LiveRef, RefEntry> refTable = new HashMap<>(5);
         /** set of RefEntry instances from last (failed) dirty call */
-        private Set invalidRefs = new HashSet(5);
+        private Set<RefEntry> invalidRefs = new HashSet<>(5);
 
         /** true if this entry has been removed from the global table */
         private boolean removed = false;
@@ -200,12 +200,12 @@
         private boolean interruptible = false;
 
         /** reference queue for phantom references */
-        private ReferenceQueue refQueue = new ReferenceQueue();
+        private ReferenceQueue<LiveRef> refQueue = new ReferenceQueue<>();
         /** set of clean calls that need to be made */
-        private Set pendingCleans = new HashSet(5);
+        private Set<CleanRequest> pendingCleans = new HashSet<>(5);
 
         /** global endpoint table: maps Endpoint to EndpointEntry */
-        private static Map endpointTable = new HashMap(5);
+        private static Map<Endpoint,EndpointEntry> endpointTable = new HashMap<>(5);
         /** handle for GC latency request (for future cancellation) */
         private static GC.LatencyRequest gcLatencyRequest = null;
 
@@ -215,7 +215,7 @@
          */
         public static EndpointEntry lookup(Endpoint ep) {
             synchronized (endpointTable) {
-                EndpointEntry entry = (EndpointEntry) endpointTable.get(ep);
+                EndpointEntry entry = endpointTable.get(ep);
                 if (entry == null) {
                     entry = new EndpointEntry(ep);
                     endpointTable.put(ep, entry);
@@ -260,10 +260,10 @@
          *
          * This method must NOT be called while synchronized on this entry.
          */
-        public boolean registerRefs(List refs) {
+        public boolean registerRefs(List<LiveRef> refs) {
             assert !Thread.holdsLock(this);
 
-            Set refsToDirty = null;     // entries for refs needing dirty
+            Set<RefEntry> refsToDirty = null;     // entries for refs needing dirty
             long sequenceNum;           // sequence number for dirty call
 
             synchronized (this) {
@@ -271,18 +271,18 @@
                     return false;
                 }
 
-                Iterator iter = refs.iterator();
+                Iterator<LiveRef> iter = refs.iterator();
                 while (iter.hasNext()) {
-                    LiveRef ref = (LiveRef) iter.next();
+                    LiveRef ref = iter.next();
                     assert ref.getEndpoint().equals(endpoint);
 
-                    RefEntry refEntry = (RefEntry) refTable.get(ref);
+                    RefEntry refEntry = refTable.get(ref);
                     if (refEntry == null) {
                         LiveRef refClone = (LiveRef) ref.clone();
                         refEntry = new RefEntry(refClone);
                         refTable.put(refClone, refEntry);
                         if (refsToDirty == null) {
-                            refsToDirty = new HashSet(5);
+                            refsToDirty = new HashSet<>(5);
                         }
                         refsToDirty.add(refEntry);
                     }
@@ -345,7 +345,7 @@
          *
          * This method must NOT be called while synchronized on this entry.
          */
-        private void makeDirtyCall(Set refEntries, long sequenceNum) {
+        private void makeDirtyCall(Set<RefEntry> refEntries, long sequenceNum) {
             assert !Thread.holdsLock(this);
 
             ObjID[] ids;
@@ -443,9 +443,9 @@
                          * refs, so that clean calls for them in the future
                          * will be strong.
                          */
-                        Iterator iter = refEntries.iterator();
+                        Iterator<RefEntry> iter = refEntries.iterator();
                         while (iter.hasNext()) {
-                            RefEntry refEntry = (RefEntry) iter.next();
+                            RefEntry refEntry = iter.next();
                             refEntry.markDirtyFailed();
                         }
                     }
@@ -497,7 +497,7 @@
                     long timeToWait;
                     RefEntry.PhantomLiveRef phantom = null;
                     boolean needRenewal = false;
-                    Set refsToDirty = null;
+                    Set<RefEntry> refsToDirty = null;
                     long sequenceNum = Long.MIN_VALUE;
 
                     synchronized (EndpointEntry.this) {
@@ -564,7 +564,7 @@
                             needRenewal = true;
                             if (!invalidRefs.isEmpty()) {
                                 refsToDirty = invalidRefs;
-                                invalidRefs = new HashSet(5);
+                                invalidRefs = new HashSet<>(5);
                             }
                             sequenceNum = getNextSequenceNum();
                         }
@@ -594,8 +594,8 @@
         private void processPhantomRefs(RefEntry.PhantomLiveRef phantom) {
             assert Thread.holdsLock(this);
 
-            Set strongCleans = null;
-            Set normalCleans = null;
+            Set<RefEntry> strongCleans = null;
+            Set<RefEntry> normalCleans = null;
 
             do {
                 RefEntry refEntry = phantom.getRefEntry();
@@ -603,12 +603,12 @@
                 if (refEntry.isRefSetEmpty()) {
                     if (refEntry.hasDirtyFailed()) {
                         if (strongCleans == null) {
-                            strongCleans = new HashSet(5);
+                            strongCleans = new HashSet<>(5);
                         }
                         strongCleans.add(refEntry);
                     } else {
                         if (normalCleans == null) {
-                            normalCleans = new HashSet(5);
+                            normalCleans = new HashSet<>(5);
                         }
                         normalCleans.add(refEntry);
                     }
@@ -659,9 +659,9 @@
         private void makeCleanCalls() {
             assert !Thread.holdsLock(this);
 
-            Iterator iter = pendingCleans.iterator();
+            Iterator<CleanRequest> iter = pendingCleans.iterator();
             while (iter.hasNext()) {
-                CleanRequest request = (CleanRequest) iter.next();
+                CleanRequest request = iter.next();
                 try {
                     dgc.clean(request.objIDs, request.sequenceNum, vmid,
                               request.strong);
@@ -683,11 +683,11 @@
          * Create an array of ObjIDs (needed for the DGC remote calls)
          * from the ids in the given set of refs.
          */
-        private static ObjID[] createObjIDArray(Set refEntries) {
+        private static ObjID[] createObjIDArray(Set<RefEntry> refEntries) {
             ObjID[] ids = new ObjID[refEntries.size()];
-            Iterator iter = refEntries.iterator();
+            Iterator<RefEntry> iter = refEntries.iterator();
             for (int i = 0; i < ids.length; i++) {
-                ids[i] = ((RefEntry) iter.next()).getRef().getObjID();
+                ids[i] = iter.next().getRef().getObjID();
             }
             return ids;
         }
@@ -704,7 +704,7 @@
             /** LiveRef value for this entry (not a registered instance) */
             private LiveRef ref;
             /** set of phantom references to registered instances */
-            private Set refSet = new HashSet(5);
+            private Set<PhantomLiveRef> refSet = new HashSet<>(5);
             /** true if a dirty call containing this ref has failed */
             private boolean dirtyFailed = false;
 
@@ -792,7 +792,7 @@
              * used to detect when the LiveRef becomes permanently
              * unreachable in this VM.
              */
-            private class PhantomLiveRef extends PhantomReference {
+            private class PhantomLiveRef extends PhantomReference<LiveRef> {
 
                 public PhantomLiveRef(LiveRef ref) {
                     super(ref, EndpointEntry.this.refQueue);
diff --git a/jdk/src/share/classes/sun/rmi/transport/DGCImpl.java b/jdk/src/share/classes/sun/rmi/transport/DGCImpl.java
index caaa381..5e59cb1 100644
--- a/jdk/src/share/classes/sun/rmi/transport/DGCImpl.java
+++ b/jdk/src/share/classes/sun/rmi/transport/DGCImpl.java
@@ -84,7 +84,7 @@
     /** remote implementation of DGC interface for this VM */
     private static DGCImpl dgc;
     /** table that maps VMID to LeaseInfo */
-    private Map<VMID,LeaseInfo> leaseTable = new HashMap<VMID,LeaseInfo>();
+    private Map<VMID,LeaseInfo> leaseTable = new HashMap<>();
     /** checks for lease expiration */
     private Future<?> checker = null;
 
@@ -236,7 +236,7 @@
         long time = System.currentTimeMillis();
 
         /* List of vmids that need to be removed from the leaseTable */
-        List<LeaseInfo> toUnregister = new ArrayList<LeaseInfo>();
+        List<LeaseInfo> toUnregister = new ArrayList<>();
 
         /* Build a list of leaseInfo objects that need to have
          * targets removed from their notifySet.  Remove expired
@@ -313,7 +313,7 @@
     private static class LeaseInfo {
         VMID vmid;
         long expiration;
-        Set<Target> notifySet = new HashSet<Target>();
+        Set<Target> notifySet = new HashSet<>();
 
         LeaseInfo(VMID vmid, long lease) {
             this.vmid = vmid;
diff --git a/jdk/src/share/classes/sun/rmi/transport/ObjectTable.java b/jdk/src/share/classes/sun/rmi/transport/ObjectTable.java
index 8c3e5cf..97956cc 100644
--- a/jdk/src/share/classes/sun/rmi/transport/ObjectTable.java
+++ b/jdk/src/share/classes/sun/rmi/transport/ObjectTable.java
@@ -62,9 +62,9 @@
 
     /** tables mapping to Target, keyed from ObjectEndpoint and impl object */
     private static final Map<ObjectEndpoint,Target> objTable =
-        new HashMap<ObjectEndpoint,Target>();
+        new HashMap<>();
     private static final Map<WeakRef,Target> implTable =
-        new HashMap<WeakRef,Target>();
+        new HashMap<>();
 
     /**
      * lock guarding keepAliveCount, reaper, and gcLatencyRequest.
@@ -79,7 +79,7 @@
     private static Thread reaper = null;
 
     /** queue notified when weak refs in the table are cleared */
-    static final ReferenceQueue reapQueue = new ReferenceQueue();
+    static final ReferenceQueue<Object> reapQueue = new ReferenceQueue<>();
 
     /** handle for GC latency request (for future cancellation) */
     private static GC.LatencyRequest gcLatencyRequest = null;
diff --git a/jdk/src/share/classes/sun/rmi/transport/StreamRemoteCall.java b/jdk/src/share/classes/sun/rmi/transport/StreamRemoteCall.java
index f0c3c29..d6d6ee8 100644
--- a/jdk/src/share/classes/sun/rmi/transport/StreamRemoteCall.java
+++ b/jdk/src/share/classes/sun/rmi/transport/StreamRemoteCall.java
@@ -199,6 +199,7 @@
     /**
      * Do whatever it takes to execute the call.
      */
+    @SuppressWarnings("fallthrough")
     public void executeCall() throws Exception {
         byte returnType;
 
@@ -252,6 +253,7 @@
             } else {
                 throw new UnmarshalException("Return type not Exception");
             }
+            // Exception is thrown before fallthrough can occur
         default:
             if (Transport.transportLog.isLoggable(Log.BRIEF)) {
                 Transport.transportLog.log(Log.BRIEF,
diff --git a/jdk/src/share/classes/sun/rmi/transport/Target.java b/jdk/src/share/classes/sun/rmi/transport/Target.java
index f784064..bd1aded 100644
--- a/jdk/src/share/classes/sun/rmi/transport/Target.java
+++ b/jdk/src/share/classes/sun/rmi/transport/Target.java
@@ -53,9 +53,10 @@
     /** stub for remote object */
     private final Remote stub;
     /** set of clients that hold references to this target */
-    private final Vector refSet = new Vector();
+    private final Vector<VMID> refSet = new Vector<>();
     /** table that maps client endpoints to sequence numbers */
-    private final Hashtable sequenceTable = new Hashtable(5);
+    private final Hashtable<VMID, SequenceEntry> sequenceTable =
+        new Hashtable<>(5);
     /** access control context in which target was created */
     private final AccessControlContext acc;
     /** context class loader in which target was created */
@@ -241,7 +242,7 @@
      */
     synchronized void referenced(long sequenceNum, VMID vmid) {
         // check sequence number for vmid
-        SequenceEntry entry = (SequenceEntry) sequenceTable.get(vmid);
+        SequenceEntry entry = sequenceTable.get(vmid);
         if (entry == null) {
             sequenceTable.put(vmid, new SequenceEntry(sequenceNum));
         } else if (entry.sequenceNum < sequenceNum) {
@@ -280,7 +281,7 @@
     synchronized void unreferenced(long sequenceNum, VMID vmid, boolean strong)
     {
         // check sequence number for vmid
-        SequenceEntry entry = (SequenceEntry) sequenceTable.get(vmid);
+        SequenceEntry entry = sequenceTable.get(vmid);
         if (entry == null || entry.sequenceNum > sequenceNum) {
             // late clean call; ignore
             return;
@@ -366,9 +367,9 @@
              */
             unpinImpl();
             DGCImpl dgc = DGCImpl.getDGCImpl();
-            Enumeration enum_ = refSet.elements();
+            Enumeration<VMID> enum_ = refSet.elements();
             while (enum_.hasMoreElements()) {
-                VMID vmid = (VMID) enum_.nextElement();
+                VMID vmid = enum_.nextElement();
                 dgc.unregisterTarget(vmid, this);
             }
             return true;
diff --git a/jdk/src/share/classes/sun/rmi/transport/Transport.java b/jdk/src/share/classes/sun/rmi/transport/Transport.java
index 82a3fe7..bfafe98 100644
--- a/jdk/src/share/classes/sun/rmi/transport/Transport.java
+++ b/jdk/src/share/classes/sun/rmi/transport/Transport.java
@@ -62,7 +62,7 @@
         Log.getLog("sun.rmi.transport.misc", "transport", Transport.logLevel);
 
     /** References the current transport when a call is being serviced */
-    private static final ThreadLocal currentTransport = new ThreadLocal();
+    private static final ThreadLocal<Transport> currentTransport = new ThreadLocal<>();
 
     /** ObjID for DGCImpl */
     private static final ObjID dgcID = new ObjID(ObjID.DGC_ID);
@@ -104,7 +104,7 @@
      * returns null.
      **/
     static Transport currentTransport() {
-        return (Transport) currentTransport.get();
+        return currentTransport.get();
     }
 
     /**
diff --git a/jdk/src/share/classes/sun/rmi/transport/WeakRef.java b/jdk/src/share/classes/sun/rmi/transport/WeakRef.java
index 98bd0db..c20a8a1 100644
--- a/jdk/src/share/classes/sun/rmi/transport/WeakRef.java
+++ b/jdk/src/share/classes/sun/rmi/transport/WeakRef.java
@@ -41,7 +41,7 @@
  * @author  Ann Wollrath
  * @author  Peter Jones
  */
-class WeakRef extends WeakReference {
+class WeakRef extends WeakReference<Object> {
 
     /** value of the referent's "identity" hash code */
     private int hashValue;
@@ -60,7 +60,7 @@
     /**
      * Create a new WeakRef to the given object, registered with a queue.
      */
-    public WeakRef(Object obj, ReferenceQueue q) {
+    public WeakRef(Object obj, ReferenceQueue<Object> q) {
         super(obj, q);
         setHashValue(obj);      // cache object's "identity" hash code
     }
diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java b/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
index 25a84fa..918986d 100644
--- a/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/CGIHandler.java
@@ -33,6 +33,7 @@
  * in a client's request.
  */
 class CGIClientException extends Exception {
+    private static final long serialVersionUID = 8147981687059865216L;
 
     public CGIClientException(String s) {
         super(s);
@@ -44,6 +45,8 @@
  */
 class CGIServerException extends Exception {
 
+    private static final long serialVersionUID = 6928425456704527017L;
+
     public CGIServerException(String s) {
         super(s);
     }
@@ -111,9 +114,9 @@
     };
 
     /* construct table mapping command strings to handlers */
-    private static Hashtable commandLookup;
+    private static Hashtable<String, CGICommandHandler> commandLookup;
     static {
-        commandLookup = new Hashtable();
+        commandLookup = new Hashtable<>();
         for (int i = 0; i < commands.length; ++ i)
             commandLookup.put(commands[i].getName(), commands[i]);
     }
@@ -140,7 +143,7 @@
                 param = QueryString.substring(delim + 1);
             }
             CGICommandHandler handler =
-                (CGICommandHandler) commandLookup.get(command);
+                commandLookup.get(command);
             if (handler != null)
                 try {
                     handler.execute(param);
@@ -200,7 +203,7 @@
 
 /**
  * "forward" command: Forward request body to local port on the server,
- * and send reponse back to client.
+ * and send response back to client.
  */
 final class CGIForwardCommand implements CGICommandHandler {
 
@@ -208,6 +211,11 @@
         return "forward";
     }
 
+    @SuppressWarnings("deprecation")
+    private String getLine (DataInputStream socketIn) throws IOException {
+        return socketIn.readLine();
+    }
+
     public void execute(String param) throws CGIClientException, CGIServerException
     {
         if (!CGIHandler.RequestMethod.equals("POST"))
@@ -276,7 +284,7 @@
         int responseContentLength = -1;
         do {
             try {
-                line = socketIn.readLine();
+                line = getLine(socketIn);
             } catch (IOException e) {
                 throw new CGIServerException("error reading from server");
             }
@@ -285,8 +293,8 @@
                     "unexpected EOF reading server response");
 
             if (line.toLowerCase().startsWith(key)) {
-                if (contentLengthFound)
-                    ; // what would we want to do in this case??
+                // if contentLengthFound is true
+                // we should probably do something here
                 responseContentLength =
                     Integer.parseInt(line.substring(key.length()).trim());
                 contentLengthFound = true;
diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java b/jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
index dc320c8..773493e 100644
--- a/jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/HttpInputStream.java
@@ -70,8 +70,8 @@
                 throw new EOFException();
 
             if (line.toLowerCase().startsWith(key)) {
-                if (contentLengthFound)
-                    ; // what would we want to do in this case??
+                // if contentLengthFound is true
+                // we should probably do something here
                 bytesLeft =
                     Integer.parseInt(line.substring(key.length()).trim());
                 contentLengthFound = true;
diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java b/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java
index b599e1b..0d790d5 100644
--- a/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/HttpSendSocket.java
@@ -203,7 +203,7 @@
 
                 message += "HttpSendSocket.readNotify: response body: ";
                 try {
-                    DataInputStream din = new DataInputStream(in);
+                    BufferedReader din = new BufferedReader(new InputStreamReader(in));
                     String line;
                     while ((line = din.readLine()) != null)
                         message += line + lineSeparator;
diff --git a/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java b/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java
index 2a2bf2a..2caf6ac 100644
--- a/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java
+++ b/jdk/src/share/classes/sun/rmi/transport/proxy/RMIMasterSocketFactory.java
@@ -74,20 +74,21 @@
             "sun.rmi.transport.proxy.eagerHttpFallback")).booleanValue();
 
     /** table of hosts successfully connected to and the factory used */
-    private Hashtable successTable = new Hashtable();
+    private Hashtable<String, RMISocketFactory> successTable =
+        new Hashtable<>();
 
     /** maximum number of hosts to remember successful connection to */
     private static final int MaxRememberedHosts = 64;
 
     /** list of the hosts in successTable in initial connection order */
-    private Vector hostList = new Vector(MaxRememberedHosts);
+    private Vector<String> hostList = new Vector<>(MaxRememberedHosts);
 
-    /** default factory to initally use for direct socket connection */
+    /** default factory for initial use for direct socket connection */
     protected RMISocketFactory initialFactory = new RMIDirectSocketFactory();
 
     /** ordered list of factories to try as alternate connection
       * mechanisms if a direct socket connections fails */
-    protected Vector altFactoryList;
+    protected Vector<RMISocketFactory> altFactoryList;
 
     /**
      * Create a RMIMasterSocketFactory object.  Establish order of
@@ -95,7 +96,7 @@
      * socket connection fails.
      */
     public RMIMasterSocketFactory() {
-        altFactoryList = new Vector(2);
+        altFactoryList = new Vector<>(2);
         boolean setFactories = false;
 
         try {
@@ -152,7 +153,7 @@
          * If we remember successfully connecting to this host before,
          * use the same factory.
          */
-        factory = (RMISocketFactory) successTable.get(host);
+        factory = successTable.get(host);
         if (factory != null) {
             if (proxyLog.isLoggable(Log.BRIEF)) {
                 proxyLog.log(Log.BRIEF,
@@ -207,9 +208,7 @@
 
             return initialSocket;
 
-        } catch (UnknownHostException e) {
-            initialFailure = e;
-        } catch (NoRouteToHostException e) {
+        } catch (UnknownHostException | NoRouteToHostException e) {
             initialFailure = e;
         } catch (SocketException e) {
             if (eagerHttpFallback) {
@@ -227,22 +226,20 @@
 
                 // Finally, try any alternate connection mechanisms.
                 for (int i = 0; i < altFactoryList.size(); ++ i) {
-                    factory = (RMISocketFactory) altFactoryList.elementAt(i);
-                    try {
-                        if (proxyLog.isLoggable(Log.BRIEF)) {
-                            proxyLog.log(Log.BRIEF,
-                                "trying with factory: " + factory);
-                        }
-
+                    factory = altFactoryList.elementAt(i);
+                    if (proxyLog.isLoggable(Log.BRIEF)) {
+                        proxyLog.log(Log.BRIEF,
+                            "trying with factory: " + factory);
+                    }
+                    try (Socket testSocket =
+                            factory.createSocket(host, port)) {
                         // For HTTP connections, the output (POST request) must
                         // be sent before we verify a successful connection.
                         // So, sacrifice a socket for the sake of testing...
                         // The following sequence should verify a successful
                         // HTTP connection if no IOException is thrown.
-                        Socket testSocket = factory.createSocket(host, port);
                         InputStream in = testSocket.getInputStream();
                         int b = in.read(); // probably -1 for EOF...
-                        testSocket.close();
                     } catch (IOException ex) {
                         if (proxyLog.isLoggable(Log.BRIEF)) {
                             proxyLog.log(Log.BRIEF, "factory failed: ", ex);
@@ -276,9 +273,7 @@
                 }
                 // if connector ever does get socket, it won't be used
                 connector.notUsed();
-            } catch (UnknownHostException e) {
-                initialFailure = e;
-            } catch (NoRouteToHostException e) {
+            } catch (UnknownHostException | NoRouteToHostException e) {
                 initialFailure = e;
             } catch (SocketException e) {
                 if (eagerHttpFallback) {
diff --git a/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java b/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java
index a3b6696..47b7143 100644
--- a/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java
+++ b/jdk/src/share/classes/sun/rmi/transport/tcp/ConnectionMultiplexer.java
@@ -85,7 +85,7 @@
     private DataOutputStream dataOut;
 
     /** table holding currently open connection IDs and related info */
-    private Hashtable connectionTable = new Hashtable(7);
+    private Hashtable<Integer, MultiplexConnectionInfo> connectionTable = new Hashtable<>(7);
 
     /** number of currently open connections */
     private int numConnections = 0;
@@ -131,7 +131,6 @@
     {
         try {
             int op, id, length;
-            Integer idObj;
             MultiplexConnectionInfo info;
 
             while (true) {
@@ -148,9 +147,7 @@
                         multiplexLog.log(Log.VERBOSE, "operation  OPEN " + id);
                     }
 
-                    idObj = new Integer(id);
-                    info =
-                        (MultiplexConnectionInfo) connectionTable.get(idObj);
+                    info = connectionTable.get(id);
                     if (info != null)
                         throw new IOException(
                             "OPEN: Connection ID already exists");
@@ -158,7 +155,7 @@
                     info.in = new MultiplexInputStream(this, info, 2048);
                     info.out = new MultiplexOutputStream(this, info, 2048);
                     synchronized (connectionTable) {
-                        connectionTable.put(idObj, info);
+                        connectionTable.put(id, info);
                         ++ numConnections;
                     }
                     sun.rmi.transport.Connection conn;
@@ -174,9 +171,7 @@
                         multiplexLog.log(Log.VERBOSE, "operation  CLOSE " + id);
                     }
 
-                    idObj = new Integer(id);
-                    info =
-                        (MultiplexConnectionInfo) connectionTable.get(idObj);
+                    info = connectionTable.get(id);
                     if (info == null)
                         throw new IOException(
                             "CLOSE: Invalid connection ID");
@@ -185,7 +180,7 @@
                     if (!info.closed)
                         sendCloseAck(info);
                     synchronized (connectionTable) {
-                        connectionTable.remove(idObj);
+                        connectionTable.remove(id);
                         -- numConnections;
                     }
                     break;
@@ -199,9 +194,7 @@
                             "operation  CLOSEACK " + id);
                     }
 
-                    idObj = new Integer(id);
-                    info =
-                        (MultiplexConnectionInfo) connectionTable.get(idObj);
+                    info = connectionTable.get(id);
                     if (info == null)
                         throw new IOException(
                             "CLOSEACK: Invalid connection ID");
@@ -211,7 +204,7 @@
                     info.in.disconnect();
                     info.out.disconnect();
                     synchronized (connectionTable) {
-                        connectionTable.remove(idObj);
+                        connectionTable.remove(id);
                         -- numConnections;
                     }
                     break;
@@ -219,9 +212,7 @@
                 // remote endpoint declaring additional bytes receivable
                 case REQUEST:
                     id = dataIn.readUnsignedShort();
-                    idObj = new Integer(id);
-                    info =
-                        (MultiplexConnectionInfo) connectionTable.get(idObj);
+                    info = connectionTable.get(id);
                     if (info == null)
                         throw new IOException(
                             "REQUEST: Invalid connection ID");
@@ -238,9 +229,7 @@
                 // remote endpoint transmitting data packet
                 case TRANSMIT:
                     id = dataIn.readUnsignedShort();
-                    idObj = new Integer(id);
-                    info =
-                        (MultiplexConnectionInfo) connectionTable.get(idObj);
+                    info = connectionTable.get(id);
                     if (info == null)
                         throw new IOException("SEND: Invalid connection ID");
                     length = dataIn.readInt();
@@ -273,7 +262,6 @@
         // If all possible 32768 IDs are used,
         // this method will block searching for a new ID forever.
         int id;
-        Integer idObj;
         do {
             lastID = (++ lastID) & 0x7FFF;
             id = lastID;
@@ -283,8 +271,7 @@
             // two endpoints.
             if (orig)
                 id |= 0x8000;
-            idObj = new Integer(id);
-        } while (connectionTable.get(idObj) != null);
+        } while (connectionTable.get(id) != null);
 
         // create multiplexing streams and bookkeeping information
         MultiplexConnectionInfo info = new MultiplexConnectionInfo(id);
@@ -298,7 +285,7 @@
             if (numConnections >= maxConnections)
                 throw new IOException("Cannot exceed " + maxConnections +
                     " simultaneous multiplexed connections");
-            connectionTable.put(idObj, info);
+            connectionTable.put(id, info);
             ++ numConnections;
         }
 
@@ -331,10 +318,10 @@
                 return;
             alive = false;
 
-            Enumeration enum_ = connectionTable.elements();
+            Enumeration<MultiplexConnectionInfo> enum_ =
+                    connectionTable.elements();
             while (enum_.hasMoreElements()) {
-                MultiplexConnectionInfo info =
-                    (MultiplexConnectionInfo) enum_.nextElement();
+                MultiplexConnectionInfo info = enum_.nextElement();
                 info.in.disconnect();
                 info.out.disconnect();
             }
diff --git a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPChannel.java b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPChannel.java
index e3aa730..7ab872c 100644
--- a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPChannel.java
+++ b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPChannel.java
@@ -64,7 +64,7 @@
     private final TCPTransport tr;
     /** list of cached connections */
     private final List<TCPConnection> freeList =
-        new ArrayList<TCPConnection>();
+        new ArrayList<>();
     /** frees cached connections that have expired (guarded by freeList) */
     private Future<?> reaper = null;
 
@@ -480,7 +480,7 @@
     private TCPTransport transport;
 
     /** queue of connections to be accepted */
-    private List<Connection> queue = new ArrayList<Connection>();
+    private List<Connection> queue = new ArrayList<>();
 
     /** thread ID counter */
     private static int threadNum = 0;
diff --git a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
index 5897877..4af3405 100644
--- a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
+++ b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java
@@ -148,7 +148,7 @@
     // TBD: should this be a weak hash table?
     private static final
         Map<TCPEndpoint,LinkedList<TCPEndpoint>> localEndpoints =
-        new HashMap<TCPEndpoint,LinkedList<TCPEndpoint>>();
+        new HashMap<>();
 
     /**
      * Create an endpoint for a specified host and port.
@@ -623,10 +623,9 @@
             try {
                 TCPEndpoint.shedConnectionCaches();
                 // REMIND: should we retry createSocket?
-            } catch (OutOfMemoryError mem) {
+            } catch (OutOfMemoryError | Exception mem) {
                 // don't quit if out of memory
-            } catch (Exception ex) {
-                // don't quit if shed fails non-catastrophically
+                // or shed fails non-catastrophically
             }
 
             throw new ConnectIOException("Exception creating connection to: " +
diff --git a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java
index a22c720..8b523df 100644
--- a/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java
+++ b/jdk/src/share/classes/sun/rmi/transport/tcp/TCPTransport.java
@@ -28,6 +28,7 @@
 import java.lang.ref.SoftReference;
 import java.lang.ref.WeakReference;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
@@ -119,7 +120,7 @@
 
     /** client host for the current thread's connection */
     private static final ThreadLocal<ConnectionHandler>
-        threadConnectionHandler = new ThreadLocal<ConnectionHandler>();
+        threadConnectionHandler = new ThreadLocal<>();
 
     /** endpoints for this transport */
     private final LinkedList<TCPEndpoint> epList;
@@ -129,7 +130,7 @@
     private ServerSocket server = null;
     /** table mapping endpoints to channels */
     private final Map<TCPEndpoint,Reference<TCPChannel>> channelTable =
-        new WeakHashMap<TCPEndpoint,Reference<TCPChannel>>();
+        new WeakHashMap<>();
 
     static final RMISocketFactory defaultSocketFactory =
         RMISocketFactory.getDefaultSocketFactory();
@@ -462,8 +463,10 @@
                             return;
                         }
                         // continue loop
-                    } else {
+                    } else if (t instanceof Error) {
                         throw (Error) t;
+                    } else {
+                        throw new UndeclaredThrowableException(t);
                     }
                 }
             }
diff --git a/jdk/src/share/classes/sun/security/krb5/Config.java b/jdk/src/share/classes/sun/security/krb5/Config.java
index 179fa70..e558eb5 100644
--- a/jdk/src/share/classes/sun/security/krb5/Config.java
+++ b/jdk/src/share/classes/sun/security/krb5/Config.java
@@ -116,7 +116,12 @@
 
     private static boolean isMacosLionOrBetter() {
         // split the "10.x.y" version number
-        String osVersion = System.getProperty("os.version");
+        String osname = getProperty("os.name");
+        if (!osname.contains("OS X")) {
+            return false;
+        }
+
+        String osVersion = getProperty("os.version");
         String[] fragments = osVersion.split("\\.");
 
         // sanity check the "10." part of the version
@@ -141,20 +146,14 @@
         /*
          * If either one system property is specified, we throw exception.
          */
-        String tmp =
-            java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction
-                    ("java.security.krb5.kdc"));
+        String tmp = getProperty("java.security.krb5.kdc");
         if (tmp != null) {
             // The user can specify a list of kdc hosts separated by ":"
             defaultKDC = tmp.replace(':', ' ');
         } else {
             defaultKDC = null;
         }
-        defaultRealm =
-            java.security.AccessController.doPrivileged(
-                new sun.security.action.GetPropertyAction
-                    ("java.security.krb5.realm"));
+        defaultRealm = getProperty("java.security.krb5.realm");
         if ((defaultKDC == null && defaultRealm != null) ||
             (defaultRealm == null && defaultKDC != null)) {
             throw new KrbException
@@ -166,11 +165,34 @@
         // Always read the Kerberos configuration file
         try {
             Vector<String> configFile;
-            configFile = loadConfigFile();
-            if (configFile == null && isMacosLionOrBetter()) {
-                stanzaTable = SCDynamicStoreConfig.getConfig();
-            } else {
+            String fileName = getJavaFileName();
+            if (fileName != null) {
+                configFile = loadConfigFile(fileName);
                 stanzaTable = parseStanzaTable(configFile);
+                if (DEBUG) {
+                    System.out.println("Loaded from Java config");
+                }
+            } else {
+                boolean found = false;
+                if (isMacosLionOrBetter()) {
+                    try {
+                        stanzaTable = SCDynamicStoreConfig.getConfig();
+                        if (DEBUG) {
+                            System.out.println("Loaded from SCDynamicStoreConfig");
+                        }
+                        found = true;
+                    } catch (IOException ioe) {
+                        // OK. Will go on with file
+                    }
+                }
+                if (!found) {
+                    fileName = getNativeFileName();
+                    configFile = loadConfigFile(fileName);
+                    stanzaTable = parseStanzaTable(configFile);
+                    if (DEBUG) {
+                        System.out.println("Loaded from native config");
+                    }
+                }
             }
         } catch (IOException ioe) {
             // No krb5.conf, no problem. We'll use DNS or system property etc.
@@ -538,10 +560,13 @@
      * [domain_realm]
      *          blue.sample.com = TEST.SAMPLE.COM
      *          .backup.com     = EXAMPLE.COM
+     *
+     * @params fileName the conf file, cannot be null
+     * @return the content, null if fileName is empty
+     * @throws IOException if there is an I/O or format error
      */
-    private Vector<String> loadConfigFile() throws IOException {
+    private Vector<String> loadConfigFile(final String fileName) throws IOException {
         try {
-            final String fileName = getFileName();
             if (!fileName.equals("")) {
                 BufferedReader br = new BufferedReader(new InputStreamReader(
                 java.security.AccessController.doPrivileged(
@@ -660,97 +685,106 @@
     }
 
     /**
-     * Gets the default configuration file name. This method will never
-     * return null.
+     * Gets the default Java configuration file name.
      *
      * If the system property "java.security.krb5.conf" is defined, we'll
-     * use its value, no matter if the file exists or not. Otherwise,
-     * the file will be searched in a list of possible loations in the
-     * following order:
+     * use its value, no matter if the file exists or not. Otherwise, we
+     * will look at $JAVA_HOME/lib/security directory with "krb5.conf" name,
+     * and return it if the file exists.
      *
-     * 1. at Java home lib\security directory with "krb5.conf" name,
-     * 2. at windows directory with the name of "krb5.ini" for Windows,
-     * /etc/krb5/krb5.conf for Solaris, /etc/krb5.conf otherwise.
+     * The method returns null if it cannot find a Java config file.
+     */
+    private String getJavaFileName() {
+        String name = getProperty("java.security.krb5.conf");
+        if (name == null) {
+            name = getProperty("java.home") + File.separator +
+                                "lib" + File.separator + "security" +
+                                File.separator + "krb5.conf";
+            if (!fileExists(name)) {
+                name = null;
+            }
+        }
+        if (DEBUG) {
+            System.out.println("Java config name: " + name);
+        }
+        return name;
+    }
+
+    /**
+     * Gets the default native configuration file name.
+     *
+     * Depending on the OS type, the method returns the default native
+     * kerberos config file name, which is at windows directory with
+     * the name of "krb5.ini" for Windows, /etc/krb5/krb5.conf for Solaris,
+     * /etc/krb5.conf otherwise. Mac OSX X has a different file name.
      *
      * Note: When the Terminal Service is started in Windows (from 2003),
      * there are two kinds of Windows directories: A system one (say,
      * C:\Windows), and a user-private one (say, C:\Users\Me\Windows).
      * We will first look for krb5.ini in the user-private one. If not
      * found, try the system one instead.
+     *
+     * This method will always return a non-null non-empty file name,
+     * even if that file does not exist.
      */
-    private String getFileName() {
-        String name =
-            java.security.AccessController.doPrivileged(
-                                new sun.security.action.
-                                GetPropertyAction("java.security.krb5.conf"));
-        if (name == null) {
-            name = java.security.AccessController.doPrivileged(
-                        new sun.security.action.
-                        GetPropertyAction("java.home")) + File.separator +
-                                "lib" + File.separator + "security" +
-                                File.separator + "krb5.conf";
-            if (!fileExists(name)) {
-                name = null;
-                String osname =
-                        java.security.AccessController.doPrivileged(
-                        new sun.security.action.GetPropertyAction("os.name"));
-                if (osname.startsWith("Windows")) {
-                    try {
-                        Credentials.ensureLoaded();
-                    } catch (Exception e) {
-                        // ignore exceptions
+    private String getNativeFileName() {
+        String name = null;
+        String osname = getProperty("os.name");
+        if (osname.startsWith("Windows")) {
+            try {
+                Credentials.ensureLoaded();
+            } catch (Exception e) {
+                // ignore exceptions
+            }
+            if (Credentials.alreadyLoaded) {
+                String path = getWindowsDirectory(false);
+                if (path != null) {
+                    if (path.endsWith("\\")) {
+                        path = path + "krb5.ini";
+                    } else {
+                        path = path + "\\krb5.ini";
                     }
-                    if (Credentials.alreadyLoaded) {
-                        String path = getWindowsDirectory(false);
-                        if (path != null) {
-                            if (path.endsWith("\\")) {
-                                path = path + "krb5.ini";
-                            } else {
-                                path = path + "\\krb5.ini";
-                            }
-                            if (fileExists(path)) {
-                                name = path;
-                            }
+                    if (fileExists(path)) {
+                        name = path;
+                    }
+                }
+                if (name == null) {
+                    path = getWindowsDirectory(true);
+                    if (path != null) {
+                        if (path.endsWith("\\")) {
+                            path = path + "krb5.ini";
+                        } else {
+                            path = path + "\\krb5.ini";
                         }
-                        if (name == null) {
-                            path = getWindowsDirectory(true);
-                            if (path != null) {
-                                if (path.endsWith("\\")) {
-                                    path = path + "krb5.ini";
-                                } else {
-                                    path = path + "\\krb5.ini";
-                                }
-                                name = path;
-                            }
-                        }
+                        name = path;
                     }
-                    if (name == null) {
-                        name = "c:\\winnt\\krb5.ini";
-                    }
-                } else if (osname.startsWith("SunOS")) {
-                    name =  "/etc/krb5/krb5.conf";
-                } else if (osname.contains("OS X")) {
-                    if (isMacosLionOrBetter()) return "";
-                    name = findMacosConfigFile();
-                } else {
-                    name =  "/etc/krb5.conf";
                 }
             }
+            if (name == null) {
+                name = "c:\\winnt\\krb5.ini";
+            }
+        } else if (osname.startsWith("SunOS")) {
+            name =  "/etc/krb5/krb5.conf";
+        } else if (osname.contains("OS X")) {
+            name = findMacosConfigFile();
+        } else {
+            name =  "/etc/krb5.conf";
         }
         if (DEBUG) {
-            System.out.println("Config name: " + name);
+            System.out.println("Native config name: " + name);
         }
         return name;
     }
 
-    private String getProperty(String property) {
-        return (String)java.security.AccessController.doPrivileged(new sun.security.action.GetPropertyAction(property));
+    private static String getProperty(String property) {
+        return java.security.AccessController.doPrivileged(
+                new sun.security.action.GetPropertyAction(property));
     }
 
     private String findMacosConfigFile() {
         String userHome = getProperty("user.home");
         final String PREF_FILE = "/Library/Preferences/edu.mit.Kerberos";
-        String userPrefs=userHome + PREF_FILE;
+        String userPrefs = userHome + PREF_FILE;
 
         if (fileExists(userPrefs)) {
             return userPrefs;
@@ -760,11 +794,7 @@
             return PREF_FILE;
         }
 
-        if (fileExists("/etc/krb5.conf")) {
-            return "/etc/krb5.conf";
-        }
-
-        return "";
+        return "/etc/krb5.conf";
     }
 
     private static String trimmed(String s) {
@@ -1284,7 +1314,7 @@
      */
     private String getKDCFromDNS(String realm) throws KrbException {
         // use DNS to locate KDC
-        String kdcs = null;
+        String kdcs = "";
         String[] srvs = null;
         // locate DNS SRV record using UDP
         if (DEBUG) {
@@ -1294,7 +1324,7 @@
         if (srvs == null) {
             // locate DNS SRV record using TCP
             if (DEBUG) {
-                System.out.println("getKDCFromDNS using UDP");
+                System.out.println("getKDCFromDNS using TCP");
             }
             srvs = KrbServiceLocator.getKerberosService(realm, "_tcp");
         }
@@ -1303,14 +1333,15 @@
             throw new KrbException(Krb5.KRB_ERR_GENERIC,
                 "Unable to locate KDC for realm " + realm);
         }
+        if (srvs.length == 0) {
+            return null;
+        }
         for (int i = 0; i < srvs.length; i++) {
-            String value = srvs[i];
-            for (int j = 0; j < srvs[i].length(); j++) {
-                // filter the KDC name
-                if (value.charAt(j) == ':') {
-                    kdcs = (value.substring(0, j)).trim();
-                }
-            }
+            kdcs += srvs[i].trim() + " ";
+        }
+        kdcs = kdcs.trim();
+        if (kdcs.equals("")) {
+            return null;
         }
         return kdcs;
     }
@@ -1334,32 +1365,52 @@
         }
     }
 
+    // Shows the content of the Config object for debug purpose.
+    //
+    // {
+    //      libdefaults = {
+    //          default_realm = R
+    //      }
+    //      realms = {
+    //          R = {
+    //              kdc = [k1,k2]
+    //          }
+    //      }
+    // }
+
     @Override
     public String toString() {
         StringBuffer sb = new StringBuffer();
-        toStringIndented("", stanzaTable, sb);
+        toStringInternal("", stanzaTable, sb);
         return sb.toString();
     }
-    private static void toStringIndented(String prefix, Object obj,
+    private static void toStringInternal(String prefix, Object obj,
             StringBuffer sb) {
         if (obj instanceof String) {
-            sb.append(prefix);
-            sb.append(obj);
-            sb.append('\n');
+            // A string value, just print it
+            sb.append(obj).append('\n');
         } else if (obj instanceof Hashtable) {
-            Hashtable tab = (Hashtable)obj;
+            // A table, start a new sub-section...
+            Hashtable<?, ?> tab = (Hashtable<?, ?>)obj;
+            sb.append("{\n");
             for (Object o: tab.keySet()) {
-                sb.append(prefix);
-                sb.append(o);
-                sb.append(" = {\n");
-                toStringIndented(prefix + "    ", tab.get(o), sb);
-                sb.append(prefix + "}\n");
+                // ...indent, print "key = ", and
+                sb.append(prefix).append("    ").append(o).append(" = ");
+                // ...go recursively into value
+                toStringInternal(prefix + "    ", tab.get(o), sb);
             }
+            sb.append(prefix).append("}\n");
         } else if (obj instanceof Vector) {
-            Vector v = (Vector)obj;
+            // A vector of strings, print them inside [ and ]
+            Vector<?> v = (Vector<?>)obj;
+            sb.append("[");
+            boolean first = true;
             for (Object o: v.toArray()) {
-                toStringIndented(prefix + "    ", o, sb);
+                if (!first) sb.append(",");
+                sb.append(o);
+                first = false;
             }
+            sb.append("]\n");
         }
     }
 }
diff --git a/jdk/src/share/classes/sun/security/krb5/Credentials.java b/jdk/src/share/classes/sun/security/krb5/Credentials.java
index 5ad32fb..1451910 100644
--- a/jdk/src/share/classes/sun/security/krb5/Credentials.java
+++ b/jdk/src/share/classes/sun/security/krb5/Credentials.java
@@ -330,12 +330,17 @@
         CredentialsCache ccache =
             CredentialsCache.getInstance(princ, ticketCache);
 
-        if (ccache == null)
+        if (ccache == null) {
             return null;
+        }
 
         sun.security.krb5.internal.ccache.Credentials tgtCred  =
             ccache.getDefaultCreds();
 
+        if (tgtCred == null) {
+            return null;
+        }
+
         if (EType.isSupported(tgtCred.getEType())) {
             return tgtCred.setKrbCreds();
         } else {
@@ -375,19 +380,21 @@
             cache = CredentialsCache.getInstance();
         }
         if (cache != null) {
-            if (DEBUG) {
-                System.out.println(">>> KrbCreds found the default ticket " +
-                                   "granting ticket in credential cache.");
-            }
             sun.security.krb5.internal.ccache.Credentials temp =
                 cache.getDefaultCreds();
-            if (EType.isSupported(temp.getEType())) {
-                result = temp.setKrbCreds();
-            } else {
+            if (temp != null) {
                 if (DEBUG) {
-                    System.out.println(
-                        ">>> unsupported key type found the default TGT: " +
-                        temp.getEType());
+                    System.out.println(">>> KrbCreds found the default ticket"
+                            + " granting ticket in credential cache.");
+                }
+                if (EType.isSupported(temp.getEType())) {
+                    result = temp.setKrbCreds();
+                } else {
+                    if (DEBUG) {
+                        System.out.println(
+                            ">>> unsupported key type found the default TGT: " +
+                            temp.getEType());
+                    }
                 }
             }
         }
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java b/jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java
index f9b901f..5bc214f 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java
@@ -356,7 +356,7 @@
      * Returns path name of the credentials cache file.
      * The path name is searched in the following order:
      *
-     * 1. KRB5CCNAME
+     * 1. KRB5CCNAME (bare file name without FILE:)
      * 2. /tmp/krb5cc_<uid> on unix systems
      * 3. <user.home>/krb5cc_<user.name>
      * 4. <user.home>/krb5cc (if can't get <user.name>)
@@ -367,11 +367,19 @@
         String stdCacheNameComponent = "krb5cc";
         String name;
 
+        // The env var can start with TYPE:, we only support FILE: here.
+        // http://docs.oracle.com/cd/E19082-01/819-2252/6n4i8rtr3/index.html
         name = java.security.AccessController.doPrivileged(
                 new java.security.PrivilegedAction<String>() {
             @Override
             public String run() {
-                return System.getenv("KRB5CCNAME");
+                String cache = System.getenv("KRB5CCNAME");
+                if (cache != null &&
+                        (cache.length() >= 5) &&
+                        cache.regionMatches(true, 0, "FILE:", 0, 5)) {
+                    cache = cache.substring(5);
+                }
+                return cache;
             }
         });
         if (name != null) {
diff --git a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
index b7b1db2..4b0ee70 100644
--- a/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
+++ b/jdk/src/share/classes/sun/security/krb5/internal/ktab/KeyTab.java
@@ -141,7 +141,7 @@
         if (s == null) {
             return getInstance();
         } else {
-            return getInstance0(parse(s));
+            return getInstance0(normalize(s));
         }
     }
 
@@ -191,7 +191,7 @@
                 if (keytab_names != null) {
                     StringTokenizer st = new StringTokenizer(keytab_names, " ");
                     while (st.hasMoreTokens()) {
-                        kname = parse(st.nextToken());
+                        kname = normalize(st.nextToken());
                         if (new File(kname).exists()) {
                             break;
                         }
@@ -220,11 +220,13 @@
     }
 
     /**
-     * Parses some common keytab name formats
+     * Normalizes some common keytab name formats into the bare file name.
+     * For example, FILE:/etc/krb5.keytab to /etc/krb5.keytab
      * @param name never null
      * @return never null
      */
-    private static String parse(String name) {
+    // This method is used in this class and Krb5LoginModule
+    public static String normalize(String name) {
         String kname;
         if ((name.length() >= 5) &&
             (name.substring(0, 5).equalsIgnoreCase("FILE:"))) {
diff --git a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java
index cceddc3..72ed28e 100644
--- a/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java
+++ b/jdk/src/share/classes/sun/security/provider/certpath/OCSPResponse.java
@@ -294,7 +294,7 @@
         }
         for (int i = 0; i < singleResponseDer.length; i++) {
             SingleResponse singleResponse
-                = new SingleResponse(singleResponseDer[i]);
+                = new SingleResponse(singleResponseDer[i], dateCheckedAgainst);
             singleResponseMap.put(singleResponse.getCertId(), singleResponse);
         }
 
@@ -442,7 +442,11 @@
 
                     // Check the date validity
                     try {
-                        signerCert.checkValidity();
+                        if (dateCheckedAgainst == null) {
+                            signerCert.checkValidity();
+                        } else {
+                            signerCert.checkValidity(dateCheckedAgainst);
+                        }
                     } catch (GeneralSecurityException e) {
                         if (DEBUG != null) {
                             DEBUG.println("Responder's certificate not within" +
@@ -572,6 +576,11 @@
         private final Map<String, java.security.cert.Extension> singleExtensions;
 
         private SingleResponse(DerValue der) throws IOException {
+            this(der, null);
+        }
+
+        private SingleResponse(DerValue der, Date dateCheckedAgainst)
+            throws IOException {
             if (der.tag != DerValue.tag_Sequence) {
                 throw new IOException("Bad ASN.1 encoding in SingleResponse");
             }
@@ -669,7 +678,8 @@
                 singleExtensions = Collections.emptyMap();
             }
 
-            long now = System.currentTimeMillis();
+            long now = (dateCheckedAgainst == null) ?
+                System.currentTimeMillis() : dateCheckedAgainst.getTime();
             Date nowPlusSkew = new Date(now + MAX_CLOCK_SKEW);
             Date nowMinusSkew = new Date(now - MAX_CLOCK_SKEW);
             if (DEBUG != null) {
diff --git a/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java b/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java
index 13cadcf..a96e5d4 100644
--- a/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java
+++ b/jdk/src/share/classes/sun/security/ssl/HandshakeMessage.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -132,7 +132,7 @@
      */
     final void write(HandshakeOutStream s) throws IOException {
         int len = messageLength();
-        if (len > (1 << 24)) {
+        if (len >= Record.OVERFLOW_OF_INT24) {
             throw new SSLException("Handshake message too big"
                 + ", type = " + messageType() + ", len = " + len);
         }
diff --git a/jdk/src/share/classes/sun/security/ssl/HandshakeOutStream.java b/jdk/src/share/classes/sun/security/ssl/HandshakeOutStream.java
index 9a7cb5b..25aeed6 100644
--- a/jdk/src/share/classes/sun/security/ssl/HandshakeOutStream.java
+++ b/jdk/src/share/classes/sun/security/ssl/HandshakeOutStream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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,10 +153,12 @@
      */
 
     void putInt8(int i) throws IOException {
+        checkOverflow(i, Record.OVERFLOW_OF_INT08);
         r.write(i);
     }
 
     void putInt16(int i) throws IOException {
+        checkOverflow(i, Record.OVERFLOW_OF_INT16);
         if (r.availableDataBytes() < 2) {
             flush();
         }
@@ -165,6 +167,7 @@
     }
 
     void putInt24(int i) throws IOException {
+        checkOverflow(i, Record.OVERFLOW_OF_INT24);
         if (r.availableDataBytes() < 3) {
             flush();
         }
@@ -191,6 +194,8 @@
         if (b == null) {
             putInt8(0);
             return;
+        } else {
+            checkOverflow(b.length, Record.OVERFLOW_OF_INT08);
         }
         putInt8(b.length);
         write(b, 0, b.length);
@@ -200,6 +205,8 @@
         if (b == null) {
             putInt16(0);
             return;
+        } else {
+            checkOverflow(b.length, Record.OVERFLOW_OF_INT16);
         }
         putInt16(b.length);
         write(b, 0, b.length);
@@ -209,8 +216,19 @@
         if (b == null) {
             putInt24(0);
             return;
+        } else {
+            checkOverflow(b.length, Record.OVERFLOW_OF_INT24);
         }
         putInt24(b.length);
         write(b, 0, b.length);
     }
+
+    private void checkOverflow(int length, int overflow) {
+        if (length >= overflow) {
+            // internal_error alert will be triggered
+            throw new RuntimeException(
+                    "Field length overflow, the field length (" +
+                    length + ") should be less than " + overflow);
+        }
+    }
 }
diff --git a/jdk/src/share/classes/sun/security/ssl/Record.java b/jdk/src/share/classes/sun/security/ssl/Record.java
index 92c8a3e..0494d9a 100644
--- a/jdk/src/share/classes/sun/security/ssl/Record.java
+++ b/jdk/src/share/classes/sun/security/ssl/Record.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, 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
@@ -110,4 +110,10 @@
                                     + maxPadding        // padding
                                     + trailerSize;      // MAC
 
+    /*
+     * The overflow values of integers of 8, 16 and 24 bits.
+     */
+    static final int OVERFLOW_OF_INT08 = (1 << 8);
+    static final int OVERFLOW_OF_INT16 = (1 << 16);
+    static final int OVERFLOW_OF_INT24 = (1 << 24);
 }
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java
index 299a258..c2081b7 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLContextImpl.java
@@ -266,7 +266,7 @@
     }
 
     // Get suported CipherSuiteList.
-    CipherSuiteList getSuportedCipherSuiteList() {
+    CipherSuiteList getSupportedCipherSuiteList() {
         // The maintenance of cipher suites needs to be synchronized.
         synchronized (this) {
             // Clear cache of available ciphersuites.
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
index 2986eef..63d59d0 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLEngineImpl.java
@@ -1987,7 +1987,7 @@
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        return sslContext.getSuportedCipherSuiteList().toStringArray();
+        return sslContext.getSupportedCipherSuiteList().toStringArray();
     }
 
     /**
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java
index c73271c..2b99129 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketFactoryImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -113,7 +113,7 @@
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        return context.getSuportedCipherSuiteList().toStringArray();
+        return context.getSupportedCipherSuiteList().toStringArray();
     }
 
 }
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java
index 1423714..c2098c1 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLServerSocketImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1996, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -168,7 +168,7 @@
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        return sslContext.getSuportedCipherSuiteList().toStringArray();
+        return sslContext.getSupportedCipherSuiteList().toStringArray();
     }
 
     /**
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java
index a475954..135b462 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketFactoryImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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,6 +177,6 @@
      * certain kinds of certificates to use certain cipher suites.
      */
     public String[] getSupportedCipherSuites() {
-        return context.getSuportedCipherSuiteList().toStringArray();
+        return context.getSupportedCipherSuiteList().toStringArray();
     }
 }
diff --git a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
index 4ee2239..9de53bb 100644
--- a/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
+++ b/jdk/src/share/classes/sun/security/ssl/SSLSocketImpl.java
@@ -1576,11 +1576,9 @@
         Throwable cachedThrowable = null;
         try {
             switch (state) {
-            /*
-             * java.net code sometimes closes sockets "early", when
-             * we can't actually do I/O on them.
-             */
             case cs_START:
+                // unconnected socket or handshaking has not been initialized
+                closeSocket(selfInitiated);
                 break;
 
             /*
@@ -2356,7 +2354,7 @@
      * @return an array of cipher suite names
      */
     public String[] getSupportedCipherSuites() {
-        return sslContext.getSuportedCipherSuiteList().toStringArray();
+        return sslContext.getSupportedCipherSuiteList().toStringArray();
     }
 
     /**
diff --git a/jdk/src/share/classes/sun/swing/FilePane.java b/jdk/src/share/classes/sun/swing/FilePane.java
index 5bf5c1f..223b659 100644
--- a/jdk/src/share/classes/sun/swing/FilePane.java
+++ b/jdk/src/share/classes/sun/swing/FilePane.java
@@ -35,6 +35,7 @@
 import java.util.List;
 import java.util.concurrent.Callable;
 
+import javax.accessibility.AccessibleContext;
 import javax.swing.*;
 import javax.swing.border.*;
 import javax.swing.event.*;
@@ -82,6 +83,9 @@
     private JPanel currentViewPanel;
     private String[] viewTypeActionNames;
 
+    private String filesListAccessibleName = null;
+    private String filesDetailsAccessibleName = null;
+
     private JPopupMenu contextMenu;
     private JMenu viewMenu;
 
@@ -450,6 +454,9 @@
         gigaByteString = UIManager.getString("FileChooser.fileSizeGigaBytes", l);
         fullRowSelection = UIManager.getBoolean("FileView.fullRowSelection");
 
+        filesListAccessibleName = UIManager.getString("FileChooser.filesListAccessibleName", l);
+        filesDetailsAccessibleName = UIManager.getString("FileChooser.filesDetailsAccessibleName", l);
+
         renameErrorTitleText = UIManager.getString("FileChooser.renameErrorTitleText", l);
         renameErrorText = UIManager.getString("FileChooser.renameErrorText", l);
         renameErrorFileExistsText = UIManager.getString("FileChooser.renameErrorFileExistsText", l);
@@ -634,6 +641,9 @@
         if (listViewBorder != null) {
             scrollpane.setBorder(listViewBorder);
         }
+
+        list.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesListAccessibleName);
+
         p.add(scrollpane, BorderLayout.CENTER);
         return p;
     }
@@ -1228,6 +1238,8 @@
 
         detailsTableModel.fireTableStructureChanged();
 
+        detailsTable.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, filesDetailsAccessibleName);
+
         return p;
     } // createDetailsView
 
diff --git a/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java b/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java
index 8db2674..085a999 100644
--- a/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java
+++ b/jdk/src/share/classes/sun/swing/plaf/synth/SynthFileChooserUI.java
@@ -256,6 +256,7 @@
         if (getFileChooser().getControlButtonsAreShown()) {
             approveButton.setText(getApproveButtonText(getFileChooser()));
             approveButton.setToolTipText(getApproveButtonToolTipText(getFileChooser()));
+            approveButton.setMnemonic(getApproveButtonMnemonic(getFileChooser()));
         }
     }
 
diff --git a/jdk/src/share/classes/sun/text/resources/FormatData_sl.java b/jdk/src/share/classes/sun/text/resources/FormatData_sl.java
index e51b739..949d750 100644
--- a/jdk/src/share/classes/sun/text/resources/FormatData_sl.java
+++ b/jdk/src/share/classes/sun/text/resources/FormatData_sl.java
@@ -131,8 +131,8 @@
                     "H:mm:ss z", // long time pattern
                     "H:mm:ss", // medium time pattern
                     "H:mm", // short time pattern
-                    "EEEE, d MMMM yyyy", // full date pattern
-                    "EEEE, d MMMM yyyy", // long date pattern
+                    "EEEE, dd. MMMM y", // full date pattern
+                    "dd. MMMM y", // long date pattern
                     "d.M.yyyy", // medium date pattern
                     "d.M.y", // short date pattern
                     "{1} {0}" // date-time pattern
diff --git a/jdk/src/share/classes/sun/tools/jar/Main.java b/jdk/src/share/classes/sun/tools/jar/Main.java
index 54f4dea..73a3d0e 100644
--- a/jdk/src/share/classes/sun/tools/jar/Main.java
+++ b/jdk/src/share/classes/sun/tools/jar/Main.java
@@ -839,8 +839,8 @@
 
     void replaceFSC(String files[]) {
         if (files != null) {
-            for (String file : files) {
-                file = file.replace(File.separatorChar, '/');
+            for (int i = 0; i < files.length; i++) {
+                files[i] = files[i].replace(File.separatorChar, '/');
             }
         }
     }
diff --git a/jdk/src/share/classes/sun/tools/java/ClassPath.java b/jdk/src/share/classes/sun/tools/java/ClassPath.java
index ccb1cff..5f8aa01 100644
--- a/jdk/src/share/classes/sun/tools/java/ClassPath.java
+++ b/jdk/src/share/classes/sun/tools/java/ClassPath.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1994, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1994, 2012, 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,7 +141,7 @@
         } else {
             StringBuilder sb = new StringBuilder(patharray[0]);
             for (int i = 1; i < patharray.length; i++) {
-                sb.append(File.separator);
+                sb.append(File.pathSeparatorChar);
                 sb.append(patharray[i]);
             }
             this.pathstr = sb.toString();
diff --git a/jdk/src/share/classes/sun/tools/jconsole/AboutDialog.java b/jdk/src/share/classes/sun/tools/jconsole/AboutDialog.java
index f6b7c5a..1d91d53 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/AboutDialog.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/AboutDialog.java
@@ -30,13 +30,12 @@
 import java.beans.PropertyVetoException;
 import java.net.URI;
 
-import javax.accessibility.*;
 import javax.swing.*;
 import javax.swing.border.*;
 import javax.swing.event.*;
 
+
 import static java.awt.BorderLayout.*;
-import static sun.tools.jconsole.Resources.*;
 import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
@@ -47,7 +46,7 @@
     private static final Color borderColor   = Color.black;
 
     private Icon mastheadIcon =
-        new MastheadIcon(getText("Help.AboutDialog.masthead.title"));
+        new MastheadIcon(Messages.HELP_ABOUT_DIALOG_MASTHEAD_TITLE);
 
     private static AboutDialog aboutDialog;
 
@@ -55,10 +54,9 @@
     private Action closeAction;
 
     public AboutDialog(JConsole jConsole) {
-        super(jConsole, Resources.getText("Help.AboutDialog.title"), false);
+        super(jConsole, Messages.HELP_ABOUT_DIALOG_TITLE, false);
 
-        setAccessibleDescription(this,
-                                 getText("Help.AboutDialog.accessibleDescription"));
+        setAccessibleDescription(this, Messages.HELP_ABOUT_DIALOG_ACCESSIBLE_DESCRIPTION);
         setDefaultCloseOperation(HIDE_ON_CLOSE);
         setResizable(false);
         JComponent cp = (JComponent)getContentPane();
@@ -67,7 +65,7 @@
 
         JLabel mastheadLabel = new JLabel(mastheadIcon);
         setAccessibleName(mastheadLabel,
-                          getText("Help.AboutDialog.masthead.accessibleName"));
+                Messages.HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME);
 
         JPanel mainPanel = new TPanel(0, 0);
         mainPanel.add(mastheadLabel, NORTH);
@@ -75,7 +73,7 @@
         String jConsoleVersion = Version.getVersion();
         String vmName = System.getProperty("java.vm.name");
         String vmVersion = System.getProperty("java.vm.version");
-        String urlStr = getText("Help.AboutDialog.userGuideLink.url");
+        String urlStr = Messages.HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL;
         if (isBrowseSupported()) {
             urlStr = "<a style='color:#35556b' href=\"" + urlStr + "\">" + urlStr + "</a>";
         }
@@ -86,9 +84,9 @@
         String colorStr = String.format("%06x", textColor.getRGB() & 0xFFFFFF);
         JEditorPane helpLink = new JEditorPane("text/html",
                                 "<html><font color=#"+ colorStr + ">" +
-                        getText("Help.AboutDialog.jConsoleVersion", jConsoleVersion) +
-                "<p>" + getText("Help.AboutDialog.javaVersion", (vmName +", "+ vmVersion)) +
-                "<p>" + getText("Help.AboutDialog.userGuideLink", urlStr) +
+                        Resources.format(Messages.HELP_ABOUT_DIALOG_JCONSOLE_VERSION, jConsoleVersion) +
+                "<p>" + Resources.format(Messages.HELP_ABOUT_DIALOG_JAVA_VERSION, (vmName +", "+ vmVersion)) +
+                "<p>" + Resources.format(Messages.HELP_ABOUT_DIALOG_USER_GUIDE_LINK, urlStr) +
                                                  "</html>");
         helpLink.setOpaque(false);
         helpLink.setEditable(false);
@@ -155,7 +153,7 @@
     }
 
     static void browseUserGuide(JConsole jConsole) {
-        getAboutDialog(jConsole).browse(getText("Help.AboutDialog.userGuideLink.url"));
+        getAboutDialog(jConsole).browse(Messages.HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL);
     }
 
     static boolean isBrowseSupported() {
@@ -176,7 +174,7 @@
     }
 
     private void createActions() {
-        closeAction = new AbstractAction(getText("Close")) {
+        closeAction = new AbstractAction(Messages.CLOSE) {
             public void actionPerformed(ActionEvent ev) {
                 setVisible(false);
                 statusBar.setText("");
diff --git a/jdk/src/share/classes/sun/tools/jconsole/BorderedComponent.java b/jdk/src/share/classes/sun/tools/jconsole/BorderedComponent.java
index 5b45d74..57549ec 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/BorderedComponent.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/BorderedComponent.java
@@ -33,11 +33,10 @@
 import javax.swing.plaf.*;
 import javax.swing.plaf.basic.BasicGraphicsUtils;
 
+
 import static javax.swing.SwingConstants.*;
 
 import static sun.tools.jconsole.JConsole.*;
-import static sun.tools.jconsole.Resources.*;
-import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
 public class BorderedComponent extends JPanel implements ActionListener {
@@ -47,8 +46,6 @@
     JComponent comp;
     boolean collapsed = false;
 
-    private JPopupMenu popupMenu;
-
     private Icon collapseIcon;
     private Icon expandIcon;
 
@@ -100,7 +97,7 @@
                 moreOrLessButton.setMargin(new Insets(0, 0, 0, 0));
                 moreOrLessButton.addActionListener(this);
                 String toolTip =
-                    getText("BorderedComponent.moreOrLessButton.toolTip");
+                    Messages.BORDERED_COMPONENT_MORE_OR_LESS_BUTTON_TOOLTIP;
                 moreOrLessButton.setToolTipText(toolTip);
                 borderLabel.add(moreOrLessButton);
                 borderLabel.setSize(borderLabel.getPreferredSize());
@@ -136,7 +133,8 @@
     public void setValueLabel(String str) {
         this.valueLabelStr = str;
         if (label != null) {
-            label.setText(Resources.getText("Current value",valueLabelStr));
+            label.setText(Resources.format(Messages.CURRENT_VALUE,
+                                           valueLabelStr));
         }
     }
 
@@ -151,8 +149,8 @@
             remove(comp);
             if (valueLabelStr != null) {
                 if (label == null) {
-                    label = new JLabel(Resources.getText("Current value",
-                                                         valueLabelStr));
+                    label = new JLabel(Resources.format(Messages.CURRENT_VALUE,
+                                                        valueLabelStr));
                 }
                 add(label);
             }
@@ -439,8 +437,6 @@
          * @param insets the object to be reinitialized
          */
         public Insets getBorderInsets(Component c, Insets insets) {
-            int height = 16;
-
             Border border = getBorder();
             if (border != null) {
                 if (border instanceof AbstractBorder) {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/ClassTab.java b/jdk/src/share/classes/sun/tools/jconsole/ClassTab.java
index c47ccbc..b192b9f 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/ClassTab.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/ClassTab.java
@@ -33,17 +33,11 @@
 
 import javax.swing.*;
 import javax.swing.border.*;
-import javax.swing.event.*;
-import javax.swing.text.*;
 
-import java.util.*;
-import java.util.List;
+
 import java.util.concurrent.*;
 
-import sun.awt.*;
-
 import static sun.tools.jconsole.Formatter.*;
-import static sun.tools.jconsole.Resources.*;
 import static sun.tools.jconsole.Utilities.*;
 
 
@@ -58,13 +52,9 @@
 
     private static final String loadedPlotterKey        = "loaded";
     private static final String totalLoadedPlotterKey   = "totalLoaded";
-    private static final String loadedPlotterName       = Resources.getText("Loaded");
-    private static final String totalLoadedPlotterName  = Resources.getText("Total Loaded");
     private static final Color  loadedPlotterColor      = Plotter.defaultColor;
     private static final Color  totalLoadedPlotterColor = Color.red;
 
-    private static final String infoLabelFormat = "ClassTab.infoLabelFormat";
-
     /*
       Hierarchy of panels and layouts for this tab:
 
@@ -88,7 +78,7 @@
     */
 
     public static String getTabName() {
-        return Resources.getText("Classes");
+        return Messages.CLASSES;
     }
 
     public ClassTab(VMPanel vmPanel) {
@@ -108,40 +98,40 @@
         JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
         topPanel.add(controlPanel, BorderLayout.CENTER);
 
-        verboseCheckBox = new JCheckBox(Resources.getText("Verbose Output"));
+        verboseCheckBox = new JCheckBox(Messages.VERBOSE_OUTPUT);
         verboseCheckBox.addActionListener(this);
-        verboseCheckBox.setToolTipText(getText("Verbose Output.toolTip"));
+        verboseCheckBox.setToolTipText(Messages.VERBOSE_OUTPUT_TOOLTIP);
         JPanel topRightPanel = new JPanel();
         topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
         topRightPanel.add(verboseCheckBox);
         topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
 
-        loadedClassesMeter = new PlotterPanel(Resources.getText("Number of Loaded Classes"),
+        loadedClassesMeter = new PlotterPanel(Messages.NUMBER_OF_LOADED_CLASSES,
                                               Plotter.Unit.NONE, false);
         loadedClassesMeter.plotter.createSequence(loadedPlotterKey,
-                                                  loadedPlotterName,
+                                                  Messages.LOADED,
                                                   loadedPlotterColor,
                                                   true);
         loadedClassesMeter.plotter.createSequence(totalLoadedPlotterKey,
-                                                  totalLoadedPlotterName,
+                                                  Messages.TOTAL_LOADED,
                                                   totalLoadedPlotterColor,
                                                   true);
         setAccessibleName(loadedClassesMeter.plotter,
-                          getText("ClassTab.loadedClassesPlotter.accessibleName"));
+                          Messages.CLASS_TAB_LOADED_CLASSES_PLOTTER_ACCESSIBLE_NAME);
         plotterPanel.add(loadedClassesMeter);
 
         timeComboBox = new TimeComboBox(loadedClassesMeter.plotter);
-        controlPanel.add(new LabeledComponent(Resources.getText("Time Range:"),
-                                              getMnemonicInt("Time Range:"),
+        controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
+                                              Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
                                               timeComboBox));
 
         LabeledComponent.layout(plotterPanel);
 
-        bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Resources.getText("Details")),
-                                                  new EmptyBorder(10, 10, 10, 10)));
+        bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Messages.DETAILS),
+                                                 new EmptyBorder(10, 10, 10, 10)));
 
         details = new HTMLPane();
-        setAccessibleName(details, getText("Details"));
+        setAccessibleName(details, Messages.DETAILS);
         JScrollPane scrollPane = new JScrollPane(details);
         scrollPane.setPreferredSize(new Dimension(0, 150));
         bottomPanel.add(scrollPane, BorderLayout.SOUTH);
@@ -226,10 +216,10 @@
 
                 long time = System.currentTimeMillis();
                 String timeStamp = formatDateTime(time);
-                text += newRow(Resources.getText("Time"), timeStamp);
-                text += newRow(Resources.getText("Current classes loaded"), justify(clCount, 5));
-                text += newRow(Resources.getText("Total classes loaded"),   justify(ctCount, 5));
-                text += newRow(Resources.getText("Total classes unloaded"), justify(cuCount, 5));
+                text += newRow(Messages.TIME, timeStamp);
+                text += newRow(Messages.CURRENT_CLASSES_LOADED, justify(clCount, 5));
+                text += newRow(Messages.TOTAL_CLASSES_LOADED,   justify(ctCount, 5));
+                text += newRow(Messages.TOTAL_CLASSES_UNLOADED, justify(cuCount, 5));
 
                 return text;
             }
@@ -246,12 +236,13 @@
 
     private static class ClassOverviewPanel extends OverviewPanel {
         ClassOverviewPanel() {
-            super(getText("Classes"), loadedPlotterKey, loadedPlotterName, null);
+            super(Messages.CLASSES, loadedPlotterKey, Messages.LOADED, null);
         }
 
         private void updateClassInfo(long total, long loaded) {
             long unloaded = (total - loaded);
-            getInfoLabel().setText(getText(infoLabelFormat, loaded, unloaded, total));
+            getInfoLabel().setText(Resources.format(Messages.CLASS_TAB_INFO_LABEL_FORMAT,
+                                   loaded, unloaded, total));
         }
     }
 }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java b/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java
index 2bdd501..ea63667 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/ConnectDialog.java
@@ -29,23 +29,17 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.util.*;
-import java.net.MalformedURLException;
-import java.io.IOException;
 
-import javax.accessibility.*;
 import javax.swing.*;
-import javax.swing.Timer;
 import javax.swing.border.*;
 import javax.swing.event.*;
 import javax.swing.plaf.basic.BasicRadioButtonUI;
 import javax.swing.table.*;
 
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.JMXConnector;
+
 
 import static java.awt.BorderLayout.*;
 import static javax.swing.ListSelectionModel.*;
-import static sun.tools.jconsole.Resources.*;
 import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
@@ -66,7 +60,7 @@
     JPanel radioButtonPanel;
 
     private Icon mastheadIcon =
-        new MastheadIcon(getText("ConnectDialog.masthead.title"));
+        new MastheadIcon(Messages.CONNECT_DIALOG_MASTHEAD_TITLE);
     private Color hintTextColor, disabledTableCellColor;
 
     // The table of managed VM (local process)
@@ -79,11 +73,11 @@
 
 
     public ConnectDialog(JConsole jConsole) {
-        super(jConsole, Resources.getText("ConnectDialog.title"), true);
+        super(jConsole, Messages.CONNECT_DIALOG_TITLE, true);
 
         this.jConsole = jConsole;
         setAccessibleDescription(this,
-                                 getText("ConnectDialog.accessibleDescription"));
+                                 Messages.CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION);
         setDefaultCloseOperation(HIDE_ON_CLOSE);
         setResizable(false);
         Container cp = (JComponent)getContentPane();
@@ -95,7 +89,7 @@
 
         statusBar = new JLabel(" ", JLabel.CENTER);
         setAccessibleName(statusBar,
-                          getText("ConnectDialog.statusBar.accessibleName"));
+                          Messages.CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME);
 
         Font normalLabelFont = statusBar.getFont();
         Font boldLabelFont = normalLabelFont.deriveFont(Font.BOLD);
@@ -103,7 +97,7 @@
 
         JLabel mastheadLabel = new JLabel(mastheadIcon);
         setAccessibleName(mastheadLabel,
-                          getText("ConnectDialog.masthead.accessibleName"));
+                          Messages.CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME);
 
         cp.add(mastheadLabel, NORTH);
         cp.add(radioButtonPanel, CENTER);
@@ -117,7 +111,7 @@
         remoteTF.addFocusListener(this);
         remoteTF.setPreferredSize(remoteTF.getPreferredSize());
         setAccessibleName(remoteTF,
-                          getText("Remote Process.textField.accessibleName"));
+                          Messages.REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME);
 
         //
         // If the VM supports the local attach mechanism (is: Sun
@@ -141,8 +135,8 @@
             TableColumn cmdLineColumn = columnModel.getColumn(COL_NAME);
             cmdLineColumn.setResizable(false);
 
-            localRadioButton = new JRadioButton(getText("Local Process:"));
-            localRadioButton.setMnemonic(getMnemonicInt("Local Process:"));
+            localRadioButton = new JRadioButton(Messages.LOCAL_PROCESS_COLON);
+            localRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.LOCAL_PROCESS_COLON));
             localRadioButton.setFont(boldLabelFont);
             localRadioButton.addItemListener(this);
             radioButtonGroup.add(localRadioButton);
@@ -167,8 +161,8 @@
             localTablePanel.add(localMessageLabel, SOUTH);
         }
 
-        remoteRadioButton = new JRadioButton(getText("Remote Process:"));
-        remoteRadioButton.setMnemonic(getMnemonicInt("Remote Process:"));
+        remoteRadioButton = new JRadioButton(Messages.REMOTE_PROCESS_COLON);
+        remoteRadioButton.setMnemonic(Resources.getMnemonicInt(Messages.REMOTE_PROCESS_COLON));
         remoteRadioButton.setFont(boldLabelFont);
         radioButtonGroup.add(remoteRadioButton);
 
@@ -207,7 +201,7 @@
 
         remoteTFPanel.add(remoteTF, NORTH);
 
-        remoteMessageLabel = new JLabel("<html>" + getText("remoteTF.usage"));
+        remoteMessageLabel = new JLabel("<html>" + Messages.REMOTE_TF_USAGE + "</html>");
         remoteMessageLabel.setFont(smallLabelFont);
         remoteMessageLabel.setForeground(hintTextColor);
         remoteTFPanel.add(remoteMessageLabel, CENTER);
@@ -222,11 +216,10 @@
         userNameTF.getDocument().addDocumentListener(this);
         userNameTF.addFocusListener(this);
         setAccessibleName(userNameTF,
-                          getText("Username.accessibleName"));
-        String labelKey = "Username: ";
+            Messages.USERNAME_ACCESSIBLE_NAME);
         LabeledComponent lc;
-        lc = new LabeledComponent(getText(labelKey),
-                                  getMnemonicInt(labelKey),
+        lc = new LabeledComponent(Messages.USERNAME_COLON_,
+                                  Resources.getMnemonicInt(Messages.USERNAME_COLON_),
                                   userNameTF);
         lc.label.setFont(boldLabelFont);
         userPwdPanel.add(lc);
@@ -238,10 +231,10 @@
         passwordTF.getDocument().addDocumentListener(this);
         passwordTF.addFocusListener(this);
         setAccessibleName(passwordTF,
-                          getText("Password.accessibleName"));
-        labelKey = "Password: ";
-        lc = new LabeledComponent(getText(labelKey),
-                                  getMnemonicInt(labelKey),
+            Messages.PASSWORD_ACCESSIBLE_NAME);
+
+        lc = new LabeledComponent(Messages.PASSWORD_COLON_,
+                                  Resources.getMnemonicInt(Messages.PASSWORD_COLON_),
                                   passwordTF);
         lc.setBorder(new EmptyBorder(0, 12, 0, 0)); // Left padding
         lc.label.setFont(boldLabelFont);
@@ -250,7 +243,7 @@
         remoteTFPanel.add(userPwdPanel, SOUTH);
 
         String connectButtonToolTipText =
-            getText("ConnectDialog.connectButton.toolTip");
+            Messages.CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP;
         connectButton = new JButton(connectAction);
         connectButton.setToolTipText(connectButtonToolTipText);
 
@@ -288,7 +281,7 @@
             String colorStr =
                 String.format("%06x", hintTextColor.getRGB() & 0xFFFFFF);
             remoteMessageLabel.setText("<html><font color=#" + colorStr + ">" +
-                                       getText("remoteTF.usage"));
+                                       Messages.REMOTE_TF_USAGE);
         }
         if (localMessageLabel != null) {
             localMessageLabel.setForeground(hintTextColor);
@@ -300,9 +293,9 @@
     }
 
     private void createActions() {
-        connectAction = new AbstractAction(getText("Connect")) {
+        connectAction = new AbstractAction(Messages.CONNECT) {
             /* init */ {
-                putValue(Action.MNEMONIC_KEY, getMnemonicInt("Connect"));
+                putValue(Action.MNEMONIC_KEY, Resources.getMnemonicInt(Messages.CONNECT));
             }
 
             public void actionPerformed(ActionEvent ev) {
@@ -321,7 +314,6 @@
                     try {
                         if (txt.startsWith(JConsole.ROOT_URL)) {
                             String url = txt;
-                            String msg = null;
                             jConsole.addUrl(url, userName, password, false);
                             remoteTF.setText(JConsole.ROOT_URL);
                             return;
@@ -361,7 +353,7 @@
             }
         };
 
-        cancelAction = new AbstractAction(getText("Cancel")) {
+        cancelAction = new AbstractAction(Messages.CANCEL) {
             public void actionPerformed(ActionEvent ev) {
                 setVisible(false);
                 statusBar.setText("");
@@ -588,9 +580,9 @@
             LocalVirtualMachine lvm = vmModel.vmAt(row);
             if (!lvm.isManageable()) {
                 if (lvm.isAttachable()) {
-                    labelText = getText("Management Will Be Enabled");
+                    labelText = Messages.MANAGEMENT_WILL_BE_ENABLED;
                 } else {
-                    labelText = getText("Management Not Enabled");
+                    labelText = Messages.MANAGEMENT_NOT_ENABLED;
                 }
             }
         }
@@ -650,8 +642,8 @@
     // Represents the list of managed VMs as a tabular data model.
     private static class ManagedVmTableModel extends AbstractTableModel {
         private static String[] columnNames = {
-            Resources.getText("Column.Name"),
-            Resources.getText("Column.PID"),
+            Messages.COLUMN_NAME,
+            Messages.COLUMN_PID,
         };
 
         private List<LocalVirtualMachine> vmList;
@@ -678,7 +670,7 @@
             }
         }
 
-        public Class getColumnClass(int column) {
+        public Class<?> getColumnClass(int column) {
             switch (column) {
                 case COL_NAME: return String.class;
                 case COL_PID:  return Integer.class;
@@ -706,13 +698,6 @@
         }
     }
 
-
-    // Convenience method
-    private static String getText(String key) {
-        return Resources.getText(key);
-    }
-
-
     // A blank component that takes up as much space as the
     // button part of a JRadioButton.
     private static class Padder extends JPanel {
@@ -721,7 +706,7 @@
         Padder(JRadioButton radioButton) {
             this.radioButton = radioButton;
 
-            setAccessibleName(this, getText("Blank"));
+            setAccessibleName(this, Messages.BLANK);
         }
 
         public Dimension getPreferredSize() {
@@ -758,7 +743,6 @@
             if (g == null) {
                 return null;
             }
-            String clippedText =
                 SwingUtilities.layoutCompoundLabel(button,
                                                    g.getFontMetrics(),
                                                    text,
diff --git a/jdk/src/share/classes/sun/tools/jconsole/CreateMBeanDialog.java b/jdk/src/share/classes/sun/tools/jconsole/CreateMBeanDialog.java
index 75c784b..7d391b8 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/CreateMBeanDialog.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/CreateMBeanDialog.java
@@ -32,23 +32,21 @@
 import java.util.Comparator;
 
 import javax.swing.*;
-import javax.swing.Timer;
 import javax.swing.border.*;
-import javax.swing.event.*;
 
 import javax.management.MBeanServerConnection;
 import javax.management.ObjectName;
 import javax.management.InstanceAlreadyExistsException;
 import javax.management.InstanceNotFoundException;
 
-import static sun.tools.jconsole.Resources.*;
+
 import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
 public class CreateMBeanDialog extends InternalDialog
                 implements ActionListener {
     JConsole jConsole;
-    JComboBox connections;
+    JComboBox<ProxyClient> connections;
     JButton createMBeanButton, unregisterMBeanButton, cancelButton;
 
     private static final String HOTSPOT_MBEAN =
@@ -60,7 +58,7 @@
 
         this.jConsole = jConsole;
         setAccessibleDescription(this,
-                                 getText("Hotspot MBeans.dialog.accessibleDescription"));
+                                 Messages.HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION);
         Container cp = getContentPane();
         ((JComponent)cp).setBorder(new EmptyBorder(10, 10, 4, 10));
 
@@ -71,12 +69,10 @@
                                                         false,
                                                         true));
         cp.add(centerPanel, BorderLayout.CENTER);
-        connections = new JComboBox();
+        connections = new JComboBox<ProxyClient>();
         updateConnections();
 
-        centerPanel.add(new LabeledComponent(Resources.
-                                             getText("Manage Hotspot MBeans "+
-                                                     "in: "),
+        centerPanel.add(new LabeledComponent(Resources.format(Messages.MANAGE_HOTSPOT_MBEANS_IN_COLON_),
                                              connections));
 
         JPanel bottomPanel = new JPanel(new BorderLayout());
@@ -85,11 +81,11 @@
         JPanel buttonPanel = new JPanel();
         bottomPanel.add(buttonPanel, BorderLayout.NORTH);
         buttonPanel.add(createMBeanButton =
-                        new JButton(Resources.getText("Create")));
+                        new JButton(Messages.CREATE));
         buttonPanel.add(unregisterMBeanButton =
-                        new JButton(Resources.getText("Unregister")));
+                        new JButton(Messages.UNREGISTER));
         buttonPanel.add(cancelButton =
-                        new JButton(Resources.getText("Cancel")));
+                        new JButton(Messages.CANCEL));
 
         statusBar = new JLabel(" ", JLabel.CENTER);
         bottomPanel.add(statusBar, BorderLayout.SOUTH);
@@ -133,7 +129,8 @@
             }
         }
         connections.invalidate();
-        connections.setModel(new DefaultComboBoxModel(data.toArray()));
+        connections.setModel(new DefaultComboBoxModel<ProxyClient>
+            (data.toArray(new ProxyClient[data.size()])));
         connections.validate();
     }
 
@@ -144,7 +141,6 @@
             new Thread("CreateMBeanDialog.actionPerformed") {
                     public void run() {
                         try {
-                            StringBuffer buff = null;
                             Object c = connections.getSelectedItem();
                             if(c == null) return;
                             if(ev.getSource() == createMBeanButton) {
@@ -163,13 +159,9 @@
                             }
                             return;
                         } catch(InstanceAlreadyExistsException e) {
-                            statusBar.setText(Resources.
-                                              getText("Error: MBeans already "
-                                                      + "exist"));
+                            statusBar.setText(Messages.ERROR_COLON_MBEANS_ALREADY_EXIST);
                         } catch(InstanceNotFoundException e) {
-                            statusBar.setText(Resources.
-                                              getText("Error: MBeans do not "
-                                                      + "exist"));
+                            statusBar.setText(Messages.ERROR_COLON_MBEANS_DO_NOT_EXIST);
                         } catch(Exception e) {
                             statusBar.setText(e.toString());
                         }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/Formatter.java b/jdk/src/share/classes/sun/tools/jconsole/Formatter.java
index 46f6c0e..1192341 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/Formatter.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/Formatter.java
@@ -28,7 +28,6 @@
 import java.text.*;
 import java.util.*;
 
-import static sun.tools.jconsole.Resources.*;
 
 class Formatter {
     final static long SECOND = 1000;
@@ -48,7 +47,7 @@
         String str;
         if (t < 1 * MINUTE) {
             String seconds = String.format("%.3f", t / (double)SECOND);
-            str = Resources.getText("DurationSeconds", seconds);
+            str = Resources.format(Messages.DURATION_SECONDS, seconds);
         } else {
             long remaining = t;
             long days = remaining / DAY;
@@ -58,13 +57,13 @@
             long minutes = remaining / MINUTE;
 
             if (t >= 1 * DAY) {
-                str = Resources.getText("DurationDaysHoursMinutes",
-                                        days, hours, minutes);
+                str = Resources.format(Messages.DURATION_DAYS_HOURS_MINUTES,
+                                       days, hours, minutes);
             } else if (t >= 1 * HOUR) {
-                str = Resources.getText("DurationHoursMinutes",
-                                        hours, minutes);
+                str = Resources.format(Messages.DURATION_HOURS_MINUTES,
+                                       hours, minutes);
             } else {
-                str = Resources.getText("DurationMinutes", minutes);
+                str = Resources.format(Messages.DURATION_MINUTES, minutes);
             }
         }
         return str;
@@ -88,8 +87,7 @@
         return dateDF.format(time) + " " + timeWithSecondsDF.format(time);
     }
 
-    static DateFormat getDateTimeFormat(String key) {
-        String dtfStr = getText(key);
+    static DateFormat getDateTimeFormat(String dtfStr) {
         int dateStyle = -1;
         int timeStyle = -1;
 
@@ -153,18 +151,18 @@
         }
         String[] strings = formatLongs(bytes);
         for (int i = 0; i < n; i++) {
-            strings[i] = getText("kbytes", strings[i]);
+            strings[i] = Resources.format(Messages.KBYTES, strings[i]);
         }
         return strings;
     }
 
     static String formatKBytes(long bytes) {
         if (bytes == -1) {
-            return getText("kbytes", "-1");
+            return Resources.format(Messages.KBYTES, "-1");
         }
 
         long kb = bytes / 1024;
-        return getText("kbytes", justify(kb, 10));
+        return Resources.format(Messages.KBYTES, justify(kb, 10));
     }
 
 
@@ -182,13 +180,13 @@
         int exp = (int)Math.log10((double)vMax);
 
         if (exp < 3) {
-            s = Resources.getText("Size Bytes", v);
+            s = Resources.format(Messages.SIZE_BYTES, v);
         } else if (exp < 6) {
-            s = Resources.getText("Size Kb", trimDouble(v / Math.pow(10.0, 3)));
+            s = Resources.format(Messages.SIZE_KB, trimDouble(v / Math.pow(10.0, 3)));
         } else if (exp < 9) {
-            s = Resources.getText("Size Mb", trimDouble(v / Math.pow(10.0, 6)));
+            s = Resources.format(Messages.SIZE_MB, trimDouble(v / Math.pow(10.0, 6)));
         } else {
-            s = Resources.getText("Size Gb", trimDouble(v / Math.pow(10.0, 9)));
+            s = Resources.format(Messages.SIZE_GB, trimDouble(v / Math.pow(10.0, 9)));
         }
         if (html) {
             s = s.replace(" ", "&nbsp;");
diff --git a/jdk/src/share/classes/sun/tools/jconsole/HTMLPane.java b/jdk/src/share/classes/sun/tools/jconsole/HTMLPane.java
index f92623a..34c3c9b 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/HTMLPane.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/HTMLPane.java
@@ -25,8 +25,6 @@
 
 package sun.tools.jconsole;
 
-import java.awt.Color;
-
 import javax.swing.*;
 import javax.swing.event.*;
 import javax.swing.text.*;
diff --git a/jdk/src/share/classes/sun/tools/jconsole/InternalDialog.java b/jdk/src/share/classes/sun/tools/jconsole/InternalDialog.java
index 736cb2f..703e626 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/InternalDialog.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/InternalDialog.java
@@ -30,8 +30,8 @@
 
 import javax.swing.*;
 
+
 import static javax.swing.JLayeredPane.*;
-import static sun.tools.jconsole.Resources.*;
 
 /**
  * Used instead of JDialog in a JDesktopPane/JInternalFrame environment.
@@ -73,7 +73,7 @@
         private ImageIcon rightIcon =
             new ImageIcon(InternalDialog.class.getResource("resources/masthead-right.png"));
 
-        private Font font = Font.decode(getText("Masthead.font"));
+        private Font font = Font.decode(Messages.MASTHEAD_FONT);
         private int gap = 10;
         private String title;
 
diff --git a/jdk/src/share/classes/sun/tools/jconsole/JConsole.java b/jdk/src/share/classes/sun/tools/jconsole/JConsole.java
index bc4aa1d..443ae80 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/JConsole.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/JConsole.java
@@ -29,7 +29,6 @@
 import java.awt.event.*;
 import java.beans.*;
 import java.io.*;
-import java.lang.reflect.InvocationTargetException;
 import java.net.*;
 import java.util.*;
 import java.util.List;
@@ -38,8 +37,6 @@
 import javax.swing.border.*;
 import javax.swing.event.*;
 import javax.swing.plaf.*;
-import javax.management.remote.JMXServiceURL;
-import javax.management.remote.JMXConnector;
 import javax.security.auth.login.FailedLoginException;
 import javax.net.ssl.SSLHandshakeException;
 
@@ -47,7 +44,6 @@
 
 import sun.net.util.IPAddressUtil;
 
-import static sun.tools.jconsole.Resources.*;
 import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
@@ -68,7 +64,7 @@
                 try {
                     UIManager.setLookAndFeel(systemLaF);
                 } catch (Exception e) {
-                    System.err.println(Resources.getText("JConsole: ", e.getMessage()));
+                    System.err.println(Resources.format(Messages.JCONSOLE_COLON_, e.getMessage()));
                 }
             }
         }
@@ -87,7 +83,7 @@
 
 
     private final static String title =
-        Resources.getText("Java Monitoring & Management Console");
+        Messages.JAVA_MONITORING___MANAGEMENT_CONSOLE;
     public final static String ROOT_URL =
         "service:jmx:";
 
@@ -116,7 +112,7 @@
 
         setRootPane(new FixedJRootPane());
         setAccessibleDescription(this,
-                                 getText("JConsole.accessibleDescription"));
+                                 Messages.JCONSOLE_ACCESSIBLE_DESCRIPTION);
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
         menuBar = new JMenuBar();
@@ -124,12 +120,12 @@
 
         // TODO: Use Actions !
 
-        JMenu connectionMenu = new JMenu(getText("Connection"));
-        connectionMenu.setMnemonic(getMnemonicInt("Connection"));
+        JMenu connectionMenu = new JMenu(Messages.CONNECTION);
+        connectionMenu.setMnemonic(Resources.getMnemonicInt(Messages.CONNECTION));
         menuBar.add(connectionMenu);
         if(hotspot) {
-            hotspotMI = new JMenuItem(getText("Hotspot MBeans..."));
-            hotspotMI.setMnemonic(getMnemonicInt("Hotspot MBeans..."));
+            hotspotMI = new JMenuItem(Messages.HOTSPOT_MBEANS_ELLIPSIS);
+            hotspotMI.setMnemonic(Resources.getMnemonicInt(Messages.HOTSPOT_MBEANS_ELLIPSIS));
             hotspotMI.setAccelerator(KeyStroke.
                                      getKeyStroke(KeyEvent.VK_H,
                                                   InputEvent.CTRL_MASK));
@@ -139,8 +135,8 @@
             connectionMenu.addSeparator();
         }
 
-        connectMI = new JMenuItem(Resources.getText("New Connection..."));
-        connectMI.setMnemonic(getMnemonicInt("New Connection..."));
+        connectMI = new JMenuItem(Messages.NEW_CONNECTION_ELLIPSIS);
+        connectMI.setMnemonic(Resources.getMnemonicInt(Messages.NEW_CONNECTION_ELLIPSIS));
         connectMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,
                                                         InputEvent.CTRL_MASK));
         connectMI.addActionListener(this);
@@ -148,27 +144,27 @@
 
         connectionMenu.addSeparator();
 
-        exitMI = new JMenuItem(Resources.getText("Exit"));
-        exitMI.setMnemonic(getMnemonicInt("Exit"));
+        exitMI = new JMenuItem(Messages.EXIT);
+        exitMI.setMnemonic(Resources.getMnemonicInt(Messages.EXIT));
         exitMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F4,
                                                      InputEvent.ALT_MASK));
         exitMI.addActionListener(this);
         connectionMenu.add(exitMI);
 
 
-        JMenu helpMenu = new JMenu(getText("HelpMenu.title"));
-        helpMenu.setMnemonic(getMnemonicInt("HelpMenu.title"));
+        JMenu helpMenu = new JMenu(Messages.HELP_MENU_TITLE);
+        helpMenu.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_TITLE));
         menuBar.add(helpMenu);
 
         if (AboutDialog.isBrowseSupported()) {
-            userGuideMI = new JMenuItem(getText("HelpMenu.UserGuide.title"));
-            userGuideMI.setMnemonic(getMnemonicInt("HelpMenu.UserGuide.title"));
+            userGuideMI = new JMenuItem(Messages.HELP_MENU_USER_GUIDE_TITLE);
+            userGuideMI.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_USER_GUIDE_TITLE));
             userGuideMI.addActionListener(this);
             helpMenu.add(userGuideMI);
             helpMenu.addSeparator();
         }
-        aboutMI = new JMenuItem(getText("HelpMenu.About.title"));
-        aboutMI.setMnemonic(getMnemonicInt("HelpMenu.About.title"));
+        aboutMI = new JMenuItem(Messages.HELP_MENU_ABOUT_TITLE);
+        aboutMI.setMnemonic(Resources.getMnemonicInt(Messages.HELP_MENU_ABOUT_TITLE));
         aboutMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
         aboutMI.addActionListener(this);
         helpMenu.add(aboutMI);
@@ -191,8 +187,8 @@
             ((BorderLayout)cp.getLayout()).
             getLayoutComponent(BorderLayout.CENTER);
 
-        windowMenu = new WindowMenu(Resources.getText("Window"));
-        windowMenu.setMnemonic(getMnemonicInt("Window"));
+        windowMenu = new WindowMenu(Messages.WINDOW);
+        windowMenu.setMnemonic(Resources.getMnemonicInt(Messages.WINDOW));
         // Add Window menu before Help menu
         menuBar.add(windowMenu, menuBar.getComponentCount() - 1);
 
@@ -219,25 +215,25 @@
         WindowMenu(String text) {
             super(text);
 
-            cascadeMI = new JMenuItem(Resources.getText("Cascade"));
-            cascadeMI.setMnemonic(getMnemonicInt("Cascade"));
+            cascadeMI = new JMenuItem(Messages.CASCADE);
+            cascadeMI.setMnemonic(Resources.getMnemonicInt(Messages.CASCADE));
             cascadeMI.addActionListener(JConsole.this);
             add(cascadeMI);
 
-            tileMI = new JMenuItem(Resources.getText("Tile"));
-            tileMI.setMnemonic(getMnemonicInt("Tile"));
+            tileMI = new JMenuItem(Messages.TILE);
+            tileMI.setMnemonic(Resources.getMnemonicInt(Messages.TILE));
             tileMI.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_T,
                                                          InputEvent.CTRL_MASK));
             tileMI.addActionListener(JConsole.this);
             add(tileMI);
 
-            minimizeAllMI = new JMenuItem(Resources.getText("Minimize All"));
-            minimizeAllMI.setMnemonic(getMnemonicInt("Minimize All"));
+            minimizeAllMI = new JMenuItem(Messages.MINIMIZE_ALL);
+            minimizeAllMI.setMnemonic(Resources.getMnemonicInt(Messages.MINIMIZE_ALL));
             minimizeAllMI.addActionListener(JConsole.this);
             add(minimizeAllMI);
 
-            restoreAllMI = new JMenuItem(Resources.getText("Restore All"));
-            restoreAllMI.setMnemonic(getMnemonicInt("Restore All"));
+            restoreAllMI = new JMenuItem(Messages.RESTORE_ALL);
+            restoreAllMI.setMnemonic(Resources.getMnemonicInt(Messages.RESTORE_ALL));
             restoreAllMI.addActionListener(JConsole.this);
             add(restoreAllMI);
 
@@ -721,7 +717,7 @@
     }
 
     private String errorMessage(Exception ex) {
-       String msg = Resources.getText("Connection failed");
+       String msg = Messages.CONNECTION_FAILED;
        if (ex instanceof IOException || ex instanceof SecurityException) {
            Throwable cause = null;
            Throwable c = ex.getCause();
@@ -732,7 +728,7 @@
            if (cause instanceof ConnectException) {
                return msg + ": " + cause.getMessage();
            } else if (cause instanceof UnknownHostException) {
-               return Resources.getText("Unknown Host", cause.getMessage());
+               return Resources.format(Messages.UNKNOWN_HOST, cause.getMessage());
            } else if (cause instanceof NoRouteToHostException) {
                return msg + ": " + cause.getMessage();
            } else if (cause instanceof FailedLoginException) {
@@ -741,7 +737,7 @@
                return msg + ": "+ cause.getMessage();
            }
         } else if (ex instanceof MalformedURLException) {
-           return Resources.getText("Invalid URL", ex.getMessage());
+           return Resources.format(Messages.INVALID_URL, ex.getMessage());
         }
         return msg + ": " + ex.getMessage();
     }
@@ -770,7 +766,7 @@
 
 
     private static void usage() {
-        System.err.println(Resources.getText("zz usage text", "jconsole"));
+        System.err.println(Resources.format(Messages.ZZ_USAGE_TEXT, "jconsole"));
     }
 
     private static void mainInit(final List<String> urls,
@@ -1003,13 +999,13 @@
                 pluginService = plugins;
             } catch (ServiceConfigurationError e) {
                 // Error occurs during initialization of plugin
-                System.out.println(Resources.getText("Fail to load plugin",
+                System.out.println(Resources.format(Messages.FAIL_TO_LOAD_PLUGIN,
                                    e.getMessage()));
             } catch (MalformedURLException e) {
                 if (JConsole.isDebug()) {
                     e.printStackTrace();
                 }
-                System.out.println(Resources.getText("Invalid plugin path",
+                System.out.println(Resources.format(Messages.INVALID_PLUGIN_PATH,
                                    e.getMessage()));
             }
         }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/LabeledComponent.java b/jdk/src/share/classes/sun/tools/jconsole/LabeledComponent.java
index 81953f4..ce045e8 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/LabeledComponent.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/LabeledComponent.java
@@ -26,7 +26,6 @@
 package sun.tools.jconsole;
 
 import java.awt.*;
-import java.awt.event.*;
 
 import javax.swing.*;
 
diff --git a/jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java b/jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java
index e41ae7c..842cb8a 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/LocalVirtualMachine.java
@@ -39,7 +39,6 @@
 // Sun private
 import sun.management.ConnectorAddressLink;
 import sun.jvmstat.monitor.HostIdentifier;
-import sun.jvmstat.monitor.Monitor;
 import sun.jvmstat.monitor.MonitoredHost;
 import sun.jvmstat.monitor.MonitoredVm;
 import sun.jvmstat.monitor.MonitoredVmUtil;
@@ -131,7 +130,7 @@
 
     private static void getMonitoredVMs(Map<Integer, LocalVirtualMachine> map) {
         MonitoredHost host;
-        Set vms;
+        Set<Integer> vms;
         try {
             host = MonitoredHost.getMonitoredHost(new HostIdentifier((String)null));
             vms = host.activeVms();
diff --git a/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java b/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java
index abd5de7..cb5bcc1 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/MBeansTab.java
@@ -52,7 +52,7 @@
     private XDataViewer viewer;
 
     public static String getTabName() {
-        return Resources.getText("MBeans");
+        return Messages.MBEANS;
     }
 
     public MBeansTab(final VMPanel vmPanel) {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/MaximizableInternalFrame.java b/jdk/src/share/classes/sun/tools/jconsole/MaximizableInternalFrame.java
index da2b91f..ab2c1bf 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/MaximizableInternalFrame.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/MaximizableInternalFrame.java
@@ -222,7 +222,7 @@
     static {
         if (JConsole.IS_WIN) {
             try {
-                Class Part =
+                Class<?> Part =
                     Class.forName("com.sun.java.swing.plaf.windows.TMSchema$Part");
                 if (Part != null) {
                     WP_MINBUTTON        = Part.getField("WP_MINBUTTON").get(null);
diff --git a/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolProxy.java b/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolProxy.java
index bc6925f..a796db0d 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolProxy.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolProxy.java
@@ -26,7 +26,6 @@
 package sun.tools.jconsole;
 
 import javax.management.ObjectName;
-import java.lang.management.ManagementFactory;
 import java.lang.management.MemoryPoolMXBean;
 import java.lang.management.MemoryUsage;
 import com.sun.management.GarbageCollectorMXBean;
@@ -34,21 +33,18 @@
 import java.util.HashMap;
 import java.util.Set;
 import java.util.Map;
-import java.util.Map.Entry;
 
 import static java.lang.management.ManagementFactory.*;
 
 public class MemoryPoolProxy {
     private String poolName;
     private ProxyClient client;
-    private ObjectName  objName;
     private MemoryPoolMXBean pool;
     private Map<ObjectName,Long> gcMBeans;
     private GcInfo lastGcInfo;
 
     public MemoryPoolProxy(ProxyClient client, ObjectName poolName) throws java.io.IOException {
         this.client = client;
-        this.objName = objName;
         this.pool = client.getMXBean(poolName, MemoryPoolMXBean.class);
         this.poolName = this.pool.getName();
         this.gcMBeans = new HashMap<ObjectName,Long>();
@@ -73,10 +69,6 @@
         return (gcMBeans.size() != 0);
     }
 
-    public ObjectName getObjectName() {
-        return objName;
-    }
-
     public MemoryPoolStat getStat() throws java.io.IOException {
         long usageThreshold = (pool.isUsageThresholdSupported()
                                   ? pool.getUsageThreshold()
diff --git a/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java b/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java
index 86cb997..869c44e 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/MemoryPoolStat.java
@@ -129,6 +129,6 @@
      * null if no GC occurs.
      */
     public MemoryUsage getAfterGcUsage() {
-        return beforeGcUsage;
+        return afterGcUsage;
     }
 }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java b/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java
index 03e2f84..756fa18 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/MemoryTab.java
@@ -38,18 +38,14 @@
 import javax.management.openmbean.CompositeData;
 import javax.swing.*;
 import javax.swing.border.*;
-import javax.swing.text.*;
 
-import sun.management.*;
 
 import static sun.tools.jconsole.Formatter.*;
-import static sun.tools.jconsole.OverviewPanel.*;
-import static sun.tools.jconsole.Resources.*;
 import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
 class MemoryTab extends Tab implements ActionListener, ItemListener {
-    JComboBox plotterChoice;
+    JComboBox<Plotter> plotterChoice;
     TimeComboBox timeComboBox;
     JButton gcButton;
 
@@ -67,19 +63,11 @@
     private static final String committedKey   = "committed";
     private static final String maxKey         = "max";
     private static final String thresholdKey   = "threshold";
-
-    private static final String usedName        = Resources.getText("Used");
-    private static final String committedName   = Resources.getText("Committed");
-    private static final String maxName         = Resources.getText("Max");
-    private static final String thresholdName   = Resources.getText("Threshold");
-
     private static final Color  usedColor      = Plotter.defaultColor;
     private static final Color  committedColor = null;
     private static final Color  maxColor       = null;
     private static final Color  thresholdColor = Color.red;
 
-    private static final String infoLabelFormat = "MemoryTab.infoLabelFormat";
-
     /*
       Hierarchy of panels and layouts for this tab:
 
@@ -105,7 +93,7 @@
 
 
     public static String getTabName() {
-        return getText("Memory");
+        return Messages.MEMORY;
     }
 
     public MemoryTab(VMPanel vmPanel) {
@@ -125,32 +113,32 @@
         topPanel.add(controlPanel, BorderLayout.CENTER);
 
         // Plotter choice
-        plotterChoice = new JComboBox();
+        plotterChoice = new JComboBox<Plotter>();
         plotterChoice.addItemListener(this);
-        controlPanel.add(new LabeledComponent(getText("Chart:"),
-                                              getMnemonicInt("Chart:"),
+        controlPanel.add(new LabeledComponent(Messages.CHART_COLON,
+                                              Resources.getMnemonicInt(Messages.CHART_COLON),
                                               plotterChoice));
 
         // Range control
         timeComboBox = new TimeComboBox();
-        controlPanel.add(new LabeledComponent(getText("Time Range:"),
-                                              getMnemonicInt("Time Range:"),
+        controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
+                                              Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
                                               timeComboBox));
 
-        gcButton = new JButton(getText("Perform GC"));
-        gcButton.setMnemonic(getMnemonicInt("Perform GC"));
+        gcButton = new JButton(Messages.PERFORM_GC);
+        gcButton.setMnemonic(Resources.getMnemonicInt(Messages.PERFORM_GC));
         gcButton.addActionListener(this);
-        gcButton.setToolTipText(getText("Perform GC.toolTip"));
+        gcButton.setToolTipText(Messages.PERFORM_GC_TOOLTIP);
         JPanel topRightPanel = new JPanel();
         topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
         topRightPanel.add(gcButton);
         topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
 
-        bottomPanel.setBorder(new CompoundBorder(new TitledBorder(getText("Details")),
+        bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Messages.DETAILS),
                                                   new EmptyBorder(10, 10, 10, 10)));
 
         details = new HTMLPane();
-        setAccessibleName(details, getText("Details"));
+        setAccessibleName(details, Messages.DETAILS);
         bottomPanel.add(new JScrollPane(details), BorderLayout.CENTER);
 
         poolChart = new PoolChart();
@@ -165,31 +153,31 @@
 
         heapPlotter = new Plotter(Plotter.Unit.BYTES) {
             public String toString() {
-                return Resources.getText("Heap Memory Usage");
+                return Messages.HEAP_MEMORY_USAGE;
             }
         };
         proxyClient.addWeakPropertyChangeListener(heapPlotter);
 
         nonHeapPlotter = new Plotter(Plotter.Unit.BYTES) {
             public String toString() {
-                return Resources.getText("Non-Heap Memory Usage");
+                return Messages.NON_HEAP_MEMORY_USAGE;
             }
         };
 
         setAccessibleName(heapPlotter,
-                          getText("MemoryTab.heapPlotter.accessibleName"));
+                          Messages.MEMORY_TAB_HEAP_PLOTTER_ACCESSIBLE_NAME);
         setAccessibleName(nonHeapPlotter,
-                          getText("MemoryTab.nonHeapPlotter.accessibleName"));
+                          Messages.MEMORY_TAB_NON_HEAP_PLOTTER_ACCESSIBLE_NAME);
 
         proxyClient.addWeakPropertyChangeListener(nonHeapPlotter);
 
-        heapPlotter.createSequence(usedKey,         usedName,      usedColor,      true);
-        heapPlotter.createSequence(committedKey,    committedName, committedColor, false);
-        heapPlotter.createSequence(maxKey,          maxName,       maxColor,       false);
+        heapPlotter.createSequence(usedKey,         Messages.USED,      usedColor,      true);
+        heapPlotter.createSequence(committedKey,    Messages.COMMITTED, committedColor, false);
+        heapPlotter.createSequence(maxKey,          Messages.MAX,       maxColor,       false);
 
-        nonHeapPlotter.createSequence(usedKey,      usedName,      usedColor,      true);
-        nonHeapPlotter.createSequence(committedKey, committedName, committedColor, false);
-        nonHeapPlotter.createSequence(maxKey,       maxName,       maxColor,       false);
+        nonHeapPlotter.createSequence(usedKey,      Messages.USED,      usedColor,      true);
+        nonHeapPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
+        nonHeapPlotter.createSequence(maxKey,       Messages.MAX,       maxColor,       false);
 
         plotterList.add(heapPlotter);
         plotterList.add(nonHeapPlotter);
@@ -202,8 +190,8 @@
         for (ObjectName objectName : objectNames) {
             String type = objectName.getKeyProperty("type");
             if (type.equals("MemoryPool")) {
-                String name = getText("MemoryPoolLabel",
-                                      objectName.getKeyProperty("name"));
+                String name = Resources.format(Messages.MEMORY_POOL_LABEL,
+                                               objectName.getKeyProperty("name"));
                 // Heap or non-heap?
                 boolean isHeap = false;
                 AttributeList al =
@@ -215,10 +203,10 @@
                 PoolPlotter poolPlotter = new PoolPlotter(objectName, name, isHeap);
                 proxyClient.addWeakPropertyChangeListener(poolPlotter);
 
-                poolPlotter.createSequence(usedKey,      usedName,      usedColor,      true);
-                poolPlotter.createSequence(committedKey, committedName, committedColor, false);
-                poolPlotter.createSequence(maxKey,       maxName,       maxColor,       false);
-                poolPlotter.createSequence(thresholdKey, thresholdName, thresholdColor, false);
+                poolPlotter.createSequence(usedKey,      Messages.USED,      usedColor,      true);
+                poolPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
+                poolPlotter.createSequence(maxKey,       Messages.MAX,       maxColor,       false);
+                poolPlotter.createSequence(thresholdKey, Messages.THRESHOLD, thresholdColor, false);
                 poolPlotter.setUseDashedTransitions(thresholdKey, true);
 
                 if (isHeap) {
@@ -286,7 +274,6 @@
                 max       = new long[n];
                 threshold = new long[n];
                 timeStamp = System.currentTimeMillis();
-                int poolCount = 0;
 
                 for (int i = 0; i < n; i++) {
                     Plotter plotter = plotterList.get(i);
@@ -400,22 +387,22 @@
         //long time = plotter.getLastTimeStamp();
         long time = System.currentTimeMillis();
         String timeStamp = formatDateTime(time);
-        text += newRow(getText("Time"), timeStamp);
+        text += newRow(Messages.TIME, timeStamp);
 
         long used = plotter.getLastValue(usedKey);
         long committed = plotter.getLastValue(committedKey);
         long max = plotter.getLastValue(maxKey);
         long threshold = plotter.getLastValue(thresholdKey);
 
-        text += newRow(getText("Used"), formatKBytes(used));
+        text += newRow(Messages.USED, formatKBytes(used));
         if (committed > 0L) {
-            text += newRow(getText("Committed"), formatKBytes(committed));
+            text += newRow(Messages.COMMITTED, formatKBytes(committed));
         }
         if (max > 0L) {
-            text += newRow(getText("Max"), formatKBytes(max));
+            text += newRow(Messages.MAX, formatKBytes(max));
         }
         if (threshold > 0L) {
-            text += newRow(getText("Usage Threshold"), formatKBytes(threshold));
+            text += newRow(Messages.USAGE_THRESHOLD, formatKBytes(threshold));
         }
 
         try {
@@ -427,11 +414,11 @@
                 String gcName = garbageCollectorMBean.getName();
                 long gcCount = garbageCollectorMBean.getCollectionCount();
                 long gcTime = garbageCollectorMBean.getCollectionTime();
-                String str = getText("GC time details", justify(formatTime(gcTime), 14),
-                                     gcName,
-                                     String.format("%,d",gcCount));
+                String str = Resources.format(Messages.GC_TIME_DETAILS, justify(formatTime(gcTime), 14),
+                                              gcName,
+                                              String.format("%,d",gcCount));
                 if (!descPrinted) {
-                    text += newRow(getText("GC time"), str);
+                    text += newRow(Messages.GC_TIME, str);
                     descPrinted = true;
                 } else {
                     text += newRow(null, str);
@@ -465,8 +452,8 @@
             this.isHeap     = isHeap;
 
             setAccessibleName(this,
-                              getText("MemoryTab.poolPlotter.accessibleName",
-                                      name));
+                              Resources.format(Messages.MEMORY_TAB_POOL_PLOTTER_ACCESSIBLE_NAME,
+                                               name));
         }
 
 
@@ -627,7 +614,7 @@
             g.setColor(nonHeapColor);
             g.fillRect(nonHeapRect.x + 1, nonHeapRect.y + 1, nonHeapRect.width - 1, nonHeapRect.height - 1);
 
-            String str = getText("Heap");
+            String str = Messages.HEAP;
             int stringWidth = fm.stringWidth(str);
             int x = heapRect.x + (heapRect.width - stringWidth) / 2;
             int y = heapRect.y + heapRect.height - 6;
@@ -639,7 +626,7 @@
             g.setColor(Color.black);
             g.drawString(str, x, y);
 
-            str = getText("Non-Heap");
+            str = Messages.NON_HEAP;
             stringWidth = fm.stringWidth(str);
             x = nonHeapRect.x + (nonHeapRect.width - stringWidth) / 2;
             y = nonHeapRect.y + nonHeapRect.height - 6;
@@ -728,26 +715,26 @@
 
         protected class AccessiblePoolChart extends AccessibleJPanel {
             public String getAccessibleName() {
-                String name = getText("MemoryTab.poolChart.accessibleName");
+                String name = Messages.MEMORY_TAB_POOL_CHART_ACCESSIBLE_NAME;
 
                 String keyValueList = "";
                 for (PoolPlotter poolPlotter : poolPlotters) {
                     String value = (poolPlotter.value * 100 / poolPlotter.max) + "%";
                     // Assume format string ends with newline
                     keyValueList +=
-                        getText("Plotter.accessibleName.keyAndValue",
-                                poolPlotter.toString(), value);
+                        Resources.format(Messages.PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE,
+                                         poolPlotter.toString(), value);
                     if (poolPlotter.threshold > 0L) {
                         String threshold =
                             (poolPlotter.threshold * 100 / poolPlotter.max) + "%";
                         if (poolPlotter.value > poolPlotter.threshold) {
                             keyValueList +=
-                                getText("MemoryTab.poolChart.aboveThreshold",
-                                        threshold);
+                               Resources.format(Messages.MEMORY_TAB_POOL_CHART_ABOVE_THRESHOLD,
+                                                threshold);
                         } else {
                             keyValueList +=
-                                getText("MemoryTab.poolChart.belowThreshold",
-                                        threshold);
+                                    Resources.format(Messages.MEMORY_TAB_POOL_CHART_BELOW_THRESHOLD,
+                                                     threshold);
                         }
                     }
                 }
@@ -767,14 +754,14 @@
 
     private static class MemoryOverviewPanel extends OverviewPanel {
         MemoryOverviewPanel() {
-            super(getText("Heap Memory Usage"), usedKey, usedName, Plotter.Unit.BYTES);
+            super(Messages.HEAP_MEMORY_USAGE, usedKey, Messages.USED, Plotter.Unit.BYTES);
         }
 
         private void updateMemoryInfo(long used, long committed, long max) {
-            getInfoLabel().setText(getText(infoLabelFormat,
-                                           formatBytes(used, true),
-                                           formatBytes(committed, true),
-                                           formatBytes(max, true)));
+            getInfoLabel().setText(Resources.format(Messages.MEMORY_TAB_INFO_LABEL_FORMAT,
+                                                    formatBytes(used, true),
+                                                    formatBytes(committed, true),
+                                                    formatBytes(max, true)));
         }
     }
 }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/Messages.java b/jdk/src/share/classes/sun/tools/jconsole/Messages.java
new file mode 100644
index 0000000..27001f2
--- /dev/null
+++ b/jdk/src/share/classes/sun/tools/jconsole/Messages.java
@@ -0,0 +1,316 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package sun.tools.jconsole;
+
+
+/**
+ * Class that contains localized messages.
+ *
+ */
+final public class Messages {
+    private static final String BUNDLE_NAME = "sun.tools.jconsole.resources.messages";
+
+    static {
+        Resources.initializeMessages(Messages.class, BUNDLE_NAME);
+    }
+    // TODO:
+    // The names of some of the constants below looks strange.
+    // That's because they  were generated programmatically
+    // from the messages. They should be cleaned up,
+    // ___ should be removed etc.
+    public static String ONE_DAY;
+    public static String ONE_HOUR;
+    public static String ONE_MIN;
+    public static String ONE_MONTH;
+    public static String ONE_YEAR;
+    public static String TWO_HOURS;
+    public static String THREE_HOURS;
+    public static String THREE_MONTHS;
+    public static String FIVE_MIN;
+    public static String SIX_HOURS;
+    public static String SIX_MONTHS;
+    public static String SEVEN_DAYS;
+    public static String TEN_MIN;
+    public static String TWELVE_HOURS;
+    public static String THIRTY_MIN;
+    public static String LESS_THAN;
+    public static String A_LOT_LESS_THAN;
+    public static String GREATER_THAN;
+    public static String ACTION_CAPITALIZED;
+    public static String ACTION_INFO_CAPITALIZED;
+    public static String ALL;
+    public static String ARCHITECTURE;
+    public static String ATTRIBUTE;
+    public static String ATTRIBUTE_VALUE;
+    public static String ATTRIBUTE_VALUES;
+    public static String ATTRIBUTES;
+    public static String BLANK;
+    public static String BLOCKED_COUNT_WAITED_COUNT;
+    public static String BOOT_CLASS_PATH;
+    public static String BORDERED_COMPONENT_MORE_OR_LESS_BUTTON_TOOLTIP;
+    public static String CPU_USAGE;
+    public static String CPU_USAGE_FORMAT;
+    public static String CANCEL;
+    public static String CASCADE;
+    public static String CHART_COLON;
+    public static String CLASS_PATH;
+    public static String CLASS_NAME;
+    public static String CLASS_TAB_INFO_LABEL_FORMAT;
+    public static String CLASS_TAB_LOADED_CLASSES_PLOTTER_ACCESSIBLE_NAME;
+    public static String CLASSES;
+    public static String CLOSE;
+    public static String COLUMN_NAME;
+    public static String COLUMN_PID;
+    public static String COMMITTED_MEMORY;
+    public static String COMMITTED_VIRTUAL_MEMORY;
+    public static String COMMITTED;
+    public static String CONNECT;
+    public static String CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP;
+    public static String CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION;
+    public static String CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME;
+    public static String CONNECT_DIALOG_MASTHEAD_TITLE;
+    public static String CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME;
+    public static String CONNECT_DIALOG_TITLE;
+    public static String CONNECTED_PUNCTUATION_CLICK_TO_DISCONNECT_;
+    public static String CONNECTION_FAILED;
+    public static String CONNECTION;
+    public static String CONNECTION_NAME;
+    public static String CONNECTION_NAME__DISCONNECTED_;
+    public static String CONSTRUCTOR;
+    public static String CURRENT_CLASSES_LOADED;
+    public static String CURRENT_HEAP_SIZE;
+    public static String CURRENT_VALUE;
+    public static String CREATE;
+    public static String DAEMON_THREADS;
+    public static String DISCONNECTED_PUNCTUATION_CLICK_TO_CONNECT_;
+    public static String DOUBLE_CLICK_TO_EXPAND_FORWARD_SLASH_COLLAPSE;
+    public static String DOUBLE_CLICK_TO_VISUALIZE;
+    public static String DESCRIPTION;
+    public static String DESCRIPTOR;
+    public static String DETAILS;
+    public static String DETECT_DEADLOCK;
+    public static String DETECT_DEADLOCK_TOOLTIP;
+    public static String DIMENSION_IS_NOT_SUPPORTED_COLON;
+    public static String DISCARD_CHART;
+    public static String DURATION_DAYS_HOURS_MINUTES;
+    public static String DURATION_HOURS_MINUTES;
+    public static String DURATION_MINUTES;
+    public static String DURATION_SECONDS;
+    public static String EMPTY_ARRAY;
+    public static String ERROR;
+    public static String ERROR_COLON_MBEANS_ALREADY_EXIST;
+    public static String ERROR_COLON_MBEANS_DO_NOT_EXIST;
+    public static String EVENT;
+    public static String EXIT;
+    public static String FAIL_TO_LOAD_PLUGIN;
+    public static String FILE_CHOOSER_FILE_EXISTS_CANCEL_OPTION;
+    public static String FILE_CHOOSER_FILE_EXISTS_MESSAGE;
+    public static String FILE_CHOOSER_FILE_EXISTS_OK_OPTION;
+    public static String FILE_CHOOSER_FILE_EXISTS_TITLE;
+    public static String FILE_CHOOSER_SAVED_FILE;
+    public static String FILE_CHOOSER_SAVE_FAILED_MESSAGE;
+    public static String FILE_CHOOSER_SAVE_FAILED_TITLE;
+    public static String FREE_PHYSICAL_MEMORY;
+    public static String FREE_SWAP_SPACE;
+    public static String GARBAGE_COLLECTOR;
+    public static String GC_INFO;
+    public static String GC_TIME;
+    public static String GC_TIME_DETAILS;
+    public static String HEAP_MEMORY_USAGE;
+    public static String HEAP;
+    public static String HELP_ABOUT_DIALOG_ACCESSIBLE_DESCRIPTION;
+    public static String HELP_ABOUT_DIALOG_JCONSOLE_VERSION;
+    public static String HELP_ABOUT_DIALOG_JAVA_VERSION;
+    public static String HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME;
+    public static String HELP_ABOUT_DIALOG_MASTHEAD_TITLE;
+    public static String HELP_ABOUT_DIALOG_TITLE;
+    public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK;
+    public static String HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL;
+    public static String HELP_MENU_ABOUT_TITLE;
+    public static String HELP_MENU_USER_GUIDE_TITLE;
+    public static String HELP_MENU_TITLE;
+    public static String HOTSPOT_MBEANS_ELLIPSIS;
+    public static String HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION;
+    public static String IMPACT;
+    public static String INFO;
+    public static String INFO_CAPITALIZED;
+    public static String INVALID_PLUGIN_PATH;
+    public static String INVALID_URL;
+    public static String IS;
+    public static String JAVA_MONITORING___MANAGEMENT_CONSOLE;
+    public static String JCONSOLE_COLON_;
+    public static String JCONSOLE_VERSION; // in version template
+    public static String JCONSOLE_ACCESSIBLE_DESCRIPTION;
+    public static String JIT_COMPILER;
+    public static String LIBRARY_PATH;
+    public static String LIVE_THREADS;
+    public static String LOADED;
+    public static String LOCAL_PROCESS_COLON;
+    public static String MASTHEAD_FONT;
+    public static String MANAGEMENT_NOT_ENABLED;
+    public static String MANAGEMENT_WILL_BE_ENABLED;
+    public static String MBEAN_ATTRIBUTE_INFO;
+    public static String MBEAN_INFO;
+    public static String MBEAN_NOTIFICATION_INFO;
+    public static String MBEAN_OPERATION_INFO;
+    public static String MBEANS;
+    public static String MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON;
+    public static String MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP;
+    public static String MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE;
+    public static String MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE;
+    public static String MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON;
+    public static String MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP;
+    public static String MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON;
+    public static String MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP;
+    public static String MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE;
+    public static String MBEANS_TAB_TABULAR_NAVIGATION_SINGLE;
+    public static String MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON;
+    public static String MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP;
+    public static String MANAGE_HOTSPOT_MBEANS_IN_COLON_;
+    public static String MAX;
+    public static String MAXIMUM_HEAP_SIZE;
+    public static String MEMORY;
+    public static String MEMORY_POOL_LABEL;
+    public static String MEMORY_TAB_HEAP_PLOTTER_ACCESSIBLE_NAME;
+    public static String MEMORY_TAB_INFO_LABEL_FORMAT;
+    public static String MEMORY_TAB_NON_HEAP_PLOTTER_ACCESSIBLE_NAME;
+    public static String MEMORY_TAB_POOL_CHART_ABOVE_THRESHOLD;
+    public static String MEMORY_TAB_POOL_CHART_ACCESSIBLE_NAME;
+    public static String MEMORY_TAB_POOL_CHART_BELOW_THRESHOLD;
+    public static String MEMORY_TAB_POOL_PLOTTER_ACCESSIBLE_NAME;
+    public static String MESSAGE;
+    public static String METHOD_SUCCESSFULLY_INVOKED;
+    public static String MINIMIZE_ALL;
+    public static String MONITOR_LOCKED;
+    public static String NAME;
+    public static String NAME_STATE;
+    public static String NAME_STATE_LOCK_NAME;
+    public static String NAME_STATE_LOCK_NAME_LOCK_OWNER;
+    public static String NAME_AND_BUILD;// in version template
+    public static String NEW_CONNECTION_ELLIPSIS;
+    public static String NO_DEADLOCK_DETECTED;
+    public static String NON_HEAP_MEMORY_USAGE;
+    public static String NON_HEAP;
+    public static String NOTIFICATION;
+    public static String NOTIFICATION_BUFFER;
+    public static String NOTIFICATIONS;
+    public static String NOTIF_TYPES;
+    public static String NUMBER_OF_THREADS;
+    public static String NUMBER_OF_LOADED_CLASSES;
+    public static String NUMBER_OF_PROCESSORS;
+    public static String OBJECT_NAME;
+    public static String OPERATING_SYSTEM;
+    public static String OPERATION;
+    public static String OPERATION_INVOCATION;
+    public static String OPERATION_RETURN_VALUE;
+    public static String OPERATIONS;
+    public static String OVERVIEW;
+    public static String OVERVIEW_PANEL_PLOTTER_ACCESSIBLE_NAME;
+    public static String PARAMETER;
+    public static String PASSWORD_COLON_;
+    public static String PASSWORD_ACCESSIBLE_NAME;
+    public static String PEAK;
+    public static String PERFORM_GC;
+    public static String PERFORM_GC_TOOLTIP;
+    public static String PLOTTER_ACCESSIBLE_NAME;
+    public static String PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE;
+    public static String PLOTTER_ACCESSIBLE_NAME_NO_DATA;
+    public static String PLOTTER_SAVE_AS_MENU_ITEM;
+    public static String PLOTTER_TIME_RANGE_MENU;
+    public static String PROBLEM_ADDING_LISTENER;
+    public static String PROBLEM_DISPLAYING_MBEAN;
+    public static String PROBLEM_INVOKING;
+    public static String PROBLEM_REMOVING_LISTENER;
+    public static String PROBLEM_SETTING_ATTRIBUTE;
+    public static String PROCESS_CPU_TIME;
+    public static String READABLE;
+    public static String RECONNECT;
+    public static String REMOTE_PROCESS_COLON;
+    public static String REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME;
+    public static String RESTORE_ALL;
+    public static String RETURN_TYPE;
+    public static String SEQ_NUM;
+    public static String SIZE_BYTES;
+    public static String SIZE_GB;
+    public static String SIZE_KB;
+    public static String SIZE_MB;
+    public static String SOURCE;
+    public static String STACK_TRACE;
+    public static String SUMMARY_TAB_HEADER_DATE_TIME_FORMAT;
+    public static String SUMMARY_TAB_PENDING_FINALIZATION_LABEL;
+    public static String SUMMARY_TAB_PENDING_FINALIZATION_VALUE;
+    public static String SUMMARY_TAB_TAB_NAME;
+    public static String SUMMARY_TAB_VM_VERSION;
+    public static String THREADS;
+    public static String THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME;
+    public static String THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME;
+    public static String THRESHOLD;
+    public static String TILE;
+    public static String TIME_RANGE_COLON;
+    public static String TIME;
+    public static String TIME_STAMP;
+    public static String TOTAL_LOADED;
+    public static String TOTAL_CLASSES_LOADED;
+    public static String TOTAL_CLASSES_UNLOADED;
+    public static String TOTAL_COMPILE_TIME;
+    public static String TOTAL_PHYSICAL_MEMORY;
+    public static String TOTAL_THREADS_STARTED;
+    public static String TOTAL_SWAP_SPACE;
+    public static String TYPE;
+    public static String UNAVAILABLE;
+    public static String UNKNOWN_CAPITALIZED;
+    public static String UNKNOWN_HOST;
+    public static String UNREGISTER;
+    public static String UPTIME;
+    public static String USAGE_THRESHOLD;
+    public static String REMOTE_TF_USAGE;
+    public static String USED;
+    public static String USERNAME_COLON_;
+    public static String USERNAME_ACCESSIBLE_NAME;
+    public static String USER_DATA;
+    public static String VIRTUAL_MACHINE;
+    public static String VM_ARGUMENTS;
+    public static String VMINTERNAL_FRAME_ACCESSIBLE_DESCRIPTION;
+    public static String VALUE;
+    public static String VENDOR;
+    public static String VERBOSE_OUTPUT;
+    public static String VERBOSE_OUTPUT_TOOLTIP;
+    public static String VIEW;
+    public static String WINDOW;
+    public static String WINDOWS;
+    public static String WRITABLE;
+    public static String CONNECTION_FAILED1;
+    public static String CONNECTION_FAILED2;
+    public static String CONNECTION_LOST1;
+    public static String CONNECTING_TO1;
+    public static String CONNECTING_TO2;
+    public static String DEADLOCK_TAB;
+    public static String DEADLOCK_TAB_N;
+    public static String EXPAND;
+    public static String KBYTES;
+    public static String PLOT;
+    public static String VISUALIZE;
+    public static String ZZ_USAGE_TEXT;
+}
diff --git a/jdk/src/share/classes/sun/tools/jconsole/OverviewPanel.java b/jdk/src/share/classes/sun/tools/jconsole/OverviewPanel.java
index 4603b97..269dbd2 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/OverviewPanel.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/OverviewPanel.java
@@ -26,14 +26,12 @@
 package sun.tools.jconsole;
 
 import java.awt.*;
-import java.awt.event.*;
 
 import javax.swing.*;
-import javax.swing.border.*;
+
 
 import static javax.swing.SwingConstants.*;
 import static sun.tools.jconsole.JConsole.*;
-import static sun.tools.jconsole.Resources.*;
 import static sun.tools.jconsole.Utilities.*;
 
 
@@ -68,7 +66,7 @@
             }
             plotter.createSequence(plotterKey, plotterName, PLOTTER_COLOR, true);
             setAccessibleName(plotter,
-                              getText("OverviewPanel.plotter.accessibleName",
+                              Resources.format(Messages.OVERVIEW_PANEL_PLOTTER_ACCESSIBLE_NAME,
                                       title));
             setPlotter(plotter);
         }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/OverviewTab.java b/jdk/src/share/classes/sun/tools/jconsole/OverviewTab.java
index 74a14ec..3b89f6e 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/OverviewTab.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/OverviewTab.java
@@ -26,15 +26,11 @@
 package sun.tools.jconsole;
 
 import java.awt.*;
-import java.lang.reflect.InvocationTargetException;
 import java.util.ArrayList;
 
 import javax.swing.*;
 import javax.swing.border.*;
 
-import static sun.tools.jconsole.JConsole.*;
-import static sun.tools.jconsole.Resources.*;
-
 
 @SuppressWarnings("serial")
 class OverviewTab extends Tab {
@@ -42,7 +38,7 @@
     TimeComboBox timeComboBox;
 
     public static String getTabName() {
-        return getText("Overview");
+        return Messages.OVERVIEW;
     }
 
     public OverviewTab(VMPanel vmPanel) {
@@ -58,8 +54,8 @@
         topPanel.add(controlPanel, BorderLayout.CENTER);
 
         timeComboBox = new TimeComboBox();
-        LabeledComponent lc = new LabeledComponent(Resources.getText("Time Range:"),
-                                                   getMnemonicInt("Time Range:"),
+        LabeledComponent lc = new LabeledComponent(Messages.TIME_RANGE_COLON,
+                                                   Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
                                                    timeComboBox);
         controlPanel.add(lc);
 
diff --git a/jdk/src/share/classes/sun/tools/jconsole/Plotter.java b/jdk/src/share/classes/sun/tools/jconsole/Plotter.java
index 351187e..a9dbece 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/Plotter.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/Plotter.java
@@ -38,14 +38,11 @@
 import javax.swing.filechooser.*;
 import javax.swing.filechooser.FileFilter;
 
-import com.sun.tools.jconsole.JConsoleContext;
 
-import static com.sun.tools.jconsole.JConsoleContext.ConnectionState.*;
+import com.sun.tools.jconsole.JConsoleContext;
 
 import static sun.tools.jconsole.Formatter.*;
 import static sun.tools.jconsole.ProxyClient.*;
-import static sun.tools.jconsole.Resources.*;
-import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
 public class Plotter extends JComponent
@@ -56,22 +53,22 @@
     }
 
     static final String[] rangeNames = {
-        Resources.getText(" 1 min"),
-        Resources.getText(" 5 min"),
-        Resources.getText("10 min"),
-        Resources.getText("30 min"),
-        Resources.getText(" 1 hour"),
-        Resources.getText(" 2 hours"),
-        Resources.getText(" 3 hours"),
-        Resources.getText(" 6 hours"),
-        Resources.getText("12 hours"),
-        Resources.getText(" 1 day"),
-        Resources.getText(" 7 days"),
-        Resources.getText(" 1 month"),
-        Resources.getText(" 3 months"),
-        Resources.getText(" 6 months"),
-        Resources.getText(" 1 year"),
-        Resources.getText("All")
+        Messages.ONE_MIN,
+        Messages.FIVE_MIN,
+        Messages.TEN_MIN,
+        Messages.THIRTY_MIN,
+        Messages.ONE_HOUR,
+        Messages.TWO_HOURS,
+        Messages.THREE_HOURS,
+        Messages.SIX_HOURS,
+        Messages.TWELVE_HOURS,
+        Messages.ONE_DAY,
+        Messages.SEVEN_DAYS,
+        Messages.ONE_MONTH,
+        Messages.THREE_MONTHS,
+        Messages.SIX_MONTHS,
+        Messages.ONE_YEAR,
+        Messages.ALL
     };
 
     static final int[] rangeValues = {
@@ -247,9 +244,9 @@
     @Override
     public JPopupMenu getComponentPopupMenu() {
         if (popupMenu == null) {
-            popupMenu = new JPopupMenu(Resources.getText("Chart:"));
-            timeRangeMenu = new JMenu(Resources.getText("Plotter.timeRangeMenu"));
-            timeRangeMenu.setMnemonic(getMnemonicInt("Plotter.timeRangeMenu"));
+            popupMenu = new JPopupMenu(Messages.CHART_COLON);
+            timeRangeMenu = new JMenu(Messages.PLOTTER_TIME_RANGE_MENU);
+            timeRangeMenu.setMnemonic(Resources.getMnemonicInt(Messages.PLOTTER_TIME_RANGE_MENU));
             popupMenu.add(timeRangeMenu);
             menuRBs = new JRadioButtonMenuItem[rangeNames.length];
             ButtonGroup rbGroup = new ButtonGroup();
@@ -265,8 +262,8 @@
 
             popupMenu.addSeparator();
 
-            saveAsMI = new JMenuItem(getText("Plotter.saveAsMenuItem"));
-            saveAsMI.setMnemonic(getMnemonicInt("Plotter.saveAsMenuItem"));
+            saveAsMI = new JMenuItem(Messages.PLOTTER_SAVE_AS_MENU_ITEM);
+            saveAsMI.setMnemonic(Resources.getMnemonicInt(Messages.PLOTTER_SAVE_AS_MENU_ITEM));
             saveAsMI.addActionListener(this);
             popupMenu.add(saveAsMI);
         }
@@ -318,9 +315,9 @@
 
             out.close();
             JOptionPane.showMessageDialog(this,
-                                          getText("FileChooser.savedFile",
-                                                  file.getAbsolutePath(),
-                                                  file.length()));
+                                          Resources.format(Messages.FILE_CHOOSER_SAVED_FILE,
+                                                           file.getAbsolutePath(),
+                                                           file.length()));
         } catch (IOException ex) {
             String msg = ex.getLocalizedMessage();
             String path = file.getAbsolutePath();
@@ -328,9 +325,10 @@
                 msg = msg.substring(path.length()).trim();
             }
             JOptionPane.showMessageDialog(this,
-                                          getText("FileChooser.saveFailed.message",
-                                                  path, msg),
-                                          getText("FileChooser.saveFailed.title"),
+                                          Resources.format(Messages.FILE_CHOOSER_SAVE_FAILED_MESSAGE,
+                                                           path,
+                                                           msg),
+                                          Messages.FILE_CHOOSER_SAVE_FAILED_TITLE,
                                           JOptionPane.ERROR_MESSAGE);
         }
     }
@@ -1020,13 +1018,13 @@
                 }
 
                 if (file.exists()) {
-                    String okStr = getText("FileChooser.fileExists.okOption");
-                    String cancelStr = getText("FileChooser.fileExists.cancelOption");
+                    String okStr = Messages.FILE_CHOOSER_FILE_EXISTS_OK_OPTION;
+                    String cancelStr = Messages.FILE_CHOOSER_FILE_EXISTS_CANCEL_OPTION;
                     int ret =
                         JOptionPane.showOptionDialog(this,
-                                                     getText("FileChooser.fileExists.message",
-                                                             file.getName()),
-                                                     getText("FileChooser.fileExists.title"),
+                                                     Resources.format(Messages.FILE_CHOOSER_FILE_EXISTS_MESSAGE,
+                                                                      file.getName()),
+                                                     Messages.FILE_CHOOSER_FILE_EXISTS_TITLE,
                                                      JOptionPane.OK_CANCEL_OPTION,
                                                      JOptionPane.WARNING_MESSAGE,
                                                      null,
@@ -1053,7 +1051,7 @@
     protected class AccessiblePlotter extends AccessibleJComponent {
         private static final long serialVersionUID = -3847205410473510922L;
         protected AccessiblePlotter() {
-            setAccessibleName(getText("Plotter.accessibleName"));
+            setAccessibleName(Messages.PLOTTER_ACCESSIBLE_NAME);
         }
 
         @Override
@@ -1067,7 +1065,7 @@
                         String value = "null";
                         if (seq.size > 0) {
                             if (unit == Unit.BYTES) {
-                                value = getText("Size Bytes", seq.value(seq.size - 1));
+                                value = Resources.format(Messages.SIZE_BYTES, seq.value(seq.size - 1));
                             } else {
                                 value =
                                     getFormattedValue(seq.value(seq.size - 1), false) +
@@ -1076,13 +1074,13 @@
                         }
                         // Assume format string ends with newline
                         keyValueList +=
-                            getText("Plotter.accessibleName.keyAndValue",
+                            Resources.format(Messages.PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE,
                                     seq.key, value);
                     }
                 }
                 name += "\n" + keyValueList + ".";
             } else {
-                name += "\n" + getText("Plotter.accessibleName.noData");
+                name += "\n" + Messages.PLOTTER_ACCESSIBLE_NAME_NO_DATA;
             }
             return name;
         }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/PlotterPanel.java b/jdk/src/share/classes/sun/tools/jconsole/PlotterPanel.java
index f9cc125..da6b2cc 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/PlotterPanel.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/PlotterPanel.java
@@ -25,7 +25,6 @@
 
 package sun.tools.jconsole;
 
-import java.awt.*;
 import java.awt.event.*;
 
 import javax.accessibility.*;
diff --git a/jdk/src/share/classes/sun/tools/jconsole/ProxyClient.java b/jdk/src/share/classes/sun/tools/jconsole/ProxyClient.java
index 1078003..88cf8f7 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/ProxyClient.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/ProxyClient.java
@@ -27,7 +27,6 @@
 
 import com.sun.management.HotSpotDiagnosticMXBean;
 import com.sun.tools.jconsole.JConsoleContext;
-import com.sun.tools.jconsole.JConsoleContext.ConnectionState;
 import java.beans.PropertyChangeListener;
 import java.beans.PropertyChangeEvent;
 import java.io.IOException;
@@ -512,7 +511,7 @@
 
     public String toString() {
         if (!isConnected()) {
-            return Resources.getText("ConnectionName (disconnected)", displayName);
+            return Resources.format(Messages.CONNECTION_NAME__DISCONNECTED_, displayName);
         } else {
             return displayName;
         }
@@ -603,10 +602,10 @@
                 assert(false);
             }
         }
-        Set mbeans = server.queryNames(name, null);
+        Set<ObjectName> mbeans = server.queryNames(name, null);
         Map<ObjectName,MBeanInfo> result =
             new HashMap<ObjectName,MBeanInfo>(mbeans.size());
-        Iterator iterator = mbeans.iterator();
+        Iterator<ObjectName> iterator = mbeans.iterator();
         while (iterator.hasNext()) {
             Object object = iterator.next();
             if (object instanceof ObjectName) {
@@ -712,10 +711,10 @@
                 // should not reach here
                 assert(false);
             }
-            Set mbeans = server.queryNames(poolName, null);
+            Set<ObjectName> mbeans = server.queryNames(poolName, null);
             if (mbeans != null) {
                 memoryPoolProxies = new ArrayList<MemoryPoolProxy>();
-                Iterator iterator = mbeans.iterator();
+                Iterator<ObjectName> iterator = mbeans.iterator();
                 while (iterator.hasNext()) {
                     ObjectName objName = (ObjectName) iterator.next();
                     MemoryPoolProxy p = new MemoryPoolProxy(this, objName);
@@ -738,10 +737,10 @@
                 // should not reach here
                 assert(false);
             }
-            Set mbeans = server.queryNames(gcName, null);
+            Set<ObjectName> mbeans = server.queryNames(gcName, null);
             if (mbeans != null) {
                 garbageCollectorMBeans = new ArrayList<GarbageCollectorMXBean>();
-                Iterator iterator = mbeans.iterator();
+                Iterator<ObjectName> iterator = mbeans.iterator();
                 while (iterator.hasNext()) {
                     ObjectName on = (ObjectName) iterator.next();
                     String name = GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE +
diff --git a/jdk/src/share/classes/sun/tools/jconsole/Resources.java b/jdk/src/share/classes/sun/tools/jconsole/Resources.java
index 26e768b..e7ced47 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/Resources.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/Resources.java
@@ -25,89 +25,185 @@
 
 package sun.tools.jconsole;
 
+import java.awt.event.KeyEvent;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
 import java.text.MessageFormat;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.MissingResourceException;
 import java.util.ResourceBundle;
 
-import sun.tools.jconsole.resources.JConsoleResources;
-
 /**
- * Provides resource support for jconsole.
+ * Toolkit that provides resource support for JConsole.
  */
 public final class Resources {
+    private static Map<String, Integer> MNEMONIC_LOOKUP = Collections
+            .synchronizedMap(new HashMap<String, Integer>());
 
-    private static final Object lock = new Object();
-    private static JConsoleResources resources = null;
-    static {
+    private Resources() {
+        throw new AssertionError();
+    }
+
+    /**
+     * Convenience method for {@link MessageFormat#format(String, Object...)}.
+     *
+     * @param pattern the pattern
+     * @param objects the arguments for the pattern
+     *
+     * @return a formatted string
+     */
+    public static String format(String pattern, Object... arguments) {
+            return MessageFormat.format(pattern, arguments);
+    }
+
+    /**
+     * Returns the mnemonic for a message.
+     *
+     * @param message the message
+     *
+     * @return the mnemonic <code>int</code>
+     */
+    public static int getMnemonicInt(String message) {
+        Integer integer = MNEMONIC_LOOKUP.get(message);
+        if (integer != null) {
+            return integer.intValue();
+        }
+        return 0;
+    }
+
+    /**
+     * Initializes all non-final public static fields in the given class with
+     * messages from a {@link ResourceBundle}.
+     *
+     * @param clazz the class containing the fields
+     */
+    public static void initializeMessages(Class<?> clazz, String rbName) {
+        ResourceBundle rb = null;
         try {
-            resources =
-                (JConsoleResources)ResourceBundle.getBundle("sun.tools.jconsole.resources.JConsoleResources");
-        } catch (MissingResourceException e) {
-            // gracefully handle this later
+            rb = ResourceBundle.getBundle(rbName);
+        } catch (MissingResourceException mre) {
+            // fall through, handled later
+        }
+        for (Field field : clazz.getFields()) {
+            if (isWritableField(field)) {
+                String key = field.getName();
+                String message = getMessage(rb, key);
+                int mnemonicInt = findMnemonicInt(message);
+                message = removeMnemonicAmpersand(message);
+                message = replaceWithPlatformLineFeed(message);
+                setFieldValue(field, message);
+                MNEMONIC_LOOKUP.put(message, mnemonicInt);
+            }
         }
     }
 
-    private Resources() { throw new AssertionError(); }
-
-    /**
-     * Returns the text of the jconsole resource for the specified key
-     * formatted with the specified arguments.
-     *
-     */
-    public static String getText(String key, Object... args) {
-        String format = getString(key);
-        if (format == null) {
-            format = "missing resource key: key = \"" + key + "\", " +
-                "arguments = \"{0}\", \"{1}\", \"{2}\"";
-        }
-        return formatMessage(format, args);
-    }
-
-    static String formatMessage(String format, Object... args) {
-        String ss = null;
-        synchronized (lock) {
-            /*
-             * External synchronization required for safe use of
-             * java.text.MessageFormat:
-             */
-            ss = MessageFormat.format(format, args);
-        }
-        return ss;
+    private static boolean isWritableField(Field field) {
+        int modifiers = field.getModifiers();
+        return Modifier.isPublic(modifiers) && Modifier.isStatic(modifiers)
+                && !Modifier.isFinal(modifiers);
     }
 
     /**
-     * Returns the mnemonic keycode int of the jconsole resource for the specified key.
+     * Returns the message corresponding to the key in the bundle or a text
+     * describing it's missing.
      *
+     * @param rb the resource bundle
+     * @param key the key
+     *
+     * @return the message
      */
-    public static int getMnemonicInt(String key) {
-        int mnemonic = 0;
-        if (resources != null) {
-            Object obj = resources.getObject(key+".mnemonic");
-            if (obj instanceof Character) {
-                mnemonic = (int)(Character)obj;
-                if (mnemonic >= 'a' && mnemonic <='z') {
-                    mnemonic -= ('a' - 'A');
+    private static String getMessage(ResourceBundle rb, String key) {
+        if (rb == null) {
+            return "missing resource bundle";
+        }
+        try {
+            return rb.getString(key);
+        } catch (MissingResourceException mre) {
+            return "missing message for key = \"" + key
+                    + "\" in resource bundle ";
+        }
+    }
+
+    private static void setFieldValue(Field field, String value) {
+        try {
+            field.set(null, value);
+        } catch (IllegalArgumentException | IllegalAccessException e) {
+            throw new Error("Unable to access or set message for field " + field.getName());
+        }
+    }
+
+    /**
+     * Returns a {@link String} where all <code>\n</code> in the <text> have
+     * been replaced with the line separator for the platform.
+     *
+     * @param text the to be replaced
+     *
+     * @return the replaced text
+     */
+    private static String replaceWithPlatformLineFeed(String text) {
+        return text.replace("\n", System.getProperty("line.separator"));
+    }
+
+    /**
+     * Removes the mnemonic identifier (<code>&</code>) from a string unless
+     * it's escaped by <code>&&</code> or placed at the end.
+     *
+     * @param message the message
+     *
+     * @return a message with the mnemonic identifier removed
+     */
+    private static String removeMnemonicAmpersand(String message) {
+        StringBuilder s = new StringBuilder();
+        for (int i = 0; i < message.length(); i++) {
+            char current = message.charAt(i);
+            if (current != '&' || i == message.length() - 1
+                    || message.charAt(i + 1) == '&') {
+                s.append(current);
+            }
+        }
+        return s.toString();
+    }
+
+    /**
+     * Finds the mnemonic character in a message.
+     *
+     * The mnemonic character is the first character followed by the first
+     * <code>&</code> that is not followed by another <code>&</code>.
+     *
+     * @return the mnemonic as an <code>int</code>, or <code>0</code> if it
+     *         can't be found.
+     */
+    private static int findMnemonicInt(String s) {
+        for (int i = 0; i < s.length() - 1; i++) {
+            if (s.charAt(i) == '&') {
+                if (s.charAt(i + 1) != '&') {
+                    return lookupMnemonicInt(s.substring(i + 1, i + 2));
+                } else {
+                    i++;
                 }
-            } else if (obj instanceof Integer) {
-                mnemonic = (Integer)obj;
             }
         }
-        return mnemonic;
+        return 0;
     }
 
     /**
-     * Returns the jconsole resource string for the specified key.
+     * Lookups the mnemonic for a key in the {@link KeyEvent} class.
      *
+     * @param c the character to lookup
+     *
+     * @return the mnemonic as an <code>int</code>, or <code>0</code> if it
+     *         can't be found.
      */
-    private static String getString(String key) {
-        if (resources != null) {
-            try {
-                return resources.getString(key);
-            } catch (MissingResourceException e) {
-                return null;
-            }
+    private static int lookupMnemonicInt(String c) {
+        try {
+            return KeyEvent.class.getDeclaredField("VK_" + c.toUpperCase())
+                    .getInt(null);
+        } catch (IllegalArgumentException | IllegalAccessException
+                | NoSuchFieldException | SecurityException e) {
+            // Missing VK is okay
+            return 0;
         }
-        return "missing resource bundle: key = \"" + key + "\", " +
-            "arguments = \"{0}\", \"{1}\", \"{2}\"";
     }
 }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/SummaryTab.java b/jdk/src/share/classes/sun/tools/jconsole/SummaryTab.java
index 5e1907f..e511100 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/SummaryTab.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/SummaryTab.java
@@ -29,24 +29,19 @@
 import java.io.*;
 import java.lang.management.*;
 import java.lang.reflect.*;
-import java.net.URL;
 import java.text.*;
 import java.util.*;
 import java.util.concurrent.*;
 
 import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.text.*;
+
 
 import static sun.tools.jconsole.Formatter.*;
-import static sun.tools.jconsole.Resources.*;
 import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
 class SummaryTab extends Tab {
     private static final String cpuUsageKey = "cpu";
-    private static final String cpuUsageName = getText("CPU Usage");
-    private static final String cpuUsageFormat = "CPUUsageFormat";
 
     private static final String newDivider =   "<tr><td colspan=4><font size =-1><hr>";
     private static final String newTable =     "<tr><td colspan=4 align=left><table cellpadding=1>";
@@ -70,7 +65,7 @@
     }
 
     public static String getTabName() {
-        return Resources.getText("SummaryTab.tabName");
+        return Messages.SUMMARY_TAB_TAB_NAME;
     }
 
     public SummaryTab(VMPanel vmPanel) {
@@ -83,7 +78,7 @@
         add(new JScrollPane(info));
 
         headerDateTimeFormat =
-            getDateTimeFormat("SummaryTab.headerDateTimeFormat");
+            Formatter.getDateTimeFormat(Messages.SUMMARY_TAB_HEADER_DATE_TIME_FORMAT);
     }
 
     public SwingWorker<?, ?> newSwingWorker() {
@@ -138,7 +133,7 @@
                proxyClient.getSunOperatingSystemMXBean();
 
             append("<tr><td colspan=4>");
-            append("<center><b>" + getText("SummaryTab.tabName") + "</b></center>");
+            append("<center><b>" + Messages.SUMMARY_TAB_TAB_NAME + "</b></center>");
             String dateTime =
                 headerDateTimeFormat.format(System.currentTimeMillis());
             append("<center>" + dateTime + "</center>");
@@ -147,30 +142,30 @@
 
             {  // VM info
                 append(newLeftTable);
-                append("Connection name", vmPanel.getDisplayName());
-                append("Virtual Machine",
-                       getText("SummaryTab.vmVersion",
-                               rmBean.getVmName(), rmBean.getVmVersion()));
-                append("Vendor", rmBean.getVmVendor());
-                append("Name", rmBean.getName());
+                append(Messages.CONNECTION_NAME, vmPanel.getDisplayName());
+                append(Messages.VIRTUAL_MACHINE,
+                       Resources.format(Messages.SUMMARY_TAB_VM_VERSION,
+                                        rmBean.getVmName(), rmBean.getVmVersion()));
+                append(Messages.VENDOR, rmBean.getVmVendor());
+                append(Messages.NAME, rmBean.getName());
                 append(endTable);
 
                 append(newRightTable);
                 result.upTime = rmBean.getUptime();
-                append("Uptime", formatTime(result.upTime));
+                append(Messages.UPTIME, formatTime(result.upTime));
                 if (sunOSMBean != null) {
                     result.processCpuTime = sunOSMBean.getProcessCpuTime();
-                    append("Process CPU time", formatNanoTime(result.processCpuTime));
+                    append(Messages.PROCESS_CPU_TIME, formatNanoTime(result.processCpuTime));
                 }
 
                 if (cmpMBean != null) {
-                    append("JIT compiler", cmpMBean.getName());
-                    append("Total compile time",
+                    append(Messages.JIT_COMPILER, cmpMBean.getName());
+                    append(Messages.TOTAL_COMPILE_TIME,
                            cmpMBean.isCompilationTimeMonitoringSupported()
                                     ? formatTime(cmpMBean.getTotalCompilationTime())
-                                    : getText("Unavailable"));
+                                    : Messages.UNAVAILABLE);
                 } else {
-                    append("JIT compiler", getText("Unavailable"));
+                    append(Messages.JIT_COMPILER, Messages.UNAVAILABLE);
                 }
                 append(endTable);
             }
@@ -185,10 +180,10 @@
                 long ttCount = tmBean.getTotalStartedThreadCount();
                 String[] strings1 = formatLongs(tlCount, tpCount,
                                                 tdCount, ttCount);
-                append("Live Threads",          strings1[0]);
-                append("Peak",                  strings1[1]);
-                append("Daemon threads",        strings1[2]);
-                append("Total threads started", strings1[3]);
+                append(Messages.LIVE_THREADS, strings1[0]);
+                append(Messages.PEAK, strings1[1]);
+                append(Messages.DAEMON_THREADS, strings1[2]);
+                append(Messages.TOTAL_THREADS_STARTED, strings1[3]);
                 append(endTable);
 
                 append(newRightTable);
@@ -196,9 +191,9 @@
                 long cuCount = clMBean.getUnloadedClassCount();
                 long ctCount = clMBean.getTotalLoadedClassCount();
                 String[] strings2 = formatLongs(clCount, cuCount, ctCount);
-                append("Current classes loaded", strings2[0]);
-                append("Total classes loaded",   strings2[2]);
-                append("Total classes unloaded", strings2[1]);
+                append(Messages.CURRENT_CLASSES_LOADED, strings2[0]);
+                append(Messages.TOTAL_CLASSES_LOADED, strings2[2]);
+                append(Messages.TOTAL_CLASSES_UNLOADED, strings2[1]);
                 append(null, "");
                 append(endTable);
             }
@@ -210,16 +205,16 @@
 
                 append(newLeftTable);
                 String[] strings1 = formatKByteStrings(u.getUsed(), u.getMax());
-                append("Current heap size", strings1[0]);
-                append("Maximum heap size", strings1[1]);
+                append(Messages.CURRENT_HEAP_SIZE, strings1[0]);
+                append(Messages.MAXIMUM_HEAP_SIZE, strings1[1]);
                 append(endTable);
 
                 append(newRightTable);
                 String[] strings2 = formatKByteStrings(u.getCommitted());
-                append("Committed memory",  strings2[0]);
-                append("SummaryTab.pendingFinalization.label",
-                       getText("SummaryTab.pendingFinalization.value",
-                               memoryBean.getObjectPendingFinalizationCount()));
+                append(Messages.COMMITTED_MEMORY,  strings2[0]);
+                append(Messages.SUMMARY_TAB_PENDING_FINALIZATION_LABEL,
+                       Messages.SUMMARY_TAB_PENDING_FINALIZATION_VALUE,
+                       memoryBean.getObjectPendingFinalizationCount());
                 append(endTable);
 
                 append(newTable);
@@ -230,10 +225,10 @@
                     long gcCount = garbageCollectorMBean.getCollectionCount();
                     long gcTime = garbageCollectorMBean.getCollectionTime();
 
-                    append("Garbage collector",
-                           getText("GcInfo", gcName, gcCount,
-                                   (gcTime >= 0) ? formatTime(gcTime)
-                                                 : getText("Unavailable")),
+                    append(Messages.GARBAGE_COLLECTOR,
+                           Resources.format(Messages.GC_INFO, gcName, gcCount,
+                                            (gcTime >= 0) ? formatTime(gcTime)
+                                                 : Messages.UNAVAILABLE),
                            4);
                 }
                 append(endTable);
@@ -247,9 +242,9 @@
                 String osVersion = osMBean.getVersion();
                 String osArch = osMBean.getArch();
                 result.nCPUs = osMBean.getAvailableProcessors();
-                append("Operating System", osName + " " + osVersion);
-                append("Architecture", osArch);
-                append("Number of processors", result.nCPUs+"");
+                append(Messages.OPERATING_SYSTEM, osName + " " + osVersion);
+                append(Messages.ARCHITECTURE, osArch);
+                append(Messages.NUMBER_OF_PROCESSORS, result.nCPUs+"");
 
                 if (pathSeparator == null) {
                     // Must use separator of remote OS, not File.pathSeparator
@@ -268,14 +263,14 @@
                                            sunOSMBean.getTotalSwapSpaceSize(),
                                            sunOSMBean.getFreeSwapSpaceSize());
 
-                    append("Committed virtual memory", kbStrings1[0]);
+                    append(Messages.COMMITTED_VIRTUAL_MEMORY, kbStrings1[0]);
                     append(endTable);
 
                     append(newRightTable);
-                    append("Total physical memory", kbStrings2[0]);
-                    append("Free physical memory",  kbStrings2[1]);
-                    append("Total swap space",      kbStrings2[2]);
-                    append("Free swap space",       kbStrings2[3]);
+                    append(Messages.TOTAL_PHYSICAL_MEMORY, kbStrings2[0]);
+                    append(Messages.FREE_PHYSICAL_MEMORY,  kbStrings2[1]);
+                    append(Messages.TOTAL_SWAP_SPACE,      kbStrings2[2]);
+                    append(Messages.FREE_SWAP_SPACE,       kbStrings2[3]);
                 }
 
                 append(endTable);
@@ -290,13 +285,13 @@
                 for (String arg : inputArguments) {
                     args += arg + " ";
                 }
-                append("VM arguments", args, 4);
-                append("Class path",   rmBean.getClassPath(), 4);
-                append("Library path", rmBean.getLibraryPath(), 4);
-                append("Boot class path",
+                append(Messages.VM_ARGUMENTS, args, 4);
+                append(Messages.CLASS_PATH,   rmBean.getClassPath(), 4);
+                append(Messages.LIBRARY_PATH, rmBean.getLibraryPath(), 4);
+                append(Messages.BOOT_CLASS_PATH,
                        rmBean.isBootClassPathSupported()
                                     ? rmBean.getBootClassPath()
-                                    : getText("Unavailable"),
+                                    : Messages.UNAVAILABLE,
                        4);
                 append(endTable);
             }
@@ -327,7 +322,7 @@
     }
 
     void append(String label, String value) {
-        append(newRow((label != null) ? getText(label) : label, value));
+        append(newRow(label, value));
     }
 
     private void append(String label, String value, int columnPerRow) {
@@ -335,13 +330,7 @@
             value = value.replace(pathSeparator,
                                   "<b></b>" + pathSeparator);
         }
-        append(newRow(getText(label), value, columnPerRow));
-    }
-
-    void append(String label1, String value1,
-                String label2, String value2) {
-        append(newRow(getText(label1), value1,
-                      getText(label2), value2));
+        append(newRow(label, value, columnPerRow));
     }
 
     OverviewPanel[] getOverviewPanels() {
@@ -355,7 +344,7 @@
         private long prevUpTime, prevProcessCpuTime;
 
         CPUOverviewPanel() {
-            super(getText("CPU Usage"), cpuUsageKey, cpuUsageName, Plotter.Unit.PERCENT);
+            super(Messages.CPU_USAGE, cpuUsageKey, Messages.CPU_USAGE, Plotter.Unit.PERCENT);
             getPlotter().setDecimals(CPU_DECIMALS);
         }
 
@@ -373,14 +362,11 @@
 
                 getPlotter().addValues(result.timeStamp,
                                 Math.round(cpuUsage * Math.pow(10.0, CPU_DECIMALS)));
-                getInfoLabel().setText(getText(cpuUsageFormat,
+                getInfoLabel().setText(Resources.format(Messages.CPU_USAGE_FORMAT,
                                                String.format("%."+CPU_DECIMALS+"f", cpuUsage)));
             }
             this.prevUpTime = result.upTime;
             this.prevProcessCpuTime = result.processCpuTime;
         }
     }
-
-
-
 }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/Tab.java b/jdk/src/share/classes/sun/tools/jconsole/Tab.java
index 32ac8d6..512cc6b 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/Tab.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/Tab.java
@@ -26,9 +26,6 @@
 package sun.tools.jconsole;
 
 import java.awt.*;
-import java.awt.event.*;
-import java.beans.*;
-
 import javax.swing.*;
 
 public abstract class Tab extends JPanel {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java b/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java
index 16a461c..d1cb677 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/ThreadTab.java
@@ -35,14 +35,11 @@
 import javax.swing.border.*;
 import javax.swing.event.*;
 
+
 import java.util.*;
 import java.util.concurrent.*;
 import java.util.List;
 
-import sun.awt.*;
-
-import static sun.tools.jconsole.OverviewPanel.*;
-import static sun.tools.jconsole.Resources.*;
 import static sun.tools.jconsole.Utilities.*;
 
 
@@ -51,7 +48,7 @@
     PlotterPanel threadMeter;
     TimeComboBox timeComboBox;
     JTabbedPane threadListTabbedPane;
-    DefaultListModel listModel;
+    DefaultListModel<Long> listModel;
     JTextField filterTF;
     JLabel messageLabel;
     JSplitPane threadsSplitPane;
@@ -64,9 +61,6 @@
     private static final String threadCountKey   = "threadCount";
     private static final String peakKey          = "peak";
 
-    private static final String threadCountName   = Resources.getText("Live Threads");
-    private static final String peakName          = Resources.getText("Peak");
-
     private static final Color  threadCountColor = Plotter.defaultColor;
     private static final Color  peakColor        = Color.red;
 
@@ -93,7 +87,7 @@
 
 
     public static String getTabName() {
-        return Resources.getText("Threads");
+        return Messages.THREADS;
     }
 
     public ThreadTab(VMPanel vmPanel) {
@@ -111,28 +105,28 @@
         JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 5));
         topPanel.add(controlPanel, BorderLayout.CENTER);
 
-        threadMeter = new PlotterPanel(Resources.getText("Number of Threads"),
+        threadMeter = new PlotterPanel(Messages.NUMBER_OF_THREADS,
                                        Plotter.Unit.NONE, true);
-        threadMeter.plotter.createSequence(threadCountKey, threadCountName,  threadCountColor, true);
-        threadMeter.plotter.createSequence(peakKey,        peakName,         peakColor,        true);
+        threadMeter.plotter.createSequence(threadCountKey, Messages.LIVE_THREADS,  threadCountColor, true);
+        threadMeter.plotter.createSequence(peakKey,        Messages.PEAK,         peakColor,        true);
         setAccessibleName(threadMeter.plotter,
-                          getText("ThreadTab.threadPlotter.accessibleName"));
+                          Messages.THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME);
 
         plotterPanel.add(threadMeter);
 
         timeComboBox = new TimeComboBox(threadMeter.plotter);
-        controlPanel.add(new LabeledComponent(Resources.getText("Time Range:"),
-                                              getMnemonicInt("Time Range:"),
+        controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
+                                              Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
                                               timeComboBox));
 
-        listModel = new DefaultListModel();
+        listModel = new DefaultListModel<Long>();
 
         JTextArea textArea = new JTextArea();
         textArea.setBorder(thinEmptyBorder);
         textArea.setEditable(false);
         setAccessibleName(textArea,
-                          getText("ThreadTab.threadInfo.accessibleName"));
-        JList list = new ThreadJList(listModel, textArea);
+                          Messages.THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME);
+        ThreadJList list = new ThreadJList(listModel, textArea);
 
         Dimension di = new Dimension(super.getPreferredSize());
         di.width = Math.min(di.width, 200);
@@ -165,11 +159,11 @@
                                                  filterTF.getPreferredSize().height));
         firstTabToolPanel.add(separator);
 
-        JButton detectDeadlockButton = new JButton(Resources.getText("Detect Deadlock"));
-        detectDeadlockButton.setMnemonic(getMnemonicInt("Detect Deadlock"));
+        JButton detectDeadlockButton = new JButton(Messages.DETECT_DEADLOCK);
+        detectDeadlockButton.setMnemonic(Resources.getMnemonicInt(Messages.DETECT_DEADLOCK));
         detectDeadlockButton.setActionCommand("detectDeadlock");
         detectDeadlockButton.addActionListener(this);
-        detectDeadlockButton.setToolTipText(getText("Detect Deadlock.toolTip"));
+        detectDeadlockButton.setToolTipText(Messages.DETECT_DEADLOCK_TOOLTIP);
         firstTabToolPanel.add(detectDeadlockButton);
 
         messageLabel = new JLabel();
@@ -177,7 +171,7 @@
 
         firstTabPanel.add(threadsSplitPane, BorderLayout.CENTER);
         firstTabPanel.add(firstTabToolPanel, BorderLayout.SOUTH);
-        threadListTabbedPane.addTab(Resources.getText("Threads"), firstTabPanel);
+        threadListTabbedPane.addTab(Messages.THREADS, firstTabPanel);
 
         plotterPanel.add(threadListTabbedPane);
     }
@@ -356,32 +350,32 @@
                         }
                         if (ti != null) {
                             if (ti.getLockName() == null) {
-                                sb.append(Resources.getText("Name State",
+                                sb.append(Resources.format(Messages.NAME_STATE,
                                               ti.getThreadName(),
                                               ti.getThreadState().toString()));
                             } else if (ti.getLockOwnerName() == null) {
-                                sb.append(Resources.getText("Name State LockName",
+                                sb.append(Resources.format(Messages.NAME_STATE_LOCK_NAME,
                                               ti.getThreadName(),
                                               ti.getThreadState().toString(),
                                               ti.getLockName()));
                             } else {
-                                sb.append(Resources.getText("Name State LockName LockOwner",
+                                sb.append(Resources.format(Messages.NAME_STATE_LOCK_NAME_LOCK_OWNER,
                                               ti.getThreadName(),
                                               ti.getThreadState().toString(),
                                               ti.getLockName(),
                                               ti.getLockOwnerName()));
                             }
-                            sb.append(Resources.getText("BlockedCount WaitedCount",
+                            sb.append(Resources.format(Messages.BLOCKED_COUNT_WAITED_COUNT,
                                               ti.getBlockedCount(),
                                               ti.getWaitedCount()));
-                            sb.append(Resources.getText("Stack trace"));
+                            sb.append(Messages.STACK_TRACE);
                             int index = 0;
                             for (StackTraceElement e : ti.getStackTrace()) {
                                 sb.append(e.toString()+"\n");
                                 if (monitors != null) {
                                     for (MonitorInfo mi : monitors) {
                                         if (mi.getLockedStackDepth() == index) {
-                                            sb.append(Resources.getText("Monitor locked", mi.toString()));
+                                            sb.append(Resources.format(Messages.MONITOR_LOCKED, mi.toString()));
                                         }
                                     }
                                 }
@@ -429,7 +423,7 @@
                                 try {
                                     SwingUtilities.invokeAndWait(new Runnable() {
                                         public void run() {
-                                            String msg = Resources.getText("No deadlock detected");
+                                            String msg = Messages.NO_DEADLOCK_DETECTED;
                                             messageLabel.setText(msg);
                                             threadListTabbedPane.revalidate();
                                         }
@@ -459,13 +453,13 @@
 
                             if (deadlockedThreads != null) {
                                 for (int i = 0; i < deadlockedThreads.length; i++) {
-                                    DefaultListModel listModel = new DefaultListModel();
+                                    DefaultListModel<Long> listModel = new DefaultListModel<Long>();
                                     JTextArea textArea = new JTextArea();
                                     textArea.setBorder(thinEmptyBorder);
                                     textArea.setEditable(false);
                                     setAccessibleName(textArea,
-                                        getText("ThreadTab.threadInfo.accessibleName"));
-                                    JList list = new ThreadJList(listModel, textArea);
+                                                      Messages.THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME);
+                                    ThreadJList list = new ThreadJList(listModel, textArea);
                                     JScrollPane threadlistSP = new JScrollPane(list);
                                     JScrollPane textAreaSP = new JScrollPane(textArea);
                                     threadlistSP.setBorder(null);
@@ -477,9 +471,9 @@
                                     splitPane.setDividerLocation(threadsSplitPane.getDividerLocation());
                                     String tabName;
                                     if (deadlockedThreads.length > 1) {
-                                        tabName = Resources.getText("deadlockTabN", i+1);
+                                        tabName = Resources.format(Messages.DEADLOCK_TAB_N, i+1);
                                     } else {
-                                        tabName = Resources.getText("deadlockTab");
+                                        tabName = Messages.DEADLOCK_TAB;
                                     }
                                     threadListTabbedPane.addTab(tabName, splitPane);
 
@@ -591,10 +585,10 @@
 
 
 
-    private class ThreadJList extends JList {
+    private class ThreadJList extends JList<Long> {
         private JTextArea textArea;
 
-        ThreadJList(DefaultListModel listModel, JTextArea textArea) {
+        ThreadJList(DefaultListModel<Long> listModel, JTextArea textArea) {
             super(listModel);
 
             this.textArea = textArea;
@@ -603,7 +597,7 @@
 
             addListSelectionListener(ThreadTab.this);
             setCellRenderer(new DefaultListCellRenderer() {
-                public Component getListCellRendererComponent(JList list, Object value, int index,
+                public Component getListCellRendererComponent(JList<?> list, Object value, int index,
                                                               boolean isSelected, boolean cellHasFocus) {
                     super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
 
@@ -691,12 +685,12 @@
 
     private static class ThreadOverviewPanel extends OverviewPanel {
         ThreadOverviewPanel() {
-            super(getText("Threads"), threadCountKey, threadCountName, null);
+            super(Messages.THREADS, threadCountKey,  Messages.LIVE_THREADS, null);
         }
 
         private void updateThreadsInfo(long tlCount, long tpCount, long ttCount, long timeStamp) {
             getPlotter().addValues(timeStamp, tlCount);
-            getInfoLabel().setText(getText(infoLabelFormat, tlCount, tpCount, ttCount));
+            getInfoLabel().setText(Resources.format(infoLabelFormat, tlCount, tpCount, ttCount));
         }
     }
 }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/VMInternalFrame.java b/jdk/src/share/classes/sun/tools/jconsole/VMInternalFrame.java
index cb38e8c..750d444 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/VMInternalFrame.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/VMInternalFrame.java
@@ -26,16 +26,9 @@
 package sun.tools.jconsole;
 
 import java.awt.*;
-import java.awt.event.*;
-import java.io.*;
-import java.util.*;
-
 import javax.swing.*;
-import javax.swing.Timer;
-import javax.swing.border.*;
-import javax.swing.event.*;
 
-import static sun.tools.jconsole.Resources.*;
+
 import static sun.tools.jconsole.Utilities.*;
 
 @SuppressWarnings("serial")
@@ -47,7 +40,7 @@
 
         this.vmPanel = vmPanel;
         setAccessibleDescription(this,
-                                 getText("VMInternalFrame.accessibleDescription"));
+                                 Messages.VMINTERNAL_FRAME_ACCESSIBLE_DESCRIPTION);
         getContentPane().add(vmPanel, BorderLayout.CENTER);
         pack();
         vmPanel.updateFrameTitle();
diff --git a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java
index ebaf170..d9072b0 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/VMPanel.java
@@ -28,18 +28,16 @@
 import java.awt.*;
 import java.awt.event.*;
 import java.beans.*;
-import java.io.*;
 import java.lang.reflect.*;
 import java.util.*;
 import java.util.List;
 import java.util.Timer;
-
 import javax.swing.*;
 import javax.swing.plaf.*;
 
+
 import com.sun.tools.jconsole.JConsolePlugin;
 import com.sun.tools.jconsole.JConsoleContext;
-import static com.sun.tools.jconsole.JConsoleContext.ConnectionState.*;
 
 import static sun.tools.jconsole.ProxyClient.*;
 
@@ -51,13 +49,10 @@
     private int updateInterval;
     private String hostName;
     private int port;
-    private int vmid;
     private String userName;
     private String password;
     private String url;
     private VMInternalFrame vmIF = null;
-    private static final String windowsLaF =
-            "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
     private static ArrayList<TabInfo> tabInfos = new ArrayList<TabInfo>();
     private boolean wasConnected = false;
 
@@ -100,7 +95,6 @@
         this.updateInterval = updateInterval;
         this.hostName = proxyClient.getHostName();
         this.port = proxyClient.getPort();
-        this.vmid = proxyClient.getVmid();
         this.userName = proxyClient.getUserName();
         this.password = proxyClient.getPassword();
         this.url = proxyClient.getUrl();
@@ -186,9 +180,9 @@
     public String getToolTipText(MouseEvent event) {
         if (connectedIconBounds.contains(event.getPoint())) {
             if (isConnected()) {
-                return getText("Connected. Click to disconnect.");
+                return Messages.CONNECTED_PUNCTUATION_CLICK_TO_DISCONNECT_;
             } else {
-                return getText("Disconnected. Click to connect.");
+                return Messages.DISCONNECTED_PUNCTUATION_CLICK_TO_CONNECT_;
             }
         } else {
             return super.getToolTipText(event);
@@ -219,7 +213,7 @@
 
     private Tab instantiate(TabInfo tabInfo) {
         try {
-            Constructor con = tabInfo.tabClass.getConstructor(VMPanel.class);
+            Constructor<?> con = tabInfo.tabClass.getConstructor(VMPanel.class);
             return (Tab) con.newInstance(this);
         } catch (Exception ex) {
             System.err.println(ex);
@@ -354,7 +348,7 @@
     private void onConnecting() {
         time0 = System.currentTimeMillis();
 
-        final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this);
+        SwingUtilities.getWindowAncestor(this);
 
         String connectionName = getConnectionName();
         progressBar = new JProgressBar();
@@ -363,9 +357,9 @@
         progressPanel.add(progressBar);
 
         Object[] message = {
-            "<html><h3>" + getText("connectingTo1", connectionName) + "</h3></html>",
+            "<html><h3>" + Resources.format(Messages.CONNECTING_TO1, connectionName) + "</h3></html>",
             progressPanel,
-            "<html><b>" + getText("connectingTo2", connectionName) + "</b></html>"
+            "<html><b>" + Resources.format(Messages.CONNECTING_TO2, connectionName) + "</b></html>"
         };
 
         optionPane =
@@ -373,7 +367,7 @@
                 message,
                 JOptionPane.DEFAULT_OPTION,
                 JOptionPane.INFORMATION_MESSAGE, null,
-                new String[]{getText("Cancel")},
+                new String[]{Messages.CANCEL},
                 0);
 
 
@@ -409,7 +403,7 @@
         if (vmIF != null) {
             String displayName = getDisplayName();
             if (!proxyClient.isConnected()) {
-                displayName = getText("ConnectionName (disconnected)", displayName);
+                displayName = Resources.format(Messages.CONNECTION_NAME__DISCONNECTED_, displayName);
             }
             vmIF.setTitle(displayName);
         }
@@ -458,25 +452,18 @@
     private void vmPanelDied() {
         disconnect();
 
-        final JConsole jc = (JConsole) SwingUtilities.getWindowAncestor(this);
-
         JOptionPane optionPane;
-
-        final String connectStr = getText("Connect");
-        final String reconnectStr = getText("Reconnect");
-        final String cancelStr = getText("Cancel");
-
         String msgTitle, msgExplanation, buttonStr;
 
         if (wasConnected) {
             wasConnected = false;
-            msgTitle = getText("connectionLost1");
-            msgExplanation = getText("connectionLost2", getConnectionName());
-            buttonStr = reconnectStr;
+            msgTitle = Messages.CONNECTION_LOST1;
+            msgExplanation = Resources.format(Messages.CONNECTING_TO2, getConnectionName());
+            buttonStr = Messages.RECONNECT;
         } else {
-            msgTitle = getText("connectionFailed1");
-            msgExplanation = getText("connectionFailed2", getConnectionName());
-            buttonStr = connectStr;
+            msgTitle =Messages.CONNECTION_FAILED1;
+            msgExplanation = Resources.format(Messages.CONNECTION_FAILED2, getConnectionName());
+            buttonStr = Messages.CONNECT;
         }
 
         optionPane =
@@ -485,7 +472,7 @@
                 "<b>" + msgExplanation + "</b>",
                 JOptionPane.DEFAULT_OPTION,
                 JOptionPane.WARNING_MESSAGE, null,
-                new String[]{buttonStr, cancelStr},
+                new String[]{buttonStr, Messages.CANCEL},
                 0);
 
         optionPane.addPropertyChangeListener(new PropertyChangeListener() {
@@ -494,7 +481,7 @@
                 if (event.getPropertyName().equals(JOptionPane.VALUE_PROPERTY)) {
                     Object value = event.getNewValue();
 
-                    if (value == reconnectStr || value == connectStr) {
+                    if (value == Messages.RECONNECT || value == Messages.CONNECT) {
                         connect();
                     } else if (!everConnected) {
                         try {
@@ -643,11 +630,6 @@
         }
     }
 
-    // Convenience methods
-    private static String getText(String key, Object... args) {
-        return Resources.getText(key, args);
-    }
-
     private void createPluginTabs() {
         // add plugin tabs if not done
         if (!pluginTabsAdded) {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/VariableGridLayout.java b/jdk/src/share/classes/sun/tools/jconsole/VariableGridLayout.java
index 3cf55b0..2d5851c 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/VariableGridLayout.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/VariableGridLayout.java
@@ -26,7 +26,6 @@
 package sun.tools.jconsole;
 
 import java.awt.*;
-import java.util.*;
 
 import javax.swing.*;
 
diff --git a/jdk/src/share/classes/sun/tools/jconsole/Version.java.template b/jdk/src/share/classes/sun/tools/jconsole/Version.java.template
index b768be8..f52ac65 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/Version.java.template
+++ b/jdk/src/share/classes/sun/tools/jconsole/Version.java.template
@@ -26,6 +26,7 @@
 package sun.tools.jconsole;
 
 import java.io.PrintStream;
+import sun.tools.jconsole.Messages;
 
 public class Version {
     private static final String jconsole_version =
@@ -34,19 +35,19 @@
     public static void print(PrintStream ps) {
         printFullVersion(ps);
 
-        ps.println(Resources.getText("Name and Build",
-                                     System.getProperty("java.runtime.name"),
-                                     System.getProperty("java.runtime.version")));
+        ps.println(Resources.format(Messages.NAME_AND_BUILD,
+                                    System.getProperty("java.runtime.name"),
+                                    System.getProperty("java.runtime.version")));
 
-        ps.println(Resources.getText("Name Build and Mode",
-                                     System.getProperty("java.vm.name"),
-                                     System.getProperty("java.vm.version"),
-                                     System.getProperty("java.vm.info")));
+        ps.println(Resources.format(Messages.NAME_AND_BUILD,
+                                    System.getProperty("java.vm.name"),
+                                    System.getProperty("java.vm.version"),
+                                    System.getProperty("java.vm.info")));
 
     }
 
     public static void printFullVersion(PrintStream ps) {
-        ps.println(Resources.getText("JConsole version", jconsole_version));
+        ps.println(Resources.format(Messages.JCONSOLE_VERSION, jconsole_version));
     }
 
     static String getVersion() {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java
index 4ada1cd..30dde2b 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/OperationEntry.java
@@ -25,30 +25,14 @@
 
 package sun.tools.jconsole.inspector;
 
-// java import
 import java.awt.*;
-import java.awt.event.*;
-import java.awt.dnd.*;
-import java.lang.reflect.*;
-import java.io.*;
-//
-
-// swing import
-import javax.swing.border.*;
-import javax.swing.event.*;
 import javax.swing.*;
-//
-
-// jmx import
 import javax.management.*;
-//
-
 
 @SuppressWarnings("serial")
 public class OperationEntry extends JPanel {
     private MBeanOperationInfo operation;
     private JComboBox sigs;
-    private Dimension preferredSize;
     private XTextField inputs[];
 
     public OperationEntry (MBeanOperationInfo operation,
@@ -61,26 +45,10 @@
         setPanel(isCallable, button, xoperations);
     }
 
-    /**
-     * This method chops off the throws exceptions, removes "java.lang".
-     */
-    private String preProcessSignature(String signature) {
-        int index;
-        if ((index=signature.indexOf(" throws"))>0) {
-            signature = signature.substring(0,index);
-        }
-        while ((index = signature.indexOf("java.lang."))>0) {
-            signature = signature.substring(0,index)+
-                signature.substring(index+10,signature.length());
-        }
-        return signature;
-    }
-
-    private void setPanel(boolean isCallable,
+     private void setPanel(boolean isCallable,
                           JButton button,
                           XOperations xoperations) {
         try {
-            String defaultVal;
             MBeanParameterInfo params[] = operation.getSignature();
             add(new JLabel("(",JLabel.CENTER));
             inputs = new XTextField[params.length];
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java
index 4894d4a..b89ab72 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/TableSorter.java
@@ -94,7 +94,7 @@
     @SuppressWarnings("unchecked")
     private int compare(Object o1, Object o2) {
         // take care of the case where both o1 & o2 are null. Needed to keep
-        // the method symetric. Without this quickSort gives surprising results.
+        // the method symmetric. Without this quickSort gives surprising results.
         if (o1 == o2)
             return 0;
         if (o1==null)
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java
index d7b6095..dbcdd63 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/ThreadDialog.java
@@ -28,7 +28,6 @@
 // java import
 import java.awt.*;
 import javax.swing.*;
-import java.io.*;
 //
 
 public class ThreadDialog implements Runnable {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java
index 885af95..cc97c4e 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/Utils.java
@@ -284,7 +284,7 @@
      */
     public static Object newStringConstructor(String type, String param)
             throws Exception {
-        Constructor c = Utils.getClass(type).getConstructor(String.class);
+        Constructor<?> c = Utils.getClass(type).getConstructor(String.class);
         try {
             return c.newInstance(param);
         } catch (InvocationTargetException e) {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XArrayDataViewer.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XArrayDataViewer.java
index 8f4abfc..b42d5c6 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XArrayDataViewer.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XArrayDataViewer.java
@@ -46,9 +46,9 @@
         if (isViewableValue(value)) {
             Object[] arr;
             if (value instanceof Collection) {
-                arr = ((Collection) value).toArray();
+                arr = ((Collection<?>) value).toArray();
             } else if (value instanceof Map) {
-                arr = ((Map) value).entrySet().toArray();
+                arr = ((Map<?,?>) value).entrySet().toArray();
             } else if (value instanceof Object[]) {
                 arr = (Object[]) value;
             } else {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java
index 0742748..c820d83 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XDataViewer.java
@@ -34,7 +34,7 @@
 import java.awt.Container;
 
 import sun.tools.jconsole.MBeansTab;
-import sun.tools.jconsole.Resources;
+import sun.tools.jconsole.Messages;
 
 public class XDataViewer {
 
@@ -100,10 +100,10 @@
     public static String getActionLabel(int type) {
         if(type == ARRAY ||
            type == OPEN)
-            return Resources.getText("visualize");
+            return Messages.VISUALIZE;
         if(type == NUMERIC)
-            return Resources.getText("plot");
-        return Resources.getText("expand");
+            return Messages.PLOT;
+        return Messages.EXPAND;
     }
 
     public Component createOperationViewer(Object value,
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java
index 0fe157f..474b928 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanAttributes.java
@@ -66,9 +66,9 @@
 import javax.swing.table.TableColumnModel;
 import javax.swing.table.TableModel;
 
-import sun.tools.jconsole.Resources;
 import sun.tools.jconsole.MBeansTab;
 import sun.tools.jconsole.JConsole;
+import sun.tools.jconsole.Messages;
 import sun.tools.jconsole.ProxyClient.SnapshotMBeanServerConnection;
 
 /*IMPORTANT :
@@ -84,8 +84,8 @@
             Logger.getLogger(XMBeanAttributes.class.getPackage().getName());
 
     private final static String[] columnNames =
-    {Resources.getText("Name"),
-     Resources.getText("Value")};
+    {Messages.NAME,
+     Messages.VALUE};
 
     private XMBean mbean;
     private MBeanInfo mbeanInfo;
@@ -267,7 +267,7 @@
 
     public boolean isColumnEditable(int column) {
         if (column < getColumnCount()) {
-            return getColumnName(column).equals(Resources.getText("Value"));
+            return getColumnName(column).equals(Messages.VALUE);
         }
         else {
             return false;
@@ -313,7 +313,7 @@
             if (value != null) {
                 tip = value.toString();
                 if(isAttributeViewable(row, VALUE_COLUMN))
-                    tip = Resources.getText("Double click to expand/collapse")+
+                    tip = Messages.DOUBLE_CLICK_TO_EXPAND_FORWARD_SLASH_COLLAPSE+
                         ". " + tip;
             }
 
@@ -589,7 +589,7 @@
                               comp,
                               rowMinHeight);
 
-                    mbeansTab.getDataViewer().registerForMouseEvent(
+                    XDataViewer.registerForMouseEvent(
                             comp, mouseListener);
                 } else
                     return cell;
@@ -724,7 +724,7 @@
                         mbeansTab.getDataViewer().createAttributeViewer(
                             value, mbean, attribute, XMBeanAttributes.this);
                     cell.init(cell.getMinRenderer(), comp, cell.getMinHeight());
-                    mbeansTab.getDataViewer().registerForMouseEvent(comp, mouseListener);
+                    XDataViewer.registerForMouseEvent(comp, mouseListener);
                 }
             } else {
                 cell = new ZoomedCell(value);
@@ -735,7 +735,7 @@
         }
     }
 
-    //will be called in a synchronzed block
+    //will be called in a synchronized block
     protected void addTableData(DefaultTableModel tableModel,
                                 XMBean mbean,
                                 MBeanAttributeInfo[] attributesInfo,
@@ -749,7 +749,7 @@
         for (int i = 0; i < attributesInfo.length; i++) {
             rowData[0] = (attributesInfo[i].getName());
             if (unavailableAttributes.containsKey(rowData[0])) {
-                rowData[1] = Resources.getText("Unavailable");
+                rowData[1] = Messages.UNAVAILABLE;
             } else if (viewableAttributes.containsKey(rowData[0])) {
                 rowData[1] = viewableAttributes.get(rowData[0]);
                 if (!attributesInfo[i].isWritable() ||
@@ -811,7 +811,6 @@
         }
     }
 
-    @SuppressWarnings("serial")
     class ValueCellEditor extends XTextFieldEditor {
         // implements javax.swing.table.TableCellEditor
         @Override
@@ -866,7 +865,6 @@
         }
     }
 
-    @SuppressWarnings("serial")
     class MaximizedCellRenderer extends  DefaultTableCellRenderer {
         Component comp;
         MaximizedCellRenderer(Component comp) {
@@ -1018,7 +1016,7 @@
                             (String)tableValue);// value
                     } catch (Throwable ex) {
                         popupAndLog(ex,"tableChanged",
-                                "Problem setting attribute");
+                                    Messages.PROBLEM_SETTING_ATTRIBUTE);
                     }
                 }
                 final String attributeName = getValueName(e.getFirstRow());
@@ -1042,7 +1040,7 @@
                         }
                         mbean.setAttribute(attribute);
                     } catch (Throwable ex) {
-                        popupAndLog(ex,method,"Problem setting attribute");
+                        popupAndLog(ex,method,Messages.PROBLEM_SETTING_ATTRIBUTE);
                     }
                     return null;
                 }
@@ -1062,7 +1060,7 @@
         }
 
         // Call this outside EDT
-        private void popupAndLog(Throwable ex, String method, String key) {
+        private void popupAndLog(Throwable ex, String method, String title) {
             ex = Utils.getActualException(ex);
             if (JConsole.isDebug()) ex.printStackTrace();
 
@@ -1070,7 +1068,7 @@
                     : ex.toString();
             EventQueue.invokeLater(
                     new ThreadDialog(component, message+"\n",
-                                     Resources.getText(key),
+                                     title,
                                      JOptionPane.ERROR_MESSAGE));
         }
     }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java
index c98c482..cac986a 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanInfo.java
@@ -35,7 +35,8 @@
 import javax.swing.border.TitledBorder;
 import javax.swing.event.*;
 import javax.swing.table.*;
-import sun.tools.jconsole.Resources;
+
+import sun.tools.jconsole.Messages;
 
 import static sun.tools.jconsole.Utilities.*;
 
@@ -43,11 +44,11 @@
 public class XMBeanInfo extends JPanel {
 
     private static final Color lightYellow = new Color(255, 255, 128);
-    private final int NAME_COLUMN = 0;
+     private final int NAME_COLUMN = 0;
     private final int VALUE_COLUMN = 1;
     private final String[] columnNames = {
-        Resources.getText("Name"),
-        Resources.getText("Value")
+        Messages.NAME,
+        Messages.VALUE
     };
     private JTable infoTable = new JTable();
     private JTable descTable = new JTable();
@@ -163,7 +164,7 @@
         descTable.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
         JScrollPane descTableScrollPane = new JScrollPane(descTable);
         descBorderPanel.setBorder(
-                BorderFactory.createTitledBorder(Resources.getText("Descriptor")));
+            BorderFactory.createTitledBorder(Messages.DESCRIPTOR));
         descBorderPanel.add(descTableScrollPane);
         // Add the two tables to the grid
         //
@@ -230,20 +231,20 @@
         emptyInfoTable();
         emptyDescTable();
         ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
-                Resources.getText("MBeanInfo"));
-        String text = Resources.getText("Info") + ":";
+                Messages.MBEAN_INFO);
+        String text = Messages.INFO + ":";
         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
         Object rowData[] = new Object[2];
         rowData[0] = new TableRowDivider(text);
         rowData[1] = new TableRowDivider("");
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("ObjectName");
+        rowData[0] = Messages.OBJECT_NAME;
         rowData[1] = mbean.getObjectName();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("ClassName");
+        rowData[0] = Messages.CLASS_NAME;
         rowData[1] = mbeanInfo.getClassName();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Description");
+        rowData[0] = Messages.DESCRIPTION;
         rowData[1] = mbeanInfo.getDescription();
         tableModel.addRow(rowData);
         addDescriptor(mbeanInfo.getDescriptor(), text);
@@ -252,13 +253,13 @@
         int i = 0;
         for (MBeanConstructorInfo mbci : mbeanInfo.getConstructors()) {
             addMBeanConstructorInfo(mbci,
-                    Resources.getText("Constructor") + "-" + i + ":");
+                    Messages.CONSTRUCTOR + "-" + i + ":");
             // MBeanParameterInfo
             //
             int j = 0;
             for (MBeanParameterInfo mbpi : mbci.getSignature()) {
                 addMBeanParameterInfo(mbpi,
-                        Resources.getText("Parameter") + "-" + i + "-" + j + ":");
+                        Messages.PARAMETER + "-" + i + "-" + j + ":");
                 j++;
             }
             i++;
@@ -271,29 +272,29 @@
         emptyInfoTable();
         emptyDescTable();
         ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
-                Resources.getText("MBeanAttributeInfo"));
-        String text = Resources.getText("Attribute") + ":";
+                Messages.MBEAN_ATTRIBUTE_INFO);
+        String text = Messages.ATTRIBUTE + ":";
         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
         Object rowData[] = new Object[2];
         rowData[0] = new TableRowDivider(text);
         rowData[1] = new TableRowDivider("");
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Name");
+        rowData[0] = Messages.NAME;
         rowData[1] = mbai.getName();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Description");
+        rowData[0] = Messages.DESCRIPTION;
         rowData[1] = mbai.getDescription();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Readable");
+        rowData[0] = Messages.READABLE;
         rowData[1] = mbai.isReadable();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Writable");
+        rowData[0] = Messages.WRITABLE;
         rowData[1] = mbai.isWritable();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Is");
+        rowData[0] = Messages.IS;
         rowData[1] = mbai.isIs();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Type");
+        rowData[0] = Messages.TYPE;
         rowData[1] = mbai.getType();
         tableModel.addRow(rowData);
         addDescriptor(mbai.getDescriptor(), text);
@@ -305,36 +306,36 @@
         emptyInfoTable();
         emptyDescTable();
         ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
-                Resources.getText("MBeanOperationInfo"));
-        String text = Resources.getText("Operation") + ":";
+                Messages.MBEAN_OPERATION_INFO);
+        String text = Messages.OPERATION + ":";
         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
         Object rowData[] = new Object[2];
         rowData[0] = new TableRowDivider(text);
         rowData[1] = new TableRowDivider("");
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Name");
+        rowData[0] = Messages.NAME;
         rowData[1] = mboi.getName();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Description");
+        rowData[0] = Messages.DESCRIPTION;
         rowData[1] = mboi.getDescription();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Impact");
+        rowData[0] = Messages.IMPACT;
         switch (mboi.getImpact()) {
             case MBeanOperationInfo.INFO:
-                rowData[1] = Resources.getText("INFO");
+                rowData[1] = Messages.INFO_CAPITALIZED;
                 break;
             case MBeanOperationInfo.ACTION:
-                rowData[1] = Resources.getText("ACTION");
+                rowData[1] = Messages.ACTION_CAPITALIZED;
                 break;
             case MBeanOperationInfo.ACTION_INFO:
-                rowData[1] = Resources.getText("ACTION_INFO");
+                rowData[1] = Messages.ACTION_INFO_CAPITALIZED;
                 break;
             case MBeanOperationInfo.UNKNOWN:
-                rowData[1] = Resources.getText("UNKNOWN");
+                rowData[1] = Messages.UNKNOWN_CAPITALIZED;
                 break;
         }
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("ReturnType");
+        rowData[0] = Messages.RETURN_TYPE;
         rowData[1] = mboi.getReturnType();
         tableModel.addRow(rowData);
         addDescriptor(mboi.getDescriptor(), text);
@@ -343,7 +344,7 @@
         int i = 0;
         for (MBeanParameterInfo mbpi : mboi.getSignature()) {
             addMBeanParameterInfo(mbpi,
-                    Resources.getText("Parameter") + "-" + i++ + ":");
+                    Messages.PARAMETER + "-" + i++ + ":");
         }
         tableModel.newDataAvailable(new TableModelEvent(tableModel));
     }
@@ -353,20 +354,20 @@
         emptyInfoTable();
         emptyDescTable();
         ((TitledBorder) infoBorderPanel.getBorder()).setTitle(
-                Resources.getText("MBeanNotificationInfo"));
-        String text = Resources.getText("Notification") + ":";
+                Messages.MBEAN_NOTIFICATION_INFO);
+        String text = Messages.NOTIFICATION + ":";
         DefaultTableModel tableModel = (DefaultTableModel) infoTable.getModel();
         Object rowData[] = new Object[2];
         rowData[0] = new TableRowDivider(text);
         rowData[1] = new TableRowDivider("");
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Name");
+        rowData[0] = Messages.NAME;
         rowData[1] = mbni.getName();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Description");
+        rowData[0] = Messages.DESCRIPTION;
         rowData[1] = mbni.getDescription();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("NotifTypes");
+        rowData[0] = Messages.NOTIF_TYPES;
         rowData[1] = Arrays.toString(mbni.getNotifTypes());
         tableModel.addRow(rowData);
         addDescriptor(mbni.getDescriptor(), text);
@@ -380,10 +381,10 @@
         rowData[0] = new TableRowDivider(text);
         rowData[1] = new TableRowDivider("");
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Name");
+        rowData[0] = Messages.NAME;
         rowData[1] = mbci.getName();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Description");
+        rowData[0] = Messages.DESCRIPTION;
         rowData[1] = mbci.getDescription();
         tableModel.addRow(rowData);
         addDescriptor(mbci.getDescriptor(), text);
@@ -397,13 +398,13 @@
         rowData[0] = new TableRowDivider(text);
         rowData[1] = new TableRowDivider("");
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Name");
+        rowData[0] = Messages.NAME;
         rowData[1] = mbpi.getName();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Description");
+        rowData[0] = Messages.DESCRIPTION;
         rowData[1] = mbpi.getDescription();
         tableModel.addRow(rowData);
-        rowData[0] = Resources.getText("Type");
+        rowData[0] = Messages.TYPE;
         rowData[1] = mbpi.getType();
         tableModel.addRow(rowData);
         addDescriptor(mbpi.getDescriptor(), text);
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java
index 2d11b8a..5077797 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XMBeanNotifications.java
@@ -26,7 +26,6 @@
 package sun.tools.jconsole.inspector;
 
 import javax.swing.*;
-import javax.swing.event.*;
 import javax.swing.table.*;
 import javax.swing.tree.*;
 import java.awt.Font;
@@ -46,19 +45,19 @@
 import javax.management.openmbean.TabularData;
 
 import sun.tools.jconsole.JConsole;
-import sun.tools.jconsole.Resources;
+import sun.tools.jconsole.Messages;
 
 @SuppressWarnings("serial")
 public class XMBeanNotifications extends JTable implements NotificationListener {
 
     private final static String[] columnNames = {
-        Resources.getText("TimeStamp"),
-        Resources.getText("Type"),
-        Resources.getText("UserData"),
-        Resources.getText("SeqNum"),
-        Resources.getText("Message"),
-        Resources.getText("Event"),
-        Resources.getText("Source")
+        Messages.TIME_STAMP,
+        Messages.TYPE,
+        Messages.USER_DATA,
+        Messages.SEQ_NUM,
+        Messages.MESSAGE,
+        Messages.EVENT,
+        Messages.SOURCE
     };
     private HashMap<ObjectName, XMBeanNotificationsListener> listeners =
             new HashMap<ObjectName, XMBeanNotificationsListener>();
@@ -183,7 +182,7 @@
         }
 
         if (cell != null) {
-            toolTip = Resources.getText("Double click to expand/collapse") +
+            toolTip = Messages.DOUBLE_CLICK_TO_EXPAND_FORWARD_SLASH_COLLAPSE+
                     ". " + cell.toString();
         } else {
             Object val =
@@ -599,7 +598,6 @@
 
     class XMBeanNotificationsListener implements NotificationListener {
 
-        private String[] columnNames;
         private XMBean xmbean;
         private DefaultMutableTreeNode node;
         private volatile long received;
@@ -615,7 +613,6 @@
             this.notifications = notifications;
             this.xmbean = xmbean;
             this.node = node;
-            this.columnNames = columnNames;
             register(node);
         }
 
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java
index 9e56286..303090a 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XObject.java
@@ -28,17 +28,6 @@
 // java import
 import javax.swing.*;
 
-//
-
-// java import
-import java.io.*;
-import java.awt.*;
-import java.awt.dnd.*;
-import java.awt.datatransfer.*;
-import java.net.*;
-//
-
-
 /**
  * This provides a wrapper to the Object class to allow it to be
  displayed/manipulated as a GUI object.
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XOpenTypeViewer.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOpenTypeViewer.java
index fb4ddf1..108ff7a 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XOpenTypeViewer.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOpenTypeViewer.java
@@ -28,33 +28,21 @@
 import javax.swing.*;
 import javax.swing.event.*;
 import javax.swing.table.*;
-import javax.swing.tree.*;
-import javax.swing.border.*;
 import java.awt.BorderLayout;
-import java.awt.GridLayout;
 import java.awt.FlowLayout;
 import java.awt.Component;
-import java.awt.EventQueue;
 import java.awt.Color;
 import java.awt.Font;
-import java.awt.Rectangle;
 import java.awt.event.*;
-import java.awt.Insets;
 import java.awt.Dimension;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
 import java.util.*;
-import java.io.*;
 import java.lang.reflect.Array;
 
-import javax.management.*;
 import javax.management.openmbean.*;
 
-import sun.tools.jconsole.BorderedComponent;
 import sun.tools.jconsole.JConsole;
-import sun.tools.jconsole.LabeledComponent;
+import sun.tools.jconsole.Messages;
 import sun.tools.jconsole.Resources;
-import sun.tools.jconsole.VariableGridLayout;
 
 @SuppressWarnings("serial")
 public class XOpenTypeViewer extends JPanel implements ActionListener {
@@ -65,9 +53,9 @@
     XOpenTypeDataListener listener = new XOpenTypeDataListener();
 
     private static final String compositeNavigationSingle =
-            Resources.getText("MBeansTab.compositeNavigationSingle");
+            Messages.MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE;
     private static final String tabularNavigationSingle =
-            Resources.getText("MBeansTab.tabularNavigationSingle");
+            Messages.MBEANS_TAB_TABULAR_NAVIGATION_SINGLE;
 
     private static TableCellEditor editor =
             new Utils.ReadOnlyTableCellEditor(new JTextField());
@@ -121,7 +109,6 @@
 
     static abstract class XOpenTypeData extends JTable {
         XOpenTypeData parent;
-        private Color defaultColor;
         protected int col1Width = -1;
         protected int col2Width = -1;
         private boolean init;
@@ -139,7 +126,7 @@
                 Object value = getModel().getValueAt(row, col);
                 if (value != null) {
                     if(isClickableElement(value))
-                        return Resources.getText("Double click to visualize")
+                        return Messages.DOUBLE_CLICK_TO_VISUALIZE
                         + ". " + value.toString();
                     else
                         return value.toString();
@@ -265,7 +252,7 @@
                 Object c1 = o1.get(key);
                 Object c2 = o2.get(key);
                 if (c1 instanceof Comparable && c2 instanceof Comparable) {
-                    int result = ((Comparable) c1).compareTo(c2);
+                    int result = ((Comparable<Object>) c1).compareTo(c2);
                     if (result != 0)
                         return result;
                 }
@@ -358,7 +345,7 @@
 
     static class XCompositeData extends XOpenTypeData {
         protected final String[] columnNames = {
-            Resources.getText("Name"), Resources.getText("Value")
+            Messages.NAME, Messages.VALUE
         };
         CompositeData composite;
 
@@ -398,8 +385,8 @@
 
         private void load(CompositeData data) {
             CompositeType type = data.getCompositeType();
-            Set keys = type.keySet();
-            Iterator it = keys.iterator();
+            Set<String> keys = type.keySet();
+            Iterator<String> it = keys.iterator();
             Object[] rowData = new Object[2];
             while (it.hasNext()) {
                 String key = (String) it.next();
@@ -408,13 +395,13 @@
                 if (val == null) {
                     rowData[1] = "";
                 } else {
-                    OpenType openType = type.getType(key);
+                    OpenType<?> openType = type.getType(key);
                     if (openType instanceof CompositeType) {
                         rowData[1] =
                                 new XCompositeData(this, (CompositeData) val);
                     } else if (openType instanceof ArrayType) {
                         rowData[1] =
-                                new XArrayData(this, (ArrayType) openType, val);
+                                new XArrayData(this, (ArrayType<?>) openType, val);
                     } else if (openType instanceof SimpleType) {
                         rowData[1] = val;
                     } else if (openType instanceof TabularType) {
@@ -453,21 +440,21 @@
 
         private int dimension;
         private int size;
-        private OpenType elemType;
+        private OpenType<?> elemType;
         private Object val;
         private boolean isCompositeType;
         private boolean isTabularType;
         private int currentIndex;
         private CompositeData[] elements;
-        private final String[] arrayColumns = {Resources.getText("Value")};
+        private final String[] arrayColumns = {Messages.VALUE};
         private Font normalFont, boldFont;
 
-        XArrayData(XOpenTypeData parent, ArrayType type, Object val) {
+        XArrayData(XOpenTypeData parent, ArrayType<?> type, Object val) {
             this(parent, type.getDimension(), type.getElementOpenType(), val);
         }
 
         XArrayData(XOpenTypeData parent, int dimension,
-                OpenType elemType, Object val) {
+                OpenType<?> elemType, Object val) {
             super(parent);
             this.dimension = dimension;
             this.elemType = elemType;
@@ -486,10 +473,9 @@
 
         public void viewed(XOpenTypeViewer viewer) throws Exception {
             if (size == 0)
-                throw new Exception(Resources.getText("Empty array"));
+                throw new Exception(Messages.EMPTY_ARRAY);
             if (dimension > 1)
-                throw new Exception(Resources.getText("Dimension is not " +
-                        "supported:") +
+                throw new Exception(Messages.DIMENSION_IS_NOT_SUPPORTED_COLON +
                         dimension);
             super.viewed(viewer);
         }
@@ -565,7 +551,7 @@
 
         public String toString() {
             if (dimension > 1) {
-                return Resources.getText("Dimension is not supported:") +
+                return Messages.DIMENSION_IS_NOT_SUPPORTED_COLON +
                         dimension;
             } else {
                 return elemType.getTypeName() + "[" + size + "]";
@@ -694,7 +680,7 @@
                     tabular.canIncrement() || tabular.canDecrement();
             if (hasMoreThanOneElement) {
                 tabularLabel.setText(
-                        Resources.getText("MBeansTab.tabularNavigationMultiple",
+                        Resources.format(Messages.MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE,
                         String.format("%d", tabular.getSelectedElementIndex() + 1),
                         String.format("%d", tabular.getElementCount())));
             } else {
@@ -717,7 +703,7 @@
                     array.canIncrement() || array.canDecrement();
             if (hasMoreThanOneElement) {
                 compositeLabel.setText(
-                        Resources.getText("MBeansTab.compositeNavigationMultiple",
+                        Resources.format(Messages.MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE,
                         String.format("%d", array.getSelectedElementIndex() + 1),
                         String.format("%d", array.getElementCount())));
             } else {
@@ -781,8 +767,8 @@
                 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
 
         JPanel buttons = new JPanel(new FlowLayout(FlowLayout.LEFT));
-        tabularPrev = new JButton(Resources.getText("<"));
-        tabularNext = new JButton(Resources.getText(">"));
+        tabularPrev = new JButton(Messages.LESS_THAN);
+        tabularNext = new JButton(Messages.GREATER_THAN);
         JPanel tabularButtons = new JPanel(new FlowLayout(FlowLayout.LEFT));
         tabularButtons.add(tabularPrev);
         tabularPrev.addActionListener(this);
@@ -793,13 +779,13 @@
         tabularNext.addActionListener(this);
         tabularButtons.setBackground(Color.white);
 
-        prev = new JButton(Resources.getText("<<"));
+        prev = new JButton(Messages.A_LOT_LESS_THAN);
         prev.addActionListener(this);
         buttons.add(prev);
 
-        incr = new JButton(Resources.getText(">"));
+        incr = new JButton(Messages.GREATER_THAN);
         incr.addActionListener(this);
-        decr = new JButton(Resources.getText("<"));
+        decr = new JButton(Messages.LESS_THAN);
         decr.addActionListener(this);
 
         JPanel array = new JPanel();
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java
index a6e7f8b..b4f24fa 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XOperations.java
@@ -26,22 +26,18 @@
 package sun.tools.jconsole.inspector;
 
 import javax.swing.*;
-import javax.swing.event.*;
-import javax.swing.table.*;
-import javax.swing.tree.*;
 import java.awt.BorderLayout;
 import java.awt.GridLayout;
 import java.awt.FlowLayout;
 import java.awt.Component;
 import java.awt.event.*;
 import java.util.*;
-import java.io.*;
 
 import javax.management.*;
 
-import sun.tools.jconsole.Resources;
 import sun.tools.jconsole.MBeansTab;
 import sun.tools.jconsole.JConsole;
+import sun.tools.jconsole.Messages;
 
 public abstract class XOperations extends JPanel implements ActionListener {
 
@@ -185,8 +181,8 @@
                     } else {
                         new ThreadDialog(
                                 button,
-                                Resources.getText("Method successfully invoked"),
-                                Resources.getText("Info"),
+                                Messages.METHOD_SUCCESSFULLY_INVOKED,
+                                Messages.INFO,
                                 JOptionPane.INFORMATION_MESSAGE).run();
                     }
                 } catch (Throwable t) {
@@ -196,9 +192,9 @@
                     }
                     new ThreadDialog(
                             button,
-                            Resources.getText("Problem invoking") + " " +
+                            Messages.PROBLEM_INVOKING + " " +
                             button.getText() + " : " + t.toString(),
-                            Resources.getText("Error"),
+                            Messages.ERROR,
                             JOptionPane.ERROR_MESSAGE).run();
                 }
             }
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java
index bcb34ad..00fdff8e 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlotter.java
@@ -27,7 +27,6 @@
 
 import sun.tools.jconsole.Plotter;
 import javax.swing.JTable;
-import java.awt.Graphics;
 
 @SuppressWarnings("serial")
 public class XPlotter extends Plotter {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java
index 280759f..f1e768c 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XPlottingViewer.java
@@ -45,10 +45,7 @@
         new HashMap<String, XPlottingViewer>();
      private static HashMap<String, Timer> timerCache =
          new HashMap<String, Timer>();
-    private JPanel bordered;
-    private Number value;
     private MBeansTab tab;
-    private XMBean mbean;
     private String attributeName;
     private String key;
     private JTable table;
@@ -62,7 +59,6 @@
 
         this.tab = tab;
         this.key = key;
-        this.mbean = mbean;
         this.table = table;
         this.attributeName = attributeName;
         Plotter plotter = createPlotter(mbean, attributeName, key, table);
@@ -70,9 +66,9 @@
     }
 
     static void dispose(MBeansTab tab) {
-        Iterator it = plotterCache.keySet().iterator();
+        Iterator<String> it = plotterCache.keySet().iterator();
         while(it.hasNext()) {
-            String key = (String) it.next();
+            String key = it.next();
             if(key.startsWith(String.valueOf(tab.hashCode()))) {
                 it.remove();
             }
@@ -187,7 +183,7 @@
         final GridBagLayout gbl = new GridBagLayout();
         buttonPanel.setLayout(gbl);
         setLayout(new BorderLayout());
-        plotButton = new JButton(Resources.getText("Discard chart"));
+        plotButton = new JButton(Messages.DISCARD_CHART);
         plotButton.addActionListener(this);
         plotButton.setEnabled(true);
 
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java
index 3739f40..f9f5bc4 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XSheet.java
@@ -57,8 +57,6 @@
 import sun.tools.jconsole.*;
 import sun.tools.jconsole.inspector.XNodeInfo.Type;
 
-import static sun.tools.jconsole.Resources.*;
-
 @SuppressWarnings("serial")
 public class XSheet extends JPanel
         implements ActionListener, NotificationListener {
@@ -106,28 +104,24 @@
         southPanel = new JPanel();
         add(southPanel, BorderLayout.SOUTH);
         // create the refresh button
-        String refreshButtonKey = "MBeansTab.refreshAttributesButton";
-        refreshButton = new JButton(getText(refreshButtonKey));
-        refreshButton.setMnemonic(getMnemonicInt(refreshButtonKey));
-        refreshButton.setToolTipText(getText(refreshButtonKey + ".toolTip"));
+        refreshButton = new JButton(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON);
+        refreshButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON));
+        refreshButton.setToolTipText(Messages.MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP);
         refreshButton.addActionListener(this);
         // create the clear button
-        String clearButtonKey = "MBeansTab.clearNotificationsButton";
-        clearButton = new JButton(getText(clearButtonKey));
-        clearButton.setMnemonic(getMnemonicInt(clearButtonKey));
-        clearButton.setToolTipText(getText(clearButtonKey + ".toolTip"));
+        clearButton = new JButton(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON);
+        clearButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON));
+        clearButton.setToolTipText(Messages.MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP);
         clearButton.addActionListener(this);
         // create the subscribe button
-        String subscribeButtonKey = "MBeansTab.subscribeNotificationsButton";
-        subscribeButton = new JButton(getText(subscribeButtonKey));
-        subscribeButton.setMnemonic(getMnemonicInt(subscribeButtonKey));
-        subscribeButton.setToolTipText(getText(subscribeButtonKey + ".toolTip"));
+        subscribeButton = new JButton(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON);
+        subscribeButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON));
+        subscribeButton.setToolTipText(Messages.MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP);
         subscribeButton.addActionListener(this);
         // create the unsubscribe button
-        String unsubscribeButtonKey = "MBeansTab.unsubscribeNotificationsButton";
-        unsubscribeButton = new JButton(getText(unsubscribeButtonKey));
-        unsubscribeButton.setMnemonic(getMnemonicInt(unsubscribeButtonKey));
-        unsubscribeButton.setToolTipText(getText(unsubscribeButtonKey + ".toolTip"));
+        unsubscribeButton = new JButton(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON);
+        unsubscribeButton.setMnemonic(Resources.getMnemonicInt(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON));
+        unsubscribeButton.setToolTipText(Messages.MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP);
         unsubscribeButton.addActionListener(this);
         // create XMBeanAttributes container
         mbeanAttributes = new XMBeanAttributes(mbeansTab);
@@ -238,7 +232,7 @@
                         t.printStackTrace();
                     }
                     showErrorDialog(t.toString(),
-                            Resources.getText("Problem displaying MBean"));
+                            Messages.PROBLEM_DISPLAYING_MBEAN);
                 }
             }
         };
@@ -279,7 +273,7 @@
                                             new JPanel(new BorderLayout());
                                     attributeBorderPanel.setBorder(
                                             BorderFactory.createTitledBorder(
-                                            Resources.getText("Attribute value")));
+                                            Messages.ATTRIBUTE_VALUE));
                                     JPanel attributeValuePanel =
                                             new JPanel(new BorderLayout());
                                     attributeValuePanel.setBorder(
@@ -314,7 +308,7 @@
                                         t.printStackTrace();
                                     }
                                     showErrorDialog(t.toString(),
-                                            Resources.getText("Problem displaying MBean"));
+                                            Messages.PROBLEM_DISPLAYING_MBEAN);
                                 }
                             }
                         };
@@ -333,7 +327,7 @@
                 JPanel operationPanel = new JPanel(new BorderLayout());
                 JPanel operationBorderPanel = new JPanel(new BorderLayout());
                 operationBorderPanel.setBorder(BorderFactory.createTitledBorder(
-                        Resources.getText("Operation invocation")));
+                        Messages.OPERATION_INVOCATION));
                 operationBorderPanel.add(new JScrollPane(mbeanOperations));
                 operationPanel.add(operationBorderPanel, BorderLayout.NORTH);
                 mbi.addMBeanOperationInfo(mboi);
@@ -389,7 +383,7 @@
                         mainPanel.removeAll();
                         JPanel borderPanel = new JPanel(new BorderLayout());
                         borderPanel.setBorder(BorderFactory.createTitledBorder(
-                                Resources.getText("Attribute values")));
+                                Messages.ATTRIBUTE_VALUES));
                         borderPanel.add(new JScrollPane(mbeanAttributes));
                         mainPanel.add(borderPanel, BorderLayout.CENTER);
                         // add the refresh button to the south panel
@@ -409,7 +403,7 @@
                         t.printStackTrace();
                     }
                     showErrorDialog(t.toString(),
-                            Resources.getText("Problem displaying MBean"));
+                            Messages.PROBLEM_DISPLAYING_MBEAN);
                 }
             }
         };
@@ -442,7 +436,7 @@
                         mainPanel.removeAll();
                         JPanel borderPanel = new JPanel(new BorderLayout());
                         borderPanel.setBorder(BorderFactory.createTitledBorder(
-                                Resources.getText("Operation invocation")));
+                                Messages.OPERATION_INVOCATION));
                         borderPanel.add(new JScrollPane(mbeanOperations));
                         mainPanel.add(borderPanel, BorderLayout.CENTER);
                         southPanel.setVisible(false);
@@ -459,7 +453,7 @@
                         t.printStackTrace();
                     }
                     showErrorDialog(t.toString(),
-                            Resources.getText("Problem displaying MBean"));
+                            Messages.PROBLEM_DISPLAYING_MBEAN);
                 }
             }
         };
@@ -479,7 +473,7 @@
         mainPanel.removeAll();
         JPanel borderPanel = new JPanel(new BorderLayout());
         borderPanel.setBorder(BorderFactory.createTitledBorder(
-                Resources.getText("Notification buffer")));
+                Messages.NOTIFICATION_BUFFER));
         borderPanel.add(new JScrollPane(mbeanNotifications));
         mainPanel.add(borderPanel, BorderLayout.CENTER);
         // add the subscribe/unsubscribe/clear buttons to the south panel
@@ -528,7 +522,7 @@
                         t.printStackTrace();
                     }
                     showErrorDialog(t.getMessage(),
-                            Resources.getText("Problem adding listener"));
+                            Messages.PROBLEM_ADDING_LISTENER);
                 }
             }
         }.execute();
@@ -557,7 +551,7 @@
                         t.printStackTrace();
                     }
                     showErrorDialog(t.getMessage(),
-                            Resources.getText("Problem removing listener"));
+                            Messages.PROBLEM_REMOVING_LISTENER);
                 }
             }
         }.execute();
@@ -586,7 +580,7 @@
     // Call on EDT
     private void updateReceivedNotifications(
             DefaultMutableTreeNode emitter, long received, boolean bold) {
-        String text = Resources.getText("Notifications") + "[" + received + "]";
+        String text = Messages.NOTIFICATIONS + "[" + received + "]";
         DefaultMutableTreeNode selectedNode = (DefaultMutableTreeNode) mbeansTab.getTree().getLastSelectedPathComponent();
         if (bold && emitter != selectedNode) {
             text = "<html><b>" + text + "</b></html>";
@@ -600,7 +594,7 @@
     // Call on EDT
     private void clearNotifications() {
         updateNotificationsNodeLabel(currentNode,
-                Resources.getText("Notifications"));
+                Messages.NOTIFICATIONS);
     }
 
     /**
@@ -609,7 +603,7 @@
     // Call on EDT
     private void clearNotifications0() {
         updateNotificationsNodeLabel(currentNode,
-                Resources.getText("Notifications") + "[0]");
+                Messages.NOTIFICATIONS + "[0]");
     }
 
     /**
@@ -712,7 +706,7 @@
             new ThreadDialog(
                     (Component) e.getSource(),
                     message,
-                    Resources.getText("Operation return value"),
+                    Messages.OPERATION_RETURN_VALUE,
                     JOptionPane.INFORMATION_MESSAGE).run();
         } // Got notification
         else if (e.getType().equals(
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java
index 3d090d6..172ded8 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTable.java
@@ -36,7 +36,7 @@
 public abstract class XTable extends JTable {
     static final int NAME_COLUMN = 0;
     static final int VALUE_COLUMN = 1;
-    private Color defaultColor, editableColor, droppableColor, errorColor;
+    private Color defaultColor, editableColor, errorColor;
     private Font normalFont, boldFont;
 
     public XTable () {
@@ -139,7 +139,6 @@
         if (defaultColor == null) {
             defaultColor = tcr.getForeground();
             editableColor = Color.blue;
-            droppableColor = Color.green;
             errorColor = Color.red;
             // this sometimes happens for some reason
             if (defaultColor == null) {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java
index 882a427..2cb2359 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTextField.java
@@ -26,12 +26,7 @@
 package sun.tools.jconsole.inspector;
 
 import java.awt.*;
-import java.awt.dnd.*;
 import java.awt.event.*;
-import java.awt.datatransfer.*;
-import java.io.*;
-import java.util.*;
-import javax.swing.plaf.*;
 import javax.swing.event.*;
 import javax.swing.*;
 
@@ -44,16 +39,8 @@
     implements DocumentListener,
                ActionListener {
 
-    private static final Color selF = Color.red;
-    private static final Color selB = Color.yellow;
-    private Color fore=null, back=null;
-    private HashMap items = null; //used for popup menu selection
     private XObject selectedObject;
-    private XObject currentObject;
-    private Class expectedClass;
-    private Object value;
     protected JTextField textField;
-    private JButton browseObjects;
 
     private static boolean allowNullSelection = false;
 
@@ -81,13 +68,12 @@
     }
 
     public XTextField(Object value,
-                      Class expectedClass,
+                      Class<?> expectedClass,
                       int colWidth,
                       boolean isCallable,
                       JButton button,
                       XOperations operation) {
         super(new BorderLayout());
-        this.expectedClass = expectedClass;
         this.button = button;
         this.operation = operation;
         add(textField = new JTextField(value.toString(),colWidth),
@@ -112,17 +98,13 @@
         return allowNullSelection;
     }
 
-    protected void init(Object value, Class expectedClass) {
-        this.expectedClass = expectedClass;
-        this.value = value;
-        boolean fieldEditable =  Utils.isEditableType(expectedClass.getName());
+    protected void init(Object value, Class<?> expectedClass) {
+         boolean fieldEditable =  Utils.isEditableType(expectedClass.getName());
         clearObject();
         if (value != null) {
-            currentObject = new XObject(value);
             textField.setText(value.toString());
         }
         else {
-            currentObject = XObject.NULL_OBJECT;
             //null String value for the moment
             textField.setText("");
         }
@@ -140,35 +122,12 @@
         }
     }
 
-
-
-
-
-    private synchronized void setObject(XObject object) {
-        clearObject();
-        selectedObject = object;
-        currentObject = object;
-        setSelectedColors();
-        textField.setText(object.getText());
-        textField.getDocument().addDocumentListener(this);
-        paintImmediately(getVisibleRect());
-    }
-
     private synchronized void clearObject() {
         textField.getDocument().removeDocumentListener(this);
         selectedObject = null;
-        currentObject = null;
         setDefaultColors();
     }
 
-    private synchronized void setSelectedColors() {
-        // fore = textField.getForeground();
-        // back = textField.getBackground();
-
-        //textField.setForeground(Color.red);
-        // textField.setBackground(Color.yellow);
-    }
-
     private synchronized void setDefaultColors() {
         //  if (fore != null) textField.setForeground(fore);
         // if (back != null)  textField.setBackground(back);
@@ -194,12 +153,6 @@
         }
     }
 
-    private JPopupMenu buildEditPopupMenu() {
-        JPopupMenu menu = new JPopupMenu();
-        return menu;
-    }
-
-
     // ACTIONLISTENER IMPLEMENTATION
     public void actionPerformed(ActionEvent e) {
         if (e.getSource() instanceof JTextField) {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java
index f81160e..303d9dc 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTree.java
@@ -32,7 +32,7 @@
 import javax.swing.tree.*;
 import sun.tools.jconsole.JConsole;
 import sun.tools.jconsole.MBeansTab;
-import sun.tools.jconsole.Resources;
+import sun.tools.jconsole.Messages;
 import sun.tools.jconsole.inspector.XNodeInfo;
 import static sun.tools.jconsole.inspector.XNodeInfo.Type;
 
@@ -182,7 +182,7 @@
      * Returns true if any of the children nodes is a non MBean metadata node.
      */
     private boolean hasNonMetadataNodes(DefaultMutableTreeNode node) {
-        for (Enumeration e = node.children(); e.hasMoreElements();) {
+        for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
             DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
             Object uo = n.getUserObject();
             if (uo instanceof XNodeInfo) {
@@ -205,7 +205,7 @@
      * Returns true if any of the children nodes is an MBean metadata node.
      */
     public boolean hasMetadataNodes(DefaultMutableTreeNode node) {
-        for (Enumeration e = node.children(); e.hasMoreElements();) {
+        for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
             DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
             Object uo = n.getUserObject();
             if (uo instanceof XNodeInfo) {
@@ -251,7 +251,7 @@
         Set<DefaultMutableTreeNode> metadataNodes =
                 new HashSet<DefaultMutableTreeNode>();
         DefaultTreeModel model = (DefaultTreeModel) getModel();
-        for (Enumeration e = node.children(); e.hasMoreElements();) {
+        for (Enumeration<?> e = node.children(); e.hasMoreElements();) {
             DefaultMutableTreeNode n = (DefaultMutableTreeNode) e.nextElement();
             Object uo = n.getUserObject();
             if (uo instanceof XNodeInfo) {
@@ -596,7 +596,7 @@
             if (ai != null && ai.length > 0) {
                 DefaultMutableTreeNode attributes = new DefaultMutableTreeNode();
                 XNodeInfo attributesUO = new XNodeInfo(Type.ATTRIBUTES, mbean,
-                        Resources.getText("Attributes"), null);
+                        Messages.ATTRIBUTES, null);
                 attributes.setUserObject(attributesUO);
                 node.insert(attributes, childIndex++);
                 for (MBeanAttributeInfo mbai : ai) {
@@ -613,7 +613,7 @@
             if (oi != null && oi.length > 0) {
                 DefaultMutableTreeNode operations = new DefaultMutableTreeNode();
                 XNodeInfo operationsUO = new XNodeInfo(Type.OPERATIONS, mbean,
-                        Resources.getText("Operations"), null);
+                        Messages.OPERATIONS, null);
                 operations.setUserObject(operationsUO);
                 node.insert(operations, childIndex++);
                 for (MBeanOperationInfo mboi : oi) {
@@ -646,7 +646,7 @@
             if (isBroadcaster != null && isBroadcaster.booleanValue()) {
                 DefaultMutableTreeNode notifications = new DefaultMutableTreeNode();
                 XNodeInfo notificationsUO = new XNodeInfo(Type.NOTIFICATIONS, mbean,
-                        Resources.getText("Notifications"), null);
+                        Messages.NOTIFICATIONS, null);
                 notifications.setUserObject(notificationsUO);
                 node.insert(notifications, childIndex++);
                 if (ni != null && ni.length > 0) {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTreeRenderer.java b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTreeRenderer.java
index 62b8843..fb885d7 100644
--- a/jdk/src/share/classes/sun/tools/jconsole/inspector/XTreeRenderer.java
+++ b/jdk/src/share/classes/sun/tools/jconsole/inspector/XTreeRenderer.java
@@ -30,8 +30,6 @@
 import javax.swing.JTree;
 import javax.swing.tree.DefaultMutableTreeNode;
 import javax.swing.tree.DefaultTreeCellRenderer;
-import sun.tools.jconsole.Resources;
-import sun.tools.jconsole.inspector.XNodeInfo.Type;
 
 @SuppressWarnings("serial")
 public class XTreeRenderer extends DefaultTreeCellRenderer {
diff --git a/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties
new file mode 100644
index 0000000..b89146e
--- /dev/null
+++ b/jdk/src/share/classes/sun/tools/jconsole/resources/messages.properties
@@ -0,0 +1,273 @@
+ONE_DAY=\ 1 day
+ONE_HOUR=\ 1 hour
+ONE_MIN=\ 1 min
+ONE_MONTH=\ 1 month
+ONE_YEAR=\ 1 year
+TWO_HOURS=\ 2 hours
+THREE_HOURS=\ 3 hours
+THREE_MONTHS=\ 3 months
+FIVE_MIN=\ 5 min
+SIX_HOURS=\ 6 hours
+SIX_MONTHS=\ 6 months
+SEVEN_DAYS=\ 7 days
+TEN_MIN=10 min
+TWELVE_HOURS=12 hours
+THIRTY_MIN=30 min
+LESS_THAN=<
+A_LOT_LESS_THAN=<<
+GREATER_THAN=>
+ACTION_CAPITALIZED=ACTION
+ACTION_INFO_CAPITALIZED=ACTION_INFO
+ALL=All
+ARCHITECTURE=Architecture
+ATTRIBUTE=Attribute
+ATTRIBUTE_VALUE=Attribute value
+ATTRIBUTE_VALUES=Attribute values
+ATTRIBUTES=Attributes
+BLANK=Blank
+BLOCKED_COUNT_WAITED_COUNT=Total blocked: {0}  Total waited: {1}\n
+BOOT_CLASS_PATH=Boot class path
+BORDERED_COMPONENT_MORE_OR_LESS_BUTTON_TOOLTIP=Toggle to show more or less information
+CPU_USAGE=CPU Usage
+CPU_USAGE_FORMAT=CPU Usage: {0}%
+CANCEL=Cancel
+CASCADE=&Cascade
+CHART_COLON=&Chart:
+CLASS_PATH=Class path
+CLASS_NAME=ClassName
+CLASS_TAB_INFO_LABEL_FORMAT=<html>Loaded: {0}    Unloaded: {1}    Total: {2}</html>
+CLASS_TAB_LOADED_CLASSES_PLOTTER_ACCESSIBLE_NAME=Chart for Loaded Classes.
+CLASSES=Classes
+CLOSE=Close
+COLUMN_NAME=Name
+COLUMN_PID=PID
+COMMITTED_MEMORY=Committed memory
+COMMITTED_VIRTUAL_MEMORY=Committed virtual memory
+COMMITTED=Committed
+CONNECT=&Connect
+CONNECT_DIALOG_CONNECT_BUTTON_TOOLTIP=Connect to Java Virtual Machine
+CONNECT_DIALOG_ACCESSIBLE_DESCRIPTION=Dialog for making a new connection to a local or remote Java Virtual Machine
+CONNECT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=Masthead Graphic
+CONNECT_DIALOG_MASTHEAD_TITLE=New Connection
+CONNECT_DIALOG_STATUS_BAR_ACCESSIBLE_NAME=Status Bar
+CONNECT_DIALOG_TITLE=JConsole: New Connection
+CONNECTED_PUNCTUATION_CLICK_TO_DISCONNECT_=Connected. Click to disconnect.
+CONNECTION_FAILED=Connection failed
+CONNECTION=&Connection
+CONNECTION_NAME=Connection name
+CONNECTION_NAME__DISCONNECTED_={0} (disconnected)
+CONSTRUCTOR=Constructor
+CURRENT_CLASSES_LOADED=Current classes loaded
+CURRENT_HEAP_SIZE=Current heap size
+CURRENT_VALUE=Current value: {0}
+CREATE=Create
+DAEMON_THREADS=Daemon threads
+DISCONNECTED_PUNCTUATION_CLICK_TO_CONNECT_=Disconnected. Click to connect.
+DOUBLE_CLICK_TO_EXPAND_FORWARD_SLASH_COLLAPSE=Double click to expand/collapse
+DOUBLE_CLICK_TO_VISUALIZE=Double click to visualize
+DESCRIPTION=Description
+DESCRIPTOR=Descriptor
+DETAILS=Details
+DETECT_DEADLOCK=&Detect Deadlock
+DETECT_DEADLOCK_TOOLTIP=Detect deadlocked threads
+DIMENSION_IS_NOT_SUPPORTED_COLON=Dimension is not supported:
+DISCARD_CHART=Discard chart
+DURATION_DAYS_HOURS_MINUTES={0,choice,1#{0,number,integer} day |1.0<{0,number,integer} days }{1,choice,0<{1,number,integer} hours |1#{1,number,integer} hour |1<{1,number,integer} hours }{2,choice,0<{2,number,integer} minutes|1#{2,number,integer} minute|1.0<{2,number,integer} minutes}
+DURATION_HOURS_MINUTES={0,choice,1#{0,number,integer} hour |1<{0,number,integer} hours }{1,choice,0<{1,number,integer} minutes|1#{1,number,integer} minute|1.0<{1,number,integer} minutes}
+DURATION_MINUTES={0,choice,1#{0,number,integer} minute|1.0<{0,number,integer} minutes}
+DURATION_SECONDS={0} seconds
+EMPTY_ARRAY=Empty array
+ERROR=Error
+ERROR_COLON_MBEANS_ALREADY_EXIST=Error: MBeans already exist
+ERROR_COLON_MBEANS_DO_NOT_EXIST=Error: MBeans do not exist
+EVENT=Event
+EXIT=E&xit
+FAIL_TO_LOAD_PLUGIN=Warning: Fail to load plugin: {0}
+FILE_CHOOSER_FILE_EXISTS_CANCEL_OPTION=Cancel
+FILE_CHOOSER_FILE_EXISTS_MESSAGE=<html><center>File already exists:<br>{0}<br>Do you want to replace it?
+FILE_CHOOSER_FILE_EXISTS_OK_OPTION=Replace
+FILE_CHOOSER_FILE_EXISTS_TITLE=File Exists
+FILE_CHOOSER_SAVED_FILE=<html>Saved to file:<br>{0}<br>({1} bytes)
+FILE_CHOOSER_SAVE_FAILED_MESSAGE=<html><center>Save to file failed:<br>{0}<br>{1}
+FILE_CHOOSER_SAVE_FAILED_TITLE=Save Failed
+FREE_PHYSICAL_MEMORY=Free physical memory
+FREE_SWAP_SPACE=Free swap space
+GARBAGE_COLLECTOR=Garbage collector
+GC_INFO=Name = ''{0}'', Collections = {1,choice,-1#Unavailable|0#{1,number,integer}}, Total time spent = {2}
+GC_TIME=GC time
+GC_TIME_DETAILS={0} on {1} ({2} collections)
+HEAP_MEMORY_USAGE=Heap Memory Usage
+HEAP=Heap
+HELP_ABOUT_DIALOG_ACCESSIBLE_DESCRIPTION=Dialog containing information about JConsole and JDK versions
+HELP_ABOUT_DIALOG_JCONSOLE_VERSION=JConsole version:<br>{0}
+HELP_ABOUT_DIALOG_JAVA_VERSION=Java VM version:<br>{0}
+HELP_ABOUT_DIALOG_MASTHEAD_ACCESSIBLE_NAME=Masthead Graphic
+HELP_ABOUT_DIALOG_MASTHEAD_TITLE=About JConsole
+HELP_ABOUT_DIALOG_TITLE=JConsole: About
+HELP_ABOUT_DIALOG_USER_GUIDE_LINK=JConsole &User Guide:<br>{0}
+HELP_ABOUT_DIALOG_USER_GUIDE_LINK_URL=http://java.sun.com/javase/6/docs/technotes/guides/management/jconsole.html
+HELP_MENU_ABOUT_TITLE=&About JConsole
+HELP_MENU_USER_GUIDE_TITLE=Online &User Guide
+HELP_MENU_TITLE=&Help
+HOTSPOT_MBEANS_ELLIPSIS=&Hotspot MBeans...
+HOTSPOT_MBEANS_DIALOG_ACCESSIBLE_DESCRIPTION=Dialog for managing Hotspot MBeans
+IMPACT=Impact
+INFO=Info
+INFO_CAPITALIZED=INFO
+INVALID_PLUGIN_PATH=Warning: Invalid plugin path: {0}
+INVALID_URL=Invalid URL: {0}
+IS=Is
+JAVA_MONITORING___MANAGEMENT_CONSOLE=Java Monitoring && Management Console
+JCONSOLE_COLON_=JConsole: {0}
+JCONSOLE_VERSION=JConsole version "{0}"
+JCONSOLE_ACCESSIBLE_DESCRIPTION=Java Monitoring && Management Console
+JIT_COMPILER=JIT compiler
+LIBRARY_PATH=Library path
+LIVE_THREADS=Live threads
+LOADED=Loaded
+LOCAL_PROCESS_COLON=&Local Process:
+MASTHEAD_FONT=Dialog-PLAIN-25
+MANAGEMENT_NOT_ENABLED=<b>Note</b>: The management agent is not enabled on this process.
+MANAGEMENT_WILL_BE_ENABLED=<b>Note</b>: The management agent will be enabled on this process.
+MBEAN_ATTRIBUTE_INFO=MBeanAttributeInfo
+MBEAN_INFO=MBeanInfo
+MBEAN_NOTIFICATION_INFO=MBeanNotificationInfo
+MBEAN_OPERATION_INFO=MBeanOperationInfo
+MBEANS=MBeans
+MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON=&Clear
+MBEANS_TAB_CLEAR_NOTIFICATIONS_BUTTON_TOOLTIP=Clear notifications
+MBEANS_TAB_COMPOSITE_NAVIGATION_MULTIPLE=Composite Navigation {0}/{1}
+MBEANS_TAB_COMPOSITE_NAVIGATION_SINGLE=Composite Navigation
+MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON=&Refresh
+MBEANS_TAB_REFRESH_ATTRIBUTES_BUTTON_TOOLTIP=Refresh attributes
+MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON=&Subscribe
+MBEANS_TAB_SUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=Start listening for notifications
+MBEANS_TAB_TABULAR_NAVIGATION_MULTIPLE=Tabular Navigation {0}/{1}
+MBEANS_TAB_TABULAR_NAVIGATION_SINGLE=Tabular Navigation
+MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON=&Unsubscribe
+MBEANS_TAB_UNSUBSCRIBE_NOTIFICATIONS_BUTTON_TOOLTIP=Stop listening for notifications
+MANAGE_HOTSPOT_MBEANS_IN_COLON_=Manage Hotspot MBeans in:
+MAX=Max
+MAXIMUM_HEAP_SIZE=Maximum heap size
+MEMORY=Memory
+MEMORY_POOL_LABEL=Memory Pool "{0}"
+MEMORY_TAB_HEAP_PLOTTER_ACCESSIBLE_NAME=Memory usage chart for heap.
+MEMORY_TAB_INFO_LABEL_FORMAT=<html>Used: {0}    Committed: {1}    Max: {2}</html>
+MEMORY_TAB_NON_HEAP_PLOTTER_ACCESSIBLE_NAME=Memory usage chart for non heap.
+MEMORY_TAB_POOL_CHART_ABOVE_THRESHOLD=which is above the threshold of {0}.\n
+MEMORY_TAB_POOL_CHART_ACCESSIBLE_NAME=Memory Pool Usage Chart.
+MEMORY_TAB_POOL_CHART_BELOW_THRESHOLD=which is below the threshold of {0}.\n
+MEMORY_TAB_POOL_PLOTTER_ACCESSIBLE_NAME=Memory usage chart for {0}.
+MESSAGE=Message
+METHOD_SUCCESSFULLY_INVOKED=Method successfully invoked
+MINIMIZE_ALL=&Minimize All
+MONITOR_LOCKED=\ \ \ - locked {0}\n
+NAME=Name
+NAME_AND_BUILD={0} (build {1})
+NAME_STATE=Name: {0}\nState: {1}\n
+NAME_STATE_LOCK_NAME=Name: {0}\nState: {1} on {2}\n
+NAME_STATE_LOCK_NAME_LOCK_OWNER=Name: {0}\nState: {1} on {2} owned by: {3}\n
+NEW_CONNECTION_ELLIPSIS=&New Connection...
+NO_DEADLOCK_DETECTED=No deadlock detected
+NON_HEAP_MEMORY_USAGE=Non-Heap Memory Usage
+NON_HEAP=Non-Heap
+NOTIFICATION=Notification
+NOTIFICATION_BUFFER=Notification buffer
+NOTIFICATIONS=Notifications
+NOTIF_TYPES=NotifTypes
+NUMBER_OF_THREADS=Number of Threads
+NUMBER_OF_LOADED_CLASSES=Number of Loaded Classes
+NUMBER_OF_PROCESSORS=Number of processors
+OBJECT_NAME=ObjectName
+OPERATING_SYSTEM=Operating System
+OPERATION=Operation
+OPERATION_INVOCATION=Operation invocation
+OPERATION_RETURN_VALUE=Operation return value
+OPERATIONS=Operations
+OVERVIEW=Overview
+OVERVIEW_PANEL_PLOTTER_ACCESSIBLE_NAME=Chart for {0}.
+PARAMETER=Parameter
+PASSWORD_ACCESSIBLE_NAME=Password
+PASSWORD_COLON_=&Password:
+PEAK=Peak
+PERFORM_GC=Perform &GC
+PERFORM_GC_TOOLTIP=Request Garbage Collection
+PLOTTER_ACCESSIBLE_NAME=Chart
+PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE={0}={1}\n
+PLOTTER_ACCESSIBLE_NAME_NO_DATA=No data plotted.
+PLOTTER_SAVE_AS_MENU_ITEM=Save data &as...
+PLOTTER_TIME_RANGE_MENU=&Time Range
+PROBLEM_ADDING_LISTENER=Problem adding listener
+PROBLEM_DISPLAYING_MBEAN=Problem displaying MBean
+PROBLEM_INVOKING=Problem invoking
+PROBLEM_REMOVING_LISTENER=Problem removing listener
+PROBLEM_SETTING_ATTRIBUTE=Problem setting attribute
+PROCESS_CPU_TIME=Process CPU time
+READABLE=Readable
+RECONNECT=Reconnect
+REMOTE_PROCESS_COLON=&Remote Process:
+REMOTE_PROCESS_TEXT_FIELD_ACCESSIBLE_NAME=Remote Process
+RESTORE_ALL=&Restore All
+RETURN_TYPE=ReturnType
+SEQ_NUM=SeqNum
+SIZE_BYTES={0,number,integer} bytes
+SIZE_GB={0} Gb
+SIZE_KB={0} Kb
+SIZE_MB={0} Mb
+SOURCE=Source
+STACK_TRACE=\nStack trace: \n
+SUMMARY_TAB_HEADER_DATE_TIME_FORMAT=FULL,FULL
+SUMMARY_TAB_PENDING_FINALIZATION_LABEL=Pending finalization
+SUMMARY_TAB_PENDING_FINALIZATION_VALUE={0} objects
+SUMMARY_TAB_TAB_NAME=VM Summary
+SUMMARY_TAB_VM_VERSION={0} version {1}
+THREADS=Threads
+THREAD_TAB_THREAD_INFO_ACCESSIBLE_NAME=Thread Information
+THREAD_TAB_THREAD_PLOTTER_ACCESSIBLE_NAME=Chart for number of threads.
+THRESHOLD=Threshold
+TILE=&Tile
+TIME_RANGE_COLON=&Time Range:
+TIME=Time
+TIME_STAMP=TimeStamp
+TOTAL_LOADED=Total Loaded
+TOTAL_CLASSES_LOADED=Total classes loaded
+TOTAL_CLASSES_UNLOADED=Total classes unloaded
+TOTAL_COMPILE_TIME=Total compile time
+TOTAL_PHYSICAL_MEMORY=Total physical memory
+TOTAL_THREADS_STARTED=Total threads started
+TOTAL_SWAP_SPACE=Total swap space
+TYPE=Type
+UNAVAILABLE=Unavailable
+UNKNOWN_CAPITALIZED=UNKNOWN
+UNKNOWN_HOST=Unknown Host: {0}
+UNREGISTER=Unregister
+UPTIME=Uptime
+USAGE_THRESHOLD=Usage Threshold
+REMOTE_TF_USAGE=<b>Usage</b>: &lt;hostname&gt;:&lt;port&gt; OR service:jmx:&lt;protocol&gt;:&lt;sap&gt;
+USED=Used
+USERNAME_COLON_=&Username:
+USERNAME_ACCESSIBLE_NAME=User Name
+USER_DATA=UserData
+VIRTUAL_MACHINE=Virtual Machine
+VM_ARGUMENTS=VM arguments
+VMINTERNAL_FRAME_ACCESSIBLE_DESCRIPTION=Internal frame for monitoring a Java Virtual Machine
+VALUE=Value
+VENDOR=Vendor
+VERBOSE_OUTPUT=Verbose Output
+VERBOSE_OUTPUT_TOOLTIP=Enable verbose output for class loading system
+VIEW=View
+WINDOW=&Window
+WINDOWS=Windows
+WRITABLE=Writable
+CONNECTION_FAILED1=Connection Failed: Retry?
+CONNECTION_FAILED2=The connection to {0} did not succeed.<br>Would you like to try again?
+CONNECTION_LOST1=Connection Lost: Reconnect?
+CONNECTING_TO1=Connecting to {0}
+CONNECTING_TO2=You are currently being connected to {0}.<br>This will take a few moments.
+DEADLOCK_TAB=Deadlock
+DEADLOCK_TAB_N=Deadlock {0}
+EXPAND=expand
+KBYTES={0} kbytes
+PLOT=plot
+VISUALIZE=visualize
+ZZ_USAGE_TEXT=Usage: {0} [ -interval=n ] [ -notile ] [ -pluginpath <path> ] [ -version ] [ connection ... ]\n\n  -interval   Set the update interval to n seconds (default is 4 seconds)\n  -notile     Do not tile windows initially (for two or more connections)\n  -pluginpath Specify the path that jconsole uses to look up the plugins\n  -version    Print program version\n\n  connection = pid || host:port || JMX URL (service:jmx:<protocol>://...)\n  pid         The process id of a target process\n  host        A remote host name or IP address\n  port        The port number for the remote connection\n\n  -J          Specify the input arguments to the Java virtual machine\n              on which jconsole is running
diff --git a/jdk/src/share/classes/sun/util/resources/CurrencyNames_es_VE.properties b/jdk/src/share/classes/sun/util/resources/CurrencyNames_es_VE.properties
index fea9c11..dd5b782 100644
--- a/jdk/src/share/classes/sun/util/resources/CurrencyNames_es_VE.properties
+++ b/jdk/src/share/classes/sun/util/resources/CurrencyNames_es_VE.properties
@@ -36,5 +36,5 @@
 # Taligent is a registered trademark of Taligent, Inc.
 
 VEB=Bs
-VEF=BsF.
+VEF=Bs.F.
 
diff --git a/jdk/src/share/demo/jvmti/hprof/hprof.h b/jdk/src/share/demo/jvmti/hprof/hprof.h
index 44afbf4..ec9fbf0 100644
--- a/jdk/src/share/demo/jvmti/hprof/hprof.h
+++ b/jdk/src/share/demo/jvmti/hprof/hprof.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -65,6 +65,7 @@
 #include "jni.h"
 #include "jvmti.h"
 #include "classfile_constants.h"
+#include "jvm_md.h"
 
 #ifndef SKIP_NPT
 #include "npt.h"   /* To get NptEnv for doing character conversions */
diff --git a/jdk/src/share/demo/jvmti/hprof/hprof_init.c b/jdk/src/share/demo/jvmti/hprof/hprof_init.c
index e3add30..328c474 100644
--- a/jdk/src/share/demo/jvmti/hprof/hprof_init.c
+++ b/jdk/src/share/demo/jvmti/hprof/hprof_init.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -1899,6 +1899,7 @@
      */
     getSystemProperty("sun.boot.library.path", &boot_path);
     md_build_library_name(lname, FILENAME_MAX, boot_path, name);
+    jvmtiDeallocate(boot_path);
     handle = md_load_library(lname, err_buf, (int)sizeof(err_buf));
     if ( handle == NULL ) {
         /* This may be necessary on Windows. */
@@ -1941,6 +1942,9 @@
 JNIEXPORT jint JNICALL
 Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
 {
+    char *boot_path = NULL;
+    char npt_lib[JVM_MAXPATHLEN];
+
     /* See if it's already loaded */
     if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
         HPROF_ERROR(JNI_TRUE, "Cannot load this JVM TI agent twice, check your java command line for duplicate hprof options.");
@@ -1957,9 +1961,15 @@
 
     gdata->jvm = vm;
 
+    /* Get the JVMTI environment */
+    getJvmti();
+
 #ifndef SKIP_NPT
+    getSystemProperty("sun.boot.library.path", &boot_path);
     /* Load in NPT library for character conversions */
-    NPT_INITIALIZE(&(gdata->npt), NPT_VERSION, NULL);
+    md_build_library_name(npt_lib, sizeof(npt_lib), boot_path, NPT_LIBNAME);
+    jvmtiDeallocate(boot_path);
+    NPT_INITIALIZE(npt_lib, &(gdata->npt), NPT_VERSION, NULL);
     if ( gdata->npt == NULL ) {
         HPROF_ERROR(JNI_TRUE, "Cannot load npt library");
     }
@@ -1969,9 +1979,6 @@
     }
 #endif
 
-    /* Get the JVMTI environment */
-    getJvmti();
-
     /* Lock needed to protect debug_malloc() code, which is not MT safe */
     #ifdef DEBUG
         gdata->debug_malloc_lock = createRawMonitor("HPROF debug_malloc lock");
diff --git a/jdk/src/share/demo/management/MemoryMonitor/MemoryMonitor.java b/jdk/src/share/demo/management/MemoryMonitor/MemoryMonitor.java
index 717e34b..5073546 100644
--- a/jdk/src/share/demo/management/MemoryMonitor/MemoryMonitor.java
+++ b/jdk/src/share/demo/management/MemoryMonitor/MemoryMonitor.java
@@ -122,6 +122,7 @@
         private Font font = new Font("Times New Roman", Font.PLAIN, 11);
         private int columnInc;
         private float usedMem[][];
+        private float usedMemMax[]; // Used when max pool size is undefined
         private int ptNum[];
         private int ascent, descent;
         private Rectangle graphOutlineRect = new Rectangle();
@@ -142,6 +143,10 @@
                 }
             });
             usedMem = new float[numPools][];
+            usedMemMax = new float[numPools];
+            for (int i = 0; i < numPools; i++) {
+                usedMemMax[i] = 1024f * 1024f ;
+            }
             ptNum = new int[numPools];
         }
 
@@ -194,6 +199,12 @@
             MemoryPoolMXBean mp = mpools.get(npool);
             float usedMemory =  mp.getUsage().getUsed();
             float totalMemory =  mp.getUsage().getMax();
+            if (totalMemory < 0) { // Max is undefined for this pool
+                if (usedMemory > usedMemMax[npool]) {
+                    usedMemMax[npool] = usedMemory;
+                }
+                totalMemory = usedMemMax[npool];
+            }
 
             // .. Draw allocated and used strings ..
             big.setColor(Color.green);
diff --git a/jdk/src/share/demo/management/MemoryMonitor/README.txt b/jdk/src/share/demo/management/MemoryMonitor/README.txt
index 9b264c7..2009e13 100644
--- a/jdk/src/share/demo/management/MemoryMonitor/README.txt
+++ b/jdk/src/share/demo/management/MemoryMonitor/README.txt
@@ -38,7 +38,7 @@
 
 To run the MemoryMonitor demo
 
-   java -jar <JDK_HOME>/demo/management/MemoryMonitor.jar 
+   java -jar <JDK_HOME>/demo/management/MemoryMonitor/MemoryMonitor.jar 
 
 These instructions assume that this installation's version of the java
 command is in your path.  If it isn't, then you should either
diff --git a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java
index 49d9ee7..f6b61fc 100644
--- a/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java
+++ b/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystemProvider.java
@@ -78,7 +78,7 @@
         }
         try {
             // only support legacy JAR URL syntax  jar:{uri}!/{entry} for now
-            String spec = uri.getSchemeSpecificPart();
+            String spec = uri.getRawSchemeSpecificPart();
             int sep = spec.indexOf("!/");
             if (sep != -1)
                 spec = spec.substring(0, sep);
diff --git a/jdk/src/share/lib/security/java.security b/jdk/src/share/lib/security/java.security-linux
similarity index 100%
rename from jdk/src/share/lib/security/java.security
rename to jdk/src/share/lib/security/java.security-linux
diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h b/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h
index e49cade..2563b2d 100644
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/defines.h
@@ -93,7 +93,7 @@
 // bytes and byte arrays
 
 typedef unsigned int uint;
-#if !defined(MACOSX) || (defined(MACOSX) && defined(NO_ZLIB))
+#if defined(NO_ZLIB)
 #ifdef _LP64
 typedef unsigned int uLong; // Historical zlib, should be 32-bit.
 #else
diff --git a/jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp b/jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp
index e77e99f..bedecda 100644
--- a/jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp
+++ b/jdk/src/share/native/com/sun/java/util/jar/pack/jni.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -82,7 +82,11 @@
 static unpacker* get_unpacker() {
   //fprintf(stderr, "get_unpacker()\n");
   JavaVM* vm = null;
-  JNI_GetCreatedJavaVMs(&vm, 1, null);
+  jsize nVM = 0;
+  jint retval = JNI_GetCreatedJavaVMs(&vm, 1, &nVM);
+  // other VM implements may differ, thus for correctness, we need these checks
+  if (retval != JNI_OK || nVM != 1)
+    return null;
   void* envRaw = null;
   vm->GetEnv(&envRaw, JNI_VERSION_1_1);
   JNIEnv* env = (JNIEnv*) envRaw;
diff --git a/jdk/src/share/native/java/io/FileInputStream.c b/jdk/src/share/native/java/io/FileInputStream.c
index 37deaf8..81fdd32 100644
--- a/jdk/src/share/native/java/io/FileInputStream.c
+++ b/jdk/src/share/native/java/io/FileInputStream.c
@@ -62,7 +62,7 @@
 }
 
 JNIEXPORT jint JNICALL
-Java_java_io_FileInputStream_read(JNIEnv *env, jobject this) {
+Java_java_io_FileInputStream_read0(JNIEnv *env, jobject this) {
     return readSingle(env, this, fis_fd);
 }
 
diff --git a/jdk/src/share/native/java/io/ObjectInputStream.c b/jdk/src/share/native/java/io/ObjectInputStream.c
index 8b8a710..1e288e9 100644
--- a/jdk/src/share/native/java/io/ObjectInputStream.c
+++ b/jdk/src/share/native/java/io/ObjectInputStream.c
@@ -173,16 +173,3 @@
     (*env)->ReleasePrimitiveArrayCritical(env, dst, doubles, 0);
 }
 
-/*
- * Class:     java_io_ObjectInputStream
- * Method:    latestUserDefinedLoader
- * Signature: ()Ljava/lang/ClassLoader;
- *
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
- */
-JNIEXPORT jobject JNICALL
-Java_java_io_ObjectInputStream_latestUserDefinedLoader(JNIEnv *env, jclass cls)
-{
-    return JVM_LatestUserDefinedLoader(env);
-}
diff --git a/jdk/src/share/native/java/io/RandomAccessFile.c b/jdk/src/share/native/java/io/RandomAccessFile.c
index 42733fb..f30d229 100644
--- a/jdk/src/share/native/java/io/RandomAccessFile.c
+++ b/jdk/src/share/native/java/io/RandomAccessFile.c
@@ -64,23 +64,23 @@
 }
 
 JNIEXPORT jint JNICALL
-Java_java_io_RandomAccessFile_read(JNIEnv *env, jobject this) {
+Java_java_io_RandomAccessFile_read0(JNIEnv *env, jobject this) {
     return readSingle(env, this, raf_fd);
 }
 
 JNIEXPORT jint JNICALL
-Java_java_io_RandomAccessFile_readBytes(JNIEnv *env,
+Java_java_io_RandomAccessFile_readBytes0(JNIEnv *env,
     jobject this, jbyteArray bytes, jint off, jint len) {
     return readBytes(env, this, bytes, off, len, raf_fd);
 }
 
 JNIEXPORT void JNICALL
-Java_java_io_RandomAccessFile_write(JNIEnv *env, jobject this, jint byte) {
+Java_java_io_RandomAccessFile_write0(JNIEnv *env, jobject this, jint byte) {
     writeSingle(env, this, byte, JNI_FALSE, raf_fd);
 }
 
 JNIEXPORT void JNICALL
-Java_java_io_RandomAccessFile_writeBytes(JNIEnv *env,
+Java_java_io_RandomAccessFile_writeBytes0(JNIEnv *env,
     jobject this, jbyteArray bytes, jint off, jint len) {
     writeBytes(env, this, bytes, off, len, JNI_FALSE, raf_fd);
 }
diff --git a/jdk/src/share/native/java/io/io_util.h b/jdk/src/share/native/java/io/io_util.h
index fd7862a..31088a9 100644
--- a/jdk/src/share/native/java/io/io_util.h
+++ b/jdk/src/share/native/java/io/io_util.h
@@ -25,9 +25,6 @@
 
 #include "jni.h"
 #include "jni_util.h"
-#ifdef MACOSX
-char* convertToNFDIfNeeded(const char *origPath, char *buf, size_t bufsize);
-#endif
 
 extern jfieldID IO_fd_fdID;
 extern jfieldID IO_handle_fdID;
@@ -59,7 +56,6 @@
 void throwFileNotFoundException(JNIEnv *env, jstring path);
 
 
-
 /*
  * Macros for managing platform strings.  The typical usage pattern is:
  *
@@ -88,35 +84,6 @@
  * declares a unique variable.
  */
 
-#ifdef MACOSX
-
-#define WITH_PLATFORM_STRING(env, strexp, var)                                \
-    if (1) {                                                                  \
-        const char *var;                                                      \
-        jstring _##var##str = (strexp);                                       \
-        if (_##var##str == NULL) {                                            \
-            JNU_ThrowNullPointerException((env), NULL);                       \
-            goto _##var##end;                                                 \
-        }                                                                     \
-        const char *temp_var = JNU_GetStringPlatformChars((env), _##var##str, NULL);      \
-        if (temp_var == NULL) goto _##var##end;                               \
-        char buf[MAXPATHLEN];                                                 \
-        var = convertToNFDIfNeeded(temp_var, buf, sizeof(buf));
-
-#define WITH_FIELD_PLATFORM_STRING(env, object, id, var)                      \
-    WITH_PLATFORM_STRING(env,                                                 \
-                         ((object == NULL)                                    \
-                          ? NULL                                              \
-                          : (*(env))->GetObjectField((env), (object), (id))), \
-                        var)
-
-#define END_PLATFORM_STRING(env, var)                                         \
-        JNU_ReleaseStringPlatformChars(env, _##var##str, temp_var);           \
-    _##var##end: ;                                                            \
-    } else ((void)NULL)
-
-#else
-
 #define WITH_PLATFORM_STRING(env, strexp, var)                                \
     if (1) {                                                                  \
         const char *var;                                                      \
@@ -140,8 +107,6 @@
     _##var##end: ;                                                            \
     } else ((void)NULL)
 
-#endif
-
 
 /* Macros for transforming Java Strings into native Unicode strings.
  * Works analogously to WITH_PLATFORM_STRING.
diff --git a/jdk/src/share/native/java/net/net_util.h b/jdk/src/share/native/java/net/net_util.h
index b385eb3..60caf79 100644
--- a/jdk/src/share/native/java/net/net_util.h
+++ b/jdk/src/share/native/java/net/net_util.h
@@ -140,6 +140,9 @@
 int
 NET_IsEqual(jbyte* caddr1, jbyte* caddr2);
 
+int
+NET_IsZeroAddr(jbyte* caddr);
+
 /* Socket operations
  *
  * These work just like the JVM_* procedures, except that they may do some
diff --git a/jdk/src/share/native/java/util/zip/Adler32.c b/jdk/src/share/native/java/util/zip/Adler32.c
index 61c5b56..87f265d 100644
--- a/jdk/src/share/native/java/util/zip/Adler32.c
+++ b/jdk/src/share/native/java/util/zip/Adler32.c
@@ -29,7 +29,7 @@
 
 #include "jni.h"
 #include "jni_util.h"
-#include "zlib.h"
+#include <zlib.h>
 
 #include "java_util_zip_Adler32.h"
 
diff --git a/jdk/src/share/native/java/util/zip/CRC32.c b/jdk/src/share/native/java/util/zip/CRC32.c
index 48b6652..689b34b 100644
--- a/jdk/src/share/native/java/util/zip/CRC32.c
+++ b/jdk/src/share/native/java/util/zip/CRC32.c
@@ -29,7 +29,7 @@
 
 #include "jni.h"
 #include "jni_util.h"
-#include "zlib.h"
+#include <zlib.h>
 
 #include "java_util_zip_CRC32.h"
 
diff --git a/jdk/src/share/native/java/util/zip/Deflater.c b/jdk/src/share/native/java/util/zip/Deflater.c
index 6cad24e..dbf5ea4 100644
--- a/jdk/src/share/native/java/util/zip/Deflater.c
+++ b/jdk/src/share/native/java/util/zip/Deflater.c
@@ -32,7 +32,7 @@
 #include "jlong.h"
 #include "jni.h"
 #include "jni_util.h"
-#include "zlib.h"
+#include <zlib.h>
 
 #include "java_util_zip_Deflater.h"
 
@@ -215,18 +215,6 @@
     return ((z_stream *)jlong_to_ptr(addr))->adler;
 }
 
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_Deflater_getBytesRead(JNIEnv *env, jclass cls, jlong addr)
-{
-    return ((z_stream *)jlong_to_ptr(addr))->total_in;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_Deflater_getBytesWritten(JNIEnv *env, jclass cls, jlong addr)
-{
-    return ((z_stream *)jlong_to_ptr(addr))->total_out;
-}
-
 JNIEXPORT void JNICALL
 Java_java_util_zip_Deflater_reset(JNIEnv *env, jclass cls, jlong addr)
 {
diff --git a/jdk/src/share/native/java/util/zip/Inflater.c b/jdk/src/share/native/java/util/zip/Inflater.c
index e5296fc..062a892 100644
--- a/jdk/src/share/native/java/util/zip/Inflater.c
+++ b/jdk/src/share/native/java/util/zip/Inflater.c
@@ -35,7 +35,7 @@
 #include "jni.h"
 #include "jvm.h"
 #include "jni_util.h"
-#include "zlib.h"
+#include <zlib.h>
 #include "java_util_zip_Inflater.h"
 
 #define ThrowDataFormatException(env, msg) \
@@ -174,18 +174,6 @@
     return ((z_stream *)jlong_to_ptr(addr))->adler;
 }
 
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_Inflater_getBytesRead(JNIEnv *env, jclass cls, jlong addr)
-{
-    return ((z_stream *)jlong_to_ptr(addr))->total_in;
-}
-
-JNIEXPORT jlong JNICALL
-Java_java_util_zip_Inflater_getBytesWritten(JNIEnv *env, jclass cls, jlong addr)
-{
-    return ((z_stream *)jlong_to_ptr(addr))->total_out;
-}
-
 JNIEXPORT void JNICALL
 Java_java_util_zip_Inflater_reset(JNIEnv *env, jclass cls, jlong addr)
 {
diff --git a/jdk/src/share/native/java/util/zip/ZipFile.c b/jdk/src/share/native/java/util/zip/ZipFile.c
index 99d6d22..281dbc6 100644
--- a/jdk/src/share/native/java/util/zip/ZipFile.c
+++ b/jdk/src/share/native/java/util/zip/ZipFile.c
@@ -117,6 +117,7 @@
             result = ptr_to_jlong(zip);
         } else if (msg != 0) {
             ThrowZipException(env, msg);
+            free(msg);
         } else if (errno == ENOMEM) {
             JNU_ThrowOutOfMemoryError(env, 0);
         } else {
diff --git a/jdk/src/share/native/java/util/zip/zip_util.c b/jdk/src/share/native/java/util/zip/zip_util.c
index 991ed5c..f46676d 100644
--- a/jdk/src/share/native/java/util/zip/zip_util.c
+++ b/jdk/src/share/native/java/util/zip/zip_util.c
@@ -44,7 +44,7 @@
 #include "io_util.h"
 #include "io_util_md.h"
 #include "zip_util.h"
-#include "zlib.h"
+#include <zlib.h>
 
 #ifdef _ALLBSD_SOURCE
 #define off64_t off_t
@@ -726,7 +726,7 @@
  * Opens a zip file with the specified mode. Returns the jzfile object
  * or NULL if an error occurred. If a zip error occurred then *pmsg will
  * be set to the error message text if pmsg != 0. Otherwise, *pmsg will be
- * set to NULL.
+ * set to NULL. Caller is responsible to free the error message.
  */
 jzfile *
 ZIP_Open_Generic(const char *name, char **pmsg, int mode, jlong lastModified)
@@ -751,12 +751,12 @@
  * Returns the jzfile corresponding to the given file name from the cache of
  * zip files, or NULL if the file is not in the cache.  If the name is longer
  * than PATH_MAX or a zip error occurred then *pmsg will be set to the error
- * message text if pmsg != 0. Otherwise, *pmsg will be set to NULL.
+ * message text if pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller
+ * is responsible to free the error message.
  */
 jzfile *
 ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified)
 {
-    static char errbuf[256];
     char buf[PATH_MAX];
     jzfile *zip;
 
@@ -771,7 +771,7 @@
 
     if (strlen(name) >= PATH_MAX) {
         if (pmsg) {
-            *pmsg = "zip file name too long";
+            *pmsg = strdup("zip file name too long");
         }
         return NULL;
     }
@@ -796,7 +796,8 @@
  * Reads data from the given file descriptor to create a jzfile, puts the
  * jzfile in a cache, and returns that jzfile.  Returns NULL in case of error.
  * If a zip error occurs, then *pmsg will be set to the error message text if
- * pmsg != 0. Otherwise, *pmsg will be set to NULL.
+ * pmsg != 0. Otherwise, *pmsg will be set to NULL. Caller is responsible to
+ * free the error message.
  */
 
 jzfile *
@@ -809,7 +810,7 @@
 ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
                  jboolean usemmap)
 {
-    static char errbuf[256];
+    char errbuf[256];
     jlong len;
     jzfile *zip;
 
@@ -825,7 +826,7 @@
 
     if (zfd == -1) {
         if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0)
-            *pmsg = errbuf;
+            *pmsg = strdup(errbuf);
         freeZip(zip);
         return NULL;
     }
@@ -834,11 +835,11 @@
     if (len <= 0) {
         if (len == 0) { /* zip file is empty */
             if (pmsg) {
-                *pmsg = "zip file is empty";
+                *pmsg = strdup("zip file is empty");
             }
         } else { /* error */
             if (pmsg && JVM_GetLastErrorString(errbuf, sizeof(errbuf)) > 0)
-                *pmsg = errbuf;
+                *pmsg = strdup(errbuf);
         }
         ZFILE_Close(zfd);
         freeZip(zip);
@@ -850,7 +851,8 @@
         /* An error occurred while trying to read the zip file */
         if (pmsg != 0) {
             /* Set the zip error message */
-            *pmsg = zip->msg;
+            if (zip->msg != NULL)
+                *pmsg = strdup(zip->msg);
         }
         freeZip(zip);
         return NULL;
@@ -867,12 +869,17 @@
  * Opens a zip file for reading. Returns the jzfile object or NULL
  * if an error occurred. If a zip error occurred then *msg will be
  * set to the error message text if msg != 0. Otherwise, *msg will be
- * set to NULL.
+ * set to NULL. Caller doesn't need to free the error message.
  */
 jzfile * JNICALL
 ZIP_Open(const char *name, char **pmsg)
 {
-    return ZIP_Open_Generic(name, pmsg, O_RDONLY, 0);
+    jzfile *file = ZIP_Open_Generic(name, pmsg, O_RDONLY, 0);
+    if (file == NULL && pmsg != NULL && *pmsg != NULL) {
+        free(*pmsg);
+        *pmsg = "Zip file open error";
+    }
+    return file;
 }
 
 /*
diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.3/compress.c b/jdk/src/share/native/java/util/zip/zlib-1.2.3/compress.c
index 5866998..c82999d 100644
--- a/jdk/src/share/native/java/util/zip/zlib-1.2.3/compress.c
+++ b/jdk/src/share/native/java/util/zip/zlib-1.2.3/compress.c
@@ -75,7 +75,7 @@
         deflateEnd(&stream);
         return err == Z_OK ? Z_BUF_ERROR : err;
     }
-    *destLen = (uLong)stream.total_out;
+    *destLen = stream.total_out;
 
     err = deflateEnd(&stream);
     return err;
diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.3/inflate.c b/jdk/src/share/native/java/util/zip/zlib-1.2.3/inflate.c
index caf1ad0..269ab33 100644
--- a/jdk/src/share/native/java/util/zip/zlib-1.2.3/inflate.c
+++ b/jdk/src/share/native/java/util/zip/zlib-1.2.3/inflate.c
@@ -1287,7 +1287,7 @@
 z_streamp strm;
 {
     unsigned len;               /* number of bytes to look at or looked at */
-    long long in, out;          /* temporary to save total_in and total_out */
+    unsigned long in, out;      /* temporary to save total_in and total_out */
     unsigned char buf[4];       /* to restore bit buffer to byte string */
     struct inflate_state FAR *state;
 
diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.3/patches/ChangeLog_java b/jdk/src/share/native/java/util/zip/zlib-1.2.3/patches/ChangeLog_java
index 068a0aa..6f013db 100644
--- a/jdk/src/share/native/java/util/zip/zlib-1.2.3/patches/ChangeLog_java
+++ b/jdk/src/share/native/java/util/zip/zlib-1.2.3/patches/ChangeLog_java
@@ -8,9 +8,3 @@
 
 (3)updated crc32.c/crc32()
    unsigned long      -> uLong
-
-(4)updated zlib.h (to support > 4G zipfile):
-   total_in/out: uLong -> long long
-
-(5)updated upinflate.c/inflateSync()
-   unsigned long in, out; -->  long long in, out;
diff --git a/jdk/src/share/native/java/util/zip/zlib-1.2.3/zlib.h b/jdk/src/share/native/java/util/zip/zlib-1.2.3/zlib.h
index 518b31a..88ffeee 100644
--- a/jdk/src/share/native/java/util/zip/zlib-1.2.3/zlib.h
+++ b/jdk/src/share/native/java/util/zip/zlib-1.2.3/zlib.h
@@ -106,11 +106,11 @@
 typedef struct z_stream_s {
     Bytef    *next_in;  /* next input byte */
     uInt     avail_in;  /* number of bytes available at next_in */
-    long long total_in; /* total nb of input bytes read so far */
+    uLong    total_in;  /* total nb of input bytes read so far */
 
     Bytef    *next_out; /* next output byte should be put there */
     uInt     avail_out; /* remaining free space at next_out */
-    long long total_out;/* total nb of bytes output so far */
+    uLong    total_out; /* total nb of bytes output so far */
 
     char     *msg;      /* last error message, NULL if no error */
     struct internal_state FAR *state; /* not visible by applications */
diff --git a/jdk/src/share/native/sun/java2d/opengl/OGLBlitLoops.c b/jdk/src/share/native/sun/java2d/opengl/OGLBlitLoops.c
index e27604a..5391434 100644
--- a/jdk/src/share/native/sun/java2d/opengl/OGLBlitLoops.c
+++ b/jdk/src/share/native/sun/java2d/opengl/OGLBlitLoops.c
@@ -393,7 +393,16 @@
                    OGLSDOps *dstOps,
                    jint dx1, jint dy1, jint dx2, jint dy2)
 {
+    jboolean adjustAlpha = (pf != NULL && !pf->hasAlpha);
     j2d_glBindTexture(dstOps->textureTarget, dstOps->textureID);
+
+    if (adjustAlpha) {
+        // if the source surface does not have an alpha channel,
+        // we need to ensure that the alpha values are forced to 1.0f
+        j2d_glPixelTransferf(GL_ALPHA_SCALE, 0.0f);
+        j2d_glPixelTransferf(GL_ALPHA_BIAS, 1.0f);
+    }
+
     // in case pixel stride is not a multiple of scanline stride the copy
     // has to be done line by line (see 6207877)
     if (srcInfo->scanStride % srcInfo->pixelStride != 0) {
@@ -413,6 +422,11 @@
                             dx1, dy1, dx2-dx1, dy2-dy1,
                             pf->format, pf->type, srcInfo->rasBase);
     }
+    if (adjustAlpha) {
+        // restore scale/bias to their original values
+        j2d_glPixelTransferf(GL_ALPHA_SCALE, 1.0f);
+        j2d_glPixelTransferf(GL_ALPHA_BIAS, 0.0f);
+    }
 }
 
 /**
diff --git a/jdk/src/share/native/sun/misc/VM.c b/jdk/src/share/native/sun/misc/VM.c
index 8744da7..2dbeb98 100644
--- a/jdk/src/share/native/sun/misc/VM.c
+++ b/jdk/src/share/native/sun/misc/VM.c
@@ -111,6 +111,11 @@
     get_thread_state_info(env, JAVA_THREAD_STATE_TERMINATED, values, names);
 }
 
+JNIEXPORT jobject JNICALL
+Java_sun_misc_VM_latestUserDefinedLoader(JNIEnv *env, jclass cls) {
+    return JVM_LatestUserDefinedLoader(env);
+}
+
 typedef void (JNICALL *GetJvmVersionInfo_fp)(JNIEnv*, jvm_version_info*, size_t);
 
 JNIEXPORT void JNICALL
diff --git a/jdk/src/solaris/back/linker_md.c b/jdk/src/solaris/back/linker_md.c
index efc09b0..0ca6bad 100644
--- a/jdk/src/solaris/back/linker_md.c
+++ b/jdk/src/solaris/back/linker_md.c
@@ -54,6 +54,32 @@
 #define LIB_SUFFIX "so"
 #endif
 
+static void dll_build_name(char* buffer, size_t buflen,
+                           const char* pname, const char* fname) {
+    // Based on os_solaris.cpp
+
+    char *path_sep = PATH_SEPARATOR;
+    char *pathname = (char *)pname;
+    while (strlen(pathname) > 0) {
+        char *p = strchr(pathname, *path_sep);
+        if (p == NULL) {
+            p = pathname + strlen(pathname);
+        }
+        /* check for NULL path */
+        if (p == pathname) {
+            continue;
+        }
+        (void)snprintf(buffer, buflen, "%.*s/lib%s." LIB_SUFFIX, (p - pathname),
+                       pathname, fname);
+
+        if (access(buffer, F_OK) == 0) {
+            break;
+        }
+        pathname = p + 1;
+        *buffer = '\0';
+    }
+}
+
 /*
  * create a string for the JNI native function name by adding the
  * appropriate decorations.
@@ -76,16 +102,16 @@
 {
     const int pnamelen = pname ? strlen(pname) : 0;
 
+    *holder = '\0';
     /* Quietly truncate on buffer overflow.  Should be an error. */
     if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
-        *holder = '\0';
         return;
     }
 
     if (pnamelen == 0) {
         (void)snprintf(holder, holderlen, "lib%s." LIB_SUFFIX, fname);
     } else {
-        (void)snprintf(holder, holderlen, "%s/lib%s." LIB_SUFFIX, pname, fname);
+      dll_build_name(holder, holderlen, pname, fname);
     }
 }
 
diff --git a/jdk/src/solaris/bin/java_md_solinux.c b/jdk/src/solaris/bin/java_md_solinux.c
index fc8bc99..b3da881 100644
--- a/jdk/src/solaris/bin/java_md_solinux.c
+++ b/jdk/src/solaris/bin/java_md_solinux.c
@@ -982,7 +982,18 @@
 int
 ContinueInNewThread0(int (JNICALL *continuation)(void *), jlong stack_size, void * args) {
     int rslt;
-#ifdef __linux__
+#ifdef __solaris__
+    thread_t tid;
+    long flags = 0;
+    if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
+      void * tmp;
+      thr_join(tid, NULL, &tmp);
+      rslt = (int)tmp;
+    } else {
+      /* See below. Continue in current thread if thr_create() failed */
+      rslt = continuation(args);
+    }
+#else /* ! __solaris__ */
     pthread_t tid;
     pthread_attr_t attr;
     pthread_attr_init(&attr);
@@ -1007,18 +1018,7 @@
     }
 
     pthread_attr_destroy(&attr);
-#else /* ! __linux__ */
-    thread_t tid;
-    long flags = 0;
-    if (thr_create(NULL, stack_size, (void *(*)(void *))continuation, args, flags, &tid) == 0) {
-      void * tmp;
-      thr_join(tid, NULL, &tmp);
-      rslt = (int)tmp;
-    } else {
-      /* See above. Continue in current thread if thr_create() failed */
-      rslt = continuation(args);
-    }
-#endif /* __linux__ */
+#endif /* __solaris__ */
     return rslt;
 }
 
diff --git a/jdk/src/solaris/bin/java_md_solinux.h b/jdk/src/solaris/bin/java_md_solinux.h
index a9e4438..4d39729 100644
--- a/jdk/src/solaris/bin/java_md_solinux.h
+++ b/jdk/src/solaris/bin/java_md_solinux.h
@@ -54,10 +54,10 @@
 #endif
 
 #include <dlfcn.h>
-#ifdef __linux__
-#include <pthread.h>
-#else
+#ifdef __solaris__
 #include <thread.h>
+#else
+#include <pthread.h>
 #endif
 
 #define JVM_DLL         "libjvm.so"
diff --git a/jdk/src/solaris/classes/java/lang/Terminator.java b/jdk/src/solaris/classes/java/lang/Terminator.java
index d0a9c49..1f430f9 100644
--- a/jdk/src/solaris/classes/java/lang/Terminator.java
+++ b/jdk/src/solaris/classes/java/lang/Terminator.java
@@ -53,14 +53,20 @@
             }
         };
         handler = sh;
+        // When -Xrs is specified the user is responsible for
+        // ensuring that shutdown hooks are run by calling
+        // System.exit()
         try {
             Signal.handle(new Signal("HUP"), sh);
+        } catch (IllegalArgumentException e) {
+        }
+        try {
             Signal.handle(new Signal("INT"), sh);
+        } catch (IllegalArgumentException e) {
+        }
+        try {
             Signal.handle(new Signal("TERM"), sh);
         } catch (IllegalArgumentException e) {
-            // When -Xrs is specified the user is responsible for
-            // ensuring that shutdown hooks are run by calling
-            // System.exit()
         }
     }
 
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java
index 8aa4e22..b957042 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XComponentPeer.java
@@ -618,7 +618,7 @@
             final XWindowPeer parentXWindow = getParentTopLevel();
             Window parentWindow = (Window)parentXWindow.getTarget();
             if (parentXWindow.isFocusableWindow() && parentXWindow.isSimpleWindow() &&
-                XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() != parentWindow)
+                XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() != parentWindow)
             {
                 postEvent(new InvocationEvent(parentWindow, new  Runnable() {
                         public void run() {
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
index bbebbf5..b4617a8 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDecoratedPeer.java
@@ -1108,7 +1108,7 @@
         focusLog.fine("Request for decorated window focus");
         // If this is Frame or Dialog we can't assure focus request success - but we still can try
         // If this is Window and its owner Frame is active we can be sure request succedded.
-        Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+        Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
         Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
 
         focusLog.finer("Current window is: active={0}, focused={1}",
@@ -1201,7 +1201,7 @@
     }
 
     public void handleWindowFocusOut(Window oppositeWindow, long serial) {
-        Window actualFocusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+        Window actualFocusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
 
         // If the actual focused window is not this decorated window then retain it.
         if (actualFocusedWindow != null && actualFocusedWindow != target) {
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java
index e76effb..fc0a0b7 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XDialogPeer.java
@@ -135,7 +135,7 @@
      * Thus we don't have to perform any transitive (a blocker of a blocker) checks.
      */
     boolean isFocusedWindowModalBlocker() {
-        Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+        Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
         XWindowPeer focusedWindowPeer = null;
 
         if (focusedWindow != null) {
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java
index 1ab53e6..c3d3e23 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedChildProxyPeer.java
@@ -98,11 +98,11 @@
     public void handleEvent(AWTEvent e) {
         switch (e.getID()) {
           case FocusEvent.FOCUS_GAINED:
-              XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(proxy);
+              XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(proxy);
               container.focusGained(handle);
               break;
           case FocusEvent.FOCUS_LOST:
-              XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+              XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
               container.focusLost(handle);
               break;
           case KeyEvent.KEY_PRESSED:
@@ -174,7 +174,7 @@
         if (lightweightChild == null) {
             lightweightChild = (Component)proxy;
         }
-        Component currentOwner = XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
+        Component currentOwner = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
         if (currentOwner != null && currentOwner.getPeer() == null) {
             currentOwner = null;
         }
@@ -226,7 +226,8 @@
               if (parent != null) {
                   Window parentWindow = (Window)parent;
                   // and check that it is focused
-                  if (!parentWindow.isFocused() && XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == parentWindow) {
+                  if (!parentWindow.isFocused() &&
+                      XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == parentWindow) {
                       // if it is not - skip requesting focus on Solaris
                       // but return true for compatibility.
                       return true;
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java
index c5384a2..026209e 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XEmbedClientHelper.java
@@ -204,7 +204,7 @@
         // XEMBED_FOCUS_OUT client messages), so we first need to check if
         // embedded is an active window before sending WINDOW_LOST_FOCUS
         // to shared code
-        if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() == embedded.target) {
+        if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == embedded.target) {
             embedded.handleWindowFocusOut(null, 0);
         }
     }
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java
index 304023b..79041cb 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java
@@ -25,66 +25,48 @@
 package sun.awt.X11;
 
 import java.awt.Component;
-import java.awt.KeyboardFocusManager;
 import java.awt.Window;
-
-import java.awt.event.FocusEvent;
-
-import java.awt.peer.KeyboardFocusManagerPeer;
-import java.awt.peer.ComponentPeer;
-
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-
 import sun.util.logging.PlatformLogger;
-
 import sun.awt.CausedFocusEvent;
-import sun.awt.SunToolkit;
 import sun.awt.KeyboardFocusManagerPeerImpl;
 
 public class XKeyboardFocusManagerPeer extends KeyboardFocusManagerPeerImpl {
     private static final PlatformLogger focusLog = PlatformLogger.getLogger("sun.awt.X11.focus.XKeyboardFocusManagerPeer");
+    private static final XKeyboardFocusManagerPeer inst = new XKeyboardFocusManagerPeer();
 
-    private static Object lock = new Object() {};
-    private static Component currentFocusOwner;
-    private static Window currentFocusedWindow;
+    private Component currentFocusOwner;
+    private Window currentFocusedWindow;
 
-    XKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
-        super(manager);
+    public static XKeyboardFocusManagerPeer getInstance() {
+        return inst;
+    }
+
+    private XKeyboardFocusManagerPeer() {
     }
 
     @Override
     public void setCurrentFocusOwner(Component comp) {
-        setCurrentNativeFocusOwner(comp);
-    }
-
-    @Override
-    public Component getCurrentFocusOwner() {
-        return getCurrentNativeFocusOwner();
-    }
-
-    @Override
-    public Window getCurrentFocusedWindow() {
-        return getCurrentNativeFocusedWindow();
-    }
-
-    public static void setCurrentNativeFocusOwner(Component comp) {
-        synchronized (lock) {
+        synchronized (this) {
             currentFocusOwner = comp;
         }
     }
 
-    public static Component getCurrentNativeFocusOwner() {
-        synchronized(lock) {
+    @Override
+    public Component getCurrentFocusOwner() {
+        synchronized(this) {
             return currentFocusOwner;
         }
     }
 
-    public static void setCurrentNativeFocusedWindow(Window win) {
-        if (focusLog.isLoggable(PlatformLogger.FINER)) focusLog.finer("Setting current native focused window " + win);
+    @Override
+    public void setCurrentFocusedWindow(Window win) {
+        if (focusLog.isLoggable(PlatformLogger.FINER)) {
+            focusLog.finer("Setting current focused window " + win);
+        }
+
         XWindowPeer from = null, to = null;
 
-        synchronized(lock) {
+        synchronized(this) {
             if (currentFocusedWindow != null) {
                 from = (XWindowPeer)currentFocusedWindow.getPeer();
             }
@@ -104,8 +86,9 @@
         }
     }
 
-    public static Window getCurrentNativeFocusedWindow() {
-        synchronized(lock) {
+    @Override
+    public Window getCurrentFocusedWindow() {
+        synchronized(this) {
             return currentFocusedWindow;
         }
     }
@@ -124,6 +107,6 @@
                                                          focusedWindowChangeAllowed,
                                                          time,
                                                          cause,
-                                                         getCurrentNativeFocusOwner());
+                                                         getInstance().getCurrentFocusOwner());
     }
 }
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XLabelPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XLabelPeer.java
index c0e2eec..3adfab0 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XLabelPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XLabelPeer.java
@@ -140,7 +140,7 @@
     }
     public void setFont(Font f) {
         super.setFont(f);
-        target.repaint();
+        repaint();
     }
 
     public void setAlignment(int align) {
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java
index 073bc7d..0fbecbf 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XTextAreaPeer.java
@@ -105,7 +105,6 @@
         this.target = target;
 
         //ComponentAccessor.enableEvents(target,AWTEvent.MOUSE_WHEEL_EVENT_MASK);
-        target.enableInputMethods(true);
 
         firstChangeSkipped = false;
         String text = ((TextArea)target).getText();
@@ -113,7 +112,6 @@
         jtext.setWrapStyleWord(true);
         jtext.getDocument().addDocumentListener(jtext);
         XToolkit.specialPeerMap.put(jtext,this);
-        jtext.enableInputMethods(true);
         textPane = new AWTTextPane(jtext,this, target.getParent());
 
         setBounds(x, y, width, height, SET_BOUNDS);
@@ -170,6 +168,8 @@
 
     public void dispose() {
         XToolkit.specialPeerMap.remove(jtext);
+        // visible caret has a timer thread which must be stopped
+        jtext.getCaret().setVisible(false);
         jtext.removeNotify();
         textPane.removeNotify();
         super.dispose();
@@ -466,13 +466,6 @@
 
     protected boolean setTextImpl(String txt) {
         if (jtext != null) {
-            // Please note that we do not want to post an event
-            // if setText() replaces an empty text by an empty text,
-            // that is, if component's text remains unchanged.
-            if (jtext.getDocument().getLength() == 0 && txt.length() == 0) {
-                return true;
-            }
-
             // JTextArea.setText() posts two different events (remove & insert).
             // Since we make no differences between text events,
             // the document listener has to be disabled while
@@ -660,10 +653,13 @@
     }
 
 
-    // TODO : fix this duplicate code
-    class XAWTCaret extends DefaultCaret {
+    static class XAWTCaret extends DefaultCaret {
         public void focusGained(FocusEvent e) {
             super.focusGained(e);
+            if (getComponent().isEnabled()){
+                // Make sure the cursor is visible in case of non-editable TextArea
+                super.setVisible(true);
+            }
             getComponent().repaint();
         }
 
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java
index c0785a8b..5ea62d3 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XTextFieldPeer.java
@@ -73,8 +73,6 @@
         xtext = new XAWTTextField(text,this, target.getParent());
         xtext.getDocument().addDocumentListener(xtext);
         xtext.setCursor(target.getCursor());
-        target.enableInputMethods(true);
-        xtext.enableInputMethods(true);
         XToolkit.specialPeerMap.put(xtext,this);
 
         TextField txt = (TextField) target;
@@ -106,6 +104,8 @@
 
     public void dispose() {
         XToolkit.specialPeerMap.remove(xtext);
+        // visible caret has a timer thread which must be stopped
+        xtext.getCaret().setVisible(false);
         xtext.removeNotify();
         super.dispose();
     }
@@ -579,31 +579,7 @@
         }
 
         protected Caret createCaret() {
-            return new XAWTCaret();
-        }
-    }
-
-    class XAWTCaret extends DefaultCaret {
-        public void focusGained(FocusEvent e) {
-            super.focusGained(e);
-            getComponent().repaint();
-        }
-
-        public void focusLost(FocusEvent e) {
-            super.focusLost(e);
-            getComponent().repaint();
-        }
-
-        // Fix for 5100950: textarea.getSelectedText() returns the de-selected text, on XToolkit
-        // Restoring Motif behaviour
-        // If the text is unhighlighted then we should sets the selection range to zero
-        public void setSelectionVisible(boolean vis) {
-            if (vis){
-                super.setSelectionVisible(vis);
-            }else{
-                // In order to de-select the selection
-                setDot(getDot());
-            }
+            return new XTextAreaPeer.XAWTCaret();
         }
     }
 
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
index 8abb788..21b1af5 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XToolkit.java
@@ -649,7 +649,7 @@
                 long w = 0;
                 if (windowToXWindow(ev.get_xany().get_window()) != null) {
                     Component owner =
-                        XKeyboardFocusManagerPeer.getCurrentNativeFocusOwner();
+                        XKeyboardFocusManagerPeer.getInstance().getCurrentFocusOwner();
                     if (owner != null) {
                         XWindow ownerWindow = (XWindow) AWTAccessor.getComponentAccessor().getPeer(owner);
                         if (ownerWindow != null) {
@@ -1121,9 +1121,8 @@
         return peer;
     }
 
-    public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) throws HeadlessException {
-        XKeyboardFocusManagerPeer peer = new XKeyboardFocusManagerPeer(manager);
-        return peer;
+    public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() throws HeadlessException {
+        return XKeyboardFocusManagerPeer.getInstance();
     }
 
     /**
@@ -1299,6 +1298,15 @@
         return new XInputMethodDescriptor();
     }
 
+    /**
+     * Returns whether enableInputMethods should be set to true for peered
+     * TextComponent instances on this platform. True by default.
+     */
+    @Override
+    public boolean enableInputMethodsForTextComponent() {
+        return true;
+    }
+
     static int getMultiClickTime() {
         if (awt_multiclick_time == 0) {
             initializeMultiClickTime();
diff --git a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java
index 6d346fb..164e6e5 100644
--- a/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java
+++ b/jdk/src/solaris/classes/sun/awt/X11/XWindowPeer.java
@@ -616,7 +616,7 @@
 
     public void handleWindowFocusIn_Dispatch() {
         if (EventQueue.isDispatchThread()) {
-            XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+            XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
             WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
             SunToolkit.setSystemGenerated(we);
             target.dispatchEvent(we);
@@ -625,7 +625,7 @@
 
     public void handleWindowFocusInSync(long serial) {
         WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
-        XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+        XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
         sendEvent(we);
     }
     // NOTE: This method may be called by privileged threads.
@@ -633,7 +633,7 @@
     public void handleWindowFocusIn(long serial) {
         WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_GAINED_FOCUS);
         /* wrap in Sequenced, then post*/
-        XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow((Window) target);
+        XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow((Window) target);
         postEvent(wrapInSequenced((AWTEvent) we));
     }
 
@@ -641,15 +641,15 @@
     //       DO NOT INVOKE CLIENT CODE ON THIS THREAD!
     public void handleWindowFocusOut(Window oppositeWindow, long serial) {
         WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
-        XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow(null);
-        XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+        XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
+        XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
         /* wrap in Sequenced, then post*/
         postEvent(wrapInSequenced((AWTEvent) we));
     }
     public void handleWindowFocusOutSync(Window oppositeWindow, long serial) {
         WindowEvent we = new WindowEvent((Window)target, WindowEvent.WINDOW_LOST_FOCUS, oppositeWindow);
-        XKeyboardFocusManagerPeer.setCurrentNativeFocusedWindow(null);
-        XKeyboardFocusManagerPeer.setCurrentNativeFocusOwner(null);
+        XKeyboardFocusManagerPeer.getInstance().setCurrentFocusedWindow(null);
+        XKeyboardFocusManagerPeer.getInstance().setCurrentFocusOwner(null);
         sendEvent(we);
     }
 
@@ -1137,7 +1137,7 @@
             // getWMState() always returns 0 (Withdrawn) for simple windows. Hence
             // we ignore the state for such windows.
             if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) {
-                if (XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow() ==
+                if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() ==
                         getTarget())
                 {
                     show = true;
@@ -1164,15 +1164,25 @@
     }
 
     public void dispose() {
+        if (isGrabbed()) {
+            if (grabLog.isLoggable(PlatformLogger.FINE)) {
+                grabLog.fine("Generating UngrabEvent on {0} because of the window disposal", this);
+            }
+            postEventToEventQueue(new sun.awt.UngrabEvent(getEventSource()));
+        }
+
         SunToolkit.awtLock();
+
         try {
             windows.remove(this);
         } finally {
             SunToolkit.awtUnlock();
         }
+
         if (warningWindow != null) {
             warningWindow.destroy();
         }
+
         removeRootPropertyEventDispatcher();
         mustControlStackPosition = false;
         super.dispose();
@@ -1184,12 +1194,13 @@
          * receive WM_TAKE_FOCUS.
          */
         if (isSimpleWindow()) {
-            if (target == XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow()) {
+            if (target == XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow()) {
                 Window owner = getDecoratedOwner((Window)target);
                 ((XWindowPeer)AWTAccessor.getComponentAccessor().getPeer(owner)).requestWindowFocus();
             }
         }
     }
+
     boolean isResizable() {
         return winAttr.isResizable;
     }
@@ -1824,7 +1835,7 @@
         // If this is Frame or Dialog we can't assure focus request success - but we still can try
         // If this is Window and its owner Frame is active we can be sure request succedded.
         Window ownerWindow  = XWindowPeer.getDecoratedOwner((Window)target);
-        Window focusedWindow = XKeyboardFocusManagerPeer.getCurrentNativeFocusedWindow();
+        Window focusedWindow = XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow();
         Window activeWindow = XWindowPeer.getDecoratedOwner(focusedWindow);
 
         if (isWMStateNetHidden()) {
diff --git a/jdk/src/solaris/classes/sun/awt/X11InputMethod.java b/jdk/src/solaris/classes/sun/awt/X11InputMethod.java
index ccfa510..b2a62c6 100644
--- a/jdk/src/solaris/classes/sun/awt/X11InputMethod.java
+++ b/jdk/src/solaris/classes/sun/awt/X11InputMethod.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -415,6 +415,10 @@
             setXICFocus(getPeer(lastXICFocussedComponent), false, isLastXICActive);
             lastXICFocussedComponent = null;
             isLastXICActive = false;
+
+            resetXIC();
+            needResetXICClient = null;
+            needResetXIC = false;
         }
     }
 
diff --git a/jdk/src/solaris/classes/sun/awt/motif/MToolkit.java b/jdk/src/solaris/classes/sun/awt/motif/MToolkit.java
index 44108be..153fa47 100644
--- a/jdk/src/solaris/classes/sun/awt/motif/MToolkit.java
+++ b/jdk/src/solaris/classes/sun/awt/motif/MToolkit.java
@@ -330,7 +330,7 @@
         return null;
     }
 
-    public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
+    public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() {
         return null;
     }
 
diff --git a/jdk/src/solaris/classes/sun/font/FontConfigManager.java b/jdk/src/solaris/classes/sun/font/FontConfigManager.java
index 41c1a5d8..c0177f3 100644
--- a/jdk/src/solaris/classes/sun/font/FontConfigManager.java
+++ b/jdk/src/solaris/classes/sun/font/FontConfigManager.java
@@ -347,6 +347,11 @@
         name = name.toLowerCase();
 
         initFontConfigFonts(false);
+        if (fontConfigFonts == null) {
+            // This avoids an immediate NPE if fontconfig look up failed
+            // but doesn't guarantee this is a recoverable situation.
+            return null;
+        }
 
         FcCompFont fcInfo = null;
         for (int i=0; i<fontConfigFonts.length; i++) {
diff --git a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
index 0ec5284..3151b22 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/DevPollArrayWrapper.java
@@ -71,7 +71,7 @@
     static final byte  IGNORE        = (byte)-1;
 
     // Maximum number of open file descriptors
-    static final int   OPEN_MAX      = fdLimit();
+    static final int   OPEN_MAX      = IOUtil.fdLimit();
 
     // Number of pollfd structures to create.
     // dpwrite/ioctl(DP_POLL) allows up to OPEN_MAX-1
@@ -316,5 +316,4 @@
     private native int poll0(long pollAddress, int numfds, long timeout,
                              int wfd);
     private static native void interrupt(int fd);
-    private static native int fdLimit();
 }
diff --git a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
index 5549de9..539b2c8 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/EPollArrayWrapper.java
@@ -74,7 +74,7 @@
     static final int EVENT_OFFSET     = 0;
     static final int DATA_OFFSET      = offsetofData();
     static final int FD_OFFSET        = DATA_OFFSET;
-    static final int NUM_EPOLLEVENTS  = Math.min(fdLimit(), 8192);
+    static final int NUM_EPOLLEVENTS  = Math.min(IOUtil.fdLimit(), 8192);
 
     // Base address of the native pollArray
     private final long pollArrayAddress;
@@ -296,7 +296,6 @@
                                  int epfd) throws IOException;
     private static native int sizeofEPollEvent();
     private static native int offsetofData();
-    private static native int fdLimit();
     private static native void interrupt(int fd);
     private static native void init();
 }
diff --git a/jdk/src/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java b/jdk/src/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java
new file mode 100644
index 0000000..2b89dad
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/EventPortSelectorImpl.java
@@ -0,0 +1,170 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.ch;
+
+import java.io.IOException;
+import java.nio.channels.*;
+import java.nio.channels.spi.*;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * Selector implementation based on the Solaris event port mechanism.
+ */
+
+class EventPortSelectorImpl
+    extends SelectorImpl
+{
+    private final EventPortWrapper pollWrapper;
+
+    // Maps from file descriptors to keys
+    private Map<Integer,SelectionKeyImpl> fdToKey;
+
+    // True if this Selector has been closed
+    private boolean closed = false;
+
+    // Lock for interrupt triggering and clearing
+    private final Object interruptLock = new Object();
+    private boolean interruptTriggered = false;
+
+    /**
+     * Package private constructor called by factory method in
+     * the abstract superclass Selector.
+     */
+    EventPortSelectorImpl(SelectorProvider sp) throws IOException {
+        super(sp);
+        pollWrapper = new EventPortWrapper();
+        fdToKey = new HashMap<>();
+    }
+
+    protected int doSelect(long timeout) throws IOException {
+        if (closed)
+            throw new ClosedSelectorException();
+        processDeregisterQueue();
+        int entries;
+        try {
+            begin();
+            entries = pollWrapper.poll(timeout);
+        } finally {
+            end();
+        }
+        processDeregisterQueue();
+        int numKeysUpdated = updateSelectedKeys(entries);
+        if (pollWrapper.interrupted()) {
+            synchronized (interruptLock) {
+                interruptTriggered = false;
+            }
+        }
+        return numKeysUpdated;
+    }
+
+    private int updateSelectedKeys(int entries) {
+        int numKeysUpdated = 0;
+        for (int i=0; i<entries; i++) {
+            int nextFD = pollWrapper.getDescriptor(i);
+            SelectionKeyImpl ski = fdToKey.get(Integer.valueOf(nextFD));
+            if (ski != null) {
+                int rOps = pollWrapper.getEventOps(i);
+                if (selectedKeys.contains(ski)) {
+                    if (ski.channel.translateAndSetReadyOps(rOps, ski)) {
+                        numKeysUpdated++;
+                    }
+                } else {
+                    ski.channel.translateAndSetReadyOps(rOps, ski);
+                    if ((ski.nioReadyOps() & ski.nioInterestOps()) != 0) {
+                        selectedKeys.add(ski);
+                        numKeysUpdated++;
+                    }
+                }
+            }
+        }
+        return numKeysUpdated;
+    }
+
+    protected void implClose() throws IOException {
+        if (closed)
+            return;
+        closed = true;
+
+        // prevent further wakeup
+        synchronized (interruptLock) {
+            interruptTriggered = true;
+        }
+
+        pollWrapper.close();
+        selectedKeys = null;
+
+        // Deregister channels
+        Iterator<SelectionKey> i = keys.iterator();
+        while (i.hasNext()) {
+            SelectionKeyImpl ski = (SelectionKeyImpl)i.next();
+            deregister(ski);
+            SelectableChannel selch = ski.channel();
+            if (!selch.isOpen() && !selch.isRegistered())
+                ((SelChImpl)selch).kill();
+            i.remove();
+        }
+    }
+
+    protected void implRegister(SelectionKeyImpl ski) {
+        int fd = IOUtil.fdVal(ski.channel.getFD());
+        fdToKey.put(Integer.valueOf(fd), ski);
+        keys.add(ski);
+    }
+
+    protected void implDereg(SelectionKeyImpl ski) throws IOException {
+        int i = ski.getIndex();
+        assert (i >= 0);
+        int fd = ski.channel.getFDVal();
+        fdToKey.remove(Integer.valueOf(fd));
+        pollWrapper.release(fd);
+        ski.setIndex(-1);
+        keys.remove(ski);
+        selectedKeys.remove(ski);
+        deregister((AbstractSelectionKey)ski);
+        SelectableChannel selch = ski.channel();
+        if (!selch.isOpen() && !selch.isRegistered())
+            ((SelChImpl)selch).kill();
+    }
+
+    public void putEventOps(SelectionKeyImpl sk, int ops) {
+        if (closed)
+            throw new ClosedSelectorException();
+        int fd = sk.channel.getFDVal();
+        pollWrapper.setInterest(fd, ops);
+    }
+
+    public Selector wakeup() {
+        synchronized (interruptLock) {
+            if (!interruptTriggered) {
+                pollWrapper.interrupt();
+                interruptTriggered = true;
+            }
+        }
+        return this;
+    }
+}
diff --git a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c b/jdk/src/solaris/classes/sun/nio/ch/EventPortSelectorProvider.java
similarity index 65%
copy from jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
copy to jdk/src/solaris/classes/sun/nio/ch/EventPortSelectorProvider.java
index 089afbd..25546e3 100644
--- a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
+++ b/jdk/src/solaris/classes/sun/nio/ch/EventPortSelectorProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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,22 +23,20 @@
  * questions.
  */
 
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
+package sun.nio.ch;
 
-#include "sun_rmi_server_MarshalInputStream.h"
+import java.io.IOException;
+import java.nio.channels.*;
+import java.nio.channels.spi.*;
 
-/*
- * Class:     sun_rmi_server_MarshalInputStream
- * Method:    latestUserDefinedLoader
- * Signature: ()Ljava/lang/ClassLoader;
- *
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
- */
-JNIEXPORT jobject JNICALL
-Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader(JNIEnv *env, jclass cls)
+public class EventPortSelectorProvider
+    extends SelectorProviderImpl
 {
-    return JVM_LatestUserDefinedLoader(env);
+    public AbstractSelector openSelector() throws IOException {
+        return new EventPortSelectorImpl(this);
+    }
+
+    public Channel inheritedChannel() throws IOException {
+        return InheritedChannel.getChannel();
+    }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java b/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java
new file mode 100644
index 0000000..8e6ec43
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/ch/EventPortWrapper.java
@@ -0,0 +1,262 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.ch;
+
+import sun.misc.Unsafe;
+import java.io.IOException;
+import java.util.*;
+import static sun.nio.ch.SolarisEventPort.*;
+
+/**
+ * Manages a Solaris event port and manipulates a native array of pollfd structs
+ * on Solaris.
+ */
+
+class EventPortWrapper {
+    private static final Unsafe unsafe = Unsafe.getUnsafe();
+    private static final int addressSize = unsafe.addressSize();
+
+    // Maximum number of open file descriptors
+    static final int   OPEN_MAX     = IOUtil.fdLimit();
+
+    // Maximum number of events to retrive in one call to port_getn
+    static final int   POLL_MAX     =  Math.min(OPEN_MAX-1, 1024);
+
+    // initial size of the array to hold pending updates
+    private final int INITIAL_PENDING_UPDATE_SIZE = 256;
+
+    // maximum size of updateArray
+    private final int MAX_UPDATE_ARRAY_SIZE = Math.min(OPEN_MAX, 64*1024);
+
+    // special update status to indicate that it should be ignored
+    private static final byte IGNORE = -1;
+
+    // port file descriptor
+    private final int pfd;
+
+    // the poll array (populated by port_getn)
+    private final long pollArrayAddress;
+    private final AllocatedNativeObject pollArray;
+
+    // required when accessing the update* fields
+    private final Object updateLock = new Object();
+
+    // the number of pending updates
+    private int updateCount;
+
+    // queue of file descriptors with updates pending
+    private int[] updateDescriptors = new int[INITIAL_PENDING_UPDATE_SIZE];
+
+    // events for file descriptors with registration changes pending, indexed
+    // by file descriptor and stored as bytes for efficiency reasons. For
+    // file descriptors higher than MAX_UPDATE_ARRAY_SIZE (unlimited case at
+    // least then the update is stored in a map.
+    private final byte[] eventsLow = new byte[MAX_UPDATE_ARRAY_SIZE];
+    private Map<Integer,Byte> eventsHigh;
+    // Used by release and updateRegistrations to track whether a file
+    // descriptor is registered with /dev/poll.
+    private final BitSet registered = new BitSet();
+
+    // bit set to indicate if a file descriptor has been visited when
+    // processing updates (used to avoid duplicates calls to port_associate)
+    private BitSet visited = new BitSet();
+
+    EventPortWrapper() throws IOException {
+        int allocationSize = POLL_MAX * SIZEOF_PORT_EVENT;
+        pollArray = new AllocatedNativeObject(allocationSize, true);
+        pollArrayAddress = pollArray.address();
+        this.pfd = port_create();
+        if (OPEN_MAX > MAX_UPDATE_ARRAY_SIZE)
+            eventsHigh = new HashMap<>();
+    }
+
+    void close() throws IOException {
+        port_close(pfd);
+        pollArray.free();
+    }
+
+    private short getSource(int i) {
+        int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_SOURCE;
+        return pollArray.getShort(offset);
+    }
+
+    int getEventOps(int i) {
+        int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_EVENTS;
+        return pollArray.getInt(offset);
+    }
+
+    int getDescriptor(int i) {
+        int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_OBJECT;
+        if (addressSize == 4) {
+            return pollArray.getInt(offset);
+        } else {
+            return (int) pollArray.getLong(offset);
+        }
+    }
+
+    private void setDescriptor(int i, int fd) {
+        int offset = SIZEOF_PORT_EVENT * i + OFFSETOF_OBJECT;
+        if (addressSize == 4) {
+            pollArray.putInt(offset, fd);
+        } else {
+            pollArray.putLong(offset, fd);
+        }
+    }
+
+    private void setUpdate(int fd, byte events) {
+        if (fd < MAX_UPDATE_ARRAY_SIZE) {
+            eventsLow[fd] = events;
+        } else {
+            eventsHigh.put(Integer.valueOf(fd), Byte.valueOf(events));
+        }
+    }
+
+    private byte getUpdate(int fd) {
+        if (fd < MAX_UPDATE_ARRAY_SIZE) {
+            return eventsLow[fd];
+        } else {
+            Byte result = eventsHigh.get(Integer.valueOf(fd));
+            // result should never be null
+            return result.byteValue();
+        }
+    }
+
+    int poll(long timeout) throws IOException {
+        // update registrations prior to poll
+        synchronized (updateLock) {
+
+            // process newest updates first
+            int i = updateCount - 1;
+            while (i >= 0) {
+                int fd = updateDescriptors[i];
+                if (!visited.get(fd)) {
+                    short ev = getUpdate(fd);
+                    if (ev != IGNORE) {
+                        if (ev == 0) {
+                            if (registered.get(fd)) {
+                                port_dissociate(pfd, PORT_SOURCE_FD, (long)fd);
+                                registered.clear(fd);
+                            }
+                        } else {
+                            if (port_associate(pfd, PORT_SOURCE_FD, (long)fd, ev)) {
+                                registered.set(fd);
+                            }
+                        }
+
+                    }
+                    visited.set(fd);
+                }
+                i--;
+            }
+            updateCount = 0;
+        }
+
+        // poll for events
+        int updated = port_getn(pfd, pollArrayAddress, POLL_MAX, timeout);
+
+        // after polling we need to queue all polled file descriptors as they
+        // are candidates to register for the next poll.
+        synchronized (updateLock) {
+            for (int i=0; i<updated; i++) {
+                if (getSource(i) == PORT_SOURCE_USER) {
+                    interrupted = true;
+                    setDescriptor(i, -1);
+                } else {
+                    // the default is to re-associate for the next poll
+                    int fd = getDescriptor(i);
+                    registered.clear(fd);
+                    setInterest(fd);
+                }
+            }
+        }
+
+        return updated;
+    }
+
+    private void setInterest(int fd) {
+        assert Thread.holdsLock(updateLock);
+
+        // record the file descriptor and events, expanding the
+        // respective arrays first if necessary.
+        int oldCapacity = updateDescriptors.length;
+        if (updateCount >= oldCapacity) {
+            int newCapacity = oldCapacity + INITIAL_PENDING_UPDATE_SIZE;
+            int[] newDescriptors = new int[newCapacity];
+            System.arraycopy(updateDescriptors, 0, newDescriptors, 0, oldCapacity);
+            updateDescriptors = newDescriptors;
+        }
+        updateDescriptors[updateCount++] = fd;
+        visited.clear(fd);
+    }
+
+    void setInterest(int fd, int mask) {
+        synchronized (updateLock) {
+            setInterest(fd);
+            setUpdate(fd, (byte)mask);
+            assert getUpdate(fd) == mask;
+        }
+    }
+
+    void release(int fd) {
+        synchronized (updateLock) {
+            if (registered.get(fd)) {
+                try {
+                    port_dissociate(pfd, PORT_SOURCE_FD, (long)fd);
+                } catch (IOException ioe) {
+                    InternalError x =
+                        new InternalError(ioe.getMessage());
+                    x.initCause(ioe);
+                    throw x;
+                }
+                registered.clear(fd);
+            }
+            setUpdate(fd, IGNORE);
+        }
+    }
+
+    // -- wakeup support --
+
+    private boolean interrupted;
+
+    public void interrupt() {
+        try {
+            port_send(pfd, 0);
+        } catch (IOException ioe) {
+            InternalError x =
+                new InternalError(ioe.getMessage());
+            x.initCause(ioe);
+            throw x;
+        }
+    }
+
+    boolean interrupted() {
+        return interrupted;
+    }
+
+    void clearInterrupted() {
+        interrupted = false;
+    }
+}
diff --git a/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java b/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java
index 276b4b9..6f20d4c 100644
--- a/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java
+++ b/jdk/src/solaris/classes/sun/nio/ch/SolarisEventPort.java
@@ -31,8 +31,8 @@
 import sun.misc.Unsafe;
 
 /**
- * AsynchronousChannelGroup implementation based on the Solaris 10 event port
- * framework.
+ * Provides an AsynchronousChannelGroup implementation based on the Solaris 10
+ * event port framework and also provides direct access to that framework.
  */
 
 class SolarisEventPort
@@ -54,14 +54,14 @@
      *     void            *portev_user;
      * } port_event_t;
      */
-    private static final int SIZEOF_PORT_EVENT  = dependsArch(16, 24);
-    private static final int OFFSETOF_EVENTS    = 0;
-    private static final int OFFSETOF_SOURCE    = 4;
-    private static final int OFFSETOF_OBJECT    = 8;
+    static final int SIZEOF_PORT_EVENT  = dependsArch(16, 24);
+    static final int OFFSETOF_EVENTS    = 0;
+    static final int OFFSETOF_SOURCE    = 4;
+    static final int OFFSETOF_OBJECT    = 8;
 
     // port sources
-    private static final short PORT_SOURCE_USER     = 3;
-    private static final short PORT_SOURCE_FD       = 4;
+    static final short PORT_SOURCE_USER     = 3;
+    static final short PORT_SOURCE_FD       = 4;
 
     // file descriptor to event port.
     private final int port;
@@ -75,7 +75,7 @@
         super(provider, pool);
 
         // create event port
-        this.port = portCreate();
+        this.port = port_create();
     }
 
     SolarisEventPort start() {
@@ -90,12 +90,12 @@
                 return;
             closed = true;
         }
-        portClose(port);
+        port_close(port);
     }
 
     private void wakeup() {
         try {
-            portSend(port, 0);
+            port_send(port, 0);
         } catch (IOException x) {
             throw new AssertionError(x);
         }
@@ -124,7 +124,7 @@
             // send user event to wakeup each thread
             while (nThreads-- > 0) {
                 try {
-                    portSend(port, 0);
+                    port_send(port, 0);
                 } catch (IOException x) {
                     throw new AssertionError(x);
                 }
@@ -137,7 +137,7 @@
         // (re-)associate file descriptor
         // no need to translate events
         try {
-            portAssociate(port, PORT_SOURCE_FD, fd, events);
+            port_associate(port, PORT_SOURCE_FD, fd, events);
         } catch (IOException x) {
             throw new AssertionError();     // should not happen
         }
@@ -164,7 +164,7 @@
                     // A error here is fatal (thread will not be replaced)
                     replaceMe = false;
                     try {
-                        portGet(port, address);
+                        port_get(port, address);
                     } catch (IOException x) {
                         x.printStackTrace();
                         return;
@@ -220,26 +220,46 @@
         }
     }
 
-    // -- Native methods --
+    /**
+     * Creates an event port
+     */
+    static native int port_create() throws IOException;
 
-    private static native void init();
-
-    private static native int portCreate() throws IOException;
-
-    private static native void portAssociate(int port, int source, long object,
-        int events) throws IOException;
-
-    private static native void portGet(int port, long pe) throws IOException;
-
-    private static native int portGetn(int port, long address, int max)
+    /**
+     * Associates specific events of a given object with a port
+     */
+    static native boolean port_associate(int port, int source, long object, int events)
         throws IOException;
 
-    private static native void portSend(int port, int events) throws IOException;
+    /**
+     * Removes the association of an object with a port.
+     */
+    static native boolean port_dissociate(int port, int source, long object)
+        throws IOException;
 
-    private static native void portClose(int port);
+    /**
+     * Retrieves a single event from a port
+     */
+    static native void port_get(int port, long pe) throws IOException;
+
+    /**
+     * Retrieves at most {@code max} events from a port.
+     */
+    static native int port_getn(int port, long address, int max, long timeout)
+        throws IOException;
+
+    /**
+     * Sends a user-defined eventto a specified  port.
+     */
+    static native void port_send(int port, int events) throws IOException;
+
+    /**
+     * Closes a port.
+     */
+    static native void port_close(int port);
+
 
     static {
         Util.load();
-        init();
     }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/BsdNativeDispatcher.java b/jdk/src/solaris/classes/sun/nio/fs/BsdNativeDispatcher.java
index 74b8cc2..83b668c 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/BsdNativeDispatcher.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/BsdNativeDispatcher.java
@@ -33,7 +33,7 @@
  */
 
 class BsdNativeDispatcher extends UnixNativeDispatcher {
-    private BsdNativeDispatcher() { }
+    protected BsdNativeDispatcher() { }
 
    /**
     * struct fsstat_iter *getfsstat();
@@ -55,11 +55,6 @@
     private static native void initIDs();
 
     static {
-        AccessController.doPrivileged(new PrivilegedAction<Void>() {
-            public Void run() {
-                System.loadLibrary("nio");
-                return null;
-        }});
-        initIDs();
+         initIDs();
     }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java
index 9f8d479..f0947c2 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileSystemProvider.java
@@ -69,7 +69,7 @@
         if (osname.equals("Linux"))
             return createProvider("sun.nio.fs.LinuxFileSystemProvider");
         if (osname.equals("Darwin") || osname.contains("OS X"))
-            return createProvider("sun.nio.fs.BsdFileSystemProvider");
+            return createProvider("sun.nio.fs.MacOSXFileSystemProvider");
         throw new AssertionError("Platform not recognized");
     }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java
index b7c791d..9259fae 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/DefaultFileTypeDetector.java
@@ -25,12 +25,15 @@
 
 package sun.nio.fs;
 
+import java.nio.file.FileSystems;
 import java.nio.file.spi.FileTypeDetector;
+import java.nio.file.spi.FileSystemProvider;
 
 public class DefaultFileTypeDetector {
     private DefaultFileTypeDetector() { }
 
     public static FileTypeDetector create() {
-        return new GnomeFileTypeDetector();
+        FileSystemProvider provider = FileSystems.getDefault().provider();
+        return ((UnixFileSystemProvider)provider).getFileTypeDetector();
     }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java
index 89be861..fb6f6d1 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystem.java
@@ -82,7 +82,7 @@
             try {
                 for (;;) {
                     UnixMountEntry entry = new UnixMountEntry();
-                    int res = getextmntent(fp, entry);
+                    int res = getmntent(fp, entry);
                     if (res < 0)
                         break;
                     entries.add(entry);
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java
index 1045a7e..4d61598 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxFileSystemProvider.java
@@ -27,6 +27,7 @@
 
 import java.nio.file.*;
 import java.nio.file.attribute.*;
+import java.nio.file.spi.FileTypeDetector;
 import java.io.IOException;
 
 /**
@@ -96,4 +97,9 @@
             return super.readAttributes(file, type, options);
         }
     }
+
+    @Override
+    FileTypeDetector getFileTypeDetector() {
+        return new GnomeFileTypeDetector();
+    }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java
index 537eaa6..d657fcb 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxNativeDispatcher.java
@@ -51,9 +51,15 @@
     private static native long setmntent0(long pathAddress, long typeAddress)
         throws UnixException;
 
-   /**
-    * int endmntent(FILE* filep);
-    */
+    /**
+     * int getmntent(FILE *fp, struct mnttab *mp, int len);
+     */
+    static native int getmntent(long fp, UnixMountEntry entry)
+        throws UnixException;
+
+    /**
+     * int endmntent(FILE* filep);
+     */
     static native void endmntent(long stream) throws UnixException;
 
     /**
@@ -90,7 +96,6 @@
     private static native void fsetxattr0(int filedes, long nameAddress,
         long valueAdddress, int valueLen) throws UnixException;
 
-
     /**
      * fremovexattr(int filedes, const char *name);
      */
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
index 586e4b3..46e7f2c 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxUserDefinedFileAttributeView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -55,7 +55,7 @@
         name = USER_NAMESPACE + name;
         byte[] bytes = name.getBytes();
         if (bytes.length > XATTR_NAME_MAX) {
-            throw new FileSystemException(file.getPathForExecptionMessage(),
+            throw new FileSystemException(file.getPathForExceptionMessage(),
                 null, "'" + name + "' is too big");
         }
         return bytes;
@@ -116,7 +116,7 @@
                         buffer = NativeBuffers.getNativeBuffer(size);
                         continue;
                     }
-                    throw new FileSystemException(file.getPathForExecptionMessage(),
+                    throw new FileSystemException(file.getPathForExceptionMessage(),
                         null, "Unable to get list of extended attributes: " +
                         x.getMessage());
                 }
@@ -138,7 +138,7 @@
             // fgetxattr returns size if called with size==0
             return fgetxattr(fd, nameAsBytes(file,name), 0L, 0);
         } catch (UnixException x) {
-            throw new FileSystemException(file.getPathForExecptionMessage(),
+            throw new FileSystemException(file.getPathForExceptionMessage(),
                 null, "Unable to get size of extended attribute '" + name +
                 "': " + x.getMessage());
         } finally {
@@ -191,7 +191,7 @@
             } catch (UnixException x) {
                 String msg = (x.errno() == ERANGE) ?
                     "Insufficient space in buffer" : x.getMessage();
-                throw new FileSystemException(file.getPathForExecptionMessage(),
+                throw new FileSystemException(file.getPathForExceptionMessage(),
                     null, "Error reading extended attribute '" + name + "': " + msg);
             } finally {
                 close(fd);
@@ -243,7 +243,7 @@
                 src.position(pos + rem);
                 return rem;
             } catch (UnixException x) {
-                throw new FileSystemException(file.getPathForExecptionMessage(),
+                throw new FileSystemException(file.getPathForExceptionMessage(),
                     null, "Error writing extended attribute '" + name + "': " +
                     x.getMessage());
             } finally {
@@ -264,7 +264,7 @@
         try {
             fremovexattr(fd, nameAsBytes(file,name));
         } catch (UnixException x) {
-            throw new FileSystemException(file.getPathForExecptionMessage(),
+            throw new FileSystemException(file.getPathForExceptionMessage(),
                 null, "Unable to delete extended attribute '" + name + "': " + x.getMessage());
         } finally {
             close(fd);
diff --git a/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java b/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java
index ec5535e..8a2e8c6 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/LinuxWatchService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -243,7 +243,7 @@
                 return x.asIOException(dir);
             }
             if (!attrs.isDirectory()) {
-                return new NotDirectoryException(dir.getPathForExecptionMessage());
+                return new NotDirectoryException(dir.getPathForExceptionMessage());
             }
 
             // register with inotify (replaces existing mask if already registered)
diff --git a/jdk/src/solaris/classes/sun/nio/fs/MacOSXFileSystem.java b/jdk/src/solaris/classes/sun/nio/fs/MacOSXFileSystem.java
new file mode 100644
index 0000000..ab9888e7
--- /dev/null
+++ b/jdk/src/solaris/classes/sun/nio/fs/MacOSXFileSystem.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright (c) 2008, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.nio.fs;
+
+import java.nio.file.*;
+import java.io.IOException;
+import java.util.*;
+import java.util.regex.Pattern;
+import java.security.AccessController;
+import sun.security.action.GetPropertyAction;
+
+import static sun.nio.fs.MacOSXNativeDispatcher.*;
+
+/**
+ * MacOS implementation of FileSystem
+ */
+
+class MacOSXFileSystem extends BsdFileSystem {
+
+    MacOSXFileSystem(UnixFileSystemProvider provider, String dir) {
+        super(provider, dir);
+    }
+
+    // match in unicode canon_eq
+    Pattern compilePathMatchPattern(String expr) {
+        return Pattern.compile(expr, Pattern.CANON_EQ) ;
+    }
+
+    char[] normalizeNativePath(char[] path) {
+        for (char c : path) {
+            if (c > 0x80)
+                return normalizepath(path, kCFStringNormalizationFormD);
+        }
+        return path;
+    }
+
+    String normalizeJavaPath(String path) {
+        for (int i = 0; i < path.length(); i++) {
+            if (path.charAt(i) > 0x80)
+                return new String(normalizepath(path.toCharArray(),
+                                  kCFStringNormalizationFormC));
+        }
+        return path;
+    }
+
+}
diff --git a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c b/jdk/src/solaris/classes/sun/nio/fs/MacOSXFileSystemProvider.java
similarity index 64%
copy from jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
copy to jdk/src/solaris/classes/sun/nio/fs/MacOSXFileSystemProvider.java
index 089afbd..5e48c00 100644
--- a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
+++ b/jdk/src/solaris/classes/sun/nio/fs/MacOSXFileSystemProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 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,22 +23,23 @@
  * questions.
  */
 
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
+package sun.nio.fs;
 
-#include "sun_rmi_server_MarshalInputStream.h"
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.io.IOException;
 
-/*
- * Class:     sun_rmi_server_MarshalInputStream
- * Method:    latestUserDefinedLoader
- * Signature: ()Ljava/lang/ClassLoader;
- *
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
+/**
+ * MacOSX implementation of FileSystemProvider
  */
-JNIEXPORT jobject JNICALL
-Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader(JNIEnv *env, jclass cls)
-{
-    return JVM_LatestUserDefinedLoader(env);
+
+public class MacOSXFileSystemProvider extends BsdFileSystemProvider {
+    public MacOSXFileSystemProvider() {
+        super();
+    }
+
+    @Override
+    MacOSXFileSystem newFileSystem(String dir) {
+        return new MacOSXFileSystem(this, dir);
+    }
 }
diff --git a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c b/jdk/src/solaris/classes/sun/nio/fs/MacOSXNativeDispatcher.java
similarity index 64%
copy from jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
copy to jdk/src/solaris/classes/sun/nio/fs/MacOSXNativeDispatcher.java
index 089afbd..d591857 100644
--- a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
+++ b/jdk/src/solaris/classes/sun/nio/fs/MacOSXNativeDispatcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2009, 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,22 +23,19 @@
  * questions.
  */
 
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
+package sun.nio.fs;
 
-#include "sun_rmi_server_MarshalInputStream.h"
+import java.security.AccessController;
+import java.security.PrivilegedAction;
 
-/*
- * Class:     sun_rmi_server_MarshalInputStream
- * Method:    latestUserDefinedLoader
- * Signature: ()Ljava/lang/ClassLoader;
- *
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
+/**
+ * MacOSX specific system calls.
  */
-JNIEXPORT jobject JNICALL
-Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader(JNIEnv *env, jclass cls)
-{
-    return JVM_LatestUserDefinedLoader(env);
+
+class MacOSXNativeDispatcher extends BsdNativeDispatcher {
+    private MacOSXNativeDispatcher() { }
+
+    static final int kCFStringNormalizationFormC = 2;
+    static final int kCFStringNormalizationFormD = 0;
+    static native char[] normalizepath(char[] path, int form);
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java
index b27f937..54023bf 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisAclFileAttributeView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -324,7 +324,7 @@
                 return decode(address, n);
             } catch (UnixException x) {
                 if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) {
-                    throw new FileSystemException(file.getPathForExecptionMessage(),
+                    throw new FileSystemException(file.getPathForExceptionMessage(),
                         null, x.getMessage() + " (file system does not support NFSv4 ACLs)");
                 }
                 x.rethrowAsIOException(file);
@@ -355,7 +355,7 @@
                 facl(fd, ACE_SETACL, n, address);
             } catch (UnixException x) {
                 if ((x.errno() == ENOSYS) || !isAclsEnabled(fd)) {
-                    throw new FileSystemException(file.getPathForExecptionMessage(),
+                    throw new FileSystemException(file.getPathForExceptionMessage(),
                         null, x.getMessage() + " (file system does not support NFSv4 ACLs)");
                 }
                 if (x.errno() == EINVAL && (n < 3))
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java
index 9aa9e53..14bc339 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystem.java
@@ -30,7 +30,7 @@
 import java.util.*;
 import java.security.AccessController;
 import sun.security.action.GetPropertyAction;
-import static sun.nio.fs.UnixNativeDispatcher.*;
+import static sun.nio.fs.SolarisNativeDispatcher.*;
 
 /**
  * Solaris implementation of FileSystem
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java
index 5564a26..fec87c7 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisFileSystemProvider.java
@@ -27,6 +27,7 @@
 
 import java.nio.file.*;
 import java.nio.file.attribute.*;
+import java.nio.file.spi.FileTypeDetector;
 import java.io.IOException;
 
 /**
@@ -79,4 +80,9 @@
                                                            Util.followLinks(options));
         return super.getFileAttributeView(obj, name, options);
     }
+
+    @Override
+    FileTypeDetector getFileTypeDetector() {
+        return new GnomeFileTypeDetector();
+    }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java
index 9adedc2..3d54b75 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisNativeDispatcher.java
@@ -36,6 +36,12 @@
     private SolarisNativeDispatcher() { }
 
     /**
+     * int getextmntent(FILE *fp, struct extmnttab *mp, int len);
+     */
+    static native int getextmntent(long fp, UnixMountEntry entry)
+        throws UnixException;
+
+    /**
      * int facl(int filedes, int cmd, int nentries, void aclbufp)
      */
     static native int facl(int fd, int cmd, int nentries, long aclbufp)
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java
index c48ecef..150c633 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisUserDefinedFileAttributeView.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -49,7 +49,7 @@
             if (bytes.length <= 1 ||
                 (bytes.length == 2 && bytes[1] == '.'))
             {
-                throw new FileSystemException(file.getPathForExecptionMessage(),
+                throw new FileSystemException(file.getPathForExceptionMessage(),
                     null, "'" + name + "' is not a valid name");
             }
         }
@@ -96,7 +96,7 @@
                 }
                 return Collections.unmodifiableList(list);
             } catch (UnixException x) {
-                throw new FileSystemException(file.getPathForExecptionMessage(),
+                throw new FileSystemException(file.getPathForExceptionMessage(),
                     null, "Unable to get list of extended attributes: " +
                     x.getMessage());
             }
@@ -126,7 +126,7 @@
                     close(afd);
                 }
             } catch (UnixException x) {
-                throw new FileSystemException(file.getPathForExecptionMessage(),
+                throw new FileSystemException(file.getPathForExceptionMessage(),
                     null, "Unable to get size of extended attribute '" + name +
                     "': " + x.getMessage());
             }
@@ -147,7 +147,7 @@
                 int afd = openat(fd, nameAsBytes(file,name), (O_RDONLY|O_XATTR), 0);
 
                 // wrap with channel
-                FileChannel fc = UnixChannelFactory.newFileChannel(afd, true, false);
+                FileChannel fc = UnixChannelFactory.newFileChannel(afd, file.toString(), true, false);
 
                 // read to EOF (nothing we can do if I/O error occurs)
                 try {
@@ -165,7 +165,7 @@
                     fc.close();
                 }
             } catch (UnixException x) {
-                throw new FileSystemException(file.getPathForExecptionMessage(),
+                throw new FileSystemException(file.getPathForExceptionMessage(),
                     null, "Unable to read extended attribute '" + name +
                     "': " + x.getMessage());
             }
@@ -188,7 +188,7 @@
                                  UnixFileModeAttribute.ALL_PERMISSIONS);
 
                 // wrap with channel
-                FileChannel fc = UnixChannelFactory.newFileChannel(afd, false, true);
+                FileChannel fc = UnixChannelFactory.newFileChannel(afd, file.toString(), false, true);
 
                 // write value (nothing we can do if I/O error occurs)
                 try {
@@ -201,7 +201,7 @@
                     fc.close();
                 }
             } catch (UnixException x) {
-                throw new FileSystemException(file.getPathForExecptionMessage(),
+                throw new FileSystemException(file.getPathForExceptionMessage(),
                     null, "Unable to write extended attribute '" + name +
                     "': " + x.getMessage());
             }
@@ -224,7 +224,7 @@
                 close(dfd);
             }
         } catch (UnixException x) {
-            throw new FileSystemException(file.getPathForExecptionMessage(),
+            throw new FileSystemException(file.getPathForExceptionMessage(),
                 null, "Unable to delete extended attribute '" + name +
                 "': " + x.getMessage());
         } finally {
diff --git a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java
index 76187ec..62b305f 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/SolarisWatchService.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -288,7 +288,7 @@
                 return x.asIOException(dir);
             }
             if (!attrs.isDirectory()) {
-                return new NotDirectoryException(dir.getPathForExecptionMessage());
+                return new NotDirectoryException(dir.getPathForExceptionMessage());
             }
 
             // return existing watch key after updating events if already
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java b/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java
index 963e377..8617cca 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixChannelFactory.java
@@ -36,8 +36,6 @@
 import sun.misc.SharedSecrets;
 import sun.misc.JavaIOFileDescriptorAccess;
 
-import com.sun.nio.file.ExtendedOpenOption;
-
 import static sun.nio.fs.UnixNativeDispatcher.*;
 import static sun.nio.fs.UnixConstants.*;
 
@@ -86,13 +84,13 @@
                     }
                     continue;
                 }
-                if (option == LinkOption.NOFOLLOW_LINKS) {
+                if (option == LinkOption.NOFOLLOW_LINKS && supportsNoFollowLinks()) {
                     flags.noFollowLinks = true;
                     continue;
                 }
                 if (option == null)
                     throw new NullPointerException();
-               throw new UnsupportedOperationException();
+               throw new UnsupportedOperationException(option + " not supported");
             }
             return flags;
         }
@@ -102,10 +100,10 @@
     /**
      * Constructs a file channel from an existing (open) file descriptor
      */
-    static FileChannel newFileChannel(int fd, boolean reading, boolean writing) {
+    static FileChannel newFileChannel(int fd, String path, boolean reading, boolean writing) {
         FileDescriptor fdObj = new FileDescriptor();
         fdAccess.set(fdObj, fd);
-        return FileChannelImpl.open(fdObj, reading, writing, null);
+        return FileChannelImpl.open(fdObj, path, reading, writing, null);
     }
 
     /**
@@ -136,7 +134,8 @@
             throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
 
         FileDescriptor fdObj = open(dfd, path, pathForPermissionCheck, flags, mode);
-        return FileChannelImpl.open(fdObj, flags.read, flags.write, flags.append, null);
+        return FileChannelImpl.open(fdObj, path.toString(),
+            flags.read, flags.write, flags.append, null);
     }
 
     /**
@@ -220,6 +219,15 @@
         // follow links by default
         boolean followLinks = true;
         if (!flags.createNew && (flags.noFollowLinks || flags.deleteOnClose)) {
+            if (flags.deleteOnClose && !supportsNoFollowLinks()) {
+                try {
+                    if (UnixFileAttributes.get(path, false).isSymbolicLink())
+                        throw new UnixException("DELETE_ON_CLOSE specified and file is a symbolic link");
+                } catch (UnixException x) {
+                    if (!flags.create || x.errno() != ENOENT)
+                        throw x;
+                }
+            }
             followLinks = false;
             oflags |= O_NOFOLLOW;
         }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java b/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java
index 08aa822..c35133b 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixCopyFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -383,8 +383,8 @@
             } catch (UnixException x) {
                 if (x.errno() == EXDEV) {
                     throw new AtomicMoveNotSupportedException(
-                        source.getPathForExecptionMessage(),
-                        target.getPathForExecptionMessage(),
+                        source.getPathForExceptionMessage(),
+                        target.getPathForExceptionMessage(),
                         x.errorString());
                 }
                 x.rethrowAsIOException(source, target);
@@ -420,7 +420,7 @@
                 return;  // nothing to do as files are identical
             if (!flags.replaceExisting) {
                 throw new FileAlreadyExistsException(
-                    target.getPathForExecptionMessage());
+                    target.getPathForExceptionMessage());
             }
 
             // attempt to delete target
@@ -436,7 +436,7 @@
                    (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
                 {
                     throw new DirectoryNotEmptyException(
-                        target.getPathForExecptionMessage());
+                        target.getPathForExceptionMessage());
                 }
                 x.rethrowAsIOException(target);
             }
@@ -489,7 +489,7 @@
                 (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
             {
                 throw new DirectoryNotEmptyException(
-                    source.getPathForExecptionMessage());
+                    source.getPathForExceptionMessage());
             }
             x.rethrowAsIOException(source);
         }
@@ -542,7 +542,7 @@
                 return;  // nothing to do as files are identical
             if (!flags.replaceExisting)
                 throw new FileAlreadyExistsException(
-                    target.getPathForExecptionMessage());
+                    target.getPathForExceptionMessage());
             try {
                 if (targetAttrs.isDirectory()) {
                     rmdir(target);
@@ -555,7 +555,7 @@
                    (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
                 {
                     throw new DirectoryNotEmptyException(
-                        target.getPathForExecptionMessage());
+                        target.getPathForExceptionMessage());
                 }
                 x.rethrowAsIOException(target);
             }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixException.java b/jdk/src/solaris/classes/sun/nio/fs/UnixException.java
index 48137b5..b4925c3 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixException.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -97,8 +97,8 @@
     }
 
     void rethrowAsIOException(UnixPath file, UnixPath other) throws IOException {
-        String a = (file == null) ? null : file.getPathForExecptionMessage();
-        String b = (other == null) ? null : other.getPathForExecptionMessage();
+        String a = (file == null) ? null : file.getPathForExceptionMessage();
+        String b = (other == null) ? null : other.getPathForExceptionMessage();
         IOException x = translateToIOException(a, b);
         throw x;
     }
@@ -108,6 +108,6 @@
     }
 
     IOException asIOException(UnixPath file) {
-        return translateToIOException(file.getPathForExecptionMessage(), null);
+        return translateToIOException(file.getPathForExceptionMessage(), null);
     }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java
index 28276e1..33ec2ba 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystem.java
@@ -302,7 +302,8 @@
         }
 
         // return matcher
-        final Pattern pattern = Pattern.compile(expr);
+        final Pattern pattern = compilePathMatchPattern(expr);
+
         return new PathMatcher() {
             @Override
             public boolean matches(Path path) {
@@ -310,11 +311,10 @@
             }
         };
     }
+
     private static final String GLOB_SYNTAX = "glob";
     private static final String REGEX_SYNTAX = "regex";
 
-
-
     @Override
     public final UserPrincipalLookupService getUserPrincipalLookupService() {
         return LookupService.instance;
@@ -339,4 +339,23 @@
             };
     }
 
+    // Override if the platform has different path match requrement, such as
+    // case insensitive or Unicode canonical equal on MacOSX
+    Pattern compilePathMatchPattern(String expr) {
+        return Pattern.compile(expr);
+    }
+
+    // Override if the platform uses different Unicode normalization form
+    // for native file path. For example on MacOSX, the native path is stored
+    // in Unicode NFD form.
+    char[] normalizeNativePath(char[] path) {
+        return path;
+    }
+
+    // Override if the native file path use non-NFC form. For example on MacOSX,
+    // the native path is stored in Unicode NFD form, the path need to be
+    // normalized back to NFC before passed back to Java level.
+    String normalizeJavaPath(String path) {
+        return path;
+    }
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java
index 0c14ef0..5058f31 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixFileSystemProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,6 +27,7 @@
 
 import java.nio.file.*;
 import java.nio.file.attribute.*;
+import java.nio.file.spi.FileTypeDetector;
 import java.nio.channels.*;
 import java.net.URI;
 import java.util.concurrent.ExecutorService;
@@ -238,7 +239,7 @@
             // DirectoryNotEmptyException if not empty
             if (attrs != null && attrs.isDirectory() &&
                 (x.errno() == EEXIST || x.errno() == ENOTEMPTY))
-                throw new DirectoryNotEmptyException(file.getPathForExecptionMessage());
+                throw new DirectoryNotEmptyException(file.getPathForExceptionMessage());
 
             x.rethrowAsIOException(file);
             return false;
@@ -395,13 +396,13 @@
 
         // can't return SecureDirectoryStream on kernels that don't support
         // openat, etc.
-        if (!supportsAtSysCalls()) {
+        if (!supportsAtSysCalls() || !supportsNoFollowLinks()) {
             try {
                 long ptr = opendir(dir);
                 return new UnixDirectoryStream(dir, ptr, filter);
             } catch (UnixException x) {
                 if (x.errno() == ENOTDIR)
-                    throw new NotDirectoryException(dir.getPathForExecptionMessage());
+                    throw new NotDirectoryException(dir.getPathForExceptionMessage());
                 x.rethrowAsIOException(dir);
             }
         }
@@ -421,7 +422,7 @@
             if (dfd2 != -1)
                 UnixNativeDispatcher.close(dfd2);
             if (x.errno() == UnixConstants.ENOTDIR)
-                throw new NotDirectoryException(dir.getPathForExecptionMessage());
+                throw new NotDirectoryException(dir.getPathForExceptionMessage());
             x.rethrowAsIOException(dir);
         }
         return new UnixSecureDirectoryStream(dir, dp, dfd2, filter);
@@ -490,9 +491,22 @@
             return new UnixPath(link.getFileSystem(), target);
         } catch (UnixException x) {
            if (x.errno() == UnixConstants.EINVAL)
-                throw new NotLinkException(link.getPathForExecptionMessage());
+                throw new NotLinkException(link.getPathForExceptionMessage());
             x.rethrowAsIOException(link);
             return null;    // keep compiler happy
         }
     }
+
+    /**
+     * Returns a {@code FileTypeDetector} for this platform.
+     */
+    FileTypeDetector getFileTypeDetector() {
+        return new AbstractFileTypeDetector() {
+            @Override
+            public String implProbeContentType(Path file) {
+                return null;
+            }
+        };
+    }
+
 }
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java b/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java
index 2d037f3..5672319 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixNativeDispatcher.java
@@ -498,11 +498,6 @@
     private static native int getgrnam0(long nameAddress) throws UnixException;
 
     /**
-     * int getextmntent(FILE *fp, struct extmnttab *mp, int len);
-     */
-    static native int getextmntent(long fp, UnixMountEntry entry) throws UnixException;
-
-    /**
      * statvfs(const char* path, struct statvfs *buf)
      */
     static void statvfs(UnixPath path, UnixFileStoreAttributes attrs)
@@ -548,6 +543,10 @@
         return hasAtSysCalls;
     }
 
+    static boolean supportsNoFollowLinks() {
+        return UnixConstants.O_NOFOLLOW != 0;
+    }
+
     // initialize syscalls and fieldIDs
     private static native int init();
 
diff --git a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java
index 30c4dfe..b9410b4 100644
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -68,7 +68,7 @@
 
     UnixPath(UnixFileSystem fs, String input) {
         // removes redundant slashes and checks for invalid characters
-        this(fs, encode(normalizeAndCheck(input)));
+        this(fs, encode(fs, normalizeAndCheck(input)));
     }
 
     // package-private
@@ -116,7 +116,7 @@
     }
 
     // encodes the given path-string into a sequence of bytes
-    private static byte[] encode(String input) {
+    private static byte[] encode(UnixFileSystem fs, String input) {
         SoftReference<CharsetEncoder> ref = encoder.get();
         CharsetEncoder ce = (ref != null) ? ref.get() : null;
         if (ce == null) {
@@ -126,7 +126,7 @@
             encoder.set(new SoftReference<CharsetEncoder>(ce));
         }
 
-        char[] ca = input.toCharArray();
+        char[] ca = fs.normalizeNativePath(input.toCharArray());
 
         // size output buffer for worse-case size
         byte[] ba = new byte[(int)(ca.length * (double)ce.maxBytesPerChar())];
@@ -179,7 +179,7 @@
     }
 
     // use this message when throwing exceptions
-    String getPathForExecptionMessage() {
+    String getPathForExceptionMessage() {
         return toString();
     }
 
@@ -728,7 +728,7 @@
             if (c1 != c2) {
                 return c1 - c2;
             }
-            k++;
+           k++;
         }
         return len1 - len2;
     }
@@ -757,8 +757,9 @@
     @Override
     public String toString() {
         // OK if two or more threads create a String
-        if (stringValue == null)
-            stringValue = new String(path);     // platform encoding
+        if (stringValue == null) {
+            stringValue = fs.normalizeJavaPath(new String(path));     // platform encoding
+        }
         return stringValue;
     }
 
@@ -767,8 +768,11 @@
     // package-private
     int openForAttributeAccess(boolean followLinks) throws IOException {
         int flags = O_RDONLY;
-        if (!followLinks)
+        if (!followLinks) {
+            if (!supportsNoFollowLinks())
+                throw new IOException("NOFOLLOW_LINKS is not supported on this platform");
             flags |= O_NOFOLLOW;
+        }
         try {
             return open(this, flags, 0);
         } catch (UnixException x) {
@@ -777,7 +781,7 @@
                 x.setError(ELOOP);
 
             if (x.errno() == ELOOP)
-                throw new FileSystemException(getPathForExecptionMessage(), null,
+                throw new FileSystemException(getPathForExceptionMessage(), null,
                     x.getMessage() + " or unable to access attributes of symbolic link");
 
             x.rethrowAsIOException(this);
diff --git a/jdk/src/solaris/classes/sun/print/UnixPrintJob.java b/jdk/src/solaris/classes/sun/print/UnixPrintJob.java
index c81328d..b7fc9f6 100644
--- a/jdk/src/solaris/classes/sun/print/UnixPrintJob.java
+++ b/jdk/src/solaris/classes/sun/print/UnixPrintJob.java
@@ -38,7 +38,9 @@
 import java.io.OutputStream;
 import java.io.OutputStreamWriter;
 import java.io.IOException;
+import java.io.PrintWriter;
 import java.io.Reader;
+import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
 import java.nio.file.Files;
 import java.util.Vector;
@@ -956,23 +958,49 @@
     private class PrinterSpooler implements java.security.PrivilegedAction {
         PrintException pex;
 
+        private void handleProcessFailure(final Process failedProcess,
+                final String[] execCmd, final int result) throws IOException {
+            try (StringWriter sw = new StringWriter();
+                    PrintWriter pw = new PrintWriter(sw)) {
+                pw.append("error=").append(Integer.toString(result));
+                pw.append(" running:");
+                for (String arg: execCmd) {
+                    pw.append(" '").append(arg).append("'");
+                }
+                try (InputStream is = failedProcess.getErrorStream();
+                        InputStreamReader isr = new InputStreamReader(is);
+                        BufferedReader br = new BufferedReader(isr)) {
+                    while (br.ready()) {
+                        pw.println();
+                        pw.append("\t\t").append(br.readLine());
+                    }
+                } finally {
+                    pw.flush();
+                    throw new IOException(sw.toString());
+                }
+            }
+        }
+
         public Object run() {
+            if (spoolFile == null || !spoolFile.exists()) {
+               pex = new PrintException("No spool file");
+               notifyEvent(PrintJobEvent.JOB_FAILED);
+               return null;
+            }
             try {
                 /**
                  * Spool to the printer.
                  */
-                if (spoolFile == null || !spoolFile.exists()) {
-                   pex = new PrintException("No spool file");
-                   notifyEvent(PrintJobEvent.JOB_FAILED);
-                   return null;
-                }
                 String fileName = spoolFile.getAbsolutePath();
                 String execCmd[] = printExecCmd(mDestination, mOptions,
                                mNoJobSheet, jobName, copies, fileName);
 
                 Process process = Runtime.getRuntime().exec(execCmd);
                 process.waitFor();
-                spoolFile.delete();
+                final int result = process.exitValue();
+                if (0 != result) {
+                    handleProcessFailure(process, execCmd, result);
+                }
                 notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE);
             } catch (IOException ex) {
                 notifyEvent(PrintJobEvent.JOB_FAILED);
@@ -982,6 +1010,7 @@
                 notifyEvent(PrintJobEvent.JOB_FAILED);
                 pex = new PrintException(ie);
             } finally {
+                spoolFile.delete();
                 notifyEvent(PrintJobEvent.NO_MORE_EVENTS);
             }
             return null;
diff --git a/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c b/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c
index 1e93bd6..1054762 100644
--- a/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c
+++ b/jdk/src/solaris/demo/jvmti/hprof/hprof_md.c
@@ -375,6 +375,31 @@
     return ntohl(l);
 }
 
+static void dll_build_name(char* buffer, size_t buflen,
+                           const char* pname, const char* fname) {
+    // Loosely based on os_solaris.cpp
+
+      char *pathname = (char *)pname;
+      while (strlen(pathname) > 0) {
+          char *p = strchr(pathname, ':');
+          if (p == NULL) {
+              p = pathname + strlen(pathname);
+          }
+          /* check for NULL path */
+          if (p == pathname) {
+              continue;
+          }
+          (void)snprintf(buffer, buflen, "%.*s/lib%s" JNI_LIB_SUFFIX,
+                         (p - pathname), pathname, fname);
+
+          if (access(buffer, F_OK) == 0) {
+            break;
+          }
+          pathname = p + 1;
+          *buffer = '\0';
+      }
+}
+
 /* Create the actual fill filename for a dynamic library.  */
 void
 md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
@@ -384,9 +409,9 @@
     /* Length of options directory location. */
     pnamelen = pname ? strlen(pname) : 0;
 
+    *holder = '\0';
     /* Quietly truncate on buffer overflow.  Should be an error. */
     if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
-        *holder = '\0';
         return;
     }
 
@@ -394,7 +419,7 @@
     if (pnamelen == 0) {
         (void)snprintf(holder, holderlen, "lib%s" JNI_LIB_SUFFIX, fname);
     } else {
-        (void)snprintf(holder, holderlen, "%s/lib%s" JNI_LIB_SUFFIX, pname, fname);
+      dll_build_name(holder, holderlen, pname, fname);
     }
 }
 
diff --git a/jdk/src/solaris/lib/content-types.properties b/jdk/src/solaris/lib/content-types.properties
index 2126b01..559de96 100644
--- a/jdk/src/solaris/lib/content-types.properties
+++ b/jdk/src/solaris/lib/content-types.properties
@@ -225,6 +225,10 @@
 	icon=png;\
 	action=browser
 
+image/bmp: \
+	description=Bitmap Image;\
+	file_extensions=.bmp;
+
 text/html: \
 	description=HTML Document;\
 	file_extensions=.htm,.html;\
diff --git a/jdk/src/solaris/native/java/io/UnixFileSystem_md.c b/jdk/src/solaris/native/java/io/UnixFileSystem_md.c
index 5ea55d8..4309ffb 100644
--- a/jdk/src/solaris/native/java/io/UnixFileSystem_md.c
+++ b/jdk/src/solaris/native/java/io/UnixFileSystem_md.c
@@ -38,6 +38,7 @@
 #include "jlong.h"
 #include "jvm.h"
 #include "io_util.h"
+#include "io_util_md.h"
 #include "java_io_FileSystem.h"
 #include "java_io_UnixFileSystem.h"
 
@@ -80,7 +81,11 @@
                          canonicalPath, JVM_MAXPATHLEN) < 0) {
             JNU_ThrowIOExceptionWithLastError(env, "Bad pathname");
         } else {
+#ifdef MACOSX
+            rv = newStringPlatform(env, canonicalPath);
+#else
             rv = JNU_NewStringPlatform(env, canonicalPath);
+#endif
         }
     } END_PLATFORM_STRING(env, path);
     return rv;
@@ -311,7 +316,11 @@
             if (JNU_CopyObjectArray(env, rv, old, len) < 0) goto error;
             (*env)->DeleteLocalRef(env, old);
         }
+#ifdef MACOSX
+        name = newStringPlatform(env, ptr->d_name);
+#else
         name = JNU_NewStringPlatform(env, ptr->d_name);
+#endif
         if (name == NULL) goto error;
         (*env)->SetObjectArrayElement(env, rv, len++, name);
         (*env)->DeleteLocalRef(env, name);
diff --git a/jdk/src/solaris/native/java/io/io_util_md.c b/jdk/src/solaris/native/java/io/io_util_md.c
index 1d9abff..646e130 100644
--- a/jdk/src/solaris/native/java/io/io_util_md.c
+++ b/jdk/src/solaris/native/java/io/io_util_md.c
@@ -34,37 +34,32 @@
 
 #include <CoreFoundation/CoreFoundation.h>
 
-static inline char *convertToNFD(const char *path, char *buf, size_t bufsize)
-{
-    CFMutableStringRef mutable = CFStringCreateMutable(NULL, 0);
-    CFStringAppendCString(mutable, path, kCFStringEncodingUTF8);
-    CFStringNormalize(mutable, kCFStringNormalizationFormD);
-
-    CFStringGetCString(mutable, buf, bufsize, kCFStringEncodingUTF8);
-
-    CFRelease(mutable);
-    return buf;
-}
-
-/* Converts the path to NFD form if it was in NFC form. Returns a pointer to
- * the converting string which could be buf (if the converstion took place) or
- * origPath if no conversion was needed
- */
 __private_extern__
-char* convertToNFDIfNeeded(const char *origPath, char *buf, size_t bufsize)
+jstring newStringPlatform(JNIEnv *env, const char* str)
 {
-    const char *current = origPath;
-    int c;
-    for (c = *current; c != 0; current++, c = *current) {
-        if (c < 0) {
-            // Need to convert
-            return convertToNFD(origPath, buf, bufsize);
+    jstring rv = NULL;
+    CFMutableStringRef csref = CFStringCreateMutable(NULL, 0);
+    if (csref == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "native heap");
+    } else {
+        CFStringAppendCString(csref, str, kCFStringEncodingUTF8);
+        CFStringNormalize(csref, kCFStringNormalizationFormC);
+        int clen = CFStringGetLength(csref);
+        int ulen = (clen + 1) * 2;        // utf16 + zero padding
+        char* chars = malloc(ulen);
+        if (chars == NULL) {
+            CFRelease(csref);
+            JNU_ThrowOutOfMemoryError(env, "native heap");
+        } else {
+            if (CFStringGetCString(csref, chars, ulen, kCFStringEncodingUTF16)) {
+                rv = (*env)->NewString(env, (jchar*)chars, clen);
+            }
+            free(chars);
+            CFRelease(csref);
         }
     }
-
-    return (char *)origPath;
+    return rv;
 }
-
 #endif
 
 void
diff --git a/jdk/src/solaris/native/java/io/io_util_md.h b/jdk/src/solaris/native/java/io/io_util_md.h
index 5c11604..fbf8172 100644
--- a/jdk/src/solaris/native/java/io/io_util_md.h
+++ b/jdk/src/solaris/native/java/io/io_util_md.h
@@ -72,3 +72,7 @@
  * IO helper function(s)
  */
 void fileClose(JNIEnv *env, jobject this, jfieldID fid);
+
+#ifdef MACOSX
+jstring newStringPlatform(JNIEnv *env, const char* str);
+#endif
diff --git a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
index 278ce13..6023e67 100644
--- a/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
+++ b/jdk/src/solaris/native/java/net/Inet4AddressImpl.c
@@ -196,7 +196,7 @@
                 struct addrinfo *next
                     = (struct addrinfo*) malloc(sizeof(struct addrinfo));
                 if (!next) {
-                    JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+                    JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
                     ret = NULL;
                     goto cleanupAndReturn;
                 }
@@ -669,11 +669,11 @@
                  sizeof(struct sockaddr));
       if (n < 0 && errno != EINPROGRESS ) {
 #ifdef __linux__
-        if (errno != EINVAL)
+        if (errno != EINVAL && errno != EHOSTUNREACH)
           /*
            * On some Linuxes, when bound to the loopback interface, sendto
-           * will fail and errno will be set to EINVAL. When that happens,
-           * don't throw an exception, just return false.
+           * will fail and errno will be set to EINVAL or EHOSTUNREACH.
+           * When that happens, don't throw an exception, just return false.
            */
 #endif /*__linux__ */
           NET_ThrowNew(env, errno, "Can't send ICMP packet");
@@ -695,12 +695,19 @@
            * We did receive something, but is it what we were expecting?
            * I.E.: A ICMP_ECHOREPLY packet with the proper PID.
            */
-          if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY &&
-               (ntohs(icmp->icmp_id) == pid) &&
-               (him->sin_addr.s_addr == sa_recv.sin_addr.s_addr)) {
-            close(fd);
-            return JNI_TRUE;
-          }
+          if (icmplen >= 8 && icmp->icmp_type == ICMP_ECHOREPLY
+               && (ntohs(icmp->icmp_id) == pid)) {
+            if ((him->sin_addr.s_addr == sa_recv.sin_addr.s_addr)) {
+              close(fd);
+              return JNI_TRUE;
+            }
+
+            if (him->sin_addr.s_addr == 0) {
+              close(fd);
+              return JNI_TRUE;
+            }
+         }
+
         }
       } while (tmout2 > 0);
       timeout -= 1000;
@@ -828,10 +835,11 @@
         case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
 #ifdef __linux__
         case EINVAL:
+        case EHOSTUNREACH:
           /*
            * On some Linuxes, when bound to the loopback interface, connect
-           * will fail and errno will be set to EINVAL. When that happens,
-           * don't throw an exception, just return false.
+           * will fail and errno will be set to EINVAL or EHOSTUNREACH.
+           * When that happens, don't throw an exception, just return false.
            */
 #endif /* __linux__ */
           close(fd);
diff --git a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
index ec2427d..4de944b 100644
--- a/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
+++ b/jdk/src/solaris/native/java/net/Inet6AddressImpl.c
@@ -270,7 +270,7 @@
                     struct addrinfo *next
                         = (struct addrinfo*) malloc(sizeof(struct addrinfo));
                     if (!next) {
-                        JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+                        JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
                         ret = NULL;
                         goto cleanupAndReturn;
                     }
@@ -512,11 +512,11 @@
       n = sendto(fd, sendbuf, plen, 0, (struct sockaddr*) him, sizeof(struct sockaddr_in6));
       if (n < 0 && errno != EINPROGRESS) {
 #ifdef __linux__
-        if (errno != EINVAL)
+        if (errno != EINVAL && errno != EHOSTUNREACH)
           /*
            * On some Linuxes, when bound to the loopback interface, sendto
-           * will fail and errno will be set to EINVAL. When that happens,
-           * don't throw an exception, just return false.
+           * will fail and errno will be set to EINVAL or EHOSTUNREACH.
+           * When that happens, don't throw an exception, just return false.
            */
 #endif /*__linux__ */
         NET_ThrowNew(env, errno, "Can't send ICMP packet");
@@ -539,10 +539,15 @@
            *       from the host that we are trying to determine is reachable.
            */
           if (n >= 8 && icmp6->icmp6_type == ICMP6_ECHO_REPLY &&
-              (ntohs(icmp6->icmp6_id) == pid) &&
-              NET_IsEqual(caddr, recv_caddr)) {
-            close(fd);
-            return JNI_TRUE;
+              (ntohs(icmp6->icmp6_id) == pid)) {
+            if (NET_IsEqual(caddr, recv_caddr)) {
+              close(fd);
+              return JNI_TRUE;
+            }
+            if (NET_IsZeroAddr(caddr)) {
+              close(fd);
+              return JNI_TRUE;
+            }
           }
         }
       } while (tmout2 > 0);
@@ -680,10 +685,11 @@
         case EADDRNOTAVAIL: /* address is not available on  the  remote machine */
 #ifdef __linux__
         case EINVAL:
+        case EHOSTUNREACH:
           /*
            * On some Linuxes, when bound to the loopback interface, connect
-           * will fail and errno will be set to EINVAL. When that happens,
-           * don't throw an exception, just return false.
+           * will fail and errno will be set to EINVAL or EHOSTUNREACH.
+           * When that happens, don't throw an exception, just return false.
            */
 #endif /* __linux__ */
           close(fd);
diff --git a/jdk/src/solaris/native/java/net/NetworkInterface.c b/jdk/src/solaris/native/java/net/NetworkInterface.c
index 6cddea3..ad6a0b6 100644
--- a/jdk/src/solaris/native/java/net/NetworkInterface.c
+++ b/jdk/src/solaris/native/java/net/NetworkInterface.c
@@ -147,7 +147,7 @@
 static short   getSubnet(JNIEnv *env, int sock, const char *ifname);
 static int     getIndex(int sock, const char *ifname);
 
-static int     getFlags(int sock, const char *ifname);
+static int     getFlags(int sock, const char *ifname, int *flags);
 static int     getMacAddress(JNIEnv *env, int sock,  const char* ifname, const struct in_addr* addr, unsigned char *buf);
 static int     getMTU(JNIEnv *env, int sock, const char *ifname);
 
@@ -561,6 +561,7 @@
     jboolean isCopy;
     int ret, sock;
     const char* name_utf;
+    int flags = 0;
 
     name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
 
@@ -571,7 +572,7 @@
 
     name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
 
-    ret = getFlags(sock, name_utf);
+    ret = getFlags(sock, name_utf, &flags);
 
     close(sock);
     (*env)->ReleaseStringUTFChars(env, name, name_utf);
@@ -581,7 +582,7 @@
         return -1;
     }
 
-    return ret;
+    return flags;
 }
 
 
@@ -804,7 +805,7 @@
        do{ \
         _pointer = (_type)malloc( _size ); \
         if (_pointer == NULL) { \
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed"); \
+            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed"); \
             return ifs; /* return untouched list */ \
         } \
        } while(0)
@@ -852,6 +853,7 @@
     int mask;
     int isVirtual = 0;
     int addr_size;
+    int flags = 0;
 
     /*
      * If the interface name is a logical interface then we
@@ -906,7 +908,7 @@
        * the 'parent' interface with the new records.
        */
         *name_colonP = 0;
-        if (getFlags(sock, name) < 0) {
+        if (getFlags(sock, name, &flags) < 0 || flags < 0) {
             // failed to access parent interface do not create parent.
             // We are a virtual interface with no parent.
             isVirtual = 1;
@@ -1278,9 +1280,8 @@
     return  if2.ifr_mtu;
 }
 
-static int getFlags(int sock, const char *ifname) {
+static int getFlags(int sock, const char *ifname, int *flags) {
   struct ifreq if2;
-  int ret = -1;
 
   memset((char *) &if2, 0, sizeof(if2));
   strcpy(if2.ifr_name, ifname);
@@ -1289,7 +1290,12 @@
       return -1;
   }
 
-  return if2.ifr_flags;
+  if (sizeof(if2.ifr_flags) == sizeof(short)) {
+      *flags = (if2.ifr_flags & 0xffff);
+  } else {
+      *flags = if2.ifr_flags;
+  }
+  return 0;
 }
 
 #endif
@@ -1663,7 +1669,7 @@
 }
 
 
-static int getFlags(int sock, const char *ifname) {
+static int getFlags(int sock, const char *ifname, int *flags) {
      struct   lifreq lifr;
      memset((caddr_t)&lifr, 0, sizeof(lifr));
      strcpy((caddr_t)&(lifr.lifr_name), ifname);
@@ -1672,7 +1678,8 @@
          return -1;
      }
 
-     return  lifr.lifr_flags;
+     *flags = lifr.lifr_flags;
+     return 0;
 }
 
 
@@ -1968,7 +1975,7 @@
     return  if2.ifr_mtu;
 }
 
-static int getFlags(int sock, const char *ifname) {
+static int getFlags(int sock, const char *ifname, int *flags) {
   struct ifreq if2;
   int ret = -1;
 
@@ -1979,7 +1986,12 @@
       return -1;
   }
 
-  return (((int) if2.ifr_flags) & 0xffff);
+  if (sizeof(if2.ifr_flags) == sizeof(short)) {
+    *flags = (if2.ifr_flags & 0xffff);
+  } else {
+    *flags = if2.ifr_flags;
+  }
+  return 0;
 }
 
 #endif
diff --git a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c
index 382ec4c..19316fd 100644
--- a/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c
+++ b/jdk/src/solaris/native/java/net/PlainDatagramSocketImpl.c
@@ -485,7 +485,7 @@
         fullPacket = (char *)malloc(packetBufferLen);
 
         if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+            JNU_ThrowOutOfMemoryError(env, "Send buffer native heap allocation failed");
             return;
         } else {
             mallocedPacket = JNI_TRUE;
@@ -714,7 +714,7 @@
         fullPacket = (char *)malloc(packetBufferLen);
 
         if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+            JNU_ThrowOutOfMemoryError(env, "Peek buffer native heap allocation failed");
             return -1;
         } else {
             mallocedPacket = JNI_TRUE;
@@ -874,7 +874,7 @@
         fullPacket = (char *)malloc(packetBufferLen);
 
         if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+            JNU_ThrowOutOfMemoryError(env, "Receive buffer native heap allocation failed");
             return;
         } else {
             mallocedPacket = JNI_TRUE;
@@ -1350,19 +1350,18 @@
          * value is an InetAddress.
          */
 #ifdef AF_INET6
-#if defined(__solaris__) || defined(MACOSX)
-        if (ipv6_available()) {
-            mcast_set_if_by_addr_v6(env, this, fd, value);
-        } else {
-            mcast_set_if_by_addr_v4(env, this, fd, value);
-        }
-#endif
 #ifdef __linux__
         mcast_set_if_by_addr_v4(env, this, fd, value);
         if (ipv6_available()) {
             mcast_set_if_by_addr_v6(env, this, fd, value);
         }
-#endif
+#else  /* __linux__ not defined */
+        if (ipv6_available()) {
+            mcast_set_if_by_addr_v6(env, this, fd, value);
+        } else {
+            mcast_set_if_by_addr_v4(env, this, fd, value);
+        }
+#endif  /* __linux__ */
 #else
         mcast_set_if_by_addr_v4(env, this, fd, value);
 #endif  /* AF_INET6 */
@@ -1373,19 +1372,18 @@
          * value is a NetworkInterface.
          */
 #ifdef AF_INET6
-#if defined(__solaris__) || defined(MACOSX)
-        if (ipv6_available()) {
-            mcast_set_if_by_if_v6(env, this, fd, value);
-        } else {
-            mcast_set_if_by_if_v4(env, this, fd, value);
-        }
-#endif
 #ifdef __linux__
         mcast_set_if_by_if_v4(env, this, fd, value);
         if (ipv6_available()) {
             mcast_set_if_by_if_v6(env, this, fd, value);
         }
-#endif
+#else  /* __linux__ not defined */
+        if (ipv6_available()) {
+            mcast_set_if_by_if_v6(env, this, fd, value);
+        } else {
+            mcast_set_if_by_if_v4(env, this, fd, value);
+        }
+#endif  /* __linux__ */
 #else
         mcast_set_if_by_if_v4(env, this, fd, value);
 #endif  /* AF_INET6 */
@@ -1456,19 +1454,18 @@
 static void setMulticastLoopbackMode(JNIEnv *env, jobject this, int fd,
                                   jint opt, jobject value) {
 #ifdef AF_INET6
-#if defined(__solaris__) || defined(MACOSX)
-    if (ipv6_available()) {
-        mcast_set_loop_v6(env, this, fd, value);
-    } else {
-        mcast_set_loop_v4(env, this, fd, value);
-    }
-#endif
 #ifdef __linux__
     mcast_set_loop_v4(env, this, fd, value);
     if (ipv6_available()) {
         mcast_set_loop_v6(env, this, fd, value);
     }
-#endif
+#else  /* __linux__ not defined */
+    if (ipv6_available()) {
+        mcast_set_loop_v6(env, this, fd, value);
+    } else {
+        mcast_set_loop_v4(env, this, fd, value);
+    }
+#endif  /* __linux__ */
 #else
     mcast_set_loop_v4(env, this, fd, value);
 #endif  /* AF_INET6 */
@@ -2030,13 +2027,6 @@
     }
     /* setsockopt to be correct ttl */
 #ifdef AF_INET6
-#if defined(__solaris__) || defined(MACOSX)
-    if (ipv6_available()) {
-        setHopLimit(env, fd, ttl);
-    } else {
-        setTTL(env, fd, ttl);
-    }
-#endif
 #ifdef __linux__
     setTTL(env, fd, ttl);
     if (ipv6_available()) {
@@ -2045,7 +2035,13 @@
             (*env)->SetIntField(env, this, pdsi_ttlID, ttl);
         }
     }
-#endif  // __linux__
+#else  /*  __linux__ not defined */
+    if (ipv6_available()) {
+        setHopLimit(env, fd, ttl);
+    } else {
+        setTTL(env, fd, ttl);
+    }
+#endif  /* __linux__ */
 #else
     setTTL(env, fd, ttl);
 #endif  /* AF_INET6 */
diff --git a/jdk/src/solaris/native/java/net/net_util_md.c b/jdk/src/solaris/native/java/net/net_util_md.c
index f0c8230..39f6844 100644
--- a/jdk/src/solaris/native/java/net/net_util_md.c
+++ b/jdk/src/solaris/native/java/net/net_util_md.c
@@ -1010,6 +1010,16 @@
     return (jboolean)(getaddrinfo_ptr != NULL);
 }
 
+int NET_IsZeroAddr(jbyte* caddr) {
+    int i;
+    for (i = 0; i < 16; i++) {
+        if (caddr[i] != 0) {
+            return 0;
+        }
+    }
+    return 1;
+}
+
 /*
  * Map the Java level socket option to the platform specific
  * level and option name.
diff --git a/jdk/src/solaris/native/sun/awt/fontpath.c b/jdk/src/solaris/native/sun/awt/fontpath.c
index e549b4f..214ecd0 100644
--- a/jdk/src/solaris/native/sun/awt/fontpath.c
+++ b/jdk/src/solaris/native/sun/awt/fontpath.c
@@ -583,9 +583,6 @@
 }
 
 #include <dlfcn.h>
-#if !(defined(__linux__) || defined(MACOSX))
-#include <link.h>
-#endif
 
 #include "fontconfig.h"
 
diff --git a/jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_config.h b/jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_config.h
index bb03165..e312c2b 100644
--- a/jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_config.h
+++ b/jdk/src/solaris/native/sun/awt/splashscreen/splashscreen_config.h
@@ -32,7 +32,7 @@
 #include <X11/Xutil.h>
 #include <X11/extensions/shape.h>
 #include <sys/types.h>
-#include <sys/unistd.h>
+#include <unistd.h>
 #include <pthread.h>
 #include <signal.h>
 #include <inttypes.h>
diff --git a/jdk/src/solaris/native/sun/java2d/opengl/OGLFuncs_md.h b/jdk/src/solaris/native/sun/java2d/opengl/OGLFuncs_md.h
index 14fe6f1..252749b 100644
--- a/jdk/src/solaris/native/sun/java2d/opengl/OGLFuncs_md.h
+++ b/jdk/src/solaris/native/sun/java2d/opengl/OGLFuncs_md.h
@@ -28,7 +28,7 @@
 
 #include <stdlib.h>
 #ifndef MACOSX
-#include <link.h>
+#include <dlfcn.h>
 #endif
 #include "jvm_md.h"
 #include "J2D_GL/glx.h"
diff --git a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
index ec90311..e48aec6 100644
--- a/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
+++ b/jdk/src/solaris/native/sun/java2d/x11/X11SurfaceData.c
@@ -563,6 +563,8 @@
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
                        "X11SD_SetupSharedSegment shmget has failed: %s",
                        strerror(errno));
+        free((void *)shminfo);
+        XDestroyImage(img);
         return NULL;
     }
 
@@ -572,6 +574,8 @@
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
                        "X11SD_SetupSharedSegment shmat has failed: %s",
                        strerror(errno));
+        free((void *)shminfo);
+        XDestroyImage(img);
         return NULL;
     }
 
@@ -592,6 +596,9 @@
         J2dRlsTraceLn1(J2D_TRACE_ERROR,
                        "X11SD_SetupSharedSegment XShmAttach has failed: %s",
                        strerror(errno));
+        shmdt(shminfo->shmaddr);
+        free((void *)shminfo);
+        XDestroyImage(img);
         return NULL;
     }
 
@@ -1485,13 +1492,10 @@
 #ifdef MITSHM
         if (image->obdata != NULL) {
             X11SD_DropSharedSegment((XShmSegmentInfo*)image->obdata);
-        } else {
-            free(image->data);
+            image->obdata = NULL;
         }
-#else
-        free(image->data);
 #endif /* MITSHM */
-        XFree(image);
+        XDestroyImage(image);
     }
 }
 
diff --git a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c
index a2b4815..0f8d0a8 100644
--- a/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c
+++ b/jdk/src/solaris/native/sun/java2d/x11/XRBackendNative.c
@@ -70,7 +70,6 @@
 
 #ifdef __solaris__
 /* Solaris 10 will not have these symbols at runtime */
-#include <link.h>
 
 typedef Picture (*XRenderCreateLinearGradientFuncType)
                                      (Display *dpy,
diff --git a/jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c b/jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
index 7d42d14..3bccd57 100644
--- a/jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
+++ b/jdk/src/solaris/native/sun/nio/ch/DatagramChannelImpl.c
@@ -77,7 +77,7 @@
 
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_DatagramChannelImpl_disconnect0(JNIEnv *env, jobject this,
-                                                jobject fdo)
+                                                jobject fdo, jboolean isIPv6)
 {
     jint fd = fdval(env, fdo);
     int rv;
@@ -94,7 +94,7 @@
         memset(&sa, 0, sizeof(sa));
 
 #ifdef AF_INET6
-        if (ipv6_available()) {
+        if (isIPv6) {
             struct sockaddr_in6 *him6 = (struct sockaddr_in6 *)&sa;
 #if defined(_ALLBSD_SOURCE)
             him6->sin6_family = AF_INET6;
diff --git a/jdk/src/solaris/native/sun/nio/ch/DatagramDispatcher.c b/jdk/src/solaris/native/sun/nio/ch/DatagramDispatcher.c
index 6d5337c..594ef9f 100644
--- a/jdk/src/solaris/native/sun/nio/ch/DatagramDispatcher.c
+++ b/jdk/src/solaris/native/sun/nio/ch/DatagramDispatcher.c
@@ -34,8 +34,10 @@
 #include <sys/types.h>
 #include <sys/uio.h>
 #include <sys/socket.h>
+#include <string.h>
 
 #include "nio_util.h"
+#include <limits.h>
 
 JNIEXPORT jint JNICALL
 Java_sun_nio_ch_DatagramDispatcher_read0(JNIEnv *env, jclass clazz,
@@ -60,23 +62,14 @@
     ssize_t result = 0;
     struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
     struct msghdr m;
-    if (len > 16) {
-        len = 16;
+    if (len > IOV_MAX) {
+        len = IOV_MAX;
     }
 
-    m.msg_name = NULL;
-    m.msg_namelen = 0;
+    // initialize the message
+    memset(&m, 0, sizeof(m));
     m.msg_iov = iov;
     m.msg_iovlen = len;
-#ifdef __solaris__
-    m.msg_accrights = NULL;
-    m.msg_accrightslen = 0;
-#endif
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-    m.msg_control = NULL;
-    m.msg_controllen = 0;
-#endif
 
     result = recvmsg(fd, &m, 0);
     if (result < 0 && errno == ECONNREFUSED) {
@@ -108,23 +101,14 @@
     struct iovec *iov = (struct iovec *)jlong_to_ptr(address);
     struct msghdr m;
     ssize_t result = 0;
-    if (len > 16) {
-        len = 16;
+    if (len > IOV_MAX) {
+        len = IOV_MAX;
     }
 
-    m.msg_name = NULL;
-    m.msg_namelen = 0;
+    // initialize the message
+    memset(&m, 0, sizeof(m));
     m.msg_iov = iov;
     m.msg_iovlen = len;
-#ifdef __solaris__
-    m.msg_accrights = NULL;
-    m.msg_accrightslen = 0;
-#endif
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
-    m.msg_control = NULL;
-    m.msg_controllen = 0;
-#endif
 
     result = sendmsg(fd, &m, 0);
     if (result < 0 && errno == ECONNREFUSED) {
diff --git a/jdk/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c b/jdk/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c
index 0c4e1b0..134a279 100644
--- a/jdk/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c
+++ b/jdk/src/solaris/native/sun/nio/ch/DevPollArrayWrapper.c
@@ -28,9 +28,7 @@
 #include "jvm.h"
 #include "jlong.h"
 #include "sun_nio_ch_DevPollArrayWrapper.h"
-#include "java_lang_Integer.h"
 #include <sys/poll.h>
-#include <sys/resource.h>
 #include <unistd.h>
 #include <sys/time.h>
 
@@ -178,21 +176,6 @@
     return result;
 }
 
-JNIEXPORT jint JNICALL
-Java_sun_nio_ch_DevPollArrayWrapper_fdLimit(JNIEnv *env, jclass this)
-{
-    struct rlimit rlp;
-    if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) {
-        JNU_ThrowIOExceptionWithLastError(env,
-                                          "getrlimit failed");
-    }
-    if (rlp.rlim_max < 0 || rlp.rlim_max > java_lang_Integer_MAX_VALUE) {
-        return java_lang_Integer_MAX_VALUE;
-    } else {
-        return (jint)rlp.rlim_max;
-    }
-}
-
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_DevPollArrayWrapper_interrupt(JNIEnv *env, jclass this, jint fd)
 {
diff --git a/jdk/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c b/jdk/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c
index 3d4f051..22ffd1d 100644
--- a/jdk/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c
+++ b/jdk/src/solaris/native/sun/nio/ch/EPollArrayWrapper.c
@@ -30,40 +30,9 @@
 
 #include "sun_nio_ch_EPollArrayWrapper.h"
 
-#include <dlfcn.h>
 #include <unistd.h>
-#include <sys/resource.h>
 #include <sys/time.h>
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-/* epoll_wait(2) man page */
-
-typedef union epoll_data {
-    void *ptr;
-    int fd;
-    __uint32_t u32;
-    __uint64_t u64;
-} epoll_data_t;
-
-
-/* x86-64 has same alignment as 32-bit */
-#ifdef __x86_64__
-#define EPOLL_PACKED __attribute__((packed))
-#else
-#define EPOLL_PACKED
-#endif
-
-struct epoll_event {
-    __uint32_t events;  /* Epoll events */
-    epoll_data_t data;  /* User data variable */
-} EPOLL_PACKED;
-
-#ifdef  __cplusplus
-}
-#endif
+#include <sys/epoll.h>
 
 #define RESTARTABLE(_cmd, _result) do { \
   do { \
@@ -71,18 +40,6 @@
   } while((_result == -1) && (errno == EINTR)); \
 } while(0)
 
-/*
- * epoll event notification is new in 2.6 kernel. As the offical build
- * platform for the JDK is on a 2.4-based distribution then we must
- * obtain the addresses of the epoll functions dynamically.
- */
-typedef int (*epoll_create_t)(int size);
-typedef int (*epoll_ctl_t)   (int epfd, int op, int fd, struct epoll_event *event);
-typedef int (*epoll_wait_t)  (int epfd, struct epoll_event *events, int maxevents, int timeout);
-
-static epoll_create_t epoll_create_func;
-static epoll_ctl_t    epoll_ctl_func;
-static epoll_wait_t   epoll_wait_func;
 
 static int
 iepoll(int epfd, struct epoll_event *events, int numfds, jlong timeout)
@@ -96,7 +53,7 @@
     start = t.tv_sec * 1000 + t.tv_usec / 1000;
 
     for (;;) {
-        int res = (*epoll_wait_func)(epfd, events, numfds, timeout);
+        int res = epoll_wait(epfd, events, numfds, timeout);
         if (res < 0 && errno == EINTR) {
             if (remaining >= 0) {
                 gettimeofday(&t, NULL);
@@ -117,14 +74,6 @@
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_EPollArrayWrapper_init(JNIEnv *env, jclass this)
 {
-    epoll_create_func = (epoll_create_t) dlsym(RTLD_DEFAULT, "epoll_create");
-    epoll_ctl_func    = (epoll_ctl_t)    dlsym(RTLD_DEFAULT, "epoll_ctl");
-    epoll_wait_func   = (epoll_wait_t)   dlsym(RTLD_DEFAULT, "epoll_wait");
-
-    if ((epoll_create_func == NULL) || (epoll_ctl_func == NULL) ||
-        (epoll_wait_func == NULL)) {
-        JNU_ThrowInternalError(env, "unable to get address of epoll functions, pre-2.6 kernel?");
-    }
 }
 
 JNIEXPORT jint JNICALL
@@ -134,7 +83,7 @@
      * epoll_create expects a size as a hint to the kernel about how to
      * dimension internal structures. We can't predict the size in advance.
      */
-    int epfd = (*epoll_create_func)(256);
+    int epfd = epoll_create(256);
     if (epfd < 0) {
        JNU_ThrowIOExceptionWithLastError(env, "epoll_create failed");
     }
@@ -142,16 +91,6 @@
 }
 
 JNIEXPORT jint JNICALL
-Java_sun_nio_ch_EPollArrayWrapper_fdLimit(JNIEnv *env, jclass this)
-{
-    struct rlimit rlp;
-    if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) {
-        JNU_ThrowIOExceptionWithLastError(env, "getrlimit failed");
-    }
-    return (jint)rlp.rlim_max;
-}
-
-JNIEXPORT jint JNICALL
 Java_sun_nio_ch_EPollArrayWrapper_sizeofEPollEvent(JNIEnv* env, jclass this)
 {
     return sizeof(struct epoll_event);
@@ -173,7 +112,7 @@
     event.events = events;
     event.data.fd = fd;
 
-    RESTARTABLE((*epoll_ctl_func)(epfd, (int)opcode, (int)fd, &event), res);
+    RESTARTABLE(epoll_ctl(epfd, (int)opcode, (int)fd, &event), res);
 
     /*
      * A channel may be registered with several Selectors. When each Selector
@@ -199,7 +138,7 @@
     int res;
 
     if (timeout <= 0) {           /* Indefinite or no wait */
-        RESTARTABLE((*epoll_wait_func)(epfd, events, numfds, timeout), res);
+        RESTARTABLE(epoll_wait(epfd, events, numfds, timeout), res);
     } else {                      /* Bounded wait; bounded restarts */
         res = iepoll(epfd, events, numfds, timeout);
     }
diff --git a/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
index d3922d5..4d987b9 100644
--- a/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
+++ b/jdk/src/solaris/native/sun/nio/ch/FileDispatcherImpl.c
@@ -200,7 +200,7 @@
     }
     lockResult = fcntl(fd, cmd, &fl);
     if (lockResult < 0) {
-        if ((cmd == F_SETLK64) && (errno == EAGAIN))
+        if ((cmd == F_SETLK64) && (errno == EAGAIN || errno == EACCES))
             return sun_nio_ch_FileDispatcherImpl_NO_LOCK;
         if (errno == EINTR)
             return sun_nio_ch_FileDispatcherImpl_INTERRUPTED;
diff --git a/jdk/src/solaris/native/sun/nio/ch/IOUtil.c b/jdk/src/solaris/native/sun/nio/ch/IOUtil.c
index 11ef86a2..faa7e36 100644
--- a/jdk/src/solaris/native/sun/nio/ch/IOUtil.c
+++ b/jdk/src/solaris/native/sun/nio/ch/IOUtil.c
@@ -25,11 +25,14 @@
 
 #include <sys/types.h>
 #include <string.h>
+#include <sys/resource.h>
+
 #include "jni.h"
 #include "jni_util.h"
 #include "jvm.h"
 #include "jlong.h"
 #include "sun_nio_ch_IOUtil.h"
+#include "java_lang_Integer.h"
 #include "nio.h"
 #include "nio_util.h"
 
@@ -118,6 +121,20 @@
     }
 }
 
+JNIEXPORT jint JNICALL
+Java_sun_nio_ch_IOUtil_fdLimit(JNIEnv *env, jclass this)
+{
+    struct rlimit rlp;
+    if (getrlimit(RLIMIT_NOFILE, &rlp) < 0) {
+        JNU_ThrowIOExceptionWithLastError(env, "getrlimit failed");
+        return -1;
+    }
+    if (rlp.rlim_max < 0 || rlp.rlim_max > java_lang_Integer_MAX_VALUE) {
+        return java_lang_Integer_MAX_VALUE;
+    } else {
+        return (jint)rlp.rlim_max;
+    }
+}
 
 /* Declared in nio_util.h for use elsewhere in NIO */
 
diff --git a/jdk/src/solaris/native/sun/nio/ch/Net.c b/jdk/src/solaris/native/sun/nio/ch/Net.c
index 45c09c3..2f01af3 100644
--- a/jdk/src/solaris/native/sun/nio/ch/Net.c
+++ b/jdk/src/solaris/native/sun/nio/ch/Net.c
@@ -39,83 +39,6 @@
 #include "nio_util.h"
 #include "nio.h"
 
-/**
- * Definitions for source-specific multicast to allow for building
- * with older header files.
- */
-
-#ifdef __solaris__
-
-#ifndef IP_BLOCK_SOURCE
-
-#define IP_BLOCK_SOURCE                 0x15
-#define IP_UNBLOCK_SOURCE               0x16
-#define IP_ADD_SOURCE_MEMBERSHIP        0x17
-#define IP_DROP_SOURCE_MEMBERSHIP       0x18
-
-#define MCAST_BLOCK_SOURCE              0x2b
-#define MCAST_UNBLOCK_SOURCE            0x2c
-#define MCAST_JOIN_SOURCE_GROUP         0x2d
-#define MCAST_LEAVE_SOURCE_GROUP        0x2e
-
-#endif  /* IP_BLOCK_SOURCE */
-
-struct my_ip_mreq_source {
-        struct in_addr  imr_multiaddr;
-        struct in_addr  imr_sourceaddr;
-        struct in_addr  imr_interface;
-};
-
-/*
- * Use #pragma pack() construct to force 32-bit alignment on amd64.
- */
-#if defined(amd64)
-#pragma pack(4)
-#endif
-
-struct my_group_source_req {
-        uint32_t                gsr_interface;  /* interface index */
-        struct sockaddr_storage gsr_group;      /* group address */
-        struct sockaddr_storage gsr_source;     /* source address */
-};
-
-#if defined(amd64)
-#pragma pack()
-#endif
-
-#endif  /* __solaris__ */
-
-
-#ifdef __linux__
-
-#ifndef IP_BLOCK_SOURCE
-
-#define IP_BLOCK_SOURCE                 38
-#define IP_UNBLOCK_SOURCE               37
-#define IP_ADD_SOURCE_MEMBERSHIP        39
-#define IP_DROP_SOURCE_MEMBERSHIP       40
-
-#define MCAST_BLOCK_SOURCE              43
-#define MCAST_UNBLOCK_SOURCE            44
-#define MCAST_JOIN_SOURCE_GROUP         42
-#define MCAST_LEAVE_SOURCE_GROUP        45
-
-#endif  /* IP_BLOCK_SOURCE */
-
-struct my_ip_mreq_source {
-        struct in_addr  imr_multiaddr;
-        struct in_addr  imr_interface;
-        struct in_addr  imr_sourceaddr;
-};
-
-struct my_group_source_req {
-        uint32_t                gsr_interface;  /* interface index */
-        struct sockaddr_storage gsr_group;      /* group address */
-        struct sockaddr_storage gsr_source;     /* source address */
-};
-
-#endif   /* __linux__ */
-
 #ifdef _ALLBSD_SOURCE
 
 #ifndef IP_BLOCK_SOURCE
@@ -155,7 +78,12 @@
         struct sockaddr_storage gsr_source;     /* source address */
 };
 
-#endif   /* _ALLBSD_SOURCE */
+#else   /* _ALLBSD_SOURCE */
+
+#define my_ip_mreq_source         ip_mreq_source
+#define my_group_source_req       group_source_req
+
+#endif
 
 
 #define COPY_INET6_ADDRESS(env, source, target) \
@@ -576,8 +504,8 @@
         optval = (void*)&mreq6;
         optlen = sizeof(mreq6);
     } else {
-#if defined (__linux__) || defined(MACOSX)
-        /* Include-mode filtering broken on Mac OS & Linux at least to 2.6.24 */
+#ifdef MACOSX
+        /* no IPv6 include-mode filtering for now */
         return IOS_UNAVAILABLE;
 #else
         initGroupSourceReq(env, group, index, source, &req);
diff --git a/jdk/src/solaris/native/sun/nio/ch/SolarisEventPort.c b/jdk/src/solaris/native/sun/nio/ch/SolarisEventPort.c
index b91bf09..70f6db4 100644
--- a/jdk/src/solaris/native/sun/nio/ch/SolarisEventPort.c
+++ b/jdk/src/solaris/native/sun/nio/ch/SolarisEventPort.c
@@ -32,17 +32,12 @@
 #include <stdlib.h>
 #include <dlfcn.h>
 #include <sys/types.h>
-#include <port.h>       // Solaris 10
+#include <port.h>
 
 #include "sun_nio_ch_SolarisEventPort.h"
 
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_SolarisEventPort_init(JNIEnv *env, jclass clazz)
-{
-}
-
 JNIEXPORT jint JNICALL
-Java_sun_nio_ch_SolarisEventPort_portCreate
+Java_sun_nio_ch_SolarisEventPort_port_1create
     (JNIEnv* env, jclass clazz)
 {
     int port = port_create();
@@ -53,37 +48,44 @@
 }
 
 JNIEXPORT void JNICALL
-Java_sun_nio_ch_SolarisEventPort_portClose
+Java_sun_nio_ch_SolarisEventPort_port_1close
     (JNIEnv* env, jclass clazz, jint port)
 {
     int res;
     RESTARTABLE(close(port), res);
 }
 
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_SolarisEventPort_portAssociate
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_ch_SolarisEventPort_port_1associate
     (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress, jint events)
 {
     uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress);
-
-    if (port_associate((int)port, (int)source, object, (int)events, NULL) == -1) {
-        JNU_ThrowIOExceptionWithLastError(env, "port_associate");
+    if (port_associate((int)port, (int)source, object, (int)events, NULL) == 0) {
+        return JNI_TRUE;
+    } else {
+        if (errno != EBADFD)
+            JNU_ThrowIOExceptionWithLastError(env, "port_associate");
+        return JNI_FALSE;
     }
 }
 
-JNIEXPORT void JNICALL
-Java_sun_nio_ch_SolarisEventPort_portDissociate
+JNIEXPORT jboolean JNICALL
+Java_sun_nio_ch_SolarisEventPort_port_1dissociate
     (JNIEnv* env, jclass clazz, jint port, jint source, jlong objectAddress)
 {
     uintptr_t object = (uintptr_t)jlong_to_ptr(objectAddress);
 
-    if (port_dissociate((int)port, (int)source, object) == -1) {
-        JNU_ThrowIOExceptionWithLastError(env, "port_dissociate");
+    if (port_dissociate((int)port, (int)source, object) == 0) {
+        return JNI_TRUE;
+    } else {
+        if (errno != ENOENT)
+            JNU_ThrowIOExceptionWithLastError(env, "port_dissociate");
+        return JNI_FALSE;
     }
 }
 
 JNIEXPORT void JNICALL
-Java_sun_nio_ch_SolarisEventPort_portSend(JNIEnv* env, jclass clazz,
+Java_sun_nio_ch_SolarisEventPort_port_1send(JNIEnv* env, jclass clazz,
     jint port, jint events)
 {
     if (port_send((int)port, (int)events, NULL) == -1) {
@@ -92,7 +94,7 @@
 }
 
 JNIEXPORT void JNICALL
-Java_sun_nio_ch_SolarisEventPort_portGet(JNIEnv* env, jclass clazz,
+Java_sun_nio_ch_SolarisEventPort_port_1get(JNIEnv* env, jclass clazz,
     jint port, jlong eventAddress)
 {
     int res;
@@ -105,16 +107,28 @@
 }
 
 JNIEXPORT jint JNICALL
-Java_sun_nio_ch_SolarisEventPort_portGetn(JNIEnv* env, jclass clazz,
-    jint port, jlong arrayAddress, jint max)
+Java_sun_nio_ch_SolarisEventPort_port_1getn(JNIEnv* env, jclass clazz,
+    jint port, jlong arrayAddress, jint max, jlong timeout)
 {
     int res;
     uint_t n = 1;
     port_event_t* list = (port_event_t*)jlong_to_ptr(arrayAddress);
+    timespec_t ts;
+    timespec_t* tsp;
 
-    RESTARTABLE(port_getn((int)port, list, (uint_t)max, &n, NULL), res);
-    if (res == -1) {
-        JNU_ThrowIOExceptionWithLastError(env, "port_getn");
+    if (timeout >= 0L) {
+        ts.tv_sec = timeout / 1000;
+        ts.tv_nsec = 1000000 * (timeout % 1000);
+        tsp = &ts;
+    } else {
+        tsp = NULL;
     }
+
+    res = port_getn((int)port, list, (uint_t)max, &n, tsp);
+    if (res == -1) {
+        if (errno != ETIME && errno != EINTR)
+            JNU_ThrowIOExceptionWithLastError(env, "port_getn");
+    }
+
     return (jint)n;
 }
diff --git a/jdk/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c b/jdk/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c
index 80342ef..71ecd90 100644
--- a/jdk/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c
+++ b/jdk/src/solaris/native/sun/nio/fs/BsdNativeDispatcher.c
@@ -46,8 +46,6 @@
 static jfieldID entry_dir;
 static jfieldID entry_fstype;
 static jfieldID entry_options;
-static jfieldID entry_dev;
-
 
 struct fsstat_iter {
     struct statfs *buf;
@@ -81,7 +79,6 @@
     entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
     entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
     entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
-    entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
 }
 
 JNIEXPORT jlong JNICALL
@@ -160,7 +157,6 @@
         options="ro";
     else
         options="";
-    dev = 0;
 
     iter->pos++;
 
@@ -192,9 +188,6 @@
     (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
     (*env)->SetObjectField(env, entry, entry_options, bytes);
 
-    if (dev != 0)
-        (*env)->SetLongField(env, entry, entry_dev, (jlong)dev);
-
     return 0;
 }
 
@@ -208,3 +201,4 @@
         free(iter);
     }
 }
+
diff --git a/jdk/src/solaris/native/sun/nio/fs/GnomeFileTypeDetector.c b/jdk/src/solaris/native/sun/nio/fs/GnomeFileTypeDetector.c
index 7dc606c..0bd8dba 100644
--- a/jdk/src/solaris/native/sun/nio/fs/GnomeFileTypeDetector.c
+++ b/jdk/src/solaris/native/sun/nio/fs/GnomeFileTypeDetector.c
@@ -30,15 +30,12 @@
 
 #include <stdlib.h>
 #include <dlfcn.h>
-#ifndef __APPLE__
-#include <link.h>
-#endif
 
 #ifdef __solaris__
 #include <strings.h>
 #endif
 
-#if defined(__linux__) || defined(__APPLE__)
+#if defined(__linux__)
 #include <string.h>
 #endif
 
diff --git a/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c b/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
index de329d5..5a158fc 100644
--- a/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
+++ b/jdk/src/solaris/native/sun/nio/fs/LinuxNativeDispatcher.c
@@ -29,6 +29,7 @@
 #include "jlong.h"
 
 #include <stdio.h>
+#include <string.h>
 #include <dlfcn.h>
 #include <errno.h>
 #include <mntent.h>
@@ -45,6 +46,11 @@
 fremovexattr_func* my_fremovexattr_func = NULL;
 flistxattr_func* my_flistxattr_func = NULL;
 
+static jfieldID entry_name;
+static jfieldID entry_dir;
+static jfieldID entry_fstype;
+static jfieldID entry_options;
+
 static void throwUnixException(JNIEnv* env, int errnum) {
     jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
         "(I)V", errnum);
@@ -60,6 +66,15 @@
     my_fsetxattr_func = (fsetxattr_func*)dlsym(RTLD_DEFAULT, "fsetxattr");
     my_fremovexattr_func = (fremovexattr_func*)dlsym(RTLD_DEFAULT, "fremovexattr");
     my_flistxattr_func = (flistxattr_func*)dlsym(RTLD_DEFAULT, "flistxattr");
+
+    clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
+    if (clazz == NULL)
+        return;
+
+    entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+    entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+    entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+    entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
 }
 
 JNIEXPORT jint JNICALL
@@ -151,6 +166,61 @@
     return ptr_to_jlong(fp);
 }
 
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_LinuxNativeDispatcher_getmntent(JNIEnv* env, jclass this,
+    jlong value, jobject entry)
+{
+    struct mntent ent;
+    char buf[1024];
+    int buflen = sizeof(buf);
+    struct mntent* m;
+    FILE* fp = jlong_to_ptr(value);
+    jsize len;
+    jbyteArray bytes;
+    char* name;
+    char* dir;
+    char* fstype;
+    char* options;
+
+    m = getmntent_r(fp, &ent, (char*)&buf, buflen);
+    if (m == NULL)
+        return -1;
+    name = m->mnt_fsname;
+    dir = m->mnt_dir;
+    fstype = m->mnt_type;
+    options = m->mnt_opts;
+
+    len = strlen(name);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
+    (*env)->SetObjectField(env, entry, entry_name, bytes);
+
+    len = strlen(dir);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);
+    (*env)->SetObjectField(env, entry, entry_dir, bytes);
+
+    len = strlen(fstype);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
+    (*env)->SetObjectField(env, entry, entry_fstype, bytes);
+
+    len = strlen(options);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
+    (*env)->SetObjectField(env, entry, entry_options, bytes);
+
+    return 0;
+}
+
 JNIEXPORT void JNICALL
 Java_sun_nio_fs_LinuxNativeDispatcher_endmntent(JNIEnv* env, jclass this, jlong stream)
 {
diff --git a/jdk/src/solaris/native/sun/nio/fs/MacOSXNativeDispatcher.c b/jdk/src/solaris/native/sun/nio/fs/MacOSXNativeDispatcher.c
new file mode 100644
index 0000000..50c5e21
--- /dev/null
+++ b/jdk/src/solaris/native/sun/nio/fs/MacOSXNativeDispatcher.c
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2008, 2009, 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.
+ */
+
+#include "jni.h"
+#include "jni_util.h"
+#include "jvm.h"
+#include "jlong.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <CoreFoundation/CoreFoundation.h>
+
+JNIEXPORT jcharArray JNICALL
+Java_sun_nio_fs_MacOSXNativeDispatcher_normalizepath(JNIEnv* env, jclass this,
+                                                     jcharArray path,
+                                                     jint form)
+{
+    jcharArray result = NULL;
+    char chars_buf[(PATH_MAX + 1) * 2];     // utf16 + zero padding
+    CFMutableStringRef csref = CFStringCreateMutable(NULL, 0);
+    if (csref == NULL) {
+        JNU_ThrowOutOfMemoryError(env, "native heap");
+    } else {
+        char *chars = (char*)(*env)->GetPrimitiveArrayCritical(env, path, 0);
+        jsize len = (*env)->GetArrayLength(env, path);
+        CFStringAppendCharacters(csref, (const UniChar*)chars, len);
+        (*env)->ReleasePrimitiveArrayCritical(env, path, chars, 0);
+        CFStringNormalize(csref, form);
+        len = CFStringGetLength(csref);
+        if (len < PATH_MAX) {
+            if (CFStringGetCString(csref, chars_buf, sizeof(chars_buf), kCFStringEncodingUTF16)) {
+                result = (*env)->NewCharArray(env, len);
+                (*env)->SetCharArrayRegion(env, result, 0, len, (jchar*)&chars_buf);
+            }
+        } else {
+            int ulen = (len + 1) * 2;
+            chars = malloc(ulen);
+            if (chars == NULL) {
+                CFRelease(csref);
+                JNU_ThrowOutOfMemoryError(env, "native heap");
+                return result;
+            } else {
+                if (CFStringGetCString(csref, chars, ulen, kCFStringEncodingUTF16)) {
+                    result = (*env)->NewCharArray(env, len);
+                    (*env)->SetCharArrayRegion(env, result, 0, len, (jchar*)chars);
+                }
+                free(chars);
+            }
+        }
+        CFRelease(csref);
+    }
+    return result;
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c b/jdk/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c
index 9bd4556..5c93fee 100644
--- a/jdk/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c
+++ b/jdk/src/solaris/native/sun/nio/fs/SolarisNativeDispatcher.c
@@ -28,12 +28,22 @@
 #include "jvm.h"
 #include "jlong.h"
 
-#include <dlfcn.h>
+#include <strings.h>
 #include <errno.h>
 #include <sys/acl.h>
+#include <sys/mnttab.h>
+#include <sys/mkdev.h>
+
+#include "jni.h"
 
 #include "sun_nio_fs_SolarisNativeDispatcher.h"
 
+static jfieldID entry_name;
+static jfieldID entry_dir;
+static jfieldID entry_fstype;
+static jfieldID entry_options;
+static jfieldID entry_dev;
+
 static void throwUnixException(JNIEnv* env, int errnum) {
     jobject x = JNU_NewObjectByName(env, "sun/nio/fs/UnixException",
         "(I)V", errnum);
@@ -44,6 +54,15 @@
 
 JNIEXPORT void JNICALL
 Java_sun_nio_fs_SolarisNativeDispatcher_init(JNIEnv *env, jclass clazz) {
+    clazz = (*env)->FindClass(env, "sun/nio/fs/UnixMountEntry");
+    if (clazz == NULL)
+        return;
+
+    entry_name = (*env)->GetFieldID(env, clazz, "name", "[B");
+    entry_dir = (*env)->GetFieldID(env, clazz, "dir", "[B");
+    entry_fstype = (*env)->GetFieldID(env, clazz, "fstype", "[B");
+    entry_options = (*env)->GetFieldID(env, clazz, "opts", "[B");
+    entry_dev = (*env)->GetFieldID(env, clazz, "dev", "J");
 }
 
 JNIEXPORT jint JNICALL
@@ -59,3 +78,63 @@
     }
     return (jint)n;
 }
+
+JNIEXPORT jint JNICALL
+Java_sun_nio_fs_SolarisNativeDispatcher_getextmntent(JNIEnv* env, jclass this,
+    jlong value, jobject entry)
+{
+    struct extmnttab ent;
+    FILE* fp = jlong_to_ptr(value);
+    jsize len;
+    jbyteArray bytes;
+    char* name;
+    char* dir;
+    char* fstype;
+    char* options;
+    dev_t dev;
+
+    if (getextmntent(fp, &ent, 0))
+        return -1;
+    name = ent.mnt_special;
+    dir = ent.mnt_mountp;
+    fstype = ent.mnt_fstype;
+    options = ent.mnt_mntopts;
+    dev = makedev(ent.mnt_major, ent.mnt_minor);
+    if (dev == NODEV) {
+        throwUnixException(env, errno);
+        return -1;
+    }
+
+    len = strlen(name);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
+    (*env)->SetObjectField(env, entry, entry_name, bytes);
+
+    len = strlen(dir);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);
+    (*env)->SetObjectField(env, entry, entry_dir, bytes);
+
+    len = strlen(fstype);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
+    (*env)->SetObjectField(env, entry, entry_fstype, bytes);
+
+    len = strlen(options);
+    bytes = (*env)->NewByteArray(env, len);
+    if (bytes == NULL)
+        return -1;
+    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
+    (*env)->SetObjectField(env, entry, entry_options, bytes);
+
+    if (dev != 0)
+        (*env)->SetLongField(env, entry, entry_dev, (jlong)dev);
+
+    return 0;
+}
diff --git a/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
index 7b7b361..09ee01b 100644
--- a/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
+++ b/jdk/src/solaris/native/sun/nio/fs/UnixNativeDispatcher.c
@@ -40,13 +40,10 @@
 
 #ifdef __solaris__
 #include <strings.h>
-#include <sys/mnttab.h>
-#include <sys/mkdev.h>
 #endif
 
 #ifdef __linux__
 #include <string.h>
-#include <mntent.h>
 #endif
 
 #ifdef _ALLBSD_SOURCE
@@ -1018,7 +1015,7 @@
 
         if (res != 0 || p == NULL || p->pw_name == NULL || *(p->pw_name) == '\0') {
             /* not found or error */
-            if (errno != 0 && errno != ENOENT)
+            if (errno != 0 && errno != ENOENT && errno != ESRCH)
                 throwUnixException(env, errno);
         } else {
             uid = p->pw_uid;
@@ -1064,7 +1061,7 @@
         retry = 0;
         if (res != 0 || g == NULL || g->gr_name == NULL || *(g->gr_name) == '\0') {
             /* not found or error */
-            if (errno != 0 && errno != ENOENT) {
+            if (errno != 0 && errno != ENOENT && errno != ESRCH) {
                 if (errno == ERANGE) {
                     /* insufficient buffer size so need larger buffer */
                     buflen += ENT_BUF_SIZE;
@@ -1083,105 +1080,3 @@
 
     return gid;
 }
-
-JNIEXPORT jint JNICALL
-Java_sun_nio_fs_UnixNativeDispatcher_getextmntent(JNIEnv* env, jclass this,
-    jlong value, jobject entry)
-{
-#ifdef __solaris__
-    struct extmnttab ent;
-#elif defined(_ALLBSD_SOURCE)
-    char buf[1024];
-    char *str;
-    char *last;
-#else
-    struct mntent ent;
-    char buf[1024];
-    int buflen = sizeof(buf);
-    struct mntent* m;
-#endif
-    FILE* fp = jlong_to_ptr(value);
-    jsize len;
-    jbyteArray bytes;
-    char* name;
-    char* dir;
-    char* fstype;
-    char* options;
-    dev_t dev;
-
-#ifdef __solaris__
-    if (getextmntent(fp, &ent, 0))
-        return -1;
-    name = ent.mnt_special;
-    dir = ent.mnt_mountp;
-    fstype = ent.mnt_fstype;
-    options = ent.mnt_mntopts;
-    dev = makedev(ent.mnt_major, ent.mnt_minor);
-    if (dev == NODEV) {
-        /* possible bug on Solaris 8 and 9 */
-        throwUnixException(env, errno);
-        return -1;
-    }
-#elif defined(_ALLBSD_SOURCE)
-again:
-    if (!(str = fgets(buf, sizeof(buf), fp)))
-        return -1;
-
-    name = strtok_r(str, " \t\n", &last);
-    if (name == NULL)
-        return -1;
-
-    // skip comments
-    if (*name == '#')
-        goto again;
-
-    dir = strtok_r((char *)NULL, " \t\n", &last);
-    fstype = strtok_r((char *)NULL, " \t\n", &last);
-    options = strtok_r((char *)NULL, " \t\n", &last);
-    if (options == NULL)
-        return -1;
-    dev = 0;
-#else
-    m = getmntent_r(fp, &ent, (char*)&buf, buflen);
-    if (m == NULL)
-        return -1;
-    name = m->mnt_fsname;
-    dir = m->mnt_dir;
-    fstype = m->mnt_type;
-    options = m->mnt_opts;
-    dev = 0;
-#endif
-
-    len = strlen(name);
-    bytes = (*env)->NewByteArray(env, len);
-    if (bytes == NULL)
-        return -1;
-    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)name);
-    (*env)->SetObjectField(env, entry, entry_name, bytes);
-
-    len = strlen(dir);
-    bytes = (*env)->NewByteArray(env, len);
-    if (bytes == NULL)
-        return -1;
-    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)dir);
-    (*env)->SetObjectField(env, entry, entry_dir, bytes);
-
-    len = strlen(fstype);
-    bytes = (*env)->NewByteArray(env, len);
-    if (bytes == NULL)
-        return -1;
-    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)fstype);
-    (*env)->SetObjectField(env, entry, entry_fstype, bytes);
-
-    len = strlen(options);
-    bytes = (*env)->NewByteArray(env, len);
-    if (bytes == NULL)
-        return -1;
-    (*env)->SetByteArrayRegion(env, bytes, 0, len, (jbyte*)options);
-    (*env)->SetObjectField(env, entry, entry_options, bytes);
-
-    if (dev != 0)
-        (*env)->SetLongField(env, entry, entry_dev, (jlong)dev);
-
-    return 0;
-}
diff --git a/jdk/src/solaris/native/sun/nio/fs/genSolarisConstants.c b/jdk/src/solaris/native/sun/nio/fs/genSolarisConstants.c
index df46398..346bfbb 100644
--- a/jdk/src/solaris/native/sun/nio/fs/genSolarisConstants.c
+++ b/jdk/src/solaris/native/sun/nio/fs/genSolarisConstants.c
@@ -27,7 +27,7 @@
 #include <errno.h>
 #include <unistd.h>
 #include <sys/acl.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
 #include <sys/stat.h>
 
 /**
diff --git a/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c b/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c
index 2c7c4fb..f9107b2 100644
--- a/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c
+++ b/jdk/src/solaris/native/sun/nio/fs/genUnixConstants.c
@@ -26,7 +26,7 @@
 #include <stdio.h>
 #include <errno.h>
 #include <unistd.h>
-#include <sys/fcntl.h>
+#include <fcntl.h>
 #include <sys/stat.h>
 
 /**
@@ -69,7 +69,12 @@
 #else
     DEFX(O_DSYNC);
 #endif
+#ifdef O_NOFOLLOW
     DEFX(O_NOFOLLOW);
+#else
+    // not supported (dummy values will not be used at runtime).
+    emitX("O_NOFOLLOW", 0x0);
+#endif
 
     // mode masks
     emitX("S_IAMB",
diff --git a/jdk/src/solaris/native/sun/security/jgss/wrapper/NativeFunc.c b/jdk/src/solaris/native/sun/security/jgss/wrapper/NativeFunc.c
index fdb32df..f46c00a 100644
--- a/jdk/src/solaris/native/sun/security/jgss/wrapper/NativeFunc.c
+++ b/jdk/src/solaris/native/sun/security/jgss/wrapper/NativeFunc.c
@@ -26,9 +26,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <dlfcn.h>
-#ifndef __APPLE__
-#include <link.h>
-#endif
 #include "NativeFunc.h"
 
 /* standard GSS method names (ordering is from mapfile) */
diff --git a/jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.c b/jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.c
index 134f0a6..8519ce2 100644
--- a/jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.c
+++ b/jdk/src/solaris/native/sun/security/pkcs11/j2secmod_md.c
@@ -28,9 +28,6 @@
 #include <string.h>
 
 #include <dlfcn.h>
-#ifndef __APPLE__
-#include <link.h>
-#endif
 
 #include <jni_util.h>
 
diff --git a/jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c b/jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c
index 59b311f..277f114 100644
--- a/jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c
+++ b/jdk/src/solaris/native/sun/security/pkcs11/wrapper/p11_md.c
@@ -64,9 +64,6 @@
 #include <assert.h>
 
 #include <dlfcn.h>
-#ifndef __APPLE__
-#include <link.h>
-#endif
 
 #include <jni.h>
 
diff --git a/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c b/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c
index 53b2431..53669c3 100644
--- a/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c
+++ b/jdk/src/solaris/native/sun/security/smartcardio/pcsc_md.c
@@ -29,9 +29,6 @@
 #include <assert.h>
 
 #include <dlfcn.h>
-#ifndef __APPLE__
-#include <link.h>
-#endif
 
 #include <winscard.h>
 
diff --git a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
index 18930fe..f48e833a 100644
--- a/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
+++ b/jdk/src/solaris/native/sun/xawt/XlibWrapper.c
@@ -1260,13 +1260,15 @@
 
 JavaVM* jvm = NULL;
 static int ToolkitErrorHandler(Display * dpy, XErrorEvent * event) {
+    JNIEnv * env;
     if (jvm != NULL) {
-        JNIEnv * env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
-        return JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit", "globalErrorHandler", "(JJ)I",
-                                          ptr_to_jlong(dpy), ptr_to_jlong(event)).i;
-    } else {
-        return 0;
+        env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2);
+        if (env) {
+            return JNU_CallStaticMethodByName(env, NULL, "sun/awt/X11/XToolkit", "globalErrorHandler", "(JJ)I",
+                                              ptr_to_jlong(dpy), ptr_to_jlong(event)).i;
+        }
     }
+    return 0;
 }
 
 /*
diff --git a/jdk/src/solaris/npt/npt_md.h b/jdk/src/solaris/npt/npt_md.h
index 8820b2c..6be1680 100644
--- a/jdk/src/solaris/npt/npt_md.h
+++ b/jdk/src/solaris/npt/npt_md.h
@@ -32,21 +32,18 @@
 #include <string.h>
 #include <errno.h>
 #include <dlfcn.h>
-#ifndef __APPLE__
-#include <link.h>
-#endif
 #include <jvm_md.h>
 
 #define NPT_LIBNAME "npt"
 
-#define NPT_INITIALIZE(pnpt,version,options)                            \
+#define NPT_INITIALIZE(path,pnpt,version,options)                       \
     {                                                                   \
         void   *_handle;                                                \
         void   *_sym;                                                   \
                                                                         \
         if ( (pnpt) == NULL ) NPT_ERROR("NptEnv* is NULL");             \
         *(pnpt) = NULL;                                                 \
-        _handle =  dlopen(JNI_LIB_NAME(NPT_LIBNAME), RTLD_LAZY);              \
+        _handle =  dlopen(path, RTLD_LAZY);                             \
         if ( _handle == NULL ) NPT_ERROR("Cannot open library");        \
         _sym = dlsym(_handle, "nptInitialize");                         \
         if ( _sym == NULL ) NPT_ERROR("Cannot find nptInitialize");     \
diff --git a/jdk/src/solaris/transport/socket/socket_md.c b/jdk/src/solaris/transport/socket/socket_md.c
index 25973d9..f570503 100644
--- a/jdk/src/solaris/transport/socket/socket_md.c
+++ b/jdk/src/solaris/transport/socket/socket_md.c
@@ -35,8 +35,7 @@
 #include <sys/time.h>
 #ifdef __solaris__
 #include <thread.h>
-#endif
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+#else
 #include <pthread.h>
 #include <sys/poll.h>
 #endif
@@ -306,9 +305,7 @@
     return r;
 }
 
-#endif
-
-#if defined(__linux__) || defined(_ALLBSD_SOURCE)
+#else
 int
 dbgsysTlsAlloc() {
     pthread_key_t key;
diff --git a/jdk/src/windows/back/linker_md.c b/jdk/src/windows/back/linker_md.c
index a651eee..e3ca258 100644
--- a/jdk/src/windows/back/linker_md.c
+++ b/jdk/src/windows/back/linker_md.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -32,11 +32,42 @@
 #include <stdio.h>
 #include <string.h>
 #include <errno.h>
+#include <io.h>
 
 #include "sys.h"
 
 #include "path_md.h"
 
+static void dll_build_name(char* buffer, size_t buflen,
+                           const char* pname, const char* fname) {
+    // Based on os_windows.cpp
+
+    char *path_sep = PATH_SEPARATOR;
+    char *pathname = (char *)pname;
+    while (strlen(pathname) > 0) {
+        char *p = strchr(pathname, *path_sep);
+        if (p == NULL) {
+            p = pathname + strlen(pathname);
+        }
+        /* check for NULL path */
+        if (p == pathname) {
+            continue;
+        }
+        if (*(p-1) == ':' || *(p-1) == '\\') {
+            (void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
+                            pathname, fname);
+        } else {
+            (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
+                            pathname, fname);
+        }
+        if (_access(buffer, 0) == 0) {
+            break;
+        }
+        pathname = p + 1;
+        *buffer = '\0';
+    }
+}
+
 /*
  * From system_md.c v1.54
  */
@@ -80,20 +111,17 @@
 dbgsysBuildLibName(char *holder, int holderlen, char *pname, char *fname)
 {
     const int pnamelen = pname ? (int)strlen(pname) : 0;
-    const char c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
 
+    *holder = '\0';
     /* Quietly truncates on buffer overflow. Should be an error. */
     if (pnamelen + (int)strlen(fname) + 10 > holderlen) {
-        *holder = '\0';
         return;
     }
 
     if (pnamelen == 0) {
         sprintf(holder, "%s.dll", fname);
-    } else if (c == ':' || c == '\\') {
-        sprintf(holder, "%s%s.dll", pname, fname);
     } else {
-        sprintf(holder, "%s\\%s.dll", pname, fname);
+      dll_build_name(holder, holderlen, pname, fname);
     }
 }
 
diff --git a/jdk/src/windows/classes/java/lang/Terminator.java b/jdk/src/windows/classes/java/lang/Terminator.java
index ef33d54..6d3d2d6 100644
--- a/jdk/src/windows/classes/java/lang/Terminator.java
+++ b/jdk/src/windows/classes/java/lang/Terminator.java
@@ -53,13 +53,17 @@
             }
         };
         handler = sh;
+
+        // When -Xrs is specified the user is responsible for
+        // ensuring that shutdown hooks are run by calling
+        // System.exit()
         try {
             Signal.handle(new Signal("INT"), sh);
+        } catch (IllegalArgumentException e) {
+        }
+        try {
             Signal.handle(new Signal("TERM"), sh);
         } catch (IllegalArgumentException e) {
-            // When -Xrs is specified the user is responsible for
-            // ensuring that shutdown hooks are run by calling
-            // System.exit()
         }
     }
 
diff --git a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
index 06331ba..c6cde3c 100644
--- a/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
+++ b/jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
@@ -1099,7 +1099,7 @@
                                     ? SwingConstants.CENTER
                                     : SwingConstants.LEADING);
 
-                            column.setComparator(new ColumnComparator(getIShellFolder(), i));
+                            column.setComparator(new ColumnComparator(Win32ShellFolder2.this, i));
 
                             notNullColumns.add(column);
                         }
@@ -1135,7 +1135,7 @@
         // synchronize the whole code of the sort method once
         invoke(new Callable<Void>() {
             public Void call() {
-                Collections.sort(files, new ColumnComparator(getIShellFolder(), 0));
+                Collections.sort(files, new ColumnComparator(Win32ShellFolder2.this, 0));
 
                 return null;
             }
@@ -1143,12 +1143,12 @@
     }
 
     private static class ColumnComparator implements Comparator<File> {
-        private final long parentIShellFolder;
+        private final Win32ShellFolder2 shellFolder;
 
         private final int columnIdx;
 
-        public ColumnComparator(long parentIShellFolder, int columnIdx) {
-            this.parentIShellFolder = parentIShellFolder;
+        public ColumnComparator(Win32ShellFolder2 shellFolder, int columnIdx) {
+            this.shellFolder = shellFolder;
             this.columnIdx = columnIdx;
         }
 
@@ -1159,7 +1159,7 @@
                     if (o instanceof Win32ShellFolder2
                         && o1 instanceof Win32ShellFolder2) {
                         // delegates comparison to native method
-                        return compareIDsByColumn(parentIShellFolder,
+                        return compareIDsByColumn(shellFolder.getIShellFolder(),
                             ((Win32ShellFolder2) o).getRelativePIDL(),
                             ((Win32ShellFolder2) o1).getRelativePIDL(),
                             columnIdx);
diff --git a/jdk/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java b/jdk/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java
index ddaf929..fdd15d2 100644
--- a/jdk/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java
+++ b/jdk/src/windows/classes/sun/awt/windows/WKeyboardFocusManagerPeer.java
@@ -25,7 +25,6 @@
 
 package sun.awt.windows;
 
-import java.awt.KeyboardFocusManager;
 import java.awt.Window;
 import java.awt.Component;
 import java.awt.peer.ComponentPeer;
@@ -37,8 +36,13 @@
     static native Component getNativeFocusOwner();
     static native Window getNativeFocusedWindow();
 
-    WKeyboardFocusManagerPeer(KeyboardFocusManager manager) {
-        super(manager);
+    private static final WKeyboardFocusManagerPeer inst = new WKeyboardFocusManagerPeer();
+
+    public static WKeyboardFocusManagerPeer getInstance() {
+        return inst;
+    }
+
+    private WKeyboardFocusManagerPeer() {
     }
 
     @Override
@@ -52,6 +56,12 @@
     }
 
     @Override
+    public void setCurrentFocusedWindow(Window win) {
+        // Not used on Windows
+        throw new RuntimeException("not implemented");
+    }
+
+    @Override
     public Window getCurrentFocusedWindow() {
         return getNativeFocusedWindow();
     }
diff --git a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java
index 26b234f..ae6188a 100644
--- a/jdk/src/windows/classes/sun/awt/windows/WToolkit.java
+++ b/jdk/src/windows/classes/sun/awt/windows/WToolkit.java
@@ -500,10 +500,10 @@
         return true;
     }
 
-    public KeyboardFocusManagerPeer createKeyboardFocusManagerPeer(KeyboardFocusManager manager)
+    public KeyboardFocusManagerPeer getKeyboardFocusManagerPeer()
       throws HeadlessException
     {
-        return new WKeyboardFocusManagerPeer(manager);
+        return WKeyboardFocusManagerPeer.getInstance();
     }
 
     protected native void setDynamicLayoutNative(boolean b);
diff --git a/jdk/src/windows/classes/sun/java2d/ScreenUpdateManager.java b/jdk/src/windows/classes/sun/java2d/ScreenUpdateManager.java
index 49816c5..d15e28c 100644
--- a/jdk/src/windows/classes/sun/java2d/ScreenUpdateManager.java
+++ b/jdk/src/windows/classes/sun/java2d/ScreenUpdateManager.java
@@ -110,6 +110,11 @@
     public SurfaceData getReplacementScreenSurface(WComponentPeer peer,
                                                    SurfaceData oldsd)
     {
+        SurfaceData surfaceData = peer.getSurfaceData();
+        if (surfaceData == null || surfaceData.isValid()) {
+            return surfaceData;
+        }
+        peer.replaceSurfaceData();
         return peer.getSurfaceData();
     }
 
diff --git a/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java b/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java
index 50a51a6..d37db9e 100644
--- a/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java
+++ b/jdk/src/windows/classes/sun/java2d/d3d/D3DSurfaceData.java
@@ -486,7 +486,7 @@
             int dataType = 0;
             int scanStride = width;
 
-            if (dcm.getPixelSize() == 24 || dcm.getPixelSize() == 32) {
+            if (dcm.getPixelSize() > 16) {
                 dataType = DataBuffer.TYPE_INT;
             } else {
                 // 15, 16
diff --git a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java
index dc8b2c8..4e976d4 100644
--- a/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java
+++ b/jdk/src/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java
@@ -194,12 +194,12 @@
             }
             String response = "NTLM " + seq.getAuthHeader (raw.length()>6?raw.substring(5):null);
             conn.setAuthenticationProperty(getHeaderName(), response);
-            if (seq.isComplete()) { // 7200720
+            if (seq.isComplete()) {
                 conn.authObj(null);
             }
             return true;
         } catch (IOException e) {
-            conn.authObj(null); // MMM 7200720 ??
+            conn.authObj(null);
             return false;
         }
     }
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java b/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java
index d9b1489..67bffcf 100644
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsChannelFactory.java
@@ -157,7 +157,7 @@
             throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed");
 
         FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor);
-        return FileChannelImpl.open(fdObj, flags.read, flags.write, flags.append, null);
+        return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, flags.append, null);
     }
 
     /**
diff --git a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
index bff9e0a..a0020e5 100644
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java
@@ -352,19 +352,34 @@
         }
     }
 
+    /**
+     * Checks if the given file(or directory) exists and is readable.
+     */
+    private void checkReadAccess(WindowsPath file) throws IOException {
+        try {
+            Set<OpenOption> opts = Collections.emptySet();
+            FileChannel fc = WindowsChannelFactory
+                .newFileChannel(file.getPathForWin32Calls(),
+                                file.getPathForPermissionCheck(),
+                                opts,
+                                0L);
+            fc.close();
+        } catch (WindowsException exc) {
+            // Windows errors are very inconsistent when the file is a directory
+            // (ERROR_PATH_NOT_FOUND returned for root directories for example)
+            // so we retry by attempting to open it as a directory.
+            try {
+                new WindowsDirectoryStream(file, null).close();
+            } catch (IOException ioe) {
+                // translate and throw original exception
+                exc.rethrowAsIOException(file);
+            }
+        }
+    }
+
     @Override
     public void checkAccess(Path obj, AccessMode... modes) throws IOException {
         WindowsPath file = WindowsPath.toWindowsPath(obj);
-        // if no access modes then simply file attributes
-        if (modes.length == 0) {
-            file.checkRead();
-            try {
-                WindowsFileAttributes.get(file, true);
-            } catch (WindowsException exc) {
-                exc.rethrowAsIOException(file);
-            }
-            return;
-        }
 
         boolean r = false;
         boolean w = false;
@@ -378,6 +393,13 @@
             }
         }
 
+        // special-case read access to avoid needing to determine effective
+        // access to file; default if modes not specified
+        if (!w && !x) {
+            checkReadAccess(file);
+            return;
+        }
+
         int mask = 0;
         if (r) {
             file.checkRead();
diff --git a/jdk/src/windows/demo/jvmti/hprof/hprof_md.c b/jdk/src/windows/demo/jvmti/hprof/hprof_md.c
index 2f3ba24..e5cbeda 100644
--- a/jdk/src/windows/demo/jvmti/hprof/hprof_md.c
+++ b/jdk/src/windows/demo/jvmti/hprof/hprof_md.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -367,28 +367,53 @@
     return 0;
 }
 
+static void dll_build_name(char* buffer, size_t buflen,
+                           const char* pname, const char* fname) {
+    // Loosley based on os_windows.cpp
+
+    char *pathname = (char *)pname;
+    while (strlen(pathname) > 0) {
+        char *p = strchr(pathname, ';');
+        if (p == NULL) {
+            p = pathname + strlen(pathname);
+        }
+        /* check for NULL path */
+        if (p == pathname) {
+            continue;
+        }
+        if (*(p-1) == ':' || *(p-1) == '\\') {
+            (void)_snprintf(buffer, buflen, "%.*s%s.dll", (p - pathname),
+                            pathname, fname);
+        } else {
+            (void)_snprintf(buffer, buflen, "%.*s\\%s.dll", (p - pathname),
+                            pathname, fname);
+        }
+        if (_access(buffer, 0) == 0) {
+            break;
+        }
+        pathname = p + 1;
+        *buffer = '\0';
+    }
+}
+
 /* Build a machine dependent library name out of a path and file name.  */
 void
 md_build_library_name(char *holder, int holderlen, char *pname, char *fname)
 {
     int   pnamelen;
-    char  c;
 
     pnamelen = pname ? (int)strlen(pname) : 0;
-    c = (pnamelen > 0) ? pname[pnamelen-1] : 0;
 
+    *holder = '\0';
     /* Quietly truncates on buffer overflow. Should be an error. */
     if (pnamelen + strlen(fname) + 10 > (unsigned int)holderlen) {
-        *holder = '\0';
         return;
     }
 
     if (pnamelen == 0) {
         sprintf(holder, "%s.dll", fname);
-    } else if (c == ':' || c == '\\') {
-        sprintf(holder, "%s%s.dll", pname, fname);
     } else {
-        sprintf(holder, "%s\\%s.dll", pname, fname);
+      dll_build_name(holder, holderlen, pname, fname);
     }
 }
 
diff --git a/jdk/src/windows/lib/content-types.properties b/jdk/src/windows/lib/content-types.properties
index 1cbfcbd..8949352 100644
--- a/jdk/src/windows/lib/content-types.properties
+++ b/jdk/src/windows/lib/content-types.properties
@@ -222,6 +222,10 @@
 	icon=png;\
 	action=browser
 
+image/bmp: \
+	description=Bitmap Image;\
+	file_extensions=.bmp;
+
 text/html: \
 	description=HTML Document;\
 	file_extensions=.htm,.html;\
diff --git a/jdk/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c b/jdk/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
index 6521e1e..0077c37 100644
--- a/jdk/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
+++ b/jdk/src/windows/native/java/net/DualStackPlainDatagramSocketImpl.c
@@ -265,7 +265,7 @@
         }
         fullPacket = (char *)malloc(packetBufferLen);
         if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
             return -1;
         }
     } else {
@@ -427,7 +427,7 @@
         }
         fullPacket = (char *)malloc(length);
         if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
             return;
         }
     } else {
diff --git a/jdk/src/windows/native/java/net/Inet6AddressImpl.c b/jdk/src/windows/native/java/net/Inet6AddressImpl.c
index efdcd54..b98b641 100644
--- a/jdk/src/windows/native/java/net/Inet6AddressImpl.c
+++ b/jdk/src/windows/native/java/net/Inet6AddressImpl.c
@@ -197,7 +197,7 @@
                 struct addrinfo *next
                     = (struct addrinfo*) malloc(sizeof(struct addrinfo));
                 if (!next) {
-                    JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+                    JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
                     ret = NULL;
                     goto cleanupAndReturn;
                 }
diff --git a/jdk/src/windows/native/java/net/NetworkInterface.c b/jdk/src/windows/native/java/net/NetworkInterface.c
index fa5dfc1..2dc3d23 100644
--- a/jdk/src/windows/native/java/net/NetworkInterface.c
+++ b/jdk/src/windows/native/java/net/NetworkInterface.c
@@ -266,7 +266,7 @@
             }
         }
         if (curr == NULL) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
+            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
             free_netif(netifP);
             free(tableP);
             return -1;
@@ -366,7 +366,7 @@
 
             netaddr *curr = (netaddr *)malloc(sizeof(netaddr));
             if (curr == NULL) {
-                JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
+                JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
                 free_netaddr(netaddrP);
                 free(tableP);
                 return -1;
@@ -504,8 +504,7 @@
      */
     if (netaddrCount < 0) {
         netaddrCount = enumAddresses_win(env, ifs, &netaddrP);
-        if ((*env)->ExceptionOccurred(env)) {
-            free_netaddr(netaddrP);
+        if (netaddrCount == -1) {
             return NULL;
         }
     }
diff --git a/jdk/src/windows/native/java/net/NetworkInterface_winXP.c b/jdk/src/windows/native/java/net/NetworkInterface_winXP.c
index ecfab49..9b624cd 100644
--- a/jdk/src/windows/native/java/net/NetworkInterface_winXP.c
+++ b/jdk/src/windows/native/java/net/NetworkInterface_winXP.c
@@ -194,8 +194,7 @@
     while (curr != NULL) {
         netaddr *netaddrP;
         ret = enumAddresses_win(env, curr, &netaddrP);
-        if ((*env)->ExceptionOccurred(env)) {
-            free_netaddr(netaddrP);
+        if (ret == -1) {
             return -1;
         }
         curr->addrs = netaddrP;
@@ -449,8 +448,7 @@
      */
     if (netaddrCount < 0) {
         netaddrCount = enumAddresses_win(env, ifs, &netaddrP);
-        if ((*env)->ExceptionOccurred(env)) {
-            free_netaddr(netaddrP);
+        if (netaddrCount == -1) {
             return NULL;
         }
     }
diff --git a/jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c b/jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
index 5ca6736..5654f0b 100644
--- a/jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
+++ b/jdk/src/windows/native/java/net/TwoStacksPlainDatagramSocketImpl.c
@@ -243,7 +243,7 @@
                                 addrList = curr;
                             }
                             LeaveCriticalSection(&sizeCheckLock);
-                            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+                            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
                             return JNI_TRUE;
                         }
                         curr->addr = htonl((*addrp)->S_un.S_addr);
@@ -740,7 +740,7 @@
          */
         fullPacket = (char *)malloc(packetBufferLen);
         if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+            JNU_ThrowOutOfMemoryError(env, "Send buf native heap allocation failed");
             return;
         }
     } else {
@@ -1003,7 +1003,7 @@
          */
         fullPacket = (char *)malloc(packetBufferLen);
         if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failed");
             return -1;
         }
     } else {
@@ -1287,7 +1287,7 @@
          */
         fullPacket = (char *)malloc(packetBufferLen);
         if (!fullPacket) {
-            JNU_ThrowOutOfMemoryError(env, "heap allocation failed");
+            JNU_ThrowOutOfMemoryError(env, "Receive buf native heap allocation failed");
             return;
         }
     } else {
diff --git a/jdk/src/windows/native/java/util/TimeZone_md.c b/jdk/src/windows/native/java/util/TimeZone_md.c
index 5abc61c..d29558c 100644
--- a/jdk/src/windows/native/java/util/TimeZone_md.c
+++ b/jdk/src/windows/native/java/util/TimeZone_md.c
@@ -165,6 +165,7 @@
     WCHAR *stdNamePtr = tzi.StandardName;
     DWORD valueSize;
     DWORD timeType;
+    int isVista;
 
     /*
      * Get the current time zone setting of the platform.
@@ -180,6 +181,7 @@
     ver.dwOSVersionInfoSize = sizeof(ver);
     GetVersionEx(&ver);
     isNT = ver.dwPlatformId == VER_PLATFORM_WIN32_NT;
+    isVista = isNT && ver.dwMajorVersion >= 6;
 
     ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_CURRENT_TZ_KEY, 0,
                        KEY_READ, (PHKEY)&hKey);
@@ -202,8 +204,13 @@
             ret = RegQueryValueExA(hKey, "DynamicDaylightTimeDisabled",
                                    NULL, &valueType, (LPBYTE) &val, &bufSize);
         }
+
         if (ret == ERROR_SUCCESS) {
-            if (val == 1) {
+            int daylightSavingsUpdateDisabledOther = val == 1 && tzi.DaylightDate.wMonth != 0;
+            int daylightSavingsUpdateDisabledVista = val == 1;
+            int daylightSavingsUpdateDisabled = isVista ? daylightSavingsUpdateDisabledVista : daylightSavingsUpdateDisabledOther;
+
+            if (daylightSavingsUpdateDisabled) {
                 (void) RegCloseKey(hKey);
                 customZoneName(tzi.Bias, winZoneName);
                 return VALUE_GMTOFFSET;
@@ -213,7 +220,7 @@
         /*
          * Vista has the key for the current "Time Zones" entry.
          */
-        if (isNT && ver.dwMajorVersion >= 6) {
+        if (isVista) {
             valueType = 0;
             bufSize = MAX_ZONE_CHAR;
             ret = RegQueryValueExA(hKey, "TimeZoneKeyName", NULL,
diff --git a/jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c b/jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
index 8df4b94..555ca9f 100644
--- a/jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
+++ b/jdk/src/windows/native/sun/nio/ch/DatagramChannelImpl.c
@@ -108,7 +108,7 @@
 
 JNIEXPORT void JNICALL
 Java_sun_nio_ch_DatagramChannelImpl_disconnect0(JNIEnv *env, jobject this,
-                                                jobject fdo)
+                                                jobject fdo, jboolean isIPv6)
 {
     jint fd = fdval(env, fdo);
     int rv = 0;
diff --git a/jdk/src/windows/native/sun/windows/awt_Component.cpp b/jdk/src/windows/native/sun/windows/awt_Component.cpp
index 221e81b..fab5efb 100644
--- a/jdk/src/windows/native/sun/windows/awt_Component.cpp
+++ b/jdk/src/windows/native/sun/windows/awt_Component.cpp
@@ -558,6 +558,8 @@
 
     m_hwnd = hwnd;
 
+    ::ImmAssociateContext(m_hwnd, NULL);
+
     SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED |
         (jint)JAWT_LOCK_BOUNDS_CHANGED |
         (jint)JAWT_LOCK_CLIP_CHANGED);
@@ -3142,7 +3144,8 @@
     return;
 }
 
-UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers)
+UINT AwtComponent::WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey)
+
 {
     // Handle the few cases where we need to take the modifier into
     // consideration for the Java VK code or where we have to take the keyboard
@@ -3169,6 +3172,15 @@
             break;
     };
 
+    // check dead key
+    if (isDeadKey) {
+      for (int i = 0; charToDeadVKTable[i].c != 0; i++) {
+        if (charToDeadVKTable[i].c == character) {
+            return charToDeadVKTable[i].javaKey;
+        }
+      }
+    }
+
     // for the general case, use a bi-directional table
     for (int i = 0; keyMapTable[i].windowsKey != 0; i++) {
         if (keyMapTable[i].windowsKey == windowsKey) {
@@ -3382,14 +3394,18 @@
     }
 }
 
-UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops)
+UINT AwtComponent::WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey)
 {
     static Hashtable transTable("VKEY translations");
+    static Hashtable deadKeyFlagTable("Dead Key Flags");
+    isDeadKey = FALSE;
 
     // Try to translate using last saved translation
     if (ops == LOAD) {
+       void* deadKeyFlag = deadKeyFlagTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
        void* value = transTable.remove(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)));
        if (value != NULL) {
+           isDeadKey = static_cast<BOOL>(reinterpret_cast<INT_PTR>(deadKeyFlag));
            return static_cast<UINT>(reinterpret_cast<INT_PTR>(value));
        }
     }
@@ -3482,12 +3498,13 @@
 
     // instead of creating our own conversion tables, I'll let Win32
     // convert the character for me.
-    WORD mbChar;
+    WORD wChar[2];
     UINT scancode = ::MapVirtualKey(wkey, 0);
-    int converted = ::ToAsciiEx(wkey, scancode, keyboardState,
-                                &mbChar, 0, GetKeyboardLayout());
+    int converted = ::ToUnicodeEx(wkey, scancode, keyboardState,
+                                  wChar, 2, 0, GetKeyboardLayout());
 
     UINT translation;
+    BOOL deadKeyFlag = (converted == 2);
 
     // Dead Key
     if (converted < 0) {
@@ -3506,16 +3523,16 @@
     } else
     // the caller expects a Unicode character.
     if (converted > 0) {
-        WCHAR unicodeChar[2];
-        VERIFY(::MultiByteToWideChar(GetCodePage(), MB_PRECOMPOSED,
-        (LPCSTR)&mbChar, 1, unicodeChar, 1));
-
-        translation = unicodeChar[0];
+        translation = wChar[0];
     }
     if (ops == SAVE) {
         transTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
                        reinterpret_cast<void*>(static_cast<INT_PTR>(translation)));
+        deadKeyFlagTable.put(reinterpret_cast<void*>(static_cast<INT_PTR>(wkey)),
+                       reinterpret_cast<void*>(static_cast<INT_PTR>(deadKeyFlag)));
     }
+
+    isDeadKey = deadKeyFlag;
     return translation;
 }
 
@@ -3535,8 +3552,9 @@
 
     UINT modifiers = GetJavaModifiers();
     jint keyLocation = GetKeyLocation(wkey, flags);
-    UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
-    UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE);
+    BOOL isDeadKey = FALSE;
+    UINT character = WindowsKeyToJavaChar(wkey, modifiers, SAVE, isDeadKey);
+    UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
 
 
@@ -3577,8 +3595,9 @@
 
     UINT modifiers = GetJavaModifiers();
     jint keyLocation = GetKeyLocation(wkey, flags);
-    UINT jkey = WindowsKeyToJavaKey(wkey, modifiers);
-    UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD);
+    BOOL isDeadKey = FALSE;
+    UINT character = WindowsKeyToJavaChar(wkey, modifiers, LOAD, isDeadKey);
+    UINT jkey = WindowsKeyToJavaKey(wkey, modifiers, character, isDeadKey);
     UpdateDynPrimaryKeymap(wkey, jkey, keyLocation, modifiers);
 
     SendKeyEventToFocusOwner(java_awt_event_KeyEvent_KEY_RELEASED,
@@ -5626,7 +5645,8 @@
                         }
                     }
 
-                    modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE);
+                    BOOL isDeadKey = FALSE;
+                    modifiedChar = p->WindowsKeyToJavaChar(winKey, modifiers, AwtComponent::NONE, isDeadKey);
                     bCharChanged = (keyChar != modifiedChar);
                 }
                 break;
diff --git a/jdk/src/windows/native/sun/windows/awt_Component.h b/jdk/src/windows/native/sun/windows/awt_Component.h
index d96f438..bb29d83 100644
--- a/jdk/src/windows/native/sun/windows/awt_Component.h
+++ b/jdk/src/windows/native/sun/windows/awt_Component.h
@@ -441,7 +441,7 @@
     static jint GetJavaModifiers();
     static jint GetButton(int mouseButton);
     static UINT GetButtonMK(int mouseButton);
-    static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers);
+    static UINT WindowsKeyToJavaKey(UINT windowsKey, UINT modifiers, UINT character, BOOL isDeadKey);
     static void JavaKeyToWindowsKey(UINT javaKey, UINT *windowsKey, UINT *modifiers, UINT originalWindowsKey);
     static void UpdateDynPrimaryKeymap(UINT wkey, UINT jkeyLegacy, jint keyLocation, UINT modifiers);
 
@@ -453,7 +453,7 @@
 
     enum TransOps {NONE, LOAD, SAVE};
 
-    UINT WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops);
+    UINT WindowsKeyToJavaChar(UINT wkey, UINT modifiers, TransOps ops, BOOL &isDeadKey);
 
     /* routines used for input method support */
     void SetInputMethod(jobject im, BOOL useNativeCompWindow);
diff --git a/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp b/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp
index e661aa0..b2d12c0 100644
--- a/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp
+++ b/jdk/src/windows/native/sun/windows/awt_InputMethod.cpp
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
@@ -517,10 +517,10 @@
     jstring infojStr = NULL;
 
     if ((buffSize = ::ImmGetDescription(hkl, szImmDescription, 0)) > 0) {
-        szImmDescription = (LPTSTR) safe_Malloc(buffSize * sizeof(TCHAR));
+        szImmDescription = (LPTSTR) safe_Malloc((buffSize+1) * sizeof(TCHAR));
 
         if (szImmDescription != NULL) {
-            ImmGetDescription(hkl, szImmDescription, buffSize);
+            ImmGetDescription(hkl, szImmDescription, (buffSize+1));
 
             infojStr = JNU_NewStringPlatform(env, szImmDescription);
 
diff --git a/jdk/src/windows/native/sun/windows/awt_TextField.cpp b/jdk/src/windows/native/sun/windows/awt_TextField.cpp
index 4ccb64d..b9edfbf 100644
--- a/jdk/src/windows/native/sun/windows/awt_TextField.cpp
+++ b/jdk/src/windows/native/sun/windows/awt_TextField.cpp
@@ -75,6 +75,7 @@
 AwtTextField::HandleEvent(MSG *msg, BOOL synthetic)
 {
     MsgRouting returnVal;
+    BOOL systemBeeperEnabled = FALSE;
     /*
      * RichEdit 1.0 control starts internal message loop if the
      * left mouse button is pressed while the cursor is not over
@@ -217,6 +218,25 @@
         }
         delete msg;
         return mrConsume;
+    } else if (msg->message == WM_KEYDOWN) {
+        UINT virtualKey = (UINT) msg->wParam;
+
+        switch(virtualKey){
+          case VK_RETURN:
+          case VK_UP:
+          case VK_DOWN:
+          case VK_LEFT:
+          case VK_RIGHT:
+          case VK_DELETE:
+          case VK_BACK:
+              SystemParametersInfo(SPI_GETBEEP, 0, &systemBeeperEnabled, 0);
+              if(systemBeeperEnabled){
+                  // disable system beeper for the RICHEDIT control to be compatible
+                  // with the EDIT control behaviour
+                  SystemParametersInfo(SPI_SETBEEP, 0, NULL, 0);
+              }
+              break;
+          }
     }
     /*
      * Store the 'synthetic' parameter so that the WM_PASTE security check
@@ -226,6 +246,10 @@
     returnVal = AwtComponent::HandleEvent(msg, synthetic);
     m_synthetic = FALSE;
 
+    if(systemBeeperEnabled){
+      SystemParametersInfo(SPI_SETBEEP, 1, NULL, 0);
+    }
+
     return returnVal;
 }
 
diff --git a/jdk/src/windows/npt/npt_md.h b/jdk/src/windows/npt/npt_md.h
index 4cf2176..e4e5dc3 100644
--- a/jdk/src/windows/npt/npt_md.h
+++ b/jdk/src/windows/npt/npt_md.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,30 +33,16 @@
 #include <string.h>
 #include <errno.h>
 
-#define NPT_LIBNAME "npt.dll"
+#define NPT_LIBNAME "npt"
 
-#define NPT_INITIALIZE(pnpt,version,options)                            \
+#define NPT_INITIALIZE(path,pnpt,version,options)                       \
     {                                                                   \
-        HINSTANCE jvm;                                                  \
         void   *_handle;                                                \
         void   *_sym;                                                   \
-        char    buf[FILENAME_MAX+32];                                   \
-        char   *lastSlash;                                              \
                                                                         \
         if ( (pnpt) == NULL ) NPT_ERROR("NptEnv* is NULL");             \
-        _handle =  NULL;                                                \
         *(pnpt) = NULL;                                                 \
-        buf[0] = 0;                                                     \
-        jvm = GetModuleHandle("jvm.dll");                               \
-        if ( jvm == NULL ) NPT_ERROR("Cannot find jvm.dll");            \
-        GetModuleFileName(jvm, buf, FILENAME_MAX);                      \
-        lastSlash = strrchr(buf, '\\');                                 \
-        if ( lastSlash != NULL ) {                                      \
-            *lastSlash = '\0';                                          \
-            (void)strcat(buf, "\\..\\");                                \
-            (void)strcat(buf, NPT_LIBNAME);                             \
-            _handle =  LoadLibrary(buf);                                \
-        }                                                               \
+        _handle =  LoadLibrary(path);                                   \
         if ( _handle == NULL ) NPT_ERROR("Cannot open library");        \
         _sym = GetProcAddress(_handle, "nptInitialize");                \
         if ( _sym == NULL ) NPT_ERROR("Cannot find nptInitialize");     \
diff --git a/jdk/test/Makefile b/jdk/test/Makefile
index 1be9043..0963ef8 100644
--- a/jdk/test/Makefile
+++ b/jdk/test/Makefile
@@ -484,71 +484,61 @@
 
 # Stable agentvm testruns (minus items from PROBLEM_LIST)
 JDK_ALL_TARGETS += jdk_lang
-jdk_lang: $(call TestDirs, java/lang)
+jdk_lang: $(call TestDirs, java/lang sun/invoke sun/misc vm)
 	$(call RunAgentvmBatch)
 
 # Stable othervm testruns (minus items from PROBLEM_LIST)
 #   Using agentvm has serious problems with these tests
-JDK_ALL_TARGETS += jdk_management1
-jdk_management1: $(call TestDirs, javax/management)
+JDK_ALL_TARGETS += jdk_jmx
+jdk_jmx: $(call TestDirs, javax/management com/sun/jmx)
 	$(call RunOthervmBatch)
 
 # Stable othervm testruns (minus items from PROBLEM_LIST)
 #   Using agentvm has serious problems with these tests
-JDK_ALL_TARGETS += jdk_management2
-jdk_management2: $(call TestDirs, com/sun/jmx com/sun/management sun/management)
+JDK_ALL_TARGETS += jdk_management
+jdk_management: $(call TestDirs, com/sun/management sun/management)
 	$(call RunOthervmBatch)
 
-# All management tests
-jdk_management: jdk_management1 jdk_management2
-	@$(SummaryInfo)
-
 # Stable samevm testruns (minus items from PROBLEM_LIST)
 JDK_ALL_TARGETS += jdk_math
 jdk_math: $(call TestDirs, java/math)
 	$(call RunAgentvmBatch)
 
 # Stable samevm testruns (minus items from PROBLEM_LIST)
-JDK_ALL_TARGETS += jdk_misc
-jdk_misc: $(call TestDirs, \
-          demo/jvmti demo/zipfs javax/naming javax/script \
-          javax/smartcardio com/sun/jndi com/sun/xml sun/misc)
+JDK_ALL_TARGETS += jdk_other
+jdk_other: $(call TestDirs, \
+          demo/jvmti demo/zipfs \
+          javax/naming com/sun/jndi \
+          javax/script \
+          java/sql javax/sql \
+          javax/smartcardio \
+          com/sun/xml \
+          javax/xml/ws com/sun/internal/ws \
+          com/sun/org/apache/xerces \
+          com/sun/corba \
+          com/sun/servicetag \
+          com/sun/tracing \
+          sun/usagetracker) 
 	$(call RunAgentvmBatch)
 
 # Stable samevm testruns (minus items from PROBLEM_LIST)
 JDK_ALL_TARGETS += jdk_net
-jdk_net: $(call TestDirs, com/sun/net java/net sun/net)
+jdk_net: $(call TestDirs, com/sun/net java/net sun/net com/oracle/net)
 	$(call RunAgentvmBatch)
 
 # Stable samevm testruns (minus items from PROBLEM_LIST)
-JDK_ALL_TARGETS += jdk_nio1
-jdk_nio1: $(call TestDirs, java/nio/file)
-	$(call RunAgentvmBatch)
-
-# Stable samevm testruns (minus items from PROBLEM_LIST)
-JDK_ALL_TARGETS += jdk_nio2
-jdk_nio2: $(call TestDirs, java/nio/Buffer java/nio/ByteOrder \
-          java/nio/channels java/nio/MappedByteBuffer)
+jdk_nio: $(call TestDirs, java/nio sun/nio com/oracle/nio)
 	$(call SharedLibraryPermissions,java/nio/channels)
 	$(call RunAgentvmBatch)
 
 # Stable samevm testruns (minus items from PROBLEM_LIST)
-JDK_ALL_TARGETS += jdk_nio3
-jdk_nio3: $(call TestDirs, sun/nio)
-	$(call RunAgentvmBatch)
-
-# All nio tests
-jdk_nio: jdk_nio1 jdk_nio2 jdk_nio3
-	@$(SummaryInfo)
-
-# Stable samevm testruns (minus items from PROBLEM_LIST)
 jdk_sctp: $(call TestDirs, com/sun/nio/sctp)
 	$(call RunAgentvmBatch)
 
 # Stable othervm testruns (minus items from PROBLEM_LIST)
 #   Using samevm has serious problems with these tests
 JDK_ALL_TARGETS += jdk_rmi
-jdk_rmi: $(call TestDirs, java/rmi javax/rmi sun/rmi)
+jdk_rmi: $(call TestDirs, java/rmi sun/rmi javax/rmi/ssl)
 	$(call RunOthervmBatch)
 
 # Stable samevm testruns (minus items from PROBLEM_LIST)
@@ -560,17 +550,17 @@
 #   Using samevm has serious problems with these tests
 JDK_ALL_TARGETS += jdk_security2
 jdk_security2: $(call TestDirs, javax/crypto com/sun/crypto)
-	$(call RunOthervmBatch)
+	$(call RunAgentvmBatch)
 
 # Stable othervm testruns (minus items from PROBLEM_LIST)
 #   Using samevm has serious problems with these tests
 JDK_ALL_TARGETS += jdk_security3
 jdk_security3: $(call TestDirs, com/sun/security lib/security \
-               javax/security sun/security \
-               com/sun/org/apache/xml/internal/security \
-               com/oracle/security/ucrypto)
+		javax/security sun/security \
+		com/sun/org/apache/xml/internal/security \
+		com/oracle/security)
 	$(call SharedLibraryPermissions,sun/security)
-	$(call RunOthervmBatch)
+	$(call RunAgentvmBatch)
 
 # All security tests
 jdk_security: jdk_security1 jdk_security2 jdk_security3
@@ -594,23 +584,19 @@
 	$(call RunAgentvmBatch)
 
 # Stable samevm testruns (minus items from PROBLEM_LIST)
-JDK_ALL_TARGETS += jdk_tools1
-jdk_tools1: $(call TestDirs, com/sun/jdi)
+JDK_ALL_TARGETS += jdk_jdi
+jdk_jdi: $(call TestDirs, com/sun/jdi)
 	$(call RunAgentvmBatch)
 
 # Stable othervm testruns (minus items from PROBLEM_LIST)
 #   Using samevm has serious problems with these tests
-JDK_ALL_TARGETS += jdk_tools2
-jdk_tools2: $(call TestDirs, \
-            com/sun/tools sun/jvmstat sun/tools tools vm \
-            com/sun/servicetag com/sun/tracing)
+JDK_ALL_TARGETS += jdk_tools
+jdk_tools: $(call TestDirs, \
+		com/sun/tools sun/jvmstat sun/tools tools \
+		com/sun/servicetag com/sun/tracing)
 	$(call SharedLibraryPermissions,tools/launcher)
 	$(call RunAgentvmBatch)
 
-# All tools tests
-jdk_tools: jdk_tools1 jdk_tools2
-	@$(SummaryInfo)
-
 # Stable samevm testruns (minus items from PROBLEM_LIST)
 JDK_ALL_TARGETS += jdk_util
 jdk_util: $(call TestDirs, java/util sun/util)
@@ -834,17 +820,17 @@
 # The jtjck.jar utility to use to run the tests
 JTJCK_JAR = $(JCK_HOME)/lib/jtjck.jar
 JTJCK_JAVA_ARGS =  -XX:MaxPermSize=256m -Xmx512m
-JTJCK_OPTIONS = -headless -v 
+JTJCK_OPTIONS = -headless -v
 
 # Default tests to run
 ifndef JCK_COMPILER_TESTS
-  JCK_COMPILER_TESTS = 
+  JCK_COMPILER_TESTS =
 endif
 ifndef JCK_RUNTIME_TESTS
-  JCK_RUNTIME_TESTS  = 
+  JCK_RUNTIME_TESTS  =
 endif
 ifndef JCK_DEVTOOLS_TESTS
-  JCK_DEVTOOLS_TESTS = 
+  JCK_DEVTOOLS_TESTS =
 endif
 
 # Generic rule used to run jck tests
@@ -870,14 +856,14 @@
                 _generic_jck_tests
 
 # JCK7 runtime tests
-jck7runtime: 
+jck7runtime:
 	$(MAKE) UNIQUE_DIR=$@ \
 	        JCK_HOME=$(JCK7RUNTIME_HOME) \
 	        TESTDIRS="$(JCK_RUNTIME_TESTS)" \
                 _generic_jck_tests
 
 # JCK7 devtools tests
-jck7devtools: 
+jck7devtools:
 	$(MAKE) UNIQUE_DIR=$@ \
 	        JCK_HOME=$(JCK7DEVTOOLS_HOME) \
                 TESTDIRS="$(JCK_DEVTOOLS_TESTS)" \
diff --git a/jdk/test/ProblemList.txt b/jdk/test/ProblemList.txt
index c64bccf..fe313f4 100644
--- a/jdk/test/ProblemList.txt
+++ b/jdk/test/ProblemList.txt
@@ -1,6 +1,6 @@
 ###########################################################################
 #
-# Copyright (c) 2009, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, 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
@@ -144,18 +144,44 @@
 
 # jdk_management
 
-# Failing, bug was filed: 6959636
-javax/management/loading/LibraryLoader/LibraryLoaderTest.java   generic-all
-
 # Access denied messages on windows/mks, filed 6954450
 sun/management/jmxremote/bootstrap/RmiSslNoKeyStoreTest.sh      windows-all
 
-# Fails on linux: KO: StringMonitor notification missed or not emitted
-javax/management/monitor/NonComparableAttributeValueTest.java   generic-all
-
 # Port conflict? Fails with communication error
 sun/management/jmxremote/bootstrap/PasswordFilePermissionTest.sh generic-all
 
+# Fails with port already in use
+sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.sh generic-all
+
+# Fails with port already in use
+sun/management/jmxremote/bootstrap/RmiRegistrySslTest.sh        generic-all
+
+# Windows run seems to have triggered a hotspot gc error (see 6801625)
+com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.sh          generic-all
+
+# Port already in use
+sun/management/jmxremote/bootstrap/LocalManagementTest.sh       generic-all
+
+# Failed to initialize connector (also overflowing jtreg io buffers)
+sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh          generic-all
+sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh       generic-all
+
+# Windows X64, java.lang.IllegalStateException
+javax/management/monitor/AttributeArbitraryDataTypeTest.java    generic-all
+
+# 7149181
+sun/management/jmxremote/startstop/JMXStartStopTest.sh          generic-all
+
+############################################################################
+
+# jdk_jmx
+
+# Failing, bug was filed: 6959636
+javax/management/loading/LibraryLoader/LibraryLoaderTest.java   generic-all
+
+# Fails on linux: KO: StringMonitor notification missed or not emitted
+javax/management/monitor/NonComparableAttributeValueTest.java   generic-all
+
 # Fails on Windows 2000, Test failed for iiop java.lang.NullPointerException
 #  at org.omg.stub.javax.management.remote.rmi._RMIConnectionImpl_Tie._invoke(Unknown Source)
 #  at com.sun.corba.se.impl.protocol.CorbaServerRequestDispatcherImpl.dispatchToServant(CorbaServerRequestDispatcherImpl.java:653)
@@ -170,21 +196,12 @@
 # Problems with rmi connection, othervm
 javax/management/remote/mandatory/subjectDelegation/SubjectDelegation2Test.java generic-all
 
-# Fails with port already in use
-sun/management/jmxremote/bootstrap/SSLConfigFilePermissionTest.sh generic-all
-
-# Fails with port already in use
-sun/management/jmxremote/bootstrap/RmiRegistrySslTest.sh        generic-all
-
 # Windows, connection can't last that long
 javax/management/eventService/LeaseTest.java                    generic-all
 
 # Linux othervm, X64, java.lang.Exception: Failed: ratio=102.4027795593753
 javax/management/remote/mandatory/notif/ListenerScaleTest.java  generic-all
 
-# Windows run seems to have triggered a hotspot gc error (see 6801625)
-com/sun/management/HotSpotDiagnosticMXBean/DumpHeap.sh          generic-all
-
 # rmi problem? othervm, java.lang.reflect.UndeclaredThrowableException
 javax/management/remote/mandatory/subjectDelegation/SubjectDelegation3Test.java generic-all
 
@@ -207,26 +224,13 @@
 # Windows i586 failure, callback did not complete
 javax/management/eventService/LeaseManagerDeadlockTest.java     windows-all
 
-# Port already in use
-sun/management/jmxremote/bootstrap/LocalManagementTest.sh       generic-all
-
-# Failed to initialize connector (also overflowing jtreg io buffers)
-sun/management/jmxremote/bootstrap/RmiBootstrapTest.sh          generic-all
-sun/management/jmxremote/bootstrap/RmiSslBootstrapTest.sh       generic-all
-
-# Windows X64, java.lang.IllegalStateException
-javax/management/monitor/AttributeArbitraryDataTypeTest.java    generic-all
-
-# 7149181 
-sun/management/jmxremote/startstop/JMXStartStopTest.sh          generic-all
-
 ############################################################################
 
 # jdk_math
 
 ############################################################################
 
-# jdk_misc
+# jdk_other
 
 # 6988950
 demo/jvmti/compiledMethodLoad/CompiledMethodLoadTest.java       generic-all
@@ -297,6 +301,11 @@
 # 6962637
 java/io/File/MaxPathLength.java                                 windows-all
 
+# 7162111 - these tests need to be updated to run headless
+java/io/Serializable/resolveClass/deserializeButton/run.sh      macosx-all
+java/io/Serializable/serialver/classpath/run.sh                 macosx-all
+java/io/Serializable/serialver/nested/run.sh                    macosx-all
+
 ############################################################################
 
 # jdk_nio
@@ -336,9 +345,6 @@
 # Registry already running on port, solaris
 java/rmi/Naming/legalRegistryNames/LegalRegistryNames.java      generic-all
 
-# Fails on Linux 32 and 64bit -server?, impl not garbage collected???
-java/rmi/transport/pinLastArguments/PinLastArguments.java       generic-all
-
 # 7146541
 java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java	linux-all
 
@@ -378,7 +384,6 @@
 java/rmi/activation/CommandEnvironment/SetChildEnv.java generic-all
 java/rmi/registry/classPathCodebase/ClassPathCodebase.java generic-all
 java/rmi/registry/reexport/Reexport.java generic-all
-java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java generic-all
 java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java generic-all
 java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java generic-all
 java/rmi/server/useCustomRef/UseCustomRef.java generic-all
@@ -395,77 +400,20 @@
 
 # jdk_security
 
-# Filed 6986868
-sun/security/tools/jarsigner/crl.sh                             generic-all
-
-# Filed 6951285, not sure how often this fails, last was Linux 64bit Fedora 9
-sun/security/krb5/auto/MaxRetries.java                          generic-all
-
-# Filed 6950930, fails on windows 32bit c1 and windows 64bit
-sun/security/krb5/auto/IgnoreChannelBinding.java                windows-all
-
-# Filed 6950931, failing on all windows systems
-sun/security/tools/jarsigner/crl.sh                             windows-all
-
-# Filed 6950929, only seemed to fail on solaris sparcv9 (-d64)
-#   Failed on Linux -server 32bit too, making generic
-sun/security/krb5/auto/BadKdc4.java                             generic-all
-
 # Failing on Solaris i586, 3/9/2010, not a -samevm issue (jdk_security3)
 sun/security/pkcs11/Secmod/AddPrivateKey.java                   solaris-i586
 sun/security/pkcs11/ec/ReadCertificates.java                    solaris-i586
 sun/security/pkcs11/ec/ReadPKCS12.java                          solaris-i586
 sun/security/pkcs11/ec/TestCurves.java                          solaris-i586
 sun/security/pkcs11/ec/TestECDSA.java                           solaris-i586
-sun/security/pkcs11/ec/TestECGenSpec.java                       solaris-i586
-sun/security/pkcs11/ec/TestKeyFactory.java                      solaris-i586
+#sun/security/pkcs11/ec/TestECGenSpec.java                       solaris-i586
+#sun/security/pkcs11/ec/TestKeyFactory.java                      solaris-i586
+sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java            generic-all
 
-# Unknown problem, could be a jtreg -samevm issue?
-#  Error while cleaning up threads after test
-java/security/Security/SynchronizedAccess.java                  generic-all
+# Directly references PKCS11 class
+sun/security/pkcs11/Provider/Absolute.java                      windows-x64
 
-# Failing on Solaris X64 (-d64 -server) with:
-#  GSSException: Failure unspecified at GSS-API level
-#    (Mechanism level: Specified version of key is not available (44))
-sun/security/krb5/auto/BasicKrb5Test.java                       generic-all
-
-# Solaris X86 failures, readjar.jks: No such file or directory
-sun/security/tools/keytool/readjar.sh                           generic-all
-
-# Fails with -ea -esa, but only on Solaris sparc? Suspect it is timing out
-sun/security/tools/keytool/standard.sh                          generic-all
-
-# Fails on Solaris 10 X64, address already in use
-sun/security/krb5/auto/HttpNegotiateServer.java                 generic-all
-
-# Fails on almost all platforms
-#   java.lang.UnsupportedClassVersionError: SerialTest :
-#      Unsupported major.minor version 51.0
-#    at java.lang.ClassLoader.defineClass1(Native Method)
-sun/security/util/Oid/S11N.sh                                   generic-all
-
-# Fails on Fedora 9 32bit
-#  GSSException: Failure unspecified at GSS-API level (Mechanism level:
-#    Invalid argument (400) - Cannot find key of appropriate type to decrypt
-#    AP REP - DES CBC mode with MD5)
-#  at sun.security.jgss.krb5.Krb5Context.acceptSecContext(Krb5Context.java:778)
-sun/security/krb5/auto/NonMutualSpnego.java                     generic-all
-
-# Fails on Solaris 10 sparc, GSSException: Failure unspecified at GSS-API level
-#   Also fails on Windows 2000 similar way
-sun/security/krb5/auto/ok-as-delegate.sh                        generic-all
-
-# Fails on Windows 2000, GSSException: Failure unspecified at GSS-API level
-#    (Mechanism level: Request is a replay (34))
-sun/security/krb5/auto/ok-as-delegate-xrealm.sh                 generic-all
-
-# Fails on Windows 2000, ExceptionInInitializerError
-sun/security/mscapi/AccessKeyStore.sh                           generic-all
-
-# Fails on Solaris 10, KrbException: Additional pre-authentication required (25)
-sun/security/krb5/auto/basic.sh                                 generic-all
-
-# Fails on Fedora 9 64bit, PKCS11Exception: CKR_DEVICE_ERROR
+# Fails on Fedora 9/Ubuntu 10.04 64bit, PKCS11Exception: CKR_DEVICE_ERROR
 sun/security/pkcs11/KeyAgreement/TestDH.java                    generic-all
 
 # Run too slow on Solaris 10 sparc
@@ -474,18 +422,10 @@
 sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ServerTimeout.java solaris-sparc
 sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java solaris-sparc
 sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NotifyHandshakeTest.sh solaris-sparc
-sun/security/tools/keytool/AltProviderPath.sh                   solaris-sparc
 
 # Solaris 10 sparc, passed/failed confusion? java.security.ProviderException: update() failed
 sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java generic-all
 
-# Seem really slow on Solaris sparc, being excluded just for timing reasons
-sun/security/tools/jarsigner/AlgOptions.sh                      solaris-sparc
-sun/security/tools/jarsigner/nameclash.sh                       solaris-sparc
-sun/security/krb5/auto/basic.sh                                 solaris-sparc
-sun/security/provider/PolicyFile/getinstance/getinstance.sh     solaris-sparc
-sun/security/tools/jarsigner/samename.sh                        solaris-sparc
-
 # Timed out, Solaris 10 64bit sparcv9
 com/sun/crypto/provider/Cipher/DES/PaddingTest.java             generic-all
 
@@ -496,79 +436,19 @@
 #    Solaris sparc and sparcv9 -server, timeout
 sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java generic-all
 
-# Failed on solaris 10 sparc, othervm mode,  "js.jks: No such file or directory"
-#  Also, cannot verify signature on solaris i586 -server
-sun/security/tools/jarsigner/concise_jarsigner.sh               generic-all
-
 # Various failures on Linux Fedora 9 X64, othervm mode
 sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/TestAllSuites.java generic-all
 sun/security/ssl/sanity/ciphersuites/CheckCipherSuites.java     generic-all
-sun/security/tools/jarsigner/oldsig.sh                          generic-all
 
 # Various failures on Linux Fedora 9 X64, othervm mode
 sun/security/ssl/sanity/interop/ClientJSSEServerJSSE.java       generic-all
 
-# Linux i586 -server, buffer too short to hold shared secret?
-com/sun/crypto/provider/KeyAgreement/DHKeyAgreement2.java       generic-all
-
-# Solaris sparcv9: Failed to parse input emptysubject.jks: No such file or directory
-sun/security/tools/keytool/emptysubject.sh                      generic-all
-
-# Timeout on solaris-sparcv9 or exception thrown
-com/sun/crypto/provider/Cipher/RSA/TestOAEP_KAT.java            solaris-all
-
-# Leaving file open: SerialVersion.current, windows samevm
-java/security/BasicPermission/SerialVersion.java                generic-all
-
 # Solaris 11 i586, these all fail with samevm, need to be othervm???
-java/security/BasicPermission/NullOrEmptyName.java              generic-all
-
-# Suspect missing close() on file PermClass.current, windows samevm cascade
-java/security/BasicPermission/PermClass.java                    generic-all
-
-# Solaris 11 i586, these all fail with samevm, need to be othervm???
-java/security/KeyPairGenerator/Failover.java                    generic-all
-java/security/Provider/DefaultPKCS11.java                       generic-all
 java/security/SecureClassLoader/DefineClassByteBuffer.java      generic-all
-java/security/SecureRandom/GetAlgorithm.java                    generic-all
-java/security/Security/removing/RemoveProviders.java            generic-all
-java/security/Signature/ByteBuffers.java                        generic-all
-java/security/Signature/NONEwithRSA.java                        generic-all
-java/security/Signature/SignWithOutputBuffer.java               generic-all
-java/security/Signature/TestInitSignWithMyOwnRandom.java        generic-all
-java/security/UnresolvedPermission/AccessorMethods.java         generic-all
-java/security/UnresolvedPermission/Equals.java                  generic-all
-
-# Fails on OpenSolaris, missing classes, slow on Solaris sparc
-sun/security/ec/TestEC.java                                     generic-all
-
-# Problems with windows x64
-sun/security/mscapi/IsSunMSCAPIAvailable.sh                     windows-x64
-sun/security/mscapi/RSAEncryptDecrypt.sh                        windows-x64
-
-# Exception in test solaris-sparc -client -server, no windows
-sun/security/pkcs11/KeyGenerator/TestKeyGenerator.java          solaris-all
-
-# Solaris sparc client, fails to compile?
-sun/security/pkcs11/KeyStore/SecretKeysBasic.sh                 solaris-all
-
-# Fails on OpenSolaris java.net.BindException: Address already in use
-sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java            generic-all
-
-# Timeout on solaris-sparcv9 or ArrayIndexOutOfBoundsException?
-sun/security/rsa/TestKeyPairGeneratorLength.java                solaris-all
-sun/security/rsa/TestSignatures.java                            solaris-all
 
 # Timeout on solaris-sparc and i586 and x64, -client and -server
 sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/InterruptedIO.java solaris-all
 
-# Do not seem to run on windows machines? dll missing?
-sun/security/tools/jarsigner/emptymanifest.sh                   windows-all
-
-# Files does not exist or no encoding? solaris-sparcv9
-sun/security/tools/keytool/importreadall.sh                     solaris-all
-sun/security/tools/keytool/selfissued.sh                        solaris-all
-
 # 7147060
 com/sun/org/apache/xml/internal/security/transforms/ClassLoaderTest.java        generic-all
 
@@ -590,12 +470,6 @@
 # 6461635
 com/sun/tools/attach/BasicTests.sh                              generic-all
 
-# Filed 6952105
-com/sun/jdi/SuspendThreadTest.java                              generic-all
-
-# Filed 6987312
-com/sun/jdi/DoubleAgentTest.java                                generic-all
-
 # Filed 6986875
 sun/tools/jps/jps-Vvml.sh                                       generic-all
 
@@ -622,6 +496,16 @@
 
 ############################################################################
 
+# jdk_jdi
+
+# Filed 6952105
+com/sun/jdi/SuspendThreadTest.java                              generic-all
+
+# Filed 6987312
+com/sun/jdi/DoubleAgentTest.java                                generic-all
+
+############################################################################
+
 # jdk_util
 
 # Need 7094995 back-ported from jdk8
diff --git a/jdk/test/com/sun/corba/cachedSocket/7056731.sh b/jdk/test/com/sun/corba/cachedSocket/7056731.sh
new file mode 100644
index 0000000..afb2278
--- /dev/null
+++ b/jdk/test/com/sun/corba/cachedSocket/7056731.sh
@@ -0,0 +1,122 @@
+#
+# Copyright (c) 2012, 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 7056731
+#  @summary Race condition in CORBA code causes re-use of ABORTed connections
+#
+#  @run shell 7056731.sh
+#
+
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin )
+    PS=":"
+    FS="/"
+    ;;
+  Windows* | CYGWIN* )
+    PS=";"
+    FS="\\"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+if [ "${TESTJAVA}" = "" ] ; then
+  echo "TESTJAVA not set.  Test cannot execute.  Failed."
+  exit 1
+fi
+
+JAVA="${TESTJAVA}${FS}bin${FS}java"
+PORT=1052
+cp -r ${TESTSRC}${FS}*.java  ${TESTSRC}${FS}Hello.idl .
+echo "Testing...please wait"
+
+${TESTJAVA}${FS}bin${FS}idlj -fall Hello.idl
+${TESTJAVA}${FS}bin${FS}javac *.java HelloApp/*.java
+
+echo "starting orbd"
+${TESTJAVA}${FS}bin${FS}orbd -ORBInitialPort $PORT -ORBInitialHost localhost &
+ORB_PROC=$!
+sleep 2 #give orbd time to start
+echo "started orb"
+echo "starting server"
+${TESTJAVA}${FS}bin${FS}java -cp . HelloServer -ORBInitialPort $PORT -ORBInitialHost localhost &
+SERVER_PROC=$!
+sleep 2 #give server time to start
+echo "started server"
+echo "starting client (debug mode)"
+${TESTJAVA}${FS}bin${FS}java -cp . -agentlib:jdwp=transport=dt_socket,server=y,address=8000 HelloClient -ORBInitialPort $PORT -ORBInitialHost localhost > client.$$ 2>&1 & 
+JVM_PROC=$!
+sleep 2 #give jvm/debugger/client time to start
+
+echo "started client (debug mode)"
+echo "starting debugger and issuing commands"
+(sleep 2;
+echo "stop in com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.unregisterWaiter";
+sleep 2;
+echo "run";
+sleep 2;
+echo "cont";
+sleep 2;
+echo "cont";
+sleep 2;
+echo "cont";
+sleep 2;
+echo "suspend 1";
+sleep 2;
+kill -9 $SERVER_PROC &> /dev/null;
+sleep 2;
+echo "cont";
+sleep 2;
+echo "thread 1"
+sleep 2;
+echo "clear com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.unregisterWaiter"
+sleep 2;
+echo "resume 1";
+)| ${TESTJAVA}${FS}bin${FS}jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8000
+
+sleep 5 # give time for Client to throw exception
+
+# JVM_PROC should have exited but just in case, include it.
+kill -9 $ORB_PROC $JVM_PROC
+
+grep "ORBUtilSystemException.writeErrorSend" client.$$
+result=$?
+if [ $result -eq 0 ]
+then
+    echo "Failed"
+    exitCode=1;
+else 
+    echo "Passed"
+    exitCode=0
+fi
+
+#jtreg complaining about not being able to clean up; let's sleep
+sleep 2
+rm -rf out.$$ client.$$
+sleep 2
+exit ${exitCode}
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/jdk/test/com/sun/corba/cachedSocket/Hello.idl
similarity index 76%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to jdk/test/com/sun/corba/cachedSocket/Hello.idl
index 077886f..454e3fd 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/jdk/test/com/sun/corba/cachedSocket/Hello.idl
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,13 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
-
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
-    }
-}
+module HelloApp
+{
+  interface Hello
+  {
+    string sayHello();
+    oneway void shutdown();
+  };
+};
diff --git a/jdk/test/com/sun/corba/cachedSocket/HelloClient.java b/jdk/test/com/sun/corba/cachedSocket/HelloClient.java
new file mode 100644
index 0000000..0cf697d
--- /dev/null
+++ b/jdk/test/com/sun/corba/cachedSocket/HelloClient.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import HelloApp.*;
+import org.omg.CosNaming.*;
+import org.omg.CosNaming.NamingContextPackage.*;
+import org.omg.CORBA.*;
+
+public class HelloClient
+{
+    static Hello helloImpl;
+
+    public static void main(String args[])
+    {
+        try{
+            // create and initialize the ORB
+            ORB orb = ORB.init(args, null);
+
+            // get the root naming context
+            org.omg.CORBA.Object objRef =
+                orb.resolve_initial_references("NameService");
+            // Use NamingContextExt instead of NamingContext. This is
+            // part of the Interoperable naming Service.
+            NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
+
+            // resolve the Object Reference in Naming
+            String name = "Hello";
+            helloImpl = HelloHelper.narrow(ncRef.resolve_str(name));
+
+            System.out.println("Obtained a handle on server object: " + helloImpl);
+            for (int i = 0; i < 2; i++) {
+                try {
+                    System.out.println(helloImpl.sayHello());
+                } catch (Exception e) {
+                    System.out.println("Exception: " + e.getMessage());
+                    e.printStackTrace();
+                }
+                Thread.sleep(2000);
+            }
+
+        } catch (Exception e) {
+            System.out.println("ERROR : " + e) ;
+            e.printStackTrace(System.out);
+        }
+    }
+
+}
diff --git a/jdk/test/com/sun/corba/cachedSocket/HelloServer.java b/jdk/test/com/sun/corba/cachedSocket/HelloServer.java
new file mode 100644
index 0000000..b6df3c0
--- /dev/null
+++ b/jdk/test/com/sun/corba/cachedSocket/HelloServer.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import HelloApp.*;
+import org.omg.CosNaming.*;
+import org.omg.CosNaming.NamingContextPackage.*;
+import org.omg.CORBA.*;
+import org.omg.PortableServer.*;
+import org.omg.PortableServer.POA;
+
+import java.util.Properties;
+
+class HelloImpl extends HelloPOA {
+    private ORB orb;
+
+    public void setORB(ORB orb_val) {
+        orb = orb_val;
+    }
+
+    // implement sayHello() method
+    public String sayHello() {
+        return "\nHello world !!\n";
+    }
+
+    // implement shutdown() method
+    public void shutdown() {
+        orb.shutdown(false);
+    }
+}
+
+
+public class HelloServer {
+
+    public static void main(String args[]) {
+        try{
+            // create and initialize the ORB
+            ORB orb = ORB.init(args, null);
+
+            // get reference to rootpoa & activate the POAManager
+            POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
+            rootpoa.the_POAManager().activate();
+
+            // create servant and register it with the ORB
+            HelloImpl helloImpl = new HelloImpl();
+            helloImpl.setORB(orb);
+
+            // get object reference from the servant
+            org.omg.CORBA.Object ref = rootpoa.servant_to_reference(helloImpl);
+            Hello href = HelloHelper.narrow(ref);
+
+            // get the root naming context
+            org.omg.CORBA.Object objRef =
+                orb.resolve_initial_references("NameService");
+            // Use NamingContextExt which is part of the Interoperable
+            // Naming Service (INS) specification.
+            NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
+
+            // bind the Object Reference in Naming
+            String name = "Hello";
+            NameComponent path[] = ncRef.to_name( name );
+            ncRef.rebind(path, href);
+
+            System.out.println("HelloServer ready and waiting ...");
+
+            // wait for invocations from clients
+            while (true) {
+                orb.run();
+            }
+        } catch (Exception e) {
+            System.out.println("ERROR: " + e);
+            e.printStackTrace(System.out);
+        }
+
+        System.out.println("HelloServer Exiting ...");
+
+    }
+}
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/DES/Sealtest.java b/jdk/test/com/sun/crypto/provider/Cipher/DES/Sealtest.java
index d7fe1b8..3a0d03b 100644
--- a/jdk/test/com/sun/crypto/provider/Cipher/DES/Sealtest.java
+++ b/jdk/test/com/sun/crypto/provider/Cipher/DES/Sealtest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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,7 +23,7 @@
 
 /*
  * @test
- * @bug 0000000
+ * @bug 0000000 7055362
  * @summary Sealtest
  * @author Jan Luehe
  */
@@ -54,14 +54,16 @@
         SealedObject sealed = new SealedObject(kp.getPrivate(), c);
 
         // serialize
-        FileOutputStream fos = new FileOutputStream("sealed");
-        ObjectOutputStream oos = new ObjectOutputStream(fos);
-        oos.writeObject(sealed);
+        try (FileOutputStream fos = new FileOutputStream("sealed");
+                ObjectOutputStream oos = new ObjectOutputStream(fos)) {
+            oos.writeObject(sealed);
+        }
 
         // deserialize
-        FileInputStream fis = new FileInputStream("sealed");
-        ObjectInputStream ois = new ObjectInputStream(fis);
-        sealed = (SealedObject)ois.readObject();
+        try (FileInputStream fis = new FileInputStream("sealed");
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            sealed = (SealedObject)ois.readObject();
+        }
 
         System.out.println(sealed.getAlgorithm());
 
diff --git a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP_KAT.java b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP_KAT.java
index 53ad3a6..b67f763 100644
--- a/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP_KAT.java
+++ b/jdk/test/com/sun/crypto/provider/Cipher/RSA/TestOAEP_KAT.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +23,7 @@
 
 /*
  * @test
- * @bug 4894151
+ * @bug 4894151 7055362
  * @summary known answer test for OAEP encryption
  * @author Andreas Sterbenz
  */
@@ -62,60 +62,62 @@
         System.out.println("Testing provider " + provider.getName() + "...");
         Cipher c = Cipher.getInstance("RSA/ECB/OAEPwithSHA1andMGF1Padding", provider);
         KeyFactory kf = KeyFactory.getInstance("RSA", kfProvider);
-        InputStream in = new FileInputStream(new File(BASE, "oaep-vect.txt"));
-        BufferedReader reader = new BufferedReader(new InputStreamReader(in, "UTF8"));
-        while (true) {
-            String line = reader.readLine();
-            if (line == null) {
-                break;
-            }
-            line = line.trim();
-            if (line.length() == 0) {
-                continue;
-            }
-            if (line.equals("# RSA modulus n:")) {
-                n = parseNumber(reader);
-            } else if (line.equals("# RSA public exponent e:")) {
-                e = parseNumber(reader);
-            } else if (line.equals("# RSA private exponent d:")) {
-                d = parseNumber(reader);
-            } else if (line.equals("# Prime p:")) {
-                p = parseNumber(reader);
-            } else if (line.equals("# Prime q:")) {
-                q = parseNumber(reader);
-            } else if (line.equals("# p's CRT exponent dP:")) {
-                pe = parseNumber(reader);
-            } else if (line.equals("# q's CRT exponent dQ:")) {
-                qe = parseNumber(reader);
-            } else if (line.equals("# CRT coefficient qInv:")) {
-                coeff = parseNumber(reader);
-            } else if (line.equals("# Message to be encrypted:")) {
-                plainText = parseBytes(reader);
-            } else if (line.equals("# Seed:")) {
-                seed = parseBytes(reader);
-            } else if (line.equals("# Encryption:")) {
-                cipherText = parseBytes(reader);
-                // do encryption test first
-                KeySpec pubSpec = new RSAPublicKeySpec(n, e);
-                PublicKey pubKey = kf.generatePublic(pubSpec);
-                c.init(Cipher.ENCRYPT_MODE, pubKey, new MyRandom(seed));
-                cipherText2 = c.doFinal(plainText);
-                if (Arrays.equals(cipherText2, cipherText) == false) {
-                    throw new Exception("Encryption mismatch");
+        try (InputStream in = new FileInputStream(new File(BASE, "oaep-vect.txt"));
+                BufferedReader reader =
+                        new BufferedReader(new InputStreamReader(in, "UTF8"))) {
+            while (true) {
+                String line = reader.readLine();
+                if (line == null) {
+                    break;
                 }
-                // followed by decryption test
-                KeySpec privSpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, pe, qe, coeff);
-                PrivateKey privKey = kf.generatePrivate(privSpec);
-                c.init(Cipher.DECRYPT_MODE, privKey);
-                byte[] dec = c.doFinal(cipherText);
-                if (Arrays.equals(plainText, dec) == false) {
-                    throw new Exception("Decryption mismatch");
+                line = line.trim();
+                if (line.length() == 0) {
+                    continue;
                 }
-            } else if (line.startsWith("# ------------------------------")) {
-                // ignore, do not print
-            } else {
-                // unknown line (comment), print
-                System.out.println(": " + line);
+                if (line.equals("# RSA modulus n:")) {
+                    n = parseNumber(reader);
+                } else if (line.equals("# RSA public exponent e:")) {
+                    e = parseNumber(reader);
+                } else if (line.equals("# RSA private exponent d:")) {
+                    d = parseNumber(reader);
+                } else if (line.equals("# Prime p:")) {
+                    p = parseNumber(reader);
+                } else if (line.equals("# Prime q:")) {
+                    q = parseNumber(reader);
+                } else if (line.equals("# p's CRT exponent dP:")) {
+                    pe = parseNumber(reader);
+                } else if (line.equals("# q's CRT exponent dQ:")) {
+                    qe = parseNumber(reader);
+                } else if (line.equals("# CRT coefficient qInv:")) {
+                    coeff = parseNumber(reader);
+                } else if (line.equals("# Message to be encrypted:")) {
+                    plainText = parseBytes(reader);
+                } else if (line.equals("# Seed:")) {
+                    seed = parseBytes(reader);
+                } else if (line.equals("# Encryption:")) {
+                    cipherText = parseBytes(reader);
+                    // do encryption test first
+                    KeySpec pubSpec = new RSAPublicKeySpec(n, e);
+                    PublicKey pubKey = kf.generatePublic(pubSpec);
+                    c.init(Cipher.ENCRYPT_MODE, pubKey, new MyRandom(seed));
+                    cipherText2 = c.doFinal(plainText);
+                    if (Arrays.equals(cipherText2, cipherText) == false) {
+                        throw new Exception("Encryption mismatch");
+                    }
+                    // followed by decryption test
+                    KeySpec privSpec = new RSAPrivateCrtKeySpec(n, e, d, p, q, pe, qe, coeff);
+                    PrivateKey privKey = kf.generatePrivate(privSpec);
+                    c.init(Cipher.DECRYPT_MODE, privKey);
+                    byte[] dec = c.doFinal(cipherText);
+                    if (Arrays.equals(plainText, dec) == false) {
+                        throw new Exception("Decryption mismatch");
+                    }
+                } else if (line.startsWith("# ------------------------------")) {
+                    // ignore, do not print
+                } else {
+                    // unknown line (comment), print
+                    System.out.println(": " + line);
+                }
             }
         }
         long stop = System.currentTimeMillis();
diff --git a/jdk/test/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI/7089914/bug7089914.java b/jdk/test/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI/7089914/bug7089914.java
new file mode 100644
index 0000000..3354f28
--- /dev/null
+++ b/jdk/test/com/sun/java/swing/plaf/windows/WindowsRadioButtonUI/7089914/bug7089914.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test
+ * @bug 7089914
+ * @summary Focus on image icons are not visible in javaws cache with high contrast mode
+ * @author Sean Chou
+ */
+
+import javax.swing.*;
+import java.lang.reflect.Field;
+
+public class bug7089914 {
+
+    public static void main(String[] args) throws Exception {
+        try {
+            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+        } catch (Exception e) {
+            System.out.println("Not WindowsLookAndFeel, test skipped");
+
+            return;
+        }
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+
+                JRadioButton rb = new JRadioButton();
+
+                if (!"com.sun.java.swing.plaf.windows.WindowsRadioButtonUI".equals(rb.getUI().getClass().getName())) {
+                    throw new RuntimeException("Unexpected UI class of JRadioButton");
+                }
+
+                try {
+                    Field initializedField = rb.getUI().getClass().getDeclaredField("initialized");
+                    initializedField.setAccessible(true);
+
+                    if (!initializedField.getBoolean(rb.getUI())) {
+                        throw new RuntimeException("initialized is false");
+                    }
+
+                    rb.getUI().uninstallUI(rb);
+
+                    if (initializedField.getBoolean(rb.getUI())) {
+                        throw new RuntimeException("initialized is true");
+                    }
+                } catch (NoSuchFieldException | IllegalAccessException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+    }
+}
diff --git a/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
new file mode 100644
index 0000000..03377dc
--- /dev/null
+++ b/jdk/test/com/sun/jndi/ldap/LdapTimeoutTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 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
+ * 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 7094377 8000487 6176036 7056489
+ * @summary Timeout tests for ldap
+ */
+
+import java.net.Socket;
+import java.net.ServerSocket;
+import java.net.SocketTimeoutException;
+import java.io.*;
+import javax.naming.*;
+import javax.naming.directory.*;
+import java.util.Hashtable;
+import java.util.concurrent.Callable;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+public class LdapTimeoutTest {
+    private static final ScheduledExecutorService pool =
+        Executors.newScheduledThreadPool(1);
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+
+    public static void main(String[] args) throws Exception {
+        ServerSocket serverSock = new ServerSocket(0);
+        Server s = new Server(serverSock);
+        s.start();
+        Thread.sleep(200);
+
+        Hashtable env = new Hashtable(11);
+        env.put(Context.INITIAL_CONTEXT_FACTORY,
+            "com.sun.jndi.ldap.LdapCtxFactory");
+        env.put(Context.PROVIDER_URL, "ldap://localhost:" +
+            serverSock.getLocalPort());
+
+        env.put(Context.SECURITY_AUTHENTICATION,"simple");
+
+        env.put(Context.SECURITY_PRINCIPAL, "user");
+        env.put(Context.SECURITY_CREDENTIALS, "password");
+
+        env.put("com.sun.jndi.ldap.connect.timeout", "10");
+        env.put("com.sun.jndi.ldap.read.timeout", "3000");
+
+        InitialContext ctx = null;
+        try {
+            new LdapTimeoutTest().ldapReadTimeoutTest(env, false);
+            new LdapTimeoutTest().ldapReadTimeoutTest(env, true);
+            new LdapTimeoutTest().simpleAuthConnectTest(env);
+        } finally {
+            s.interrupt();
+            LdapTimeoutTest.pool.shutdown();
+        }
+
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");
+    }
+
+    void ldapReadTimeoutTest(Hashtable env, boolean ssl) {
+        InitialContext ctx = null;
+        if (ssl) env.put(Context.SECURITY_PROTOCOL, "ssl");
+        ScheduledFuture killer = killSwitch();
+        long start = System.nanoTime();
+        try {
+            ctx = new InitialDirContext(env);
+            SearchControls scl = new SearchControls();
+            scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
+            NamingEnumeration<SearchResult> answer = ((InitialDirContext)ctx)
+                .search("ou=People,o=JNDITutorial", "(objectClass=*)", scl);
+            // shouldn't reach here
+            fail();
+        } catch (NamingException e) {
+            if (ssl) {
+                if (e.getCause() instanceof SocketTimeoutException) {
+                    pass();
+                } else if (e.getCause() instanceof InterruptedIOException) {
+                    Thread.interrupted();
+                    fail();
+                }
+            } else {
+                pass();
+            }
+        } finally {
+            if (!shutItDown(killer, ctx)) fail();
+        }
+    }
+
+    void simpleAuthConnectTest(Hashtable env) {
+        InitialContext ctx = null;
+        ScheduledFuture killer = killSwitch();
+        long start = System.nanoTime();
+        try {
+            ctx = new InitialDirContext(env);
+            // shouldn't reach here
+            System.err.println("Fail: InitialDirContext succeeded");
+            fail();
+        } catch (NamingException e) {
+            long end = System.nanoTime();
+            if (e.getCause() instanceof SocketTimeoutException) {
+                if (TimeUnit.NANOSECONDS.toMillis(end - start) < 2900) {
+                    pass();
+                } else {
+                    System.err.println("Fail: Waited too long");
+                    fail();
+                }
+            } else if (e.getCause() instanceof InterruptedIOException) {
+                Thread.interrupted();
+                fail();
+            } else {
+                fail();
+            }
+        } finally {
+            if (!shutItDown(killer, ctx)) fail();
+        }
+    }
+
+    boolean shutItDown(ScheduledFuture killer, InitialContext ctx) {
+        killer.cancel(true);
+        try {
+            if (ctx != null) ctx.close();
+            return true;
+        } catch (NamingException ex) {
+            return false;
+        }
+    }
+
+    ScheduledFuture killSwitch() {
+        final Thread current = Thread.currentThread();
+        return LdapTimeoutTest.pool.schedule(new Callable<Void>() {
+            public Void call() throws Exception {
+                System.err.println("Fail: killSwitch()");
+                current.interrupt();
+                return null;
+            }
+        }, 5000, TimeUnit.MILLISECONDS);
+    }
+
+    static class Server extends Thread {
+        final ServerSocket serverSock;
+
+        Server(ServerSocket serverSock) {
+            this.serverSock = serverSock;
+        }
+
+        public void run() {
+            try {
+                Socket socket = serverSock.accept();
+            } catch (IOException e) {}
+        }
+    }
+}
+
diff --git a/jdk/test/com/sun/jndi/ldap/LdapsReadTimeoutTest.java b/jdk/test/com/sun/jndi/ldap/LdapsReadTimeoutTest.java
deleted file mode 100644
index 9fae77d..0000000
--- a/jdk/test/com/sun/jndi/ldap/LdapsReadTimeoutTest.java
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 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
- * 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 7094377
- * @summary Com.sun.jndi.ldap.read.timeout doesn't work with ldaps.
- */
-
-import java.net.Socket;
-import java.net.ServerSocket;
-import java.io.*;
-import javax.naming.*;
-import javax.naming.directory.*;
-import java.util.Hashtable;
-
-public class LdapsReadTimeoutTest {
-
-    public static void main(String[] args) throws Exception {
-        boolean passed = false;
-
-        // create the server
-        try (Server server = Server.create()) {
-            // Set up the environment for creating the initial context
-            Hashtable<String,Object> env = new Hashtable<>(11);
-            env.put(Context.INITIAL_CONTEXT_FACTORY,
-                "com.sun.jndi.ldap.LdapCtxFactory");
-            env.put("com.sun.jndi.ldap.connect.timeout", "1000");
-            env.put("com.sun.jndi.ldap.read.timeout", "1000");
-            env.put(Context.PROVIDER_URL, "ldaps://localhost:" + server.port());
-
-
-            // Create initial context
-            DirContext ctx = new InitialDirContext(env);
-            try {
-                System.out.println("LDAP Client: Connected to the Server");
-
-                SearchControls scl = new SearchControls();
-                scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
-                System.out.println("Performing Search");
-                NamingEnumeration<SearchResult> answer =
-                    ctx.search("ou=People,o=JNDITutorial", "(objectClass=*)", scl);
-            } finally {
-                // Close the context when we're done
-                ctx.close();
-            }
-        } catch (NamingException e) {
-            passed = true;
-            e.printStackTrace();
-        }
-
-        if (!passed) {
-            throw new Exception("Read timeout test failed," +
-                         " read timeout exception not thrown");
-        }
-        System.out.println("The test PASSED");
-    }
-
-    static class Server implements Runnable, Closeable {
-        private final ServerSocket ss;
-        private Socket sref;
-
-        private Server(ServerSocket ss) {
-            this.ss = ss;
-        }
-
-        static Server create() throws IOException {
-            Server server = new Server(new ServerSocket(0));
-            new Thread(server).start();
-            return server;
-        }
-
-        int port() {
-            return ss.getLocalPort();
-        }
-
-        public void run() {
-            try (Socket s = ss.accept()) {
-                sref = s;
-                System.out.println("Server: Connection accepted");
-                BufferedInputStream bis =
-                    new BufferedInputStream(s.getInputStream());
-                byte[] buf = new byte[100];
-                int n;
-                do {
-                    n = bis.read(buf);
-                } while (n > 0);
-            } catch (IOException e) {
-                // ignore
-            }
-        }
-
-        public void close() throws IOException {
-            ss.close();
-            sref.close();
-        }
-    }
-}
diff --git a/jdk/test/com/sun/jndi/ldap/ReadTimeoutTest.java b/jdk/test/com/sun/jndi/ldap/ReadTimeoutTest.java
deleted file mode 100644
index b5349da..0000000
--- a/jdk/test/com/sun/jndi/ldap/ReadTimeoutTest.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (c) 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
- * 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 6176036
- * @summary Read-timeout specification for LDAP operations
- */
-
-import java.net.Socket;
-import java.net.ServerSocket;
-import java.io.*;
-import javax.naming.*;
-import javax.naming.directory.*;
-import java.util.Hashtable;
-
-public class ReadTimeoutTest {
-
-    public static void main(String[] args) throws Exception {
-
-        boolean passed = false;
-
-        // Set up the environment for creating the initial context
-        Hashtable env = new Hashtable(11);
-        env.put(Context.INITIAL_CONTEXT_FACTORY,
-            "com.sun.jndi.ldap.LdapCtxFactory");
-        env.put("com.sun.jndi.ldap.read.timeout", "1000");
-        env.put(Context.PROVIDER_URL, "ldap://localhost:2001");
-
-        Server s = new Server();
-
-        try {
-
-            // start the server
-            s.start();
-
-            // Create initial context
-            DirContext ctx = new InitialDirContext(env);
-            System.out.println("LDAP Client: Connected to the Server");
-
-            SearchControls scl = new SearchControls();
-            scl.setSearchScope(SearchControls.SUBTREE_SCOPE);
-            System.out.println("Performing Search");
-            NamingEnumeration answer =
-                ctx.search("ou=People,o=JNDITutorial", "(objectClass=*)", scl);
-
-            // Close the context when we're done
-            ctx.close();
-        } catch (NamingException e) {
-            passed = true;
-            e.printStackTrace();
-        }
-        s.interrupt();
-        if (!passed) {
-            throw new Exception("Read timeout test failed," +
-                         " read timeout exception not thrown");
-        }
-        System.out.println("The test PASSED");
-    }
-
-    static class Server extends Thread {
-
-        static int serverPort = 2001;
-
-        Server() {
-        }
-
-        public void run() {
-            try {
-                ServerSocket serverSock = new ServerSocket(serverPort);
-                Socket socket = serverSock.accept();
-                System.out.println("Server: Connection accepted");
-
-                BufferedInputStream bin = new BufferedInputStream(socket.
-                                getInputStream());
-                while (true) {
-                    bin.read();
-                }
-            } catch (IOException e) {
-                // ignore
-            }
-    }
-}
-}
diff --git a/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java b/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java
index f8706df..edd15ae 100644
--- a/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java
+++ b/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/ContextWithNullProperties.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,26 +25,21 @@
  * @test
  * @bug 6676075
  * @summary RegistryContext (com.sun.jndi.url.rmi.rmiURLContext) coding problem
+ * @library ../../../../../../java/rmi/testlibrary
+ * @build TestLibrary
+ * @run main ContextWithNullProperties
  */
 
-import java.rmi.RemoteException;
-import java.rmi.registry.LocateRegistry;
-
-import com.sun.jndi.rmi.registry.*;
+import com.sun.jndi.rmi.registry.RegistryContext;
+import java.rmi.registry.Registry;
 
 public class ContextWithNullProperties {
-
     public static void main(String[] args) throws Exception {
-
-        // Create registry on port 1099 if one is not already running.
-        try {
-            LocateRegistry.createRegistry(1099);
-        } catch (RemoteException e) {
-        }
-
+        Registry registry = TestLibrary.createRegistryOnUnusedPort();
+        int registryPort = TestLibrary.getRegistryPort(registry);
         System.out.println("Connecting to the default Registry...");
         // Connect to the default Registry.
         // Pass null as the JNDI environment properties (see final argument)
-        RegistryContext ctx = new RegistryContext(null, -1, null);
+        RegistryContext ctx = new RegistryContext(null, registryPort, null);
     }
 }
diff --git a/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/UnbindIdempotent.java b/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/UnbindIdempotent.java
index 35753b8..692c7fd 100644
--- a/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/UnbindIdempotent.java
+++ b/jdk/test/com/sun/jndi/rmi/registry/RegistryContext/UnbindIdempotent.java
@@ -1,26 +1,52 @@
 /*
+ * Copyright (c) 2007, 2012, 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 4278121
  * @summary Ensure that calling unbind() on an unbound name returns
  *      successfully.
+ * @library ../../../../../../java/rmi/testlibrary
+ * @build TestLibrary
+ * @run main UnbindIdempotent
  */
 
-import javax.naming.*;
+import java.rmi.registry.Registry;
+import javax.naming.Context;
+import javax.naming.InitialContext;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingException;
 
 public class UnbindIdempotent {
 
     public static void main(String[] args) throws Exception {
-
-        // Create registry on port 1099 if one is not already running.
-        try {
-            java.rmi.registry.LocateRegistry.createRegistry(1099);
-        } catch (java.rmi.RemoteException e) {
-        }
-
-        Context ictx = new InitialContext();
+        Registry registry = TestLibrary.createRegistryOnUnusedPort();
+        int registryPort = TestLibrary.getRegistryPort(registry);
+        InitialContext ictx = new InitialContext();
         Context rctx;
+
         try {
-            rctx = (Context)ictx.lookup("rmi://localhost:1099");
+            rctx = (Context)ictx.lookup("rmi://localhost:" + Integer.toString(registryPort));
         } catch (NamingException e) {
             // Unable to set up for test.
             return;
diff --git a/jdk/test/com/sun/security/auth/login/ConfigFile/IllegalURL.java b/jdk/test/com/sun/security/auth/login/ConfigFile/IllegalURL.java
index f091548..5e7fb6e 100644
--- a/jdk/test/com/sun/security/auth/login/ConfigFile/IllegalURL.java
+++ b/jdk/test/com/sun/security/auth/login/ConfigFile/IllegalURL.java
@@ -43,8 +43,9 @@
     static void use(String f) throws Exception {
         System.out.println("Testing " + f  + "...");
         System.setProperty("java.security.auth.login.config", f);
-        try {
-            new FileInputStream(new URL(f).getFile().replace('/', File.separatorChar));
+        try (FileInputStream fis =
+                new FileInputStream(new URL(f).getFile().replace('/', File.separatorChar))) {
+            // do nothing
         } catch (Exception e) {
             System.out.println("Even old implementation does not support it. Ignored.");
             return;
diff --git a/jdk/test/demo/zipfs/ZFSTests.java b/jdk/test/demo/zipfs/ZFSTests.java
new file mode 100644
index 0000000..c5d6e8c
--- /dev/null
+++ b/jdk/test/demo/zipfs/ZFSTests.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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 7156873
+   @summary ZipFileSystem regression tests
+ */
+
+
+import java.net.URI;
+import java.nio.file.*;
+import java.util.Map;
+import java.util.HashMap;
+
+public class ZFSTests {
+
+    public static void main(String[] args) throws Throwable {
+        test7156873();
+    }
+
+    static void test7156873() throws Throwable {
+        String DIRWITHSPACE = "testdir with spaces";
+        Path dir = Paths.get(DIRWITHSPACE);
+        Path path = Paths.get(DIRWITHSPACE, "file.zip");
+        try {
+            Files.createDirectory(dir);
+            URI uri = URI.create("jar:" + path.toUri());
+            Map<String, Object> env = new HashMap<String, Object>();
+            env.put("create", "true");
+            try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {}
+        } finally {
+            Files.deleteIfExists(path);
+            Files.deleteIfExists(dir);
+        }
+    }
+}
diff --git a/jdk/test/java/awt/Focus/OverrideRedirectWindowActivationTest/OverrideRedirectWindowActivationTest.java b/jdk/test/java/awt/Focus/OverrideRedirectWindowActivationTest/OverrideRedirectWindowActivationTest.java
new file mode 100644
index 0000000..598adfb
--- /dev/null
+++ b/jdk/test/java/awt/Focus/OverrideRedirectWindowActivationTest/OverrideRedirectWindowActivationTest.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (c) 2012, 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       6385277
+ * @summary   Tests that override redirect window gets activated on click.
+ * @author    anton.tarasov@sun.com: area=awt.focus
+ * @library   ../../regtesthelpers
+ * @build     Util
+ * @run       main OverrideRedirectWindowActivationTest
+ */
+import java.awt.*;
+import java.awt.event.*;
+import java.util.concurrent.Callable;
+import javax.swing.SwingUtilities;
+import sun.awt.SunToolkit;
+import test.java.awt.regtesthelpers.Util;
+
+public class OverrideRedirectWindowActivationTest {
+
+    private static Frame frame;
+    private static Window window;
+    private static Button fbutton;
+    private static Button wbutton;
+    private static Label label;
+    private static Robot robot;
+    private static SunToolkit toolkit;
+
+    public static void main(String[] args) throws Exception {
+
+        if ("sun.awt.motif.MToolkit".equals(Toolkit.getDefaultToolkit().getClass().getName())) {
+            System.out.println("No testing on Motif. Test passed.");
+            return;
+        }
+
+        toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        robot = new Robot();
+        robot.setAutoDelay(50);
+
+        Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
+
+            public void eventDispatched(AWTEvent e) {
+                System.out.println(e);
+            }
+        }, FocusEvent.FOCUS_EVENT_MASK | WindowEvent.WINDOW_FOCUS_EVENT_MASK);
+
+        createAndShowWindow();
+        toolkit.realSync();
+
+        createAndShowFrame();
+        toolkit.realSync();
+
+        // click on Frame
+        clickOn(getClickPoint(frame));
+
+        if (!frame.isFocused()) {
+            throw new RuntimeException("Error: a frame couldn't be focused by click.");
+        }
+
+        //click on Label in Window
+        clickOn(getClickPoint(label));
+
+        if (!window.isFocused()) {
+            throw new RuntimeException("Test failed: the window couldn't be activated by click!");
+        }
+
+        // bring focus back to the frame
+        clickOn(getClickPoint(fbutton));
+
+        if (!frame.isFocused()) {
+            throw new RuntimeException("Error: a frame couldn't be focused by click.");
+        }
+
+        // Test 2. Verifies that clicking on a component of unfocusable Window
+        //         won't activate it.
+
+        window.setFocusableWindowState(false);
+        toolkit.realSync();
+
+
+        clickOn(getClickPoint(label));
+
+        if (window.isFocused()) {
+            throw new RuntimeException("Test failed: unfocusable window got activated by click!");
+        }
+        System.out.println("Test passed.");
+
+    }
+
+    private static void createAndShowWindow() {
+
+        frame = new Frame("Test Frame");
+        window = new Window(frame);
+        wbutton = new Button("wbutton");
+        label = new Label("label");
+
+        window.setBounds(800, 200, 200, 100);
+        window.setLayout(new FlowLayout());
+        window.add(wbutton);
+        window.add(label);
+        window.setVisible(true);
+
+    }
+
+    private static void createAndShowFrame() {
+        fbutton = new Button("fbutton");
+
+        frame.setBounds(800, 0, 200, 100);
+        frame.setLayout(new FlowLayout());
+        frame.add(fbutton);
+        frame.setVisible(true);
+
+    }
+
+    static void clickOn(Point point) {
+
+        robot.mouseMove(point.x, point.y);
+
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+
+        toolkit.realSync();
+    }
+
+    static Point getClickPoint(Component c) {
+        Point p = c.getLocationOnScreen();
+        Dimension d = c.getSize();
+        return new Point(p.x + (int) (d.getWidth() / 2), p.y + (int) (d.getHeight() / 2));
+    }
+
+    static Point getClickPoint(Frame frame) {
+        Point p = frame.getLocationOnScreen();
+        Dimension d = frame.getSize();
+        return new Point(p.x + (int) (d.getWidth() / 2), p.y + (frame.getInsets().top / 2));
+    }
+}
diff --git a/jdk/test/java/awt/Frame/ResizeAfterSetFont/ResizeAfterSetFont.java b/jdk/test/java/awt/Frame/ResizeAfterSetFont/ResizeAfterSetFont.java
new file mode 100644
index 0000000..32ed472
--- /dev/null
+++ b/jdk/test/java/awt/Frame/ResizeAfterSetFont/ResizeAfterSetFont.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/*
+ @test
+ @bug 7170655
+ @summary Frame size does not change after changing font
+ @author Jonathan Lu
+ @library ../../regtesthelpers
+ @build Util
+ @run main ResizeAfterSetFont
+ */
+
+import java.awt.*;
+import test.java.awt.regtesthelpers.Util;
+
+public class ResizeAfterSetFont {
+
+    public static void main(String[] args) throws Exception {
+        Frame frame = new Frame("bug7170655");
+        frame.setLayout(new BorderLayout());
+        frame.setBackground(Color.LIGHT_GRAY);
+
+        Panel panel = new Panel();
+        panel.setLayout(new GridLayout(0, 1, 1, 1));
+
+        Label label = new Label("Test Label");
+        label.setBackground(Color.white);
+        label.setForeground(Color.RED);
+        label.setFont(new Font("Dialog", Font.PLAIN, 12));
+
+        panel.add(label);
+        frame.add(panel, "South");
+        frame.pack();
+        frame.setVisible(true);
+
+        Util.waitForIdle(null);
+
+        Dimension dimBefore = frame.getSize();
+        label.setFont(new Font("Dialog", Font.PLAIN, 24));
+
+        frame.validate();
+        frame.pack();
+        Dimension dimAfter = frame.getSize();
+
+        if (dimBefore.equals(dimAfter)) {
+            throw new Exception(
+                    "Frame size does not change after Label.setFont()!");
+        }
+    }
+}
diff --git a/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java b/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java
deleted file mode 100644
index ccba2bc..0000000
--- a/jdk/test/java/awt/Mouse/EnterExitEvents/DragWindowTest.java
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (c) 2005, 2006, 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 7154048
- * @summary Window created under a mouse does not receive mouse enter event.
- *     Mouse Entered/Exited events are wrongly generated during dragging the window
- *     from one component to another
- * @library ../../regtesthelpers
- * @build Util
- * @author alexandr.scherbatiy area=awt.event
- * @run main DragWindowTest
- */
-
-import java.awt.*;
-import java.awt.event.*;
-import javax.swing.*;
-
-import java.util.concurrent.*;
-import sun.awt.SunToolkit;
-
-import test.java.awt.regtesthelpers.Util;
-
-public class DragWindowTest {
-
-    private static volatile int dragWindowMouseEnteredCount = 0;
-    private static volatile int dragWindowMouseReleasedCount = 0;
-    private static volatile int buttonMouseEnteredCount = 0;
-    private static volatile int labelMouseReleasedCount = 0;
-    private static MyDragWindow dragWindow;
-    private static JLabel label;
-    private static JButton button;
-
-    public static void main(String[] args) throws Exception {
-
-        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
-        Robot robot = new Robot();
-        robot.setAutoDelay(50);
-
-        SwingUtilities.invokeAndWait(new Runnable() {
-
-            @Override
-            public void run() {
-                createAndShowGUI();
-            }
-        });
-
-        toolkit.realSync();
-
-        Point pointToClick = Util.invokeOnEDT(new Callable<Point>() {
-
-            @Override
-            public Point call() throws Exception {
-                return getCenterPoint(label);
-            }
-        });
-
-
-        robot.mouseMove(pointToClick.x, pointToClick.y);
-        robot.mousePress(InputEvent.BUTTON1_MASK);
-        toolkit.realSync();
-
-        if (dragWindowMouseEnteredCount != 1) {
-            throw new RuntimeException("No MouseEntered event on Drag Window!");
-        }
-
-        Point pointToDrag = Util.invokeOnEDT(new Callable<Point>() {
-
-            @Override
-            public Point call() throws Exception {
-                button.addMouseListener(new ButtonMouseListener());
-                return getCenterPoint(button);
-            }
-        });
-
-        robot.mouseMove(pointToDrag.x, pointToDrag.y);
-        toolkit.realSync();
-
-        if (buttonMouseEnteredCount != 0) {
-            throw new RuntimeException("Extra MouseEntered event on button!");
-        }
-
-        robot.mouseRelease(InputEvent.BUTTON1_MASK);
-        toolkit.realSync();
-
-        if (labelMouseReleasedCount != 1) {
-            throw new RuntimeException("No MouseReleased event on label!");
-        }
-
-    }
-
-    private static Point getCenterPoint(Component comp) {
-        Point p = comp.getLocationOnScreen();
-        Rectangle rect = comp.getBounds();
-        return new Point(p.x + rect.width / 2, p.y + rect.height / 2);
-    }
-
-    private static void createAndShowGUI() {
-
-        JFrame frame = new JFrame("Main Frame");
-        frame.setSize(300, 200);
-        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-
-        label = new JLabel("Label");
-
-        LabelMouseListener listener = new LabelMouseListener(frame);
-        label.addMouseListener(listener);
-        label.addMouseMotionListener(listener);
-
-        button = new JButton("Button");
-        Panel panel = new Panel(new BorderLayout());
-
-        panel.add(label, BorderLayout.NORTH);
-        panel.add(button, BorderLayout.CENTER);
-
-        frame.getContentPane().add(panel);
-        frame.setVisible(true);
-
-    }
-
-    private static Point getAbsoluteLocation(MouseEvent e) {
-        return new Point(e.getXOnScreen(), e.getYOnScreen());
-    }
-
-    static class MyDragWindow extends Window {
-
-        static int d = 30;
-
-        public MyDragWindow(Window parent, Point location) {
-            super(parent);
-            setSize(150, 150);
-            setVisible(true);
-            JPanel panel = new JPanel();
-            add(panel);
-            setLocation(location.x - d, location.y - d);
-            addMouseListener(new DragWindowMouseListener());
-        }
-
-        void dragTo(Point point) {
-            setLocation(point.x - d, point.y - d);
-        }
-    }
-
-    static class LabelMouseListener extends MouseAdapter {
-
-        Point origin;
-        Window parent;
-
-        public LabelMouseListener(Window parent) {
-            this.parent = parent;
-        }
-
-        @Override
-        public void mousePressed(MouseEvent e) {
-            if (dragWindow == null) {
-                dragWindow = new MyDragWindow(parent, getAbsoluteLocation(e));
-            } else {
-                dragWindow.setVisible(true);
-                dragWindow.dragTo(getAbsoluteLocation(e));
-            }
-        }
-
-        @Override
-        public void mouseReleased(MouseEvent e) {
-            labelMouseReleasedCount++;
-            if (dragWindow != null) {
-                dragWindow.setVisible(false);
-            }
-        }
-
-        public void mouseDragged(MouseEvent e) {
-            if (dragWindow != null) {
-                dragWindow.dragTo(getAbsoluteLocation(e));
-            }
-        }
-    }
-
-    static class DragWindowMouseListener extends MouseAdapter {
-
-        @Override
-        public void mouseEntered(MouseEvent e) {
-            dragWindowMouseEnteredCount++;
-        }
-
-        @Override
-        public void mouseReleased(MouseEvent e) {
-            dragWindowMouseReleasedCount++;
-        }
-    }
-
-    static class ButtonMouseListener extends MouseAdapter {
-
-        @Override
-        public void mouseEntered(MouseEvent e) {
-            buttonMouseEnteredCount++;
-        }
-    }
-}
diff --git a/jdk/test/java/awt/TextArea/DisposeTest/TestDispose.java b/jdk/test/java/awt/TextArea/DisposeTest/TestDispose.java
new file mode 100644
index 0000000..eaa912d
--- /dev/null
+++ b/jdk/test/java/awt/TextArea/DisposeTest/TestDispose.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test
+ * @bug 7155298
+ * @run main/othervm/timeout=60 TestDispose
+ * @summary Editable TextArea blocks GUI application from exit.
+ * @author Sean Chou
+ */
+
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.TextArea;
+import java.awt.Toolkit;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import sun.awt.SunToolkit;
+
+public class TestDispose {
+
+    public static Frame frame = null;
+    public static TextArea textArea = null;
+    public static volatile Process worker = null;
+
+    public void testDispose() throws InvocationTargetException,
+            InterruptedException {
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame("Test");
+
+                textArea = new TextArea("editable textArea");
+                textArea.setEditable(true);
+                // textArea.setEditable(false); // this testcase passes if textArea is non-editable
+
+                frame.setLayout(new FlowLayout());
+                frame.add(textArea);
+
+                frame.pack();
+                frame.setVisible(true);
+            }
+        });
+        toolkit.realSync();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+        toolkit.realSync();
+    }
+
+    public static void main(String[] args) throws Exception{
+        if(args.length == 0) {
+            Runtime.getRuntime().addShutdownHook(new Thread(){
+                public void run() {
+                    worker.destroy();
+                }
+            });
+
+            System.out.println(System.getProperty("java.home")+"/bin/java TestDispose workprocess");
+            worker = Runtime.getRuntime().exec(System.getProperty("java.home")+"/bin/java TestDispose workprocess");
+            worker.waitFor();
+            return;
+        }
+
+        TestDispose app = new TestDispose();
+        app.testDispose();
+    }
+
+}
diff --git a/jdk/test/java/awt/TextArea/TextAreaCaretVisibilityTest/bug7129742.java b/jdk/test/java/awt/TextArea/TextAreaCaretVisibilityTest/bug7129742.java
new file mode 100644
index 0000000..188cd3f
--- /dev/null
+++ b/jdk/test/java/awt/TextArea/TextAreaCaretVisibilityTest/bug7129742.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+
+/* @test
+ * @bug 7129742
+ * @summary Focus in non-editable TextArea is not shown on Linux.
+ * @author Sean Chou
+ */
+
+import java.awt.FlowLayout;
+import java.awt.TextArea;
+import java.awt.Toolkit;
+import java.lang.reflect.Field;
+
+import javax.swing.JFrame;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.text.DefaultCaret;
+
+import sun.awt.SunToolkit;
+
+public class bug7129742 {
+
+    public static DefaultCaret caret = null;
+    public static JFrame frame = null;
+    public static boolean fastreturn = false;
+
+    public static void main(String[] args) throws Exception {
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame("Test");
+                TextArea textArea = new TextArea("Non-editable textArea");
+                textArea.setEditable(false);
+                frame.setLayout(new FlowLayout());
+                frame.add(textArea);
+                frame.pack();
+                frame.setVisible(true);
+
+                try {
+                    Class XTextAreaPeerClzz  = textArea.getPeer().getClass();
+                    System.out.println(XTextAreaPeerClzz.getName());
+                    if (!XTextAreaPeerClzz.getName().equals("sun.awt.X11.XTextAreaPeer")) {
+                        fastreturn = true;
+                        return;
+                    }
+
+                    Field jtextField = XTextAreaPeerClzz.getDeclaredField("jtext");
+                    jtextField.setAccessible(true);
+                    JTextArea jtext = (JTextArea)jtextField.get(textArea.getPeer());
+                    caret = (DefaultCaret) jtext.getCaret();
+
+                    textArea.requestFocusInWindow();
+                } catch (NoSuchFieldException | SecurityException
+                         | IllegalArgumentException | IllegalAccessException e) {
+                    /* These exceptions mean the implementation of XTextAreaPeer is
+                     * changed, this testcase is not valid any more, fix it or remove.
+                     */
+                    frame.dispose();
+                    throw new RuntimeException("This testcase is not valid any more!");
+                }
+            }
+        });
+        toolkit.realSync();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                try{
+                    if (fastreturn) {
+                        return;
+                    }
+                    boolean passed = caret.isActive();
+                    System.out.println("is caret visible : " + passed);
+
+                    if (!passed) {
+                        throw new RuntimeException("The test for bug 71297422 failed");
+                    }
+                } finally {
+                    frame.dispose();
+                }
+            }
+        });
+    }
+
+}
diff --git a/jdk/test/java/awt/TextField/DisposeTest/TestDispose.java b/jdk/test/java/awt/TextField/DisposeTest/TestDispose.java
new file mode 100644
index 0000000..a8a2fda
--- /dev/null
+++ b/jdk/test/java/awt/TextField/DisposeTest/TestDispose.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test
+ * @bug 7155298
+ * @run main/othervm/timeout=60 TestDispose
+ * @summary Editable TextField blocks GUI application from exit.
+ * @author Sean Chou
+ */
+
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.TextField;
+import java.awt.Toolkit;
+import java.lang.reflect.InvocationTargetException;
+
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import sun.awt.SunToolkit;
+
+public class TestDispose {
+
+    public static Frame frame = null;
+    public static TextField textField = null;
+    public static volatile Process worker = null;
+
+    public void testDispose() throws InvocationTargetException,
+            InterruptedException {
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame("Test");
+
+                textField = new TextField("editable textArea");
+                textField.setEditable(true);
+                // textField.setEditable(false); // this testcase passes if textField is non-editable
+
+                frame.setLayout(new FlowLayout());
+                frame.add(textField);
+
+                frame.pack();
+                frame.setVisible(true);
+            }
+        });
+        toolkit.realSync();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+        toolkit.realSync();
+
+    }
+
+    public static void main(String[] args) throws Exception{
+        if(args.length == 0) {
+            Runtime.getRuntime().addShutdownHook(new Thread(){
+                public void run() {
+                    worker.destroy();
+                }
+            });
+
+            System.out.println(System.getProperty("java.home")+"/bin/java TestDispose workprocess");
+            worker = Runtime.getRuntime().exec(System.getProperty("java.home")+"/bin/java TestDispose workprocess");
+            worker.waitFor();
+            return;
+        }
+
+        TestDispose app = new TestDispose();
+        app.testDispose();
+    }
+
+}
diff --git a/jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh b/jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh
index 71c8fa7..148041c 100644
--- a/jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh
+++ b/jdk/test/java/awt/Toolkit/AutoShutdown/ShowExitTest/ShowExitTest.sh
@@ -1,7 +1,7 @@
 #!/bin/ksh -p
 
 #
-# Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2007, 2012, 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
@@ -39,7 +39,7 @@
 
 #Call this from anywhere to fail the test with an error message
 # usage: fail "reason why the test failed"
-fail() 
+fail()
  { echo "The test failed :-("
    echo "$*" 1>&2
    echo "exit status was $status"
@@ -48,7 +48,7 @@
 
 #Call this from anywhere to pass the test with a message
 # usage: pass "reason why the test passed if applicable"
-pass() 
+pass()
  { echo "The test passed!!!"
    echo "$*" 1>&2
    exit 0
@@ -64,20 +64,42 @@
 case "$OS" in
    SunOS )
       VAR="One value for Sun"
-      DEFAULT_JDK=/usr/local/java/jdk1.2/solaris
+      DEFAULT_JDK=/
       FILESEP="/"
+      PATHSEP=":"
+      TMP="/tmp"
       ;;
 
    Linux )
       VAR="A different value for Linux"
-      DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
+      DEFAULT_JDK=/
       FILESEP="/"
+      PATHSEP=":"
+      TMP="/tmp"
       ;;
 
-   Windows_95 | Windows_98 | Windows_NT | Windows_ME )
+   Darwin )
+      VAR="A different value for MacOSX"
+      DEFAULT_JDK=/usr
+      FILESEP="/"
+      PATHSEP=":"
+      TMP="/tmp"
+      ;;
+
+   Windows* )
       VAR="A different value for Win32"
-      DEFAULT_JDK=/usr/local/java/jdk1.2/win32
+      DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
       FILESEP="\\"
+      PATHSEP=";"
+      TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
+      ;;
+
+    CYGWIN* )
+      VAR="A different value for Cygwin"
+      DEFAULT_JDK="/cygdrive/c/Program\ Files/Java/jdk1.8.0"
+      FILESEP="/"
+      PATHSEP=";"
+      TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
       ;;
 
    # catch all other OSs
@@ -88,8 +110,8 @@
 esac
 
 
-# Want this test to run standalone as well as in the harness, so do the 
-#  following to copy the test's directory into the harness's scratch directory 
+# Want this test to run standalone as well as in the harness, so do the
+#  following to copy the test's directory into the harness's scratch directory
 #  and set all appropriate variables:
 
 if [ -z "${TESTJAVA}" ] ; then
@@ -104,7 +126,7 @@
    if [ -n "$1" ] ;
       then TESTJAVA=$1
       else echo "no JDK specified on command line so using default!"
-	 TESTJAVA=$DEFAULT_JDK
+     TESTJAVA=$DEFAULT_JDK
    fi
    TESTSRC=.
    TESTCLASSES=.
@@ -113,25 +135,25 @@
 echo "JDK under test is: $TESTJAVA"
 
 #Deal with .class files:
-if [ -n "${STANDALONE}" ] ; 
-   then 
+if [ -n "${STANDALONE}" ] ;
+   then
    #if standalone, remind user to cd to dir. containing test before running it
    echo "Just a reminder: cd to the dir containing this test when running it"
    # then compile all .java files (if there are any) into .class files
-   if [ -a *.java ] ; 
+   if [ -a *.java ] ;
       then echo "Reminder, this test should be in its own directory with all"
       echo "supporting files it needs in the directory with it."
-      ${TESTJAVA}/bin/javac ./*.java ; 
+      ${TESTJAVA}/bin/javac ./*.java ;
    fi
    # else in harness so copy all the class files from where jtreg put them
-   # over to the scratch directory this test is running in. 
+   # over to the scratch directory this test is running in.
    else cp ${TESTCLASSES}/*.class . ;
 fi
 
-#if in test harness, then copy the entire directory that the test is in over 
+#if in test harness, then copy the entire directory that the test is in over
 # to the scratch directory.  This catches any support files needed by the test.
-if [ -z "${STANDALONE}" ] ; 
-   then cp ${TESTSRC}/* . 
+if [ -z "${STANDALONE}" ] ;
+   then cp ${TESTSRC}/* .
 fi
 
 #Just before executing anything, make sure it has executable permission!
diff --git a/jdk/test/java/awt/Window/Grab/GrabTest.java b/jdk/test/java/awt/Window/Grab/GrabTest.java
index 53b7b58..ff447e1 100644
--- a/jdk/test/java/awt/Window/Grab/GrabTest.java
+++ b/jdk/test/java/awt/Window/Grab/GrabTest.java
@@ -65,7 +65,7 @@
             }, sun.awt.SunToolkit.GRAB_EVENT_MASK);
 
         f = new Frame("Frame");
-        f.setSize(200, 200);
+        f.setBounds(0, 0, 300, 300);
         f.addMouseListener(new MouseAdapter() {
                 public void mousePressed(MouseEvent e) {
                     System.out.println(e);
@@ -74,7 +74,7 @@
             });
 
         f1 = new Frame("OtherFrame");
-        f1.setBounds(600, 100, 200, 200);
+        f1.setBounds(700, 100, 200, 200);
 
         w = new Window(f);
         w.setLayout(new FlowLayout());
@@ -86,7 +86,7 @@
                 }
             });
         w.add(b);
-        w.setBounds(300, 100, 200, 200);
+        w.setBounds(400, 100, 200, 200);
         w.setBackground(Color.blue);
         w.addMouseListener(new MouseAdapter() {
                 public void mousePressed(MouseEvent e) {
@@ -175,7 +175,8 @@
 
         // 6. Check that press on the outside area causes ungrab
         Point loc = f.getLocationOnScreen();
-        robot.mouseMove(loc.x + 100, loc.y + f.getSize().height + 300);
+        robot.mouseMove(loc.x + 100, loc.y + f.getSize().height + 1);
+        Util.waitForIdle(robot);
         robot.mousePress(InputEvent.BUTTON1_MASK);
         robot.delay(50);
         robot.mouseRelease(InputEvent.BUTTON1_MASK);
diff --git a/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh b/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh
index 0e22776b..923cac5 100644
--- a/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh
+++ b/jdk/test/java/awt/appletviewer/IOExceptionIfEncodedURLTest/IOExceptionIfEncodedURLTest.sh
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2008, 2012, 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
@@ -38,7 +38,7 @@
 
 #Call this from anywhere to fail the test with an error message
 # usage: fail "reason why the test failed"
-fail() 
+fail()
  { echo "The test failed :-("
    echo "$*" 1>&2
    echo "exit status was $status"
@@ -47,7 +47,7 @@
 
 #Call this from anywhere to pass the test with a message
 # usage: pass "reason why the test passed if applicable"
-pass() 
+pass()
  { echo "The test passed!!!"
    echo "$*" 1>&2
    exit 0
@@ -99,20 +99,42 @@
 case "$OS" in
    SunOS )
       VAR="One value for Sun"
-      DEFAULT_JDK=/usr/local/java/jdk1.2.1/solaris
+      DEFAULT_JDK=/
       FILESEP="/"
+      PATHSEP=":"
+      TMP="/tmp"
       ;;
 
    Linux )
       VAR="A different value for Linux"
-      DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
+      DEFAULT_JDK=/
       FILESEP="/"
+      PATHSEP=":"
+      TMP="/tmp"
       ;;
 
-   Windows_95 | Windows_98 | Windows_NT | Windows_ME | CYGWIN_NT-5.1)
+   Darwin )
+      VAR="A different value for MacOSX"
+      DEFAULT_JDK=/usr
+      FILESEP="/"
+      PATHSEP=":"
+      TMP="/tmp"
+      ;;
+
+   Windows* )
       VAR="A different value for Win32"
-      DEFAULT_JDK=/usr/local/java/jdk1.2.1/win32
+      DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
       FILESEP="\\"
+      PATHSEP=";"
+      TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
+      ;;
+
+    CYGWIN* )
+      VAR="A different value for Cygwin"
+      DEFAULT_JDK="/cygdrive/c/Program\ Files/Java/jdk1.8.0"
+      FILESEP="/"
+      PATHSEP=";"
+      TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
       ;;
 
    # catch all other OSs
@@ -132,12 +154,12 @@
 #  note that the name of the executable is in the fail string as well.
 # this is how to check for presence of the compiler, etc.
 #RESOURCE=`whence SomeProgramOrFileNeeded`
-#if [ "${RESOURCE}" = "" ] ; 
-#   then fail "Need SomeProgramOrFileNeeded to perform the test" ; 
+#if [ "${RESOURCE}" = "" ] ;
+#   then fail "Need SomeProgramOrFileNeeded to perform the test" ;
 #fi
 
-# Want this test to run standalone as well as in the harness, so do the 
-#  following to copy the test's directory into the harness's scratch directory 
+# Want this test to run standalone as well as in the harness, so do the
+#  following to copy the test's directory into the harness's scratch directory
 #  and set all appropriate variables:
 
 if [ -z "${TESTJAVA}" ] ; then
@@ -152,7 +174,7 @@
    if [ -n "$1" ] ;
       then TESTJAVA=$1
       else echo "no JDK specified on command line so using default!"
-	 TESTJAVA=$DEFAULT_JDK
+     TESTJAVA=$DEFAULT_JDK
    fi
    TESTSRC=.
    TESTCLASSES=.
@@ -161,25 +183,25 @@
 echo "JDK under test is: $TESTJAVA"
 
 #Deal with .class files:
-if [ -n "${STANDALONE}" ] ; 
-   then 
+if [ -n "${STANDALONE}" ] ;
+   then
    #if standalone, remind user to cd to dir. containing test before running it
    echo "Just a reminder: cd to the dir containing this test when running it"
    # then compile all .java files (if there are any) into .class files
-   if [ -a *.java ] ; 
+   if [ -a *.java ] ;
       then echo "Reminder, this test should be in its own directory with all"
       echo "supporting files it needs in the directory with it."
-      ${TESTJAVA}/bin/javac ./*.java ; 
+      ${TESTJAVA}/bin/javac ./*.java ;
    fi
    # else in harness so copy all the class files from where jtreg put them
-   # over to the scratch directory this test is running in. 
+   # over to the scratch directory this test is running in.
    else cp ${TESTCLASSES}/*.class . ;
 fi
 
-#if in test harness, then copy the entire directory that the test is in over 
+#if in test harness, then copy the entire directory that the test is in over
 # to the scratch directory.  This catches any support files needed by the test.
-#if [ -z "${STANDALONE}" ] ; 
-#   then cp ${TESTSRC}/* . 
+#if [ -z "${STANDALONE}" ] ;
+#   then cp ${TESTSRC}/* .
 #fi
 
 #Just before executing anything, make sure it has executable permission!
@@ -198,7 +220,7 @@
 # this shell test as appropriate ( 0 status is considered a pass here )
 
 # The test verifies that appletviewer correctly works with the different
-# names of the files, including relative and absolute paths 
+# names of the files, including relative and absolute paths
 
 # 6619458: exclude left brace from the name of the files managed by the VCS
 NAME='test.html'
diff --git a/jdk/test/java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSX.java b/jdk/test/java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSX.java
new file mode 100644
index 0000000..6f22ca2
--- /dev/null
+++ b/jdk/test/java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSX.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2012, 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 7196547
+ * @summary Dead Key implementation for KeyEvent on Mac OS X
+ * @author alexandr.scherbatiy area=awt.event
+ * @run main DeadKeyMacOSX
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.event.KeyEvent;
+import sun.awt.OSInfo;
+import sun.awt.SunToolkit;
+
+public class DeadKeyMacOSX {
+
+    private static SunToolkit toolkit;
+    private static volatile int state = 0;
+
+    public static void main(String[] args) throws Exception {
+
+        if (OSInfo.getOSType() != OSInfo.OSType.MACOSX) {
+            return;
+        }
+
+        toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        Robot robot = new Robot();
+        robot.setAutoDelay(50);
+
+        createAndShowGUI();
+
+        // Pressed keys: Alt + E + A
+        // Results:  ALT + VK_DEAD_ACUTE + a with accute accent
+        robot.keyPress(KeyEvent.VK_ALT);
+        robot.keyPress(KeyEvent.VK_E);
+        robot.keyRelease(KeyEvent.VK_E);
+        robot.keyRelease(KeyEvent.VK_ALT);
+
+        robot.keyPress(KeyEvent.VK_A);
+        robot.keyRelease(KeyEvent.VK_A);
+
+        if (state != 3) {
+            throw new RuntimeException("Wrong number of key events.");
+        }
+    }
+
+    static void createAndShowGUI() {
+        Frame frame = new Frame();
+        frame.setSize(300, 300);
+        Panel panel = new Panel();
+        panel.addKeyListener(new DeadKeyListener());
+        frame.add(panel);
+        frame.setVisible(true);
+        toolkit.realSync();
+
+        panel.requestFocusInWindow();
+        toolkit.realSync();
+    }
+
+    static class DeadKeyListener extends KeyAdapter {
+
+        @Override
+        public void keyPressed(KeyEvent e) {
+            int keyCode = e.getKeyCode();
+            char keyChar = e.getKeyChar();
+
+            switch (state) {
+                case 0:
+                    if (keyCode != KeyEvent.VK_ALT) {
+                        throw new RuntimeException("Alt is not pressed.");
+                    }
+                    state++;
+                    break;
+                case 1:
+                    if (keyCode != KeyEvent.VK_DEAD_ACUTE) {
+                        throw new RuntimeException("Dead ACUTE is not pressed.");
+                    }
+                    if (keyChar != 0xB4) {
+                        throw new RuntimeException("Pressed char is not dead acute.");
+                    }
+
+                    state++;
+                    break;
+                case 2:
+                    if (keyCode != KeyEvent.VK_A) {
+                        throw new RuntimeException("A is not pressed.");
+                    }
+                    if (keyChar != 0xE1) {
+                        throw new RuntimeException("A char does not have ACCUTE accent");
+                    }
+                    state++;
+                    break;
+                default:
+                    throw new RuntimeException("Excessive keyPressed event.");
+            }
+        }
+
+        @Override
+        public void keyTyped(KeyEvent e) {
+            int keyCode = e.getKeyCode();
+            char keyChar = e.getKeyChar();
+
+            if (state == 3) {
+                if (keyCode != 0) {
+                    throw new RuntimeException("Key code should be undefined.");
+                }
+                if (keyChar != 0xE1) {
+                    throw new RuntimeException("A char does not have ACCUTE accent");
+                }
+            } else {
+                throw new RuntimeException("Wron number of keyTyped events.");
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java b/jdk/test/java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java
new file mode 100644
index 0000000..3ae73c6
--- /dev/null
+++ b/jdk/test/java/awt/event/KeyEvent/DeadKey/DeadKeyMacOSXInputText.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012, 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 7199180
+ * @summary [macosx] Dead keys handling for input methods
+ * @author alexandr.scherbatiy area=awt.event
+ * @run main DeadKeyMacOSXInputText
+ */
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.event.KeyEvent;
+import javax.swing.JTextField;
+import sun.awt.OSInfo;
+import sun.awt.SunToolkit;
+
+public class DeadKeyMacOSXInputText {
+
+    private static SunToolkit toolkit;
+    private static volatile int state = 0;
+
+    public static void main(String[] args) throws Exception {
+
+        if (OSInfo.getOSType() != OSInfo.OSType.MACOSX) {
+            return;
+        }
+
+        toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        Robot robot = new Robot();
+        robot.setAutoDelay(50);
+
+        createAndShowGUI();
+
+        // Pressed keys: Alt + E + A
+        // Results:  ALT + VK_DEAD_ACUTE + a with accute accent
+        robot.keyPress(KeyEvent.VK_ALT);
+        robot.keyPress(KeyEvent.VK_E);
+        robot.keyRelease(KeyEvent.VK_E);
+        robot.keyRelease(KeyEvent.VK_ALT);
+
+        robot.keyPress(KeyEvent.VK_A);
+        robot.keyRelease(KeyEvent.VK_A);
+        toolkit.realSync();
+
+        if (state != 3) {
+            throw new RuntimeException("Wrong number of key events.");
+        }
+    }
+
+    static void createAndShowGUI() {
+        Frame frame = new Frame();
+        frame.setSize(300, 300);
+        Panel panel = new Panel(new BorderLayout());
+        JTextField textField = new JTextField();
+        textField.addKeyListener(new DeadKeyListener());
+        panel.add(textField, BorderLayout.CENTER);
+        frame.add(panel);
+        frame.setVisible(true);
+        toolkit.realSync();
+
+        textField.requestFocusInWindow();
+        toolkit.realSync();
+
+    }
+
+    static class DeadKeyListener extends KeyAdapter {
+
+        @Override
+        public void keyPressed(KeyEvent e) {
+            int keyCode = e.getKeyCode();
+            char keyChar = e.getKeyChar();
+
+            switch (state) {
+                case 0:
+                    if (keyCode != KeyEvent.VK_ALT) {
+                        throw new RuntimeException("Alt is not pressed.");
+                    }
+                    state++;
+                    break;
+                case 1:
+                    if (keyCode != KeyEvent.VK_DEAD_ACUTE) {
+                        throw new RuntimeException("Dead ACUTE is not pressed.");
+                    }
+                    if (keyChar != 0xB4) {
+                        throw new RuntimeException("Pressed char is not dead acute.");
+                    }
+                    state++;
+                    break;
+            }
+        }
+
+        @Override
+        public void keyTyped(KeyEvent e) {
+            int keyCode = e.getKeyCode();
+            char keyChar = e.getKeyChar();
+
+            if (state == 2) {
+                if (keyCode != 0) {
+                    throw new RuntimeException("Key code should be undefined.");
+                }
+                if (keyChar != 0xE1) {
+                    throw new RuntimeException("A char does not have ACCUTE accent");
+                }
+                state++;
+            } else {
+                throw new RuntimeException("Wron number of keyTyped events.");
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/awt/event/TextEvent/TextEventSequenceTest/TextEventSequenceTest.java b/jdk/test/java/awt/event/TextEvent/TextEventSequenceTest/TextEventSequenceTest.java
new file mode 100644
index 0000000..7836b08
--- /dev/null
+++ b/jdk/test/java/awt/event/TextEvent/TextEventSequenceTest/TextEventSequenceTest.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2012, 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 4028580
+ * @summary TextArea does not send TextEvent when setText. Does for insert
+ * @author kdm@sparc.spb.su: area= awt.TextAvent
+ * @run main TextEventSequenceTest
+ */
+import java.awt.*;
+import java.awt.event.*;
+import sun.awt.SunToolkit;
+
+public class TextEventSequenceTest {
+
+    private static Frame f;
+    private static TextField tf;
+    private static TextArea t;
+    private static int cntEmptyStrings = 0;
+    private static int cntNonEmptyStrings = 0;
+
+    public static void main(String[] args) {
+
+        test("non-empty text string");
+        test("");
+        test(null);
+    }
+
+    private static void test(String test) {
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        createAndShowGUI(test);
+        toolkit.realSync();
+
+        initCounts();
+        t.setText("Hello ");
+        toolkit.realSync();
+        t.append("World! !");
+        toolkit.realSync();
+        t.insert("from Roger Pham", 13);
+        toolkit.realSync();
+        t.replaceRange("Java Duke", 18, 28);
+        toolkit.realSync();
+        checkCounts(0, 4);
+
+        initCounts();
+        t.setText("");
+        toolkit.realSync();
+        t.setText("");
+        toolkit.realSync();
+        t.setText("");
+        toolkit.realSync();
+        checkCounts(1, 0);
+
+        initCounts();
+        tf.setText("Hello There!");
+        toolkit.realSync();
+        checkCounts(0, 1);
+
+        initCounts();
+        tf.setText("");
+        toolkit.realSync();
+        tf.setText("");
+        toolkit.realSync();
+        tf.setText("");
+        toolkit.realSync();
+        checkCounts(1, 0);
+
+        f.dispose();
+    }
+
+    private static void createAndShowGUI(String text) {
+        f = new Frame("TextEventSequenceTest");
+        f.setLayout(new FlowLayout());
+
+        TextListener listener = new MyTextListener();
+
+        tf = new TextField(text);
+        tf.addTextListener(listener);
+        f.add(tf);
+
+        t = new TextArea(text, 10, 30);
+        t.addTextListener(listener);
+        f.add(t);
+
+        f.pack();
+        f.setVisible(true);
+    }
+
+    static class MyTextListener implements TextListener {
+
+        public synchronized void textValueChanged(TextEvent e) {
+            TextComponent tc = (TextComponent) e.getSource();
+            String text = tc.getText();
+            if (text.length() == 0) {
+                cntEmptyStrings++;
+            } else {
+                cntNonEmptyStrings++;
+            }
+        }
+    }
+
+    synchronized static void initCounts() {
+        cntEmptyStrings = 0;
+        cntNonEmptyStrings = 0;
+    }
+
+    synchronized static void checkCounts(int empty, int nonempty) {
+        if (empty != cntEmptyStrings || nonempty != cntNonEmptyStrings) {
+            throw new RuntimeException(
+                    String.format("Expected events: empty = %d, nonempty = %d, "
+                    + "actual events: empty = %d, nonempty = %d",
+                    empty, nonempty, cntEmptyStrings, cntNonEmptyStrings));
+        }
+    }
+}
+
diff --git a/jdk/test/java/beans/EventHandler/Test6277266.java b/jdk/test/java/beans/EventHandler/Test6277266.java
index 60bc137..72383f4 100644
--- a/jdk/test/java/beans/EventHandler/Test6277266.java
+++ b/jdk/test/java/beans/EventHandler/Test6277266.java
@@ -51,9 +51,11 @@
                     )
             );
             throw new Error("SecurityException expected");
+        } catch (SecurityException exception) {
+            return; // expected security exception in JDK 7
         } catch (InvocationTargetException exception) {
             if (exception.getCause() instanceof SecurityException){
-                return; // expected security exception
+                return; // expected security exception in JDK 8
             }
             throw new Error("unexpected exception", exception);
         } catch (InterruptedException exception) {
diff --git a/jdk/test/java/beans/Introspector/Test7186794.java b/jdk/test/java/beans/Introspector/Test7186794.java
new file mode 100644
index 0000000..5ee13ba
--- /dev/null
+++ b/jdk/test/java/beans/Introspector/Test7186794.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 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 7186794
+ * @summary Tests setter in the super class
+ * @author Sergey Malenkov
+ */
+
+import java.util.List;
+
+public class Test7186794 {
+
+    public static void main(String[] args) {
+        if (null == BeanUtils.findPropertyDescriptor(MyBean.class, "value").getWriteMethod()) {
+            throw new Error("The property setter is not found");
+        }
+    }
+
+    public static class BaseBean {
+
+        protected List<String> value;
+
+        public void setValue(List<String> value) {
+            this.value = value;
+        }
+    }
+
+    public static class MyBean extends BaseBean {
+        public List<String> getValue() {
+            return super.value;
+        }
+    }
+}
diff --git a/jdk/test/java/beans/Introspector/Test7189112.java b/jdk/test/java/beans/Introspector/Test7189112.java
new file mode 100644
index 0000000..938731a
--- /dev/null
+++ b/jdk/test/java/beans/Introspector/Test7189112.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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 7189112
+ * @summary Tests overridden getter
+ * @author Sergey Malenkov
+ */
+
+public class Test7189112 {
+
+    public static void main(String[] args) {
+        if (null == BeanUtils.findPropertyDescriptor(MyBean.class, "value").getWriteMethod()) {
+            throw new Error("The property setter is not found");
+        }
+    }
+
+    public static class BaseBean {
+
+        private Object value;
+
+        public Object getValue() {
+            return this.value;
+        }
+
+        public void setValue(Object value) {
+            this.value = value;
+        }
+    }
+
+    public static class MyBean extends BaseBean {
+        @Override
+        public String getValue() {
+            return (String) super.getValue();
+        }
+    }
+}
diff --git a/jdk/test/java/beans/Introspector/Test7192955.java b/jdk/test/java/beans/Introspector/Test7192955.java
new file mode 100644
index 0000000..13e874b
--- /dev/null
+++ b/jdk/test/java/beans/Introspector/Test7192955.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, 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 7192955
+ * @summary Tests that all properties are bound
+ * @author Sergey Malenkov
+ */
+
+import java.beans.PropertyChangeListener;
+import java.util.List;
+
+public class Test7192955 {
+
+    public static void main(String[] args) {
+        if (!BeanUtils.findPropertyDescriptor(MyBean.class, "test").isBound()) {
+            throw new Error("a simple property is not bound");
+        }
+        if (!BeanUtils.findPropertyDescriptor(MyBean.class, "list").isBound()) {
+            throw new Error("a generic property is not bound");
+        }
+        if (!BeanUtils.findPropertyDescriptor(MyBean.class, "readOnly").isBound()) {
+            throw new Error("a read-only property is not bound");
+        }
+    }
+
+    public static class BaseBean {
+
+        private List<String> list;
+
+        public List<String> getList() {
+            return this.list;
+        }
+
+        public void setList(List<String> list) {
+            this.list = list;
+        }
+
+        public void addPropertyChangeListener(PropertyChangeListener listener) {
+        }
+
+        public void removePropertyChangeListener(PropertyChangeListener listener) {
+        }
+
+        public List<String> getReadOnly() {
+            return this.list;
+        }
+    }
+
+    public static class MyBean extends BaseBean {
+
+        private String test;
+
+        public String getTest() {
+            return this.test;
+        }
+
+        public void setTest(String test) {
+            this.test = test;
+        }
+    }
+}
diff --git a/jdk/test/java/beans/Performance/Test7122740.java b/jdk/test/java/beans/Performance/Test7122740.java
new file mode 100644
index 0000000..4924c6e
--- /dev/null
+++ b/jdk/test/java/beans/Performance/Test7122740.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2012, 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 7122740
+ * @summary Tests just a benchmark of PropertyDescriptor(String, Class) performance
+ * @author Sergey Malenkov
+ * @run main/manual Test7122740
+ */
+
+import java.beans.PropertyDescriptor;
+
+public class Test7122740 {
+    public static void main(String[] args) throws Exception {
+        long time = System.nanoTime();
+        for (int i = 0; i < 1000; i++) {
+            new PropertyDescriptor("name", PropertyDescriptor.class);
+            new PropertyDescriptor("value", Concrete.class);
+        }
+        time -= System.nanoTime();
+        System.out.println("Time (ms): " + (-time / 1000000));
+    }
+
+    public static class Abstract<T> {
+        private T value;
+        public T getValue() {
+            return this.value;
+        }
+        public void setValue(T value) {
+            this.value = value;
+        }
+    }
+
+    private static class Concrete extends Abstract<String> {
+    }
+}
diff --git a/jdk/test/java/beans/Performance/Test7184799.java b/jdk/test/java/beans/Performance/Test7184799.java
new file mode 100644
index 0000000..563328a
--- /dev/null
+++ b/jdk/test/java/beans/Performance/Test7184799.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 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 7184799
+ * @summary Tests just a benchmark of Introspector.getBeanInfo(Class) performance
+ * @author Sergey Malenkov
+ * @run main/manual Test7184799
+ */
+
+import java.beans.Introspector;
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+
+public class Test7184799 {
+    private static final Class[] TYPES = {
+            Class.class,
+            String.class,
+            Character.class,
+            Boolean.class,
+            Byte.class,
+            Short.class,
+            Integer.class,
+            Long.class,
+            Float.class,
+            Double.class,
+            Collection.class,
+            Set.class,
+            HashSet.class,
+            TreeSet.class,
+            LinkedHashSet.class,
+            Map.class,
+            HashMap.class,
+            TreeMap.class,
+            LinkedHashMap.class,
+            WeakHashMap.class,
+            ConcurrentHashMap.class,
+            Dictionary.class,
+            Exception.class,
+    };
+
+    public static void main(String[] args) throws Exception {
+        long time = System.nanoTime();
+        for (Class type : TYPES) {
+            Introspector.getBeanInfo(type);
+        }
+        time -= System.nanoTime();
+        System.out.println("Time (ms): " + (-time / 1000000));
+    }
+}
diff --git a/jdk/test/java/io/File/MacPathTest.java b/jdk/test/java/io/File/MacPathTest.java
new file mode 100644
index 0000000..9b310c1
--- /dev/null
+++ b/jdk/test/java/io/File/MacPathTest.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (c) 2008, 2012, 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 7130915
+ * @summary Tests file path with nfc/nfd forms on MacOSX
+ * @build MacPathTest
+ * @run shell MacPathTest.sh
+ */
+
+import java.io.*;
+import java.text.*;
+import java.util.*;
+
+public class MacPathTest {
+
+    public static void main(String args[]) throws Throwable {
+        String osname = System.getProperty("os.name");
+        if (!osname.contains("OS X") && !osname.contains("Darwin"))
+            return;
+
+        // English
+        test("TestDir_apple",                                    // test dir
+             "dir_macosx",                                       // dir
+             "file_macosx");                                     // file
+
+        // Japanese composite character
+        test("TestDir_\u30c8\u30a4\u30e4\u30cb\u30ca\u30eb/",
+             "dir_\u30a4\u30c1\u30b4\u306e\u30b1\u30fc\u30ad",
+             "file_\u30a4\u30c1\u30b4\u306e\u30b1\u30fc\u30ad");
+
+        // latin-1 supplementory
+        test("TestDir_K\u00f6rperlich\u00e4\u00df/",
+             "dir_Entt\u00e4uschung",
+             "file_Entt\u00e4uschung");
+
+        test("TestDir_K\u00f6rperlich\u00e4\u00df/",
+             "dir_Entt\u00c4uschung",
+             "file_Entt\u00c4uschung");
+
+        // Korean syblla
+        test("TestDir_\uac00\uac01\uac02",
+             "dir_\uac20\uac21\uac22",
+             "file_\uacc0\uacc1\uacc2");
+    }
+
+    private static void removeAll(File file) throws Throwable {
+        if (file.isDirectory()) {
+            for (File f : file.listFiles()) {
+                removeAll(f);
+            }
+        }
+        file.delete();
+    }
+
+    private static boolean equal(Object x, Object y) {
+        return x == null ? y == null : x.equals(y);
+    }
+
+    private static boolean match(File target, File src) {
+        if (target.equals(src)) {
+            String fname = target.toString();
+            System.out.printf("    ->matched   : [%s], length=%d%n", fname, fname.length());
+            return true;
+        }
+        return false;
+    }
+
+    private static void open_read(String what, File file) throws Throwable {
+        try (FileInputStream fis = new FileInputStream(file)) {
+           byte[] bytes = new byte[10];
+           fis.read(bytes);
+           System.out.printf("    %s:%s%n", what, new String(bytes));
+        }
+    }
+
+    private static void test(String testdir, String dname, String fname_nfc)
+        throws Throwable
+    {
+        String fname = null;
+        String dname_nfd = Normalizer.normalize(dname, Normalizer.Form.NFD);
+        String fname_nfd = Normalizer.normalize(fname_nfc, Normalizer.Form.NFD);
+
+        System.out.printf("%n%n--------Testing...----------%n");
+        File base = new File(testdir);
+        File dir  = new File(base, dname);
+        File dir_nfd =  new File(base, dname_nfd);
+        File file_nfc = new File(base, fname_nfc);
+        File file_nfd = new File(base, fname_nfd);
+
+        System.out.printf("base           :[%s][len=%d]%n", testdir, testdir.length());
+        System.out.printf("dir            :[%s][len=%d]%n", dname, dname.length());
+        System.out.printf("fname_nfc      :[%s][len=%d]%n", fname_nfc, fname_nfc.length());
+        System.out.printf("fname_nfd      :[%s][len=%d]%n", fname_nfd, fname_nfd.length());
+
+        fname = file_nfc.toString();
+        System.out.printf("file_nfc ->[%s][len=%d]%n", fname, fname.length());
+        fname = file_nfd.toString();
+        System.out.printf("file_nfd ->[%s][len=%d]%n%n", fname, fname.length());
+
+        removeAll(base);
+        dir.mkdirs();
+
+        fname = dir.toString();
+        System.out.printf(":Directory [%s][len=%d] created%n", fname, fname.length());
+
+        //////////////////////////////////////////////////////////////
+        if (!dir.isDirectory() || !dir_nfd.isDirectory()) {
+            throw new RuntimeException("File.isDirectory() failed");
+        }
+
+        //////////////////////////////////////////////////////////////
+        // write to via nfd
+        try (FileOutputStream fos = new FileOutputStream(file_nfd)) {
+           fos.write('n'); fos.write('f'); fos.write('d');
+        }
+        open_read("read in with nfc (from nfd)", file_nfc);
+        file_nfd.delete();
+
+        //////////////////////////////////////////////////////////////
+        // write to with nfc
+        try (FileOutputStream fos = new FileOutputStream(file_nfc)) {
+           fos.write('n'); fos.write('f'); fos.write('c');
+        }
+        open_read("read in with nfd      (from nfc)", file_nfd);
+        //file_nfc.delete();
+
+        //////////////////////////////////////////////////////////////
+        boolean found_dir = false;
+        boolean found_file_nfc = false;
+        boolean found_file_nfd = false;
+
+        for (File f : base.listFiles()) {
+            fname = f.toString();
+            System.out.printf("Found   : [%s], length=%d%n", fname, fname.length());
+            found_dir      |= match(dir, f);
+            found_file_nfc |= match(file_nfc, f);
+            found_file_nfd |= match(file_nfd, f);
+        }
+
+        if (!found_dir || !found_file_nfc || !found_file_nfc) {
+            throw new RuntimeException("File.equal() failed");
+        }
+        removeAll(base);
+    }
+}
diff --git a/jdk/make/sun/rmi/rmi/mapfile-vers b/jdk/test/java/io/File/MacPathTest.sh
similarity index 68%
copy from jdk/make/sun/rmi/rmi/mapfile-vers
copy to jdk/test/java/io/File/MacPathTest.sh
index dc33402..ebba514 100644
--- a/jdk/make/sun/rmi/rmi/mapfile-vers
+++ b/jdk/test/java/io/File/MacPathTest.sh
@@ -1,12 +1,12 @@
+#! /bin/sh
+
 #
-# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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.
+# 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
@@ -22,12 +22,18 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
+#
+OS=`uname -s`
+case "$OS" in
+  Darwin ) ;;
+  * )
+    exit 0
+    ;;
+esac
 
-# Define library interface.
+if [ "x$TESTJAVA" = x ]; then
+  TESTJAVA=$1; shift
+  TESTCLASSES=.
+fi
 
-SUNWprivate_1.1 {
-	global:
-	    Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader;
-	local:
-	    *;
-};
+export LC_ALL=en_US.UTF-8 ;${TESTJAVA}/bin/java -cp ${TESTCLASSES} MacPathTest
diff --git a/jdk/test/java/lang/ProcessBuilder/Basic.java b/jdk/test/java/lang/ProcessBuilder/Basic.java
index cd37d4f..e7c9f09 100644
--- a/jdk/test/java/lang/ProcessBuilder/Basic.java
+++ b/jdk/test/java/lang/ProcessBuilder/Basic.java
@@ -36,9 +36,11 @@
 import static java.lang.ProcessBuilder.Redirect.*;
 
 import java.io.*;
+import java.lang.reflect.Field;
 import java.util.*;
 import java.util.concurrent.CountDownLatch;
 import java.security.*;
+import sun.misc.Unsafe;
 import java.util.regex.Pattern;
 import java.util.regex.Matcher;
 import static java.lang.System.getenv;
@@ -1908,17 +1910,21 @@
                 final byte[] bytes = new byte[10];
                 final Process p = new ProcessBuilder(childArgs).start();
                 final CountDownLatch latch = new CountDownLatch(1);
+                final InputStream s;
+                switch (action & 0x1) {
+                    case 0: s = p.getInputStream(); break;
+                    case 1: s = p.getErrorStream(); break;
+                    default: throw new Error();
+                }
                 final Thread thread = new Thread() {
                     public void run() {
                         try {
-                            latch.countDown();
                             int r;
-                            switch (action) {
-                            case 0: r = p.getInputStream().read(); break;
-                            case 1: r = p.getErrorStream().read(); break;
-                            case 2: r = p.getInputStream().read(bytes); break;
-                            case 3: r = p.getErrorStream().read(bytes); break;
-                            default: throw new Error();
+                            latch.countDown();
+                            switch (action & 0x2) {
+                                case 0: r = s.read(); break;
+                                case 2: r = s.read(bytes); break;
+                                default: throw new Error();
                             }
                             equal(-1, r);
                         } catch (Throwable t) { unexpected(t); }}};
@@ -1926,6 +1932,40 @@
                 thread.start();
                 latch.await();
                 Thread.sleep(10);
+
+                String os = System.getProperty("os.name");
+                if (os.equalsIgnoreCase("Solaris") ||
+                    os.equalsIgnoreCase("SunOS"))
+                {
+                    final Object deferred;
+                    Class<?> c = s.getClass();
+                    if (c.getName().equals(
+                        "java.lang.UNIXProcess$DeferredCloseInputStream"))
+                    {
+                        deferred = s;
+                    } else {
+                        Field deferredField = p.getClass().
+                            getDeclaredField("stdout_inner_stream");
+                        deferredField.setAccessible(true);
+                        deferred = deferredField.get(p);
+                    }
+                    Field useCountField = deferred.getClass().
+                        getDeclaredField("useCount");
+                    useCountField.setAccessible(true);
+
+                    while (useCountField.getInt(deferred) <= 0) {
+                        Thread.yield();
+                    }
+                } else if (s instanceof BufferedInputStream) {
+                    Field f = Unsafe.class.getDeclaredField("theUnsafe");
+                    f.setAccessible(true);
+                    Unsafe unsafe = (Unsafe)f.get(null);
+
+                    while (unsafe.tryMonitorEnter(s)) {
+                        unsafe.monitorExit(s);
+                        Thread.sleep(1);
+                    }
+                }
                 p.destroy();
                 thread.join();
             }
diff --git a/jdk/test/java/lang/invoke/7157574/Test7157574.java b/jdk/test/java/lang/invoke/7157574/Test7157574.java
new file mode 100644
index 0000000..f7f2a24
--- /dev/null
+++ b/jdk/test/java/lang/invoke/7157574/Test7157574.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2012, 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.
+ *
+ */
+
+/*
+7157574 method handles returned by reflective lookup API sometimes have wrong receiver type
+
+When an inherited non-static field or method is looked up in a class C using Lookup.findVirtual(C...), etc., the JSR 292 API, the first argument of the resulting method handle must be the receiver ('this'), and must be the requested class (or more specific, in the case of findSpecial or a lookup of a protected method).
+
+But currently, if a supertype T defines the looked-up method or field and C inherits it, the returned method handle might have the more specific initial type T.
+
+The relevant javadoc (and 292 spec.) is as follows:
+    * The formal parameter {@code this} stands for the self-reference of type {@code C};
+    * if it is present, it is always the leading argument to the method handle invocation.
+    * (In the case of some {@code protected} members, {@code this} may be
+    * restricted in type to the lookup class; see below.)
+
+Because of this bug, all of the assertions fail in the following example:
+*/
+
+/* @test
+ * @bug 7157574
+ * @summary method handles returned by reflective lookup API sometimes have wrong receiver type
+ *
+ * @run main Test7157574
+ */
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+public class Test7157574 {
+    interface Intf { void ig1(); void ig2(); void ig3(); void ig4(); void m1(); }
+    static abstract class Super implements Intf { public abstract void m2(); public int f2; }
+    static abstract class Sub extends Super { }
+    public static void main(String... av) throws Throwable {
+        MethodHandle m1 = lookup().findVirtual(Sub.class, "m1", methodType(void.class));
+        System.out.println(m1);
+        MethodHandle m2 = lookup().findVirtual(Sub.class, "m2", methodType(void.class));
+        System.out.println(m2);
+        MethodHandle f2 = lookup().findGetter(Sub.class, "f2", int.class);
+        System.out.println(f2);
+        MethodHandle f2s = lookup().findSetter(Sub.class, "f2", int.class);
+        System.out.println(f2s);
+        MethodHandle chc = lookup().findVirtual(Sub.class,  "hashCode", methodType(int.class));
+        System.out.println(chc);
+        MethodHandle ihc = lookup().findVirtual(Intf.class, "hashCode", methodType(int.class));
+        System.out.println(ihc);
+        assertEquals(Sub.class, m1.type().parameterType(0));
+        assertEquals(Sub.class, m2.type().parameterType(0));
+        assertEquals(Sub.class, f2.type().parameterType(0));
+        assertEquals(Sub.class, f2s.type().parameterType(0));
+        assertEquals(Sub.class, chc.type().parameterType(0));
+        assertEquals(Intf.class, ihc.type().parameterType(0));
+        // test the MHs on a concrete version of Sub
+        class C extends Sub {
+            public void m1() { this.f2 = -1; }
+            public void m2() { this.f2 = -2; }
+            // Pack the vtable of Intf with leading junk:
+            private void ig() { throw new RuntimeException(); }
+            public void ig1() { ig(); }
+            public void ig2() { ig(); }
+            public void ig3() { ig(); }
+            public void ig4() { ig(); }
+        }
+        testConcrete(new C(), m1, m2, f2, f2s, chc, ihc);
+    }
+    private static void testConcrete(Sub s,
+                                     MethodHandle m1, MethodHandle m2,
+                                     MethodHandle f2, MethodHandle f2s,
+                                     MethodHandle chc, MethodHandle ihc
+                                     ) throws Throwable {
+        s.f2 = 0;
+        m1.invokeExact(s);
+        assertEquals(-1, s.f2);
+        m2.invokeExact(s);
+        assertEquals(-2, s.f2);
+        s.f2 = 2;
+        assertEquals(2, (int) f2.invokeExact(s));
+        f2s.invokeExact(s, 0);
+        assertEquals(0, s.f2);
+        assertEquals(s.hashCode(), (int) chc.invokeExact(s));
+        assertEquals(s.hashCode(), (int) ihc.invokeExact((Intf)s));
+    }
+
+    private static void assertEquals(Object expect, Object observe) {
+        if (java.util.Objects.equals(expect, observe))  return;
+        String msg = ("expected "+expect+" but observed "+observe);
+        System.out.println("FAILED: "+msg);
+        throw new AssertionError(msg);
+    }
+}
diff --git a/jdk/test/java/lang/invoke/BigArityTest.java b/jdk/test/java/lang/invoke/BigArityTest.java
new file mode 100644
index 0000000..fa4d597
--- /dev/null
+++ b/jdk/test/java/lang/invoke/BigArityTest.java
@@ -0,0 +1,1044 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/* @test
+ * @summary High arity invocations, up to the maximum of 255 arguments
+ * @compile BigArityTest.java
+ * @run junit/othervm -DBigArityTest.ITERATION_COUNT=1 test.java.lang.invoke.BigArityTest
+ */
+
+package test.java.lang.invoke;
+
+import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodType;
+import java.lang.invoke.WrongMethodTypeException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Objects;
+import static org.junit.Assert.assertEquals;
+import org.junit.Test;
+
+public class BigArityTest {
+
+    static MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
+
+    static final int MAX_JVM_ARITY = 255;
+    static final int ITERATION_COUNT = getProperty("ITERATION_COUNT", 40000);
+    static final int MIN_ARITY = getProperty("MIN_ARITY", 250);
+    static final int SLOW_ARITY = getProperty("SLOW_ARITY", MAX_JVM_ARITY-3);
+    static final int MAX_ARITY = getProperty("MAX_ARITY", MAX_JVM_ARITY-1);  // always -1 for the MH reciever itself
+    private static int getProperty(String name, int dflt) {
+        return Integer.parseInt(getProperty(name, ""+dflt));
+    }
+    private static String getProperty(String name, String dflt) {
+        String x = System.getProperty(BigArityTest.class.getSimpleName() + "." + name);
+        if (x == null)  x = System.getProperty(BigArityTest.class.getName() + "." + name);
+        return x == null ? dflt : x;
+    }
+
+    static Object hashArguments(Object... args) {
+        return Objects.hash(args);
+    }
+    static final MethodHandle MH_hashArguments_VA;
+    static {
+        try {
+            MH_hashArguments_VA =
+                MethodHandles.lookup().unreflect(
+                    BigArityTest.class.getDeclaredMethod("hashArguments", Object[].class));
+        } catch (ReflectiveOperationException ex) {
+            throw new Error(ex);
+        }
+    }
+    static MethodHandle MH_hashArguments(int arity) {
+        MethodType mt = MethodType.genericMethodType(arity);
+        return MH_hashArguments_VA.asType(mt);
+    }
+    static MethodHandle MH_hashArguments(Class<? extends Object[]> arrayClass, int arity) {
+        if (arrayClass == Object[].class)
+            return MH_hashArguments(arity);
+        ArrayList<Class<?>> ptypes = new ArrayList<>(Collections.<Class<?>>nCopies(arity, arrayClass.getComponentType()));
+        MethodType mt = MethodType.methodType(Object.class, ptypes);
+        return MH_hashArguments_VA.asType(mt);
+    }
+
+    static Object[] testArgs(int arity) {
+        Object args[] = new Object[arity];
+        for (int i = 0; i < arity; i++)
+            args[i] = i * (i + 1) / 2;
+        return args;
+    }
+
+    @Test
+    public void testBoundaryValues() throws Throwable {
+        for (int badArity : new int[]{ -1, MAX_JVM_ARITY+1, MAX_JVM_ARITY }) {
+            try {
+                MethodHandle badmh = MH_hashArguments(badArity);
+                throw new AssertionError("should not be able to build a 255-arity MH: "+badmh);
+            } catch (IllegalArgumentException | WrongMethodTypeException ex) {
+                System.out.println("OK: "+ex);
+            }
+        }
+    }
+
+    // Make sure the basic argument spreading and varargs mechanisms are working.
+    // Exercise arity 3 thoroughly.
+    @Test
+    public void testSpreads() throws Throwable {
+        System.out.println("testing asSpreader on arity=3");
+        Object[] args = testArgs(3);
+        int r0 = Objects.hash(args);
+        MethodHandle mh = MH_hashArguments(3);
+        Object r;
+        r = mh.invokeExact(args[0], args[1], args[2]);
+        assertEquals(r0, r);
+        r = mh.invoke(args[0], args[1], args[2]);
+        assertEquals(r0, r);
+        r = mh.invoke((Comparable) args[0], (Integer) args[1], (Number) args[2]);
+        assertEquals(r0, r);
+        r = mh.invokeWithArguments(args);
+        assertEquals(r0, r);
+        for (Class<?> cls0 : new Class<?>[] {
+            Object[].class, Number[].class, Integer[].class, Comparable[].class
+        }) {
+            @SuppressWarnings("unchecked")
+            Class<? extends Object[]> cls = (Class<? extends Object[]>) cls0;
+            //Class<? extends Object[]> cls = Object[].class.asSubclass(cls0);
+            int nargs = args.length, skip;
+            MethodHandle smh = mh.asSpreader(cls, nargs - (skip = 0));
+            Object[] tail = Arrays.copyOfRange(args, skip, nargs, cls);
+            if (cls == Object[].class)
+                r = smh.invokeExact(tail);
+            else if (cls == Integer[].class)
+                r = smh.invokeExact((Integer[]) tail);
+            else
+                r = smh.invoke(tail);
+            assertEquals(r0, r);
+            smh = mh.asSpreader(cls, nargs - (skip = 1));
+            tail = Arrays.copyOfRange(args, skip, nargs, cls);
+            if (cls == Object[].class)
+                r = smh.invokeExact(args[0], tail);
+            else if (cls == Integer[].class)
+                r = smh.invokeExact(args[0], (Integer[]) tail);
+            else
+                r = smh.invoke(args[0], tail);
+            assertEquals(r0, r);
+            smh = mh.asSpreader(cls, nargs - (skip = 2));
+            tail = Arrays.copyOfRange(args, skip, nargs, cls);
+            if (cls == Object[].class)
+                r = smh.invokeExact(args[0], args[1], tail);
+            else if (cls == Integer[].class)
+                r = smh.invokeExact(args[0], args[1], (Integer[]) tail);
+            else
+                r = smh.invoke(args[0], args[1], tail);
+            assertEquals(r0, r);
+            smh = mh.asSpreader(cls, nargs - (skip = 3));
+            tail = Arrays.copyOfRange(args, skip, nargs, cls);
+            if (cls == Object[].class)
+                r = smh.invokeExact(args[0], args[1], args[2], tail);
+            else if (cls == Integer[].class)
+                r = smh.invokeExact(args[0], args[1], args[2], (Integer[]) tail);
+            else
+                r = smh.invoke(args[0], args[1], args[2], tail);
+            assertEquals(r0, r);
+            // Try null array in addition to zero-length array:
+            tail = null;
+            if (cls == Object[].class)
+                r = smh.invokeExact(args[0], args[1], args[2], tail);
+            else if (cls == Integer[].class)
+                r = smh.invokeExact(args[0], args[1], args[2], (Integer[]) tail);
+            else
+                r = smh.invoke(args[0], args[1], args[2], tail);
+            assertEquals(r0, r);
+        }
+    }
+
+    @Test
+    public void testInvokeWithArguments() throws Throwable {
+        System.out.println("testing invokeWithArguments on all arities");
+        for (int arity = 0; arity < MAX_ARITY; arity++) {
+            Object[] args = testArgs(arity);
+            Object r0 = Objects.hash(args);
+            Object r = MH_hashArguments(arity).invokeWithArguments(args);
+            assertEquals("arity="+arity, r0, r);
+        }
+        // The next one is the most likely to fail:
+        int arity = MAX_ARITY;
+        Object[] args = testArgs(arity);
+        Object r0 = Objects.hash(args);
+        Object r = MH_hashArguments(arity).invokeWithArguments(args);
+        assertEquals("arity=MAX_ARITY", r0, r);
+    }
+
+    static Object[] cat(Object a, Object[] b) {
+        int alen = 1, blen = b.length;
+        Object[] c = new Object[alen + blen];
+        c[0] = a;
+        System.arraycopy(b, 0, c, alen, blen);
+        return c;
+    }
+
+    @Test
+    public void testArities() throws Throwable {
+        System.out.println("testing spreaders and collectors on high arities...");
+            int iterations = ITERATION_COUNT;
+        testArities(Object[].class, MIN_ARITY-10, MIN_ARITY-1, iterations / 1000);
+        testArities(Object[].class, MIN_ARITY, SLOW_ARITY-1, iterations);
+        testArities(Object[].class, SLOW_ARITY, MAX_ARITY, iterations / 1000);
+    }
+
+    @Test
+    public void testAritiesOnTypedArrays() throws Throwable {
+        for (Class<?> cls0 : new Class<?>[] {
+            Number[].class, Integer[].class, Comparable[].class
+        }) {
+            @SuppressWarnings("unchecked")
+            Class<? extends Object[]> cls = (Class<? extends Object[]>) cls0;
+            System.out.println("array class: "+cls.getSimpleName());
+            int iterations = ITERATION_COUNT / 1000;
+            testArities(cls, MIN_ARITY, SLOW_ARITY-1, iterations);
+            testArities(cls, SLOW_ARITY, MAX_ARITY, iterations / 100);
+        }
+    }
+
+    private void testArities(Class<? extends Object[]> cls,
+                             int minArity,
+                             int maxArity,
+                             int iterations) throws Throwable {
+        boolean verbose = (cls == Object[].class);
+        for (int arity = minArity; arity <= maxArity; arity++) {
+            if (verbose)  System.out.println("arity="+arity);
+            MethodHandle mh = MH_hashArguments(cls, arity);
+            MethodHandle mh_VA = mh.asSpreader(cls, arity);
+            assert(mh_VA.type().parameterType(0) == cls);
+            testArities(cls, arity, iterations, verbose, mh, mh_VA);
+            if (cls != Object[].class) {
+                // mh_CA will collect arguments of a particular type and pass them to mh_VA
+                MethodHandle mh_CA = mh_VA.asCollector(cls, arity);
+                MethodHandle mh_VA2 = mh_CA.asSpreader(cls, arity);
+                try {
+                    mh_VA2.invokeWithArguments(new Object[arity]);
+                    throw new AssertionError("should not reach");
+                } catch (ClassCastException | WrongMethodTypeException ex) {
+                }
+                assert(mh_CA.type().equals(mh.type()));
+                assert(mh_VA2.type().equals(mh_VA.type()));
+                testArities(cls, arity, iterations, false, mh_CA, mh_VA2);
+            }
+        }
+    }
+    private void testArities(Class<? extends Object[]> cls,
+                             int arity,
+                             int iterations,
+                             boolean verbose,
+                             MethodHandle mh,
+                             MethodHandle mh_VA
+                             ) throws Throwable {
+        if (iterations < 4)  iterations = 4;
+        final int MAX_MH_ARITY      = MAX_JVM_ARITY - 1;  // mh.invoke(arg*[N])
+        final int MAX_INVOKER_ARITY = MAX_MH_ARITY - 1;   // inv.invoke(mh, arg*[N])
+        Object[] args = testArgs(arity);
+        if (cls != Object[].class)
+            args = Arrays.copyOf(args, arity, cls);
+        Object r0 = Objects.hash(args);
+        Object r;
+        MethodHandle ximh = null;
+        MethodHandle gimh = null;
+        if (arity <= MAX_INVOKER_ARITY) {
+            ximh = MethodHandles.exactInvoker(mh.type());
+            gimh = MethodHandles.invoker(mh.type());
+        } else {
+            try {
+                ximh = MethodHandles.exactInvoker(mh.type());
+                throw new AssertionError("should fail to create ximh of arity "+arity);
+            } catch (IllegalArgumentException ex) {
+                if (verbose)
+                    System.out.println("OK: xmih["+arity+"] => "+ex);
+            }
+            try {
+                gimh = MethodHandles.invoker(mh.type());
+                throw new AssertionError("should fail to create gimh of arity "+arity);
+            } catch (IllegalArgumentException ex) {
+                if (verbose)
+                    System.out.println("OK: gmih["+arity+"] => "+ex);
+            }
+        }
+        Object[] mh_args = cat(mh, args);
+        assert(arity <= MAX_MH_ARITY);
+        for (int i = 0; i < iterations; ++i) {
+            if (cls == Object[].class)
+                r = mh_VA.invokeExact(args);
+            else if (cls == Integer[].class)
+                r = mh_VA.invokeExact((Integer[])args);
+            else
+                r = mh_VA.invoke(args);
+            assertEquals(r0, r);
+            r = mh.invokeWithArguments(args);
+            assertEquals(r0, r);
+            if (ximh != null) {
+                r = ximh.invokeWithArguments(mh_args);
+                assertEquals(r0, r);
+            }
+            if (gimh != null) {
+                r = gimh.invokeWithArguments(mh_args);
+                assertEquals(r0, r);
+            }
+        }
+    }
+
+    static Object hashArguments_252(
+    // <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
+    Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
+    Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
+    Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
+    Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
+    Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
+    Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
+    Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
+    Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
+    Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
+    Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
+    Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
+    Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
+    Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
+    Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
+    Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
+    Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
+    Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
+    Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
+    Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
+    Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
+    Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
+    Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
+    Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
+    Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
+    Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
+    Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
+    Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
+    Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
+    Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
+    Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
+    Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
+    // </editor-fold>
+    Object xF8, Object xF9, Object xFA, Object xFB) {
+        return Objects.hash(
+    // <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
+    x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+    x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+    x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+    x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+    x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+    x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+    x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+    x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+    x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+    x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+    xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+    xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+    xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+    xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+    xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+    xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
+    // </editor-fold>
+    xF8, xF9, xFA, xFB);
+    }
+
+    @Test
+    public void test252() throws Throwable {
+        final int ARITY = 252;
+        System.out.println("test"+ARITY);
+        Object[] a = testArgs(ARITY);
+        Object r0 = hashArguments(a);
+        Object r;
+        r = hashArguments_252(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+        assertEquals(r0, r);
+        MethodType mt = MethodType.genericMethodType(ARITY);
+        MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+        r = mh.invokeExact(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+        assertEquals(r0, r);
+        r = mh.invokeWithArguments(a);
+        assertEquals(r0, r);
+        MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
+        r = ximh.invokeExact(mh,
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+        assertEquals(r0, r);
+        r = ximh.invokeWithArguments(cat(mh,a));
+        assertEquals(r0, r);
+        MethodHandle gimh = MethodHandles.invoker(mh.type());
+        r = gimh.invoke(mh,
+    // <editor-fold defaultstate="collapsed" desc="(Number) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    (Number)
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+        assertEquals(r0, r);
+        r = gimh.invokeWithArguments(cat(mh,a));
+        assertEquals(r0, r);
+        mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
+        //System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
+        r = mh.invokeExact(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    (Integer)
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+        assertEquals(r0, r);
+        r = mh.invoke(
+    // <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    (Comparable<?>)
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB]);
+        assertEquals(r0, r);
+    }
+
+    static Object hashArguments_253(
+    // <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
+    Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
+    Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
+    Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
+    Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
+    Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
+    Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
+    Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
+    Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
+    Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
+    Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
+    Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
+    Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
+    Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
+    Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
+    Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
+    Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
+    Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
+    Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
+    Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
+    Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
+    Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
+    Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
+    Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
+    Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
+    Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
+    Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
+    Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
+    Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
+    Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
+    Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
+    Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
+    // </editor-fold>
+    Object xF8, Object xF9, Object xFA, Object xFB, Object xFC) {
+        return Objects.hash(
+    // <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
+    x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+    x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+    x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+    x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+    x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+    x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+    x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+    x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+    x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+    x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+    xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+    xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+    xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+    xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+    xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+    xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
+    // </editor-fold>
+    xF8, xF9, xFA, xFB, xFC);
+    }
+
+    @Test
+    public void test253() throws Throwable {
+        final int ARITY = 253;
+        System.out.println("test"+ARITY);
+        Object[] a = testArgs(ARITY);
+        Object r0 = hashArguments(a);
+        Object r;
+        r = hashArguments_253(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+        assertEquals(r0, r);
+        MethodType mt = MethodType.genericMethodType(ARITY);
+        MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+        r = mh.invokeExact(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+        assertEquals(r0, r);
+        r = mh.invokeWithArguments(a);
+        assertEquals(r0, r);
+        MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
+        r = ximh.invokeExact(mh,
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+        assertEquals(r0, r);
+        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+        r = ximh.invokeWithArguments(cat(mh,a));
+        assertEquals(r0, r);
+        MethodHandle gimh = MethodHandles.invoker(mh.type());
+        r = gimh.invoke(mh,
+    // <editor-fold defaultstate="collapsed" desc="(Number) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    (Number)
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+        assertEquals(r0, r);
+        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+        r = gimh.invokeWithArguments(cat(mh,a));
+        assertEquals(r0, r);
+        mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
+        //System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
+        r = mh.invokeExact(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    (Integer)
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+        assertEquals(r0, r);
+        r = mh.invoke(
+    // <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    (Comparable<?>)
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC]);
+        assertEquals(r0, r);
+    }
+
+    static Object hashArguments_254(
+    // <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
+    Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
+    Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
+    Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
+    Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
+    Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
+    Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
+    Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
+    Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
+    Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
+    Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
+    Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
+    Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
+    Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
+    Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
+    Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
+    Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
+    Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
+    Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
+    Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
+    Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
+    Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
+    Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
+    Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
+    Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
+    Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
+    Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
+    Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
+    Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
+    Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
+    Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
+    Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
+    // </editor-fold>
+    Object xF8, Object xF9, Object xFA, Object xFB, Object xFC, Object xFD) {
+        return Objects.hash(
+    // <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
+    x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+    x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+    x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+    x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+    x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+    x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+    x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+    x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+    x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+    x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+    xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+    xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+    xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+    xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+    xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+    xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
+    // </editor-fold>
+    xF8, xF9, xFA, xFB, xFC, xFD);
+    }
+
+    @Test
+    public void test254() throws Throwable {
+        final int ARITY = 254;
+        System.out.println("test"+ARITY);
+        Object[] a = testArgs(ARITY);
+        Object r0 = hashArguments(a);
+        Object r;
+        r = hashArguments_254(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+        assertEquals(r0, r);
+        MethodType mt = MethodType.genericMethodType(ARITY);
+        MethodHandle mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+        r = mh.invokeExact(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+        assertEquals(r0, r);
+        // FIXME: This next one fails, because it uses an internal invoker of arity 255.
+        r = mh.invokeWithArguments(a);
+        assertEquals(r0, r);
+        try {
+            MethodHandle ximh = MethodHandles.exactInvoker(mh.type());
+            throw new AssertionError("should have thrown IAE; cannot have 1+1+254 arguments");
+        } catch (IllegalArgumentException ex) {
+            System.out.println("OK: "+ex);
+        }
+        mh = mh.asType(mh.type().changeParameterType(0x10, Integer.class));
+        //System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
+        r = mh.invokeExact(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    (Integer)
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+        assertEquals(r0, r);
+        mh = mh.asType(mh.type().changeParameterType(0xE0, Number.class));
+        //System.out.println("type="+mh.type().toString().replaceAll("Object", ""));
+        r = mh.invokeExact(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ... (Integer) a[0x10], ... (Number) a[0xE0], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    (Integer)
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    (Number)
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+        assertEquals(r0, r);
+        r = mh.invoke(
+    // <editor-fold defaultstate="collapsed" desc="(Comparable) a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    (Comparable<?>)
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD]);
+        assertEquals(r0, r);
+    }
+
+    static Object hashArguments_255(
+    // <editor-fold defaultstate="collapsed" desc="Object x00, Object x01, Object x02, Object x03, Object x04, ...">
+    Object x00, Object x01, Object x02, Object x03, Object x04, Object x05, Object x06, Object x07,
+    Object x08, Object x09, Object x0A, Object x0B, Object x0C, Object x0D, Object x0E, Object x0F,
+    Object x10, Object x11, Object x12, Object x13, Object x14, Object x15, Object x16, Object x17,
+    Object x18, Object x19, Object x1A, Object x1B, Object x1C, Object x1D, Object x1E, Object x1F,
+    Object x20, Object x21, Object x22, Object x23, Object x24, Object x25, Object x26, Object x27,
+    Object x28, Object x29, Object x2A, Object x2B, Object x2C, Object x2D, Object x2E, Object x2F,
+    Object x30, Object x31, Object x32, Object x33, Object x34, Object x35, Object x36, Object x37,
+    Object x38, Object x39, Object x3A, Object x3B, Object x3C, Object x3D, Object x3E, Object x3F,
+    Object x40, Object x41, Object x42, Object x43, Object x44, Object x45, Object x46, Object x47,
+    Object x48, Object x49, Object x4A, Object x4B, Object x4C, Object x4D, Object x4E, Object x4F,
+    Object x50, Object x51, Object x52, Object x53, Object x54, Object x55, Object x56, Object x57,
+    Object x58, Object x59, Object x5A, Object x5B, Object x5C, Object x5D, Object x5E, Object x5F,
+    Object x60, Object x61, Object x62, Object x63, Object x64, Object x65, Object x66, Object x67,
+    Object x68, Object x69, Object x6A, Object x6B, Object x6C, Object x6D, Object x6E, Object x6F,
+    Object x70, Object x71, Object x72, Object x73, Object x74, Object x75, Object x76, Object x77,
+    Object x78, Object x79, Object x7A, Object x7B, Object x7C, Object x7D, Object x7E, Object x7F,
+    Object x80, Object x81, Object x82, Object x83, Object x84, Object x85, Object x86, Object x87,
+    Object x88, Object x89, Object x8A, Object x8B, Object x8C, Object x8D, Object x8E, Object x8F,
+    Object x90, Object x91, Object x92, Object x93, Object x94, Object x95, Object x96, Object x97,
+    Object x98, Object x99, Object x9A, Object x9B, Object x9C, Object x9D, Object x9E, Object x9F,
+    Object xA0, Object xA1, Object xA2, Object xA3, Object xA4, Object xA5, Object xA6, Object xA7,
+    Object xA8, Object xA9, Object xAA, Object xAB, Object xAC, Object xAD, Object xAE, Object xAF,
+    Object xB0, Object xB1, Object xB2, Object xB3, Object xB4, Object xB5, Object xB6, Object xB7,
+    Object xB8, Object xB9, Object xBA, Object xBB, Object xBC, Object xBD, Object xBE, Object xBF,
+    Object xC0, Object xC1, Object xC2, Object xC3, Object xC4, Object xC5, Object xC6, Object xC7,
+    Object xC8, Object xC9, Object xCA, Object xCB, Object xCC, Object xCD, Object xCE, Object xCF,
+    Object xD0, Object xD1, Object xD2, Object xD3, Object xD4, Object xD5, Object xD6, Object xD7,
+    Object xD8, Object xD9, Object xDA, Object xDB, Object xDC, Object xDD, Object xDE, Object xDF,
+    Object xE0, Object xE1, Object xE2, Object xE3, Object xE4, Object xE5, Object xE6, Object xE7,
+    Object xE8, Object xE9, Object xEA, Object xEB, Object xEC, Object xED, Object xEE, Object xEF,
+    Object xF0, Object xF1, Object xF2, Object xF3, Object xF4, Object xF5, Object xF6, Object xF7,
+    // </editor-fold>
+    Object xF8, Object xF9, Object xFA, Object xFB, Object xFC, Object xFD, Object xFE) {
+        return Objects.hash(
+    // <editor-fold defaultstate="collapsed" desc="x00, x01, x02, x03, x04, ...">
+    x00, x01, x02, x03, x04, x05, x06, x07, x08, x09, x0A, x0B, x0C, x0D, x0E, x0F,
+    x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x1A, x1B, x1C, x1D, x1E, x1F,
+    x20, x21, x22, x23, x24, x25, x26, x27, x28, x29, x2A, x2B, x2C, x2D, x2E, x2F,
+    x30, x31, x32, x33, x34, x35, x36, x37, x38, x39, x3A, x3B, x3C, x3D, x3E, x3F,
+    x40, x41, x42, x43, x44, x45, x46, x47, x48, x49, x4A, x4B, x4C, x4D, x4E, x4F,
+    x50, x51, x52, x53, x54, x55, x56, x57, x58, x59, x5A, x5B, x5C, x5D, x5E, x5F,
+    x60, x61, x62, x63, x64, x65, x66, x67, x68, x69, x6A, x6B, x6C, x6D, x6E, x6F,
+    x70, x71, x72, x73, x74, x75, x76, x77, x78, x79, x7A, x7B, x7C, x7D, x7E, x7F,
+    x80, x81, x82, x83, x84, x85, x86, x87, x88, x89, x8A, x8B, x8C, x8D, x8E, x8F,
+    x90, x91, x92, x93, x94, x95, x96, x97, x98, x99, x9A, x9B, x9C, x9D, x9E, x9F,
+    xA0, xA1, xA2, xA3, xA4, xA5, xA6, xA7, xA8, xA9, xAA, xAB, xAC, xAD, xAE, xAF,
+    xB0, xB1, xB2, xB3, xB4, xB5, xB6, xB7, xB8, xB9, xBA, xBB, xBC, xBD, xBE, xBF,
+    xC0, xC1, xC2, xC3, xC4, xC5, xC6, xC7, xC8, xC9, xCA, xCB, xCC, xCD, xCE, xCF,
+    xD0, xD1, xD2, xD3, xD4, xD5, xD6, xD7, xD8, xD9, xDA, xDB, xDC, xDD, xDE, xDF,
+    xE0, xE1, xE2, xE3, xE4, xE5, xE6, xE7, xE8, xE9, xEA, xEB, xEC, xED, xEE, xEF,
+    xF0, xF1, xF2, xF3, xF4, xF5, xF6, xF7,
+    // </editor-fold>
+    xF8, xF9, xFA, xFB, xFC, xFD, xFE);
+    }
+
+    @Test
+    public void test255() throws Throwable {
+        final int ARITY = 255;
+        System.out.println("test"+ARITY);
+        Object[] a = testArgs(ARITY);
+        Object r0 = hashArguments(a);
+        Object r;
+        r = hashArguments_255(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]);
+        assertEquals(r0, r);
+        MethodType mt = MethodType.genericMethodType(ARITY);
+        MethodHandle mh;
+        try {
+            mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+ARITY, mt);
+            throw new AssertionError("should not create an arity 255 method handle");
+        } catch (IllegalArgumentException ex) {
+            System.out.println("OK: "+ex);
+            mh = MethodHandles.lookup().findStatic(BigArityTest.class, "hashArguments_"+(ARITY-1), mt.dropParameterTypes(ARITY-1, ARITY));
+        }
+        try {
+            r = mh.invokeExact(
+    // <editor-fold defaultstate="collapsed" desc="a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], ...">
+    a[0x00], a[0x01], a[0x02], a[0x03], a[0x04], a[0x05], a[0x06], a[0x07], a[0x08], a[0x09], a[0x0A], a[0x0B], a[0x0C], a[0x0D], a[0x0E], a[0x0F],
+    a[0x10], a[0x11], a[0x12], a[0x13], a[0x14], a[0x15], a[0x16], a[0x17], a[0x18], a[0x19], a[0x1A], a[0x1B], a[0x1C], a[0x1D], a[0x1E], a[0x1F],
+    a[0x20], a[0x21], a[0x22], a[0x23], a[0x24], a[0x25], a[0x26], a[0x27], a[0x28], a[0x29], a[0x2A], a[0x2B], a[0x2C], a[0x2D], a[0x2E], a[0x2F],
+    a[0x30], a[0x31], a[0x32], a[0x33], a[0x34], a[0x35], a[0x36], a[0x37], a[0x38], a[0x39], a[0x3A], a[0x3B], a[0x3C], a[0x3D], a[0x3E], a[0x3F],
+    a[0x40], a[0x41], a[0x42], a[0x43], a[0x44], a[0x45], a[0x46], a[0x47], a[0x48], a[0x49], a[0x4A], a[0x4B], a[0x4C], a[0x4D], a[0x4E], a[0x4F],
+    a[0x50], a[0x51], a[0x52], a[0x53], a[0x54], a[0x55], a[0x56], a[0x57], a[0x58], a[0x59], a[0x5A], a[0x5B], a[0x5C], a[0x5D], a[0x5E], a[0x5F],
+    a[0x60], a[0x61], a[0x62], a[0x63], a[0x64], a[0x65], a[0x66], a[0x67], a[0x68], a[0x69], a[0x6A], a[0x6B], a[0x6C], a[0x6D], a[0x6E], a[0x6F],
+    a[0x70], a[0x71], a[0x72], a[0x73], a[0x74], a[0x75], a[0x76], a[0x77], a[0x78], a[0x79], a[0x7A], a[0x7B], a[0x7C], a[0x7D], a[0x7E], a[0x7F],
+    a[0x80], a[0x81], a[0x82], a[0x83], a[0x84], a[0x85], a[0x86], a[0x87], a[0x88], a[0x89], a[0x8A], a[0x8B], a[0x8C], a[0x8D], a[0x8E], a[0x8F],
+    a[0x90], a[0x91], a[0x92], a[0x93], a[0x94], a[0x95], a[0x96], a[0x97], a[0x98], a[0x99], a[0x9A], a[0x9B], a[0x9C], a[0x9D], a[0x9E], a[0x9F],
+    a[0xA0], a[0xA1], a[0xA2], a[0xA3], a[0xA4], a[0xA5], a[0xA6], a[0xA7], a[0xA8], a[0xA9], a[0xAA], a[0xAB], a[0xAC], a[0xAD], a[0xAE], a[0xAF],
+    a[0xB0], a[0xB1], a[0xB2], a[0xB3], a[0xB4], a[0xB5], a[0xB6], a[0xB7], a[0xB8], a[0xB9], a[0xBA], a[0xBB], a[0xBC], a[0xBD], a[0xBE], a[0xBF],
+    a[0xC0], a[0xC1], a[0xC2], a[0xC3], a[0xC4], a[0xC5], a[0xC6], a[0xC7], a[0xC8], a[0xC9], a[0xCA], a[0xCB], a[0xCC], a[0xCD], a[0xCE], a[0xCF],
+    a[0xD0], a[0xD1], a[0xD2], a[0xD3], a[0xD4], a[0xD5], a[0xD6], a[0xD7], a[0xD8], a[0xD9], a[0xDA], a[0xDB], a[0xDC], a[0xDD], a[0xDE], a[0xDF],
+    a[0xE0], a[0xE1], a[0xE2], a[0xE3], a[0xE4], a[0xE5], a[0xE6], a[0xE7], a[0xE8], a[0xE9], a[0xEA], a[0xEB], a[0xEC], a[0xED], a[0xEE], a[0xEF],
+    a[0xF0], a[0xF1], a[0xF2], a[0xF3], a[0xF4], a[0xF5], a[0xF6], a[0xF7],
+    // </editor-fold>
+    a[0xF8], a[0xF9], a[0xFA], a[0xFB], a[0xFC], a[0xFD], a[0xFE]);
+            throw new AssertionError("should not call an arity 255 method handle");
+        } catch (LinkageError ex) {
+            System.out.println("OK: "+ex);
+        }
+        try {
+            MethodHandle ximh = MethodHandles.exactInvoker(mt);
+            throw new AssertionError("should have thrown IAE; cannot have 1+1+255 arguments");
+        } catch (IllegalArgumentException ex) {
+            System.out.println("OK: "+ex);
+        }
+    }
+}
diff --git a/jdk/test/java/lang/invoke/CallSiteTest.java b/jdk/test/java/lang/invoke/CallSiteTest.java
new file mode 100644
index 0000000..5e0a875
--- /dev/null
+++ b/jdk/test/java/lang/invoke/CallSiteTest.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright (c) 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
+ * 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
+ * @summary smoke tests for CallSite
+ *
+ * @build indify.Indify
+ * @compile CallSiteTest.java
+ * @run main/othervm
+ *      indify.Indify
+ *      --expand-properties --classpath ${test.classes}
+ *      --java test.java.lang.invoke.CallSiteTest
+ */
+
+package test.java.lang.invoke;
+
+import java.io.*;
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class CallSiteTest {
+    private final static Class<?> CLASS = CallSiteTest.class;
+
+    private static CallSite mcs;
+    private static CallSite vcs;
+    private static MethodHandle mh_foo;
+    private static MethodHandle mh_bar;
+
+    static {
+        try {
+            mh_foo = lookup().findStatic(CLASS, "foo", methodType(int.class, int.class, int.class));
+            mh_bar = lookup().findStatic(CLASS, "bar", methodType(int.class, int.class, int.class));
+            mcs = new MutableCallSite(mh_foo);
+            vcs = new VolatileCallSite(mh_foo);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String... av) throws Throwable {
+        testMutableCallSite();
+        testVolatileCallSite();
+    }
+
+    private final static int N = Integer.MAX_VALUE / 100;
+    private final static int RESULT1 = 762786192;
+    private final static int RESULT2 = -21474836;
+
+    private static void assertEquals(int expected, int actual) {
+        if (expected != actual)
+            throw new AssertionError("expected: " + expected + ", actual: " + actual);
+    }
+
+    private static void testMutableCallSite() throws Throwable {
+        // warm-up
+        for (int i = 0; i < 20000; i++) {
+            mcs.setTarget(mh_foo);
+        }
+        // run
+        for (int n = 0; n < 2; n++) {
+            mcs.setTarget(mh_foo);
+            for (int i = 0; i < 5; i++) {
+                assertEquals(RESULT1, runMutableCallSite());
+            }
+            mcs.setTarget(mh_bar);
+            for (int i = 0; i < 5; i++) {
+                assertEquals(RESULT2, runMutableCallSite());
+            }
+        }
+    }
+    private static void testVolatileCallSite() throws Throwable {
+        // warm-up
+        for (int i = 0; i < 20000; i++) {
+            vcs.setTarget(mh_foo);
+        }
+        // run
+        for (int n = 0; n < 2; n++) {
+            vcs.setTarget(mh_foo);
+            for (int i = 0; i < 5; i++) {
+                assertEquals(RESULT1, runVolatileCallSite());
+            }
+            vcs.setTarget(mh_bar);
+            for (int i = 0; i < 5; i++) {
+                assertEquals(RESULT2, runVolatileCallSite());
+            }
+        }
+    }
+
+    private static int runMutableCallSite() throws Throwable {
+        int sum = 0;
+        for (int i = 0; i < N; i++) {
+            sum += (int) INDY_mcs().invokeExact(i, i+1);
+        }
+        return sum;
+    }
+    private static int runVolatileCallSite() throws Throwable {
+        int sum = 0;
+        for (int i = 0; i < N; i++) {
+            sum += (int) INDY_vcs().invokeExact(i, i+1);
+        }
+        return sum;
+    }
+
+    static int foo(int a, int b) { return a + b; }
+    static int bar(int a, int b) { return a - b; }
+
+    private static MethodType MT_bsm() {
+        shouldNotCallThis();
+        return methodType(CallSite.class, Lookup.class, String.class, MethodType.class);
+    }
+
+    private static CallSite bsm_mcs(Lookup caller, String name, MethodType type) throws ReflectiveOperationException {
+        return mcs;
+    }
+    private static MethodHandle MH_bsm_mcs() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return lookup().findStatic(lookup().lookupClass(), "bsm_mcs", MT_bsm());
+    }
+    private static MethodHandle INDY_mcs() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm_mcs().invoke(lookup(), "foo", methodType(int.class, int.class, int.class))).dynamicInvoker();
+    }
+
+    private static CallSite bsm_vcs(Lookup caller, String name, MethodType type) throws ReflectiveOperationException {
+        return vcs;
+    }
+    private static MethodHandle MH_bsm_vcs() throws ReflectiveOperationException {
+        shouldNotCallThis();
+        return lookup().findStatic(lookup().lookupClass(), "bsm_vcs", MT_bsm());
+    }
+    private static MethodHandle INDY_vcs() throws Throwable {
+        shouldNotCallThis();
+        return ((CallSite) MH_bsm_vcs().invoke(lookup(), "foo", methodType(int.class, int.class, int.class))).dynamicInvoker();
+    }
+
+    private static void shouldNotCallThis() {
+        // if this gets called, the transformation has not taken place
+        throw new AssertionError("this code should be statically transformed away by Indify");
+    }
+}
diff --git a/jdk/test/java/lang/invoke/ClassValueTest.java b/jdk/test/java/lang/invoke/ClassValueTest.java
index c0033fe..56b5771 100644
--- a/jdk/test/java/lang/invoke/ClassValueTest.java
+++ b/jdk/test/java/lang/invoke/ClassValueTest.java
@@ -38,10 +38,6 @@
 
 package test.java.lang.invoke;
 
-import java.util.*;
-
-import java.lang.invoke.*;
-
 import org.junit.*;
 import static org.junit.Assert.*;
 
diff --git a/jdk/test/java/lang/invoke/InvokeGenericTest.java b/jdk/test/java/lang/invoke/InvokeGenericTest.java
index 43e019f..5f7e54c 100644
--- a/jdk/test/java/lang/invoke/InvokeGenericTest.java
+++ b/jdk/test/java/lang/invoke/InvokeGenericTest.java
@@ -25,7 +25,7 @@
 
 /* @test
  * @summary unit tests for java.lang.invoke.MethodHandle.invoke
- * @compile -target 7 InvokeGenericTest.java
+ * @compile InvokeGenericTest.java
  * @run junit/othervm test.java.lang.invoke.InvokeGenericTest
  */
 
@@ -45,6 +45,7 @@
  *
  * @author jrose
  */
+@SuppressWarnings("cast")  // various casts help emphasize arguments to invokeExact
 public class InvokeGenericTest {
     // How much output?
     static int verbosity = 0;
@@ -67,24 +68,6 @@
     public InvokeGenericTest() {
     }
 
-    @Before
-    public void checkImplementedPlatform() {
-        boolean platformOK = false;
-        Properties properties = System.getProperties();
-        String vers = properties.getProperty("java.vm.version");
-        String name = properties.getProperty("java.vm.name");
-        String arch = properties.getProperty("os.arch");
-        if ((arch.equals("amd64") || arch.equals("i386") || arch.equals("x86") ||
-             arch.equals("x86_64") || arch.equals("sparc") || arch.equals("sparcv9")) &&
-            (name.contains("Client") || name.contains("Server"))
-            ) {
-            platformOK = true;
-        } else {
-            System.err.println("Skipping tests for unsupported platform: "+Arrays.asList(vers, name, arch));
-        }
-        assumeTrue(platformOK);
-    }
-
     String testName;
     static int allPosTests, allNegTests;
     int posTests, negTests;
@@ -129,7 +112,7 @@
         }
     }
 
-    static List<Object> calledLog = new ArrayList<Object>();
+    static List<Object> calledLog = new ArrayList<>();
     static Object logEntry(String name, Object... args) {
         return Arrays.asList(name, Arrays.asList(args));
     }
@@ -237,8 +220,7 @@
         else
             try {
                 return param.newInstance();
-            } catch (InstantiationException ex) {
-            } catch (IllegalAccessException ex) {
+            } catch (InstantiationException | IllegalAccessException ex) {
             }
         return null;  // random class not Object, String, Integer, etc.
     }
@@ -274,9 +256,11 @@
         return zeroArgs(params.toArray(new Class<?>[0]));
     }
 
+    @SafeVarargs @SuppressWarnings("varargs")
     static <T, E extends T> T[] array(Class<T[]> atype, E... a) {
         return Arrays.copyOf(a, a.length, atype);
     }
+    @SafeVarargs @SuppressWarnings("varargs")
     static <T> T[] cat(T[] a, T... b) {
         int alen = a.length, blen = b.length;
         if (blen == 0)  return a;
@@ -311,7 +295,7 @@
             int beg, int end, Class<?> argType) {
         MethodType targetType = target.type();
         end = Math.min(end, targetType.parameterCount());
-        ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>(targetType.parameterList());
+        ArrayList<Class<?>> argTypes = new ArrayList<>(targetType.parameterList());
         Collections.fill(argTypes.subList(beg, end), argType);
         MethodType ttype2 = MethodType.methodType(targetType.returnType(), argTypes);
         return target.asType(ttype2);
@@ -320,7 +304,7 @@
     // This lookup is good for all members in and under InvokeGenericTest.
     static final Lookup LOOKUP = MethodHandles.lookup();
 
-    Map<List<Class<?>>, MethodHandle> CALLABLES = new HashMap<List<Class<?>>, MethodHandle>();
+    Map<List<Class<?>>, MethodHandle> CALLABLES = new HashMap<>();
     MethodHandle callable(List<Class<?>> params) {
         MethodHandle mh = CALLABLES.get(params);
         if (mh == null) {
@@ -353,8 +337,8 @@
         countTest();
         String[] args = { "one", "two" };
         MethodHandle mh = callable(Object.class, String.class);
-        Object res; List resl;
-        res = resl = (List) mh.invoke((String)args[0], (Object)args[1]);
+        Object res; List<?> resl;
+        res = resl = (List<?>) mh.invoke((String)args[0], (Object)args[1]);
         //System.out.println(res);
         assertEquals(Arrays.asList(args), res);
     }
@@ -365,8 +349,8 @@
         countTest();
         int[] args = { 1, 2 };
         MethodHandle mh = callable(Object.class, Object.class);
-        Object res; List resl;
-        res = resl = (List) mh.invoke(args[0], args[1]);
+        Object res; List<?> resl;
+        res = resl = (List<?>) mh.invoke(args[0], args[1]);
         //System.out.println(res);
         assertEquals(Arrays.toString(args), res.toString());
     }
@@ -377,8 +361,8 @@
         countTest();
         String[] args = { "one", "two" };
         MethodHandle mh = callable(Object.class, String.class);
-        Object res; List resl;
-        res = resl = (List) mh.invoke((String)args[0], (Object)args[1]);
+        Object res; List<?> resl;
+        res = resl = (List<?>) mh.invoke((String)args[0], (Object)args[1]);
         //System.out.println(res);
         assertEquals(Arrays.asList(args), res);
     }
@@ -440,9 +424,9 @@
      *  A void return type is possible iff the first type is void.class.
      */
     static List<MethodType> allMethodTypes(int minargc, int maxargc, Class<?>... types) {
-        ArrayList<MethodType> result = new ArrayList<MethodType>();
+        ArrayList<MethodType> result = new ArrayList<>();
         if (types.length > 0) {
-            ArrayList<MethodType> argcTypes = new ArrayList<MethodType>();
+            ArrayList<MethodType> argcTypes = new ArrayList<>();
             // build arity-zero types first
             for (Class<?> rtype : types) {
                 argcTypes.add(MethodType.methodType(rtype));
@@ -456,7 +440,7 @@
                 if (argc >= maxargc)
                     break;
                 ArrayList<MethodType> prevTypes = argcTypes;
-                argcTypes = new ArrayList<MethodType>();
+                argcTypes = new ArrayList<>();
                 for (MethodType prevType : prevTypes) {
                     for (Class<?> ptype : types) {
                         argcTypes.add(prevType.insertParameterTypes(argc, ptype));
@@ -524,8 +508,8 @@
         countTest();
         Object[] args = { 1, 2 };
         MethodHandle mh = callable(Object.class, int.class);
-        Object res; List resl; int resi;
-        res = resl = (List) mh.invoke((int)args[0], (Object)args[1]);
+        Object res; List<?> resl; int resi;
+        res = resl = (List<?>) mh.invoke((int)args[0], (Object)args[1]);
         //System.out.println(res);
         assertEquals(Arrays.asList(args), res);
         mh = MethodHandles.identity(int.class);
diff --git a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java
index ba1eed5..9fd2429 100644
--- a/jdk/test/java/lang/invoke/JavaDocExamplesTest.java
+++ b/jdk/test/java/lang/invoke/JavaDocExamplesTest.java
@@ -69,6 +69,7 @@
         testDropArguments();
         testFilterArguments();
         testFoldArguments();
+        testFoldArguments2();
         testMethodHandlesSummary();
         testAsSpreader();
         testAsCollector();
@@ -335,6 +336,7 @@
             }}
     }
 
+    @SuppressWarnings("rawtypes")
     @Test public void testAsVarargsCollector() throws Throwable {
         {{
 {} /// JAVADOC
@@ -490,6 +492,47 @@
             }}
     }
 
+    @Test public void testFoldArguments2() throws Throwable {
+        {{
+{} /// JAVADOC
+// argument-based dispatch for methods of the form boolean x.___(y: String)
+Lookup lookup = publicLookup();
+// first, a tracing hack:
+MethodHandle println = lookup.findVirtual(java.io.PrintStream.class, "println", methodType(void.class, String.class));
+MethodHandle arrayToString = lookup.findStatic(Arrays.class, "toString", methodType(String.class, Object[].class));
+MethodHandle concat = lookup.findVirtual(String.class, "concat", methodType(String.class, String.class));
+MethodHandle arrayToString_DIS = filterReturnValue(arrayToString, concat.bindTo("DIS:"));
+MethodHandle arrayToString_INV = filterReturnValue(arrayToString, concat.bindTo("INV:"));
+MethodHandle printArgs_DIS = filterReturnValue(arrayToString_DIS, println.bindTo(System.out)).asVarargsCollector(Object[].class);
+MethodHandle printArgs_INV = filterReturnValue(arrayToString_INV, println.bindTo(System.out)).asVarargsCollector(Object[].class);
+// metaobject protocol:
+MethodType mtype = methodType(boolean.class, String.class);
+MethodHandle findVirtual = lookup.findVirtual(Lookup.class,
+  "findVirtual", methodType(MethodHandle.class, Class.class, String.class, MethodType.class));
+MethodHandle getClass = lookup.findVirtual(Object.class,
+  "getClass", methodType(Class.class));
+MethodHandle dispatch = findVirtual;
+dispatch = filterArguments(dispatch, 1, getClass);
+dispatch = insertArguments(dispatch, 3, mtype);
+dispatch = dispatch.bindTo(lookup);
+assertEquals(methodType(MethodHandle.class, Object.class, String.class), dispatch.type());
+MethodHandle invoker = invoker(mtype.insertParameterTypes(0, Object.class));
+// wrap tracing around the dispatch and invoke steps:
+dispatch = foldArguments(dispatch, printArgs_DIS.asType(dispatch.type().changeReturnType(void.class)));
+invoker = foldArguments(invoker, printArgs_INV.asType(invoker.type().changeReturnType(void.class)));
+invoker = dropArguments(invoker, 2, String.class);  // ignore selector
+// compose the dispatcher and the invoker:
+MethodHandle invokeDispatched = foldArguments(invoker, dispatch);
+Object x = "football", y = new java.util.Scanner("bar");
+assert( (boolean) invokeDispatched.invokeExact(x, "startsWith", "foo"));
+assert(!(boolean) invokeDispatched.invokeExact(x, "startsWith", "#"));
+assert( (boolean) invokeDispatched.invokeExact(x, "endsWith", "all"));
+assert(!(boolean) invokeDispatched.invokeExact(x, "endsWith", "foo"));
+assert( (boolean) invokeDispatched.invokeExact(y, "hasNext", "[abc]+[rst]"));
+assert(!(boolean) invokeDispatched.invokeExact(y, "hasNext", "[123]+[789]"));
+            }}
+    }
+
     /* ---- TEMPLATE ----
     @Test public void testFoo() throws Throwable {
         {{
diff --git a/jdk/test/java/lang/invoke/MethodHandlesTest.java b/jdk/test/java/lang/invoke/MethodHandlesTest.java
index 8ced35b..aaa41a8 100644
--- a/jdk/test/java/lang/invoke/MethodHandlesTest.java
+++ b/jdk/test/java/lang/invoke/MethodHandlesTest.java
@@ -25,19 +25,19 @@
 
 /* @test
  * @summary unit tests for java.lang.invoke.MethodHandles
- * @compile -source 7 -target 7 MethodHandlesTest.java
+ * @compile MethodHandlesTest.java remote/RemoteExample.java
  * @run junit/othervm test.java.lang.invoke.MethodHandlesTest
  */
 
 package test.java.lang.invoke;
 
+import test.java.lang.invoke.remote.RemoteExample;
 import java.lang.invoke.*;
 import java.lang.invoke.MethodHandles.Lookup;
 import java.lang.reflect.*;
 import java.util.*;
 import org.junit.*;
 import static org.junit.Assert.*;
-import static org.junit.Assume.*;
 
 
 /**
@@ -45,22 +45,30 @@
  * @author jrose
  */
 public class MethodHandlesTest {
+    static final Class<?> THIS_CLASS = MethodHandlesTest.class;
     // How much output?
     static int verbosity = 0;
     static {
-        String vstr = System.getProperty("test.java.lang.invoke.MethodHandlesTest.verbosity");
+        String vstr = System.getProperty(THIS_CLASS.getSimpleName()+".verbosity");
+        if (vstr == null)
+            vstr = System.getProperty(THIS_CLASS.getName()+".verbosity");
         if (vstr != null)  verbosity = Integer.parseInt(vstr);
     }
 
     // Set this true during development if you want to fast-forward to
     // a particular new, non-working test.  Tests which are known to
     // work (or have recently worked) test this flag and return on true.
-    static boolean CAN_SKIP_WORKING = false;
-    //static { CAN_SKIP_WORKING = true; }
+    static final boolean CAN_SKIP_WORKING;
+    static {
+        String vstr = System.getProperty(THIS_CLASS.getSimpleName()+".CAN_SKIP_WORKING");
+        if (vstr == null)
+            vstr = System.getProperty(THIS_CLASS.getName()+".CAN_SKIP_WORKING");
+        CAN_SKIP_WORKING = Boolean.parseBoolean(vstr);
+    }
 
-    // Set true to test more calls.  If false, some tests are just
-    // lookups, without exercising the actual method handle.
-    static boolean DO_MORE_CALLS = true;
+    // Set 'true' to do about 15x fewer tests, especially those redundant with RicochetTest.
+    // This might be useful with -Xcomp stress tests that compile all method handles.
+    static boolean CAN_TEST_LIGHTLY = Boolean.getBoolean(THIS_CLASS.getName()+".CAN_TEST_LIGHTLY");
 
     @Test
     public void testFirst() throws Throwable {
@@ -69,62 +77,6 @@
         } finally { printCounts(); verbosity -= 9; }
     }
 
-    // current failures
-    @Test @Ignore("failure in call to makeRawRetypeOnly in ToGeneric")
-    public void testFail_1() throws Throwable {
-        // AMH.<init>: IllegalArgumentException: bad adapter (conversion=0xfffab300): adapter pushes too many parameters
-        testSpreadArguments(int.class, 0, 6);
-    }
-    @Test @Ignore("failure in JVM when expanding the stack using asm stub for _adapter_spread_args")
-    public void testFail_2() throws Throwable {
-        // if CONV_OP_IMPLEMENTED_MASK includes OP_SPREAD_ARGS, this crashes:
-        testSpreadArguments(Object.class, 0, 2);
-    }
-    @Test @Ignore("IllArgEx failure in call to ToGeneric.make")
-    public void testFail_3() throws Throwable {
-        // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
-        testSpreadArguments(int.class, 1, 2);
-    }
-    @Test @Ignore("IllArgEx failure in call to ToGeneric.make")
-    public void testFail_4() throws Throwable {
-        // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
-        testCollectArguments(int.class, 1, 2);
-    }
-    @Test @Ignore("cannot collect leading primitive types")
-    public void testFail_5() throws Throwable {
-        // ToGeneric.<init>: UnsupportedOperationException: NYI: primitive parameters must follow references; entryType = (int,java.lang.Object)java.lang.Object
-        testInvokers(MethodType.genericMethodType(2).changeParameterType(0, int.class));
-    }
-    @Test @Ignore("should not insert arguments beyond MethodHandlePushLimit")
-    public void testFail_6() throws Throwable {
-        // ValueConversions.varargsArray: UnsupportedOperationException: NYI: cannot form a varargs array of length 13
-        testInsertArguments(0, 0, MAX_ARG_INCREASE+10);
-    }
-    @Test @Ignore("permuteArguments has trouble with double slots")
-    public void testFail_7() throws Throwable {
-        testPermuteArguments(new Object[]{10, 200L},
-                             new Class<?>[]{Integer.class, long.class},
-                             new int[]{1,0});
-        testPermuteArguments(new Object[]{10, 200L, 5000L},
-                             new Class<?>[]{Integer.class, long.class, long.class},
-                             new int[]{2,0,1}); //rot
-        testPermuteArguments(new Object[]{10, 200L, 5000L},
-                             new Class<?>[]{Integer.class, long.class, long.class},
-                             new int[]{1,2,0}); //rot
-        testPermuteArguments(new Object[]{10, 200L, 5000L},
-                             new Class<?>[]{Integer.class, long.class, long.class},
-                             new int[]{2,1,0}); //swap
-        testPermuteArguments(new Object[]{10, 200L, 5000L},
-                             new Class<?>[]{Integer.class, long.class, long.class},
-                             new int[]{0,1,2,2}); //dup
-        testPermuteArguments(new Object[]{10, 200L, 5000L},
-                             new Class<?>[]{Integer.class, long.class, long.class},
-                             new int[]{2,0,1,2});
-        testPermuteArguments(new Object[]{10, 200L, 5000L},
-                             new Class<?>[]{Integer.class, long.class, long.class},
-                             new int[]{2,2,0,1});
-        testPermuteArguments(4, Integer.class,  2, long.class,    6);
-    }
     static final int MAX_ARG_INCREASE = 3;
 
     public MethodHandlesTest() {
@@ -167,18 +119,18 @@
     @AfterClass
     public static void tearDownClass() throws Exception {
         int posTests = allPosTests, negTests = allNegTests;
-        if (verbosity >= 2 && (posTests | negTests) != 0) {
+        if (verbosity >= 0 && (posTests | negTests) != 0) {
             System.out.println();
             if (posTests != 0)  System.out.println("=== "+posTests+" total positive test cases");
             if (negTests != 0)  System.out.println("=== "+negTests+" total negative test cases");
         }
     }
 
-    static List<Object> calledLog = new ArrayList<Object>();
+    static List<Object> calledLog = new ArrayList<>();
     static Object logEntry(String name, Object... args) {
         return Arrays.asList(name, Arrays.asList(args));
     }
-    static Object called(String name, Object... args) {
+    public static Object called(String name, Object... args) {
         Object entry = logEntry(name, args);
         calledLog.add(entry);
         return entry;
@@ -209,6 +161,7 @@
         return dst.cast(value);
     }
 
+    @SuppressWarnings("cast")  // primitive cast to (long) is part of the pattern
     static Object castToWrapperOrNull(long value, Class<?> dst) {
         if (dst == int.class || dst == Integer.class)
             return (int)(value);
@@ -277,13 +230,14 @@
                     { param = c; break; }
             }
         }
+        if (param.isInterface() && param.isAssignableFrom(List.class))
+            return Arrays.asList("#"+nextArg());
         if (param.isInterface() || param.isAssignableFrom(String.class))
             return "#"+nextArg();
         else
             try {
                 return param.newInstance();
-            } catch (InstantiationException ex) {
-            } catch (IllegalAccessException ex) {
+            } catch (InstantiationException | IllegalAccessException ex) {
             }
         return null;  // random class not Object, String, Integer, etc.
     }
@@ -300,9 +254,11 @@
         return args;
     }
 
+    @SafeVarargs @SuppressWarnings("varargs")
     static <T, E extends T> T[] array(Class<T[]> atype, E... a) {
         return Arrays.copyOf(a, a.length, atype);
     }
+    @SafeVarargs @SuppressWarnings("varargs")
     static <T> T[] cat(T[] a, T... b) {
         int alen = a.length, blen = b.length;
         if (blen == 0)  return a;
@@ -352,14 +308,14 @@
                 try {
                     LIST_TO_STRING = PRIVATE.findStatic(PRIVATE.lookupClass(), "listToString",
                                                         MethodType.methodType(String.class, List.class));
-                } catch (Exception ex) { throw new RuntimeException(ex); }
+                } catch (NoSuchMethodException | IllegalAccessException ex) { throw new RuntimeException(ex); }
             list = MethodHandles.filterReturnValue(list, LIST_TO_STRING);
         } else if (rtype.isPrimitive()) {
             if (LIST_TO_INT == null)
                 try {
                     LIST_TO_INT = PRIVATE.findStatic(PRIVATE.lookupClass(), "listToInt",
                                                      MethodType.methodType(int.class, List.class));
-                } catch (Exception ex) { throw new RuntimeException(ex); }
+                } catch (NoSuchMethodException | IllegalAccessException ex) { throw new RuntimeException(ex); }
             list = MethodHandles.filterReturnValue(list, LIST_TO_INT);
             list = MethodHandles.explicitCastArguments(list, listType);
         } else {
@@ -368,8 +324,8 @@
         return list.asType(listType);
     }
     private static MethodHandle LIST_TO_STRING, LIST_TO_INT;
-    private static String listToString(List x) { return x.toString(); }
-    private static int listToInt(List x) { return x.toString().hashCode(); }
+    private static String listToString(List<?> x) { return x.toString(); }
+    private static int listToInt(List<?> x) { return x.toString().hashCode(); }
 
     static MethodHandle changeArgTypes(MethodHandle target, Class<?> argType) {
         return changeArgTypes(target, 0, 999, argType);
@@ -378,16 +334,25 @@
             int beg, int end, Class<?> argType) {
         MethodType targetType = target.type();
         end = Math.min(end, targetType.parameterCount());
-        ArrayList<Class<?>> argTypes = new ArrayList<Class<?>>(targetType.parameterList());
+        ArrayList<Class<?>> argTypes = new ArrayList<>(targetType.parameterList());
         Collections.fill(argTypes.subList(beg, end), argType);
         MethodType ttype2 = MethodType.methodType(targetType.returnType(), argTypes);
         return target.asType(ttype2);
     }
+    static MethodHandle addTrailingArgs(MethodHandle target, int nargs, Class<?> argClass) {
+        int targetLen = target.type().parameterCount();
+        int extra = (nargs - targetLen);
+        if (extra <= 0)  return target;
+        List<Class<?>> fakeArgs = Collections.<Class<?>>nCopies(extra, argClass);
+        return MethodHandles.dropArguments(target, targetLen, fakeArgs);
+    }
 
     // This lookup is good for all members in and under MethodHandlesTest.
     static final Lookup PRIVATE = MethodHandles.lookup();
     // This lookup is good for package-private members but not private ones.
     static final Lookup PACKAGE = PackageSibling.lookup();
+    // This lookup is good for public members and protected members of PubExample
+    static final Lookup SUBCLASS = RemoteExample.lookup();
     // This lookup is good only for public members.
     static final Lookup PUBLIC  = MethodHandles.publicLookup();
 
@@ -396,13 +361,16 @@
         final String name;
         public Example() { name = "Example#"+nextArg(); }
         protected Example(String name) { this.name = name; }
+        @SuppressWarnings("LeakingThisInConstructor")
         protected Example(int x) { this(); called("protected <init>", this, x); }
         @Override public String toString() { return name; }
 
         public void            v0()     { called("v0", this); }
+        protected void         pro_v0() { called("pro_v0", this); }
         void                   pkg_v0() { called("pkg_v0", this); }
         private void           pri_v0() { called("pri_v0", this); }
         public static void     s0()     { called("s0"); }
+        protected static void  pro_s0() { called("pro_s0"); }
         static void            pkg_s0() { called("pkg_s0"); }
         private static void    pri_s0() { called("pri_s0"); }
 
@@ -419,15 +387,29 @@
         public static Object   s6(int x, long y) { return called("s6", x, y); }
         public static Object   s7(float x, double y) { return called("s7", x, y); }
 
+        // for testing findConstructor:
+        public Example(String x, int y) { this.name = x+y; called("Example.<init>", x, y); }
+        public Example(int x, String y) { this.name = x+y; called("Example.<init>", x, y); }
+        public Example(int x, int    y) { this.name = x+""+y; called("Example.<init>", x, y); }
+        public Example(int x, long   y) { this.name = x+""+y; called("Example.<init>", x, y); }
+        public Example(int x, float  y) { this.name = x+""+y; called("Example.<init>", x, y); }
+        public Example(int x, double y) { this.name = x+""+y; called("Example.<init>", x, y); }
+        public Example(int x, int    y, int z) { this.name = x+""+y+""+z; called("Example.<init>", x, y, z); }
+        public Example(int x, int    y, int z, int a) { this.name = x+""+y+""+z+""+a; called("Example.<init>", x, y, z, a); }
+
         static final Lookup EXAMPLE = MethodHandles.lookup();  // for testing findSpecial
     }
     static final Lookup EXAMPLE = Example.EXAMPLE;
     public static class PubExample extends Example {
-        public PubExample() { super("PubExample#"+nextArg()); }
+        public PubExample() { this("PubExample"); }
+        protected PubExample(String prefix) { super(prefix+"#"+nextArg()); }
+        protected void         pro_v0() { called("Pub/pro_v0", this); }
+        protected static void  pro_s0() { called("Pub/pro_s0"); }
     }
     static class SubExample extends Example {
         @Override public void  v0()     { called("Sub/v0", this); }
         @Override void         pkg_v0() { called("Sub/pkg_v0", this); }
+        @SuppressWarnings("LeakingThisInConstructor")
         private      SubExample(int x)  { called("<init>", this, x); }
         public SubExample() { super("SubExample#"+nextArg()); }
     }
@@ -440,12 +422,14 @@
             @Override public String toString() { return name; }
         }
     }
+    static interface SubIntExample extends IntExample { }
 
     static final Object[][][] ACCESS_CASES = {
-        { { false, PUBLIC }, { false, PACKAGE }, { false, PRIVATE }, { false, EXAMPLE } }, //[0]: all false
-        { { false, PUBLIC }, { false, PACKAGE }, { true,  PRIVATE }, { true,  EXAMPLE } }, //[1]: only PRIVATE
-        { { false, PUBLIC }, { true,  PACKAGE }, { true,  PRIVATE }, { true,  EXAMPLE } }, //[2]: PUBLIC false
-        { { true,  PUBLIC }, { true,  PACKAGE }, { true,  PRIVATE }, { true,  EXAMPLE } }, //[3]: all true
+        { { false, PUBLIC }, { false, SUBCLASS }, { false, PACKAGE }, { false, PRIVATE }, { false, EXAMPLE } }, //[0]: all false
+        { { false, PUBLIC }, { false, SUBCLASS }, { false, PACKAGE }, { true,  PRIVATE }, { true,  EXAMPLE } }, //[1]: only PRIVATE
+        { { false, PUBLIC }, { false, SUBCLASS }, { true,  PACKAGE }, { true,  PRIVATE }, { true,  EXAMPLE } }, //[2]: PUBLIC false
+        { { false, PUBLIC }, { true,  SUBCLASS }, { true,  PACKAGE }, { true,  PRIVATE }, { true,  EXAMPLE } }, //[3]: subclass OK
+        { { true,  PUBLIC }, { true,  SUBCLASS }, { true,  PACKAGE }, { true,  PRIVATE }, { true,  EXAMPLE } }, //[4]: all true
     };
 
     static Object[][] accessCases(Class<?> defc, String name, boolean isSpecial) {
@@ -454,11 +438,13 @@
             cases = ACCESS_CASES[1]; // PRIVATE only
         } else if (name.contains("pkg_") || !Modifier.isPublic(defc.getModifiers())) {
             cases = ACCESS_CASES[2]; // not PUBLIC
+        } else if (name.contains("pro_")) {
+            cases = ACCESS_CASES[3]; // PUBLIC class, protected member
         } else {
-            assertTrue(name.indexOf('_') < 0);
+            assertTrue(name.indexOf('_') < 0 || name.contains("fin_"));
             boolean pubc = Modifier.isPublic(defc.getModifiers());
             if (pubc)
-                cases = ACCESS_CASES[3]; // all access levels
+                cases = ACCESS_CASES[4]; // all access levels
             else
                 cases = ACCESS_CASES[2]; // PACKAGE but not PUBLIC
         }
@@ -470,6 +456,13 @@
         return accessCases(defc, name, false);
     }
 
+    static Lookup maybeMoveIn(Lookup lookup, Class<?> defc) {
+        if (lookup == PUBLIC || lookup == SUBCLASS || lookup == PACKAGE)
+            // external views stay external
+            return lookup;
+        return lookup.in(defc);
+    }
+
     @Test
     public void testFindStatic() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
@@ -478,6 +471,8 @@
         testFindStatic(Example.class, void.class, "s0");
         testFindStatic(Example.class, void.class, "pkg_s0");
         testFindStatic(Example.class, void.class, "pri_s0");
+        testFindStatic(Example.class, void.class, "pro_s0");
+        testFindStatic(PubExample.class, void.class, "Pub/pro_s0");
 
         testFindStatic(Example.class, Object.class, "s1", Object.class);
         testFindStatic(Example.class, Object.class, "s2", int.class);
@@ -488,6 +483,7 @@
         testFindStatic(Example.class, Object.class, "s7", float.class, double.class);
 
         testFindStatic(false, PRIVATE, Example.class, void.class, "bogus");
+        testFindStatic(false, PRIVATE, Example.class, void.class, "v0");
     }
 
     void testFindStatic(Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
@@ -500,14 +496,16 @@
     }
     void testFindStatic(boolean positive, Lookup lookup, Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
         countTest(positive);
+        String methodName = name.substring(1 + name.indexOf('/'));  // foo/bar => foo
         MethodType type = MethodType.methodType(ret, params);
         MethodHandle target = null;
         Exception noAccess = null;
         try {
             if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
-            target = lookup.in(defc).findStatic(defc, name, type);
+            target = maybeMoveIn(lookup, defc).findStatic(defc, methodName, type);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            if (verbosity >= 5)  ex.printStackTrace(System.out);
             if (name.contains("bogus"))
                 assertTrue(noAccess instanceof NoSuchMethodException);
             else
@@ -520,8 +518,7 @@
         assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
         if (!positive)  return; // negative test failed as expected
         assertEquals(type, target.type());
-        assertNameStringContains(target, name);
-        if (!DO_MORE_CALLS && lookup != PRIVATE)  return;
+        assertNameStringContains(target, methodName);
         Object[] args = randomArgs(params);
         printCalled(target, name, args);
         target.invokeWithArguments(args);
@@ -555,7 +552,12 @@
         testFindVirtual(Example.class, Object.class, "v2", Object.class, int.class);
         testFindVirtual(Example.class, Object.class, "v2", int.class, Object.class);
         testFindVirtual(Example.class, Object.class, "v2", int.class, int.class);
+        testFindVirtual(Example.class, void.class, "pro_v0");
+        testFindVirtual(PubExample.class, void.class, "Pub/pro_v0");
+
         testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "bogus");
+        testFindVirtual(false, PRIVATE, Example.class, Example.class, void.class, "s0");
+
         // test dispatch
         testFindVirtual(SubExample.class,      SubExample.class, void.class, "Sub/v0");
         testFindVirtual(SubExample.class,         Example.class, void.class, "Sub/v0");
@@ -586,9 +588,10 @@
         Exception noAccess = null;
         try {
             if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
-            target = lookup.in(defc).findVirtual(defc, methodName, type);
+            target = maybeMoveIn(lookup, defc).findVirtual(defc, methodName, type);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            if (verbosity >= 5)  ex.printStackTrace(System.out);
             if (name.contains("bogus"))
                 assertTrue(noAccess instanceof NoSuchMethodException);
             else
@@ -600,13 +603,20 @@
         if (positive && noAccess != null)  throw noAccess;
         assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
         if (!positive)  return; // negative test failed as expected
-        Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)defc), params);
+        Class<?> selfc = defc;
+        // predict receiver type narrowing:
+        if (lookup == SUBCLASS &&
+                name.contains("pro_") &&
+                selfc.isAssignableFrom(lookup.lookupClass())) {
+            selfc = lookup.lookupClass();
+            if (name.startsWith("Pub/"))  name = "Rem/"+name.substring(4);
+        }
+        Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)selfc), params);
         MethodType typeWithSelf = MethodType.methodType(ret, paramsWithSelf);
         assertEquals(typeWithSelf, target.type());
         assertNameStringContains(target, methodName);
-        if (!DO_MORE_CALLS && lookup != PRIVATE)  return;
         Object[] argsWithSelf = randomArgs(paramsWithSelf);
-        if (rcvc != defc)  argsWithSelf[0] = randomArg(rcvc);
+        if (selfc.isAssignableFrom(rcvc) && rcvc != selfc)  argsWithSelf[0] = randomArg(rcvc);
         printCalled(target, name, argsWithSelf);
         target.invokeWithArguments(argsWithSelf);
         assertCalled(name, argsWithSelf);
@@ -620,6 +630,7 @@
         startTest("findSpecial");
         testFindSpecial(SubExample.class, Example.class, void.class, "v0");
         testFindSpecial(SubExample.class, Example.class, void.class, "pkg_v0");
+        testFindSpecial(RemoteExample.class, PubExample.class, void.class, "Pub/pro_v0");
         // Do some negative testing:
         testFindSpecial(false, EXAMPLE, SubExample.class, Example.class, void.class, "bogus");
         testFindSpecial(false, PRIVATE, SubExample.class, Example.class, void.class, "bogus");
@@ -632,23 +643,34 @@
 
     void testFindSpecial(Class<?> specialCaller,
                          Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
-        testFindSpecial(true,  EXAMPLE, specialCaller, defc, ret, name, params);
-        testFindSpecial(true,  PRIVATE, specialCaller, defc, ret, name, params);
-        testFindSpecial(false, PACKAGE, specialCaller, defc, ret, name, params);
-        testFindSpecial(false, PUBLIC,  specialCaller, defc, ret, name, params);
+        if (specialCaller == RemoteExample.class) {
+            testFindSpecial(false, EXAMPLE,  specialCaller, defc, ret, name, params);
+            testFindSpecial(false, PRIVATE,  specialCaller, defc, ret, name, params);
+            testFindSpecial(false, PACKAGE,  specialCaller, defc, ret, name, params);
+            testFindSpecial(true,  SUBCLASS, specialCaller, defc, ret, name, params);
+            testFindSpecial(false, PUBLIC,   specialCaller, defc, ret, name, params);
+            return;
+        }
+        testFindSpecial(true,  EXAMPLE,  specialCaller, defc, ret, name, params);
+        testFindSpecial(true,  PRIVATE,  specialCaller, defc, ret, name, params);
+        testFindSpecial(false, PACKAGE,  specialCaller, defc, ret, name, params);
+        testFindSpecial(false, SUBCLASS, specialCaller, defc, ret, name, params);
+        testFindSpecial(false, PUBLIC,   specialCaller, defc, ret, name, params);
     }
     void testFindSpecial(boolean positive, Lookup lookup, Class<?> specialCaller,
                          Class<?> defc, Class<?> ret, String name, Class<?>... params) throws Throwable {
         countTest(positive);
+        String methodName = name.substring(1 + name.indexOf('/'));  // foo/bar => foo
         MethodType type = MethodType.methodType(ret, params);
         MethodHandle target = null;
         Exception noAccess = null;
         try {
             if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
-            if (verbosity >= 5)  System.out.println("  lookup => "+lookup.in(specialCaller));
-            target = lookup.in(specialCaller).findSpecial(defc, name, type, specialCaller);
+            if (verbosity >= 5)  System.out.println("  lookup => "+maybeMoveIn(lookup, specialCaller));
+            target = maybeMoveIn(lookup, specialCaller).findSpecial(defc, methodName, type, specialCaller);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            if (verbosity >= 5)  ex.printStackTrace(System.out);
             if (name.contains("bogus"))
                 assertTrue(noAccess instanceof NoSuchMethodException);
             else
@@ -665,8 +687,7 @@
         assertEquals(type,          target.type().dropParameterTypes(0,1));
         Class<?>[] paramsWithSelf = cat(array(Class[].class, (Class)specialCaller), params);
         MethodType typeWithSelf = MethodType.methodType(ret, paramsWithSelf);
-        assertNameStringContains(target, name);
-        if (!DO_MORE_CALLS && lookup != PRIVATE && lookup != EXAMPLE)  return;
+        assertNameStringContains(target, methodName);
         Object[] args = randomArgs(paramsWithSelf);
         printCalled(target, name, args);
         target.invokeWithArguments(args);
@@ -674,6 +695,49 @@
     }
 
     @Test
+    public void testFindConstructor() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
+        startTest("findConstructor");
+        testFindConstructor(true, EXAMPLE, Example.class);
+        testFindConstructor(true, EXAMPLE, Example.class, int.class);
+        testFindConstructor(true, EXAMPLE, Example.class, int.class, int.class);
+        testFindConstructor(true, EXAMPLE, Example.class, int.class, long.class);
+        testFindConstructor(true, EXAMPLE, Example.class, int.class, float.class);
+        testFindConstructor(true, EXAMPLE, Example.class, int.class, double.class);
+        testFindConstructor(true, EXAMPLE, Example.class, String.class);
+        testFindConstructor(true, EXAMPLE, Example.class, int.class, int.class, int.class);
+        testFindConstructor(true, EXAMPLE, Example.class, int.class, int.class, int.class, int.class);
+    }
+    void testFindConstructor(boolean positive, Lookup lookup,
+                             Class<?> defc, Class<?>... params) throws Throwable {
+        countTest(positive);
+        MethodType type = MethodType.methodType(void.class, params);
+        MethodHandle target = null;
+        Exception noAccess = null;
+        try {
+            if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" <init>"+type);
+            target = lookup.findConstructor(defc, type);
+        } catch (ReflectiveOperationException ex) {
+            noAccess = ex;
+            assertTrue(noAccess instanceof IllegalAccessException);
+        }
+        if (verbosity >= 3)
+            System.out.println("findConstructor "+defc.getName()+".<init>/"+type+" => "+target
+                               +(target == null ? "" : target.type())
+                               +(noAccess == null ? "" : " !! "+noAccess));
+        if (positive && noAccess != null)  throw noAccess;
+        assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, target != null);
+        if (!positive)  return; // negative test failed as expected
+        assertEquals(type.changeReturnType(defc), target.type());
+        Object[] args = randomArgs(params);
+        printCalled(target, defc.getSimpleName(), args);
+        Object obj = target.invokeWithArguments(args);
+        if (!(defc == Example.class && params.length < 2))
+            assertCalled(defc.getSimpleName()+".<init>", args);
+        assertTrue("instance of "+defc.getName(), defc.isInstance(obj));
+    }
+
+    @Test
     public void testBind() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("bind");
@@ -706,9 +770,10 @@
         Exception noAccess = null;
         try {
             if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
-            target = lookup.in(defc).bind(receiver, methodName, type);
+            target = maybeMoveIn(lookup, defc).bind(receiver, methodName, type);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            if (verbosity >= 5)  ex.printStackTrace(System.out);
             if (name.contains("bogus"))
                 assertTrue(noAccess instanceof NoSuchMethodException);
             else
@@ -735,6 +800,7 @@
         if (CAN_SKIP_WORKING)  return;
         startTest("unreflect");
         testUnreflect(Example.class, true, void.class, "s0");
+        testUnreflect(Example.class, true, void.class, "pro_s0");
         testUnreflect(Example.class, true, void.class, "pkg_s0");
         testUnreflect(Example.class, true, void.class, "pri_s0");
 
@@ -753,6 +819,9 @@
         testUnreflect(Example.class, false, Object.class, "v2", Object.class, int.class);
         testUnreflect(Example.class, false, Object.class, "v2", int.class, Object.class);
         testUnreflect(Example.class, false, Object.class, "v2", int.class, int.class);
+
+        // Test a public final member in another package:
+        testUnreflect(RemoteExample.class, false, void.class, "Rem/fin_v0");
     }
 
     void testUnreflect(Class<?> defc, boolean isStatic, Class<?> ret, String name, Class<?>... params) throws Throwable {
@@ -769,8 +838,9 @@
                                    boolean positive, Lookup lookup,
                                    Class<?> defc, Class<?> rcvc, Class<?> ret, String name, Class<?>... params) throws Throwable {
         countTest(positive);
+        String methodName = name.substring(1 + name.indexOf('/'));  // foo/bar => foo
         MethodType type = MethodType.methodType(ret, params);
-        Method rmethod = defc.getDeclaredMethod(name, params);
+        Method rmethod = defc.getDeclaredMethod(methodName, params);
         MethodHandle target = null;
         Exception noAccess = null;
         boolean isStatic = (rcvc == null);
@@ -778,11 +848,12 @@
         try {
             if (verbosity >= 4)  System.out.println("lookup via "+lookup+" of "+defc+" "+name+type);
             if (isSpecial)
-                target = lookup.in(specialCaller).unreflectSpecial(rmethod, specialCaller);
+                target = maybeMoveIn(lookup, specialCaller).unreflectSpecial(rmethod, specialCaller);
             else
-                target = lookup.in(defc).unreflect(rmethod);
+                target = maybeMoveIn(lookup, defc).unreflect(rmethod);
         } catch (ReflectiveOperationException ex) {
             noAccess = ex;
+            if (verbosity >= 5)  ex.printStackTrace(System.out);
             if (name.contains("bogus"))
                 assertTrue(noAccess instanceof NoSuchMethodException);
             else
@@ -865,7 +936,7 @@
 
         static final Object[][] CASES;
         static {
-            ArrayList<Object[]> cases = new ArrayList<Object[]>();
+            ArrayList<Object[]> cases = new ArrayList<>();
             Object types[][] = {
                 {'L',Object.class}, {'R',String.class},
                 {'I',int.class}, {'J',long.class},
@@ -884,12 +955,12 @@
                     Field field;
                         try {
                         field = HasFields.class.getDeclaredField(name);
-                    } catch (Exception ex) {
+                    } catch (NoSuchFieldException | SecurityException ex) {
                         throw new InternalError("no field HasFields."+name);
                     }
                     try {
                         value = field.get(fields);
-                    } catch (Exception ex) {
+                    } catch (IllegalArgumentException | IllegalAccessException ex) {
                         throw new InternalError("cannot fetch field HasFields."+name);
                     }
                     if (type == float.class) {
@@ -909,7 +980,7 @@
         }
     }
 
-    static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC = 3, TEST_SETTER = 0x10;
+    static final int TEST_UNREFLECT = 1, TEST_FIND_FIELD = 2, TEST_FIND_STATIC = 3, TEST_SETTER = 0x10, TEST_BOUND = 0x20, TEST_NPE = 0x40;
     static boolean testModeMatches(int testMode, boolean isStatic) {
         switch (testMode) {
         case TEST_FIND_STATIC:          return isStatic;
@@ -921,16 +992,20 @@
 
     @Test
     public void testUnreflectGetter() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
         startTest("unreflectGetter");
         testGetter(TEST_UNREFLECT);
     }
     @Test
     public void testFindGetter() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
         startTest("findGetter");
         testGetter(TEST_FIND_FIELD);
+        testGetter(TEST_FIND_FIELD | TEST_BOUND);
     }
     @Test
     public void testFindStaticGetter() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
         startTest("findStaticGetter");
         testGetter(TEST_FIND_STATIC);
     }
@@ -939,6 +1014,8 @@
         for (Object[] c : HasFields.CASES) {
             boolean positive = (c[1] != Error.class);
             testGetter(positive, lookup, c[0], c[1], testMode);
+            if (positive)
+                testGetter(positive, lookup, c[0], c[1], testMode | TEST_NPE);
         }
         testGetter(true, lookup,
                    new Object[]{ true,  System.class, "out", java.io.PrintStream.class },
@@ -954,10 +1031,15 @@
         testAccessor(positive, lookup, fieldRef, value, testMode);
     }
 
-    public void testAccessor(boolean positive, MethodHandles.Lookup lookup,
+    public void testAccessor(boolean positive0, MethodHandles.Lookup lookup,
                              Object fieldRef, Object value, int testMode0) throws Throwable {
+        if (verbosity >= 4)
+            System.out.println("testAccessor"+Arrays.deepToString(new Object[]{positive0, lookup, fieldRef, value, testMode0}));
         boolean isGetter = ((testMode0 & TEST_SETTER) == 0);
-        int testMode = testMode0 & ~TEST_SETTER;
+        boolean doBound  = ((testMode0 & TEST_BOUND) != 0);
+        boolean testNPE  = ((testMode0 & TEST_NPE) != 0);
+        int testMode = testMode0 & ~(TEST_SETTER | TEST_BOUND | TEST_NPE);
+        boolean positive = positive0 && !testNPE;
         boolean isStatic;
         Class<?> fclass;
         String   fname;
@@ -982,6 +1064,7 @@
         }
         if (!testModeMatches(testMode, isStatic))  return;
         if (f == null && testMode == TEST_UNREFLECT)  return;
+        if (testNPE && isStatic)  return;
         countTest(positive);
         MethodType expType;
         if (isGetter)
@@ -992,7 +1075,7 @@
         Exception noAccess = null;
         MethodHandle mh;
         try {
-            switch (testMode0) {
+            switch (testMode0 & ~(TEST_BOUND | TEST_NPE)) {
             case TEST_UNREFLECT:   mh = lookup.unreflectGetter(f);                      break;
             case TEST_FIND_FIELD:  mh = lookup.findGetter(fclass, fname, ftype);        break;
             case TEST_FIND_STATIC: mh = lookup.findStaticGetter(fclass, fname, ftype);  break;
@@ -1008,6 +1091,7 @@
         } catch (ReflectiveOperationException ex) {
             mh = null;
             noAccess = ex;
+            if (verbosity >= 5)  ex.printStackTrace(System.out);
             if (fname.contains("bogus"))
                 assertTrue(noAccess instanceof NoSuchFieldException);
             else
@@ -1017,15 +1101,19 @@
             System.out.println("find"+(isStatic?"Static":"")+(isGetter?"Getter":"Setter")+" "+fclass.getName()+"."+fname+"/"+ftype
                                +" => "+mh
                                +(noAccess == null ? "" : " !! "+noAccess));
-        if (positive && noAccess != null)  throw new RuntimeException(noAccess);
-        assertEquals(positive ? "positive test" : "negative test erroneously passed", positive, mh != null);
-        if (!positive)  return; // negative test failed as expected
+        if (positive && !testNPE && noAccess != null)  throw new RuntimeException(noAccess);
+        assertEquals(positive0 ? "positive test" : "negative test erroneously passed", positive0, mh != null);
+        if (!positive && !testNPE)  return; // negative access test failed as expected
         assertEquals((isStatic ? 0 : 1)+(isGetter ? 0 : 1), mh.type().parameterCount());
 
 
         assertSame(mh.type(), expType);
-        assertNameStringContains(mh, fname);
+        //assertNameStringContains(mh, fname);  // This does not hold anymore with LFs
         HasFields fields = new HasFields();
+        HasFields fieldsForMH = fields;
+        if (testNPE)  fieldsForMH = null;  // perturb MH argument to elicit expected error
+        if (doBound)
+            mh = mh.bindTo(fieldsForMH);
         Object sawValue;
         Class<?> vtype = ftype;
         if (ftype != int.class)  vtype = Object.class;
@@ -1041,19 +1129,28 @@
         if (f != null && f.getDeclaringClass() == HasFields.class) {
             assertEquals(f.get(fields), value);  // clean to start with
         }
+        Throwable caughtEx = null;
         if (isGetter) {
             Object expValue = value;
             for (int i = 0; i <= 1; i++) {
-                if (isStatic) {
-                    if (ftype == int.class)
-                        sawValue = (int) mh.invokeExact();  // do these exactly
-                    else
-                        sawValue = mh.invokeExact();
-                } else {
-                    if (ftype == int.class)
-                        sawValue = (int) mh.invokeExact((Object) fields);
-                    else
-                        sawValue = mh.invokeExact((Object) fields);
+                sawValue = null;  // make DA rules happy under try/catch
+                try {
+                    if (isStatic || doBound) {
+                        if (ftype == int.class)
+                            sawValue = (int) mh.invokeExact();  // do these exactly
+                        else
+                            sawValue = mh.invokeExact();
+                    } else {
+                        if (ftype == int.class)
+                            sawValue = (int) mh.invokeExact((Object) fieldsForMH);
+                        else
+                            sawValue = mh.invokeExact((Object) fieldsForMH);
+                    }
+                } catch (RuntimeException ex) {
+                    if (ex instanceof NullPointerException && testNPE) {
+                        caughtEx = ex;
+                        break;
+                    }
                 }
                 assertEquals(sawValue, expValue);
                 if (f != null && f.getDeclaringClass() == HasFields.class
@@ -1068,16 +1165,23 @@
         } else {
             for (int i = 0; i <= 1; i++) {
                 Object putValue = randomArg(ftype);
-                if (isStatic) {
-                    if (ftype == int.class)
-                        mh.invokeExact((int)putValue);  // do these exactly
-                    else
-                        mh.invokeExact(putValue);
-                } else {
-                    if (ftype == int.class)
-                        mh.invokeExact((Object) fields, (int)putValue);
-                    else
-                        mh.invokeExact((Object) fields, putValue);
+                try {
+                    if (isStatic || doBound) {
+                        if (ftype == int.class)
+                            mh.invokeExact((int)putValue);  // do these exactly
+                        else
+                            mh.invokeExact(putValue);
+                    } else {
+                        if (ftype == int.class)
+                            mh.invokeExact((Object) fieldsForMH, (int)putValue);
+                        else
+                            mh.invokeExact((Object) fieldsForMH, putValue);
+                    }
+                } catch (RuntimeException ex) {
+                    if (ex instanceof NullPointerException && testNPE) {
+                        caughtEx = ex;
+                        break;
+                    }
                 }
                 if (f != null && f.getDeclaringClass() == HasFields.class) {
                     assertEquals(f.get(fields), putValue);
@@ -1087,21 +1191,33 @@
         if (f != null && f.getDeclaringClass() == HasFields.class) {
             f.set(fields, value);  // put it back
         }
+        if (testNPE) {
+            if (caughtEx == null || !(caughtEx instanceof NullPointerException))
+                throw new RuntimeException("failed to catch NPE exception"+(caughtEx == null ? " (caughtEx=null)" : ""), caughtEx);
+            caughtEx = null;  // nullify expected exception
+        }
+        if (caughtEx != null) {
+            throw new RuntimeException("unexpected exception", caughtEx);
+        }
     }
 
 
     @Test
     public void testUnreflectSetter() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
         startTest("unreflectSetter");
         testSetter(TEST_UNREFLECT);
     }
     @Test
     public void testFindSetter() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
         startTest("findSetter");
         testSetter(TEST_FIND_FIELD);
+        testSetter(TEST_FIND_FIELD | TEST_BOUND);
     }
     @Test
     public void testFindStaticSetter() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
         startTest("findStaticSetter");
         testSetter(TEST_FIND_STATIC);
     }
@@ -1111,6 +1227,8 @@
         for (Object[] c : HasFields.CASES) {
             boolean positive = (c[1] != Error.class);
             testSetter(positive, lookup, c[0], c[1], testMode);
+            if (positive)
+                testSetter(positive, lookup, c[0], c[1], testMode | TEST_NPE);
         }
         for (int isStaticN = 0; isStaticN <= 1; isStaticN++) {
             testSetter(false, lookup,
@@ -1125,34 +1243,84 @@
 
     @Test
     public void testArrayElementGetter() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
         startTest("arrayElementGetter");
         testArrayElementGetterSetter(false);
     }
 
     @Test
     public void testArrayElementSetter() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
         startTest("arrayElementSetter");
         testArrayElementGetterSetter(true);
     }
 
+    private static final int TEST_ARRAY_NONE = 0, TEST_ARRAY_NPE = 1, TEST_ARRAY_OOB = 2, TEST_ARRAY_ASE = 3;
+
     public void testArrayElementGetterSetter(boolean testSetter) throws Throwable {
-        testArrayElementGetterSetter(new Object[10], testSetter);
-        testArrayElementGetterSetter(new String[10], testSetter);
-        testArrayElementGetterSetter(new boolean[10], testSetter);
-        testArrayElementGetterSetter(new byte[10], testSetter);
-        testArrayElementGetterSetter(new char[10], testSetter);
-        testArrayElementGetterSetter(new short[10], testSetter);
-        testArrayElementGetterSetter(new int[10], testSetter);
-        testArrayElementGetterSetter(new float[10], testSetter);
-        testArrayElementGetterSetter(new long[10], testSetter);
-        testArrayElementGetterSetter(new double[10], testSetter);
+        testArrayElementGetterSetter(testSetter, TEST_ARRAY_NONE);
     }
 
-    public void testArrayElementGetterSetter(Object array, boolean testSetter) throws Throwable {
-        countTest(true);
-        if (verbosity >= 2)  System.out.println("array type = "+array.getClass().getComponentType().getName()+"["+Array.getLength(array)+"]");
+    @Test
+    public void testArrayElementErrors() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
+        startTest("arrayElementErrors");
+        testArrayElementGetterSetter(false, TEST_ARRAY_NPE);
+        testArrayElementGetterSetter(true, TEST_ARRAY_NPE);
+        testArrayElementGetterSetter(false, TEST_ARRAY_OOB);
+        testArrayElementGetterSetter(true, TEST_ARRAY_OOB);
+        testArrayElementGetterSetter(new Object[10], true, TEST_ARRAY_ASE);
+        testArrayElementGetterSetter(new Example[10], true, TEST_ARRAY_ASE);
+        testArrayElementGetterSetter(new IntExample[10], true, TEST_ARRAY_ASE);
+    }
+
+    public void testArrayElementGetterSetter(boolean testSetter, int negTest) throws Throwable {
+        testArrayElementGetterSetter(new String[10], testSetter, negTest);
+        testArrayElementGetterSetter(new Iterable<?>[10], testSetter, negTest);
+        testArrayElementGetterSetter(new Example[10], testSetter, negTest);
+        testArrayElementGetterSetter(new IntExample[10], testSetter, negTest);
+        testArrayElementGetterSetter(new Object[10], testSetter, negTest);
+        testArrayElementGetterSetter(new boolean[10], testSetter, negTest);
+        testArrayElementGetterSetter(new byte[10], testSetter, negTest);
+        testArrayElementGetterSetter(new char[10], testSetter, negTest);
+        testArrayElementGetterSetter(new short[10], testSetter, negTest);
+        testArrayElementGetterSetter(new int[10], testSetter, negTest);
+        testArrayElementGetterSetter(new float[10], testSetter, negTest);
+        testArrayElementGetterSetter(new long[10], testSetter, negTest);
+        testArrayElementGetterSetter(new double[10], testSetter, negTest);
+    }
+
+    public void testArrayElementGetterSetter(Object array, boolean testSetter, int negTest) throws Throwable {
+        boolean positive = (negTest == TEST_ARRAY_NONE);
+        int length = java.lang.reflect.Array.getLength(array);
         Class<?> arrayType = array.getClass();
         Class<?> elemType = arrayType.getComponentType();
+        Object arrayToMH = array;
+        // this stanza allows negative tests to make argument perturbations:
+        switch (negTest) {
+        case TEST_ARRAY_NPE:
+            arrayToMH = null;
+            break;
+        case TEST_ARRAY_OOB:
+            assert(length > 0);
+            arrayToMH = java.lang.reflect.Array.newInstance(elemType, 0);
+            break;
+        case TEST_ARRAY_ASE:
+            assert(testSetter && !elemType.isPrimitive());
+            if (elemType == Object.class)
+                arrayToMH = new StringBuffer[length];  // very random subclass of Object!
+            else if (elemType == Example.class)
+                arrayToMH = new SubExample[length];
+            else if (elemType == IntExample.class)
+                arrayToMH = new SubIntExample[length];
+            else
+                return;  // can't make an ArrayStoreException test
+            assert(arrayType.isInstance(arrayToMH))
+                : Arrays.asList(arrayType, arrayToMH.getClass(), testSetter, negTest);
+            break;
+        }
+        countTest(positive);
+        if (verbosity > 2)  System.out.println("array type = "+array.getClass().getComponentType().getName()+"["+length+"]"+(positive ? "" : " negative test #"+negTest+" using "+Arrays.deepToString(new Object[]{arrayToMH})));
         MethodType expType = !testSetter
                 ? MethodType.methodType(elemType,   arrayType, int.class)
                 : MethodType.methodType(void.class, arrayType, int.class, elemType);
@@ -1161,25 +1329,29 @@
                 : MethodHandles.arrayElementSetter(arrayType);
         assertSame(mh.type(), expType);
         if (elemType != int.class && elemType != boolean.class) {
-            // FIXME: change Integer.class and (Integer) below to int.class and (int) below.
-            MethodType gtype = mh.type().generic().changeParameterType(1, Integer.class);
+            MethodType gtype = mh.type().generic().changeParameterType(1, int.class);
             if (testSetter)  gtype = gtype.changeReturnType(void.class);
             mh = mh.asType(gtype);
         }
         Object sawValue, expValue;
         List<Object> model = array2list(array);
-        int length = Array.getLength(array);
+        Throwable caughtEx = null;
         for (int i = 0; i < length; i++) {
             // update array element
             Object random = randomArg(elemType);
             model.set(i, random);
             if (testSetter) {
-                if (elemType == int.class)
-                    mh.invokeExact((int[]) array, i, (int)random);
-                else if (elemType == boolean.class)
-                    mh.invokeExact((boolean[]) array, i, (boolean)random);
-                else
-                    mh.invokeExact(array, (Integer)i, random);
+                try {
+                    if (elemType == int.class)
+                        mh.invokeExact((int[]) arrayToMH, i, (int)random);
+                    else if (elemType == boolean.class)
+                        mh.invokeExact((boolean[]) arrayToMH, i, (boolean)random);
+                    else
+                        mh.invokeExact(arrayToMH, i, random);
+                } catch (RuntimeException ex) {
+                    caughtEx = ex;
+                    break;
+                }
                 assertEquals(model, array2list(array));
             } else {
                 Array.set(array, i, random);
@@ -1194,21 +1366,44 @@
             sawValue = Array.get(array, i);
             if (!testSetter) {
                 expValue = sawValue;
-                if (elemType == int.class)
-                    sawValue = (int) mh.invokeExact((int[]) array, i);
-                else if (elemType == boolean.class)
-                    sawValue = (boolean) mh.invokeExact((boolean[]) array, i);
-                else
-                    sawValue = mh.invokeExact(array, (Integer)i);
+                try {
+                    if (elemType == int.class)
+                        sawValue = (int) mh.invokeExact((int[]) arrayToMH, i);
+                    else if (elemType == boolean.class)
+                        sawValue = (boolean) mh.invokeExact((boolean[]) arrayToMH, i);
+                    else
+                        sawValue = mh.invokeExact(arrayToMH, i);
+                } catch (RuntimeException ex) {
+                    caughtEx = ex;
+                    break;
+                }
                 assertEquals(sawValue, expValue);
                 assertEquals(model, array2list(array));
             }
         }
+        if (!positive) {
+            if (caughtEx == null)
+                throw new RuntimeException("failed to catch exception for negTest="+negTest);
+            // test the kind of exception
+            Class<?> reqType = null;
+            switch (negTest) {
+            case TEST_ARRAY_ASE:  reqType = ArrayStoreException.class; break;
+            case TEST_ARRAY_OOB:  reqType = ArrayIndexOutOfBoundsException.class; break;
+            case TEST_ARRAY_NPE:  reqType = NullPointerException.class; break;
+            default:              assert(false);
+            }
+            if (reqType.isInstance(caughtEx)) {
+                caughtEx = null;  // nullify expected exception
+            }
+        }
+        if (caughtEx != null) {
+            throw new RuntimeException("unexpected exception", caughtEx);
+        }
     }
 
     List<Object> array2list(Object array) {
         int length = Array.getLength(array);
-        ArrayList<Object> model = new ArrayList<Object>(length);
+        ArrayList<Object> model = new ArrayList<>(length);
         for (int i = 0; i < length; i++)
             model.add(Array.get(array, i));
         return model;
@@ -1239,7 +1434,7 @@
             String name = pfx+"id";
             try {
                 return PRIVATE.findStatic(Callee.class, name, type);
-            } catch (Exception ex) {
+            } catch (NoSuchMethodException | IllegalAccessException ex) {
                 throw new RuntimeException(ex);
             }
         }
@@ -1290,7 +1485,7 @@
         RuntimeException error = null;
         try {
             target = id.asType(newType);
-        } catch (RuntimeException ex) {
+        } catch (WrongMethodTypeException ex) {
             error = ex;
         }
         if (verbosity >= 3)
@@ -1310,25 +1505,28 @@
 
     @Test
     public void testVarargsCollector() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
+        startTest("varargsCollector");
         MethodHandle vac0 = PRIVATE.findStatic(MethodHandlesTest.class, "called",
                                MethodType.methodType(Object.class, String.class, Object[].class));
         vac0 = vac0.bindTo("vac");
         MethodHandle vac = vac0.asVarargsCollector(Object[].class);
         testConvert(true, vac.asType(MethodType.genericMethodType(0)), null, "vac");
         testConvert(true, vac.asType(MethodType.genericMethodType(0)), null, "vac");
-        for (Class<?> at : new Class[] { Object.class, String.class, Integer.class }) {
+        for (Class<?> at : new Class<?>[] { Object.class, String.class, Integer.class }) {
             testConvert(true, vac.asType(MethodType.genericMethodType(1)), null, "vac", at);
             testConvert(true, vac.asType(MethodType.genericMethodType(2)), null, "vac", at, at);
         }
     }
 
-    @Test
+    @Test  // SLOW
     public void testPermuteArguments() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("permuteArguments");
+        testPermuteArguments(4, Integer.class,  2, long.class,    6);
+        if (CAN_TEST_LIGHTLY)  return;
         testPermuteArguments(4, Integer.class,  2, String.class,  0);
         testPermuteArguments(6, Integer.class,  0, null,         30);
-        //testPermuteArguments(4, Integer.class,  2, long.class,    6);  // FIXME Fail_7
     }
     public void testPermuteArguments(int max, Class<?> type1, int t2c, Class<?> type2, int dilution) throws Throwable {
         if (verbosity >= 2)
@@ -1354,7 +1552,9 @@
                     casStep++;
                 testPermuteArguments(args, types, outargs, numcases, casStep);
                 numcases *= inargs;
+                if (CAN_TEST_LIGHTLY && outargs < max-2)  continue;
                 if (dilution > 10 && outargs >= 4) {
+                    if (CAN_TEST_LIGHTLY)  continue;
                     int[] reorder = new int[outargs];
                     // Do some special patterns, which we probably missed.
                     // Replication of a single argument or argument pair.
@@ -1392,6 +1592,7 @@
                 reorder[i] = c % inargs;
                 c /= inargs;
             }
+            if (CAN_TEST_LIGHTLY && outargs >= 3 && (reorder[0] == reorder[1] || reorder[1] == reorder[2]))  continue;
             testPermuteArguments(args, types, reorder);
         }
     }
@@ -1457,19 +1658,20 @@
     }
 
 
-    @Test
+    @Test  // SLOW
     public void testSpreadArguments() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("spreadArguments");
-        for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+        for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {
             if (verbosity >= 3)
                 System.out.println("spreadArguments "+argType);
-            // FIXME: enable _adapter_spread_args and fix Fail_2
-            for (int nargs = 0; nargs < 10; nargs++) {
-                if (argType == int.class && nargs >= 6)  continue; // FIXME Fail_1
-                for (int pos = 0; pos < nargs; pos++) {
-                    if (argType == int.class && pos > 0)  continue; // FIXME Fail_3
-                     testSpreadArguments(argType, pos, nargs);
+            for (int nargs = 0; nargs < 50; nargs++) {
+                if (CAN_TEST_LIGHTLY && nargs > 11)  break;
+                for (int pos = 0; pos <= nargs; pos++) {
+                    if (CAN_TEST_LIGHTLY && pos > 2 && pos < nargs-2)  continue;
+                    if (nargs > 10 && pos > 4 && pos < nargs-4 && pos % 10 != 3)
+                        continue;
+                    testSpreadArguments(argType, pos, nargs);
                 }
             }
         }
@@ -1484,7 +1686,7 @@
         Object[] args = randomArgs(target2.type().parameterArray());
         // make sure the target does what we think it does:
         if (pos == 0 && nargs < 5 && !argType.isPrimitive()) {
-            Object[] check = (Object[]) (Object) target.invokeWithArguments(args);
+            Object[] check = (Object[]) target.invokeWithArguments(args);
             assertArrayEquals(args, check);
             switch (nargs) {
                 case 0:
@@ -1501,7 +1703,7 @@
                     break;
             }
         }
-        List<Class<?>> newParams = new ArrayList<Class<?>>(target2.type().parameterList());
+        List<Class<?>> newParams = new ArrayList<>(target2.type().parameterList());
         {   // modify newParams in place
             List<Class<?>> spreadParams = newParams.subList(pos, nargs);
             spreadParams.clear(); spreadParams.add(arrayType);
@@ -1550,16 +1752,19 @@
         }
     }
 
-    @Test
+    @Test  // SLOW
     public void testCollectArguments() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("collectArguments");
-        for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+        for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {
             if (verbosity >= 3)
                 System.out.println("collectArguments "+argType);
-            for (int nargs = 0; nargs < 10; nargs++) {
-                for (int pos = 0; pos < nargs; pos++) {
-                    if (argType == int.class)  continue; // FIXME Fail_4
+            for (int nargs = 0; nargs < 50; nargs++) {
+                if (CAN_TEST_LIGHTLY && nargs > 11)  break;
+                for (int pos = 0; pos <= nargs; pos++) {
+                    if (CAN_TEST_LIGHTLY && pos > 2 && pos < nargs-2)  continue;
+                    if (nargs > 10 && pos > 4 && pos < nargs-4 && pos % 10 != 3)
+                        continue;
                     testCollectArguments(argType, pos, nargs);
                 }
             }
@@ -1589,14 +1794,19 @@
         assertArrayEquals(collectedArgs, returnValue);
     }
 
-    @Test
+    @Test  // SLOW
     public void testInsertArguments() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("insertArguments");
-        for (int nargs = 0; nargs <= 4; nargs++) {
-            for (int ins = 0; ins <= 4; ins++) {
-                if (ins > MAX_ARG_INCREASE)  continue;  // FIXME Fail_6
+        for (int nargs = 0; nargs < 50; nargs++) {
+            if (CAN_TEST_LIGHTLY && nargs > 11)  break;
+            for (int ins = 0; ins <= nargs; ins++) {
+                if (nargs > 10 && ins > 4 && ins < nargs-4 && ins % 10 != 3)
+                    continue;
                 for (int pos = 0; pos <= nargs; pos++) {
+                    if (nargs > 10 && pos > 4 && pos < nargs-4 && pos % 10 != 3)
+                        continue;
+                    if (CAN_TEST_LIGHTLY && pos > 2 && pos < nargs-2)  continue;
                     testInsertArguments(nargs, pos, ins);
                 }
             }
@@ -1608,12 +1818,13 @@
         MethodHandle target = varargsArray(nargs + ins);
         Object[] args = randomArgs(target.type().parameterArray());
         List<Object> resList = Arrays.asList(args);
-        List<Object> argsToPass = new ArrayList<Object>(resList);
+        List<Object> argsToPass = new ArrayList<>(resList);
         List<Object> argsToInsert = argsToPass.subList(pos, pos + ins);
         if (verbosity >= 3)
-            System.out.println("insert: "+argsToInsert+" into "+target);
+            System.out.println("insert: "+argsToInsert+" @"+pos+" into "+target);
+        @SuppressWarnings("cast")  // cast to spread Object... is helpful
         MethodHandle target2 = MethodHandles.insertArguments(target, pos,
-                (Object[]) argsToInsert.toArray());
+                (Object[]/*...*/) argsToInsert.toArray());
         argsToInsert.clear();  // remove from argsToInsert
         Object res2 = target2.invokeWithArguments(argsToPass);
         Object res2List = Arrays.asList((Object[])res2);
@@ -1631,11 +1842,11 @@
         Class<?> classOfVCList = varargsList(1).invokeWithArguments(0).getClass();
         assertTrue(List.class.isAssignableFrom(classOfVCList));
         for (int nargs = 0; nargs <= 3; nargs++) {
-            for (Class<?> rtype : new Class[] { Object.class,
+            for (Class<?> rtype : new Class<?>[] { Object.class,
                                                 List.class,
                                                 int.class,
-                                                //byte.class, //FIXME: add this
-                                                //long.class, //FIXME: add this
+                                                byte.class,
+                                                long.class,
                                                 CharSequence.class,
                                                 String.class }) {
                 testFilterReturnValue(nargs, rtype);
@@ -1728,7 +1939,7 @@
             System.out.println("fold "+target+" with "+combine);
         MethodHandle target2 = MethodHandles.foldArguments(target, combine);
         // Simulate expected effect of combiner on arglist:
-        List<Object> expected = new ArrayList<Object>(argsToPass);
+        List<Object> expected = new ArrayList<>(argsToPass);
         List<Object> argsToFold = expected.subList(pos, pos + fold);
         if (verbosity >= 3)
             System.out.println("fold: "+argsToFold+" into "+target2);
@@ -1760,9 +1971,9 @@
         MethodHandle target = varargsArray(nargs);
         Object[] args = randomArgs(target.type().parameterArray());
         MethodHandle target2 = MethodHandles.dropArguments(target, pos,
-                Collections.nCopies(drop, Object.class).toArray(new Class[0]));
+                Collections.nCopies(drop, Object.class).toArray(new Class<?>[0]));
         List<Object> resList = Arrays.asList(args);
-        List<Object> argsToDrop = new ArrayList<Object>(resList);
+        List<Object> argsToDrop = new ArrayList<>(resList);
         for (int i = drop; i > 0; i--) {
             argsToDrop.add(pos, "blort#"+i);
         }
@@ -1773,15 +1984,16 @@
         assertEquals(resList, res2List);
     }
 
-    @Test
+    @Test  // SLOW
     public void testInvokers() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("exactInvoker, genericInvoker, varargsInvoker, dynamicInvoker");
         // exactInvoker, genericInvoker, varargsInvoker[0..N], dynamicInvoker
-        Set<MethodType> done = new HashSet<MethodType>();
+        Set<MethodType> done = new HashSet<>();
         for (int i = 0; i <= 6; i++) {
+            if (CAN_TEST_LIGHTLY && i > 3)  break;
             MethodType gtype = MethodType.genericMethodType(i);
-            for (Class<?> argType : new Class[]{Object.class, Integer.class, int.class}) {
+            for (Class<?> argType : new Class<?>[]{Object.class, Integer.class, int.class}) {
                 for (int j = -1; j < i; j++) {
                     MethodType type = gtype;
                     if (j < 0)
@@ -1790,7 +2002,6 @@
                         continue;
                     else
                         type = type.changeParameterType(j, argType);
-                    if (argType.isPrimitive() && j != i-1)  continue; // FIXME Fail_5
                     if (done.add(type))
                         testInvokers(type);
                     MethodType vtype = type.changeReturnType(void.class);
@@ -1811,7 +2022,7 @@
         assertTrue(target.isVarargsCollector());
         target = target.asType(type);
         Object[] args = randomArgs(type.parameterArray());
-        List<Object> targetPlusArgs = new ArrayList<Object>(Arrays.asList(args));
+        List<Object> targetPlusArgs = new ArrayList<>(Arrays.asList(args));
         targetPlusArgs.add(0, target);
         int code = (Integer) invokee(args);
         Object log = logEntry("invokee", args);
@@ -1890,6 +2101,7 @@
         }
         for (int k = 0; k <= nargs; k++) {
             // varargs invoker #0..N
+            if (CAN_TEST_LIGHTLY && (k > 1 || k < nargs - 1))  continue;
             countTest();
             calledLog.clear();
             inv = MethodHandles.spreadInvoker(type, k);
@@ -1897,7 +2109,7 @@
                                   .appendParameterTypes(Object[].class)
                                   .insertParameterTypes(0, MethodHandle.class));
             assertEquals(expType, inv.type());
-            List<Object> targetPlusVarArgs = new ArrayList<Object>(targetPlusArgs);
+            List<Object> targetPlusVarArgs = new ArrayList<>(targetPlusArgs);
             List<Object> tailList = targetPlusVarArgs.subList(1+k, 1+nargs);
             Object[] tail = tailList.toArray();
             tailList.clear(); tailList.add(tail);
@@ -1933,6 +2145,7 @@
     }
 
     private static final String MISSING_ARG = "missingArg";
+    private static final String MISSING_ARG_2 = "missingArg#2";
     static Object targetIfEquals() {
         return called("targetIfEquals");
     }
@@ -1968,28 +2181,39 @@
     public void testGuardWithTest() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("guardWithTest");
-        for (int nargs = 0; nargs <= 3; nargs++) {
-            if (nargs != 2)  continue;  // FIXME: test more later
+        for (int nargs = 0; nargs <= 50; nargs++) {
+            if (CAN_TEST_LIGHTLY && nargs > 7)  break;
             testGuardWithTest(nargs, Object.class);
             testGuardWithTest(nargs, String.class);
         }
     }
     void testGuardWithTest(int nargs, Class<?> argClass) throws Throwable {
+        testGuardWithTest(nargs, 0, argClass);
+        if (nargs <= 5 || nargs % 10 == 3) {
+            for (int testDrops = 1; testDrops <= nargs; testDrops++)
+                testGuardWithTest(nargs, testDrops, argClass);
+        }
+    }
+    void testGuardWithTest(int nargs, int testDrops, Class<?> argClass) throws Throwable {
         countTest();
+        int nargs1 = Math.min(3, nargs);
         MethodHandle test = PRIVATE.findVirtual(Object.class, "equals", MethodType.methodType(boolean.class, Object.class));
-        MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "targetIfEquals", MethodType.genericMethodType(nargs));
-        MethodHandle fallback = PRIVATE.findStatic(MethodHandlesTest.class, "fallbackIfNotEquals", MethodType.genericMethodType(nargs));
-        while (test.type().parameterCount() < nargs)
-            test = MethodHandles.dropArguments(test, test.type().parameterCount()-1, Object.class);
+        MethodHandle target = PRIVATE.findStatic(MethodHandlesTest.class, "targetIfEquals", MethodType.genericMethodType(nargs1));
+        MethodHandle fallback = PRIVATE.findStatic(MethodHandlesTest.class, "fallbackIfNotEquals", MethodType.genericMethodType(nargs1));
         while (test.type().parameterCount() > nargs)
+            // 0: test = constant(MISSING_ARG.equals(MISSING_ARG))
+            // 1: test = lambda (_) MISSING_ARG.equals(_)
             test = MethodHandles.insertArguments(test, 0, MISSING_ARG);
         if (argClass != Object.class) {
             test = changeArgTypes(test, argClass);
             target = changeArgTypes(target, argClass);
             fallback = changeArgTypes(fallback, argClass);
         }
-        MethodHandle mh = MethodHandles.guardWithTest(test, target, fallback);
-        assertEquals(target.type(), mh.type());
+        int testArgs = nargs - testDrops;
+        assert(testArgs >= 0);
+        test = addTrailingArgs(test, Math.min(testArgs, nargs), argClass);
+        target = addTrailingArgs(target, nargs, argClass);
+        fallback = addTrailingArgs(fallback, nargs, argClass);
         Object[][] argLists = {
             { },
             { "foo" }, { MISSING_ARG },
@@ -1997,7 +2221,19 @@
             { "foo", "foo", "baz" }, { "foo", "bar", "baz" }
         };
         for (Object[] argList : argLists) {
-            if (argList.length != nargs)  continue;
+            Object[] argList1 = argList;
+            if (argList.length != nargs) {
+                if (argList.length != nargs1)  continue;
+                argList1 = Arrays.copyOf(argList, nargs);
+                Arrays.fill(argList1, nargs1, nargs, MISSING_ARG_2);
+            }
+            MethodHandle test1 = test;
+            if (test1.type().parameterCount() > testArgs) {
+                int pc = test1.type().parameterCount();
+                test1 = MethodHandles.insertArguments(test, testArgs, Arrays.copyOfRange(argList1, testArgs, pc));
+            }
+            MethodHandle mh = MethodHandles.guardWithTest(test1, target, fallback);
+            assertEquals(target.type(), mh.type());
             boolean equals;
             switch (nargs) {
             case 0:   equals = true; break;
@@ -2007,7 +2243,7 @@
             String willCall = (equals ? "targetIfEquals" : "fallbackIfNotEquals");
             if (verbosity >= 3)
                 System.out.println(logEntry(willCall, argList));
-            Object result = mh.invokeWithArguments(argList);
+            Object result = mh.invokeWithArguments(argList1);
             assertCalled(willCall, argList);
         }
     }
@@ -2016,49 +2252,102 @@
     public void testCatchException() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("catchException");
-        for (int nargs = 2; nargs <= 6; nargs++) {
-            for (int ti = 0; ti <= 1; ti++) {
-                boolean throwIt = (ti != 0);
-                testCatchException(int.class, new ClassCastException("testing"), throwIt, nargs);
-                testCatchException(void.class, new java.io.IOException("testing"), throwIt, nargs);
-                testCatchException(String.class, new LinkageError("testing"), throwIt, nargs);
+        for (int nargs = 0; nargs < 40; nargs++) {
+            if (CAN_TEST_LIGHTLY && nargs > 11)  break;
+            for (int throwMode = 0; throwMode < THROW_MODE_LIMIT; throwMode++) {
+                testCatchException(int.class, new ClassCastException("testing"), throwMode, nargs);
+                if (CAN_TEST_LIGHTLY && nargs > 3)  continue;
+                testCatchException(void.class, new java.io.IOException("testing"), throwMode, nargs);
+                testCatchException(String.class, new LinkageError("testing"), throwMode, nargs);
             }
         }
     }
 
+    static final int THROW_NOTHING = 0, THROW_CAUGHT = 1, THROW_UNCAUGHT = 2, THROW_THROUGH_ADAPTER = 3, THROW_MODE_LIMIT = 4;
+
+    void testCatchException(Class<?> returnType, Throwable thrown, int throwMode, int nargs) throws Throwable {
+        testCatchException(returnType, thrown, throwMode, nargs, 0);
+        if (nargs <= 5 || nargs % 10 == 3) {
+            for (int catchDrops = 1; catchDrops <= nargs; catchDrops++)
+                testCatchException(returnType, thrown, throwMode, nargs, catchDrops);
+        }
+    }
+
     private static <T extends Throwable>
     Object throwOrReturn(Object normal, T exception) throws T {
-        if (exception != null)  throw exception;
+        if (exception != null) {
+            called("throwOrReturn/throw", normal, exception);
+            throw exception;
+        }
+        called("throwOrReturn/normal", normal, exception);
         return normal;
     }
+    private int fakeIdentityCount;
+    private Object fakeIdentity(Object x) {
+        System.out.println("should throw through this!");
+        fakeIdentityCount++;
+        return x;
+    }
 
-    void testCatchException(Class<?> returnType, Throwable thrown, boolean throwIt, int nargs) throws Throwable {
+    void testCatchException(Class<?> returnType, Throwable thrown, int throwMode, int nargs, int catchDrops) throws Throwable {
         countTest();
         if (verbosity >= 3)
-            System.out.println("catchException rt="+returnType+" throw="+throwIt+" nargs="+nargs);
+            System.out.println("catchException rt="+returnType+" throw="+throwMode+" nargs="+nargs+" drops="+catchDrops);
         Class<? extends Throwable> exType = thrown.getClass();
+        if (throwMode > THROW_CAUGHT)  thrown = new UnsupportedOperationException("do not catch this");
         MethodHandle throwOrReturn
                 = PRIVATE.findStatic(MethodHandlesTest.class, "throwOrReturn",
                     MethodType.methodType(Object.class, Object.class, Throwable.class));
+        if (throwMode == THROW_THROUGH_ADAPTER) {
+            MethodHandle fakeIdentity
+                = PRIVATE.findVirtual(MethodHandlesTest.class, "fakeIdentity",
+                    MethodType.methodType(Object.class, Object.class)).bindTo(this);
+            for (int i = 0; i < 10; i++)
+                throwOrReturn = MethodHandles.filterReturnValue(throwOrReturn, fakeIdentity);
+        }
+        int nargs1 = Math.max(2, nargs);
         MethodHandle thrower = throwOrReturn.asType(MethodType.genericMethodType(2));
-        while (thrower.type().parameterCount() < nargs)
-            thrower = MethodHandles.dropArguments(thrower, thrower.type().parameterCount(), Object.class);
-        MethodHandle catcher = varargsList(1+nargs).asType(MethodType.genericMethodType(1+nargs));
-        MethodHandle target = MethodHandles.catchException(thrower,
-                thrown.getClass(), catcher);
-        assertEquals(thrower.type(), target.type());
-        //System.out.println("catching with "+target+" : "+throwOrReturn);
+        thrower = addTrailingArgs(thrower, nargs, Object.class);
+        int catchArgc = 1 + nargs - catchDrops;
+        MethodHandle catcher = varargsList(catchArgc).asType(MethodType.genericMethodType(catchArgc));
         Object[] args = randomArgs(nargs, Object.class);
-        args[1] = (throwIt ? thrown : null);
-        Object returned = target.invokeWithArguments(args);
+        Object arg0 = MISSING_ARG;
+        Object arg1 = (throwMode == THROW_NOTHING) ? (Throwable) null : thrown;
+        if (nargs > 0)  arg0 = args[0];
+        if (nargs > 1)  args[1] = arg1;
+        assertEquals(nargs1, thrower.type().parameterCount());
+        if (nargs < nargs1) {
+            Object[] appendArgs = { arg0, arg1 };
+            appendArgs = Arrays.copyOfRange(appendArgs, nargs, nargs1);
+            thrower = MethodHandles.insertArguments(thrower, nargs, appendArgs);
+        }
+        assertEquals(nargs, thrower.type().parameterCount());
+        MethodHandle target = MethodHandles.catchException(thrower, exType, catcher);
+        assertEquals(thrower.type(), target.type());
+        assertEquals(nargs, target.type().parameterCount());
+        //System.out.println("catching with "+target+" : "+throwOrReturn);
+        Object returned;
+        try {
+            returned = target.invokeWithArguments(args);
+        } catch (Throwable ex) {
+            assertSame("must get the out-of-band exception", thrown, ex);
+            if (throwMode <= THROW_CAUGHT)
+                assertEquals(THROW_UNCAUGHT, throwMode);
+            returned = ex;
+        }
+        assertCalled("throwOrReturn/"+(throwMode == THROW_NOTHING ? "normal" : "throw"), arg0, arg1);
         //System.out.println("return from "+target+" : "+returned);
-        if (!throwIt) {
-            assertSame(args[0], returned);
-        } else {
-            List<Object> catchArgs = new ArrayList<Object>(Arrays.asList(args));
+        if (throwMode == THROW_NOTHING) {
+            assertSame(arg0, returned);
+        } else if (throwMode == THROW_CAUGHT) {
+            List<Object> catchArgs = new ArrayList<>(Arrays.asList(args));
+            // catcher receives an initial subsequence of target arguments:
+            catchArgs.subList(nargs - catchDrops, nargs).clear();
+            // catcher also receives the exception, prepended:
             catchArgs.add(0, thrown);
             assertEquals(catchArgs, returned);
         }
+        assertEquals(0, fakeIdentityCount);
     }
 
     @Test
@@ -2093,10 +2382,108 @@
     }
 
     @Test
+    public void testInterfaceCast() throws Throwable {
+        //if (CAN_SKIP_WORKING)  return;
+        startTest("interfaceCast");
+        assert( (((Object)"foo") instanceof CharSequence));
+        assert(!(((Object)"foo") instanceof Iterable));
+        for (MethodHandle mh : new MethodHandle[]{
+            MethodHandles.identity(String.class),
+            MethodHandles.identity(CharSequence.class),
+            MethodHandles.identity(Iterable.class)
+        }) {
+            if (verbosity > 0)  System.out.println("-- mh = "+mh);
+            for (Class<?> ctype : new Class<?>[]{
+                Object.class, String.class, CharSequence.class,
+                Number.class, Iterable.class
+            }) {
+                if (verbosity > 0)  System.out.println("---- ctype = "+ctype.getName());
+                //                           doret  docast
+                testInterfaceCast(mh, ctype, false, false);
+                testInterfaceCast(mh, ctype, true,  false);
+                testInterfaceCast(mh, ctype, false, true);
+                testInterfaceCast(mh, ctype, true,  true);
+            }
+        }
+    }
+    private static Class<?> i2o(Class<?> c) {
+        return (c.isInterface() ? Object.class : c);
+    }
+    public void testInterfaceCast(MethodHandle mh, Class<?> ctype,
+                                                   boolean doret, boolean docast) throws Throwable {
+        MethodHandle mh0 = mh;
+        if (verbosity > 1)
+            System.out.println("mh="+mh+", ctype="+ctype.getName()+", doret="+doret+", docast="+docast);
+        String normalRetVal = "normal return value";
+        MethodType mt = mh.type();
+        MethodType mt0 = mt;
+        if (doret)  mt = mt.changeReturnType(ctype);
+        else        mt = mt.changeParameterType(0, ctype);
+        if (docast) mh = MethodHandles.explicitCastArguments(mh, mt);
+        else        mh = mh.asType(mt);
+        assertEquals(mt, mh.type());
+        MethodType mt1 = mt;
+        // this bit is needed to make the interface types disappear for invokeWithArguments:
+        mh = MethodHandles.explicitCastArguments(mh, mt.generic());
+        Class<?>[] step = {
+            mt1.parameterType(0),  // param as passed to mh at first
+            mt0.parameterType(0),  // param after incoming cast
+            mt0.returnType(),      // return value before cast
+            mt1.returnType(),      // return value after outgoing cast
+        };
+        // where might a checkCast occur?
+        boolean[] checkCast = new boolean[step.length];
+        // the string value must pass each step without causing an exception
+        if (!docast) {
+            if (!doret) {
+                if (step[0] != step[1])
+                    checkCast[1] = true;  // incoming value is cast
+            } else {
+                if (step[2] != step[3])
+                    checkCast[3] = true;  // outgoing value is cast
+            }
+        }
+        boolean expectFail = false;
+        for (int i = 0; i < step.length; i++) {
+            Class<?> c = step[i];
+            if (!checkCast[i])  c = i2o(c);
+            if (!c.isInstance(normalRetVal)) {
+                if (verbosity > 3)
+                    System.out.println("expect failure at step "+i+" in "+Arrays.toString(step)+Arrays.toString(checkCast));
+                expectFail = true;
+                break;
+            }
+        }
+        countTest(!expectFail);
+        if (verbosity > 2)
+            System.out.println("expectFail="+expectFail+", mt="+mt);
+        Object res;
+        try {
+            res = mh.invokeWithArguments(normalRetVal);
+        } catch (Exception ex) {
+            res = ex;
+        }
+        boolean sawFail = !(res instanceof String);
+        if (sawFail != expectFail) {
+            System.out.println("*** testInterfaceCast: mh0 = "+mh0);
+            System.out.println("  retype using "+(docast ? "explicitCastArguments" : "asType")+" to "+mt+" => "+mh);
+            System.out.println("  call returned "+res);
+            System.out.println("  expected "+(expectFail ? "an exception" : normalRetVal));
+        }
+        if (!expectFail) {
+            assertFalse(res.toString(), sawFail);
+            assertEquals(normalRetVal, res);
+        } else {
+            assertTrue(res.toString(), sawFail);
+        }
+    }
+
+    @Test  // SLOW
     public void testCastFailure() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
         startTest("testCastFailure");
         testCastFailure("cast/argument", 11000);
+        if (CAN_TEST_LIGHTLY)  return;
         testCastFailure("unbox/argument", 11000);
         testCastFailure("cast/return", 11000);
         testCastFailure("unbox/return", 11000);
@@ -2135,12 +2522,13 @@
                 INT_IDENTITY = PRIVATE.findStatic(
                     Surprise.class, "intIdentity",
                         MethodType.methodType(int.class, int.class));
-            } catch (Exception ex) {
+            } catch (NoSuchMethodException | IllegalAccessException ex) {
                 throw new RuntimeException(ex);
             }
         }
     }
 
+    @SuppressWarnings("ConvertToStringSwitch")
     void testCastFailure(String mode, int okCount) throws Throwable {
         countTest(false);
         if (verbosity > 2)  System.out.println("mode="+mode);
@@ -2192,7 +2580,7 @@
             if (verbosity > 2)
                 System.out.println("caught "+ex);
             if (verbosity > 3)
-                ex.printStackTrace();
+                ex.printStackTrace(System.out);
             assertTrue(true);  // all is well
         }
     }
@@ -2235,46 +2623,106 @@
         called("runForRunnable");
     }
     public interface Fooable {
-        Object foo(Fooable x, Object y);
-        // this is for randomArg:
-        public class Impl implements Fooable {
-            public Object foo(Fooable x, Object y) {
-                throw new RuntimeException("do not call");
-            }
-            final String name;
-            public Impl() { name = "Fooable#"+nextArg(); }
-            @Override public String toString() { return name; }
-        }
+        // overloads:
+        Object  foo(Object x, String y);
+        List<?> foo(String x, int y);
+        Object  foo(String x);
     }
-    static Object fooForFooable(Fooable x, Object y) {
-        return called("fooForFooable", x, y);
+    static Object fooForFooable(String x, Object... y) {
+        return called("fooForFooable/"+x, y);
     }
+    @SuppressWarnings("serial")  // not really a public API, just a test case
     public static class MyCheckedException extends Exception {
     }
     public interface WillThrow {
         void willThrow() throws MyCheckedException;
     }
+    /*non-public*/ interface PrivateRunnable {
+        public void run();
+    }
 
     @Test
-    public void testAsInstance() throws Throwable {
+    public void testAsInterfaceInstance() throws Throwable {
         if (CAN_SKIP_WORKING)  return;
+        startTest("asInterfaceInstance");
         Lookup lookup = MethodHandles.lookup();
+        // test typical case:  Runnable.run
         {
+            countTest();
+            if (verbosity >= 2)  System.out.println("Runnable");
             MethodType mt = MethodType.methodType(void.class);
             MethodHandle mh = lookup.findStatic(MethodHandlesTest.class, "runForRunnable", mt);
             Runnable proxy = MethodHandleProxies.asInterfaceInstance(Runnable.class, mh);
             proxy.run();
             assertCalled("runForRunnable");
         }
+        // well known single-name overloaded interface:  Appendable.append
         {
-            MethodType mt = MethodType.methodType(Object.class, Fooable.class, Object.class);
-            MethodHandle mh = lookup.findStatic(MethodHandlesTest.class, "fooForFooable", mt);
-            Fooable proxy = MethodHandleProxies.asInterfaceInstance(Fooable.class, mh);
-            Object[] args = randomArgs(mt.parameterArray());
-            Object result = proxy.foo((Fooable) args[0], args[1]);
-            assertCalled("fooForFooable", args);
-            assertEquals(result, logEntry("fooForFooable", args));
+            countTest();
+            if (verbosity >= 2)  System.out.println("Appendable");
+            ArrayList<List<?>> appendResults = new ArrayList<>();
+            MethodHandle append = lookup.bind(appendResults, "add", MethodType.methodType(boolean.class, Object.class));
+            append = append.asType(MethodType.methodType(void.class, List.class)); // specialize the type
+            MethodHandle asList = lookup.findStatic(Arrays.class, "asList", MethodType.methodType(List.class, Object[].class));
+            MethodHandle mh = MethodHandles.filterReturnValue(asList, append).asVarargsCollector(Object[].class);
+            Appendable proxy = MethodHandleProxies.asInterfaceInstance(Appendable.class, mh);
+            proxy.append("one");
+            proxy.append("two", 3, 4);
+            proxy.append('5');
+            assertEquals(Arrays.asList(Arrays.asList("one"),
+                                       Arrays.asList("two", 3, 4),
+                                       Arrays.asList('5')),
+                         appendResults);
+            if (verbosity >= 3)  System.out.println("appendResults="+appendResults);
+            appendResults.clear();
+            Formatter formatter = new Formatter(proxy);
+            String fmt = "foo str=%s char='%c' num=%d";
+            Object[] fmtArgs = { "str!", 'C', 42 };
+            String expect = String.format(fmt, fmtArgs);
+            formatter.format(fmt, fmtArgs);
+            String actual = "";
+            if (verbosity >= 3)  System.out.println("appendResults="+appendResults);
+            for (List<?> l : appendResults) {
+                Object x = l.get(0);
+                switch (l.size()) {
+                case 1:  actual += x; continue;
+                case 3:  actual += ((String)x).substring((int)(Object)l.get(1), (int)(Object)l.get(2)); continue;
+                }
+                actual += l;
+            }
+            if (verbosity >= 3)  System.out.println("expect="+expect);
+            if (verbosity >= 3)  System.out.println("actual="+actual);
+            assertEquals(expect, actual);
         }
+        // test case of an single name which is overloaded:  Fooable.foo(...)
+        {
+            if (verbosity >= 2)  System.out.println("Fooable");
+            MethodHandle mh = lookup.findStatic(MethodHandlesTest.class, "fooForFooable",
+                                                MethodType.methodType(Object.class, String.class, Object[].class));
+            Fooable proxy = MethodHandleProxies.asInterfaceInstance(Fooable.class, mh);
+            for (Method m : Fooable.class.getDeclaredMethods()) {
+                countTest();
+                assertSame("foo", m.getName());
+                if (verbosity > 3)
+                    System.out.println("calling "+m);
+                MethodHandle invoker = lookup.unreflect(m);
+                MethodType mt = invoker.type();
+                Class<?>[] types = mt.parameterArray();
+                types[0] = int.class;  // placeholder
+                Object[] args = randomArgs(types);
+                args[0] = proxy;
+                if (verbosity > 3)
+                    System.out.println("calling "+m+" on "+Arrays.asList(args));
+                Object result = invoker.invokeWithArguments(args);
+                if (verbosity > 4)
+                    System.out.println("result = "+result);
+                String name = "fooForFooable/"+args[1];
+                Object[] argTail = Arrays.copyOfRange(args, 2, args.length);
+                assertCalled(name, argTail);
+                assertEquals(result, logEntry(name, argTail));
+            }
+        }
+        // test processing of thrown exceptions:
         for (Throwable ex : new Throwable[] { new NullPointerException("ok"),
                                               new InternalError("ok"),
                                               new Throwable("fail"),
@@ -2285,11 +2733,12 @@
             mh = MethodHandles.insertArguments(mh, 0, ex);
             WillThrow proxy = MethodHandleProxies.asInterfaceInstance(WillThrow.class, mh);
             try {
+                countTest();
                 proxy.willThrow();
                 System.out.println("Failed to throw: "+ex);
                 assertTrue(false);
             } catch (Throwable ex1) {
-                if (verbosity > 2) {
+                if (verbosity > 3) {
                     System.out.println("throw "+ex);
                     System.out.println("catch "+(ex == ex1 ? "UNWRAPPED" : ex1));
                 }
@@ -2301,28 +2750,88 @@
                 } else {
                     assertNotSame("must pass undeclared checked exception with wrapping", ex, ex1);
                     if (!(ex1 instanceof UndeclaredThrowableException) || ex1.getCause() != ex) {
-                        ex1.printStackTrace();
+                        ex1.printStackTrace(System.out);
                     }
                     assertSame(ex, ex1.getCause());
                     UndeclaredThrowableException utex = (UndeclaredThrowableException) ex1;
                 }
             }
         }
-        // Test error checking:
-        for (Class<?> nonSAM : new Class[] { Object.class,
+        // Test error checking on bad interfaces:
+        for (Class<?> nonSMI : new Class<?>[] { Object.class,
                                              String.class,
                                              CharSequence.class,
+                                             java.io.Serializable.class,
+                                             PrivateRunnable.class,
                                              Example.class }) {
+            if (verbosity > 2)  System.out.println(nonSMI.getName());
             try {
-                MethodHandleProxies.asInterfaceInstance(nonSAM, varargsArray(0));
-                System.out.println("Failed to throw");
-                assertTrue(false);
+                countTest(false);
+                MethodHandleProxies.asInterfaceInstance(nonSMI, varargsArray(0));
+                assertTrue("Failed to throw on "+nonSMI.getName(), false);
             } catch (IllegalArgumentException ex) {
+                if (verbosity > 2)  System.out.println(nonSMI.getSimpleName()+": "+ex);
+                // Object: java.lang.IllegalArgumentException:
+                //     not a public interface: java.lang.Object
+                // String: java.lang.IllegalArgumentException:
+                //     not a public interface: java.lang.String
+                // CharSequence: java.lang.IllegalArgumentException:
+                //     not a single-method interface: java.lang.CharSequence
+                // Serializable: java.lang.IllegalArgumentException:
+                //     not a single-method interface: java.io.Serializable
+                // PrivateRunnable: java.lang.IllegalArgumentException:
+                //     not a public interface: test.java.lang.invoke.MethodHandlesTest$PrivateRunnable
+                // Example: java.lang.IllegalArgumentException:
+                //     not a public interface: test.java.lang.invoke.MethodHandlesTest$Example
+            }
+        }
+        // Test error checking on interfaces with the wrong method type:
+        for (Class<?> intfc : new Class<?>[] { Runnable.class /*arity 0*/,
+                                            Fooable.class /*arity 1 & 2*/ }) {
+            int badArity = 1;  // known to be incompatible
+            if (verbosity > 2)  System.out.println(intfc.getName());
+            try {
+                countTest(false);
+                MethodHandleProxies.asInterfaceInstance(intfc, varargsArray(badArity));
+                assertTrue("Failed to throw on "+intfc.getName(), false);
+            } catch (WrongMethodTypeException ex) {
+                if (verbosity > 2)  System.out.println(intfc.getSimpleName()+": "+ex);
+                // Runnable: java.lang.invoke.WrongMethodTypeException:
+                //     cannot convert MethodHandle(Object)Object[] to ()void
+                // Fooable: java.lang.invoke.WrongMethodTypeException:
+                //     cannot convert MethodHandle(Object)Object[] to (Object,String)Object
             }
         }
     }
+
+    @Test
+    public void testRunnableProxy() throws Throwable {
+        if (CAN_SKIP_WORKING)  return;
+        startTest("testRunnableProxy");
+        MethodHandles.Lookup lookup = MethodHandles.lookup();
+        MethodHandle run = lookup.findStatic(lookup.lookupClass(), "runForRunnable", MethodType.methodType(void.class));
+        Runnable r = MethodHandleProxies.asInterfaceInstance(Runnable.class, run);
+        testRunnableProxy(r);
+        assertCalled("runForRunnable");
+    }
+    private static void testRunnableProxy(Runnable r) {
+        //7058630: JSR 292 method handle proxy violates contract for Object methods
+        r.run();
+        Object o = r;
+        r = null;
+        boolean eq = (o == o);
+        int     hc = System.identityHashCode(o);
+        String  st = o.getClass().getName() + "@" + Integer.toHexString(hc);
+        Object expect = Arrays.asList(st, eq, hc);
+        if (verbosity >= 2)  System.out.println("expect st/eq/hc = "+expect);
+        Object actual = Arrays.asList(o.toString(), o.equals(o), o.hashCode());
+        if (verbosity >= 2)  System.out.println("actual st/eq/hc = "+actual);
+        assertEquals(expect, actual);
+    }
 }
 // Local abbreviated copy of sun.invoke.util.ValueConversions
+// This guy tests access from outside the same package member, but inside
+// the package itself.
 class ValueConversions {
     private static final Lookup IMPL_LOOKUP = MethodHandles.lookup();
     private static final Object[] NO_ARGS_ARRAY = {};
@@ -2357,7 +2866,7 @@
                                   Object a8, Object a9)
                 { return makeArray(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
     static MethodHandle[] makeArrays() {
-        ArrayList<MethodHandle> arrays = new ArrayList<MethodHandle>();
+        ArrayList<MethodHandle> arrays = new ArrayList<>();
         MethodHandles.Lookup lookup = IMPL_LOOKUP;
         for (;;) {
             int nargs = arrays.size();
@@ -2446,7 +2955,7 @@
                                      Object a8, Object a9)
                 { return makeList(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); }
     static MethodHandle[] makeLists() {
-        ArrayList<MethodHandle> lists = new ArrayList<MethodHandle>();
+        ArrayList<MethodHandle> lists = new ArrayList<>();
         MethodHandles.Lookup lookup = IMPL_LOOKUP;
         for (;;) {
             int nargs = lists.size();
@@ -2469,7 +2978,7 @@
     static {
         try {
             AS_LIST = IMPL_LOOKUP.findStatic(Arrays.class, "asList", MethodType.methodType(List.class, Object[].class));
-        } catch (Exception ex) { throw new RuntimeException(ex); }
+        } catch (NoSuchMethodException | IllegalAccessException ex) { throw new RuntimeException(ex); }
     }
 
     /** Return a method handle that takes the indicated number of Object
diff --git a/jdk/test/java/lang/invoke/MethodTypeTest.java b/jdk/test/java/lang/invoke/MethodTypeTest.java
index aa540b0..d8d460f 100644
--- a/jdk/test/java/lang/invoke/MethodTypeTest.java
+++ b/jdk/test/java/lang/invoke/MethodTypeTest.java
@@ -29,6 +29,7 @@
 
 package test.java.lang.invoke;
 
+import java.io.IOException;
 import java.lang.invoke.MethodType;
 import java.lang.reflect.Method;
 
@@ -378,7 +379,7 @@
     public void testHashCode() {
         System.out.println("hashCode");
         MethodType instance = mt_viS;
-        ArrayList<Class<?>> types = new ArrayList<Class<?>>();
+        ArrayList<Class<?>> types = new ArrayList<>();
         types.add(instance.returnType());
         types.addAll(instance.parameterList());
         int expResult = types.hashCode();
@@ -556,7 +557,7 @@
             Object decode;
             try {
                 decode = readSerial(wire);
-            } catch (Exception ex) {
+            } catch (IOException | ClassNotFoundException ex) {
                 decode = ex;  // oops!
             }
             assertEquals(mt, decode);
diff --git a/jdk/test/java/lang/invoke/PermuteArgsTest.java b/jdk/test/java/lang/invoke/PermuteArgsTest.java
index e02137e..2e31921 100644
--- a/jdk/test/java/lang/invoke/PermuteArgsTest.java
+++ b/jdk/test/java/lang/invoke/PermuteArgsTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,7 @@
 
 /* @test
  * @summary unit tests for method handles which permute their arguments
- * @run junit/othervm -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
+ * @run junit/othervm -XX:+IgnoreUnrecognizedVMOptions -XX:-VerifyDependencies -ea -esa -DPermuteArgsTest.MAX_ARITY=8 test.java.lang.invoke.PermuteArgsTest
  */
 /* Examples of manual runs:
  * java -DPermuteArgsTest.{DRY_RUN=true,MAX_ARITY=253} test.java.lang.invoke.PermuteArgsTest
@@ -45,7 +45,7 @@
 import static java.lang.invoke.MethodType.*;
 
 public class PermuteArgsTest {
-    private static final Class CLASS = PermuteArgsTest.class;
+    private static final Class<?> CLASS = PermuteArgsTest.class;
     private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 8);
     private static final boolean DRY_RUN = Boolean.getBoolean(CLASS.getSimpleName()+".DRY_RUN");
     private static final boolean VERBOSE = Boolean.getBoolean(CLASS.getSimpleName()+".VERBOSE") || DRY_RUN;
@@ -99,12 +99,12 @@
         return Arrays.asList(w, x, y, z);
     }
     static Object listI_etc(int... va) {
-        ArrayList<Object> res = new ArrayList<Object>();
+        ArrayList<Object> res = new ArrayList<>();
         for (int x : va)  res.add(x);
         return res;
     }
     static Object listIJL_etc(int x, long y, Object z, Object... va) {
-        ArrayList<Object> res = new ArrayList<Object>();
+        ArrayList<Object> res = new ArrayList<>();
         res.addAll(Arrays.asList(x, y, z));
         res.addAll(Arrays.asList(va));
         return res;
@@ -168,7 +168,7 @@
                     mh1 = adjustArity(mh, arity);
                 } catch (IllegalArgumentException ex) {
                     System.out.println("*** mh = "+name+" : "+mh+"; arity = "+arity+" => "+ex);
-                    ex.printStackTrace();
+                    ex.printStackTrace(System.out);
                     break;  // cannot get this arity for this type
                 }
                 test("("+arity+")"+name, mh1);
@@ -191,7 +191,11 @@
                 pt = mt1.parameterType(mt1.parameterCount() - posArgs);
             mt1 = mt1.appendParameterTypes(pt);
         }
-        return mh.asType(mt1);
+        try {
+            return mh.asType(mt1);
+        } catch (WrongMethodTypeException | IllegalArgumentException ex) {
+            throw new IllegalArgumentException("cannot convert to type "+mt1+" from "+mh, ex);
+        }
     }
     static MethodHandle findTestMH(String name, int[] perm) throws ReflectiveOperationException {
         int arity = perm.length;
@@ -213,7 +217,7 @@
     }
 
     static void testPermutations(MethodHandle mh) throws Throwable {
-        HashSet<String> done = new HashSet<String>();
+        HashSet<String> done = new HashSet<>();
         MethodType mt = mh.type();
         int[] perm = nullPerm(mt.parameterCount());
         final int MARGIN = (perm.length <= 10 ? 2 : 0);
@@ -326,8 +330,8 @@
             Class<?> pt = ptypes[i];
             Object arg;
             if (pt == Void.class)       arg = null;
-            else if (pt == int.class)   arg = (int)  i + 101;
-            else if (pt == long.class)  arg = (long) i + 10_000_000_001L;
+            else if (pt == int.class)   arg = i + 101;
+            else if (pt == long.class)  arg = i + 10_000_000_001L;
             else                        arg = "#" + (i + 1);
             args[i] = arg;
         }
diff --git a/jdk/test/java/lang/invoke/PrivateInvokeTest.java b/jdk/test/java/lang/invoke/PrivateInvokeTest.java
new file mode 100644
index 0000000..434b8e8
--- /dev/null
+++ b/jdk/test/java/lang/invoke/PrivateInvokeTest.java
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2009, 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
+ * 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.
+ */
+
+/* @test
+ * @summary white-box testing of method handle sub-primitives
+ * @run junit test.java.lang.invoke.PrivateInvokeTest
+ */
+
+package test.java.lang.invoke;
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+import java.lang.reflect.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.junit.*;
+import static org.junit.Assert.*;
+
+public class PrivateInvokeTest {
+    // Utility functions
+    private static final Lookup LOOKUP = lookup();
+    private static final Class<?> THIS_CLASS = PrivateInvokeTest.class;
+    private static final int
+            REF_NONE                    = 0,  // null value
+            REF_getField                = 1,
+            REF_getStatic               = 2,
+            REF_putField                = 3,
+            REF_putStatic               = 4,
+            REF_invokeVirtual           = 5,
+            REF_invokeStatic            = 6,
+            REF_invokeSpecial           = 7,
+            REF_newInvokeSpecial        = 8,
+            REF_invokeInterface         = 9,
+            REF_LIMIT                  = 10,
+            REF_MH_invokeBasic         = REF_NONE;;
+    private static final String[] REF_KIND_NAMES = {
+        "MH::invokeBasic",
+        "REF_getField", "REF_getStatic", "REF_putField", "REF_putStatic",
+        "REF_invokeVirtual", "REF_invokeStatic", "REF_invokeSpecial",
+        "REF_newInvokeSpecial", "REF_invokeInterface"
+    };
+    private int verbose;
+    //{ verbose = 99; }  // for debugging
+    {
+        String vstr = System.getProperty(THIS_CLASS.getSimpleName()+".verbose");
+        if (vstr == null)
+            vstr = System.getProperty(THIS_CLASS.getName()+".verbose");
+        if (vstr == null)
+            vstr = System.getProperty("test.verbose");
+        if (vstr != null)  verbose = Integer.parseInt(vstr);
+    }
+    private static int referenceKind(Method m) {
+        if (Modifier.isStatic(m.getModifiers()))
+            return REF_invokeStatic;
+        else if (m.getDeclaringClass().isInterface())
+            return REF_invokeInterface;
+        else if (Modifier.isFinal(m.getModifiers()) ||
+            Modifier.isFinal(m.getDeclaringClass().getModifiers()))
+            return REF_invokeSpecial;
+        else
+            return REF_invokeVirtual;
+    }
+    private static MethodType basicType(MethodType mtype) {
+        MethodType btype = mtype.erase();
+        if (btype.hasPrimitives()) {
+            for (int i = -1; i < mtype.parameterCount(); i++) {
+                Class<?> type = (i < 0 ? mtype.returnType() : mtype.parameterType(i));
+                if (type == boolean.class ||
+                    type == byte.class ||
+                    type == char.class ||
+                    type == short.class) {
+                    type = int.class;
+                    if (i < 0)
+                        btype = btype.changeReturnType(type);
+                    else
+                        btype = btype.changeParameterType(i, type);
+                }
+            }
+        }
+        return btype;
+    }
+    private static Method getMethod(Class<?> defc, String name, Class<?>... ptypes) {
+        try {
+            return defc.getDeclaredMethod(name, ptypes);
+        } catch (NoSuchMethodException ex) {
+        }
+        try {
+            return defc.getMethod(name, ptypes);
+        } catch (NoSuchMethodException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+    private static MethodHandle unreflect(Method m) {
+        try {
+            MethodHandle mh = LOOKUP.unreflect(m);
+            if (Modifier.isTransient(m.getModifiers()))
+                mh = mh.asFixedArity();  // remove varargs wrapper
+            return mh;
+        } catch (IllegalAccessException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+    private static final Lookup DIRECT_INVOKER_LOOKUP;
+    private static final Class<?> MEMBER_NAME_CLASS;
+    private static final MethodHandle MH_INTERNAL_MEMBER_NAME;
+    private static final MethodHandle MH_DEBUG_STRING;
+    static {
+        try {
+            // This is white box testing.  Use reflection to grab private implementation bits.
+            String magicName = "IMPL_LOOKUP";
+            Field magicLookup = MethodHandles.Lookup.class.getDeclaredField(magicName);
+            // This unit test will fail if a security manager is installed.
+            magicLookup.setAccessible(true);
+            // Forbidden fruit...
+            DIRECT_INVOKER_LOOKUP = (Lookup) magicLookup.get(null);
+            MEMBER_NAME_CLASS = Class.forName("java.lang.invoke.MemberName", false, MethodHandle.class.getClassLoader());
+            MH_INTERNAL_MEMBER_NAME = DIRECT_INVOKER_LOOKUP
+                    .findVirtual(MethodHandle.class, "internalMemberName", methodType(MEMBER_NAME_CLASS))
+                    .asType(methodType(Object.class, MethodHandle.class));
+            MH_DEBUG_STRING = DIRECT_INVOKER_LOOKUP
+                    .findVirtual(MethodHandle.class, "debugString", methodType(String.class));
+        } catch (ReflectiveOperationException ex) {
+            throw new Error(ex);
+        }
+    }
+    private Object internalMemberName(MethodHandle mh) {
+        try {
+            return MH_INTERNAL_MEMBER_NAME.invokeExact(mh);
+        } catch (Throwable ex) {
+            throw new Error(ex);
+        }
+    }
+    private String debugString(MethodHandle mh) {
+        try {
+            return (String) MH_DEBUG_STRING.invokeExact(mh);
+        } catch (Throwable ex) {
+            throw new Error(ex);
+        }
+    }
+    private static MethodHandle directInvoker(int refKind, MethodType mtype) {
+        return directInvoker(REF_KIND_NAMES[refKind], mtype);
+    }
+    private static MethodHandle directInvoker(String name, MethodType mtype) {
+        boolean isStatic;
+        mtype = mtype.erase();
+        if (name.startsWith("MH::")) {
+            isStatic = false;
+            name = strip("MH::", name);
+        } else if (name.startsWith("REF_")) {
+            isStatic = true;
+            name = strip("REF_", name);
+            if (name.startsWith("invoke"))
+                name = "linkTo"+strip("invoke", name);
+            mtype = mtype.appendParameterTypes(MEMBER_NAME_CLASS);
+        } else {
+            throw new AssertionError("name="+name);
+        }
+        //System.out.println("directInvoker = "+name+mtype);
+        try {
+            if (isStatic)
+                return DIRECT_INVOKER_LOOKUP
+                        .findStatic(MethodHandle.class, name, mtype);
+            else
+                return DIRECT_INVOKER_LOOKUP
+                        .findVirtual(MethodHandle.class, name, mtype);
+        } catch (ReflectiveOperationException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+    private Object invokeWithArguments(Method m, Object... args) {
+        Object recv = null;
+        if (!Modifier.isStatic(m.getModifiers())) {
+            recv = args[0];
+            args = pop(1, args);
+        }
+        try {
+            return m.invoke(recv, args);
+        } catch (IllegalAccessException|IllegalArgumentException|InvocationTargetException ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+    private Object invokeWithArguments(MethodHandle mh, Object... args) {
+        try {
+            return mh.invokeWithArguments(args);
+        } catch (Throwable ex) {
+            throw new IllegalArgumentException(ex);
+        }
+    }
+    private int counter;
+    private Object makeArgument(Class<?> type) {
+        final String cname = type.getSimpleName();
+        final int n = ++counter;
+        final int nn = (n << 10) + 13;
+        if (type.isAssignableFrom(String.class)) {
+            return "<"+cname+"#"+nn+">";
+        }
+        if (type == THIS_CLASS)  return this.withCounter(nn);
+        if (type == Integer.class   || type == int.class)     return nn;
+        if (type == Character.class || type == char.class)    return (char)(n % 100+' ');
+        if (type == Byte.class      || type == byte.class)    return (byte)-(n % 100);
+        if (type == Long.class      || type == long.class)    return (long)nn;
+        throw new IllegalArgumentException("don't know how to make argument of type: "+type);
+    }
+    private Object[] makeArguments(Class<?>... ptypes) {
+        Object[] args = new Object[ptypes.length];
+        for (int i = 0; i < args.length; i++)
+            args[i] = makeArgument(ptypes[i]);
+        return args;
+    }
+    private Object[] makeArguments(MethodType mtype) {
+        return makeArguments(mtype.parameterArray());
+    }
+    private Object[] pop(int n, Object[] args) {
+        if (n >= 0)
+            return Arrays.copyOfRange(args, n, args.length);
+        else
+            return Arrays.copyOfRange(args, 0, args.length+n);
+    }
+    private Object[] pushAtFront(Object arg1, Object[] args) {
+        Object[] res = new Object[1+args.length];
+        res[0] = arg1;
+        System.arraycopy(args, 0, res, 1, args.length);
+        return res;
+    }
+    private Object[] pushAtBack(Object[] args, Object argN) {
+        Object[] res = new Object[1+args.length];
+        System.arraycopy(args, 0, res, 0, args.length);
+        res[args.length] = argN;
+        return res;
+    }
+    private static String strip(String prefix, String s) {
+        assert(s.startsWith(prefix));
+        return s.substring(prefix.length());
+    }
+
+    private final int[] refKindTestCounts = new int[REF_KIND_NAMES.length];
+    @After
+    public void printCounts() {
+        ArrayList<String> zeroes = new ArrayList<>();
+        for (int i = 0; i < refKindTestCounts.length; i++) {
+            final int count = refKindTestCounts[i];
+            final String name = REF_KIND_NAMES[i];
+            if (count == 0) {
+                if (name != null)  zeroes.add(name);
+                continue;
+            }
+            if (verbose >= 0)
+                System.out.println("test count for "+name+" : "+count);
+            else if (name != null)
+                zeroes.add(name);
+        }
+        if (verbose >= 0)
+            System.out.println("test counts zero for "+zeroes);
+    }
+
+    // Test subjects
+    public static String makeString(Object x) { return "makeString("+x+")"; }
+    public static String dupString(String x) { return "("+x+"+"+x+")"; }
+    public static String intString(int x) { return "intString("+x+")"; }
+    public static String byteString(byte x) { return "byteString("+x+")"; }
+    public static String longString(String x, long y, String z) { return "longString("+x+y+z+")"; }
+
+    public final String toString() {
+        return "<"+getClass().getSimpleName()+"#"+counter+">";
+    }
+    public final String hello() { return "hello from "+this; }
+    private PrivateInvokeTest withCounter(int counter) {
+        PrivateInvokeTest res = new PrivateInvokeTest();
+        res.counter = counter;
+        return res;
+    }
+
+    public static void main(String... av) throws Throwable {
+        new PrivateInvokeTest().run();
+    }
+    public void run() throws Throwable {
+        testFirst();
+        testInvokeDirect();
+    }
+
+    @Test
+    public void testFirst() throws Throwable {
+        if (true)  return;  // nothing here
+        try {
+            System.out.println("start of testFirst");
+        } finally {
+            System.out.println("end of testFirst");
+        }
+    }
+
+    @Test
+    public void testInvokeDirect() {
+        testInvokeDirect(getMethod(THIS_CLASS, "hello"));
+        testInvokeDirect(getMethod(Object.class, "toString"));
+        testInvokeDirect(getMethod(Comparable.class, "compareTo", Object.class));
+        testInvokeDirect(getMethod(THIS_CLASS, "makeString", Object.class));
+        testInvokeDirect(getMethod(THIS_CLASS, "dupString", String.class));
+        testInvokeDirect(getMethod(THIS_CLASS, "intString", int.class));
+        testInvokeDirect(getMethod(THIS_CLASS, "byteString", byte.class));
+        testInvokeDirect(getMethod(THIS_CLASS, "longString", String.class, long.class, String.class));
+    }
+
+    void testInvokeDirect(Method m) {
+        final int refKind = referenceKind(m);
+        testInvokeDirect(m, refKind);
+        testInvokeDirect(m, REF_MH_invokeBasic);
+    }
+    void testInvokeDirect(Method m, int refKind) {
+        if (verbose >= 1)
+            System.out.println("testInvoke m="+m+" : "+REF_KIND_NAMES[refKind]);
+        final MethodHandle mh = unreflect(m);
+        Object[] args = makeArguments(mh.type());
+        Object res1 = invokeWithArguments(m, args);
+        // res1 comes from java.lang.reflect.Method::invoke
+        if (verbose >= 1)
+            System.out.println("m"+Arrays.asList(args)+" => "+res1);
+        // res2 comes from java.lang.invoke.MethodHandle::invoke
+        Object res2 = invokeWithArguments(mh, args);
+        assertEquals(res1, res2);
+        MethodType mtype = mh.type();
+        testInvokeVia("DMH invoker", refKind, directInvoker(refKind, mtype), mh, res1, args);
+        MethodType etype = mtype.erase();
+        if (etype != mtype) {
+            // Try a detuned invoker.
+            testInvokeVia("erased DMH invoker", refKind, directInvoker(refKind, etype), mh, res1, args);
+        }
+        MethodType btype = basicType(mtype);
+        if (btype != mtype && btype != etype) {
+            // Try a detuned invoker.
+            testInvokeVia("basic DMH invoker", refKind, directInvoker(refKind, btype), mh, res1, args);
+        }
+        if (false) {
+            // this can crash the JVM
+            testInvokeVia("generic DMH invoker", refKind, directInvoker(refKind, mtype.generic()), mh, res1, args);
+        }
+        refKindTestCounts[refKind] += 1;
+    }
+
+    void testInvokeVia(String kind, int refKind, MethodHandle invoker, MethodHandle mh, Object res1, Object... args) {
+        Object[] args1;
+        if (refKind == REF_MH_invokeBasic)
+            args1 = pushAtFront(mh, args);
+        else
+            args1 = pushAtBack(args, internalMemberName(mh));
+        if (verbose >= 2) {
+            System.out.println(kind+" invoker="+invoker+" mh="+debugString(mh)+" args="+Arrays.asList(args1));
+        }
+        Object res3 = invokeWithArguments(invoker, args1);
+        assertEquals(res1, res3);
+    }
+}
diff --git a/jdk/test/java/lang/invoke/RicochetTest.java b/jdk/test/java/lang/invoke/RicochetTest.java
index 1ac7290..342cffb 100644
--- a/jdk/test/java/lang/invoke/RicochetTest.java
+++ b/jdk/test/java/lang/invoke/RicochetTest.java
@@ -40,7 +40,6 @@
 import static java.lang.invoke.MethodType.*;
 import static java.lang.invoke.MethodHandles.*;
 import static org.junit.Assert.*;
-import static org.junit.Assume.*;
 
 
 /**
@@ -48,7 +47,7 @@
  * @author jrose
  */
 public class RicochetTest {
-    private static final Class CLASS = RicochetTest.class;
+    private static final Class<?> CLASS = RicochetTest.class;
     private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 40);
 
     public static void main(String... av) throws Throwable {
@@ -82,6 +81,7 @@
         testLongSpreads();
         testIntCollects();
         testReturns();
+        testRecursion();
     }
 
     @Test
@@ -147,7 +147,7 @@
         for (int nargs = 0; nargs <= MAX; nargs++) {
             if (nargs > 30 && nargs < MAX-20)  nargs += 10;
             int[] args = new int[nargs];
-            for (int j = 0; j < args.length; j++)  args[j] = (int)(j + 11);
+            for (int j = 0; j < args.length; j++)  args[j] = j + 11;
             //System.out.println("testIntSpreads "+Arrays.toString(args));
             int[] args1 = (int[]) id.invokeExact(args);
             assertArrayEquals(args, args1);
@@ -256,7 +256,7 @@
                     //System.out.println("  expect="+expect);
 
                     // now use the combined MH, and test the output:
-                    MethodHandle mh = collectArguments(lister, pos, INT_COLLECTORS[collects]);
+                    MethodHandle mh = collectArguments(lister, pos, int[].class, INT_COLLECTORS[collects]);
                     if (mh == null)  continue;  // no infix collection, yet
                     assert(mh.type().parameterCount() == inputs);
                     Object observe = mh.asSpreader(int[].class, args.length).invokeExact(args);
@@ -266,13 +266,53 @@
         }
     }
 
-    private static MethodHandle collectArguments(MethodHandle lister, int pos, MethodHandle collector) {
+    @Test
+    public void testByteCollects() throws Throwable {
+        if (!startTest("testByteCollects"))  return;
+        for (MethodHandle lister : BYTE_LISTERS) {
+            int outputs = lister.type().parameterCount();
+            for (int collects = 0; collects <= Math.min(outputs, BYTE_COLLECTORS.length-1); collects++) {
+                int inputs = outputs - 1 + collects;
+                if (inputs < 0)  continue;
+                for (int pos = 0; pos + collects <= inputs; pos++) {
+                    MethodHandle collector = BYTE_COLLECTORS[collects];
+                    byte[] args = new byte[inputs];
+                    int ap = 0, arg = 31;
+                    for (int i = 0; i < pos; i++)
+                        args[ap++] = (byte)(arg++ + 0);
+                    for (int i = 0; i < collects; i++)
+                        args[ap++] = (byte)(arg++ + 10);
+                    while (ap < args.length)
+                        args[ap++] = (byte)(arg++ + 20);
+                    // calculate piecemeal:
+                    //System.out.println("testIntCollects "+Arrays.asList(lister, pos, collector)+" on "+Arrays.toString(args));
+                    byte[] collargs = Arrays.copyOfRange(args, pos, pos+collects);
+                    byte coll = (byte) collector.asSpreader(byte[].class, collargs.length).invokeExact(collargs);
+                    byte[] listargs = Arrays.copyOfRange(args, 0, outputs);
+                    System.arraycopy(args, pos+collects, listargs, pos+1, outputs - (pos+1));
+                    listargs[pos] = coll;
+                    //System.out.println("  coll="+coll+" listargs="+Arrays.toString(listargs));
+                    Object expect = lister.asSpreader(byte[].class, listargs.length).invokeExact(listargs);
+                    //System.out.println("  expect="+expect);
+
+                    // now use the combined MH, and test the output:
+                    MethodHandle mh = collectArguments(lister, pos, byte[].class, BYTE_COLLECTORS[collects]);
+                    if (mh == null)  continue;  // no infix collection, yet
+                    assert(mh.type().parameterCount() == inputs);
+                    Object observe = mh.asSpreader(byte[].class, args.length).invokeExact(args);
+                    assertEquals(expect, observe);
+                }
+            }
+        }
+    }
+
+    private static MethodHandle collectArguments(MethodHandle lister, int pos, Class<?> array, MethodHandle collector) {
         int collects = collector.type().parameterCount();
         int outputs = lister.type().parameterCount();
         if (pos == outputs - 1)
             return MethodHandles.filterArguments(lister, pos,
-                        collector.asSpreader(int[].class, collects))
-                            .asCollector(int[].class, collects);
+                        collector.asSpreader(array, collects))
+                            .asCollector(array, collects);
         //return MethodHandles.collectArguments(lister, pos, collector); //no such animal
         return null;
     }
@@ -371,6 +411,62 @@
         //System.out.println("faultCount="+faultCount);
     }
 
+    @Test
+    public void testRecursion() throws Throwable {
+        if (!startTest("testRecursion"))  return;
+        final int LIMIT = 10;
+        for (int i = 0; i < LIMIT; i++) {
+            RFCB rfcb = new RFCB(i);
+            Object x = "x", y = "y";
+            Object result = rfcb.recursiveFunction(x, y);
+            verbose(1, result);
+        }
+    }
+    /** Recursive Function Control Block */
+    private static class RFCB {
+        java.util.Random random;
+        final MethodHandle[] fns;
+        int depth;
+        @SuppressWarnings("LeakingThisInConstructor")
+        RFCB(int seed) throws Throwable {
+            this.random = new java.util.Random(seed);
+            this.fns = new MethodHandle[Math.max(29, (1 << MAX_DEPTH-2)/3)];
+            java.util.Arrays.fill(fns, lookup().bind(this, "recursiveFunction", genericMethodType(2)));
+            for (int i = 5; i < fns.length; i++) {
+                switch (i % 4) {
+                case 0: fns[i] = filterArguments(fns[i - 5], 0, insertArguments(fns[i - 4], 1, ".")); break;
+                case 1: fns[i] = filterArguments(fns[i - 5], 1, insertArguments(fns[i - 3], 1, ".")); break;
+                case 2: fns[i] = filterReturnValue(fns[i - 5], insertArguments(fns[i - 2], 1, ".")); break;
+                }
+            }
+        }
+        Object recursiveFunction(Object x, Object y) throws Throwable {
+            depth++;
+            try {
+                final int ACTION_COUNT = 11;
+                switch (random.nextInt(ACTION_COUNT)) {
+                case 1:
+                    Throwable ex = new RuntimeException();
+                    ex.fillInStackTrace();
+                    if (VERBOSITY >= 2) ex.printStackTrace(System.out);
+                    x = "ST; " + x;
+                    break;
+                case 2:
+                    System.gc();
+                    x = "GC; " + x;
+                    break;
+                }
+                boolean isLeaf = (depth >= MAX_DEPTH);
+                if (isLeaf) {
+                    return Arrays.asList(x, y).toString();
+                }
+                return fns[random.nextInt(fns.length)].invokeExact(x, y);
+            } finally {
+                depth--;
+            }
+        }
+    }
+
     private static MethodHandle sequence(MethodHandle mh1, MethodHandle... mhs) {
         MethodHandle res = mh1;
         for (MethodHandle mh2 : mhs)
@@ -411,7 +507,7 @@
             return mh.invokeWithArguments(args);
         } catch (Throwable ex) {
             System.out.println("threw: "+mh+Arrays.asList(args));
-            ex.printStackTrace();
+            ex.printStackTrace(System.out);
             return ex;
         }
     }
@@ -459,8 +555,8 @@
     private static long opJ(long x) { return (long) opI((int)x); }
     private static Object opL2(Object x, Object y) { return (Object) opI2((int)x, (int)y); }
     private static Object opL(Object x) { return (Object) opI((int)x); }
-    private static int opL2_I(Object x, Object y) { return (int) opI2((int)x, (int)y); }
-    private static int opL_I(Object x) { return (int) opI((int)x); }
+    private static int opL2_I(Object x, Object y) { return opI2((int)x, (int)y); }
+    private static int opL_I(Object x) { return opI((int)x); }
     private static long opL_J(Object x) { return (long) opI((int)x); }
     private static final MethodHandle opI, opI2, opI3, opI4, opI_L, opJ, opJ2, opJ3, opL2, opL, opL2_I, opL_I, opL_J;
     static {
@@ -481,6 +577,9 @@
     private static final MethodHandle[] INT_COLLECTORS = {
         constant(int.class, 42), opI, opI2, opI3, opI4
     };
+    private static final MethodHandle[] BYTE_COLLECTORS = {
+        constant(byte.class, (byte)42), i2b(opI), i2b(opI2), i2b(opI3), i2b(opI4)
+    };
     private static final MethodHandle[] LONG_COLLECTORS = {
         constant(long.class, 42), opJ, opJ2, opJ3
     };
@@ -503,21 +602,36 @@
                                                              Collections.nCopies(8, int.class));
     private static final MethodHandle list8longs = findStatic("list8longs", Object.class,
                                                               Collections.nCopies(8, long.class));
-    private static final MethodHandle[] INT_LISTERS, LONG_LISTERS;
+    private static final MethodHandle[] INT_LISTERS, LONG_LISTERS, BYTE_LISTERS;
     static {
         int listerCount = list8ints.type().parameterCount() + 1;
         INT_LISTERS  = new MethodHandle[listerCount];
         LONG_LISTERS = new MethodHandle[listerCount];
+        BYTE_LISTERS = new MethodHandle[listerCount];
         MethodHandle lister = list8ints;
         MethodHandle llister = list8longs;
         for (int i = listerCount - 1; ; i--) {
             INT_LISTERS[i] = lister;
             LONG_LISTERS[i] = llister;
+            BYTE_LISTERS[i] = i2b(lister);
             if (i == 0)  break;
-            lister  = insertArguments(lister,  i-1, (int)0);
-            llister = insertArguments(llister, i-1, (long)0);
+            lister  = insertArguments(lister,  i-1, 0);
+            llister = insertArguments(llister, i-1, 0L);
         }
     }
+    private static MethodHandle i2b(MethodHandle mh) {
+        return MethodHandles.explicitCastArguments(mh, subst(mh.type(), int.class, byte.class));
+    }
+    private static MethodType subst(MethodType mt, Class<?> from, Class<?> to) {
+        for (int i = 0; i < mt.parameterCount(); i++) {
+            if (mt.parameterType(i) == from)
+                mt = mt.changeParameterType(i, to);
+        }
+        if (mt.returnType() == from)
+            mt = mt.changeReturnType(to);
+        return mt;
+    }
+
 
     private static Object  convI_L(int     x) { stress(); return (Object)  x; }
     private static int     convL_I(Object  x) { stress(); return (int)     x; }
@@ -536,6 +650,7 @@
     }
 
     // stress modes:
+    private static final int MAX_DEPTH = getProperty("MAX_DEPTH", 5);
     private static final int REPEAT = getProperty("REPEAT", 0);
     private static final int STRESS = getProperty("STRESS", 0);
     private static /*v*/ int STRESS_COUNT;
diff --git a/jdk/test/java/lang/invoke/ThrowExceptionsTest.java b/jdk/test/java/lang/invoke/ThrowExceptionsTest.java
new file mode 100644
index 0000000..b22d370
--- /dev/null
+++ b/jdk/test/java/lang/invoke/ThrowExceptionsTest.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+/* @test
+ * @summary unit tests for method handles which permute their arguments
+ * @run junit test.java.lang.invoke.ThrowExceptionsTest
+ */
+
+package test.java.lang.invoke;
+
+import org.junit.*;
+
+import java.util.*;
+import java.lang.reflect.*;
+
+import java.lang.invoke.*;
+import static java.lang.invoke.MethodHandles.*;
+import static java.lang.invoke.MethodType.*;
+
+public class ThrowExceptionsTest {
+    private static final Class<?> CLASS = ThrowExceptionsTest.class;
+    private static final Lookup LOOKUP = lookup();
+
+    public static void main(String argv[]) throws Throwable {
+        new ThrowExceptionsTest().testAll((argv.length == 0 ? null : Arrays.asList(argv).toString()));
+    }
+
+    @Test
+    public void testWMT() throws Throwable {
+        // mostly call testWMTCallee, but sometimes call its void-returning variant
+        MethodHandle mh = testWMTCallee();
+        MethodHandle mh1 = mh.asType(mh.type().changeReturnType(void.class));
+        assert(mh1 != mh);
+        testWMT(mh, mh1, 1000);
+    }
+
+    @Test
+    public void testBoundWMT() throws Throwable {
+        // mostly call exactInvoker.bindTo(testWMTCallee), but sometimes call its void-returning variant
+        MethodHandle callee = testWMTCallee();
+        MethodHandle callee1 = callee.asType(callee.type().changeReturnType(void.class));
+        MethodHandle invoker = exactInvoker(callee.type());
+        MethodHandle mh  = invoker.bindTo(callee);
+        MethodHandle mh1 = invoker.bindTo(callee1);
+        testWMT(mh, mh1, 1000);
+    }
+
+    @Test
+    public void testFoldWMT() throws Throwable {
+        // mostly call exactInvoker.fold(constant(testWMTCallee)), but sometimes call its void-returning variant
+        MethodHandle callee = testWMTCallee();
+        MethodHandle callee1 = callee.asType(callee.type().changeReturnType(void.class));
+        MethodHandle invoker = exactInvoker(callee.type());
+        MethodHandle mh  = foldArguments(invoker, constant(MethodHandle.class, callee));
+        MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));
+        testWMT(mh, mh1, 1000);
+    }
+
+    @Test
+    public void testFoldCCE() throws Throwable {
+        MethodHandle callee = testWMTCallee();
+        MethodHandle callee1 = callee.asType(callee.type().changeParameterType(1, Number.class)).asType(callee.type());
+        MethodHandle invoker = exactInvoker(callee.type());
+        MethodHandle mh  = foldArguments(invoker, constant(MethodHandle.class, callee));
+        MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));
+        testWMT(mh, mh1, 1000);
+    }
+
+    @Test
+    public void testStackOverflow() throws Throwable {
+        MethodHandle callee = testWMTCallee();
+        MethodHandle callee1 = makeStackOverflow().asType(callee.type());
+        MethodHandle invoker = exactInvoker(callee.type());
+        MethodHandle mh  = foldArguments(invoker, constant(MethodHandle.class, callee));
+        MethodHandle mh1 = foldArguments(invoker, constant(MethodHandle.class, callee1));
+        for (int i = 0; i < REPEAT; i++) {
+            try {
+                testWMT(mh, mh1, 1000);
+            } catch (StackOverflowError ex) {
+                // OK, try again
+            }
+        }
+    }
+
+    private static MethodHandle makeStackOverflow() {
+        MethodType cellType = methodType(void.class);
+        MethodHandle[] cell = { null };  // recursion point
+        MethodHandle getCell = insertArguments(arrayElementGetter(cell.getClass()), 0, cell, 0);
+        MethodHandle invokeCell = foldArguments(exactInvoker(cellType), getCell);
+        assert(invokeCell.type() == cellType);
+        cell[0] = invokeCell;
+        // make it conformable to any type:
+        invokeCell = dropArguments(invokeCell, 0, Object[].class).asVarargsCollector(Object[].class);
+        return invokeCell;
+    }
+
+    static int testCases;
+
+    private void testAll(String match) throws Throwable {
+        testCases = 0;
+        Lookup lookup = lookup();
+        for (Method m : CLASS.getDeclaredMethods()) {
+            String name = m.getName();
+            if (name.startsWith("test") &&
+                (match == null || match.contains(name.substring("test".length()))) &&
+                m.getParameterTypes().length == 0 &&
+                Modifier.isPublic(m.getModifiers()) &&
+                !Modifier.isStatic(m.getModifiers())) {
+                System.out.println("["+name+"]");
+                int tc = testCases;
+                try {
+                    m.invoke(this);
+                } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
+                    System.out.println("*** "+ex);
+                    ex.printStackTrace(System.out);
+                }
+                if (testCases == tc)  testCases++;
+            }
+        }
+        if (testCases == 0)  throw new RuntimeException("no test cases found");
+        System.out.println("ran a total of "+testCases+" test cases");
+    }
+
+    private static MethodHandle findStatic(String name) {
+        return findMethod(name, true);
+    }
+    private static MethodHandle findVirtual(String name) {
+        return findMethod(name, false);
+    }
+    private static MethodHandle findMethod(String name, boolean isStatic) {
+        MethodHandle mh = null;
+        for (Method m : CLASS.getDeclaredMethods()) {
+            if (m.getName().equals(name) &&
+                Modifier.isStatic(m.getModifiers()) == isStatic) {
+                if (mh != null)
+                    throw new RuntimeException("duplicate methods: "+name);
+                try {
+                    mh = LOOKUP.unreflect(m);
+                } catch (ReflectiveOperationException ex) {
+                    throw new RuntimeException(ex);
+                }
+            }
+        }
+        if (mh == null)
+            throw new RuntimeException("no method: "+name);
+        return mh;
+    }
+
+    int testWMTCallee;
+    private int testWMTCallee(String x) {
+        return testWMTCallee++;
+    }
+    private static MethodHandle testWMTCallee() {
+        MethodHandle callee = findVirtual("testWMTCallee");
+        // FIXME: should not have to retype callee
+        callee = callee.asType(callee.type().changeParameterType(0, Object.class));
+        return callee;
+    }
+
+    private Exception testWMT(MethodHandle[] mhs, int reps) throws Throwable {
+        testCases += 1;
+        testWMTCallee = 0;
+        int catches = 0;
+        Exception savedEx = null;
+        for (int i = 0; i < reps; i++) {
+            MethodHandle mh = mhs[i % mhs.length];
+            int n;
+            try {
+                // FIXME: should not have to retype this
+                n = (int) mh.invokeExact((Object)this, "x");
+                assertEquals(n, i - catches);
+                // Using the exact type for this causes endless deopt due to
+                // 'non_cached_result' in SystemDictionary::find_method_handle_invoke.
+                // The problem is that the compiler thread needs to access a cached
+                // invoke method, but invoke methods are not cached if one of the
+                // component types is not on the BCP.
+            } catch (Exception ex) {
+                savedEx = ex;
+                catches++;
+            }
+        }
+        //VERBOSE: System.out.println("reps="+reps+" catches="+catches);
+        return savedEx;
+    }
+
+    private static final int REPEAT = Integer.getInteger(CLASS.getSimpleName()+".REPEAT", 10);
+
+    private Exception testWMT(MethodHandle mh, MethodHandle mh1, int reps) throws Throwable {
+        //VERBOSE: System.out.println("mh="+mh+" mh1="+mh1);
+        MethodHandle[] mhs = new MethodHandle[100];
+        Arrays.fill(mhs, mh);
+        int patch = mhs.length-1;
+        Exception savedEx = null;
+        for (int i = 0; i < REPEAT; i++) {
+            mhs[patch] = mh;
+            testWMT(mhs, 10000);
+            mhs[patch] = mh1;
+            savedEx = testWMT(mhs, reps);
+        }
+        return savedEx;
+    }
+
+    private static void assertEquals(Object x, Object y) {
+        if (x == y || x != null && x.equals(y))  return;
+        throw new RuntimeException(x+" != "+y);
+    }
+}
diff --git a/jdk/test/java/lang/invoke/remote/RemoteExample.java b/jdk/test/java/lang/invoke/remote/RemoteExample.java
new file mode 100644
index 0000000..0829a65
--- /dev/null
+++ b/jdk/test/java/lang/invoke/remote/RemoteExample.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2009-2010 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+package test.java.lang.invoke.remote;
+
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import test.java.lang.invoke.MethodHandlesTest;
+
+/**
+ * Out-of-package access into protected members of test.java.lang.invoke.remote.MethodHandle.PubExample.
+ */
+public class RemoteExample extends MethodHandlesTest.PubExample {
+    public RemoteExample() { super("RemoteExample"); }
+    public static Lookup lookup() { return MethodHandles.lookup(); }
+    public final     void fin_v0() { MethodHandlesTest.called("Rem/fin_v0", this); }
+    protected        void pro_v0() { MethodHandlesTest.called("Rem/pro_v0", this); }
+    protected static void pro_s0() { MethodHandlesTest.called("Rem/pro_s0"); }
+}
diff --git a/jdk/test/java/net/CookieHandler/B6791927.java b/jdk/test/java/net/CookieHandler/B6791927.java
index e4ee023..13d7ea3 100644
--- a/jdk/test/java/net/CookieHandler/B6791927.java
+++ b/jdk/test/java/net/CookieHandler/B6791927.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2009, 2012, 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
@@ -35,7 +35,7 @@
     public static final void main( String[] aaParamters ) throws Exception{
         // Forces a non US locale
         Locale.setDefault(Locale.FRANCE);
-        List<HttpCookie> cookies = HttpCookie.parse("set-cookie: CUSTOMER=WILE_E_COYOTE; expires=Wednesday, 09-Nov-2019 23:12:40 GMT");
+        List<HttpCookie> cookies = HttpCookie.parse("set-cookie: CUSTOMER=WILE_E_COYOTE; expires=Sat, 09-Nov-2019 23:12:40 GMT");
         if (cookies == null || cookies.isEmpty()) {
             throw new RuntimeException("No cookie found");
         }
diff --git a/jdk/test/java/net/CookieHandler/CookieManagerTest.java b/jdk/test/java/net/CookieHandler/CookieManagerTest.java
index ebad359..c60a816 100644
--- a/jdk/test/java/net/CookieHandler/CookieManagerTest.java
+++ b/jdk/test/java/net/CookieHandler/CookieManagerTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -126,7 +126,7 @@
         testPolicies[count] = CookiePolicy.ACCEPT_ORIGINAL_SERVER;
         testCases[count++] = new CookieTestCase[]{
                 new CookieTestCase("Set-Cookie",
-                "CUSTOMER=WILE:BOB; path=/; expires=Wednesday, 09-Nov-2030 23:12:40 GMT;" + "domain=." + localHostAddr,
+                "CUSTOMER=WILE:BOB; path=/; expires=Sat, 09-Nov-2030 23:12:40 GMT;" + "domain=." + localHostAddr,
                 "CUSTOMER=WILE:BOB",
                 "/"
                 ),
diff --git a/jdk/test/java/net/CookieHandler/NullUriCookieTest.java b/jdk/test/java/net/CookieHandler/NullUriCookieTest.java
new file mode 100644
index 0000000..60d0550
--- /dev/null
+++ b/jdk/test/java/net/CookieHandler/NullUriCookieTest.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 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
+ * 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 6953455
+ * @summary CookieStore.add() cannot handle null URI parameter
+ */
+
+import java.net.CookieManager;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.List;
+
+public class NullUriCookieTest {
+    static boolean fail = false;
+
+    public static void main(String[] args) throws Exception {
+        checkCookieNullUri();
+    }
+
+    static void checkCookieNullUri() throws Exception {
+        //get a cookie store implementation and add a cookie to the store with null URI
+        CookieStore cookieStore = (new CookieManager()).getCookieStore();
+        HttpCookie cookie = new HttpCookie("MY_COOKIE", "MY_COOKIE_VALUE");
+        cookie.setDomain("foo.com");
+        cookieStore.add(null, cookie);
+
+        //Retrieve added cookie
+        URI uri = new URI("http://foo.com");
+        List<HttpCookie> addedCookieList = cookieStore.get(uri);
+
+        //Verify CookieStore behaves well
+        if (addedCookieList.size() != 1) {
+           fail = true;
+        }
+        checkFail("Abnormal size of cookie jar");
+
+        for (HttpCookie chip : addedCookieList) {
+            if (!chip.equals(cookie)) {
+                 fail = true;
+            }
+        }
+        checkFail("Cookie not retrieved from Cookie Jar");
+        boolean ret = cookieStore.remove(null,cookie);
+        if (!ret) {
+            fail = true;
+        }
+        checkFail("Abnormal removal behaviour from Cookie Jar");
+    }
+
+    static void checkFail(String exp) {
+        if (fail) {
+            throw new RuntimeException(exp);
+        }
+    }
+}
+
diff --git a/jdk/test/java/net/HttpCookie/ExpiredCookieTest.java b/jdk/test/java/net/HttpCookie/ExpiredCookieTest.java
new file mode 100644
index 0000000..b43065f
--- /dev/null
+++ b/jdk/test/java/net/HttpCookie/ExpiredCookieTest.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2012, 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 8000525
+ */
+
+import java.net.*;
+import java.util.*;
+import java.io.*;
+import java.text.*;
+
+public class ExpiredCookieTest {
+    // lifted from HttpCookie.java
+    private final static String[] COOKIE_DATE_FORMATS = {
+        "EEE',' dd-MMM-yy HH:mm:ss 'GMT'",
+        "EEE',' dd MMM yy HH:mm:ss 'GMT'",
+        "EEE MMM dd yy HH:mm:ss 'GMT'Z",
+        "EEE',' dd-MMM-yyyy HH:mm:ss 'GMT'",
+        "EEE',' dd MMM yyyy HH:mm:ss 'GMT'",
+        "EEE MMM dd yyyy HH:mm:ss 'GMT'Z"
+    };
+    static final TimeZone GMT = TimeZone.getTimeZone("GMT");
+
+    public static void main(String[] args) throws Exception {
+        Calendar cal = Calendar.getInstance(GMT);
+
+        for (int i = 0; i < COOKIE_DATE_FORMATS.length; i++) {
+            SimpleDateFormat df = new SimpleDateFormat(COOKIE_DATE_FORMATS[i],
+                                                     Locale.US);
+            cal.set(1970, 0, 1, 0, 0, 0);
+            df.setTimeZone(GMT);
+            df.setLenient(false);
+            df.set2DigitYearStart(cal.getTime());
+            CookieManager cm = new CookieManager(
+                null, CookiePolicy.ACCEPT_ALL);
+            CookieHandler.setDefault(cm);
+            Map<String,List<String>> header = new HashMap<>();
+            List<String> values = new ArrayList<>();
+
+            cal.set(1970, 6, 9, 10, 10, 1);
+            StringBuilder datestring =
+                new StringBuilder(df.format(cal.getTime()));
+            values.add(
+                "TEST1=TEST1; Path=/; Expires=" + datestring.toString());
+
+            cal.set(1969, 6, 9, 10, 10, 2);
+            datestring = new StringBuilder(df.format(cal.getTime()));
+            values.add(
+                "TEST2=TEST2; Path=/; Expires=" + datestring.toString());
+
+            cal.set(2070, 6, 9, 10, 10, 3);
+            datestring = new StringBuilder(df.format(cal.getTime()));
+            values.add(
+                "TEST3=TEST3; Path=/; Expires=" + datestring.toString());
+
+            cal.set(2069, 6, 9, 10, 10, 4);
+            datestring = new StringBuilder(df.format(cal.getTime()));
+            values.add(
+                "TEST4=TEST4; Path=/; Expires=" + datestring.toString());
+
+            header.put("Set-Cookie", values);
+            cm.put(new URI("http://127.0.0.1/"), header);
+
+            CookieStore cookieJar =  cm.getCookieStore();
+            List <HttpCookie> cookies = cookieJar.getCookies();
+            if (COOKIE_DATE_FORMATS[i].contains("yyyy")) {
+                if (cookies.size() != 2)
+                    throw new RuntimeException(
+                        "Incorrectly parsing a bad date");
+            } else if (cookies.size() != 1) {
+                throw new RuntimeException(
+                    "Incorrectly parsing a bad date");
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/net/Inet4Address/PingThis.java b/jdk/test/java/net/Inet4Address/PingThis.java
new file mode 100644
index 0000000..515a873
--- /dev/null
+++ b/jdk/test/java/net/Inet4Address/PingThis.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test
+ * @bug 7163874
+ * @summary InetAddress.isReachable is returning false
+ *          for InetAdress 0.0.0.0 and ::0
+ * @run main PingThis
+ * @run main/othervm -Djava.net.preferIPv4Stack=true PingThis
+ */
+
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+public class PingThis {
+    private static boolean hasIPv6() throws Exception {
+        List<NetworkInterface> nics = Collections.list(NetworkInterface
+                .getNetworkInterfaces());
+        for (NetworkInterface nic : nics) {
+            List<InetAddress> addrs = Collections.list(nic.getInetAddresses());
+            for (InetAddress addr : addrs) {
+                if (addr instanceof Inet6Address)
+                    return true;
+            }
+        }
+
+        return false;
+    }
+
+    public static void main(String args[]) throws Exception {
+        if (System.getProperty("os.name").startsWith("Windows")) {
+            return;
+        }
+
+        boolean preferIPv4Stack = "true".equals(System
+                .getProperty("java.net.preferIPv4Stack"));
+        List<String> addrs = new ArrayList<String>();
+        InetAddress inetAddress = null;
+
+        addrs.add("0.0.0.0");
+        if (!preferIPv4Stack) {
+            if (hasIPv6()) {
+                addrs.add("::0");
+            }
+        }
+
+        for (String addr : addrs) {
+            inetAddress = InetAddress.getByName(addr);
+            System.out.println("The target ip is "
+                    + inetAddress.getHostAddress());
+            boolean isReachable = inetAddress.isReachable(3000);
+            System.out.println("the target is reachable: " + isReachable);
+            if (isReachable) {
+                System.out.println("Test passed ");
+            } else {
+                System.out.println("Test failed ");
+                throw new Exception("address " + inetAddress.getHostAddress()
+                        + " can not be reachable!");
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/net/ProxySelector/MultiThreadedSystemProxies.java b/jdk/test/java/net/ProxySelector/MultiThreadedSystemProxies.java
new file mode 100644
index 0000000..63a385c
--- /dev/null
+++ b/jdk/test/java/net/ProxySelector/MultiThreadedSystemProxies.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2012 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 7188755
+ * @run main/othervm MultiThreadedSystemProxies
+ * @summary Crash due to missing synchronization on gconf_client in
+ *          DefaultProxySelector.c
+ */
+import java.net.ProxySelector;
+import java.net.URI;
+
+/* Racey test, not guaranteed to fail, but if it does we have a problem. */
+
+public class MultiThreadedSystemProxies {
+    static final int NUM_THREADS = 100;
+
+    public static void main(String[] args) throws Exception {
+        System.setProperty("java.net.useSystemProxies", "true");
+        final ProxySelector ps = ProxySelector.getDefault();
+        final URI uri = new URI("http://ubuntu.com");
+        Thread[] threads = new Thread[NUM_THREADS];
+
+        for (int i = 0; i < NUM_THREADS; i++) {
+            threads[i] = new Thread(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        ps.select(uri);
+                    } catch (Exception x) {
+                        throw new RuntimeException(x);
+                    }
+                }
+            });
+        }
+        for (int i = 0; i < NUM_THREADS; i++) {
+            threads[i].start();
+        }
+        for (int i = 0; i < NUM_THREADS; i++) {
+            threads[i].join();
+        }
+    }
+}
diff --git a/jdk/test/java/net/ResponseCache/Test.java b/jdk/test/java/net/ResponseCache/Test.java
new file mode 100644
index 0000000..59951a4
--- /dev/null
+++ b/jdk/test/java/net/ResponseCache/Test.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2012, 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
+ * @summary Fixed a potential NullPointerException when setting a ResponseCache that returns a null CacheRequest
+ * @bug 4837267
+ * @author Michael McMahon
+ */
+
+import com.sun.net.httpserver.*;
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+public class Test
+{
+
+    static class MyHandler implements HttpHandler {
+        public void handle(HttpExchange t) throws IOException {
+            byte[] b = new byte[1024];
+            int r = 0;
+            InputStream is = t.getRequestBody();
+            while (is.read(b) != -1) ;
+            String response = "This is the response";
+            t.sendResponseHeaders(200, response.length());
+            OutputStream os = t.getResponseBody();
+            os.write(response.getBytes());
+            os.close();
+        }
+    }
+
+    public static void main(String args[])  throws Exception {
+        HttpServer server = HttpServer.create(new InetSocketAddress(0), 0);
+        server.createContext("/", new MyHandler());
+        server.start();
+        ResponseCache bak = ResponseCache.getDefault();
+
+        try {
+            ResponseCache.setDefault (new ResponseCache() {
+                public CacheResponse get (URI uri, String rqstMethod, Map<String,List<String>> rqstHeaders)
+                    throws IOException {
+                    return null;
+                }
+                public CacheRequest put(URI uri, URLConnection conn)  throws IOException
+                {
+                    return null;
+                }
+            });
+
+            URL url = new URL ("http://localhost:" + server.getAddress().getPort() + "/");
+            URLConnection urlc = url.openConnection ();
+            InputStream is = urlc.getInputStream();
+            while (is.read() != -1) ;
+            is.close();
+        } finally {
+            ResponseCache.setDefault(bak);
+            server.stop(0);
+        }
+    }
+}
diff --git a/jdk/test/java/net/Socket/B6210227.java b/jdk/test/java/net/Socket/B6210227.java
new file mode 100644
index 0000000..d8f4909
--- /dev/null
+++ b/jdk/test/java/net/Socket/B6210227.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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 6210227
+ * @summary  REGRESSION: Socket.getLocalAddress() returns address of 0.0.0.0 on outbound TCP
+ */
+
+import java.util.*;
+import java.net.*;
+
+public class B6210227 {
+    public static void main(String[] args) throws Exception
+    {
+        ServerSocket ss = new ServerSocket(0);
+        int port = ss.getLocalPort();
+
+        byte[] bad = {0,0,0,0};
+        try {
+            InetSocketAddress isa = new InetSocketAddress(InetAddress.getLocalHost(), port);
+            Socket s = new Socket();
+            s.connect( isa, 1000 );
+            InetAddress iaLocal = s.getLocalAddress(); // if this comes back as 0.0. 0.0 this would demonstrate issue
+            String      sLocalHostname = iaLocal.getHostName();
+            if (Arrays.equals (iaLocal.getAddress(), bad)) {
+                throw new RuntimeException ("0.0.0.0 returned");
+            }
+            System.out.println("local hostname is "+sLocalHostname );
+        } catch(Exception e) {
+            System.out.println("Exception happened");
+            throw e;
+        } finally {
+            ss.close();
+        }
+    }
+}
+
diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java
index 7002dcd..32b6c83 100644
--- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java
+++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Basic.java
@@ -24,7 +24,7 @@
 /* @test
  * @bug 4607272 6842687 6878369 6944810 7023403
  * @summary Unit test for AsynchronousSocketChannel
- * @run main/timeout=600 Basic
+ * @run main Basic -skipSlowConnectTest
  */
 
 import java.nio.ByteBuffer;
@@ -34,12 +34,25 @@
 import java.util.Random;
 import java.util.concurrent.*;
 import java.util.concurrent.atomic.*;
+import java.io.Closeable;
 import java.io.IOException;
 
 public class Basic {
     static final Random rand = new Random();
 
+    static boolean skipSlowConnectTest = false;
+
     public static void main(String[] args) throws Exception {
+        for (String arg: args) {
+            switch (arg) {
+            case "-skipSlowConnectTest" :
+                skipSlowConnectTest = true;
+                break;
+            default:
+                throw new RuntimeException("Unrecognized argument: " + arg);
+            }
+        }
+
         testBind();
         testSocketOptions();
         testConnect();
@@ -54,7 +67,7 @@
         testShutdown();
     }
 
-    static class Server {
+    static class Server implements Closeable {
         private final ServerSocketChannel ssc;
         private final InetSocketAddress address;
 
@@ -74,10 +87,8 @@
             return ssc.accept();
         }
 
-        void close() {
-            try {
-                ssc.close();
-            } catch (IOException ignore) { }
+        public void close() throws IOException {
+            ssc.close();
         }
 
     }
@@ -85,28 +96,28 @@
     static void testBind() throws Exception {
         System.out.println("-- bind --");
 
-        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        if (ch.getLocalAddress() != null)
-            throw new RuntimeException("Local address should be 'null'");
-        ch.bind(new InetSocketAddress(0));
-
-        // check local address after binding
-        InetSocketAddress local = (InetSocketAddress)ch.getLocalAddress();
-        if (local.getPort() == 0)
-            throw new RuntimeException("Unexpected port");
-        if (!local.getAddress().isAnyLocalAddress())
-            throw new RuntimeException("Not bound to a wildcard address");
-
-        // try to re-bind
-        try {
+        try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
+            if (ch.getLocalAddress() != null)
+                throw new RuntimeException("Local address should be 'null'");
             ch.bind(new InetSocketAddress(0));
-            throw new RuntimeException("AlreadyBoundException expected");
-        } catch (AlreadyBoundException x) {
+
+            // check local address after binding
+            InetSocketAddress local = (InetSocketAddress)ch.getLocalAddress();
+            if (local.getPort() == 0)
+                throw new RuntimeException("Unexpected port");
+            if (!local.getAddress().isAnyLocalAddress())
+                throw new RuntimeException("Not bound to a wildcard address");
+
+            // try to re-bind
+            try {
+                ch.bind(new InetSocketAddress(0));
+                throw new RuntimeException("AlreadyBoundException expected");
+            } catch (AlreadyBoundException x) {
+            }
         }
-        ch.close();
 
         // check ClosedChannelException
-        ch = AsynchronousSocketChannel.open();
+        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
         ch.close();
         try {
             ch.bind(new InetSocketAddress(0));
@@ -118,109 +129,124 @@
     static void testSocketOptions() throws Exception {
         System.out.println("-- socket options --");
 
-        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()
-            .setOption(SO_RCVBUF, 128*1024)
-            .setOption(SO_SNDBUF, 128*1024)
-            .setOption(SO_REUSEADDR, true);
+        try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
+            ch.setOption(SO_RCVBUF, 128*1024)
+              .setOption(SO_SNDBUF, 128*1024)
+              .setOption(SO_REUSEADDR, true);
 
-        // check SO_SNDBUF/SO_RCVBUF limits
-        int before, after;
-        before = ch.getOption(SO_SNDBUF);
-        after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
-        if (after < before)
-            throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
-        before = ch.getOption(SO_RCVBUF);
-        after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
-        if (after < before)
-            throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
+            // check SO_SNDBUF/SO_RCVBUF limits
+            int before, after;
+            before = ch.getOption(SO_SNDBUF);
+            after = ch.setOption(SO_SNDBUF, Integer.MAX_VALUE).getOption(SO_SNDBUF);
+            if (after < before)
+                throw new RuntimeException("setOption caused SO_SNDBUF to decrease");
+            before = ch.getOption(SO_RCVBUF);
+            after = ch.setOption(SO_RCVBUF, Integer.MAX_VALUE).getOption(SO_RCVBUF);
+            if (after < before)
+                throw new RuntimeException("setOption caused SO_RCVBUF to decrease");
 
-        ch.bind(new InetSocketAddress(0));
+            ch.bind(new InetSocketAddress(0));
 
-        // default values
-        if ((Boolean)ch.getOption(SO_KEEPALIVE))
-            throw new RuntimeException("Default of SO_KEEPALIVE should be 'false'");
-        if ((Boolean)ch.getOption(TCP_NODELAY))
-            throw new RuntimeException("Default of TCP_NODELAY should be 'false'");
+            // default values
+            if (ch.getOption(SO_KEEPALIVE))
+                throw new RuntimeException("Default of SO_KEEPALIVE should be 'false'");
+            if (ch.getOption(TCP_NODELAY))
+                throw new RuntimeException("Default of TCP_NODELAY should be 'false'");
 
-        // set and check
-        if (!(Boolean)ch.setOption(SO_KEEPALIVE, true).getOption(SO_KEEPALIVE))
-            throw new RuntimeException("SO_KEEPALIVE did not change");
-        if (!(Boolean)ch.setOption(TCP_NODELAY, true).getOption(TCP_NODELAY))
-            throw new RuntimeException("SO_KEEPALIVE did not change");
+            // set and check
+            if (!ch.setOption(SO_KEEPALIVE, true).getOption(SO_KEEPALIVE))
+                throw new RuntimeException("SO_KEEPALIVE did not change");
+            if (!ch.setOption(TCP_NODELAY, true).getOption(TCP_NODELAY))
+                throw new RuntimeException("SO_KEEPALIVE did not change");
 
-        // read others (can't check as actual value is implementation dependent)
-        ch.getOption(SO_RCVBUF);
-        ch.getOption(SO_SNDBUF);
-
-        ch.close();
+            // read others (can't check as actual value is implementation dependent)
+            ch.getOption(SO_RCVBUF);
+            ch.getOption(SO_SNDBUF);
+        }
     }
 
     static void testConnect() throws Exception {
         System.out.println("-- connect --");
 
-        Server server = new Server();
-        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
+        SocketAddress address;
 
-        // check local address
-        if (ch.getLocalAddress() == null)
-            throw new RuntimeException("Not bound to local address");
+        try (Server server = new Server()) {
+            address = server.address();
 
-        // check remote address
-        InetSocketAddress remote = (InetSocketAddress)ch.getRemoteAddress();
-        if (remote.getPort() != server.address().getPort())
-            throw new RuntimeException("Connected to unexpected port");
-        if (!remote.getAddress().equals(server.address().getAddress()))
-            throw new RuntimeException("Connected to unexpected address");
+            // connect to server and check local/remote addresses
+            try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
+                ch.connect(address).get();
+                // check local address
+                if (ch.getLocalAddress() == null)
+                    throw new RuntimeException("Not bound to local address");
 
-        // try to connect again
-        try {
-            ch.connect(server.address()).get();
-            throw new RuntimeException("AlreadyConnectedException expected");
-        } catch (AlreadyConnectedException x) {
-        }
-        ch.close();
+                // check remote address
+                InetSocketAddress remote = (InetSocketAddress)ch.getRemoteAddress();
+                if (remote.getPort() != server.address().getPort())
+                    throw new RuntimeException("Connected to unexpected port");
+                if (!remote.getAddress().equals(server.address().getAddress()))
+                    throw new RuntimeException("Connected to unexpected address");
 
-        // check that connect fails with ClosedChannelException)
-        ch = AsynchronousSocketChannel.open();
-        ch.close();
-        try {
-            ch.connect(server.address()).get();
-            throw new RuntimeException("ExecutionException expected");
-        } catch (ExecutionException x) {
-            if (!(x.getCause() instanceof ClosedChannelException))
-                throw new RuntimeException("Cause of ClosedChannelException expected");
-        }
-        final AtomicReference<Throwable> connectException =
-            new AtomicReference<Throwable>();
-        ch.connect(server.address(), (Void)null, new CompletionHandler<Void,Void>() {
-            public void completed(Void result, Void att) {
+                // try to connect again
+                try {
+                    ch.connect(server.address()).get();
+                    throw new RuntimeException("AlreadyConnectedException expected");
+                } catch (AlreadyConnectedException x) {
+                }
+
+                // clean-up
+                server.accept().close();
             }
-            public void failed(Throwable exc, Void att) {
-                connectException.set(exc);
-            }
-        });
-        while (connectException.get() == null) {
-            Thread.sleep(100);
-        }
-        if (!(connectException.get() instanceof ClosedChannelException))
-            throw new RuntimeException("ClosedChannelException expected");
 
-        System.out.println("-- connect to non-existent host --");
+            // check that connect fails with ClosedChannelException
+            AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            ch.close();
+            try {
+                ch.connect(server.address()).get();
+                throw new RuntimeException("ExecutionException expected");
+            } catch (ExecutionException x) {
+                if (!(x.getCause() instanceof ClosedChannelException))
+                    throw new RuntimeException("Cause of ClosedChannelException expected");
+            }
+            final AtomicReference<Throwable> connectException = new AtomicReference<>();
+            ch.connect(server.address(), (Void)null, new CompletionHandler<Void,Void>() {
+                public void completed(Void result, Void att) {
+                }
+                public void failed(Throwable exc, Void att) {
+                    connectException.set(exc);
+                }
+            });
+            while (connectException.get() == null) {
+                Thread.sleep(100);
+            }
+            if (!(connectException.get() instanceof ClosedChannelException))
+                throw new RuntimeException("ClosedChannelException expected");
+        }
 
         // test that failure to connect closes the channel
-        ch = AsynchronousSocketChannel.open();
-        try {
-            ch.connect(genSocketAddress()).get();
-        } catch (ExecutionException x) {
-            // failed to establish connection
-            if (ch.isOpen())
-                throw new RuntimeException("Channel should be closed");
-        } finally {
-            ch.close();
+        try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
+            try {
+                ch.connect(address).get();
+            } catch (ExecutionException x) {
+                // failed to establish connection
+                if (ch.isOpen())
+                    throw new RuntimeException("Channel should be closed");
+            }
         }
 
-        server.close();
+        // repeat test by connecting to a (probably) non-existent host. This
+        // improves the chance that the connect will not fail immediately.
+        if (!skipSlowConnectTest) {
+            try (AsynchronousSocketChannel ch = AsynchronousSocketChannel.open()) {
+                try {
+                    ch.connect(genSocketAddress()).get();
+                } catch (ExecutionException x) {
+                    // failed to establish connection
+                    if (ch.isOpen())
+                        throw new RuntimeException("Channel should be closed");
+                }
+            }
+        }
     }
 
     static void testCloseWhenPending() throws Exception {
@@ -249,466 +275,460 @@
 
         System.out.println("-- asynchronous close when reading --");
 
-        Server server = new Server();
-        ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
+        try (Server server = new Server()) {
+            ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
 
-        ByteBuffer dst = ByteBuffer.allocateDirect(100);
-        Future<Integer> result = ch.read(dst);
+            ByteBuffer dst = ByteBuffer.allocateDirect(100);
+            Future<Integer> result = ch.read(dst);
 
-        // attempt a second read - should fail with ReadPendingException
-        ByteBuffer buf = ByteBuffer.allocateDirect(100);
-        try {
-            ch.read(buf);
-            throw new RuntimeException("ReadPendingException expected");
-        } catch (ReadPendingException x) {
-        }
-
-        // close channel (should cause initial read to complete)
-        ch.close();
-
-        // check that AsynchronousCloseException is thrown
-        try {
-            result.get();
-            throw new RuntimeException("Should not read");
-        } catch (ExecutionException x) {
-            if (!(x.getCause() instanceof AsynchronousCloseException))
-                throw new RuntimeException(x);
-        }
-
-        System.out.println("-- asynchronous close when writing --");
-
-        ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
-
-        final AtomicReference<Throwable> writeException =
-            new AtomicReference<Throwable>();
-
-        // write bytes to fill socket buffer
-        ch.write(genBuffer(), ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
-            public void completed(Integer result, AsynchronousSocketChannel ch) {
-                ch.write(genBuffer(), ch, this);
+            // attempt a second read - should fail with ReadPendingException
+            ByteBuffer buf = ByteBuffer.allocateDirect(100);
+            try {
+                ch.read(buf);
+                throw new RuntimeException("ReadPendingException expected");
+            } catch (ReadPendingException x) {
             }
-            public void failed(Throwable x, AsynchronousSocketChannel ch) {
-                writeException.set(x);
+
+            // close channel (should cause initial read to complete)
+            ch.close();
+            server.accept().close();
+
+            // check that AsynchronousCloseException is thrown
+            try {
+                result.get();
+                throw new RuntimeException("Should not read");
+            } catch (ExecutionException x) {
+                if (!(x.getCause() instanceof AsynchronousCloseException))
+                    throw new RuntimeException(x);
             }
-        });
 
-        // give time for socket buffer to fill up.
-        Thread.sleep(5*1000);
+            System.out.println("-- asynchronous close when writing --");
 
-        //  attempt a concurrent write - should fail with WritePendingException
-        try {
-            ch.write(genBuffer());
-            throw new RuntimeException("WritePendingException expected");
-        } catch (WritePendingException x) {
+            ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
+
+            final AtomicReference<Throwable> writeException =
+                new AtomicReference<Throwable>();
+
+            // write bytes to fill socket buffer
+            ch.write(genBuffer(), ch, new CompletionHandler<Integer,AsynchronousSocketChannel>() {
+                public void completed(Integer result, AsynchronousSocketChannel ch) {
+                    ch.write(genBuffer(), ch, this);
+                }
+                public void failed(Throwable x, AsynchronousSocketChannel ch) {
+                    writeException.set(x);
+                }
+            });
+
+            // give time for socket buffer to fill up.
+            Thread.sleep(5*1000);
+
+            //  attempt a concurrent write - should fail with WritePendingException
+            try {
+                ch.write(genBuffer());
+                throw new RuntimeException("WritePendingException expected");
+            } catch (WritePendingException x) {
+            }
+
+            // close channel - should cause initial write to complete
+            ch.close();
+            server.accept().close();
+
+            // wait for exception
+            while (writeException.get() == null) {
+                Thread.sleep(100);
+            }
+            if (!(writeException.get() instanceof AsynchronousCloseException))
+                throw new RuntimeException("AsynchronousCloseException expected");
         }
-
-        // close channel - should cause initial write to complete
-        ch.close();
-
-        // wait for exception
-        while (writeException.get() == null) {
-            Thread.sleep(100);
-        }
-        if (!(writeException.get() instanceof AsynchronousCloseException))
-            throw new RuntimeException("AsynchronousCloseException expected");
-
-        server.close();
     }
 
     static void testCancel() throws Exception {
         System.out.println("-- cancel --");
 
-        Server server = new Server();
+        try (Server server = new Server()) {
+            for (int i=0; i<2; i++) {
+                boolean mayInterruptIfRunning = (i == 0) ? false : true;
 
-        for (int i=0; i<2; i++) {
-            boolean mayInterruptIfRunning = (i == 0) ? false : true;
+                // establish loopback connection
+                AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+                ch.connect(server.address()).get();
+                SocketChannel peer = server.accept();
 
-            // establish loopback connection
-            AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-            ch.connect(server.address()).get();
-            SocketChannel peer = server.accept();
+                // start read operation
+                ByteBuffer buf = ByteBuffer.allocate(1);
+                Future<Integer> res = ch.read(buf);
 
-            // start read operation
-            ByteBuffer buf = ByteBuffer.allocate(1);
-            Future<Integer> res = ch.read(buf);
+                // cancel operation
+                boolean cancelled = res.cancel(mayInterruptIfRunning);
 
-            // cancel operation
-            boolean cancelled = res.cancel(mayInterruptIfRunning);
+                // check post-conditions
+                if (!res.isDone())
+                    throw new RuntimeException("isDone should return true");
+                if (res.isCancelled() != cancelled)
+                    throw new RuntimeException("isCancelled not consistent");
+                try {
+                    res.get();
+                    throw new RuntimeException("CancellationException expected");
+                } catch (CancellationException x) {
+                }
+                try {
+                    res.get(1, TimeUnit.SECONDS);
+                    throw new RuntimeException("CancellationException expected");
+                } catch (CancellationException x) {
+                }
 
-            // check post-conditions
-            if (!res.isDone())
-                throw new RuntimeException("isDone should return true");
-            if (res.isCancelled() != cancelled)
-                throw new RuntimeException("isCancelled not consistent");
-            try {
-                res.get();
-                throw new RuntimeException("CancellationException expected");
-            } catch (CancellationException x) {
+                // check that the cancel doesn't impact writing to the channel
+                if (!mayInterruptIfRunning) {
+                    buf = ByteBuffer.wrap("a".getBytes());
+                    ch.write(buf).get();
+                }
+
+                ch.close();
+                peer.close();
             }
-            try {
-                res.get(1, TimeUnit.SECONDS);
-                throw new RuntimeException("CancellationException expected");
-            } catch (CancellationException x) {
-            }
-
-            // check that the cancel doesn't impact writing to the channel
-            if (!mayInterruptIfRunning) {
-                buf = ByteBuffer.wrap("a".getBytes());
-                ch.write(buf).get();
-            }
-
-            ch.close();
-            peer.close();
         }
-
-        server.close();
     }
 
     static void testRead1() throws Exception {
         System.out.println("-- read (1) --");
 
-        Server server = new Server();
-        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
+        try (Server server = new Server()) {
+            final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
 
-        // read with 0 bytes remaining should complete immediately
-        ByteBuffer buf = ByteBuffer.allocate(1);
-        buf.put((byte)0);
-        int n = ch.read(buf).get();
-        if (n != 0)
-            throw new RuntimeException("0 expected");
+            // read with 0 bytes remaining should complete immediately
+            ByteBuffer buf = ByteBuffer.allocate(1);
+            buf.put((byte)0);
+            int n = ch.read(buf).get();
+            if (n != 0)
+                throw new RuntimeException("0 expected");
 
-        // write bytes and close connection
-        SocketChannel sc = server.accept();
-        ByteBuffer src = genBuffer();
-        sc.setOption(StandardSocketOptions.SO_SNDBUF, src.remaining());
-        while (src.hasRemaining())
-            sc.write(src);
-        sc.close();
+            // write bytes and close connection
+            ByteBuffer src = genBuffer();
+            try (SocketChannel sc = server.accept()) {
+                sc.setOption(SO_SNDBUF, src.remaining());
+                while (src.hasRemaining())
+                    sc.write(src);
+            }
 
-        // reads should complete immediately
-        final ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity() + 100);
-        final CountDownLatch latch = new CountDownLatch(1);
-        ch.read(dst, (Void)null, new CompletionHandler<Integer,Void>() {
-            public void completed(Integer result, Void att) {
-                int n = result;
-                if (n > 0) {
-                    ch.read(dst, (Void)null, this);
-                } else {
-                    latch.countDown();
+            // reads should complete immediately
+            final ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity() + 100);
+            final CountDownLatch latch = new CountDownLatch(1);
+            ch.read(dst, (Void)null, new CompletionHandler<Integer,Void>() {
+                public void completed(Integer result, Void att) {
+                    int n = result;
+                    if (n > 0) {
+                        ch.read(dst, (Void)null, this);
+                    } else {
+                        latch.countDown();
+                    }
                 }
+                public void failed(Throwable exc, Void att) {
+                }
+            });
+
+            latch.await();
+
+            // check buffers
+            src.flip();
+            dst.flip();
+            if (!src.equals(dst)) {
+                throw new RuntimeException("Contents differ");
             }
-            public void failed(Throwable exc, Void att) {
+
+            // close channel
+            ch.close();
+
+            // check read fails with ClosedChannelException
+            try {
+                ch.read(dst).get();
+                throw new RuntimeException("ExecutionException expected");
+            } catch (ExecutionException x) {
+                if (!(x.getCause() instanceof ClosedChannelException))
+                    throw new RuntimeException("Cause of ClosedChannelException expected");
             }
-        });
-
-        latch.await();
-
-        // check buffers
-        src.flip();
-        dst.flip();
-        if (!src.equals(dst)) {
-            throw new RuntimeException("Contents differ");
         }
-
-        // close channel
-        ch.close();
-
-        // check read fails with ClosedChannelException
-        try {
-            ch.read(dst).get();
-            throw new RuntimeException("ExecutionException expected");
-        } catch (ExecutionException x) {
-            if (!(x.getCause() instanceof ClosedChannelException))
-                throw new RuntimeException("Cause of ClosedChannelException expected");
-        }
-
-        server.close();
     }
 
     static void testRead2() throws Exception {
         System.out.println("-- read (2) --");
 
-        Server server = new Server();
+        try (Server server = new Server()) {
+            final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
+            SocketChannel sc = server.accept();
 
-        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
-        SocketChannel sc = server.accept();
+            ByteBuffer src = genBuffer();
 
-        ByteBuffer src = genBuffer();
-
-        // read until the buffer is full
-        final ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity());
-        final CountDownLatch latch = new CountDownLatch(1);
-        ch.read(dst, (Void)null, new CompletionHandler<Integer,Void>() {
-            public void completed(Integer result, Void att) {
-                if (dst.hasRemaining()) {
-                    ch.read(dst, (Void)null, this);
-                } else {
-                    latch.countDown();
+            // read until the buffer is full
+            final ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity());
+            final CountDownLatch latch = new CountDownLatch(1);
+            ch.read(dst, (Void)null, new CompletionHandler<Integer,Void>() {
+                public void completed(Integer result, Void att) {
+                    if (dst.hasRemaining()) {
+                        ch.read(dst, (Void)null, this);
+                    } else {
+                        latch.countDown();
+                    }
                 }
+                public void failed(Throwable exc, Void att) {
+                }
+            });
+
+            // trickle the writing
+            do {
+                int rem = src.remaining();
+                int size = (rem <= 100) ? rem : 50 + rand.nextInt(rem - 100);
+                ByteBuffer buf = ByteBuffer.allocate(size);
+                for (int i=0; i<size; i++)
+                    buf.put(src.get());
+                buf.flip();
+                Thread.sleep(50 + rand.nextInt(1500));
+                while (buf.hasRemaining())
+                    sc.write(buf);
+            } while (src.hasRemaining());
+
+            // wait until ascynrhonous reading has completed
+            latch.await();
+
+            // check buffers
+            src.flip();
+            dst.flip();
+            if (!src.equals(dst)) {
+               throw new RuntimeException("Contents differ");
             }
-            public void failed(Throwable exc, Void att) {
-            }
-        });
 
-        // trickle the writing
-        do {
-            int rem = src.remaining();
-            int size = (rem <= 100) ? rem : 50 + rand.nextInt(rem - 100);
-            ByteBuffer buf = ByteBuffer.allocate(size);
-            for (int i=0; i<size; i++)
-                buf.put(src.get());
-            buf.flip();
-            Thread.sleep(50 + rand.nextInt(1500));
-            while (buf.hasRemaining())
-                sc.write(buf);
-        } while (src.hasRemaining());
-
-        // wait until ascynrhonous reading has completed
-        latch.await();
-
-        // check buffers
-        src.flip();
-        dst.flip();
-        if (!src.equals(dst)) {
-           throw new RuntimeException("Contents differ");
+            sc.close();
+            ch.close();
         }
-
-        sc.close();
-        ch.close();
-        server.close();
     }
 
     // exercise scattering read
     static void testRead3() throws Exception {
         System.out.println("-- read (3) --");
 
-        Server server = new Server();
-        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
-        SocketChannel sc = server.accept();
+        try (Server server = new Server()) {
+            final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
+            SocketChannel sc = server.accept();
 
-        ByteBuffer[] dsts = new ByteBuffer[3];
-        for (int i=0; i<dsts.length; i++) {
-            dsts[i] = ByteBuffer.allocateDirect(100);
+            ByteBuffer[] dsts = new ByteBuffer[3];
+            for (int i=0; i<dsts.length; i++) {
+                dsts[i] = ByteBuffer.allocateDirect(100);
+            }
+
+            // scattering read that completes ascynhronously
+            final CountDownLatch l1 = new CountDownLatch(1);
+            ch.read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, (Void)null,
+                new CompletionHandler<Long,Void>() {
+                    public void completed(Long result, Void att) {
+                        long n = result;
+                        if (n <= 0)
+                            throw new RuntimeException("No bytes read");
+                        l1.countDown();
+                    }
+                    public void failed(Throwable exc, Void att) {
+                    }
+            });
+
+            // write some bytes
+            sc.write(genBuffer());
+
+            // read should now complete
+            l1.await();
+
+            // write more bytes
+            sc.write(genBuffer());
+
+            // read should complete immediately
+            for (int i=0; i<dsts.length; i++) {
+                dsts[i].rewind();
+            }
+
+            final CountDownLatch l2 = new CountDownLatch(1);
+            ch.read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, (Void)null,
+                new CompletionHandler<Long,Void>() {
+                    public void completed(Long result, Void att) {
+                        long n = result;
+                        if (n <= 0)
+                            throw new RuntimeException("No bytes read");
+                        l2.countDown();
+                    }
+                    public void failed(Throwable exc, Void att) {
+                    }
+            });
+            l2.await();
+
+            ch.close();
+            sc.close();
         }
-
-        // scattering read that completes ascynhronously
-        final CountDownLatch l1 = new CountDownLatch(1);
-        ch.read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, (Void)null,
-            new CompletionHandler<Long,Void>() {
-                public void completed(Long result, Void att) {
-                    long n = result;
-                    if (n <= 0)
-                        throw new RuntimeException("No bytes read");
-                    l1.countDown();
-                }
-                public void failed(Throwable exc, Void att) {
-                }
-        });
-
-        // write some bytes
-        sc.write(genBuffer());
-
-        // read should now complete
-        l1.await();
-
-        // write more bytes
-        sc.write(genBuffer());
-
-        // read should complete immediately
-        for (int i=0; i<dsts.length; i++) {
-            dsts[i].rewind();
-        }
-
-        final CountDownLatch l2 = new CountDownLatch(1);
-        ch.read(dsts, 0, dsts.length, 0L, TimeUnit.SECONDS, (Void)null,
-            new CompletionHandler<Long,Void>() {
-                public void completed(Long result, Void att) {
-                    long n = result;
-                    if (n <= 0)
-                        throw new RuntimeException("No bytes read");
-                    l2.countDown();
-                }
-                public void failed(Throwable exc, Void att) {
-                }
-        });
-        l2.await();
-
-        ch.close();
-        sc.close();
-        server.close();
     }
 
     static void testWrite1() throws Exception {
         System.out.println("-- write (1) --");
 
-        Server server = new Server();
-        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
-        SocketChannel sc = server.accept();
+        try (Server server = new Server()) {
+            final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
+            SocketChannel sc = server.accept();
 
-        // write with 0 bytes remaining should complete immediately
-        ByteBuffer buf = ByteBuffer.allocate(1);
-        buf.put((byte)0);
-        int n = ch.write(buf).get();
-        if (n != 0)
-            throw new RuntimeException("0 expected");
+            // write with 0 bytes remaining should complete immediately
+            ByteBuffer buf = ByteBuffer.allocate(1);
+            buf.put((byte)0);
+            int n = ch.write(buf).get();
+            if (n != 0)
+                throw new RuntimeException("0 expected");
 
-        // write all bytes and close connection when done
-        final ByteBuffer src = genBuffer();
-        ch.write(src, (Void)null, new CompletionHandler<Integer,Void>() {
-            public void completed(Integer result, Void att) {
-                if (src.hasRemaining()) {
-                    ch.write(src, (Void)null, this);
-                } else {
-                    try {
-                        ch.close();
-                    } catch (IOException ignore) { }
+            // write all bytes and close connection when done
+            final ByteBuffer src = genBuffer();
+            ch.write(src, (Void)null, new CompletionHandler<Integer,Void>() {
+                public void completed(Integer result, Void att) {
+                    if (src.hasRemaining()) {
+                        ch.write(src, (Void)null, this);
+                    } else {
+                        try {
+                            ch.close();
+                        } catch (IOException ignore) { }
+                    }
                 }
+                public void failed(Throwable exc, Void att) {
+                }
+            });
+
+            // read to EOF or buffer full
+            ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity() + 100);
+            do {
+                n = sc.read(dst);
+            } while (n > 0);
+            sc.close();
+
+            // check buffers
+            src.flip();
+            dst.flip();
+            if (!src.equals(dst)) {
+                throw new RuntimeException("Contents differ");
             }
-            public void failed(Throwable exc, Void att) {
+
+            // check write fails with ClosedChannelException
+            try {
+                ch.read(dst).get();
+                throw new RuntimeException("ExecutionException expected");
+            } catch (ExecutionException x) {
+                if (!(x.getCause() instanceof ClosedChannelException))
+                    throw new RuntimeException("Cause of ClosedChannelException expected");
             }
-        });
-
-        // read to EOF or buffer full
-        ByteBuffer dst = ByteBuffer.allocateDirect(src.capacity() + 100);
-        do {
-            n = sc.read(dst);
-        } while (n > 0);
-        sc.close();
-
-        // check buffers
-        src.flip();
-        dst.flip();
-        if (!src.equals(dst)) {
-            throw new RuntimeException("Contents differ");
         }
-
-        // check write fails with ClosedChannelException
-        try {
-            ch.read(dst).get();
-            throw new RuntimeException("ExecutionException expected");
-        } catch (ExecutionException x) {
-            if (!(x.getCause() instanceof ClosedChannelException))
-                throw new RuntimeException("Cause of ClosedChannelException expected");
-        }
-
-        server.close();
     }
 
     // exercise gathering write
     static void testWrite2() throws Exception {
         System.out.println("-- write (2) --");
 
-        Server server = new Server();
-        final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
-        SocketChannel sc = server.accept();
+        try (Server server = new Server()) {
+            final AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
+            SocketChannel sc = server.accept();
 
-        // number of bytes written
-        final AtomicLong bytesWritten = new AtomicLong(0);
+            // number of bytes written
+            final AtomicLong bytesWritten = new AtomicLong(0);
 
-        // write buffers (should complete immediately)
-        ByteBuffer[] srcs = genBuffers(1);
-        final CountDownLatch l1 = new CountDownLatch(1);
-        ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, (Void)null,
-            new CompletionHandler<Long,Void>() {
-                public void completed(Long result, Void att) {
-                    long n = result;
-                    if (n <= 0)
-                        throw new RuntimeException("No bytes read");
-                    bytesWritten.addAndGet(n);
-                    l1.countDown();
-                }
-                public void failed(Throwable exc, Void att) {
-                }
-        });
-        l1.await();
-
-        // set to true to signal that no more buffers should be written
-        final AtomicBoolean continueWriting = new AtomicBoolean(true);
-
-        // write until socket buffer is full so as to create the conditions
-        // for when a write does not complete immediately
-        srcs = genBuffers(1);
-        ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, (Void)null,
-            new CompletionHandler<Long,Void>() {
-                public void completed(Long result, Void att) {
-                    long n = result;
-                    if (n <= 0)
-                        throw new RuntimeException("No bytes written");
-                    bytesWritten.addAndGet(n);
-                    if (continueWriting.get()) {
-                        ByteBuffer[] srcs = genBuffers(8);
-                        ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS,
-                            (Void)null, this);
+            // write buffers (should complete immediately)
+            ByteBuffer[] srcs = genBuffers(1);
+            final CountDownLatch l1 = new CountDownLatch(1);
+            ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, (Void)null,
+                new CompletionHandler<Long,Void>() {
+                    public void completed(Long result, Void att) {
+                        long n = result;
+                        if (n <= 0)
+                            throw new RuntimeException("No bytes read");
+                        bytesWritten.addAndGet(n);
+                        l1.countDown();
                     }
-                }
-                public void failed(Throwable exc, Void att) {
-                }
-        });
+                    public void failed(Throwable exc, Void att) {
+                    }
+            });
+            l1.await();
 
-        // give time for socket buffer to fill up.
-        Thread.sleep(5*1000);
+            // set to true to signal that no more buffers should be written
+            final AtomicBoolean continueWriting = new AtomicBoolean(true);
 
-        // signal handler to stop further writing
-        continueWriting.set(false);
+            // write until socket buffer is full so as to create the conditions
+            // for when a write does not complete immediately
+            srcs = genBuffers(1);
+            ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS, (Void)null,
+                new CompletionHandler<Long,Void>() {
+                    public void completed(Long result, Void att) {
+                        long n = result;
+                        if (n <= 0)
+                            throw new RuntimeException("No bytes written");
+                        bytesWritten.addAndGet(n);
+                        if (continueWriting.get()) {
+                            ByteBuffer[] srcs = genBuffers(8);
+                            ch.write(srcs, 0, srcs.length, 0L, TimeUnit.SECONDS,
+                                (Void)null, this);
+                        }
+                    }
+                    public void failed(Throwable exc, Void att) {
+                    }
+            });
 
-        // read until done
-        ByteBuffer buf = ByteBuffer.allocateDirect(4096);
-        long total = 0L;
-        do {
-            int n = sc.read(buf);
-            if (n <= 0)
-                throw new RuntimeException("No bytes read");
-            buf.rewind();
-            total += n;
-        } while (total < bytesWritten.get());
+            // give time for socket buffer to fill up.
+            Thread.sleep(5*1000);
 
-        ch.close();
-        sc.close();
-        server.close();
+            // signal handler to stop further writing
+            continueWriting.set(false);
+
+            // read until done
+            ByteBuffer buf = ByteBuffer.allocateDirect(4096);
+            long total = 0L;
+            do {
+                int n = sc.read(buf);
+                if (n <= 0)
+                    throw new RuntimeException("No bytes read");
+                buf.rewind();
+                total += n;
+            } while (total < bytesWritten.get());
+
+            ch.close();
+            sc.close();
+        }
     }
 
     static void testShutdown() throws Exception {
         System.out.println("-- shutdown--");
 
-        Server server = new Server();
-        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
-        SocketChannel sc = server.accept();
+        try (Server server = new Server();
+             AsynchronousSocketChannel ch = AsynchronousSocketChannel.open())
+        {
+            ch.connect(server.address()).get();
+            try (SocketChannel peer = server.accept()) {
+                ByteBuffer buf = ByteBuffer.allocateDirect(1000);
+                int n;
 
-        ByteBuffer buf = ByteBuffer.allocateDirect(1000);
-        int n;
+                // check read
+                ch.shutdownInput();
+                n = ch.read(buf).get();
+                if (n != -1)
+                    throw new RuntimeException("-1 expected");
+                // check full with full buffer
+                buf.put(new byte[100]);
+                n = ch.read(buf).get();
+                if (n != -1)
+                    throw new RuntimeException("-1 expected");
 
-        // check read
-        ch.shutdownInput();
-        n = ch.read(buf).get();
-        if (n != -1)
-            throw new RuntimeException("-1 expected");
-        // check full with full buffer
-        buf.put(new byte[100]);
-        n = ch.read(buf).get();
-        if (n != -1)
-            throw new RuntimeException("-1 expected");
-
-        // check write
-        ch.shutdownOutput();
-        try {
-            ch.write(buf).get();
-            throw new RuntimeException("ClosedChannelException expected");
-        } catch (ExecutionException x) {
-            if (!(x.getCause() instanceof ClosedChannelException))
-                throw new RuntimeException("ClosedChannelException expected");
+                // check write
+                ch.shutdownOutput();
+                try {
+                    ch.write(buf).get();
+                    throw new RuntimeException("ClosedChannelException expected");
+                } catch (ExecutionException x) {
+                    if (!(x.getCause() instanceof ClosedChannelException))
+                        throw new RuntimeException("ClosedChannelException expected");
+                }
+            }
         }
-
-        sc.close();
-        ch.close();
-        server.close();
     }
 
     static void testTimeout() throws Exception {
@@ -720,88 +740,88 @@
     }
 
     static void testTimeout(final long timeout, final TimeUnit unit) throws Exception {
-        Server server = new Server();
-        AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
-        ch.connect(server.address()).get();
+        try (Server server = new Server()) {
+            AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();
+            ch.connect(server.address()).get();
 
-        ByteBuffer dst = ByteBuffer.allocate(512);
+            ByteBuffer dst = ByteBuffer.allocate(512);
 
-        final AtomicReference<Throwable> readException = new AtomicReference<Throwable>();
+            final AtomicReference<Throwable> readException = new AtomicReference<Throwable>();
 
-        // this read should timeout if value is > 0
-        ch.read(dst, timeout, unit, null, new CompletionHandler<Integer,Void>() {
-            public void completed(Integer result, Void att) {
-                readException.set(new RuntimeException("Should not complete"));
-            }
-            public void failed(Throwable exc, Void att) {
-                readException.set(exc);
-            }
-        });
-        if (timeout > 0L) {
-            // wait for exception
-            while (readException.get() == null) {
-                Thread.sleep(100);
-            }
-            if (!(readException.get() instanceof InterruptedByTimeoutException))
-                throw new RuntimeException("InterruptedByTimeoutException expected");
+            // this read should timeout if value is > 0
+            ch.read(dst, timeout, unit, null, new CompletionHandler<Integer,Void>() {
+                public void completed(Integer result, Void att) {
+                    readException.set(new RuntimeException("Should not complete"));
+                }
+                public void failed(Throwable exc, Void att) {
+                    readException.set(exc);
+                }
+            });
+            if (timeout > 0L) {
+                // wait for exception
+                while (readException.get() == null) {
+                    Thread.sleep(100);
+                }
+                if (!(readException.get() instanceof InterruptedByTimeoutException))
+                    throw new RuntimeException("InterruptedByTimeoutException expected");
 
-            // after a timeout then further reading should throw unspecified runtime exception
-            boolean exceptionThrown = false;
-            try {
-                ch.read(dst);
-            } catch (RuntimeException x) {
-                exceptionThrown = true;
+                // after a timeout then further reading should throw unspecified runtime exception
+                boolean exceptionThrown = false;
+                try {
+                    ch.read(dst);
+                } catch (RuntimeException x) {
+                    exceptionThrown = true;
+                }
+                if (!exceptionThrown)
+                    throw new RuntimeException("RuntimeException expected after timeout.");
+            } else {
+                Thread.sleep(1000);
+                Throwable exc = readException.get();
+                if (exc != null)
+                    throw new RuntimeException(exc);
             }
-            if (!exceptionThrown)
-                throw new RuntimeException("RuntimeException expected after timeout.");
-        } else {
-            Thread.sleep(1000);
-            Throwable exc = readException.get();
-            if (exc != null)
-                throw new RuntimeException(exc);
+
+            final AtomicReference<Throwable> writeException = new AtomicReference<Throwable>();
+
+            // write bytes to fill socket buffer
+            ch.write(genBuffer(), timeout, unit, ch,
+                new CompletionHandler<Integer,AsynchronousSocketChannel>()
+            {
+                public void completed(Integer result, AsynchronousSocketChannel ch) {
+                    ch.write(genBuffer(), timeout, unit, ch, this);
+                }
+                public void failed(Throwable exc, AsynchronousSocketChannel ch) {
+                    writeException.set(exc);
+                }
+            });
+            if (timeout > 0) {
+                // wait for exception
+                while (writeException.get() == null) {
+                    Thread.sleep(100);
+                }
+                if (!(writeException.get() instanceof InterruptedByTimeoutException))
+                    throw new RuntimeException("InterruptedByTimeoutException expected");
+
+                // after a timeout then further writing should throw unspecified runtime exception
+                boolean exceptionThrown = false;
+                try {
+                    ch.write(genBuffer());
+                } catch (RuntimeException x) {
+                    exceptionThrown = true;
+                }
+                if (!exceptionThrown)
+                    throw new RuntimeException("RuntimeException expected after timeout.");
+            } else {
+                Thread.sleep(1000);
+                Throwable exc = writeException.get();
+                if (exc != null)
+                    throw new RuntimeException(exc);
+            }
+
+            // clean-up
+            server.accept().close();
+            ch.close();
         }
-
-        final AtomicReference<Throwable> writeException = new AtomicReference<Throwable>();
-
-        // write bytes to fill socket buffer
-        ch.write(genBuffer(), timeout, unit, ch,
-            new CompletionHandler<Integer,AsynchronousSocketChannel>()
-        {
-            public void completed(Integer result, AsynchronousSocketChannel ch) {
-                ch.write(genBuffer(), timeout, unit, ch, this);
-            }
-            public void failed(Throwable exc, AsynchronousSocketChannel ch) {
-                writeException.set(exc);
-            }
-        });
-        if (timeout > 0) {
-            // wait for exception
-            while (writeException.get() == null) {
-                Thread.sleep(100);
-            }
-            if (!(writeException.get() instanceof InterruptedByTimeoutException))
-                throw new RuntimeException("InterruptedByTimeoutException expected");
-
-            // after a timeout then further writing should throw unspecified runtime exception
-            boolean exceptionThrown = false;
-            try {
-                ch.write(genBuffer());
-            } catch (RuntimeException x) {
-                exceptionThrown = true;
-            }
-            if (!exceptionThrown)
-                throw new RuntimeException("RuntimeException expected after timeout.");
-        } else {
-            Thread.sleep(1000);
-            Throwable exc = writeException.get();
-            if (exc != null)
-                throw new RuntimeException(exc);
-        }
-
-        // clean-up
-        server.accept().close();
-        ch.close();
-        server.close();
     }
 
     // returns ByteBuffer with random bytes
diff --git a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Leaky.java b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Leaky.java
index 39b5018..776542b 100644
--- a/jdk/test/java/nio/channels/AsynchronousSocketChannel/Leaky.java
+++ b/jdk/test/java/nio/channels/AsynchronousSocketChannel/Leaky.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -22,9 +22,9 @@
  */
 
 /* @test
- * @bug 4607272 6999915
+ * @bug 4607272 6999915 7185340
  * @summary Unit test for AsynchronousSocketChannel
- * @run main/othervm -XX:+DisableExplicitGC -XX:MaxDirectMemorySize=64m Leaky
+ * @run main/othervm -XX:+DisableExplicitGC -XX:MaxDirectMemorySize=75m Leaky
  */
 
 import java.nio.ByteBuffer;
diff --git a/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java b/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java
index 022455f..1763ef3 100644
--- a/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java
+++ b/jdk/test/java/nio/channels/DatagramChannel/AdaptDatagramSocket.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,29 +27,16 @@
  * @library ..
  */
 
-import java.io.*;
 import java.net.*;
-import java.nio.*;
 import java.nio.channels.*;
-import java.nio.charset.*;
 import java.util.*;
 
 
 public class AdaptDatagramSocket {
 
     static java.io.PrintStream out = System.out;
-
     static Random rand = new Random();
 
-    static final int ECHO_PORT = 7;
-    static final int DISCARD_PORT = 9;
-    static final String REMOTE_HOST = TestUtil.HOST;
-
-    static final InetSocketAddress echoAddress
-        = new InetSocketAddress(REMOTE_HOST, ECHO_PORT);
-    static final InetSocketAddress discardAddress
-        = new InetSocketAddress(REMOTE_HOST, DISCARD_PORT);
-
     static String toString(DatagramPacket dp) {
         return ("DatagramPacket[off=" + dp.getOffset()
                 + ", len=" + dp.getLength()
@@ -88,10 +75,11 @@
         out.println("rtt: " + (System.currentTimeMillis() - start));
         out.println("post op: " + toString(op) + "  ip: " + toString(ip));
 
-        for (int i = 0; i < ip.getLength(); i++)
+        for (int i = 0; i < ip.getLength(); i++) {
             if (ip.getData()[ip.getOffset() + i]
                 != op.getData()[op.getOffset() + i])
                 throw new Exception("Incorrect data received");
+        }
 
         if (!(ip.getSocketAddress().equals(dst))) {
             throw new Exception("Incorrect sender address, expected: " + dst
@@ -130,8 +118,9 @@
             ds.setSoTimeout(timeout);
         out.println("timeout: " + ds.getSoTimeout());
 
-        for (int i = 0; i < 5; i++)
+        for (int i = 0; i < 5; i++) {
             test(ds, dst, shouldTimeout);
+        }
 
         // Leave the socket open so that we don't reuse the old src address
         //ds.close();
@@ -139,10 +128,23 @@
     }
 
     public static void main(String[] args) throws Exception {
-        test(echoAddress, 0, false, false);
-        test(echoAddress, 0, false, true);
-        test(echoAddress, 5000, false, false);
-        test(discardAddress, 10, true, false);
+        // need an UDP echo server
+        try (TestServers.UdpEchoServer echoServer
+                = TestServers.UdpEchoServer.startNewServer(100)) {
+            final InetSocketAddress address
+                = new InetSocketAddress(echoServer.getAddress(),
+                                        echoServer.getPort());
+            test(address, 0, false, false);
+            test(address, 0, false, true);
+            test(address, 5000, false, false);
+        }
+        try (TestServers.UdpDiscardServer discardServer
+                = TestServers.UdpDiscardServer.startNewServer()) {
+            final InetSocketAddress address
+                = new InetSocketAddress(discardServer.getAddress(),
+                                        discardServer.getPort());
+            test(address, 10, true, false);
+        }
     }
 
 }
diff --git a/jdk/test/java/nio/channels/DatagramChannel/Disconnect.java b/jdk/test/java/nio/channels/DatagramChannel/Disconnect.java
new file mode 100644
index 0000000..e5a1d3a
--- /dev/null
+++ b/jdk/test/java/nio/channels/DatagramChannel/Disconnect.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, 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 7132924
+ * @summary Test DatagramChannel.disconnect when DatagramChannel is connected to an IPv4 socket
+ * @run main Disconnect
+ * @run main/othervm -Djava.net.preferIPv4Stack=true Disconnect
+ */
+
+import java.net.*;
+import java.nio.*;
+import java.nio.channels.*;
+import java.io.IOException;
+
+public class Disconnect {
+    public static void main(String[] args) throws IOException {
+        // test with default protocol family
+        try (DatagramChannel dc = DatagramChannel.open()) {
+            test(dc);
+            test(dc);
+        }
+
+        // test with IPv4 only
+        try (DatagramChannel dc = DatagramChannel.open(StandardProtocolFamily.INET)) {
+            test(dc);
+            test(dc);
+        }
+    }
+
+    /**
+     * Connect DatagramChannel to a server, write a datagram and disconnect. Invoke
+     * a second or subsequent time with the same DatagramChannel instance to check
+     * that disconnect works as expected.
+     */
+    static void test(DatagramChannel dc) throws IOException {
+        try (DatagramChannel server = DatagramChannel.open()) {
+            server.bind(new InetSocketAddress(0));
+
+            InetAddress lh = InetAddress.getLocalHost();
+            dc.connect(new InetSocketAddress(lh, server.socket().getLocalPort()));
+
+            dc.write(ByteBuffer.wrap("hello".getBytes()));
+
+            ByteBuffer bb = ByteBuffer.allocate(100);
+            server.receive(bb);
+
+            dc.disconnect();
+
+            try {
+                dc.write(ByteBuffer.wrap("another message".getBytes()));
+                throw new RuntimeException("write should fail, not connected");
+            } catch (NotYetConnectedException expected) {
+            }
+        }
+    }
+}
diff --git a/jdk/test/java/nio/channels/DatagramChannel/IsBound.java b/jdk/test/java/nio/channels/DatagramChannel/IsBound.java
index 6fae668..7a028ec 100644
--- a/jdk/test/java/nio/channels/DatagramChannel/IsBound.java
+++ b/jdk/test/java/nio/channels/DatagramChannel/IsBound.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -34,21 +34,25 @@
 
 public class IsBound {
     public static void main(String argv[]) throws Exception {
-        InetSocketAddress isa = new InetSocketAddress(
-            InetAddress.getByName(TestUtil.HOST), 13);
-        ByteBuffer bb = ByteBuffer.allocateDirect(256);
-        bb.put("hello".getBytes());
-        bb.flip();
+        try (TestServers.UdpDayTimeServer daytimeServer
+                = TestServers.UdpDayTimeServer.startNewServer(100)) {
+            InetSocketAddress isa = new InetSocketAddress(
+                daytimeServer.getAddress(),
+                daytimeServer.getPort());
+            ByteBuffer bb = ByteBuffer.allocateDirect(256);
+            bb.put("hello".getBytes());
+            bb.flip();
 
-        DatagramChannel dc = DatagramChannel.open();
-        dc.send(bb, isa);
-        if(!dc.socket().isBound())
-            throw new Exception("Test failed");
-        dc.close();
+            DatagramChannel dc = DatagramChannel.open();
+            dc.send(bb, isa);
+            if(!dc.socket().isBound())
+                throw new Exception("Test failed");
+            dc.close();
 
-        dc = DatagramChannel.open();
-        if(dc.socket().isBound())
-            throw new Exception("Test failed");
-        dc.close();
+            dc = DatagramChannel.open();
+            if(dc.socket().isBound())
+                throw new Exception("Test failed");
+            dc.close();
+        }
     }
 }
diff --git a/jdk/test/java/nio/channels/DatagramChannel/IsConnected.java b/jdk/test/java/nio/channels/DatagramChannel/IsConnected.java
index f71d869..db4cb89 100644
--- a/jdk/test/java/nio/channels/DatagramChannel/IsConnected.java
+++ b/jdk/test/java/nio/channels/DatagramChannel/IsConnected.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,21 +28,23 @@
  */
 
 import java.net.*;
-import java.nio.*;
 import java.nio.channels.*;
 
 
 public class IsConnected {
     public static void main(String argv[]) throws Exception {
-        InetSocketAddress isa = new InetSocketAddress(
-            InetAddress.getByName(TestUtil.HOST), 13);
-        DatagramChannel dc = DatagramChannel.open();
-        dc.configureBlocking(true);
-        dc.connect(isa);
-        if  (!dc.isConnected())
-            throw new RuntimeException("channel.isConnected inconsistent");
-        if (!dc.socket().isConnected())
-            throw new RuntimeException("socket.isConnected inconsistent");
-        dc.close();
+        try (TestServers.UdpDayTimeServer daytimeServer
+                = TestServers.UdpDayTimeServer.startNewServer(100)) {
+            InetSocketAddress isa = new InetSocketAddress(
+                daytimeServer.getAddress(), daytimeServer.getPort());
+            DatagramChannel dc = DatagramChannel.open();
+            dc.configureBlocking(true);
+            dc.connect(isa);
+            if  (!dc.isConnected())
+                throw new RuntimeException("channel.isConnected inconsistent");
+            if (!dc.socket().isConnected())
+                throw new RuntimeException("socket.isConnected inconsistent");
+            dc.close();
+        }
     }
 }
diff --git a/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java b/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java
index 8e6251d..3591e83 100644
--- a/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java
+++ b/jdk/test/java/nio/channels/DatagramChannel/MulticastSendReceiveTests.java
@@ -22,10 +22,11 @@
  */
 
 /* @test
- * @bug 4527345 7026376
+ * @bug 4527345 7026376 6633549
  * @summary Unit test for DatagramChannel's multicast support
  * @build MulticastSendReceiveTests NetworkConfiguration
  * @run main MulticastSendReceiveTests
+ * @run main/othervm -Djava.net.preferIPv4Stack=true MulticastSendReceiveTests
  */
 
 import java.nio.ByteBuffer;
@@ -186,6 +187,10 @@
                 id = sendDatagram(source, nif, group, port);
                 receiveDatagram(dc, source, id);
             } catch (UnsupportedOperationException x) {
+                String os = System.getProperty("os.name");
+                // Exclude-mode filtering supported on these platforms so UOE should never be thrown
+                if (os.equals("SunOS") || os.equals("Linux"))
+                    throw x;
                 System.out.println("Exclude-mode filtering not supported!");
             }
 
@@ -212,6 +217,10 @@
                 id = sendDatagram(source, nif, group, port);
                 receiveDatagram(dc, source, id);
             } catch (UnsupportedOperationException x) {
+                String os = System.getProperty("os.name");
+                // Include-mode filtering supported on these platforms so UOE should never be thrown
+                if (os.equals("SunOS") || os.equals("Linux"))
+                    throw x;
                 System.out.println("Include-mode filtering not supported!");
             }
         }
diff --git a/jdk/test/java/nio/channels/SelectionKey/RacyRegister.java b/jdk/test/java/nio/channels/SelectionKey/RacyRegister.java
new file mode 100644
index 0000000..d3df102
--- /dev/null
+++ b/jdk/test/java/nio/channels/SelectionKey/RacyRegister.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 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 7132889
+ * @summary Test that register does not return a valid SelectionKey when
+ *    invoked at around the time that the channel is closed
+ */
+
+import java.nio.channels.*;
+import java.util.concurrent.*;
+import java.util.Random;
+import java.io.IOException;
+
+public class RacyRegister {
+
+    public static void main(String[] args) throws Exception {
+        ExecutorService pool = Executors.newFixedThreadPool(1);
+        try (Selector sel = Selector.open()) {
+            int count = 100;
+            while (count-- > 0) {
+                final SocketChannel sc = SocketChannel.open();
+                sc.configureBlocking(false);
+
+                // close channel asynchronously
+                Future<Void> result = pool.submit(new Callable<Void>() {
+                    public Void call() throws IOException {
+                        sc.close();
+                        return null;
+                    }
+                });
+
+                // attempt to register channel with Selector
+                SelectionKey key = null;
+                try {
+                    key = sc.register(sel, SelectionKey.OP_READ);
+                } catch (ClosedChannelException ignore) {
+                }
+
+                // ensure close is done
+                result.get();
+
+                // if we have a key then it should be invalid
+                if (key != null && key.isValid())
+                    throw new RuntimeException("Key is valid");
+            }
+        } finally {
+            pool.shutdown();
+        }
+    }
+}
diff --git a/jdk/test/java/nio/channels/Selector/Alias.java b/jdk/test/java/nio/channels/Selector/Alias.java
index c3554b9..731703b 100644
--- a/jdk/test/java/nio/channels/Selector/Alias.java
+++ b/jdk/test/java/nio/channels/Selector/Alias.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,12 +27,11 @@
  * @library ..
  */
 
-import java.io.*;
 import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
-import java.util.*;
 import java.nio.channels.spi.SelectorProvider;
+import java.util.*;
 
 public class Alias {
 
@@ -40,18 +39,26 @@
     static int LIMIT = 20; // Hangs after just 1 if problem is present
 
     public static void main(String[] args) throws Exception {
-        test1();
+        try (TestServers.DayTimeServer daytimeServer
+                = TestServers.DayTimeServer.startNewServer(100)) {
+            test1(daytimeServer);
+        }
     }
 
-    public static void test1() throws Exception {
+    static void test1(TestServers.DayTimeServer daytimeServer) throws Exception {
         Selector selector = SelectorProvider.provider().openSelector();
-        InetAddress myAddress=InetAddress.getByName(TestUtil.HOST);
-        InetSocketAddress isa = new InetSocketAddress(myAddress,13);
+        InetAddress myAddress = daytimeServer.getAddress();
+        InetSocketAddress isa
+            = new InetSocketAddress(myAddress,
+                                    daytimeServer.getPort());
 
         for (int j=0; j<LIMIT; j++) {
             SocketChannel sc = SocketChannel.open();
             sc.configureBlocking(false);
             boolean result = sc.connect(isa);
+
+            // On some platforms - given that we're using a local server,
+            // we may not enter into the if () { } statement below...
             if (!result) {
                 SelectionKey key = sc.register(selector,
                                                SelectionKey.OP_CONNECT);
diff --git a/jdk/test/java/nio/channels/Selector/BasicConnect.java b/jdk/test/java/nio/channels/Selector/BasicConnect.java
index 61575b1..e440fe7 100644
--- a/jdk/test/java/nio/channels/Selector/BasicConnect.java
+++ b/jdk/test/java/nio/channels/Selector/BasicConnect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,12 +27,10 @@
  * @library ..
  */
 
-import java.io.*;
 import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
 import java.nio.channels.spi.SelectorProvider;
-import java.nio.charset.*;
 import java.util.*;
 
 
@@ -44,52 +42,57 @@
 
 public class BasicConnect {
 
-    static final int PORT = 7;          // echo
-    static final String HOST = TestUtil.HOST;
-
     public static void main(String[] args) throws Exception {
         Selector connectSelector =
             SelectorProvider.provider().openSelector();
-        InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(HOST), PORT);
-        SocketChannel sc = SocketChannel.open();
-        sc.configureBlocking(false);
-        boolean result = sc.connect(isa);
-        while (!result) {
-            SelectionKey connectKey = sc.register(connectSelector,
-                                                  SelectionKey.OP_CONNECT);
-            int keysAdded = connectSelector.select();
-            if (keysAdded > 0) {
-                Set readyKeys = connectSelector.selectedKeys();
-                Iterator i = readyKeys.iterator();
-                while (i.hasNext()) {
-                    SelectionKey sk = (SelectionKey)i.next();
-                    i.remove();
-                    SocketChannel nextReady = (SocketChannel)sk.channel();
-                    result = nextReady.finishConnect();
-                    if (result)
-                        sk.cancel();
+        try (TestServers.EchoServer echoServer
+                = TestServers.EchoServer.startNewServer(100)) {
+            InetSocketAddress isa
+                = new InetSocketAddress(echoServer.getAddress(),
+                                        echoServer.getPort());
+            SocketChannel sc = SocketChannel.open();
+            sc.configureBlocking(false);
+            boolean result = sc.connect(isa);
+            if (result) {
+                System.out.println("Socket immediately connected on "
+                        + System.getProperty("os.name")
+                        + ": " + sc);
+            }
+            while (!result) {
+                SelectionKey connectKey = sc.register(connectSelector,
+                                                      SelectionKey.OP_CONNECT);
+                int keysAdded = connectSelector.select();
+                if (keysAdded > 0) {
+                    Set readyKeys = connectSelector.selectedKeys();
+                    Iterator i = readyKeys.iterator();
+                    while (i.hasNext()) {
+                        SelectionKey sk = (SelectionKey)i.next();
+                        i.remove();
+                        SocketChannel nextReady = (SocketChannel)sk.channel();
+                        result = nextReady.finishConnect();
+                        if (result)
+                            sk.cancel();
+                    }
                 }
             }
+
+            byte[] bs = new byte[] { (byte)0xca, (byte)0xfe,
+                                     (byte)0xba, (byte)0xbe };
+            ByteBuffer bb = ByteBuffer.wrap(bs);
+            sc.configureBlocking(true);
+            sc.write(bb);
+            bb.rewind();
+
+            ByteBuffer bb2 = ByteBuffer.allocateDirect(100);
+            int n = sc.read(bb2);
+            bb2.flip();
+
+            sc.close();
+            connectSelector.close();
+
+            if (!bb.equals(bb2))
+                throw new Exception("Echoed bytes incorrect: Sent "
+                                    + bb + ", got " + bb2);
         }
-
-        byte[] bs = new byte[] { (byte)0xca, (byte)0xfe,
-                                 (byte)0xba, (byte)0xbe };
-        ByteBuffer bb = ByteBuffer.wrap(bs);
-        sc.configureBlocking(true);
-        sc.write(bb);
-        bb.rewind();
-
-        ByteBuffer bb2 = ByteBuffer.allocateDirect(100);
-        int n = sc.read(bb2);
-        bb2.flip();
-
-        sc.close();
-        connectSelector.close();
-
-        if (!bb.equals(bb2))
-            throw new Exception("Echoed bytes incorrect: Sent "
-                                + bb + ", got " + bb2);
     }
-
 }
diff --git a/jdk/test/java/nio/channels/Selector/Connect.java b/jdk/test/java/nio/channels/Selector/Connect.java
index af1ce98..67f48d8 100644
--- a/jdk/test/java/nio/channels/Selector/Connect.java
+++ b/jdk/test/java/nio/channels/Selector/Connect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,12 +27,11 @@
  * @library ..
  */
 
-import java.io.*;
 import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
-import java.util.*;
 import java.nio.channels.spi.SelectorProvider;
+import java.util.*;
 
 public class Connect {
 
@@ -40,12 +39,18 @@
     static int LIMIT = 100;
 
     public static void main(String[] args) throws Exception {
-        scaleTest();
+        try (TestServers.DayTimeServer daytimeServer
+                = TestServers.DayTimeServer.startNewServer(50)) {
+            scaleTest(daytimeServer);
+        }
     }
 
-    public static void scaleTest() throws Exception {
-        InetAddress myAddress=InetAddress.getByName(TestUtil.HOST);
-        InetSocketAddress isa = new InetSocketAddress(myAddress,13);
+    static void scaleTest(TestServers.DayTimeServer daytimeServer)
+        throws Exception
+    {
+        InetAddress myAddress = daytimeServer.getAddress();
+        InetSocketAddress isa
+            = new InetSocketAddress(myAddress, daytimeServer.getPort());
 
         for (int j=0; j<LIMIT; j++) {
             SocketChannel sc = SocketChannel.open();
diff --git a/jdk/test/java/nio/channels/Selector/ConnectWrite.java b/jdk/test/java/nio/channels/Selector/ConnectWrite.java
index 904f3a6..f1ce975 100644
--- a/jdk/test/java/nio/channels/Selector/ConnectWrite.java
+++ b/jdk/test/java/nio/channels/Selector/ConnectWrite.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,23 +27,25 @@
  * @library ..
  */
 
-import java.io.*;
 import java.net.*;
-import java.nio.*;
 import java.nio.channels.*;
-import java.util.*;
 import java.nio.channels.spi.SelectorProvider;
+import java.util.*;
 
 public class ConnectWrite {
 
     public static void main(String[] args) throws Exception {
-        test1(13);
+        try (TestServers.DayTimeServer daytimeServer
+                = TestServers.DayTimeServer.startNewServer(25)) {
+            test1(daytimeServer);
+        }
     }
 
-    public static void test1(int port) throws Exception {
+    static void test1(TestServers.DayTimeServer daytimeServer) throws Exception {
         Selector selector = SelectorProvider.provider().openSelector();
-        InetAddress myAddress=InetAddress.getByName(TestUtil.HOST);
-        InetSocketAddress isa = new InetSocketAddress(myAddress, port);
+        InetAddress myAddress = daytimeServer.getAddress();
+        InetSocketAddress isa
+            = new InetSocketAddress(myAddress, daytimeServer.getPort());
         SocketChannel sc = SocketChannel.open();
         try {
             sc.configureBlocking(false);
diff --git a/jdk/test/java/nio/channels/Selector/KeysReady.java b/jdk/test/java/nio/channels/Selector/KeysReady.java
index ba09a4c..de27aa4a 100644
--- a/jdk/test/java/nio/channels/Selector/KeysReady.java
+++ b/jdk/test/java/nio/channels/Selector/KeysReady.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,21 +28,15 @@
  */
 
 import java.net.*;
-import java.io.*;
-import java.nio.*;
 import java.nio.channels.*;
-import java.nio.charset.*;
 import java.nio.channels.spi.SelectorProvider;
 
 public class KeysReady {
 
-    static final int DAYTIME_PORT = 13;
-    static final String DAYTIME_HOST = TestUtil.HOST;
-
-    static void test() throws Exception {
+    static void test(TestServers.DayTimeServer dayTimeServer) throws Exception {
         InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(DAYTIME_HOST),
-                                    DAYTIME_PORT);
+            = new InetSocketAddress(dayTimeServer.getAddress(),
+                                    dayTimeServer.getPort());
         SocketChannel sc = SocketChannel.open();
         sc.configureBlocking(false);
         sc.connect(isa);
@@ -64,7 +58,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        test();
+        try (TestServers.DayTimeServer daytimeServer
+                = TestServers.DayTimeServer.startNewServer(50)) {
+            test(daytimeServer);
+        }
     }
 
 }
diff --git a/jdk/test/java/nio/channels/Selector/lots_of_updates.sh b/jdk/test/java/nio/channels/Selector/lots_of_updates.sh
index 021d5a4..c484158 100644
--- a/jdk/test/java/nio/channels/Selector/lots_of_updates.sh
+++ b/jdk/test/java/nio/channels/Selector/lots_of_updates.sh
@@ -46,4 +46,4 @@
     ulimit -n 2048
 fi
 
-${TESTJAVA}/bin/java LotsOfUpdates
+${TESTJAVA}/bin/java ${TESTVMOPTS} LotsOfUpdates
diff --git a/jdk/test/java/nio/channels/SocketChannel/AdaptSocket.java b/jdk/test/java/nio/channels/SocketChannel/AdaptSocket.java
index 09c14e2..5979c72 100644
--- a/jdk/test/java/nio/channels/SocketChannel/AdaptSocket.java
+++ b/jdk/test/java/nio/channels/SocketChannel/AdaptSocket.java
@@ -35,19 +35,16 @@
 
     static java.io.PrintStream out = System.out;
 
-    static final int ECHO_PORT = 7;
-    static final int DAYTIME_PORT = 13;
-    static final String REMOTE_HOST = TestUtil.HOST;
-    static final String VERY_REMOTE_HOST = TestUtil.FAR_HOST;
-
-    static void test(String hn, int timeout, boolean shouldTimeout)
+    static void test(TestServers.DayTimeServer dayTimeServer,
+                     int timeout,
+                     boolean shouldTimeout)
         throws Exception
     {
         out.println();
 
         InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(hn),
-                                    DAYTIME_PORT);
+            = new InetSocketAddress(dayTimeServer.getAddress(),
+                                    dayTimeServer.getPort());
         SocketChannel sc = SocketChannel.open();
         Socket so = sc.socket();
         out.println("opened: " + so);
@@ -116,13 +113,16 @@
         }
     }
 
-    static void testRead(String hn, int timeout, boolean shouldTimeout)
+    static void testRead(TestServers.EchoServer echoServer,
+                         int timeout,
+                         boolean shouldTimeout)
         throws Exception
     {
         out.println();
 
         InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(hn), ECHO_PORT);
+            = new InetSocketAddress(echoServer.getAddress(),
+                                    echoServer.getPort());
         SocketChannel sc = SocketChannel.open();
         sc.connect(isa);
         Socket so = sc.socket();
@@ -134,22 +134,38 @@
         out.println("timeout: " + so.getSoTimeout());
 
         testRead(so, shouldTimeout);
-        for (int i = 0; i < 4; i++)
+        for (int i = 0; i < 4; i++) {
             testRead(so, shouldTimeout);
+        }
 
         sc.close();
     }
 
     public static void main(String[] args) throws Exception {
 
-        test(REMOTE_HOST, 0, false);
-        test(REMOTE_HOST, 1000, false);
-        test(VERY_REMOTE_HOST, 10, true);
+        try (TestServers.DayTimeServer dayTimeServer
+                = TestServers.DayTimeServer.startNewServer()) {
+            test(dayTimeServer, 0, false);
+            test(dayTimeServer, 1000, false);
+        }
 
-        testRead(REMOTE_HOST, 0, false);
-        testRead(REMOTE_HOST, 8000, false);
-        testRead(VERY_REMOTE_HOST, 10, true);
+        try (TestServers.DayTimeServer lingerDayTimeServer
+                = TestServers.DayTimeServer.startNewServer(100)) {
+            // this test no longer really test the connection timeout
+            // since there is no way to prevent the server from eagerly
+            // accepting connection...
+            test(lingerDayTimeServer, 10, true);
+        }
 
+        try (TestServers.EchoServer echoServer
+                = TestServers.EchoServer.startNewServer()) {
+            testRead(echoServer, 0, false);
+            testRead(echoServer, 8000, false);
+        }
+
+        try (TestServers.EchoServer lingerEchoServer
+                = TestServers.EchoServer.startNewServer(100)) {
+            testRead(lingerEchoServer, 10, true);
+        }
     }
-
 }
diff --git a/jdk/test/java/nio/channels/SocketChannel/Basic.java b/jdk/test/java/nio/channels/SocketChannel/Basic.java
index 79ea9ce..9cf789f 100644
--- a/jdk/test/java/nio/channels/SocketChannel/Basic.java
+++ b/jdk/test/java/nio/channels/SocketChannel/Basic.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -36,13 +36,10 @@
 
     static java.io.PrintStream out = System.out;
 
-    static final int DAYTIME_PORT = 13;
-    static final String DAYTIME_HOST = TestUtil.HOST;
-
-    static void test() throws Exception {
+    static void test(TestServers.DayTimeServer daytimeServer) throws Exception {
         InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(DAYTIME_HOST),
-                                    DAYTIME_PORT);
+            = new InetSocketAddress(daytimeServer.getAddress(),
+                                    daytimeServer.getPort());
         SocketChannel sc = SocketChannel.open(isa);
         out.println("opened: " + sc);
         /*
@@ -76,7 +73,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        test();
+        try (TestServers.DayTimeServer dayTimeServer
+                = TestServers.DayTimeServer.startNewServer(100)) {
+            test(dayTimeServer);
+        }
     }
 
 }
diff --git a/jdk/test/java/nio/channels/SocketChannel/BufferSize.java b/jdk/test/java/nio/channels/SocketChannel/BufferSize.java
index f7d84bb..736d0e1 100644
--- a/jdk/test/java/nio/channels/SocketChannel/BufferSize.java
+++ b/jdk/test/java/nio/channels/SocketChannel/BufferSize.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,17 +28,10 @@
  */
 
 import java.nio.channels.*;
-import java.net.*;
 
 public class BufferSize {
 
-    static final int DAYTIME_PORT = 13;
-    static final String DAYTIME_HOST = TestUtil.HOST;
-
     public static void main(String[] args) throws Exception {
-        InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(DAYTIME_HOST),
-                                    DAYTIME_PORT);
         ServerSocketChannel sc = ServerSocketChannel.open();
         try {
             sc.socket().setReceiveBufferSize(-1);
diff --git a/jdk/test/java/nio/channels/SocketChannel/Connect.java b/jdk/test/java/nio/channels/SocketChannel/Connect.java
index 260bf53..76a32e7 100644
--- a/jdk/test/java/nio/channels/SocketChannel/Connect.java
+++ b/jdk/test/java/nio/channels/SocketChannel/Connect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,9 @@
  * @library ..
  */
 
+import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
-import java.net.*;
 import java.util.*;
 
 public class Connect {
@@ -37,21 +37,26 @@
     private static final long INCREMENTAL_DELAY = 30L * 1000L;
 
     public static void main(String args[]) throws Exception {
-        test1(TestUtil.HOST);
+        try (TestServers.EchoServer echoServer
+                = TestServers.EchoServer.startNewServer(1000)) {
+            test1(echoServer);
+        }
         try {
-            test1(TestUtil.REFUSING_HOST);
+            TestServers.RefusingServer refusingServer
+                = TestServers.RefusingServer.startNewServer();
+            test1(refusingServer);
             throw new Exception("Refused connection throws no exception");
         } catch (ConnectException ce) {
             // Correct result
         }
     }
 
-    static void test1(String hostname) throws Exception {
+    static void test1(TestServers.AbstractServer server) throws Exception {
         Selector selector;
         SocketChannel sc;
         SelectionKey sk;
         InetSocketAddress isa = new InetSocketAddress(
-            InetAddress.getByName (hostname), 80);
+            server.getAddress(), server.getPort());
         sc = SocketChannel.open();
         sc.configureBlocking(false);
 
diff --git a/jdk/test/java/nio/channels/SocketChannel/ConnectState.java b/jdk/test/java/nio/channels/SocketChannel/ConnectState.java
index 9c86d96..df7d0cd 100644
--- a/jdk/test/java/nio/channels/SocketChannel/ConnectState.java
+++ b/jdk/test/java/nio/channels/SocketChannel/ConnectState.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,20 +30,39 @@
 import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
 
 
 public class ConnectState {
 
     static PrintStream log = System.err;
 
-    static String REMOTE_HOST = TestUtil.HOST;
-    static int REMOTE_PORT = 7;                         // echo
     static InetSocketAddress remote;
 
     final static int ST_UNCONNECTED = 0;
     final static int ST_PENDING = 1;
     final static int ST_CONNECTED = 2;
     final static int ST_CLOSED = 3;
+    final static int ST_PENDING_OR_CONNECTED = 4;
+    // NO exceptions expected
+    final static Collection<Class<?>> NONE = Collections.emptySet();
+
+    // make a set of expected exception.
+    static Collection<Class<?>> expectedExceptions(Class<?>... expected) {
+        final Collection<Class<?>> exceptions;
+        if (expected.length == 0) {
+            exceptions = NONE;
+        } else if (expected.length == 1) {
+            assert expected[0] != null;
+            exceptions = Collections.<Class<?>>singleton(expected[0]);
+        } else {
+            exceptions = new HashSet<>(Arrays.asList(expected));
+        }
+        return exceptions;
+    }
 
     static abstract class Test {
 
@@ -76,37 +95,65 @@
                 check(!sc.isConnectionPending(), "!isConnectionPending");
                 check(sc.isOpen(), "isOpen");
                 break;
+            case ST_PENDING_OR_CONNECTED:
+                check(sc.isConnected() || sc.isConnectionPending(),
+                        "isConnected || isConnectionPending");
+                check(sc.isOpen(), "isOpen");
+                break;
             }
         }
 
-        Test(String name, Class exception, int state) throws Exception {
+        Test(String name, Class<?> exception, int state) throws Exception {
+            this(name, expectedExceptions(exception), state);
+        }
+
+        // On some architecture we may need to accept several exceptions.
+        // For instance on Solaris, when using a server colocated on the
+        // machine we cannot guarantee that we will get a
+        // ConnectionPendingException when connecting twice on the same
+        // non-blocking socket. We may instead get a an
+        // AlreadyConnectedException, which is also valid: it simply means
+        // that the first connection has been immediately accepted.
+        Test(String name, Collection<Class<?>> exceptions, int state)
+                throws Exception {
             SocketChannel sc = SocketChannel.open();
-            String note = null;
+            String note;
             try {
                 try {
                     note = go(sc);
                 } catch (Exception x) {
-                    if (exception != null) {
+                    Class<?> expectedExceptionClass = null;
+                    for (Class<?> exception : exceptions) {
                         if (exception.isInstance(x)) {
                             log.println(name + ": As expected: "
                                         + x);
+                            expectedExceptionClass = exception;
                             check(sc, state);
-                            return;
-                        } else {
-                            throw new Exception(name
+                            break;
+                        }
+                    }
+                    if (expectedExceptionClass == null
+                            && !exceptions.isEmpty()) {
+                        // we had an exception, but it's not of the set of
+                        // exceptions we expected.
+                        throw new Exception(name
                                                 + ": Incorrect exception",
                                                 x);
-                        }
-                    } else {
+                    } else if (exceptions.isEmpty()) {
+                        // we didn't expect any exception
                         throw new Exception(name
                                             + ": Unexpected exception",
                                             x);
                     }
+                    // if we reach here, we have our expected exception
+                    assert expectedExceptionClass != null;
+                    return;
                 }
-                if (exception != null)
+                if (!exceptions.isEmpty()) {
                     throw new Exception(name
                                         + ": Expected exception not thrown: "
-                                        + exception);
+                                        + exceptions.iterator().next());
+                }
                 check(sc, state);
                 log.println(name + ": Returned normally"
                             + ((note != null) ? ": " + note : ""));
@@ -123,6 +170,7 @@
 
         new Test("Read unconnected", NotYetConnectedException.class,
                  ST_UNCONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     ByteBuffer b = ByteBuffer.allocateDirect(1024);
                     sc.read(b);
@@ -131,19 +179,22 @@
 
         new Test("Write unconnected", NotYetConnectedException.class,
                  ST_UNCONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     ByteBuffer b = ByteBuffer.allocateDirect(1024);
                     sc.write(b);
                     return null;
                 }};
 
-        new Test("Simple connect", null, ST_CONNECTED) {
+        new Test("Simple connect", NONE, ST_CONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     sc.connect(remote);
                     return null;
                 }};
 
-        new Test("Simple connect & finish", null, ST_CONNECTED) {
+        new Test("Simple connect & finish", NONE, ST_CONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     sc.connect(remote);
                     if (!sc.finishConnect())
@@ -153,6 +204,7 @@
 
         new Test("Double connect",
                  AlreadyConnectedException.class, ST_CONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     sc.connect(remote);
                     sc.connect(remote);
@@ -161,12 +213,16 @@
 
         new Test("Finish w/o start",
                  NoConnectionPendingException.class, ST_UNCONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     sc.finishConnect();
                     return null;
                 }};
 
-        new Test("NB simple connect", null, ST_CONNECTED) {
+        // Note: using our local EchoServer rather than echo on a distant
+        //       host - we see that Tries to finish = 0 (instead of ~ 18).
+        new Test("NB simple connect", NONE, ST_CONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     sc.configureBlocking(false);
                     sc.connect(remote);
@@ -179,8 +235,15 @@
                     return ("Tries to finish = " + n);
                 }};
 
+        // Note: using our local EchoServer rather than echo on a distant
+        //       host - we cannot guarantee that this test will get a
+        //       a ConnectionPendingException: it may get an
+        //       AlreadyConnectedException, so we should allow for both.
         new Test("NB double connect",
-                 ConnectionPendingException.class, ST_PENDING) {
+                 expectedExceptions(ConnectionPendingException.class,
+                                    AlreadyConnectedException.class),
+                 ST_PENDING_OR_CONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     sc.configureBlocking(false);
                     sc.connect(remote);
@@ -190,13 +253,15 @@
 
         new Test("NB finish w/o start",
                  NoConnectionPendingException.class, ST_UNCONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     sc.configureBlocking(false);
                     sc.finishConnect();
                     return null;
                 }};
 
-        new Test("NB connect, B finish", null, ST_CONNECTED) {
+        new Test("NB connect, B finish", NONE, ST_CONNECTED) {
+                @Override
                 String go(SocketChannel sc) throws Exception {
                     sc.configureBlocking(false);
                     sc.connect(remote);
@@ -208,9 +273,12 @@
     }
 
     public static void main(String[] args) throws Exception {
-        remote = new InetSocketAddress(InetAddress.getByName(REMOTE_HOST),
-                                       REMOTE_PORT);
-        tests();
+        try (TestServers.EchoServer echoServer
+                = TestServers.EchoServer.startNewServer(500)) {
+            remote = new InetSocketAddress(echoServer.getAddress(),
+                                           echoServer.getPort());
+            tests();
+        }
     }
 
 }
diff --git a/jdk/test/java/nio/channels/SocketChannel/FinishConnect.java b/jdk/test/java/nio/channels/SocketChannel/FinishConnect.java
index 3d53c98..efcf38a 100644
--- a/jdk/test/java/nio/channels/SocketChannel/FinishConnect.java
+++ b/jdk/test/java/nio/channels/SocketChannel/FinishConnect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -36,21 +36,25 @@
 
 public class FinishConnect {
 
-    static final int DAYTIME_PORT = 13;
-    static final String DAYTIME_HOST = TestUtil.HOST;
-
     public static void main(String[] args) throws Exception {
-        test1(true, true);
-        test1(true, false);
-        test1(false, true);
-        test1(false, false);
-        test2();
+        try (TestServers.DayTimeServer dayTimeServer
+                = TestServers.DayTimeServer.startNewServer(100)) {
+            test1(dayTimeServer, true, true);
+            test1(dayTimeServer, true, false);
+            test1(dayTimeServer, false, true);
+            test1(dayTimeServer, false, false);
+            test2(dayTimeServer);
+        }
     }
 
-    static void test1(boolean select, boolean setBlocking) throws Exception {
+    static void test1(TestServers.DayTimeServer daytimeServer,
+                      boolean select,
+                      boolean setBlocking)
+        throws Exception
+    {
         InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(DAYTIME_HOST),
-                                    DAYTIME_PORT);
+            = new InetSocketAddress(daytimeServer.getAddress(),
+                                    daytimeServer.getPort());
         SocketChannel sc = SocketChannel.open();
         sc.configureBlocking(false);
         boolean connected = sc.connect(isa);
@@ -109,15 +113,27 @@
         sc.close();
     }
 
-    static void test2() throws Exception {
+    static void test2(TestServers.DayTimeServer daytimeServer) throws Exception {
         InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(DAYTIME_HOST),
-                                    DAYTIME_PORT);
+            = new InetSocketAddress(daytimeServer.getAddress(),
+                                    daytimeServer.getPort());
         boolean done = false;
         int globalAttempts = 0;
+        int connectSuccess = 0;
         while (!done) {
-            if (globalAttempts++ > 50)
+            // When using a local daytime server it is not always possible
+            // to get a pending connection, as sc.connect(isa) may always
+            // return true.
+            // So we're going to throw the exception only if there was
+            // at least 1 case where we did not manage to connect.
+            if (globalAttempts++ > 50) {
+                if (globalAttempts == connectSuccess + 1) {
+                    System.out.println("Can't fully test on "
+                            + System.getProperty("os.name"));
+                    break;
+                }
                 throw new RuntimeException("Failed to connect");
+            }
             SocketChannel sc = SocketChannel.open();
             sc.configureBlocking(false);
             boolean connected = sc.connect(isa);
@@ -132,6 +148,9 @@
                 }
                 Thread.sleep(10);
             }
+            if (connected) {
+                connectSuccess++;
+            }
             sc.close();
         }
     }
diff --git a/jdk/test/java/nio/channels/SocketChannel/IsConnectable.java b/jdk/test/java/nio/channels/SocketChannel/IsConnectable.java
index d646d19..21bdd80 100644
--- a/jdk/test/java/nio/channels/SocketChannel/IsConnectable.java
+++ b/jdk/test/java/nio/channels/SocketChannel/IsConnectable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,24 +28,19 @@
  */
 
 import java.net.*;
-import java.io.*;
-import java.nio.*;
 import java.nio.channels.*;
 import java.nio.channels.spi.SelectorProvider;
 import java.util.*;
 
 public class IsConnectable {
 
-    static final int DAYTIME_PORT = 13;
-    static final String DAYTIME_HOST = TestUtil.HOST;
-
-    static void test() throws Exception {
+    static void test(TestServers.DayTimeServer daytimeServer) throws Exception {
         InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(DAYTIME_HOST),
-                                    DAYTIME_PORT);
+            = new InetSocketAddress(daytimeServer.getAddress(),
+                                    daytimeServer.getPort());
         SocketChannel sc = SocketChannel.open();
         sc.configureBlocking(false);
-        sc.connect(isa);
+        final boolean immediatelyConnected = sc.connect(isa);
 
         Selector selector = SelectorProvider.provider().openSelector();
         try {
@@ -67,7 +62,12 @@
                         throw new Exception("Test failed: 4737146 detected");
                 }
             } else {
-                throw new Exception("Select failed");
+                if (!immediatelyConnected) {
+                    throw new Exception("Select failed");
+                } else {
+                    System.out.println("IsConnectable couldn't be fully tested for "
+                            + System.getProperty("os.name"));
+                }
             }
         } finally {
             sc.close();
@@ -76,7 +76,10 @@
     }
 
     public static void main(String[] args) throws Exception {
-        test();
+        try (TestServers.DayTimeServer daytimeServer
+                = TestServers.DayTimeServer.startNewServer(100)) {
+            test(daytimeServer);
+        }
     }
 
 }
diff --git a/jdk/test/java/nio/channels/SocketChannel/LocalAddress.java b/jdk/test/java/nio/channels/SocketChannel/LocalAddress.java
index 1bcd0a1..03a0382 100644
--- a/jdk/test/java/nio/channels/SocketChannel/LocalAddress.java
+++ b/jdk/test/java/nio/channels/SocketChannel/LocalAddress.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,18 +28,20 @@
  */
 
 import java.net.*;
-import java.nio.*;
 import java.nio.channels.*;
 
 public class LocalAddress {
     public static void main(String[] args) throws Exception {
-        test1();
+        try (TestServers.EchoServer echoServer
+                = TestServers.EchoServer.startNewServer()) {
+            test1(echoServer);
+        }
     }
 
-    static void test1() throws Exception {
+    static void test1(TestServers.AbstractServer server) throws Exception {
         InetAddress bogus = InetAddress.getByName("0.0.0.0");
         InetSocketAddress saddr = new InetSocketAddress(
-            InetAddress.getByName(TestUtil.HOST), 23);
+            server.getAddress(), server.getPort());
 
         //Test1: connect only
         SocketChannel sc = SocketChannel.open();
diff --git a/jdk/test/java/nio/channels/SocketChannel/Open.sh b/jdk/test/java/nio/channels/SocketChannel/Open.sh
index cb90696..013f8a1 100644
--- a/jdk/test/java/nio/channels/SocketChannel/Open.sh
+++ b/jdk/test/java/nio/channels/SocketChannel/Open.sh
@@ -29,7 +29,7 @@
     case "$OS" in
         SunOS )
             ulimit -n 100
-            $TESTJAVA/bin/java -classpath $TESTCLASSES Open ;;
+            $TESTJAVA/bin/java ${TESTVMOPTS} -classpath $TESTCLASSES Open ;;
         * )
             echo "unrecognized system: $OS" ;;
     esac
diff --git a/jdk/test/java/nio/channels/SocketChannel/Stream.java b/jdk/test/java/nio/channels/SocketChannel/Stream.java
index 456363f..fadf0dc 100644
--- a/jdk/test/java/nio/channels/SocketChannel/Stream.java
+++ b/jdk/test/java/nio/channels/SocketChannel/Stream.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,22 +27,17 @@
  * @library ..
  */
 
-import java.net.*;
 import java.io.*;
-import java.nio.*;
+import java.net.*;
 import java.nio.channels.*;
-import java.nio.charset.*;
 
 
 public class Stream {
 
-    static final int DAYTIME_PORT = 13;
-    static final String DAYTIME_HOST = TestUtil.HOST;
-
-    static void test() throws Exception {
+    static void test(TestServers.DayTimeServer daytimeServer) throws Exception {
         InetSocketAddress isa
-            = new InetSocketAddress(InetAddress.getByName(DAYTIME_HOST),
-                                    DAYTIME_PORT);
+            = new InetSocketAddress(daytimeServer.getAddress(),
+                                    daytimeServer.getPort());
         SocketChannel sc = SocketChannel.open();
         sc.connect(isa);
         sc.configureBlocking(false);
@@ -58,7 +53,9 @@
     }
 
     public static void main(String[] args) throws Exception {
-        test();
+        try (TestServers.DayTimeServer dayTimeServer
+                = TestServers.DayTimeServer.startNewServer(100)) {
+            test(dayTimeServer);
+        }
     }
-
 }
diff --git a/jdk/test/java/nio/channels/SocketChannel/VectorParams.java b/jdk/test/java/nio/channels/SocketChannel/VectorParams.java
index 9696927..f90867f 100644
--- a/jdk/test/java/nio/channels/SocketChannel/VectorParams.java
+++ b/jdk/test/java/nio/channels/SocketChannel/VectorParams.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,31 +27,31 @@
  * @library ..
  */
 
-import java.net.*;
 import java.io.*;
+import java.net.*;
 import java.nio.*;
 import java.nio.channels.*;
-import java.nio.charset.*;
 
 public class VectorParams {
 
     static java.io.PrintStream out = System.out;
 
-    static final int DAYTIME_PORT = 13;
-    static final String DAYTIME_HOST = TestUtil.HOST;
     static final int testSize = 10;
     static ByteBuffer[] bufs = null;
     static InetSocketAddress isa = null;
 
     public static void main(String[] args) throws Exception {
-        initBufs();
-        testSocketChannelVectorParams();
-        testDatagramChannelVectorParams();
-        testPipeVectorParams();
-        testFileVectorParams();
+        try (TestServers.DayTimeServer daytimeServer
+                = TestServers.DayTimeServer.startNewServer(100)) {
+            initBufs(daytimeServer);
+            testSocketChannelVectorParams();
+            testDatagramChannelVectorParams();
+            testPipeVectorParams();
+            testFileVectorParams();
+        }
     }
 
-    static void initBufs() throws Exception {
+    static void initBufs(TestServers.DayTimeServer daytimeServer) throws Exception {
         bufs = new ByteBuffer[testSize];
         for(int i=0; i<testSize; i++) {
             String source = "buffer" + i;
@@ -59,8 +59,8 @@
             bufs[i].put(source.getBytes("8859_1"));
             bufs[i].flip();
         }
-        isa =  new InetSocketAddress(InetAddress.getByName(DAYTIME_HOST),
-                                    DAYTIME_PORT);
+        isa = new InetSocketAddress(daytimeServer.getAddress(),
+                                    daytimeServer.getPort());
     }
 
     static void testSocketChannelVectorParams() throws Exception {
diff --git a/jdk/test/java/nio/channels/TestServers.java b/jdk/test/java/nio/channels/TestServers.java
new file mode 100644
index 0000000..22d4523
--- /dev/null
+++ b/jdk/test/java/nio/channels/TestServers.java
@@ -0,0 +1,849 @@
+/*
+ * Copyright (c) 2012, 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 utility classes
+ *
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+
+
+public class TestServers {
+
+    private TestServers() { }
+
+    /**
+     * An abstract server identifies a server which listens on a port on on a
+     * given machine.
+     */
+    static abstract class AbstractServer {
+
+        private AbstractServer() {
+        }
+
+        public abstract int getPort();
+
+        public abstract InetAddress getAddress();
+    }
+
+    /**
+     * A downgraded type of AbstractServer which will refuse connections. Note:
+     * use it once and throw it away - this implementation opens an anonymous
+     * socket and closes it, returning the address of the closed socket. If
+     * other servers are started afterwards, the address/port might get reused
+     * and become connectable again - so it's not a good idea to assume that
+     * connections using this address/port will always be refused. Connections
+     * will be refused as long as the address/port of the refusing server has
+     * not been reused.
+     */
+    static class RefusingServer extends AbstractServer {
+
+        final InetAddress address;
+        final int port;
+
+        private RefusingServer(InetAddress address, int port) {
+            this.address = address;
+            this.port = port;
+        }
+
+        @Override
+        public int getPort() {
+            return port;
+        }
+
+        @Override
+        public InetAddress getAddress() {
+            return address;
+        }
+
+        public static RefusingServer startNewServer() throws IOException {
+            ServerSocket socket = new ServerSocket(0, 100,
+                    InetAddress.getLocalHost());
+            RefusingServer server = new RefusingServer(socket.getInetAddress(),
+                    socket.getLocalPort());
+            socket.close();
+            return server;
+        }
+    }
+
+    /**
+     * An abstract class for implementing small TCP servers for the nio tests
+     * purposes. Disclaimer: This is a naive implementation that uses the old
+     * networking APIs (not those from {@code java.nio.*}) and shamelessly
+     * extends/creates Threads instead of using an executor service.
+     */
+    static abstract class AbstractTcpServer extends AbstractServer
+            implements Runnable, Closeable {
+
+        protected final long linger; // #of ms to wait before responding
+        private Thread acceptThread; // thread waiting for accept
+        // list of opened connections that should be closed on close.
+        private List<TcpConnectionThread> connections = new ArrayList<>();
+        private ServerSocket serverSocket; // the server socket
+        private boolean started = false; // whether the server is started
+        Throwable error = null;
+
+        /**
+         * Creates a new abstract TCP server.
+         *
+         * @param linger the amount of time the server should wait before
+         * responding to requests.
+         */
+        protected AbstractTcpServer(long linger) {
+            this.linger = linger;
+        }
+
+        /**
+         * The local port to which the server is bound.
+         *
+         * @return The local port to which the server is bound.
+         * @exception IllegalStateException is thrown if the server is not
+         * started.
+         */
+        @Override
+        public final synchronized int getPort() {
+            if (!started) {
+                throw new IllegalStateException("Not started");
+            }
+            return serverSocket.getLocalPort();
+        }
+
+        /**
+         * The local address to which the server is bound.
+         *
+         * @return The local address to which the server is bound.
+         * @exception IllegalStateException is thrown if the server is not
+         * started.
+         */
+        @Override
+        public final synchronized InetAddress getAddress() {
+            if (!started) {
+                throw new IllegalStateException("Not started");
+            }
+            return serverSocket.getInetAddress();
+        }
+
+        /**
+         * Tells whether the server is started.
+         *
+         * @return true if the server is started.
+         */
+        public final synchronized boolean isStarted() {
+            return started;
+        }
+
+        /**
+         * Creates a new server socket.
+         *
+         * @param port local port to bind to.
+         * @param backlog requested maximum length of the queue of incoming
+         * connections.
+         * @param address local address to bind to.
+         * @return a new bound server socket ready to accept connections.
+         * @throws IOException if the socket cannot be created or bound.
+         */
+        protected ServerSocket newServerSocket(int port, int backlog,
+                InetAddress address)
+                throws IOException {
+            return new ServerSocket(port, backlog, address);
+        }
+
+        /**
+         * Starts listening for connections.
+         *
+         * @throws IOException if the server socket cannot be created or bound.
+         */
+        public final synchronized void start() throws IOException {
+            if (started) {
+                return;
+            }
+            final ServerSocket socket =
+                    newServerSocket(0, 100, InetAddress.getLocalHost());
+            serverSocket = socket;
+            acceptThread = new Thread(this);
+            acceptThread.setDaemon(true);
+            acceptThread.start();
+            started = true;
+        }
+
+        /**
+         * Calls {@code Thread.sleep(linger);}
+         */
+        protected final void lingerIfRequired() {
+            if (linger > 0) {
+                try {
+                    Thread.sleep(linger);
+                } catch (InterruptedException x) {
+                    Thread.interrupted();
+                    final ServerSocket socket = serverSocket();
+                    if (socket != null && !socket.isClosed()) {
+                        System.err.println("Thread interrupted...");
+                    }
+                }
+            }
+        }
+
+        final synchronized ServerSocket serverSocket() {
+            return this.serverSocket;
+        }
+
+        /**
+         * The main accept loop.
+         */
+        @Override
+        public final void run() {
+            final ServerSocket sSocket = serverSocket();
+            try {
+                Socket s;
+                while (isStarted() && !Thread.interrupted()
+                        && (s = sSocket.accept()) != null) {
+                    lingerIfRequired();
+                    listen(s);
+                }
+            } catch (Exception x) {
+                error = x;
+            } finally {
+                synchronized (this) {
+                    if (!sSocket.isClosed()) {
+                        try {
+                            sSocket.close();
+                        } catch (IOException x) {
+                            System.err.println("Failed to close server socket");
+                        }
+                    }
+                    if (started && this.serverSocket == sSocket) {
+                        started = false;
+                        this.serverSocket = null;
+                        this.acceptThread = null;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Represents a connection accepted by the server.
+         */
+        protected abstract class TcpConnectionThread extends Thread {
+
+            protected final Socket socket;
+
+            protected TcpConnectionThread(Socket socket) {
+                this.socket = socket;
+                this.setDaemon(true);
+            }
+
+            public void close() throws IOException {
+                socket.close();
+                interrupt();
+            }
+        }
+
+        /**
+         * Creates a new TcpConnnectionThread to handle the connection through
+         * an accepted socket.
+         *
+         * @param s the socket returned by {@code serverSocket.accept()}.
+         * @return a new TcpConnnectionThread to handle the connection through
+         * an accepted socket.
+         */
+        protected abstract TcpConnectionThread createConnection(Socket s);
+
+        /**
+         * Creates and starts a new TcpConnectionThread to handle the accepted
+         * socket.
+         *
+         * @param s the socket returned by {@code serverSocket.accept()}.
+         */
+        private synchronized void listen(Socket s) {
+            TcpConnectionThread c = createConnection(s);
+            c.start();
+            addConnection(c);
+        }
+
+        /**
+         * Add the connection to the list of accepted connections.
+         *
+         * @param connection an accepted connection.
+         */
+        protected synchronized void addConnection(
+                TcpConnectionThread connection) {
+            connections.add(connection);
+        }
+
+        /**
+         * Remove the connection from the list of accepted connections.
+         *
+         * @param connection an accepted connection.
+         */
+        protected synchronized void removeConnection(
+                TcpConnectionThread connection) {
+            connections.remove(connection);
+        }
+
+        /**
+         * Close the server socket and all the connections present in the list
+         * of accepted connections.
+         *
+         * @throws IOException
+         */
+        @Override
+        public synchronized void close() throws IOException {
+            if (serverSocket != null && !serverSocket.isClosed()) {
+                serverSocket.close();
+            }
+            if (acceptThread != null) {
+                acceptThread.interrupt();
+            }
+            int failed = 0;
+            for (TcpConnectionThread c : connections) {
+                try {
+                    c.close();
+                } catch (IOException x) {
+                    // no matter - we're closing.
+                    failed++;
+                }
+            }
+            connections.clear();
+            if (failed > 0) {
+                throw new IOException("Failed to close some connections");
+            }
+        }
+    }
+
+    /**
+     * A small TCP Server that emulates the echo service for tests purposes. See
+     * http://en.wikipedia.org/wiki/Echo_Protocol This server uses an anonymous
+     * port - NOT the standard port 7. We don't guarantee that its behavior
+     * exactly matches the RFC - the only purpose of this server is to have
+     * something that responds to nio tests...
+     */
+    static final class EchoServer extends AbstractTcpServer {
+
+        public EchoServer() {
+            this(0L);
+        }
+
+        public EchoServer(long linger) {
+            super(linger);
+        }
+
+        @Override
+        protected TcpConnectionThread createConnection(Socket s) {
+            return new EchoConnection(s);
+        }
+
+        private final class EchoConnection extends TcpConnectionThread {
+
+            public EchoConnection(Socket socket) {
+                super(socket);
+            }
+
+            @Override
+            public void run() {
+                try {
+                    final InputStream is = socket.getInputStream();
+                    final OutputStream out = socket.getOutputStream();
+                    byte[] b = new byte[255];
+                    int n;
+                    while ((n = is.read(b)) > 0) {
+                        lingerIfRequired();
+                        out.write(b, 0, n);
+                    }
+                } catch (IOException io) {
+                    // fall through to finally
+                } finally {
+                    if (!socket.isClosed()) {
+                        try {
+                            socket.close();
+                        } catch (IOException x) {
+                            System.err.println(
+                                    "Failed to close echo connection socket");
+                        }
+                    }
+                    removeConnection(this);
+                }
+            }
+        }
+
+        public static EchoServer startNewServer() throws IOException {
+            return startNewServer(0);
+        }
+
+        public static EchoServer startNewServer(long linger) throws IOException {
+            final EchoServer echoServer = new EchoServer(linger);
+            echoServer.start();
+            return echoServer;
+        }
+    }
+
+    /**
+     * A small TCP server that emulates the Day & Time service for tests
+     * purposes. See http://en.wikipedia.org/wiki/Daytime_Protocol This server
+     * uses an anonymous port - NOT the standard port 13. We don't guarantee
+     * that its behavior exactly matches the RFC - the only purpose of this
+     * server is to have something that responds to nio tests...
+     */
+    static final class DayTimeServer extends AbstractTcpServer {
+
+        public DayTimeServer() {
+            this(0L);
+        }
+
+        public DayTimeServer(long linger) {
+            super(linger);
+        }
+
+        @Override
+        protected TcpConnectionThread createConnection(Socket s) {
+            return new DayTimeServerConnection(s);
+        }
+
+        @Override
+        protected void addConnection(TcpConnectionThread connection) {
+            // do nothing - the connection just write the date and terminates.
+        }
+
+        @Override
+        protected void removeConnection(TcpConnectionThread connection) {
+            // do nothing - we're not adding connections to the list...
+        }
+
+        private final class DayTimeServerConnection extends TcpConnectionThread {
+
+            public DayTimeServerConnection(Socket socket) {
+                super(socket);
+            }
+
+            @Override
+            public void run() {
+                try {
+                    final OutputStream out = socket.getOutputStream();
+                    lingerIfRequired();
+                    out.write(new Date(System.currentTimeMillis())
+                            .toString().getBytes("US-ASCII"));
+                    out.flush();
+                } catch (IOException io) {
+                    // fall through to finally
+                } finally {
+                    if (!socket.isClosed()) {
+                        try {
+                            socket.close();
+                        } catch (IOException x) {
+                            System.err.println(
+                                    "Failed to close echo connection socket");
+                        }
+                    }
+                }
+            }
+        }
+
+        public static DayTimeServer startNewServer()
+                throws IOException {
+            return startNewServer(0);
+        }
+
+        public static DayTimeServer startNewServer(long linger)
+                throws IOException {
+            final DayTimeServer daytimeServer = new DayTimeServer(linger);
+            daytimeServer.start();
+            return daytimeServer;
+        }
+    }
+
+    /**
+     * An abstract class for implementing small UDP Servers for the nio tests
+     * purposes. Disclaimer: This is a naive implementation that uses the old
+     * networking APIs (not those from {@code java.nio.*}) and shamelessly
+     * extends/creates Threads instead of using an executor service.
+     */
+    static abstract class AbstractUdpServer extends AbstractServer
+            implements Runnable, Closeable {
+
+        protected final long linger; // #of ms to wait before responding
+        private Thread acceptThread; // thread waiting for packets
+        private DatagramSocket serverSocket; // the server socket
+        private boolean started = false; // whether the server is started
+        Throwable error = null;
+
+        /**
+         * Creates a new abstract UDP server.
+         *
+         * @param linger the amount of time the server should wait before
+         * responding to requests.
+         */
+        protected AbstractUdpServer(long linger) {
+            this.linger = linger;
+        }
+
+        /**
+         * The local port to which the server is bound.
+         *
+         * @return The local port to which the server is bound.
+         * @exception IllegalStateException is thrown if the server is not
+         * started.
+         */
+        @Override
+        public final synchronized int getPort() {
+            if (!started) {
+                throw new IllegalStateException("Not started");
+            }
+            return serverSocket.getLocalPort();
+        }
+
+        /**
+         * The local address to which the server is bound.
+         *
+         * @return The local address to which the server is bound.
+         * @exception IllegalStateException is thrown if the server is not
+         * started.
+         */
+        @Override
+        public final synchronized InetAddress getAddress() {
+            if (!started) {
+                throw new IllegalStateException("Not started");
+            }
+            return serverSocket.getLocalAddress();
+        }
+
+        /**
+         * Tells whether the server is started.
+         *
+         * @return true if the server is started.
+         */
+        public final synchronized boolean isStarted() {
+            return started;
+        }
+
+        /**
+         * Creates a new datagram socket.
+         *
+         * @param port local port to bind to.
+         * @param address local address to bind to.
+         * @return a new bound server socket ready to listen for packets.
+         * @throws IOException if the socket cannot be created or bound.
+         */
+        protected DatagramSocket newDatagramSocket(int port,
+                InetAddress address)
+                throws IOException {
+            return new DatagramSocket(port, address);
+        }
+
+        /**
+         * Starts listening for connections.
+         *
+         * @throws IOException if the server socket cannot be created or bound.
+         */
+        public final synchronized void start() throws IOException {
+            if (started) {
+                return;
+            }
+            final DatagramSocket socket =
+                    newDatagramSocket(0, InetAddress.getLocalHost());
+            serverSocket = socket;
+            acceptThread = new Thread(this);
+            acceptThread.setDaemon(true);
+            acceptThread.start();
+            started = true;
+        }
+
+        /**
+         * Calls {@code Thread.sleep(linger);}
+         */
+        protected final void lingerIfRequired() {
+            if (linger > 0) {
+                try {
+                    Thread.sleep(linger);
+                } catch (InterruptedException x) {
+                    Thread.interrupted();
+                    final DatagramSocket socket = serverSocket();
+                    if (socket != null && !socket.isClosed()) {
+                        System.err.println("Thread interrupted...");
+                    }
+                }
+            }
+        }
+
+        final synchronized DatagramSocket serverSocket() {
+            return this.serverSocket;
+        }
+
+        final synchronized boolean send(DatagramSocket socket,
+                DatagramPacket response) throws IOException {
+            if (!socket.isClosed()) {
+                socket.send(response);
+                return true;
+            } else {
+                return false;
+            }
+        }
+
+        /**
+         * The main receive loop.
+         */
+        @Override
+        public final void run() {
+            final DatagramSocket sSocket = serverSocket();
+            try {
+                final int size = Math.max(1024, sSocket.getReceiveBufferSize());
+                if (size > sSocket.getReceiveBufferSize()) {
+                    sSocket.setReceiveBufferSize(size);
+                }
+                while (isStarted() && !Thread.interrupted() && !sSocket.isClosed()) {
+                    final byte[] buf = new byte[size];
+                    final DatagramPacket packet =
+                            new DatagramPacket(buf, buf.length);
+                    lingerIfRequired();
+                    sSocket.receive(packet);
+                    //System.out.println("Received packet from: "
+                    //        + packet.getAddress()+":"+packet.getPort());
+                    handle(sSocket, packet);
+                }
+            } catch (Exception x) {
+                error = x;
+            } finally {
+                synchronized (this) {
+                    if (!sSocket.isClosed()) {
+                        sSocket.close();
+                    }
+                    if (started && this.serverSocket == sSocket) {
+                        started = false;
+                        this.serverSocket = null;
+                        this.acceptThread = null;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Represents an UDP request received by the server.
+         */
+        protected abstract class UdpRequestThread extends Thread {
+
+            protected final DatagramPacket request;
+            protected final DatagramSocket socket;
+
+            protected UdpRequestThread(DatagramSocket socket, DatagramPacket request) {
+                this.socket = socket;
+                this.request = request;
+                this.setDaemon(true);
+            }
+        }
+
+        /**
+         * Creates a new UdpRequestThread to handle a DatagramPacket received
+         * through a DatagramSocket.
+         *
+         * @param socket the socket through which the request was received.
+         * @param request the datagram packet received through the socket.
+         * @return a new UdpRequestThread to handle the request received through
+         * a DatagramSocket.
+         */
+        protected abstract UdpRequestThread createConnection(DatagramSocket socket,
+                DatagramPacket request);
+
+        /**
+         * Creates and starts a new UdpRequestThread to handle the received
+         * datagram packet.
+         *
+         * @param socket the socket through which the request was received.
+         * @param request the datagram packet received through the socket.
+         */
+        private synchronized void handle(DatagramSocket socket,
+                DatagramPacket request) {
+            UdpRequestThread c = createConnection(socket, request);
+            // c can be null if the request requires no response.
+            if (c != null) {
+                c.start();
+            }
+        }
+
+        /**
+         * Close the server socket.
+         *
+         * @throws IOException
+         */
+        @Override
+        public synchronized void close() throws IOException {
+            if (serverSocket != null && !serverSocket.isClosed()) {
+                serverSocket.close();
+            }
+            if (acceptThread != null) {
+                acceptThread.interrupt();
+            }
+        }
+    }
+
+    /**
+     * A small UDP Server that emulates the discard service for tests purposes.
+     * See http://en.wikipedia.org/wiki/Discard_Protocol This server uses an
+     * anonymous port - NOT the standard port 9. We don't guarantee that its
+     * behavior exactly matches the RFC - the only purpose of this server is to
+     * have something that responds to nio tests...
+     */
+    static final class UdpDiscardServer extends AbstractUdpServer {
+
+        public UdpDiscardServer() {
+            this(0L);
+        }
+
+        public UdpDiscardServer(long linger) {
+            super(linger);
+        }
+
+        @Override
+        protected UdpRequestThread createConnection(DatagramSocket socket,
+                DatagramPacket request) {
+            // no response required
+            return null;
+        }
+
+        public static UdpDiscardServer startNewServer() throws IOException {
+            return startNewServer(0);
+        }
+
+        public static UdpDiscardServer startNewServer(long linger) throws IOException {
+            final UdpDiscardServer discardServer = new UdpDiscardServer(linger);
+            discardServer.start();
+            return discardServer;
+        }
+    }
+
+    /**
+     * A small UDP Server that emulates the echo service for tests purposes. See
+     * http://en.wikipedia.org/wiki/Echo_Protocol This server uses an anonymous
+     * port - NOT the standard port 7. We don't guarantee that its behavior
+     * exactly matches the RFC - the only purpose of this server is to have
+     * something that responds to nio tests...
+     */
+    static final class UdpEchoServer extends AbstractUdpServer {
+
+        public UdpEchoServer() {
+            this(0L);
+        }
+
+        public UdpEchoServer(long linger) {
+            super(linger);
+        }
+
+        @Override
+        protected UdpEchoRequest createConnection(DatagramSocket socket,
+                DatagramPacket request) {
+            return new UdpEchoRequest(socket, request);
+        }
+
+        private final class UdpEchoRequest extends UdpRequestThread {
+
+            public UdpEchoRequest(DatagramSocket socket, DatagramPacket request) {
+                super(socket, request);
+            }
+
+            @Override
+            public void run() {
+                try {
+                    lingerIfRequired();
+                    final DatagramPacket response =
+                            new DatagramPacket(request.getData(),
+                                    request.getOffset(), request.getLength(),
+                                    request.getAddress(), request.getPort());
+                    send(socket, response);
+                } catch (IOException io) {
+                    System.err.println("Failed to send response: " + io);
+                    io.printStackTrace(System.err);
+                }
+            }
+        }
+
+        public static UdpEchoServer startNewServer() throws IOException {
+            return startNewServer(0);
+        }
+
+        public static UdpEchoServer startNewServer(long linger) throws IOException {
+            final UdpEchoServer echoServer = new UdpEchoServer(linger);
+            echoServer.start();
+            return echoServer;
+        }
+    }
+
+    /**
+     * A small UDP server that emulates the Day & Time service for tests
+     * purposes. See http://en.wikipedia.org/wiki/Daytime_Protocol This server
+     * uses an anonymous port - NOT the standard port 13. We don't guarantee
+     * that its behavior exactly matches the RFC - the only purpose of this
+     * server is to have something that responds to nio tests...
+     */
+    static final class UdpDayTimeServer extends AbstractUdpServer {
+
+        public UdpDayTimeServer() {
+            this(0L);
+        }
+
+        public UdpDayTimeServer(long linger) {
+            super(linger);
+        }
+
+        @Override
+        protected UdpDayTimeRequestThread createConnection(DatagramSocket socket,
+                DatagramPacket request) {
+            return new UdpDayTimeRequestThread(socket, request);
+        }
+
+        private final class UdpDayTimeRequestThread extends UdpRequestThread {
+
+            public UdpDayTimeRequestThread(DatagramSocket socket,
+                    DatagramPacket request) {
+                super(socket, request);
+            }
+
+            @Override
+            public void run() {
+                try {
+                    lingerIfRequired();
+                    final byte[] data = new Date(System.currentTimeMillis())
+                            .toString().getBytes("US-ASCII");
+                    final DatagramPacket response =
+                            new DatagramPacket(data, 0, data.length,
+                                    request.getAddress(), request.getPort());
+                    send(socket, response);
+                } catch (IOException io) {
+                    System.err.println("Failed to send response: " + io);
+                    io.printStackTrace(System.err);
+                }
+            }
+        }
+
+        public static UdpDayTimeServer startNewServer() throws IOException {
+            return startNewServer(0);
+        }
+
+        public static UdpDayTimeServer startNewServer(long linger)
+                throws IOException {
+            final UdpDayTimeServer echoServer = new UdpDayTimeServer(linger);
+            echoServer.start();
+            return echoServer;
+        }
+    }
+}
diff --git a/jdk/test/java/nio/channels/TestUtil.java b/jdk/test/java/nio/channels/TestUtil.java
index c396709..7c1bdeb 100644
--- a/jdk/test/java/nio/channels/TestUtil.java
+++ b/jdk/test/java/nio/channels/TestUtil.java
@@ -27,7 +27,6 @@
 
 import java.io.*;
 import java.net.*;
-import java.nio.*;
 import java.nio.channels.*;
 import java.util.Random;
 
@@ -36,9 +35,6 @@
 
     // Test hosts used by the channels tests - change these when
     // executing in a different network.
-    public static final String HOST = "javaweb.sfbay.sun.com";
-    public static final String REFUSING_HOST = "jano1.sfbay.sun.com";
-    public static final String FAR_HOST = "irejano.ireland.sun.com";
     public static final String UNRESOLVABLE_HOST = "blah-blah.blah-blah.blah";
 
     private TestUtil() { }
diff --git a/jdk/test/java/nio/file/Path/MacPathTest.java b/jdk/test/java/nio/file/Path/MacPathTest.java
new file mode 100644
index 0000000..3bfa14a
--- /dev/null
+++ b/jdk/test/java/nio/file/Path/MacPathTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright (c) 2008, 2012, 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 7130915
+ * @summary Tests file path with nfc/nfd forms on MacOSX
+ * @library ../
+ * @build MacPathTest
+ * @run shell MacPathTest.sh
+ */
+
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.text.*;
+import java.util.*;
+import java.util.regex.*;
+
+public class MacPathTest {
+
+    public static void main(String args[]) throws Throwable {
+        String osname = System.getProperty("os.name");
+        if (!osname.contains("OS X") && !osname.contains("Darwin"))
+            return;
+        System.out.printf("sun.jnu.encoding=%s, file.encoding=%s%n",
+                          System.getProperty("file.encoding"),
+                          System.getProperty("sun.jnu.encoding"));
+        // English
+        test("TestDir_apple",                                    // test dir
+             "dir_macosx",                                       // dir
+             "file_macosx");                                     // file
+
+        // Japanese composite character
+        test("TestDir_\u30c8\u30a4\u30e4\u30cb\u30ca\u30eb/",
+             "dir_\u30a4\u30c1\u30b4\u306e\u30b1\u30fc\u30ad",
+             "file_\u30a4\u30c1\u30b4\u306e\u30b1\u30fc\u30ad");
+
+        // latin-1 supplementory
+        test("TestDir_K\u00f6rperlich\u00e4\u00df/",
+             "dir_Entt\u00e4uschung",
+             "file_Entt\u00e4uschung");
+
+        test("TestDir_K\u00f6rperlich\u00e4\u00df/",
+             "dir_Entt\u00c4uschung",
+             "file_Entt\u00c4uschung");
+
+        // Korean syblla
+        test("TestDir_\uac00\uac01\uac02",
+             "dir_\uac20\uac21\uac22",
+             "file_\uacc0\uacc1\uacc2");
+    }
+
+    private static boolean equal(Object x, Object y) {
+        return x == null ? y == null : x.equals(y);
+    }
+
+    private static boolean match(Path target, Path src) {
+        String fname = target.toString();
+        System.out.printf("    --> Trying  [%s], length=%d...", fname, fname.length());
+        if (target.equals(src)) {
+            System.out.println(" MATCHED!");
+            return true;
+        } else {
+            System.out.println(" NOT MATCHED!");
+        }
+        return false;
+    }
+
+    private static void test(String testdir, String dname, String fname_nfc)
+        throws Throwable
+    {
+        String fname = null;
+        String dname_nfd = Normalizer.normalize(dname, Normalizer.Form.NFD);
+        String fname_nfd = Normalizer.normalize(fname_nfc, Normalizer.Form.NFD);
+
+        System.out.printf("%n%n--------Testing...----------%n");
+        Path bpath = Paths.get(testdir);
+        Path dpath = Paths.get(testdir, dname);
+        Path dpath_nfd = Paths.get(testdir, dname_nfd);
+        Path fpath_nfc = Paths.get(testdir, fname_nfc);
+        Path fpath_nfd = Paths.get(testdir, fname_nfd);
+
+        if (Files.exists(bpath))
+            TestUtil.removeAll(bpath);
+        Files.createDirectories(dpath);
+
+        fname = dpath.toString();
+        System.out.printf(":Directory [%s][len=%d] created%n", fname, fname.length());
+
+        //////////////////////////////////////////////////////////////
+        if (!Files.isDirectory(dpath) || !Files.isDirectory(dpath_nfd)) {
+            throw new RuntimeException("Files.isDirectory(...) failed");
+        }
+
+        //////////////////////////////////////////////////////////////
+        // write out with nfd, read in with nfc + case
+        Files.write(fpath_nfd, new byte[] { 'n', 'f', 'd'});
+        System.out.println("    read in with nfc      (from nfd):" + new String(Files.readAllBytes(fpath_nfc)));
+
+        // check attrs with nfc + case
+        Set<PosixFilePermission> pfp = Files.getPosixFilePermissions(fpath_nfd);
+        if (!equal(pfp, Files.getPosixFilePermissions(fpath_nfc)) ) {
+            throw new RuntimeException("Files.getPosixfilePermission(...) failed");
+        }
+        Files.delete(fpath_nfd);
+
+        // write out with nfc, read in with nfd + case
+        Files.write(fpath_nfc, new byte[] { 'n', 'f', 'c'});
+        System.out.println("    read in with nfd      (from nfc):" + new String(Files.readAllBytes(fpath_nfd)));
+
+        // check attrs with nfc + case
+        pfp = Files.getPosixFilePermissions(fpath_nfc);
+        if (!equal(pfp, Files.getPosixFilePermissions(fpath_nfd))) {
+            throw new RuntimeException("Files.getPosixfilePermission(...) failed");
+        }
+        //////////////////////////////////////////////////////////////
+        boolean found_dir = false;
+        boolean found_file_nfc = false;
+        boolean found_file_nfd = false;
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(bpath)) {
+            for (Path path: stream) {
+                fname = path.toString();
+                System.out.printf("Found   : [%s], length=%d%n", fname, fname.length());
+                found_dir      |= match(dpath, path);
+                found_file_nfc |= match(fpath_nfc, path);
+                found_file_nfd |= match(fpath_nfd, path);
+            }
+        }
+        if (!found_dir || !found_file_nfc || !found_file_nfd) {
+            throw new RuntimeException("File.equal() failed");
+        }
+        // glob
+        String glob = "*" + fname_nfd.substring(2);  // remove leading "FI" from "FILE..."
+        System.out.println("glob=" + glob);
+        boolean globmatched = false;
+        try (DirectoryStream<Path> stream = Files.newDirectoryStream(bpath, glob)) {
+            for (Path path: stream) {
+                fname = path.toString();
+                System.out.printf("PathMatch : [%s], length=%d%n", fname, fname.length());
+                globmatched |= match(fpath_nfc, path);
+            }
+        }
+        if (!globmatched) {
+            //throw new RuntimeException("path matcher failed");
+            // it appears we have a regex.anon_eq bug in hangul syllable handling
+            System.out.printf("pathmatcher failed, glob=[%s]%n", glob);
+            System.out.printf("    -> fname_nfd.matches(fname_nfc)=%b%n",
+                              Pattern.compile(fname_nfd, Pattern.CANON_EQ)
+                                     .matcher(fname_nfc)
+                                     .matches());
+            System.out.printf("    -> fname_nfc.matches(fname_nfd)=%b%n",
+                              Pattern.compile(fname_nfc, Pattern.CANON_EQ)
+                                     .matcher(fname_nfd)
+                                     .matches());
+        }
+        TestUtil.removeAll(bpath);
+    }
+}
diff --git a/jdk/make/sun/rmi/rmi/mapfile-vers b/jdk/test/java/nio/file/Path/MacPathTest.sh
similarity index 68%
rename from jdk/make/sun/rmi/rmi/mapfile-vers
rename to jdk/test/java/nio/file/Path/MacPathTest.sh
index dc33402..e81c62a 100644
--- a/jdk/make/sun/rmi/rmi/mapfile-vers
+++ b/jdk/test/java/nio/file/Path/MacPathTest.sh
@@ -1,12 +1,12 @@
+#! /bin/sh
+
 #
-# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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.
+# 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
@@ -22,12 +22,18 @@
 # or visit www.oracle.com if you need additional information or have any
 # questions.
 #
+#
+OS=`uname -s`
+case "$OS" in
+  Darwin )  ;;
+  * )
+    exit 0
+    ;;
+esac
 
-# Define library interface.
+if [ "x$TESTJAVA" = x ]; then
+  TESTJAVA=$1; shift
+  TESTCLASSES=.
+fi
 
-SUNWprivate_1.1 {
-	global:
-	    Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader;
-	local:
-	    *;
-};
+export LC_ALL=en_US.UTF-8; ${TESTJAVA}/bin/java -cp ${TESTCLASSES} MacPathTest
diff --git a/jdk/test/java/rmi/MarshalledObject/compare/Compare.java b/jdk/test/java/rmi/MarshalledObject/compare/Compare.java
index 96ea46f..2032264 100644
--- a/jdk/test/java/rmi/MarshalledObject/compare/Compare.java
+++ b/jdk/test/java/rmi/MarshalledObject/compare/Compare.java
@@ -29,7 +29,6 @@
  *          not involved in location should be compared.
  * @author Ken Arnold
  *
- * @build Compare
  * @run main Compare 11 annotatedRef
  */
 
diff --git a/jdk/test/java/rmi/MarshalledObject/compare/HashCode.java b/jdk/test/java/rmi/MarshalledObject/compare/HashCode.java
index 6a0266b..768e418 100644
--- a/jdk/test/java/rmi/MarshalledObject/compare/HashCode.java
+++ b/jdk/test/java/rmi/MarshalledObject/compare/HashCode.java
@@ -27,7 +27,6 @@
  * @summary MarshalledObject with null throws NullPointerException
  * @author Ken Arnold
  *
- * @build HashCode
  * @run main HashCode 11 annotatedRef
  */
 
diff --git a/jdk/test/java/rmi/MarshalledObject/compare/NullReference.java b/jdk/test/java/rmi/MarshalledObject/compare/NullReference.java
index f8ff9a1..5210e94 100644
--- a/jdk/test/java/rmi/MarshalledObject/compare/NullReference.java
+++ b/jdk/test/java/rmi/MarshalledObject/compare/NullReference.java
@@ -27,7 +27,6 @@
  * @summary MarshalledObject with null throws NullPointerException
  * @author Ken Arnold
  *
- * @build NullReference
  * @run main NullReference
  */
 
diff --git a/jdk/test/java/rmi/Naming/DefaultRegistryPort.java b/jdk/test/java/rmi/Naming/DefaultRegistryPort.java
index 4290bf5..a4c4979 100644
--- a/jdk/test/java/rmi/Naming/DefaultRegistryPort.java
+++ b/jdk/test/java/rmi/Naming/DefaultRegistryPort.java
@@ -28,7 +28,6 @@
  * @author Dana Burns
  * @library ../testlibrary
  * @build TestLibrary
- * @build DefaultRegistryPort
  * @run main DefaultRegistryPort
  */
 
diff --git a/jdk/test/java/rmi/Naming/LookupIPv6.java b/jdk/test/java/rmi/Naming/LookupIPv6.java
index ebdd9f3..da6c62c 100644
--- a/jdk/test/java/rmi/Naming/LookupIPv6.java
+++ b/jdk/test/java/rmi/Naming/LookupIPv6.java
@@ -22,12 +22,11 @@
  */
 
 /* @test
+ * @summary Ensure that java.rmi.Naming.lookup can handle URLs containing
+ *          IPv6 addresses.
  * @bug 4402708
  *
  * @run main/othervm -Djava.net.preferIPv6Addresses=true LookupIPv6
- *
- * @summary Ensure that java.rmi.Naming.lookup can handle URLs containing
- *          IPv6 addresses.
  */
 
 import java.net.InetAddress;
diff --git a/jdk/test/java/rmi/Naming/LookupNameWithColon.java b/jdk/test/java/rmi/Naming/LookupNameWithColon.java
index 15b9663..e3865fd 100644
--- a/jdk/test/java/rmi/Naming/LookupNameWithColon.java
+++ b/jdk/test/java/rmi/Naming/LookupNameWithColon.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,13 @@
  * @bug 4387038
  * @summary Ensure that java.rmi.Naming.lookup functions properly for names
  *          containing embedded ':' characters.
+ *
+ * @library ../testlibrary
+ * @build TestLibrary
+ * @run main LookupNameWithColon
  */
 
 import java.rmi.Naming;
-import java.rmi.registry.LocateRegistry;
 import java.rmi.registry.Registry;
 
 public class LookupNameWithColon {
@@ -38,15 +41,12 @@
             "multiple:colons:in:name"
         };
 
-        Registry reg;
-        try {
-            reg = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
-        } catch (Exception ex) {
-            reg = LocateRegistry.getRegistry();
-        }
+        Registry reg = TestLibrary.createRegistryOnUnusedPort();
+        int port = TestLibrary.getRegistryPort(reg);
+
         for (int i = 0; i < names.length; i++) {
             reg.rebind(names[i], reg);
-            Naming.lookup("rmi://localhost/" + names[i]);
+            Naming.lookup("rmi://localhost:" + port + "/" + names[i]);
         }
     }
 }
diff --git a/jdk/test/java/rmi/Naming/RmiIsNoScheme.java b/jdk/test/java/rmi/Naming/RmiIsNoScheme.java
index 9edebe3..fe6d1ab 100644
--- a/jdk/test/java/rmi/Naming/RmiIsNoScheme.java
+++ b/jdk/test/java/rmi/Naming/RmiIsNoScheme.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,6 @@
  *
  * @library ../testlibrary
  * @build TestLibrary
- * @build RmiIsNoScheme
  * @run main/othervm RmiIsNoScheme
  */
 
@@ -39,9 +38,6 @@
 import java.rmi.registry.*;
 
 public class RmiIsNoScheme implements Remote, Serializable {
-
-    private static final int REGISTRY_PORT = 2002;
-
     private RmiIsNoScheme() {}
 
     public static void main(String[] args) {
@@ -49,10 +45,11 @@
         System.err.println("\nRegression test for bug 4626311\n");
 
         try {
-            LocateRegistry.createRegistry(REGISTRY_PORT);
-            Naming.rebind("//:" + REGISTRY_PORT + "/RmiIsNoScheme",
+            Registry registry = TestLibrary.createRegistryOnUnusedPort();
+            int registryPort = TestLibrary.getRegistryPort(registry);
+            Naming.rebind("//:" + registryPort + "/RmiIsNoScheme",
                           new RmiIsNoScheme());
-            String name = Naming.list("//:" + REGISTRY_PORT)[0];
+            String name = Naming.list("//:" + registryPort)[0];
             System.err.println("name = " + name);
             if (name.startsWith("rmi:", 0) == false) {
                 System.err.println("TEST PASSED: rmi scheme not present");
diff --git a/jdk/test/java/rmi/Naming/UnderscoreHost.java b/jdk/test/java/rmi/Naming/UnderscoreHost.java
index 1dd81c3..b88ca62 100644
--- a/jdk/test/java/rmi/Naming/UnderscoreHost.java
+++ b/jdk/test/java/rmi/Naming/UnderscoreHost.java
@@ -1,37 +1,36 @@
-/*
- * Copyright (c) 2005, 2006, 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.
- */
+ /*
+  * Copyright (c) 2005, 2012, 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 5083594
- * @summary Ensure that Naming.java correctly parses host names with '_' in
- * them.
- * @author Vinod Johnson
- *
- * @library ../testlibrary
- * @build TestLibrary
- * @build UnderscoreHost UnderscoreHost_Stub
- * @run main/othervm UnderscoreHost
+ /*
+  * @test
+  * @bug 5083594
+  * @summary Ensure that Naming.java correctly parses host names with '_' in
+  * them.
+  * @author Vinod Johnson
+  *
+  * @library ../testlibrary
+  * @build TestLibrary UnderscoreHost_Stub
+  * @run main/othervm UnderscoreHost
  */
 
 import java.io.IOException;
@@ -77,11 +76,12 @@
         try {
             HostVerifyingSocketFactory hvf = new HostVerifyingSocketFactory();
             RMISocketFactory.setSocketFactory(hvf);
-            Registry r = LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
+            Registry r = TestLibrary.createRegistryOnUnusedPort();
+            int port = TestLibrary.getRegistryPort(r);
             t = new UnderscoreHost();
             r.rebind(NAME, t);
             Naming.lookup("rmi://" + HOSTNAME +
-                          ":" + Registry.REGISTRY_PORT + "/" + NAME);
+                          ":" + port + "/" + NAME);
             /*
              * This test is coded to pass whether java.net.URI obeys
              * RFC 2396 or RFC 3986 (see 5085902, 6394131, etc.).
diff --git a/jdk/test/java/rmi/Naming/legalRegistryNames/LegalRegistryNames.java b/jdk/test/java/rmi/Naming/legalRegistryNames/LegalRegistryNames.java
index 8ac8bdb..725d9ca 100644
--- a/jdk/test/java/rmi/Naming/legalRegistryNames/LegalRegistryNames.java
+++ b/jdk/test/java/rmi/Naming/legalRegistryNames/LegalRegistryNames.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -21,14 +21,13 @@
  * questions.
  */
 
-/**
+/*
  * @test
  * @bug 4254808
  * @summary Naming assumes '/' is present in relative URL; change in URL causes regression
  * @author Dana Burns
  * @library ../../testlibrary
- * @build TestLibrary
- * @build Legal LegalRegistryNames LegalRegistryNames_Stub
+ * @build TestLibrary Legal LegalRegistryNames_Stub
  * @run main LegalRegistryNames
  */
 
@@ -45,7 +44,9 @@
 
 /**
  * Ensure that all legal forms of Naming URLs operate with the
- * java.rmi.Naming interface
+ * java.rmi.Naming interface.  This test requires using the default RMI Registry
+ * port as it tests all of the RMI naming URL's, including the ones which do not
+ * take a port (and therefore uses the default port).
  */
 public class LegalRegistryNames extends UnicastRemoteObject
     implements Legal
diff --git a/jdk/test/java/rmi/RMISecurityManager/checkPackageAccess/CheckPackageAccess.java b/jdk/test/java/rmi/RMISecurityManager/checkPackageAccess/CheckPackageAccess.java
index 6487088..32cbe5f 100644
--- a/jdk/test/java/rmi/RMISecurityManager/checkPackageAccess/CheckPackageAccess.java
+++ b/jdk/test/java/rmi/RMISecurityManager/checkPackageAccess/CheckPackageAccess.java
@@ -28,10 +28,9 @@
  * as when the default java.lang.SecurityManager is set, which with the
  * default "java.security" file in the JDK means that access to packages in
  * the sun.* package hierarchy is denied (without explicit runtime permission
- * "accessClassInPackge.*").
+ * "accessClassInPackage.*").
  * @author Peter Jones
  *
- * @build CheckPackageAccess
  * @run main/othervm CheckPackageAccess
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/checkActivateRef/CheckActivateRef.java b/jdk/test/java/rmi/activation/Activatable/checkActivateRef/CheckActivateRef.java
index 9bd8475..fce32f9 100644
--- a/jdk/test/java/rmi/activation/Activatable/checkActivateRef/CheckActivateRef.java
+++ b/jdk/test/java/rmi/activation/Activatable/checkActivateRef/CheckActivateRef.java
@@ -36,8 +36,7 @@
  *          functionality is in place
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID
- * @build ActivateMe CheckActivateRef_Stub CheckActivateRef
+ * @build TestLibrary RMID ActivateMe CheckActivateRef_Stub
  * @run main/othervm/policy=security.policy/timeout=240 -Djava.rmi.server.ignoreStubClasses=true CheckActivateRef
  * @run main/othervm/policy=security.policy/timeout=240 -Djava.rmi.server.ignoreStubClasses=false CheckActivateRef
  */
diff --git a/jdk/test/java/rmi/activation/Activatable/checkActivateRef/security.policy b/jdk/test/java/rmi/activation/Activatable/checkActivateRef/security.policy
index 078b8a7..f33bc85 100644
--- a/jdk/test/java/rmi/activation/Activatable/checkActivateRef/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/checkActivateRef/security.policy
@@ -29,11 +29,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java
index ae7b843..b6e4abd 100644
--- a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java
+++ b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/CheckAnnotations.java
@@ -28,10 +28,7 @@
  * @author Laird Dornin; code borrowed from Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build MyRMI
- * @build CheckAnnotations
- * @build CheckAnnotations_Stub
+ * @build TestLibrary RMID MyRMI CheckAnnotations_Stub
  * @run main/othervm/policy=security.policy/timeout=480 CheckAnnotations
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/security.policy b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/security.policy
index b6e691b..e13da7f 100644
--- a/jdk/test/java/rmi/activation/Activatable/checkAnnotations/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/checkAnnotations/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // required for test to create an ActivationGroup
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/CheckImplClassLoader.java b/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/CheckImplClassLoader.java
index e3a1467..3d06941 100644
--- a/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/CheckImplClassLoader.java
+++ b/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/CheckImplClassLoader.java
@@ -24,14 +24,11 @@
 /* @test
  * @bug 4289544
  * @summary ActivationGroupImpl.newInstance does not set context classloader for impl
- *
  * @author Laird Dornin; code borrowed from Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build MyRMI
- * @build CheckImplClassLoader ActivatableImpl
- * @build ActivatableImpl ActivatableImpl_Stub
+ * @build TestLibrary RMID
+ *     MyRMI ActivatableImpl ActivatableImpl ActivatableImpl_Stub
  * @run main/othervm/policy=security.policy/timeout=150 CheckImplClassLoader
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/security.policy b/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/security.policy
index 8b7ec7c..b66dd8c 100644
--- a/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/checkImplClassLoader/security.policy
@@ -32,11 +32,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // required for test to create an ActivationGroup
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/CheckRegisterInLog.java b/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/CheckRegisterInLog.java
index 59f5c99..b46142f 100644
--- a/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/CheckRegisterInLog.java
+++ b/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/CheckRegisterInLog.java
@@ -27,8 +27,8 @@
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build RMID ActivationLibrary TestLibrary
- * @build ActivateMe CheckRegisterInLog CheckRegisterInLog_Stub
+ * @build TestLibrary RMID ActivationLibrary
+ *     ActivateMe CheckRegisterInLog_Stub
  * @run main/othervm/policy=security.policy/timeout=240 CheckRegisterInLog
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/security.policy b/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/security.policy
index d1d1b62..f78e106 100644
--- a/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/checkRegisterInLog/security.policy
@@ -21,17 +21,18 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
 
   // allow exporting of remote objects on an arbitrary port.
-  permission java.net.SocketPermission "*:1024-", "connect,accept";
+  permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
 
   // allow exporting object with non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
diff --git a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java
index 4d4d073..41a2886 100644
--- a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java
+++ b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/CreatePrivateActivatable.java
@@ -22,14 +22,12 @@
  */
 
 /* @test
- * @author Laird Dornin
  * @bug 4164971
  * @summary allow non-public activatable class and/or constructor
+ * @author Laird Dornin
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID
- * @build ActivateMe
- * @build CreatePrivateActivatable
+ * @build TestLibrary RMID ActivateMe
  * @run main/othervm/policy=security.policy/timeout=240 CreatePrivateActivatable
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/security.policy b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/security.policy
index e6178a5..f78e106 100644
--- a/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/createPrivateActivable/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/DownloadParameterClass.java b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/DownloadParameterClass.java
index 1bb909a..42d309b 100644
--- a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/DownloadParameterClass.java
+++ b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/DownloadParameterClass.java
@@ -32,11 +32,7 @@
  *
  * @library ../../../testlibrary
  * @build TestLibrary RMID ActivationLibrary
- * @build DownloadParameterClass
- * @build Foo
- * @build FooReceiverImpl
- * @build FooReceiverImpl_Stub
- * @build Bar
+ *     Foo FooReceiverImpl FooReceiverImpl_Stub Bar
  * @run main/othervm/policy=security.policy/timeout=240 DownloadParameterClass
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/security.policy b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/security.policy
index e4948a9..657881b 100644
--- a/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/downloadParameterClass/security.policy
@@ -31,11 +31,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
diff --git a/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/ElucidateNoSuchMethod.java b/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/ElucidateNoSuchMethod.java
index 3d82bfb..7ee451d 100644
--- a/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/ElucidateNoSuchMethod.java
+++ b/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/ElucidateNoSuchMethod.java
@@ -23,14 +23,11 @@
 
 /* @test
  * @bug 4128620
- *
  * @summary synopsis: NoSuchMethodError should be elucidated
- *
  * @author Laird Dornin
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID
- * @build ActivateMe ElucidateNoSuchMethod ElucidateNoSuchMethod_Stub
+ * @build TestLibrary RMID ActivateMe ElucidateNoSuchMethod_Stub
  * @run main/othervm/policy=security.policy/timeout=240 ElucidateNoSuchMethod
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/security.policy b/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/security.policy
index ede8bd0..3d1c769 100644
--- a/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/elucidateNoSuchMethod/security.policy
@@ -30,11 +30,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh
index 342e57d..9232496 100644
--- a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh
+++ b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/ext.sh
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -28,11 +28,25 @@
 # set to the impl's class loader) when the impl is activated.
 # @library ../../../testlibrary
 # @build TestLibrary RMID ActivationLibrary
-# @build ExtLoadedImplTest ExtLoadedImpl ExtLoadedImpl_Stub CheckLoader
+#     ExtLoadedImplTest ExtLoadedImpl ExtLoadedImpl_Stub CheckLoader
 # @run shell ext.sh
 
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin )
+    PS=":"
+    ;;
+  Windows* | CYGWIN* )
+    PS=";"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
 mkdir -p classes
-cp $TESTCLASSES/*.class classes
+for dir in `echo ${TESTCLASSPATH:-$TESTCLASSES} | sed -e "s/$PS/ /"` ; do cp $dir/*.class classes ; done
 rm classes/ExtLoadedImpl.class classes/ExtLoadedImpl_Stub.class classes/CheckLoader.class
 mkdir -p ext
 $TESTJAVA/bin/jar cf ext/ext.jar -C $TESTCLASSES ExtLoadedImpl.class -C $TESTCLASSES ExtLoadedImpl_Stub.class -C $TESTCLASSES CheckLoader.class
diff --git a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/security.policy b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/security.policy
index c5b33d9..7eb3072 100644
--- a/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/extLoadedImpl/security.policy
@@ -17,11 +17,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
diff --git a/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java b/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java
index 6791148..9af0bf3 100644
--- a/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java
+++ b/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/ForceLogSnapshot.java
@@ -27,9 +27,8 @@
  * @author Laird Dornin
  *
  * @library ../../../testlibrary
- * @build ActivateMe
- * @build ForceLogSnapshot
- * @build ForceLogSnapshot_Stub
+ * @build TestLibrary RMID ActivationLibrary
+ *     ActivateMe ForceLogSnapshot_Stub
  * @run main/othervm/policy=security.policy/timeout=640 ForceLogSnapshot
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/security.policy b/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/security.policy
index e6178a5..f78e106 100644
--- a/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/forceLogSnapshot/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/Activatable/inactiveGroup/InactiveGroup.java b/jdk/test/java/rmi/activation/Activatable/inactiveGroup/InactiveGroup.java
index a1b02b1..238d347 100644
--- a/jdk/test/java/rmi/activation/Activatable/inactiveGroup/InactiveGroup.java
+++ b/jdk/test/java/rmi/activation/Activatable/inactiveGroup/InactiveGroup.java
@@ -29,10 +29,7 @@
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID ActivationLibrary
- * @build ActivateMe
- * @build InactiveGroup
- * @build InactiveGroup_Stub
+ * @build TestLibrary RMID ActivationLibrary ActivateMe InactiveGroup_Stub
  * @run main/othervm/policy=security.policy/timeout=240 InactiveGroup
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/inactiveGroup/security.policy b/jdk/test/java/rmi/activation/Activatable/inactiveGroup/security.policy
index d1d1b62..f78e106 100644
--- a/jdk/test/java/rmi/activation/Activatable/inactiveGroup/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/inactiveGroup/security.policy
@@ -21,17 +21,18 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
 
   // allow exporting of remote objects on an arbitrary port.
-  permission java.net.SocketPermission "*:1024-", "connect,accept";
+  permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
 
   // allow exporting object with non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
diff --git a/jdk/test/java/rmi/activation/Activatable/lookupActivationSystem/LookupActivationSystem.java b/jdk/test/java/rmi/activation/Activatable/lookupActivationSystem/LookupActivationSystem.java
index 03d3c17..ce154c4 100644
--- a/jdk/test/java/rmi/activation/Activatable/lookupActivationSystem/LookupActivationSystem.java
+++ b/jdk/test/java/rmi/activation/Activatable/lookupActivationSystem/LookupActivationSystem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -24,14 +24,12 @@
 /*
  * @test
  * @bug 6245733
- *
  * @summary synopsis: rmid's registry's list operation doesn't include
  * activation system
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
  * @build TestLibrary RMID ActivationLibrary
- * @build LookupActivationSystem
  * @run main/othervm/timeout=240 LookupActivationSystem
  */
 
@@ -58,7 +56,7 @@
 
             System.err.println("look up activation system");
             Registry rmidRegistry =
-                LocateRegistry.getRegistry(ActivationSystem.SYSTEM_PORT);
+                LocateRegistry.getRegistry(rmid.getPort());
             ActivationSystem system = (ActivationSystem)
                 rmidRegistry.lookup(NAME);
 
diff --git a/jdk/test/java/rmi/activation/Activatable/nestedActivate/NestedActivate.java b/jdk/test/java/rmi/activation/Activatable/nestedActivate/NestedActivate.java
index 9ad2d54..2cd5a63 100644
--- a/jdk/test/java/rmi/activation/Activatable/nestedActivate/NestedActivate.java
+++ b/jdk/test/java/rmi/activation/Activatable/nestedActivate/NestedActivate.java
@@ -23,15 +23,11 @@
 
 /* @test
  * @bug 4138056
- *
  * @summary synopsis: Activating objects from an Activatable constructor causes deadlock
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID ActivationLibrary
- * @build ActivateMe
- * @build NestedActivate
- * @build NestedActivate_Stub
+ * @build TestLibrary RMID ActivationLibrary ActivateMe NestedActivate_Stub
  * @run main/othervm/policy=security.policy/timeout=240 NestedActivate
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/nestedActivate/security.policy b/jdk/test/java/rmi/activation/Activatable/nestedActivate/security.policy
index c08ff33..7972e5c 100644
--- a/jdk/test/java/rmi/activation/Activatable/nestedActivate/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/nestedActivate/security.policy
@@ -21,17 +21,18 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
 
   // allow exporting of remote objects on an arbitrary port.
-  permission java.net.SocketPermission "*:1024-", "connect,accept";
+  permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
 
   // allow exporting of non-public remote interface
   permission java.rmi.RMIPermission "exportRemoteInterface.ActivateMe";
diff --git a/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/NonExistentActivatable.java b/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/NonExistentActivatable.java
index 76d68e9..625661b 100644
--- a/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/NonExistentActivatable.java
+++ b/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/NonExistentActivatable.java
@@ -23,16 +23,13 @@
 
 /* @test
  * @bug 4115296
- *
  * @summary synopsis: NoSuchObjectException not thrown for non-existent
  * activatable objects
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
  * @build TestLibrary RMID ActivationLibrary
- * @build ActivateMe
- * @build NonExistentActivatable
- * @build NonExistentActivatable_Stub
+ *     ActivateMe NonExistentActivatable_Stub
  * @run main/othervm/policy=security.policy/timeout=240 NonExistentActivatable
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/security.policy b/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/security.policy
index 63f2306..99fedda 100644
--- a/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/nonExistentActivatable/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/Activatable/restartCrashedService/RestartCrashedService.java b/jdk/test/java/rmi/activation/Activatable/restartCrashedService/RestartCrashedService.java
index 164a842..b403c28 100644
--- a/jdk/test/java/rmi/activation/Activatable/restartCrashedService/RestartCrashedService.java
+++ b/jdk/test/java/rmi/activation/Activatable/restartCrashedService/RestartCrashedService.java
@@ -28,10 +28,7 @@
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build ActivateMe
- * @build RestartCrashedService
- * @build RestartCrashedService_Stub
+ * @build TestLibrary RMID ActivateMe RestartCrashedService_Stub
  * @run main/othervm/policy=security.policy/timeout=240 RestartCrashedService
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/restartCrashedService/security.policy b/jdk/test/java/rmi/activation/Activatable/restartCrashedService/security.policy
index fe05fca..881781b 100644
--- a/jdk/test/java/rmi/activation/Activatable/restartCrashedService/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/restartCrashedService/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/Activatable/restartLatecomer/RestartLatecomer.java b/jdk/test/java/rmi/activation/Activatable/restartLatecomer/RestartLatecomer.java
index 3175098..c53053e 100644
--- a/jdk/test/java/rmi/activation/Activatable/restartLatecomer/RestartLatecomer.java
+++ b/jdk/test/java/rmi/activation/Activatable/restartLatecomer/RestartLatecomer.java
@@ -28,8 +28,7 @@
  *
  * @library ../../../testlibrary
  * @build TestLibrary RMID ActivationLibrary
- * @build RestartLatecomer
- * @build RestartLatecomer_Stub
+ *     RestartLatecomer RestartLatecomer_Stub
  * @run main/othervm/policy=security.policy/timeout=240 RestartLatecomer
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/restartLatecomer/security.policy b/jdk/test/java/rmi/activation/Activatable/restartLatecomer/security.policy
index a96acd7..0e70b29 100644
--- a/jdk/test/java/rmi/activation/Activatable/restartLatecomer/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/restartLatecomer/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Used in remote impl of Activator.inactive; by the method
   // "restartThread.dispose()"when it calls thread.interrupt()
diff --git a/jdk/test/java/rmi/activation/Activatable/restartService/RestartService.java b/jdk/test/java/rmi/activation/Activatable/restartService/RestartService.java
index a98ce83..973916f 100644
--- a/jdk/test/java/rmi/activation/Activatable/restartService/RestartService.java
+++ b/jdk/test/java/rmi/activation/Activatable/restartService/RestartService.java
@@ -23,15 +23,11 @@
 
 /* @test
  * @bug 4095165 4321151
-
  * @summary synopsis: activator should restart daemon services
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID ActivationLibrary
- * @build ActivateMe
- * @build RestartService
- * @build RestartService_Stub
+ * @build TestLibrary RMID ActivationLibrary ActivateMe RestartService_Stub
  * @run main/othervm/policy=security.policy/timeout=240 RestartService
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/restartService/security.policy b/jdk/test/java/rmi/activation/Activatable/restartService/security.policy
index a96acd7..0e70b29 100644
--- a/jdk/test/java/rmi/activation/Activatable/restartService/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/restartService/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Used in remote impl of Activator.inactive; by the method
   // "restartThread.dispose()"when it calls thread.interrupt()
diff --git a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java
index 162eb38..64233bf 100644
--- a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java
+++ b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/ShutdownGracefully.java
@@ -28,11 +28,8 @@
  * @author Laird Dornin; code borrowed from Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build TestSecurityManager
- * @build RegisteringActivatable
- * @build ShutdownGracefully
- * @build ShutdownGracefully_Stub
+ * @build TestLibrary RMID
+ *     TestSecurityManager RegisteringActivatable ShutdownGracefully_Stub
  * @run main/othervm/policy=security.policy/timeout=700 ShutdownGracefully
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/security.policy b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/security.policy
index 6f39361..693ce51 100644
--- a/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/shutdownGracefully/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // allow exporting of remote objects on an arbitrary port.
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
diff --git a/jdk/test/java/rmi/activation/Activatable/unregisterInactive/UnregisterInactive.java b/jdk/test/java/rmi/activation/Activatable/unregisterInactive/UnregisterInactive.java
index 5d8c50c..412901e 100644
--- a/jdk/test/java/rmi/activation/Activatable/unregisterInactive/UnregisterInactive.java
+++ b/jdk/test/java/rmi/activation/Activatable/unregisterInactive/UnregisterInactive.java
@@ -23,16 +23,12 @@
 
 /* @test
  * @bug 4115331
-
  * @summary synopsis: activatable object fails to go inactive after
  * unregister/inactive sequence.
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID ActivationLibrary
- * @build ActivateMe
- * @build UnregisterInactive
- * @build UnregisterInactive_Stub
+ * @build TestLibrary RMID ActivationLibrary ActivateMe UnregisterInactive_Stub
  * @run main/othervm/policy=security.policy/timeout=240 UnregisterInactive
  */
 
diff --git a/jdk/test/java/rmi/activation/Activatable/unregisterInactive/security.policy b/jdk/test/java/rmi/activation/Activatable/unregisterInactive/security.policy
index ff2ecca..749e142 100644
--- a/jdk/test/java/rmi/activation/Activatable/unregisterInactive/security.policy
+++ b/jdk/test/java/rmi/activation/Activatable/unregisterInactive/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // Needed to create an activation group
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java
index a5a5b0d..a7d7643 100644
--- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java
+++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/ActivateFails.java
@@ -31,11 +31,8 @@
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build ActivateMe
- * @build ActivateFails
- * @build ActivateFails_Stub
- * @build ShutdownThread
+ * @build TestLibrary RMID ActivationLibrary
+ *     ActivateMe ActivateFails_Stub ShutdownThread
  * @run main/othervm/policy=security.policy/timeout=240 ActivateFails
  */
 
diff --git a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy
index b6e691b..e13da7f 100644
--- a/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy
+++ b/jdk/test/java/rmi/activation/ActivateFailedException/activateFails/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // required for test to create an ActivationGroup
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java
index f7f8643..880f1e8 100644
--- a/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java
+++ b/jdk/test/java/rmi/activation/ActivationGroup/downloadActivationGroup/DownloadActivationGroup.java
@@ -33,9 +33,7 @@
  *
  * @library ../../../testlibrary
  * @build TestLibrary RMID ActivationLibrary
- * @build MyActivationGroupImpl
- * @build DownloadActivationGroup
- * @build DownloadActivationGroup_Stub
+ *     DownloadActivationGroup MyActivationGroupImpl DownloadActivationGroup_Stub
  * @run main/othervm/policy=security.policy/timeout=240 DownloadActivationGroup
  */
 
diff --git a/jdk/test/java/rmi/activation/ActivationGroupDesc/checkDefaultGroupName/CheckDefaultGroupName.java b/jdk/test/java/rmi/activation/ActivationGroupDesc/checkDefaultGroupName/CheckDefaultGroupName.java
index bd47502..f37cbae 100644
--- a/jdk/test/java/rmi/activation/ActivationGroupDesc/checkDefaultGroupName/CheckDefaultGroupName.java
+++ b/jdk/test/java/rmi/activation/ActivationGroupDesc/checkDefaultGroupName/CheckDefaultGroupName.java
@@ -21,16 +21,15 @@
  * questions.
  */
 
-/**
+/*
  * @test
  * @bug 4252236
  * @summary ActivationGroupDesc should not do early binding of default classname
- * @library ../../../testlibrary
- *
- * @build CheckDefaultGroupName
- *
- * @run main CheckDefaultGroupName
  * @author Laird Dornin
+ *
+ * @library ../../../testlibrary
+ * @build TestLibrary
+ * @run main CheckDefaultGroupName
  */
 
 import java.rmi.activation.*;
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java b/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java
index 41670ee..391a862 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java
+++ b/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/IdempotentActiveGroup.java
@@ -23,15 +23,13 @@
 
 /* @test
  * @bug 4720528
- *
  * @summary synopsis: (spec) ActivationSystem.activeGroup spec should be
  * relaxed (duplicate call to activeGroup with same instantiator and
  * incarnation should not throw ActivationException; it should succeed)
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID
- * @build IdempotentActiveGroup
+ * @build TestLibrary RMID ActivationLibrary
  * @run main/othervm/policy=security.policy/timeout=480 IdempotentActiveGroup
  */
 
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/security.policy b/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/security.policy
index a9431dc..fe01125 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/security.policy
+++ b/jdk/test/java/rmi/activation/ActivationSystem/activeGroup/security.policy
@@ -15,11 +15,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // test needs to export rmid and communicate with objects on arbitrary ports
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java
index 4f3d51e..19034e5 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java
+++ b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/ModifyDescriptor.java
@@ -29,9 +29,8 @@
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build ActivateMe
- * @build ModifyDescriptor
- * @build ModifyDescriptor_Stub
+ * @build TestLibrary RMID ActivationLibrary
+ *     ActivateMe ModifyDescriptor_Stub
  * @run main/othervm/policy=security.policy/timeout=240 ModifyDescriptor
  */
 
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/security.policy b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/security.policy
index b6e691b..e13da7f 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/security.policy
+++ b/jdk/test/java/rmi/activation/ActivationSystem/modifyDescriptor/security.policy
@@ -21,11 +21,12 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // required for test to create an ActivationGroup
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java
index eb4e4f0..d987f93 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java
+++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/StubClassesPermitted.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -24,14 +24,11 @@
 /* @test
  * @bug 4179055
  * @summary Some java apps need to have access to read "accessClassInPackage.sun.rmi.server"
- *
  * @author Laird Dornin
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe ActivationLibrary
- * @build CanCreateStubs
- * @build StubClassesPermitted
- * @build StubClassesPermitted_Stub
+ * @build TestLibrary RMID ActivationLibrary
+ *     CanCreateStubs StubClassesPermitted_Stub
  * @run main/othervm/policy=security.policy/secure=java.lang.SecurityManager/timeout=240 StubClassesPermitted
  */
 
@@ -61,7 +58,7 @@
     extends Activatable implements Runnable, CanCreateStubs
 {
     public static boolean sameGroup = false;
-
+    private static int registryPort = -1;
     private static CanCreateStubs canCreateStubs = null;
     private static Registry registry = null;
 
@@ -76,8 +73,8 @@
         try {
             TestLibrary.suggestSecurityManager("java.lang.SecurityManager");
 
-            registry = java.rmi.registry.LocateRegistry.
-                createRegistry(TestLibrary.REGISTRY_PORT);
+            registry = TestLibrary.createRegistryOnUnusedPort();
+            registryPort = TestLibrary.getRegistryPort(registry);
 
             // must run with java.lang.SecurityManager or the test
             // result will be nullified if running with a build where
@@ -192,7 +189,7 @@
 
         // obtain reference to the test registry
         registry = java.rmi.registry.LocateRegistry.
-            getRegistry(TestLibrary.REGISTRY_PORT);
+            getRegistry(registryPort);
     }
 
     /**
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/security.policy b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/security.policy
index b6e691b..b6f6ef2 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/security.policy
+++ b/jdk/test/java/rmi/activation/ActivationSystem/stubClassesPermitted/security.policy
@@ -21,15 +21,22 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // required for test to create an ActivationGroup
   permission java.lang.RuntimePermission "setFactory";
 
+  // required for test to get the registry port
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
+
   // test needs to export rmid and communicate with objects on arbitrary ports
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
 };
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java
index 02cfe29..59fee9d 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java
+++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/UnregisterGroup.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -24,16 +24,12 @@
 /* @test
  * @bug 4134233
  * @bug 4213186
- *
  * @summary synopsis: ActivationSystem.unregisterGroup should unregister objects in group
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build ActivateMe CallbackInterface
- * @build UnregisterGroup
- * @build UnregisterGroup_Stub
- * @build Callback_Stub
+ * @build TestLibrary RMID ActivationLibrary
+ *     ActivateMe CallbackInterface UnregisterGroup_Stub Callback_Stub
  * @run main/othervm/policy=security.policy/timeout=480 UnregisterGroup
  */
 
@@ -45,36 +41,29 @@
 import java.util.Properties;
 
 class Callback extends UnicastRemoteObject implements CallbackInterface {
+    public int num_deactivated = 0;
 
-  public static int num_deactivated = 0;
+    public Callback() throws RemoteException { super(); }
 
-  public Callback() throws RemoteException { super(); }
+    public synchronized void inc() throws RemoteException {
+        num_deactivated++;
+    }
 
-  public void inc() throws RemoteException {
-    incNumDeactivated();
-  }
-
-  public synchronized int getNumDeactivated() throws RemoteException {
-    return(num_deactivated);
-  }
-
-  public synchronized void incNumDeactivated() {
-    num_deactivated++;
-  }
-
+    public synchronized int getNumDeactivated() throws RemoteException {
+        return num_deactivated;
+    }
 }
 
 public class UnregisterGroup
         extends Activatable
         implements ActivateMe, Runnable
 {
-
     private static Exception exception = null;
     private static String error = null;
     private static boolean done = false;
     private static ActivateMe lastResortExitObj = null;
     private static final int NUM_OBJECTS = 10;
-    private static int PORT = 2006;
+    private static int registryPort = -1;
 
     public UnregisterGroup(ActivationID id, MarshalledObject mobj)
         throws Exception
@@ -104,36 +93,47 @@
     }
 
     /**
-     * Thread to deactivate object. First attempts to make object
-     * inactive (via the inactive method).  If that fails (the
-     * object may still have pending/executing calls), then
-     * unexport the object forcibly.
+     * Thread to deactivate object. Get the callback object from the registry,
+     * call inc() on it, and finally call deactivate(). The call to
+     * deactivate() causes this JVM to be destroyed, so anything following
+     * might not be executed.
      */
     public void run() {
+        String regPortStr = System.getProperty("unregisterGroup.port");
+        int regPort = -1;
 
-        ActivationLibrary.deactivate(this, getID());
-        System.err.println("\tActivationLibrary.deactivate returned");
+        if (regPortStr != null) {
+            regPort = Integer.parseInt(regPortStr);
+        }
 
         try {
             CallbackInterface cobj =
-                (CallbackInterface)Naming.lookup("//:" + PORT + "/Callback");
+                (CallbackInterface)Naming.lookup("//:" + regPort + "/Callback");
             cobj.inc();
+            System.err.println("cobj.inc called and returned ok");
         } catch (Exception e) {
             System.err.println("cobj.inc exception");
             e.printStackTrace();
         }
 
+        ActivationLibrary.deactivate(this, getID());
+        System.err.println("\tActivationLibrary.deactivate returned");
     }
 
-    public static void main(String[] args) {
-
-        Registry registry;
-
+    public static void main(String[] args) throws RemoteException {
         System.err.println("\nRegression test for bug 4134233\n");
-
         TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
         RMID rmid = null;
 
+        // Create registry and export callback object so they're
+        // available to the objects that are activated below.
+        // TODO: see if we can use RMID's registry instead of
+        // creating one here.
+        Registry registry = TestLibrary.createRegistryOnUnusedPort();
+        registryPort = TestLibrary.getRegistryPort(registry);
+        Callback robj = new Callback();
+        registry.rebind("Callback", robj);
+
         try {
             RMID.removeLog();
             rmid = RMID.createRMID();
@@ -149,8 +149,7 @@
                   TestParams.defaultGroupPolicy);
             p.put("java.security.manager",
                   TestParams.defaultSecurityManager);
-
-            //final int NUM_OBJECTS = 10;
+            p.put("unregisterGroup.port", Integer.toString(registryPort));
 
             Thread t = new Thread() {
                 public void run () {
@@ -219,8 +218,6 @@
             } else {
                 System.err.println("Test passed");
             }
-
-
         } catch (Exception e) {
             TestLibrary.bomb("test failed", e);
         } finally {
@@ -233,12 +230,6 @@
 
             // Wait for the object deactivation to take place first
             try {
-
-                // create reg and export callback object
-                registry = LocateRegistry.createRegistry(PORT);
-                Callback robj = new Callback();
-                registry.bind("Callback", robj);
-
                 //get the callback object
                 int maxwait=30;
                 int nd = robj.getNumDeactivated();
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/group.security.policy b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/group.security.policy
index 440910b..e596baa 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/group.security.policy
+++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/group.security.policy
@@ -7,4 +7,5 @@
 
   // test needs to communicate with the activation system
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+  permission java.util.PropertyPermission "unregisterGroup.port", "read";
 };
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/rmid.security.policy b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/rmid.security.policy
index 0e43c5d..fa1bc1e 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/rmid.security.policy
+++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/rmid.security.policy
@@ -1,4 +1,5 @@
 grant {
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.manager=default";
     permission com.sun.rmi.rmid.ExecOptionPermission "-Djava.security.policy=*";
+    permission com.sun.rmi.rmid.ExecOptionPermission "-DunregisterGroup.port=*";
 };
diff --git a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/security.policy b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/security.policy
index b6e691b..d1828e5 100644
--- a/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/security.policy
+++ b/jdk/test/java/rmi/activation/ActivationSystem/unregisterGroup/security.policy
@@ -21,15 +21,22 @@
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
-  // used by TestLibrary to determine test environment 
+  // used by TestLibrary to determine test environment
   permission java.util.PropertyPermission "test.classes", "read";
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // required for test to create an ActivationGroup
   permission java.lang.RuntimePermission "setFactory";
 
   // test needs to export rmid and communicate with objects on arbitrary ports
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
+
+  // required for test to get the registry port
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
 };
diff --git a/jdk/test/java/rmi/activation/CommandEnvironment/NullOptions.java b/jdk/test/java/rmi/activation/CommandEnvironment/NullOptions.java
index 3ef97e8..a1ec946 100644
--- a/jdk/test/java/rmi/activation/CommandEnvironment/NullOptions.java
+++ b/jdk/test/java/rmi/activation/CommandEnvironment/NullOptions.java
@@ -27,7 +27,6 @@
  * ActivationGroupDesc.CommandEnvironment
  * @author  Ann Wollrath
  *
- * @build NullOptions
  * @run main/othervm/timeout=240 NullOptions
  */
 
diff --git a/jdk/test/java/rmi/activation/CommandEnvironment/SetChildEnv.java b/jdk/test/java/rmi/activation/CommandEnvironment/SetChildEnv.java
index cbee67c..7b1a968 100644
--- a/jdk/test/java/rmi/activation/CommandEnvironment/SetChildEnv.java
+++ b/jdk/test/java/rmi/activation/CommandEnvironment/SetChildEnv.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -35,9 +35,10 @@
  * @author Adrian Colley
  *
  * @library ../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build Eliza Retireable Doctor Doctor_Stub SetChildEnv
- * @run main/othervm/timeout=240/policy=security.policy -Djava.compiler=NONE  SetChildEnv
+ * @build TestLibrary RMID ActivationLibrary
+ *     Eliza Retireable Doctor Doctor_Stub
+ * @run main/othervm/timeout=240/policy=security.policy
+ *     -Djava.compiler=NONE SetChildEnv
  */
 import java.rmi.*;
 import java.util.Properties;
@@ -53,31 +54,37 @@
     public static void main(String argv[])
         throws Exception
     {
+        int runningPort = TestLibrary.getUnusedRandomPort();
+
         System.out.println("java.compiler=" + System.getProperty("java.compiler"));
         // don't embed spaces in any of the test args/props, because
         // they won't be parsed properly
-        runwith (new String[0], new String[0]);
+        runwith (new String[0], new String[0], runningPort);
 
         runwith (
             new String[] { "-verbosegc" },
             new String[] { "foo.bar=SetChildEnvTest",
-                           "sun.rmi.server.doSomething=true" }
+                           "sun.rmi.server.doSomething=true" },
+            runningPort
             );
 
         runwith (
             new String[] { },
-            new String[] { "parameter.count=zero" }
+            new String[] { "parameter.count=zero" },
+            runningPort
             );
 
         runwith (
             new String[] { "-Xmx32m" },
-            new String[] { }
+            new String[] { },
+            runningPort
             );
     }
 
     private static void runwith(
         String[] params,        // extra args
-        String[] props          // extra system properties
+        String[] props,         // extra system properties
+        int port                // port on which to communicate
     )
         throws Exception
     {
@@ -89,7 +96,8 @@
 
         RMID.removeLog();
         RMID rmid = RMID.createRMID(watcher.otherEnd(), watcher.otherEnd(),
-                                    true); // debugExec turned on
+                                    true,  // debugExec turned on
+                                    true, port);
 
         rmid.start();
 
@@ -195,7 +203,7 @@
         actsys.unregisterGroup(gid);
 
         Thread.sleep(5000);
-        rmid.destroy();
+        ActivationLibrary.rmidCleanup(rmid);
     }
 
     public static class DebugExecWatcher
@@ -243,7 +251,19 @@
                     System.err.println(line);
                 }
             } catch (IOException e) {
-                e.printStackTrace();
+                /* During termination of distant rmid, StreamPipes will be broken when
+                 * distant vm terminates. A "Pipe broken" exception is expected because
+                 * DebugExecWatcher points to the same streams as StreamPipes used by RMID.
+                 * If we get this exception. We just terminate the thread.
+                 */
+                if (e.getMessage().equals("Pipe broken")) {
+                    try {
+                        str.close();
+                    } catch (IOException ioe) {}
+                }
+                else {
+                    e.printStackTrace();
+                }
             }
         }
     }
diff --git a/jdk/test/java/rmi/activation/CommandEnvironment/security.policy b/jdk/test/java/rmi/activation/CommandEnvironment/security.policy
index 14df213..fd455a6 100644
--- a/jdk/test/java/rmi/activation/CommandEnvironment/security.policy
+++ b/jdk/test/java/rmi/activation/CommandEnvironment/security.policy
@@ -27,6 +27,7 @@
   permission java.util.PropertyPermission "test.src", "read";
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 
   // required for test to create an ActivationGroup
   permission java.lang.RuntimePermission "setFactory";
diff --git a/jdk/test/java/rmi/activation/checkusage/CheckUsage.java b/jdk/test/java/rmi/activation/checkusage/CheckUsage.java
index 7f3f041..004c2eb 100644
--- a/jdk/test/java/rmi/activation/checkusage/CheckUsage.java
+++ b/jdk/test/java/rmi/activation/checkusage/CheckUsage.java
@@ -25,7 +25,7 @@
  * @bug 4259564
  *
  * @library ../../testlibrary
- * @build TestLibrary JavaVM CheckUsage
+ * @build TestLibrary JavaVM
  * @run main/othervm CheckUsage
  */
 
@@ -53,12 +53,9 @@
             rmidVM.start();
 
             // wait for registry exit
+            int rmidVMExitStatus = rmidVM.getVM().waitFor();
             System.err.println("rmid exited with status: " +
-                               rmidVM.getVM().waitFor());
-            try {
-                Thread.sleep(7000);
-            } catch (InterruptedException ie) {
-            }
+                               rmidVMExitStatus);
 
             String usage = new String(berr.toByteArray());
 
diff --git a/jdk/test/java/rmi/activation/log/LogTest.java b/jdk/test/java/rmi/activation/log/LogTest.java
index 2e503b9..53efeb4 100644
--- a/jdk/test/java/rmi/activation/log/LogTest.java
+++ b/jdk/test/java/rmi/activation/log/LogTest.java
@@ -29,7 +29,6 @@
  * boundaries
  * @author Ann Wollrath
  *
- * @build LogTest
  * @run main/othervm/timeout=240 LogTest
  */
 
diff --git a/jdk/test/java/rmi/activation/rmidViaInheritedChannel/InheritedChannelNotServerSocket.java b/jdk/test/java/rmi/activation/rmidViaInheritedChannel/InheritedChannelNotServerSocket.java
index 70e98c6..4611a83 100644
--- a/jdk/test/java/rmi/activation/rmidViaInheritedChannel/InheritedChannelNotServerSocket.java
+++ b/jdk/test/java/rmi/activation/rmidViaInheritedChannel/InheritedChannelNotServerSocket.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -29,10 +29,8 @@
  * @author Peter Jones
  *
  * @library ../../testlibrary
- * @build RMID ActivationLibrary
- * @build InheritedChannelNotServerSocket
- * @run main/othervm/timeout=240 -Djava.rmi.activation.port=5398
- *     InheritedChannelNotServerSocket
+ * @build TestLibrary RMID ActivationLibrary
+ * @run main/othervm/timeout=240 InheritedChannelNotServerSocket
  */
 
 import java.io.IOException;
@@ -55,8 +53,6 @@
 import java.rmi.server.UnicastRemoteObject;
 
 public class InheritedChannelNotServerSocket {
-
-    private static final int PORT = 5398;
     private static final Object lock = new Object();
     private static boolean notified = false;
 
@@ -79,7 +75,8 @@
 
     public static void main(String[] args) throws Exception {
         System.err.println("\nRegression test for bug 6261402\n");
-
+        System.setProperty("java.rmi.activation.port",
+                           Integer.toString(TestLibrary.INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT));
         RMID rmid = null;
         Callback obj = null;
         try {
@@ -91,7 +88,8 @@
             Callback proxy =
                 (Callback) UnicastRemoteObject.exportObject(obj, 0);
             Registry registry =
-                LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
+                LocateRegistry.createRegistry(
+                    TestLibrary.INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT);
             registry.bind("Callback", proxy);
 
             /*
@@ -99,7 +97,8 @@
              */
             System.err.println("start rmid with inherited channel");
             RMID.removeLog();
-            rmid = RMID.createRMID(System.out, System.err, true, true, PORT);
+            rmid = RMID.createRMID(System.out, System.err, true, true,
+                                   TestLibrary.INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT);
             rmid.addOptions(new String[]{
                 "-Djava.nio.channels.spi.SelectorProvider=" +
                 "InheritedChannelNotServerSocket$SP"});
@@ -122,7 +121,7 @@
             if (obj != null) {
                 UnicastRemoteObject.unexportObject(obj, true);
             }
-            ActivationLibrary.rmidCleanup(rmid, PORT);
+            ActivationLibrary.rmidCleanup(rmid);
         }
     }
 
@@ -175,7 +174,7 @@
                 try {
                     System.err.println("notify test...");
                     Registry registry =
-                        LocateRegistry.getRegistry(TestLibrary.REGISTRY_PORT);
+                        LocateRegistry.getRegistry(TestLibrary.INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT);
                     Callback obj = (Callback) registry.lookup("Callback");
                     obj.notifyTest();
                 } catch (NotBoundException nbe) {
diff --git a/jdk/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java b/jdk/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java
index 170e171..be9234d 100644
--- a/jdk/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java
+++ b/jdk/test/java/rmi/activation/rmidViaInheritedChannel/RmidViaInheritedChannel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,9 +27,8 @@
  * @author Ann Wollrath
  *
  * @library ../../testlibrary
- * @build RMID ActivationLibrary
- * @build RmidViaInheritedChannel
- * @run main/othervm/timeout=240 -Djava.rmi.activation.port=5398 RmidViaInheritedChannel
+ * @build TestLibrary RMID ActivationLibrary
+ * @run main/othervm/timeout=240 RmidViaInheritedChannel
  */
 
 import java.io.IOException;
@@ -48,8 +47,6 @@
 import java.rmi.server.UnicastRemoteObject;
 
 public class RmidViaInheritedChannel implements Callback {
-
-    private static final int PORT = 5398;
     private static final Object lock = new Object();
     private static boolean notified = false;
 
@@ -64,7 +61,8 @@
     }
 
     public static void main(String[] args) throws Exception {
-
+        System.setProperty("java.rmi.activation.port",
+                           Integer.toString(TestLibrary.RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT));
         RMID rmid = null;
         Callback obj = null;
 
@@ -77,7 +75,8 @@
             Callback proxy = (Callback)
                 UnicastRemoteObject.exportObject(obj, 0);
             Registry registry =
-                LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
+                LocateRegistry.createRegistry(
+                    TestLibrary.RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT);
             registry.bind("Callback", proxy);
 
             /*
@@ -85,7 +84,8 @@
              */
             System.err.println("start rmid with inherited channel");
             RMID.removeLog();
-            rmid = RMID.createRMID(System.out, System.err, true, false, PORT);
+            rmid = RMID.createRMID(System.out, System.err, true, false,
+                                   TestLibrary.RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT);
             rmid.addOptions(new String[]{
                 "-Djava.nio.channels.spi.SelectorProvider=RmidViaInheritedChannel$RmidSelectorProvider"});
             rmid.start();
@@ -108,7 +108,7 @@
             if (obj != null) {
                 UnicastRemoteObject.unexportObject(obj, true);
             }
-            ActivationLibrary.rmidCleanup(rmid, PORT);
+            ActivationLibrary.rmidCleanup(rmid);
         }
     }
 
@@ -166,7 +166,8 @@
                 channel = ServerSocketChannel.open();
                 ServerSocket serverSocket = channel.socket();
                 serverSocket.bind(
-                     new InetSocketAddress(InetAddress.getLocalHost(), PORT));
+                     new InetSocketAddress(InetAddress.getLocalHost(),
+                     TestLibrary.RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT));
                 System.err.println("serverSocket = " + serverSocket);
 
                 /*
@@ -175,7 +176,7 @@
                 try {
                     System.err.println("notify test...");
                     Registry registry =
-                        LocateRegistry.getRegistry(TestLibrary.REGISTRY_PORT);
+                        LocateRegistry.getRegistry(TestLibrary.RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT);
                     Callback obj = (Callback) registry.lookup("Callback");
                     obj.notifyTest();
                 } catch (NotBoundException nbe) {
diff --git a/jdk/test/java/rmi/activation/rmidViaInheritedChannel/rmid.security.policy b/jdk/test/java/rmi/activation/rmidViaInheritedChannel/rmid.security.policy
index ceee4d7..9ddb556 100644
--- a/jdk/test/java/rmi/activation/rmidViaInheritedChannel/rmid.security.policy
+++ b/jdk/test/java/rmi/activation/rmidViaInheritedChannel/rmid.security.policy
@@ -2,4 +2,5 @@
     permission java.lang.RuntimePermission "selectorProvider";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.nio.ch";
     permission java.net.SocketPermission "*", "connect,accept";
+    permission java.util.PropertyPermission "java.rmi.activation.port", "write";
 };
diff --git a/jdk/test/java/rmi/dgc/VMID/CheckVMID.java b/jdk/test/java/rmi/dgc/VMID/CheckVMID.java
index dcdc9fd..0b69ff4 100644
--- a/jdk/test/java/rmi/dgc/VMID/CheckVMID.java
+++ b/jdk/test/java/rmi/dgc/VMID/CheckVMID.java
@@ -30,7 +30,7 @@
  * @author Ann Wollrath
  *
  * @library ../../testlibrary
- * @build CheckVMID
+ * @build TestLibrary
  * @run main/othervm/policy=security.policy CheckVMID
  */
 
diff --git a/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java b/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java
index c416063..6a47245 100644
--- a/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java
+++ b/jdk/test/java/rmi/dgc/dgcAckFailure/DGCAckFailure.java
@@ -30,8 +30,7 @@
  * rather than pinning it indefinitely.
  * @author Peter Jones
  *
- * @build DGCAckFailure
- * @build DGCAckFailure_Stub
+ * @build DGCAckFailure DGCAckFailure_Stub
  * @run main/othervm DGCAckFailure
  */
 
diff --git a/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation.java b/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation.java
index 246c2b5..4043268 100644
--- a/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation.java
+++ b/jdk/test/java/rmi/dgc/dgcImplInsulation/DGCImplInsulation.java
@@ -31,9 +31,7 @@
  * @author Peter Jones
  *
  * @library ../../testlibrary
- * @build TestLibrary
- * @build DGCImplInsulation
- * @build DGCImplInsulation_Stub
+ * @build TestLibrary DGCImplInsulation_Stub
  * @run main/othervm/policy=security.policy DGCImplInsulation
  */
 
diff --git a/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java b/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java
index 10cb15f..b2f0af6 100644
--- a/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java
+++ b/jdk/test/java/rmi/dgc/retryDirtyCalls/RetryDirtyCalls.java
@@ -29,8 +29,7 @@
  * renewing that lease at all after the first failure.
  * @author Peter Jones (inspired by Adrian Colley's test case in 4268258)
  *
- * @build RetryDirtyCalls
- * @build RetryDirtyCalls_Stub
+ * @build RetryDirtyCalls RetryDirtyCalls_Stub
  * @run main/othervm RetryDirtyCalls
  */
 
diff --git a/jdk/test/java/rmi/invalidName/InvalidName.java b/jdk/test/java/rmi/invalidName/InvalidName.java
index 8d522f5..74da1a5 100644
--- a/jdk/test/java/rmi/invalidName/InvalidName.java
+++ b/jdk/test/java/rmi/invalidName/InvalidName.java
@@ -32,7 +32,7 @@
  * @author Laird Dornin
  *
  * @library ../testlibrary
- * @build InvalidName
+ * @build TestLibrary
  * @run main/othervm InvalidName
  */
 
diff --git a/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java b/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java
index 2436920..08d030e 100644
--- a/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java
+++ b/jdk/test/java/rmi/registry/altSecurityManager/AltSecurityManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,8 +27,7 @@
  * @author Laird Dornin
  *
  * @library ../../testlibrary
- * @build StreamPipe TestParams TestLibrary JavaVM
- * @build AltSecurityManager TestSecurityManager
+ * @build TestLibrary JavaVM RMID TestSecurityManager
  * @run main/othervm AltSecurityManager
  */
 
@@ -41,23 +40,41 @@
  * if registry and rmid take too long to exit.
  */
 public class AltSecurityManager implements Runnable {
-
+    private final int regPort;
     // variable to hold registry and rmid children
     static JavaVM vm = null;
 
     // names of utilities
     static String utilityToStart = null;
-    static String registry = "sun.rmi.registry.RegistryImpl";
-    static String rmid = "sun.rmi.server.Activation";
+    static final String REGISTRY_IMPL = "sun.rmi.registry.RegistryImpl";
+    static final String ACTIVATION = "sun.rmi.server.Activation";
 
     // children should exit in at least this time.
     static long TIME_OUT = 15000;
 
+    public AltSecurityManager(int port) {
+        if (port <= 0) {
+            TestLibrary.bomb("Port must be greater then 0.");
+        }
+
+        this.regPort = port;
+    }
+
     public void run() {
         try {
-            vm = new JavaVM(utilityToStart,
-                            " -Djava.security.manager=TestSecurityManager",
-                            "");
+            if (utilityToStart.equals(REGISTRY_IMPL)) {
+                vm = new JavaVM(utilityToStart,
+                        " -Djava.security.manager=TestSecurityManager",
+                        Integer.toString(regPort));
+            } else if (utilityToStart.contains(ACTIVATION)) {
+                vm = new JavaVM(utilityToStart,
+                        " -Djava.security.manager=TestSecurityManager",
+                        "-port " + Integer.toString(regPort));
+            } else {
+                TestLibrary.bomb("Utility to start must be " + REGISTRY_IMPL +
+                        " or " + ACTIVATION);
+            }
+
             System.err.println("starting " + utilityToStart);
             vm.start();
             vm.getVM().waitFor();
@@ -75,7 +92,8 @@
         utilityToStart = utility;
 
         try {
-            Thread thread = new Thread(new AltSecurityManager());
+            int port = TestLibrary.getUnusedRandomPort();
+            Thread thread = new Thread(new AltSecurityManager(port));
             System.err.println("expecting RuntimeException for " +
                                "checkListen in child process");
             long start = System.currentTimeMillis();
@@ -90,8 +108,8 @@
 
                 // dont pollute other tests; increase the likelihood
                 // that rmid will go away if it did not exit already.
-                if (utility.equals(rmid)) {
-                    RMID.shutdown();
+                if (utility.equals(ACTIVATION)) {
+                    RMID.shutdown(port);
                 }
 
                 TestLibrary.bomb(utilityToStart +
@@ -111,10 +129,10 @@
             System.err.println("\nRegression test for bug 4183202\n");
 
             // make sure the registry exits early.
-            ensureExit(registry);
+            ensureExit(REGISTRY_IMPL);
 
             // make sure rmid exits early
-            ensureExit(rmid);
+            ensureExit(ACTIVATION);
 
             System.err.println("test passed");
 
diff --git a/jdk/test/java/rmi/registry/checkusage/CheckUsage.java b/jdk/test/java/rmi/registry/checkusage/CheckUsage.java
index 71deb55..19dac5b 100644
--- a/jdk/test/java/rmi/registry/checkusage/CheckUsage.java
+++ b/jdk/test/java/rmi/registry/checkusage/CheckUsage.java
@@ -27,7 +27,7 @@
  * @author Laird Dornin
  *
  * @library ../../testlibrary
- * @build TestLibrary JavaVM CheckUsage
+ * @build TestLibrary JavaVM
  * @run main/othervm CheckUsage
  */
 
diff --git a/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java b/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java
index 10534e1..99ac5f0 100644
--- a/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java
+++ b/jdk/test/java/rmi/registry/classPathCodebase/ClassPathCodebase.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,7 @@
  * @author Peter Jones
  *
  * @library ../../testlibrary
- * @build ClassPathCodebase Dummy
+ * @build TestLibrary Dummy
  * @run main/othervm/policy=security.policy ClassPathCodebase
  */
 
@@ -83,11 +83,12 @@
                 System.getProperty("java.home") + File.separator +
                 "bin" + File.separator + "rmiregistry";
 
+            int port = TestLibrary.getUnusedRandomPort();
             String cmdarray[] = new String[] {
                 rmiregistryCommand,
                 "-J-Denv.class.path=.",
                 "-J-Djava.rmi.server.codebase=" + exportCodebaseURL,
-                Integer.toString(TestLibrary.REGISTRY_PORT) };
+                Integer.toString(port) };
 
             System.err.println("\nCommand used to spawn rmiregistry process:");
             System.err.println("\t" + Arrays.asList(cmdarray).toString());
@@ -118,7 +119,7 @@
              * dummy object to it.
              */
             Registry registry = LocateRegistry.getRegistry(
-                "localhost", TestLibrary.REGISTRY_PORT);
+                "localhost", port);
 
             try {
                 registry.bind(dummyBinding, dummyObject);
@@ -133,7 +134,7 @@
                 {
                     System.err.println(
                         "Error: another registry running on port " +
-                        TestLibrary.REGISTRY_PORT + "?");
+                        port + "?");
                 }
                 throw e;
             }
diff --git a/jdk/test/java/rmi/registry/emptyName/EmptyName.java b/jdk/test/java/rmi/registry/emptyName/EmptyName.java
index c3e9f59..d572b8f 100644
--- a/jdk/test/java/rmi/registry/emptyName/EmptyName.java
+++ b/jdk/test/java/rmi/registry/emptyName/EmptyName.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, 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
@@ -24,6 +24,8 @@
 /* @test
  * @bug 4399304
  * @summary check that registry allows empty names
+ * @library ../../testlibrary
+ * @build TestLibrary
  * @run main/othervm EmptyName
  */
 import java.rmi.registry.LocateRegistry;
@@ -32,7 +34,7 @@
 
 public class EmptyName {
     public static void main(String[] args) throws Exception {
-        Registry impl = LocateRegistry.createRegistry(0);
+        Registry impl = TestLibrary.createRegistryOnUnusedPort();
         Registry stub = (Registry) RemoteObject.toStub(impl);
         stub.bind("", stub);
         stub.lookup("");
diff --git a/jdk/test/java/rmi/registry/interfaceHash/InterfaceHash.java b/jdk/test/java/rmi/registry/interfaceHash/InterfaceHash.java
index a3605f5..2eba1d6 100644
--- a/jdk/test/java/rmi/registry/interfaceHash/InterfaceHash.java
+++ b/jdk/test/java/rmi/registry/interfaceHash/InterfaceHash.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -35,8 +35,8 @@
  * "interface hash": 4905912898345647071L.
  *
  * @author Peter Jones
- * @build InterfaceHash
- * @build ReferenceRegistryStub
+ * @library ../../testlibrary
+ * @build TestLibrary ReferenceRegistryStub
  * @run main/othervm InterfaceHash
  */
 
@@ -58,7 +58,7 @@
 
 public class InterfaceHash {
 
-    private static final int PORT = 2020;
+    private static final int PORT = TestLibrary.getUnusedRandomPort();
     private static final String NAME = "WMM";
 
     public static void main(String[] args) throws Exception {
diff --git a/jdk/test/java/rmi/registry/multipleRegistries/MultipleRegistries.java b/jdk/test/java/rmi/registry/multipleRegistries/MultipleRegistries.java
index 198aa63..1945ebe 100644
--- a/jdk/test/java/rmi/registry/multipleRegistries/MultipleRegistries.java
+++ b/jdk/test/java/rmi/registry/multipleRegistries/MultipleRegistries.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,8 @@
  * @summary Can't run multiple registries in the same VM
  * @author Ann Wollrath
  *
- * @build MultipleRegistries
+ * @library ../../testlibrary
+ * @build TestLibrary
  * @run main/othervm/timeout=240 MultipleRegistries
  */
 
@@ -58,12 +59,13 @@
             System.err.println("proxy = " + proxy);
 
             System.err.println("export registries");
-            Registry registryImpl1 = LocateRegistry.createRegistry(2030);
-            Registry registryImpl2 = LocateRegistry.createRegistry(2040);
-
+            Registry registryImpl1 = TestLibrary.createRegistryOnUnusedPort();
+            int port1 = TestLibrary.getRegistryPort(registryImpl1);
+            Registry registryImpl2 = TestLibrary.createRegistryOnUnusedPort();
+            int port2 = TestLibrary.getRegistryPort(registryImpl2);
             System.err.println("bind remote object in registries");
-            Registry registry1 = LocateRegistry.getRegistry(2030);
-            Registry registry2 = LocateRegistry.getRegistry(2040);
+            Registry registry1 = LocateRegistry.getRegistry(port1);
+            Registry registry2 = LocateRegistry.getRegistry(port2);
 
             registry1.bind(NAME, proxy);
             registry2.bind(NAME, proxy);
diff --git a/jdk/test/java/rmi/registry/readTest/readTest.java b/jdk/test/java/rmi/registry/readTest/readTest.java
index 8890ea1..a636f8d 100644
--- a/jdk/test/java/rmi/registry/readTest/readTest.java
+++ b/jdk/test/java/rmi/registry/readTest/readTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,18 +30,19 @@
 public class readTest {
 
     public static void main(String args[]) throws Exception {
-        int port = 7491;
         try {
             testPkg.Server obj = new testPkg.Server();
             testPkg.Hello stub = (testPkg.Hello) UnicastRemoteObject.exportObject(obj, 0);
             // Bind the remote object's stub in the registry
-            Registry registry = LocateRegistry.getRegistry(port);
+            Registry registry =
+                LocateRegistry.getRegistry(TestLibrary.READTEST_REGISTRY_PORT);
             registry.bind("Hello", stub);
 
             System.err.println("Server ready");
 
             // now, let's test client
-            testPkg.Client client = new testPkg.Client(port);
+            testPkg.Client client =
+                new testPkg.Client(TestLibrary.READTEST_REGISTRY_PORT);
             String testStubReturn = client.testStub();
             if(!testStubReturn.equals(obj.hello)) {
                 throw new RuntimeException("Test Fails : unexpected string from stub call");
diff --git a/jdk/test/java/rmi/registry/readTest/readTest.sh b/jdk/test/java/rmi/registry/readTest/readTest.sh
index cb600d5..47221ae 100644
--- a/jdk/test/java/rmi/registry/readTest/readTest.sh
+++ b/jdk/test/java/rmi/registry/readTest/readTest.sh
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2011, 2012, 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,7 +23,9 @@
 
 # @test
 # @bug 7102369 7094468 7100592
-# @summary remove java.rmi.server.codebase property parsing from registyimpl
+# @library ../../testlibrary
+# @build TestLibrary
+# @summary remove java.rmi.server.codebase property parsing from RegistryImpl
 # @run shell readTest.sh
 
 OS=`uname -s`
@@ -33,33 +35,48 @@
     FS="/"
     FILEURL="file:"
     ;;
-  Windows* | CYGWIN* )
+  Windows* )
     PS=";"
     FS="\\"
     FILEURL="file:/"
     ;;
+  CYGWIN* )
+    PS=";"
+    FS="/"
+    FILEURL="file:/"
+    ;;
   * )
     echo "Unrecognized system!"
     exit 1;
     ;;
 esac
 
+TEST_CLASSPATH=.$PS${TESTCLASSPATH:-$TESTCLASSES}
 cp -r ${TESTSRC}${FS}* .
 ${TESTJAVA}${FS}bin${FS}javac testPkg${FS}*java
-${TESTJAVA}${FS}bin${FS}javac readTest.java
+${TESTJAVA}${FS}bin${FS}javac -cp $TEST_CLASSPATH readTest.java
 
 mkdir rmi_tmp
 RMIREG_OUT=rmi.out
 #start rmiregistry without any local classes on classpath
 cd rmi_tmp
-${TESTJAVA}${FS}bin${FS}rmiregistry 7491 > ..${FS}${RMIREG_OUT} 2>&1 &
+# NOTE: This RMI Registry port must match TestLibrary.READTEST_REGISTRY_PORT
+${TESTJAVA}${FS}bin${FS}rmiregistry 64005 > ..${FS}${RMIREG_OUT} 2>&1 &
 RMIREG_PID=$!
 # allow some time to start
 sleep 3
 cd ..
 
+case "$OS" in
+  CYGWIN* )
+    CODEBASE=`cygpath -w $PWD`
+    ;;
+  * )
+    CODEBASE=`pwd`
+    ;;  
+esac
 # trailing / after code base is important for rmi codebase property.
-${TESTJAVA}${FS}bin${FS}java -Djava.rmi.server.codebase=${FILEURL}`pwd`/ readTest > OUT.TXT 2>&1 &
+${TESTJAVA}${FS}bin${FS}java -cp $TEST_CLASSPATH -Djava.rmi.server.codebase=${FILEURL}$CODEBASE/ readTest > OUT.TXT 2>&1 &
 TEST_PID=$!
 #bulk of testcase - let it run for a while
 sleep 5
diff --git a/jdk/test/java/rmi/registry/reexport/Reexport.java b/jdk/test/java/rmi/registry/reexport/Reexport.java
index be71632..c209f7c 100644
--- a/jdk/test/java/rmi/registry/reexport/Reexport.java
+++ b/jdk/test/java/rmi/registry/reexport/Reexport.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,7 @@
  * @bug 4120329
  * @summary RMI registry creation is impossible if first attempt fails.
  * @library ../../testlibrary
- * @build StreamPipe TestParams TestLibrary JavaVM
- * @build RegistryRunner RegistryRunner_Stub
- * @build Reexport
+ * @build TestLibrary JavaVM RegistryRunner RegistryRunner_Stub
  * @run main/othervm Reexport
  */
 
@@ -49,22 +47,21 @@
 import java.rmi.server.*;
 
 public class Reexport {
-    static public final int regport = TestLibrary.REGISTRY_PORT;
-
     static public void main(String[] argv) {
 
         Registry reg = null;
+        int regPort = TestLibrary.getUnusedRandomPort();
 
         try {
             System.err.println("\nregression test for 4120329\n");
 
             // establish the registry (we hope)
-            System.err.println("Starting registry on port " + regport);
-            Reexport.makeRegistry(regport);
+            System.err.println("Starting registry on port " + regPort);
+            Reexport.makeRegistry(regPort);
 
             // Get a handle to the registry
             System.err.println("Creating duplicate registry, this should fail...");
-            reg = createReg(true);
+            reg = createReg(true, regPort);
 
             if (reg != null) {
                 TestLibrary.bomb("failed was able to duplicate the registry?!?");
@@ -73,7 +70,7 @@
             // Kill the first registry.
             System.err.println("Bringing down the first registry");
             try {
-                Reexport.killRegistry();
+                Reexport.killRegistry(regPort);
             } catch (Exception foo) {
             }
 
@@ -81,7 +78,7 @@
             System.err.println("Trying again to start our own " +
                                "registry... this should work");
 
-            reg = createReg(false);
+            reg = createReg(false, regPort);
 
             if (reg == null) {
                 TestLibrary.bomb("Could not create registry on second try");
@@ -93,17 +90,17 @@
             TestLibrary.bomb(e);
         } finally {
             // dont leave the registry around to affect other tests.
-            killRegistry();
+            killRegistry(regPort);
 
             reg = null;
         }
     }
 
-    static Registry createReg(boolean remoteOk) {
+    static Registry createReg(boolean remoteOk, int port) {
         Registry reg = null;
 
         try {
-            reg = LocateRegistry.createRegistry(regport);
+            reg = LocateRegistry.createRegistry(port);
         } catch (Throwable e) {
             if (remoteOk) {
                 System.err.println("EXPECTING PORT IN USE EXCEPTION:");
@@ -140,10 +137,10 @@
     }
     private static Process subreg = null;
 
-    public static void killRegistry() {
+    public static void killRegistry(int port) {
         if (Reexport.subreg != null) {
 
-            RegistryRunner.requestExit();
+            RegistryRunner.requestExit(port);
 
             try {
                 Reexport.subreg.waitFor();
diff --git a/jdk/test/java/rmi/reliability/benchmark/runRmiBench.sh b/jdk/test/java/rmi/reliability/benchmark/runRmiBench.sh
index cfa23f7..98a31d1 100644
--- a/jdk/test/java/rmi/reliability/benchmark/runRmiBench.sh
+++ b/jdk/test/java/rmi/reliability/benchmark/runRmiBench.sh
@@ -27,20 +27,20 @@
 #          used to run the test under JTREG.
 #
 # @build bench.BenchInfo bench.HtmlReporter bench.Util bench.Benchmark 
-# @build bench.Reporter bench.XmlReporter bench.ConfigFormatException 
-# @build bench.Harness bench.TextReporter bench.rmi.BenchServer 
-# @build bench.rmi.DoubleArrayCalls bench.rmi.LongCalls bench.rmi.ShortCalls
-# @build bench.rmi.BenchServerImpl bench.rmi.DoubleCalls 
-# @build bench.rmi.Main bench.rmi.SmallObjTreeCalls
-# @build bench.rmi.BooleanArrayCalls bench.rmi.ExceptionCalls 
-# @build bench.rmi.NullCalls bench.rmi.BooleanCalls bench.rmi.ExportObjs 
-# @build bench.rmi.ObjArrayCalls bench.rmi.ByteArrayCalls 
-# @build bench.rmi.FloatArrayCalls bench.rmi.ObjTreeCalls
-# @build bench.rmi.ByteCalls bench.rmi.FloatCalls bench.rmi.ProxyArrayCalls
-# @build bench.rmi.CharArrayCalls bench.rmi.IntArrayCalls 
-# @build bench.rmi.RemoteObjArrayCalls bench.rmi.CharCalls bench.rmi.IntCalls
-# @build bench.rmi.ClassLoading bench.rmi.LongArrayCalls 
-# @build bench.rmi.ShortArrayCalls bench.rmi.altroot.Node
+#     bench.Reporter bench.XmlReporter bench.ConfigFormatException 
+#     bench.Harness bench.TextReporter bench.rmi.BenchServer 
+#     bench.rmi.DoubleArrayCalls bench.rmi.LongCalls bench.rmi.ShortCalls
+#     bench.rmi.BenchServerImpl bench.rmi.DoubleCalls 
+#     bench.rmi.Main bench.rmi.SmallObjTreeCalls
+#     bench.rmi.BooleanArrayCalls bench.rmi.ExceptionCalls 
+#     bench.rmi.NullCalls bench.rmi.BooleanCalls bench.rmi.ExportObjs 
+#     bench.rmi.ObjArrayCalls bench.rmi.ByteArrayCalls 
+#     bench.rmi.FloatArrayCalls bench.rmi.ObjTreeCalls
+#     bench.rmi.ByteCalls bench.rmi.FloatCalls bench.rmi.ProxyArrayCalls
+#     bench.rmi.CharArrayCalls bench.rmi.IntArrayCalls 
+#     bench.rmi.RemoteObjArrayCalls bench.rmi.CharCalls bench.rmi.IntCalls
+#     bench.rmi.ClassLoading bench.rmi.LongArrayCalls 
+#     bench.rmi.ShortArrayCalls bench.rmi.altroot.Node
 #
 # @run shell/timeout=1800 runRmiBench.sh
 #
diff --git a/jdk/test/java/rmi/reliability/benchmark/runSerialBench.sh b/jdk/test/java/rmi/reliability/benchmark/runSerialBench.sh
index aac0d3f..28fa90a 100644
--- a/jdk/test/java/rmi/reliability/benchmark/runSerialBench.sh
+++ b/jdk/test/java/rmi/reliability/benchmark/runSerialBench.sh
@@ -27,22 +27,22 @@
 #          used to run the test under JTREG.
 #
 # @build bench.BenchInfo bench.HtmlReporter bench.Util bench.Benchmark 
-# @build bench.Reporter bench.XmlReporter bench.ConfigFormatException 
-# @build bench.Harness bench.TextReporter
-# @build bench.serial.BooleanArrays bench.serial.Booleans
-# @build bench.serial.ByteArrays bench.serial.Bytes bench.serial.CharArrays
-# @build bench.serial.Chars bench.serial.ClassDesc bench.serial.Cons
-# @build bench.serial.CustomDefaultObjTrees bench.serial.CustomObjTrees
-# @build bench.serial.DoubleArrays bench.serial.Doubles
-# @build bench.serial.ExternObjTrees bench.serial.FloatArrays
-# @build bench.serial.Floats bench.serial.GetPutFieldTrees
-# @build bench.serial.IntArrays bench.serial.Ints bench.serial.LongArrays
-# @build bench.serial.Longs bench.serial.Main bench.serial.ObjArrays
-# @build bench.serial.ObjTrees bench.serial.ProxyArrays
-# @build bench.serial.ProxyClassDesc bench.serial.RepeatObjs
-# @build bench.serial.ReplaceTrees bench.serial.ShortArrays
-# @build bench.serial.Shorts bench.serial.SmallObjTrees
-# @build bench.serial.StreamBuffer bench.serial.Strings
+#     bench.Reporter bench.XmlReporter bench.ConfigFormatException 
+#     bench.Harness bench.TextReporter
+#     bench.serial.BooleanArrays bench.serial.Booleans
+#     bench.serial.ByteArrays bench.serial.Bytes bench.serial.CharArrays
+#     bench.serial.Chars bench.serial.ClassDesc bench.serial.Cons
+#     bench.serial.CustomDefaultObjTrees bench.serial.CustomObjTrees
+#     bench.serial.DoubleArrays bench.serial.Doubles
+#     bench.serial.ExternObjTrees bench.serial.FloatArrays
+#     bench.serial.Floats bench.serial.GetPutFieldTrees
+#     bench.serial.IntArrays bench.serial.Ints bench.serial.LongArrays
+#     bench.serial.Longs bench.serial.Main bench.serial.ObjArrays
+#     bench.serial.ObjTrees bench.serial.ProxyArrays
+#     bench.serial.ProxyClassDesc bench.serial.RepeatObjs
+#     bench.serial.ReplaceTrees bench.serial.ShortArrays
+#     bench.serial.Shorts bench.serial.SmallObjTrees
+#     bench.serial.StreamBuffer bench.serial.Strings
 #
 # @run shell/timeout=1800 runSerialBench.sh
 #
diff --git a/jdk/test/java/rmi/reliability/juicer/AppleUserImpl.java b/jdk/test/java/rmi/reliability/juicer/AppleUserImpl.java
index 775ca5d..70b187e 100644
--- a/jdk/test/java/rmi/reliability/juicer/AppleUserImpl.java
+++ b/jdk/test/java/rmi/reliability/juicer/AppleUserImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -55,23 +55,24 @@
  * has been reached.
  *
  * @library ../../testlibrary
- *
- * @build Apple AppleEvent AppleImpl AppleUserImpl
- * @build Orange OrangeEcho OrangeEchoImpl OrangeImpl
- * @build ApplicationServer
+ * @build TestLibrary
+ *     Apple AppleEvent AppleImpl
+ *     Orange OrangeEcho OrangeEchoImpl OrangeImpl
+ *     ApplicationServer
  *
  * @run main/othervm/policy=security.policy AppleUserImpl -seconds 30
  *
  * @author Peter Jones, Nigel Daley
  */
 
-import java.rmi.RemoteException;
 import java.rmi.NoSuchObjectException;
-import java.rmi.server.UnicastRemoteObject;
+import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.UnicastRemoteObject;
 import java.util.Random;
-import java.util.logging.Logger;
 import java.util.logging.Level;
+import java.util.logging.Logger;
 
 /**
  * The AppleUserImpl class implements the behavior of the remote
@@ -80,7 +81,7 @@
  * AppleUserThread is created for each apple.
  */
 public class AppleUserImpl extends UnicastRemoteObject implements AppleUser {
-
+    private static int registryPort = -1;
     private static final Logger logger =
         Logger.getLogger("reliability.appleuser");
     private static int threadNum = 0;
@@ -308,8 +309,10 @@
 
             synchronized (user) {
                 // create new registry and bind new AppleUserImpl in registry
-                LocateRegistry.createRegistry(2006);
-                LocateRegistry.getRegistry(2006).rebind("AppleUser",user);
+                Registry registry = TestLibrary.createRegistryOnUnusedPort();
+                registryPort = TestLibrary.getRegistryPort(registry);
+                LocateRegistry.getRegistry(registryPort).rebind("AppleUser",
+                                                                 user);
 
                 // start the other server if applicable
                 if (othervm) {
@@ -318,7 +321,9 @@
                         "started in separate process");
                 } else {
                     Class app = Class.forName("ApplicationServer");
-                    server = new Thread((Runnable) app.newInstance());
+                    java.lang.reflect.Constructor appConstructor =
+                            app.getDeclaredConstructor(new Class[] {Integer.TYPE});
+                    server = new Thread((Runnable) appConstructor.newInstance(registryPort));
                     logger.log(Level.INFO, "Starting application server " +
                         "in same process");
                     server.start();
diff --git a/jdk/test/java/rmi/reliability/juicer/ApplicationServer.java b/jdk/test/java/rmi/reliability/juicer/ApplicationServer.java
index 1d1beb2..9e4b404 100644
--- a/jdk/test/java/rmi/reliability/juicer/ApplicationServer.java
+++ b/jdk/test/java/rmi/reliability/juicer/ApplicationServer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -38,18 +38,21 @@
     private static final int LOOKUP_ATTEMPTS = 5;
     private static final int DEFAULT_NUMAPPLES = 10;
     private static final String DEFAULT_REGISTRYHOST = "localhost";
+    private static final int DEFAULT_REGISTRYPORT = -1;
     private final int numApples;
     private final String registryHost;
+    private final int registryPort;
     private final Apple[] apples;
     private AppleUser user;
 
-    ApplicationServer() {
-        this(DEFAULT_NUMAPPLES, DEFAULT_REGISTRYHOST);
+    ApplicationServer(int registryPort) {
+        this(DEFAULT_NUMAPPLES, DEFAULT_REGISTRYHOST, registryPort);
     }
 
-    ApplicationServer(int numApples, String registryHost) {
+    ApplicationServer(int numApples, String registryHost, int registryPort) {
         this.numApples = numApples;
         this.registryHost = registryHost;
+        this.registryPort = registryPort;
         apples = new Apple[numApples];
     }
 
@@ -71,7 +74,7 @@
             for (i = 0; i < LOOKUP_ATTEMPTS; i++) {
                 try {
                     Registry registry = LocateRegistry.getRegistry(
-                        registryHost, 2006);
+                           registryHost, registryPort);
                     user = (AppleUser) registry.lookup("AppleUser");
                     user.startTest();
                     break; //successfully obtained AppleUser
@@ -120,16 +123,20 @@
     private static void usage() {
         System.err.println("Usage: ApplicationServer [-numApples <numApples>]");
         System.err.println("                         [-registryHost <host>]");
+        System.err.println("                         -registryPort <port>");
         System.err.println("  numApples  The number of apples (threads) to use.");
         System.err.println("             The default is 10 apples.");
         System.err.println("  host       The host running rmiregistry " +
                                          "which contains AppleUser.");
         System.err.println("             The default is \"localhost\".");
+        System.err.println("  port       The port the rmiregistry is running" +
+                                         "on.");
         System.err.println();
     }
 
     public static void main(String[] args) {
         int num = DEFAULT_NUMAPPLES;
+        int port = -1;
         String host = DEFAULT_REGISTRYHOST;
 
         // parse command line args
@@ -142,17 +149,25 @@
                 } else if (arg.equals("-registryHost")) {
                     i++;
                     host = args[i];
+                } else if (arg.equals("-registryPort")) {
+                    i++;
+                    port = Integer.parseInt(args[i]);
                 } else {
                     usage();
                 }
             }
+
+            if (port == -1) {
+                usage();
+                throw new RuntimeException("Port must be specified.");
+            }
         } catch (Throwable t) {
             usage();
             throw new RuntimeException("TEST FAILED: Bad argument");
         }
 
         // start the client server
-        Thread server = new Thread(new ApplicationServer(num,host));
+        Thread server = new Thread(new ApplicationServer(num,host,port));
         server.start();
         // main should exit once all exported remote objects are gc'd
     }
diff --git a/jdk/test/java/rmi/server/ObjID/randomIDs/RandomIDs.java b/jdk/test/java/rmi/server/ObjID/randomIDs/RandomIDs.java
index 9c20ab4..ebe7192 100644
--- a/jdk/test/java/rmi/server/ObjID/randomIDs/RandomIDs.java
+++ b/jdk/test/java/rmi/server/ObjID/randomIDs/RandomIDs.java
@@ -30,7 +30,6 @@
  * ObjID() should still generate sequential object numbers.
  * @author Peter Jones
  *
- * @build RandomIDs
  * @run main/othervm RandomIDs random
  * @run main/othervm -Djava.rmi.server.randomIDs=true RandomIDs random
  * @run main/othervm -Djava.rmi.server.randomIDs=false RandomIDs sequential
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/delegateBeforePermissionCheck/DelegateBeforePermissionCheck.java b/jdk/test/java/rmi/server/RMIClassLoader/delegateBeforePermissionCheck/DelegateBeforePermissionCheck.java
index fba4939..6187f0c 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/delegateBeforePermissionCheck/DelegateBeforePermissionCheck.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/delegateBeforePermissionCheck/DelegateBeforePermissionCheck.java
@@ -33,9 +33,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build DelegateBeforePermissionCheck
- * @build Foo
+ * @build TestLibrary Foo
  * @run main/othervm DelegateBeforePermissionCheck
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/delegateToContextLoader/DelegateToContextLoader.java b/jdk/test/java/rmi/server/RMIClassLoader/delegateToContextLoader/DelegateToContextLoader.java
index 51b5bd4..7ae4c5e 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/delegateToContextLoader/DelegateToContextLoader.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/delegateToContextLoader/DelegateToContextLoader.java
@@ -29,7 +29,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build DelegateToContextLoader Dummy
+ * @build TestLibrary Dummy
  * @run main/othervm/policy=security.policy/timeout=120 DelegateToContextLoader
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/downloadArrayClass/DownloadArrayClass.java b/jdk/test/java/rmi/server/RMIClassLoader/downloadArrayClass/DownloadArrayClass.java
index 34a21bd..9df187a 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/downloadArrayClass/DownloadArrayClass.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/downloadArrayClass/DownloadArrayClass.java
@@ -31,11 +31,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build Receiver
- * @build DownloadArrayClass
- * @build DownloadArrayClass_Stub
- * @build Foo
+ * @build TestLibrary Receiver DownloadArrayClass_Stub Foo
  * @run main/othervm/policy=security.policy DownloadArrayClass
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/getClassAnnotation/NullClass.java b/jdk/test/java/rmi/server/RMIClassLoader/getClassAnnotation/NullClass.java
index 0a0cfb7..5167fc4 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/getClassAnnotation/NullClass.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/getClassAnnotation/NullClass.java
@@ -29,7 +29,6 @@
  *
  * @library ../../../testlibrary
  * @build TestLibrary
- * @build NullClass
  * @run main/othervm NullClass
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/getClassLoader/GetClassLoader.java b/jdk/test/java/rmi/server/RMIClassLoader/getClassLoader/GetClassLoader.java
index f54a5cf..10a9cc9 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/getClassLoader/GetClassLoader.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/getClassLoader/GetClassLoader.java
@@ -29,9 +29,7 @@
  * @author Ann Wollrath
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build GetClassLoader
- * @build Foo
+ * @build TestLibrary Foo
  * @run main/othervm/policy=security.policy GetClassLoader
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java b/jdk/test/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java
index 4feed26..6d29cb2 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/loadProxyClasses/LoadProxyClasses.java
@@ -30,8 +30,8 @@
  * @author Laird Dornin
  *
  * @library ../../../testlibrary
- * @build TestLibrary FnnClass FnnUnmarshal LoadProxyClasses NonpublicInterface
- * @build NonpublicInterface1 PublicInterface PublicInterface1
+ * @build TestLibrary FnnClass FnnUnmarshal NonpublicInterface
+ *     NonpublicInterface1 PublicInterface PublicInterface1
  * @run main/othervm/policy=security.policy LoadProxyClasses
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/noSecurityManager/NoSecurityManager.java b/jdk/test/java/rmi/server/RMIClassLoader/noSecurityManager/NoSecurityManager.java
index 182db1c..93a33b9 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/noSecurityManager/NoSecurityManager.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/noSecurityManager/NoSecurityManager.java
@@ -30,7 +30,7 @@
  * been used for the RMI class loader instance.
  * @author Peter Jones
  *
- * @build NoSecurityManager Dummy LocalDummy
+ * @build Dummy LocalDummy
  * @run main/othervm/timeout=120 NoSecurityManager
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/spi/ContextInsulation.java b/jdk/test/java/rmi/server/RMIClassLoader/spi/ContextInsulation.java
index 56cd08d..de3d79b 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/spi/ContextInsulation.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/spi/ContextInsulation.java
@@ -30,11 +30,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build ContextInsulation
- * @build ServiceConfiguration
- * @build TestProvider
- * @build TestProvider2
+ * @build TestLibrary ServiceConfiguration TestProvider TestProvider2
  * @run main/othervm/policy=security.policy ContextInsulation
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/spi/DefaultProperty.java b/jdk/test/java/rmi/server/RMIClassLoader/spi/DefaultProperty.java
index 4cb8169..f91ef3d 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/spi/DefaultProperty.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/spi/DefaultProperty.java
@@ -29,10 +29,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build DefaultProperty
- * @build ServiceConfiguration
- * @build Foo
+ * @build TestLibrary ServiceConfiguration Foo
  * @run main/othervm/policy=security.policy DefaultProperty
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/spi/Installed.java b/jdk/test/java/rmi/server/RMIClassLoader/spi/Installed.java
index 23ce956..d32a8af 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/spi/Installed.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/spi/Installed.java
@@ -29,11 +29,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build Installed
- * @build ServiceConfiguration
- * @build TestProvider
- * @build TestProvider2
+ * @build TestLibrary ServiceConfiguration TestProvider TestProvider2
  * @run main/othervm/policy=security.policy Installed
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/spi/InvalidProperty.java b/jdk/test/java/rmi/server/RMIClassLoader/spi/InvalidProperty.java
index e7b157c..d41cef1 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/spi/InvalidProperty.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/spi/InvalidProperty.java
@@ -29,9 +29,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build InvalidProperty
- * @build ServiceConfiguration
+ * @build TestLibrary ServiceConfiguration
  * @run main/othervm/policy=security.policy InvalidProperty
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/spi/Property.java b/jdk/test/java/rmi/server/RMIClassLoader/spi/Property.java
index 427e5a3..6113a6e 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/spi/Property.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/spi/Property.java
@@ -29,10 +29,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build Property
- * @build ServiceConfiguration
- * @build TestProvider
+ * @build TestLibrary ServiceConfiguration TestProvider
  * @run main/othervm/policy=security.policy Property
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/useCodebaseOnly/UseCodebaseOnly.java b/jdk/test/java/rmi/server/RMIClassLoader/useCodebaseOnly/UseCodebaseOnly.java
index cd79782..dc80837 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/useCodebaseOnly/UseCodebaseOnly.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/useCodebaseOnly/UseCodebaseOnly.java
@@ -31,12 +31,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build Receiver
- * @build UseCodebaseOnly
- * @build UseCodebaseOnly_Stub
- * @build Foo
- * @build Bar
+ * @build TestLibrary Receiver UseCodebaseOnly_Stub Foo Bar
  * @run main/othervm/policy=security.policy UseCodebaseOnly
  */
 
diff --git a/jdk/test/java/rmi/server/RMIClassLoader/useGetURLs/UseGetURLs.java b/jdk/test/java/rmi/server/RMIClassLoader/useGetURLs/UseGetURLs.java
index 295b994..d80907e 100644
--- a/jdk/test/java/rmi/server/RMIClassLoader/useGetURLs/UseGetURLs.java
+++ b/jdk/test/java/rmi/server/RMIClassLoader/useGetURLs/UseGetURLs.java
@@ -30,8 +30,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build UseGetURLs Dummy
+ * @build TestLibrary Dummy
  * @run main/othervm/policy=security.policy/timeout=120 UseGetURLs
  */
 
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl.java
index f711805..209be45 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl.java
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/EchoImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -128,8 +128,9 @@
             ActivationGroup.createGroup(groupID, groupDesc, 0);
 
             EchoImpl impl = new EchoImpl(protocol);
-            System.out.println("EchoServer: binding in registry");
-            Naming.rebind("//:" + UseCustomSocketFactory.REGISTRY_PORT +
+            int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
+            System.out.println("EchoServer: binding in registry on port:" + registryPort);
+            Naming.rebind("//:" + registryPort +
                           "/EchoServer", impl);
             System.out.println("EchoServer ready.");
         } catch (Exception e) {
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java
index 49a24b7..5f032ec 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/UseCustomSocketFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,7 @@
  * @author Ann Wollrath
  *
  * @library ../../../../testlibrary
- * @build Echo
- * @build EchoImpl
- * @build EchoImpl_Stub
- * @build UseCustomSocketFactory
+ * @build TestLibrary Echo EchoImpl EchoImpl_Stub
  * @run main/othervm/policy=security.policy/timeout=360 UseCustomSocketFactory
  */
 
@@ -42,8 +39,8 @@
 import java.rmi.registry.*;
 
 public class UseCustomSocketFactory {
+    static final int REGISTRY_PORT = TestLibrary.getUnusedRandomPort();
 
-    final static int REGISTRY_PORT = 2006;
     static String[] protocol = new String[] { "", "compress", "xor" };
 
     public static void main(String[] args) {
@@ -68,7 +65,7 @@
                     " -C-Djava.security.manager=java.rmi.RMISecurityManager "});
             rmid.start();
 
-            Echo[] echo = spawnAndTest();
+            Echo[] echo = spawnAndTest(rmid.getPort());
             reactivateAndTest(echo);
         } catch (IOException e) {
             TestLibrary.bomb("creating rmid", e);
@@ -78,17 +75,20 @@
         }
     }
 
-    private static Echo[] spawnAndTest() {
+    private static Echo[] spawnAndTest(int rmidPort) {
 
         System.err.println("\nCreate Test-->");
 
         Echo[] echo = new Echo[protocol.length];
 
         for (int i = 0; i < protocol.length; i++) {
-
             JavaVM serverVM = new JavaVM("EchoImpl",
                                          "-Djava.security.policy=" +
-                                         TestParams.defaultPolicy,
+                                         TestParams.defaultPolicy +
+                                         " -Drmi.registry.port=" +
+                                         REGISTRY_PORT +
+                                         " -Djava.rmi.activation.port=" +
+                                         rmidPort,
                                          protocol[i]);
 
             System.err.println("\nusing protocol: " +
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/security.policy b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/security.policy
index 57bd984..ffc9b1e 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/security.policy
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/activatable/security.policy
@@ -30,6 +30,9 @@
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
 
+  permission java.util.PropertyPermission "rmi.registry.port", "read";
+  permission java.util.PropertyPermission "java.rmi.activation.port", "write";
+
   // required for test to create an ActivationGroup
   permission java.lang.RuntimePermission "setFactory";
 
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl.java
index 17cc832..e2dde85 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl.java
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/HelloImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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,8 +65,9 @@
             if (args.length >= 1)
                 protocol = args[0];
 
+            int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
             registry = java.rmi.registry.LocateRegistry.
-                getRegistry("localhost", TestLibrary.REGISTRY_PORT,
+                getRegistry("localhost", registryPort,
                             new Compress.CompressRMIClientSocketFactory());
             UseCustomSocketFactory.checkStub(registry, "RMIClientSocket");
             hello = (Hello) registry.lookup("/HelloServer");
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java
index 5fb383d..774e823 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/UseCustomSocketFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -29,11 +29,7 @@
  * @author Laird Dornin; code borrowed from Ann Wollrath
  *
  * @library ../../../../testlibrary
- * @build Hello
- * @build HelloImpl
- * @build HelloImpl_Stub
- * @build UseCustomSocketFactory
- * @build Compress
+ * @build TestLibrary Compress Hello HelloImpl HelloImpl_Stub
  * @run main/othervm/policy=security.policy/timeout=240 UseCustomSocketFactory
  */
 
@@ -58,6 +54,7 @@
         System.out.println("\nRegression test for bug 4148850\n");
 
         TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
+        int registryPort = TestLibrary.getUnusedRandomPort();
 
         try {
             impl = new HelloImpl();
@@ -67,7 +64,7 @@
              * allow the rmiregistry to be secure.
              */
             registry = LocateRegistry.
-                createRegistry(TestLibrary.REGISTRY_PORT,
+                createRegistry(registryPort,
                                new Compress.CompressRMIClientSocketFactory(),
                                new Compress.CompressRMIServerSocketFactory());
             registry.rebind("/HelloServer", impl);
@@ -77,8 +74,12 @@
             TestLibrary.bomb("creating registry", e);
         }
 
-        JavaVM serverVM = new JavaVM("HelloImpl", "-Djava.security.policy=" +
-                                     TestParams.defaultPolicy, "");
+        JavaVM serverVM = new JavaVM("HelloImpl",
+                                     "-Djava.security.policy=" +
+                                     TestParams.defaultPolicy +
+                                     " -Drmi.registry.port=" +
+                                     registryPort,
+                                     "");
 
         try {
 
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/security.policy b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/security.policy
index 31d3bc5..7567ae1 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/security.policy
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/registry/security.policy
@@ -22,6 +22,8 @@
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
 
+  permission java.util.PropertyPermission "rmi.registry.port", "read";	
+
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl.java
index 0dd30c5..d1b4d06 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl.java
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/EchoImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -64,8 +64,9 @@
 
             System.out.println("EchoServer: creating remote object");
             EchoImpl impl = new EchoImpl(protocol);
+            int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
             System.out.println("EchoServer: binding in registry");
-            Naming.rebind("//:" + TestLibrary.REGISTRY_PORT +
+            Naming.rebind("//:" + registryPort +
                           "/EchoServer", impl);
             System.out.println("EchoServer ready.");
         } catch (Exception e) {
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java
index 20d00df..06571df 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/UseCustomSocketFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -29,11 +29,7 @@
  * @author Ann Wollrath
  *
  * @library ../../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build Echo
- * @build EchoImpl
- * @build EchoImpl_Stub
- * @build UseCustomSocketFactory
+ * @build TestLibrary RMID JavaVM Echo EchoImpl EchoImpl_Stub
  * @run main/othervm/policy=security.policy/timeout=120 UseCustomSocketFactory
  */
 
@@ -46,6 +42,8 @@
 
     public static void main(String[] args) {
 
+        int registryPort = -1;
+
         String[] protocol = new String[] { "", "compress", "xor" };
 
         System.out.println("\nRegression test for bug 4127826\n");
@@ -53,7 +51,8 @@
         TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
 
         try {
-            LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
+            Registry registry = TestLibrary.createRegistryOnUnusedPort();
+            registryPort = TestLibrary.getRegistryPort(registry);
         } catch (Exception e) {
             TestLibrary.bomb("creating registry", e);
         }
@@ -65,7 +64,9 @@
 
             JavaVM serverVM = new JavaVM("EchoImpl",
                                          "-Djava.security.policy=" +
-                                         TestParams.defaultPolicy,
+                                         TestParams.defaultPolicy +
+                                         " -Drmi.registry.port=" +
+                                         registryPort,
                                          protocol[i]);
             System.err.println("\nusing protocol: " +
                                (protocol[i] == "" ? "none" : protocol[i]));
@@ -79,7 +80,7 @@
                 Echo obj = null;
                 do {
                     try {
-                        obj = (Echo) Naming.lookup("//:" + TestLibrary.REGISTRY_PORT +
+                        obj = (Echo) Naming.lookup("//:" + registryPort +
                                                    "/EchoServer");
                         break;
                     } catch (NotBoundException e) {
@@ -109,7 +110,7 @@
             } finally {
                 serverVM.destroy();
                 try {
-                    Naming.unbind("//:" + TestLibrary.REGISTRY_PORT +
+                    Naming.unbind("//:" + registryPort +
                                   "/EchoServer");
                 } catch (Exception e) {
                     TestLibrary.bomb("unbinding EchoServer", e);
diff --git a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/security.policy b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/security.policy
index 31d3bc5..d1b5073 100644
--- a/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/security.policy
+++ b/jdk/test/java/rmi/server/RMISocketFactory/useSocketFactory/unicast/security.policy
@@ -22,9 +22,18 @@
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
 
+  permission java.util.PropertyPermission "rmi.registry.port", "read";	
+
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
+  // used by TestLibrary to get the RMI Registry port
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.proxy";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
+
   // test needs to export rmid and communicate with objects on arbitrary ports
   permission java.net.SocketPermission "*:1024-", "connect,accept,listen";
 };
diff --git a/jdk/test/java/rmi/server/RemoteObject/notExtending/NotExtending.java b/jdk/test/java/rmi/server/RemoteObject/notExtending/NotExtending.java
index 0023fc5..ef524a4 100644
--- a/jdk/test/java/rmi/server/RemoteObject/notExtending/NotExtending.java
+++ b/jdk/test/java/rmi/server/RemoteObject/notExtending/NotExtending.java
@@ -29,9 +29,7 @@
  *          (specifically: stubs) that contain the instance's RemoteRef.
  * @author Peter Jones
  *
- * @build NotExtending
- * @build NotExtending_Stub
- * @build NotExtending_Skel
+ * @build NotExtending_Stub NotExtending_Skel
  * @run main/othervm/timeout=240 NotExtending
  */
 
diff --git a/jdk/test/java/rmi/server/RemoteObject/verifyRemoteEquals/VerifyRemoteEquals.java b/jdk/test/java/rmi/server/RemoteObject/verifyRemoteEquals/VerifyRemoteEquals.java
index 8b6bcca..b89e362 100644
--- a/jdk/test/java/rmi/server/RemoteObject/verifyRemoteEquals/VerifyRemoteEquals.java
+++ b/jdk/test/java/rmi/server/RemoteObject/verifyRemoteEquals/VerifyRemoteEquals.java
@@ -21,16 +21,16 @@
  * questions.
  */
 
-/**
+/*
  * @test
  * @bug 4251010
  * @summary equals does not works on stub objects created with
  *           custom socket AndFactory
- * @library ../../../testlibrary
- *
- * @build VerifyRemoteEquals
- * @run main/othervm/timeout=40 VerifyRemoteEquals
  * @author Laird Dornin
+ *
+ * @library ../../../testlibrary
+ * @build TestLibrary
+ * @run main/othervm/timeout=40 VerifyRemoteEquals
  */
 
 import java.io.*;
diff --git a/jdk/test/java/rmi/server/RemoteServer/AddrInUse.java b/jdk/test/java/rmi/server/RemoteServer/AddrInUse.java
index ad88f98..34e343b 100644
--- a/jdk/test/java/rmi/server/RemoteServer/AddrInUse.java
+++ b/jdk/test/java/rmi/server/RemoteServer/AddrInUse.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -26,7 +26,6 @@
  * @summary retryServerSocket should not retry on BindException
  * @author Ann Wollrath
  *
- * @build AddrInUse
  * @run main/othervm AddrInUse
  */
 
@@ -36,7 +35,7 @@
 
 public class AddrInUse implements Runnable {
 
-    private static final int PORT = 9999;
+    private static int port = -1;
     private static final long TIMEOUT = 10000;
 
     private boolean exportSucceeded = false;
@@ -49,7 +48,7 @@
          * has already been bound, and record the result.
          */
         try {
-            LocateRegistry.createRegistry(PORT);
+            LocateRegistry.createRegistry(port);
             synchronized (this) {
                 exportSucceeded = true;
                 notifyAll();
@@ -68,8 +67,9 @@
         /*
          * Bind a server socket to a port.
          */
-        System.err.println("create a ServerSocket on port " + PORT + "...");
-        ServerSocket server = new ServerSocket(PORT);
+        ServerSocket server = new ServerSocket(0);
+        port = server.getLocalPort();
+        System.err.println("Created a ServerSocket on port " + port + "...");
 
         /*
          * Start a thread that creates a registry on the same port,
diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName.java b/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName.java
index 0716c1a..523c3a0 100644
--- a/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName.java
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/changeHostName/ChangeHostName.java
@@ -31,8 +31,7 @@
  *
  * @author Ann Wollrath
  *
- * @build ChangeHostName
- * @build ChangeHostName_Stub
+ * @build ChangeHostName ChangeHostName_Stub
  * @run main/othervm ChangeHostName
  */
 
diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/exportObject/GcDuringExport.java b/jdk/test/java/rmi/server/UnicastRemoteObject/exportObject/GcDuringExport.java
index 59663db..def2806 100644
--- a/jdk/test/java/rmi/server/UnicastRemoteObject/exportObject/GcDuringExport.java
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/exportObject/GcDuringExport.java
@@ -30,6 +30,7 @@
  * @bug 6597112
  * @summary GC'ing objects whilst being exported to RMI should not cause exceptions
  * @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
+ * @run main GcDuringExport
  */
 
 import java.rmi.Remote;
diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java
index 2867985..780e7e5 100644
--- a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/KeepAliveDuringCall.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -32,14 +32,8 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build JavaVM
- * @build KeepAliveDuringCall
- * @build KeepAliveDuringCall_Stub
- * @build ShutdownMonitor
- * @build Shutdown
- * @build ShutdownImpl
- * @build ShutdownImpl_Stub
+ * @build TestLibrary JavaVM KeepAliveDuringCall_Stub
+ *     ShutdownMonitor Shutdown ShutdownImpl ShutdownImpl_Stub
  * @run main/othervm KeepAliveDuringCall
  */
 
@@ -82,15 +76,17 @@
             UnicastRemoteObject.exportObject(obj);
             System.err.println("exported shutdown monitor");
 
-            Registry localRegistry =
-                LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
+            Registry localRegistry = TestLibrary.createRegistryOnUnusedPort();
+            int registryPort = TestLibrary.getRegistryPort(localRegistry);
             System.err.println("created local registry");
 
             localRegistry.bind(BINDING, obj);
             System.err.println("bound shutdown monitor in local registry");
 
             System.err.println("starting remote ShutdownImpl VM...");
-            (new JavaVM("ShutdownImpl")).start();
+            (new JavaVM("ShutdownImpl",
+                        "-Drmi.registry.port=" +
+                        registryPort, "")).start();
 
             Shutdown s;
             synchronized (obj.lock) {
diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl.java b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl.java
index 6ab0dc6..7a3d040 100644
--- a/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl.java
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/keepAliveDuringCall/ShutdownImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -68,8 +68,9 @@
 
     public static void main(String[] args) {
         try {
+            int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
             Registry registry =
-                LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT);
+                LocateRegistry.getRegistry("", registryPort);
             ShutdownMonitor monitor = (ShutdownMonitor)
                 registry.lookup(KeepAliveDuringCall.BINDING);
             System.err.println("(ShutdownImpl) retrieved shutdown monitor");
diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport.java b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport.java
index 743d461..a165dd8 100644
--- a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport.java
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport.java
@@ -31,8 +31,7 @@
  * IOException (see fix for bugid 4017232).
  * @author Peter Jones
  *
- * @build MarshalAfterUnexport
- * @build MarshalAfterUnexport_Stub
+ * @build MarshalAfterUnexport MarshalAfterUnexport_Stub
  * @run main/othervm MarshalAfterUnexport
  */
 
diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2.java b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2.java
index ea1e482..b72efa4 100644
--- a/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2.java
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/marshalAfterUnexport/MarshalAfterUnexport2.java
@@ -33,8 +33,7 @@
  * @author Peter Jones
  * @author Ann Wollrath
  *
- * @build MarshalAfterUnexport2
- * @build MarshalAfterUnexport2_Stub
+ * @build MarshalAfterUnexport2 MarshalAfterUnexport2_Stub
  * @run main/othervm MarshalAfterUnexport2
  */
 
diff --git a/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java b/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java
index ed00080..62804fe 100644
--- a/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java
+++ b/jdk/test/java/rmi/server/UnicastRemoteObject/unexportObject/UnexportLeak.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,9 +28,8 @@
  *
  * @author Ann Wollrath
  *
- * @build UnexportLeak
- * @build UnexportLeak_Stub
- * @build Ping
+ * @library ../../../testlibrary
+ * @build TestLibrary UnexportLeak_Stub Ping
  * @run main/othervm UnexportLeak
  */
 
@@ -40,20 +39,18 @@
 import java.rmi.registry.*;
 
 public class UnexportLeak implements Ping {
-
-    private static int PORT = 2006;
-
     public void ping() {
     }
 
     public static void main(String[] args) {
         try {
             System.err.println("\nRegression test for bug 4331349\n");
-            LocateRegistry.createRegistry(PORT);
+            Registry registry = TestLibrary.createRegistryOnUnusedPort();
+            int registryPort = TestLibrary.getRegistryPort(registry);
             Remote obj = new UnexportLeak();
             WeakReference wr = new WeakReference(obj);
             UnicastRemoteObject.exportObject(obj);
-            LocateRegistry.getRegistry(PORT).rebind("UnexportLeak", obj);
+            LocateRegistry.getRegistry(registryPort).rebind("UnexportLeak", obj);
             UnicastRemoteObject.unexportObject(obj, true);
             obj = null;
             flushRefs();
diff --git a/jdk/test/java/rmi/server/Unmarshal/PrimitiveClasses.java b/jdk/test/java/rmi/server/Unmarshal/PrimitiveClasses.java
index 8d7b30d..b9dfb0c 100644
--- a/jdk/test/java/rmi/server/Unmarshal/PrimitiveClasses.java
+++ b/jdk/test/java/rmi/server/Unmarshal/PrimitiveClasses.java
@@ -25,6 +25,7 @@
  * @bug 4442373
  * @summary Verify that RMI can successfully unmarshal Class objects for
  *          primitive types.
+ * @run main PrimitiveClasses
  */
 
 import java.rmi.MarshalledObject;
diff --git a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshall.java b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshal.java
similarity index 100%
rename from jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshall.java
rename to jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshal.java
diff --git a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread.java b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread.java
index 60dce66..95dee53 100644
--- a/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread.java
+++ b/jdk/test/java/rmi/server/Unmarshal/checkUnmarshalOnStopThread/CheckUnmarshalOnStopThread.java
@@ -31,10 +31,8 @@
  * @author Laird Dornin
  *
  * @library ../../../testlibrary
- * @build TestLibrary RMID JavaVM StreamPipe
- * @build CheckUnmarshall PoisonPill RuntimeExceptionParameter
- * @build CheckUnmarshalOnStopThread
- * @build CheckUnmarshalOnStopThread_Stub
+ * @build TestLibrary CheckUnmarshal CheckUnmarshalOnStopThread_Stub
+ *     PoisonPill RuntimeExceptionParameter
  * @run main/othervm/timeout=480 CheckUnmarshalOnStopThread
  */
 
diff --git a/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java b/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java
index b60dcc5..f15883c 100644
--- a/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java
+++ b/jdk/test/java/rmi/server/Unreferenced/finiteGCLatency/FiniteGCLatency.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -35,8 +35,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build FiniteGCLatency
- * @build FiniteGCLatency_Stub
+ * @build TestLibrary FiniteGCLatency_Stub
  * @run main/othervm/timeout=120 FiniteGCLatency
  */
 
@@ -78,11 +77,11 @@
         try {
             UnicastRemoteObject.exportObject(obj);
             System.err.println("exported remote object");
-
-            LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
+            Registry registry1 = TestLibrary.createRegistryOnUnusedPort();
+            int port = TestLibrary.getRegistryPort(registry1);
             System.err.println("created registry");
 
-            Registry registry = LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT);
+            Registry registry = LocateRegistry.getRegistry("", port);
             registry.bind(BINDING, obj);
             System.err.println("bound remote object in registry");
 
diff --git a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java
index fb8e875..b488e76 100644
--- a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java
+++ b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/LeaseCheckInterval.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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,11 +37,7 @@
  * @author Peter Jones
  *
  * @library ../../../testlibrary
- * @build TestLibrary
- * @build JavaVM
- * @build LeaseCheckInterval
- * @build LeaseCheckInterval_Stub
- * @build SelfTerminator
+ * @build TestLibrary JavaVM LeaseCheckInterval_Stub SelfTerminator
  * @run main/othervm LeaseCheckInterval
  */
 
@@ -87,8 +83,9 @@
             UnicastRemoteObject.exportObject(obj);
             System.err.println("exported remote object");
 
+            int registryPort = TestLibrary.getUnusedRandomPort();
             Registry localRegistry =
-                LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
+                LocateRegistry.createRegistry(registryPort);
             System.err.println("created local registry");
 
             localRegistry.bind(BINDING, obj);
@@ -96,7 +93,8 @@
 
             synchronized (obj.lock) {
                 System.err.println("starting remote client VM...");
-                (new JavaVM("SelfTerminator")).start();
+                (new JavaVM("SelfTerminator", "-Drmi.registry.port=" +
+                            registryPort, "")).start();
 
                 System.err.println("waiting for unreferenced() callback...");
                 obj.lock.wait(TIMEOUT);
diff --git a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java
index 5bb579f..4875634 100644
--- a/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java
+++ b/jdk/test/java/rmi/server/Unreferenced/leaseCheckInterval/SelfTerminator.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,8 +33,10 @@
 
     public static void main(String[] args) {
         try {
+            int registryPort =
+                Integer.parseInt(System.getProperty("rmi.registry.port"));
             Registry registry =
-                LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT);
+                LocateRegistry.getRegistry("", registryPort);
             Remote stub = registry.lookup(LeaseCheckInterval.BINDING);
             Runtime.getRuntime().halt(0);
         } catch (Exception e) {
diff --git a/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet.java b/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet.java
index 8170168..0ae059b 100644
--- a/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet.java
+++ b/jdk/test/java/rmi/server/Unreferenced/marshalledObjectGet/MarshalledObjectGet.java
@@ -30,8 +30,6 @@
  * invoked.
  * @author Peter Jones
  *
- * @library ../../../testlibrary
- * @build MarshalledObjectGet
  * @build MarshalledObjectGet_Stub
  * @run main/othervm/timeout=120 MarshalledObjectGet
  */
diff --git a/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java b/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java
index 38ce260..05be7ae 100644
--- a/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java
+++ b/jdk/test/java/rmi/server/Unreferenced/unreferencedContext/UnreferencedContext.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -39,8 +39,7 @@
  * @author Laird Dornin
  *
  * @library ../../../testlibrary
- * @build UnreferencedContext
- * @build UnreferencedContext_Stub
+ * @build TestLibrary UnreferencedContext_Stub
  * @run main/othervm/timeout=120 UnreferencedContext
  */
 
@@ -119,10 +118,11 @@
             UnicastRemoteObject.exportObject(obj);
             System.err.println("exported remote object");
 
-            LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
+            Registry registry1 = TestLibrary.createRegistryOnUnusedPort();
+            int port = TestLibrary.getRegistryPort(registry1);
             System.err.println("created registry");
 
-            Registry registry = LocateRegistry.getRegistry("", TestLibrary.REGISTRY_PORT);
+            Registry registry = LocateRegistry.getRegistry("", port);
             registry.bind(BINDING, obj);
             System.err.println("bound remote object in registry");
 
diff --git a/jdk/test/java/rmi/server/clientStackTrace/ClientStackTrace.java b/jdk/test/java/rmi/server/clientStackTrace/ClientStackTrace.java
index 41a2103..d685557 100644
--- a/jdk/test/java/rmi/server/clientStackTrace/ClientStackTrace.java
+++ b/jdk/test/java/rmi/server/clientStackTrace/ClientStackTrace.java
@@ -28,7 +28,7 @@
  * @author Laird Dornin
  *
  * @library ../../testlibrary
- * @build ClientStackTrace MyRemoteObject_Stub TestLibrary TestParams
+ * @build TestLibrary ClientStackTrace MyRemoteObject_Stub
  * @run main/othervm/policy=security.policy/timeout=120 ClientStackTrace
  */
 
diff --git a/jdk/test/java/rmi/server/getRemoteClass/GetRemoteClass.java b/jdk/test/java/rmi/server/getRemoteClass/GetRemoteClass.java
index 8fa4710..b6f21b4 100644
--- a/jdk/test/java/rmi/server/getRemoteClass/GetRemoteClass.java
+++ b/jdk/test/java/rmi/server/getRemoteClass/GetRemoteClass.java
@@ -28,7 +28,7 @@
  * @author Laird Dornin
  *
  * @library ../../testlibrary
- * @build GetRemoteClass TestLibrary TestParams
+ * @build TestLibrary
  * @run main/othervm GetRemoteClass
  */
 
diff --git a/jdk/test/java/rmi/server/serverStackTrace/ServerStackTrace.java b/jdk/test/java/rmi/server/serverStackTrace/ServerStackTrace.java
index 6cc9b2d..43504af 100644
--- a/jdk/test/java/rmi/server/serverStackTrace/ServerStackTrace.java
+++ b/jdk/test/java/rmi/server/serverStackTrace/ServerStackTrace.java
@@ -29,8 +29,7 @@
  * serialized with the Throwable from the server.
  * @author Peter Jones
  *
- * @build ServerStackTrace
- * @build ServerStackTrace_Stub
+ * @build ServerStackTrace ServerStackTrace_Stub
  * @run main/othervm ServerStackTrace
  */
 
diff --git a/jdk/test/java/rmi/server/serverStackTrace/SuppressStackTraces.java b/jdk/test/java/rmi/server/serverStackTrace/SuppressStackTraces.java
index 243d322..9606d12 100644
--- a/jdk/test/java/rmi/server/serverStackTrace/SuppressStackTraces.java
+++ b/jdk/test/java/rmi/server/serverStackTrace/SuppressStackTraces.java
@@ -36,10 +36,7 @@
  * for reasons of performance or confidentiality requirements.
  * @author Peter Jones
  *
- * @build SuppressStackTraces
- * @build Impl2_Stub
- * @build Impl1_Stub
- * @build Impl1_Skel
+ * @build SuppressStackTraces Impl2_Stub Impl1_Stub Impl1_Skel
  * @run main/othervm SuppressStackTraces
  */
 
diff --git a/jdk/test/java/rmi/server/useCustomRef/UseCustomRef.java b/jdk/test/java/rmi/server/useCustomRef/UseCustomRef.java
index f42aa05..23d7847 100644
--- a/jdk/test/java/rmi/server/useCustomRef/UseCustomRef.java
+++ b/jdk/test/java/rmi/server/useCustomRef/UseCustomRef.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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,10 +31,7 @@
  * 4180392
  *
  * @library ../../testlibrary
- * @build UseCustomRef
- * @build Ping
- * @build UseCustomRef_Stub
- * @build UseCustomRef_Skel
+ * @build TestLibrary Ping UseCustomRef_Stub UseCustomRef_Skel
  * @run main/othervm/policy=security.policy/secure=java.rmi.RMISecurityManager/timeout=120 UseCustomRef
  *
  * This test was failing to run because the synthetic access
@@ -84,8 +81,9 @@
             TestLibrary.suggestSecurityManager("java.rmi.RMISecurityManager");
 
             System.err.println("creating Registry...");
-            registry = LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
 
+            registry = TestLibrary.createRegistryOnUnusedPort();
+            int port = TestLibrary.getRegistryPort(registry);
             /*
              * create object with custom ref and bind in registry
              */
@@ -97,7 +95,7 @@
                                 "instanceof CustomServerRef");
             }
 
-            String name = "//:" + TestLibrary.REGISTRY_PORT + "/UseCustomRef";
+            String name = "//:" + port + "/UseCustomRef";
             //      String name = "UseCustomRef";
             System.err.println("binding object in registry...");
             Naming.rebind(name, cr);
diff --git a/jdk/test/java/rmi/server/useCustomRef/security.policy b/jdk/test/java/rmi/server/useCustomRef/security.policy
index c2a4b08..7be818a 100644
--- a/jdk/test/java/rmi/server/useCustomRef/security.policy
+++ b/jdk/test/java/rmi/server/useCustomRef/security.policy
@@ -8,8 +8,11 @@
 
 grant {
   // the test uses a class in the package sun.rmi.server
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
   permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
   permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.proxy";
+  permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
   permission java.util.PropertyPermission "package.restrict.access.sun", "read";
   permission java.util.PropertyPermission "package.restrict.access.sun.rmi", "read";
 
diff --git a/jdk/test/java/rmi/testlibrary/ActivationLibrary.java b/jdk/test/java/rmi/testlibrary/ActivationLibrary.java
index 2dd2734..5d21a4a 100644
--- a/jdk/test/java/rmi/testlibrary/ActivationLibrary.java
+++ b/jdk/test/java/rmi/testlibrary/ActivationLibrary.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -63,19 +63,30 @@
      */
     public static void deactivate(Remote remote,
                                   ActivationID id) {
-        for (int i = 0; i < 5; i ++) {
+        // We do as much as 50 deactivation trials, each separated by
+        // at least 100 milliseconds sleep time (max sleep time of 5 secs).
+        final long deactivateSleepTime = 100;
+        for (int i = 0; i < 50; i ++) {
             try {
                 if (Activatable.inactive(id) == true) {
                     mesg("inactive successful");
                     return;
                 } else {
-                    Thread.sleep(1000);
+                    mesg("inactive trial failed. Sleeping " +
+                         deactivateSleepTime +
+                         " milliseconds before next trial");
+                    Thread.sleep(deactivateSleepTime);
                 }
             } catch (InterruptedException e) {
-                continue;
+                Thread.currentThread().interrupt();
+                mesg("Thread interrupted while trying to deactivate activatable. Exiting deactivation");
+                return;
             } catch (Exception e) {
                 try {
                     // forcibly unexport the object
+                    mesg("Unexpected exception. Have to forcibly unexport the object." +
+                         " Exception was :");
+                    e.printStackTrace();
                     Activatable.unexportObject(remote, true);
                 } catch (NoSuchObjectException ex) {
                 }
@@ -99,59 +110,60 @@
      * activation system.
      */
     public static boolean rmidRunning(int port) {
-        int allowedNotReady = 10;
+        int allowedNotReady = 50;
         int connectionRefusedExceptions = 0;
 
-        for (int i = 0; i < 15 ; i++) {
+        /* We wait as much as a total of 7.5 secs trying to see Rmid running.
+         * We do this by pausing steps of 100 milliseconds (so up to 75 steps),
+         * right after trying to lookup and find RMID running in the other vm.
+         */
+        final long rmidWaitingStepTime = 100;
+        for (int i = 0; i <= 74; i++) {
 
             try {
-                Thread.sleep(500);
                 LocateRegistry.getRegistry(port).lookup(SYSTEM_NAME);
+                mesg("Activation System available after " +
+                     (i * rmidWaitingStepTime) + " milliseconds");
                 return true;
 
             } catch (java.rmi.ConnectException e) {
-                // ignore connect exceptions until we decide rmid is not up
+                mesg("Remote connection refused after " +
+                     (i * rmidWaitingStepTime) + " milliseconds");
 
+                // ignore connect exceptions until we decide rmid is not up
                 if ((connectionRefusedExceptions ++) >= allowedNotReady) {
                     return false;
                 }
 
-            } catch (NotBoundException e) {
+            } catch (java.rmi.NoSuchObjectException nsoe) {
+                /* Activation System still unavailable.
+                 * Ignore this since we are just waiting for its availibility.
+                 * Just signal unavailibility.
+                 */
+                mesg("Activation System still unavailable after more than " +
+                     (i * rmidWaitingStepTime) + " milliseconds");
 
+            } catch (NotBoundException e) {
                 return false;
 
             } catch (Exception e) {
-                // print out other types of exceptions as an FYI.
-                // test should not fail as rmid is likely to be in an
-                // undetermined state at this point.
-
+                /* print out other types of exceptions as an FYI.
+                 * test should not fail as rmid is likely to be in an
+                 * undetermined state at this point.
+                 */
                 mesg("caught an exception trying to" +
                      " start rmid, last exception was: " +
                      e.getMessage());
                 e.printStackTrace();
             }
-        }
-        return false;
-    }
 
-    /**
-     * Check to see if an arry of Strings contains a given string.
-     */
-    private static boolean
-        containsString(String[] strings, String contained)
-    {
-        if (strings == null) {
-            if (contained == null) {
-                return true;
-            }
-            return false;
-        }
-
-        for (int i = 0 ; i < strings.length ; i ++ ) {
-            if ((strings[i] != null) &&
-                (strings[i].indexOf(contained) >= 0))
-            {
-                return true;
+            // Waiting for another 100 milliseconds.
+            try {
+                Thread.sleep(100);
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                mesg("Thread interrupted while checking if Activation System is running. Exiting check");
+                return false;
             }
         }
         return false;
@@ -159,12 +171,8 @@
 
     /** cleanup after rmid */
     public static void rmidCleanup(RMID rmid) {
-        rmidCleanup(rmid, TestLibrary.RMID_PORT);
-    }
-
-    public static void rmidCleanup(RMID rmid, int port) {
         if (rmid != null) {
-            if (!ActivationLibrary.safeDestroy(rmid, port, SAFE_WAIT_TIME)) {
+            if (!ActivationLibrary.safeDestroy(rmid, SAFE_WAIT_TIME)) {
                 TestLibrary.bomb("rmid not destroyed in: " +
                                  SAFE_WAIT_TIME +
                                  " milliseconds");
@@ -180,8 +188,8 @@
      * @return whether or not shutdown completed succesfully in the
      *         timeAllowed
      */
-    private static boolean safeDestroy(RMID rmid, int port, long timeAllowed) {
-        DestroyThread destroyThread = new DestroyThread(rmid, port);
+    private static boolean safeDestroy(RMID rmid, long timeAllowed) {
+        DestroyThread destroyThread = new DestroyThread(rmid);
         destroyThread.start();
 
         try {
@@ -201,9 +209,9 @@
         private final int port;
         private boolean succeeded = false;
 
-        DestroyThread(RMID rmid, int port) {
+        DestroyThread(RMID rmid) {
             this.rmid = rmid;
-            this.port = port;
+            this.port = rmid.getPort();
             this.setDaemon(true);
         }
 
diff --git a/jdk/test/java/rmi/testlibrary/JavaVM.java b/jdk/test/java/rmi/testlibrary/JavaVM.java
index 4356f34..62be87d 100644
--- a/jdk/test/java/rmi/testlibrary/JavaVM.java
+++ b/jdk/test/java/rmi/testlibrary/JavaVM.java
@@ -36,7 +36,6 @@
  */
 public class JavaVM {
 
-    // need to
     protected Process vm = null;
 
     private String classname = "";
@@ -46,6 +45,10 @@
     private OutputStream errorStream = System.err;
     private String policyFileName = null;
 
+    // This is used to shorten waiting time at startup.
+    private volatile boolean started = false;
+    private boolean forcesOutput = true; // default behavior
+
     private static void mesg(Object mesg) {
         System.err.println("JAVAVM: " + mesg.toString());
     }
@@ -79,6 +82,25 @@
         this.errorStream = err;
     }
 
+    /* This constructor will instantiate a JavaVM object for which caller
+     * can ask for forcing initial version output on child vm process
+     * (if forcesVersionOutput is true), or letting the started vm behave freely
+     * (when forcesVersionOutput is false).
+     */
+    public JavaVM(String classname,
+                  String options, String args,
+                  OutputStream out, OutputStream err,
+                  boolean forcesVersionOutput) {
+        this(classname, options, args, out, err);
+        this.forcesOutput = forcesVersionOutput;
+    }
+
+
+    public void setStarted() {
+        started = true;
+    }
+
+    // Prepends passed opts array to current options
     public void addOptions(String[] opts) {
         String newOpts = "";
         for (int i = 0 ; i < opts.length ; i ++) {
@@ -87,6 +109,8 @@
         newOpts += " ";
         options = newOpts + options;
     }
+
+    // Prepends passed arguments array to current args
     public void addArguments(String[] arguments) {
         String newArgs = "";
         for (int i = 0 ; i < arguments.length ; i ++) {
@@ -127,6 +151,18 @@
 
         addOptions(new String[] { getCodeCoverageOptions() });
 
+        /*
+         * If forcesOutput is true :
+         *  We force the new starting vm to output something so that we can know
+         *  when it is effectively started by redirecting standard output through
+         *  the next StreamPipe call (the vm is considered started when a first
+         *  output has been streamed out).
+         *  We do this by prepnding a "-showversion" option in the command line.
+         */
+        if (forcesOutput) {
+            addOptions(new String[] {"-showversion"});
+        }
+
         StringTokenizer optionsTokenizer = new StringTokenizer(options);
         StringTokenizer argsTokenizer = new StringTokenizer(args);
         int optionsCount = optionsTokenizer.countTokens();
@@ -150,15 +186,43 @@
         vm = Runtime.getRuntime().exec(javaCommand);
 
         /* output from the execed process may optionally be captured. */
-        StreamPipe.plugTogether(vm.getInputStream(), this.outputStream);
-        StreamPipe.plugTogether(vm.getErrorStream(), this.errorStream);
+        StreamPipe.plugTogether(this, vm.getInputStream(), this.outputStream);
+        StreamPipe.plugTogether(this, vm.getErrorStream(), this.errorStream);
 
         try {
-            Thread.sleep(2000);
-        } catch (Exception ignore) {
-        }
+            if (forcesOutput) {
+                // Wait distant vm to start, by using waiting time slices of 100 ms.
+                // Wait at most for 2secs, after it considers the vm to be started.
+                final long vmStartSleepTime = 100;
+                final int maxTrials = 20;
+                int numTrials = 0;
+                while (!started && numTrials < maxTrials) {
+                    numTrials++;
+                    Thread.sleep(vmStartSleepTime);
+                }
 
-        mesg("finished starting vm.");
+                // Outputs running status of distant vm
+                String message =
+                    "after " + (numTrials * vmStartSleepTime) + " milliseconds";
+                if (started) {
+                    mesg("distant vm process running, " + message);
+                }
+                else {
+                    mesg("unknown running status of distant vm process, " + message);
+                }
+            }
+            else {
+                // Since we have no way to know if the distant vm is started,
+                // we just consider the vm to be started after a 2secs waiting time.
+                Thread.sleep(2000);
+                mesg("distant vm considered to be started after a waiting time of 2 secs");
+            }
+        } catch (InterruptedException e) {
+            Thread.currentThread().interrupt();
+            mesg("Thread interrupted while checking if distant vm is started. Giving up check.");
+            mesg("Distant vm state unknown");
+            return;
+        }
     }
 
     public void destroy() {
diff --git a/jdk/test/java/rmi/testlibrary/RMID.java b/jdk/test/java/rmi/testlibrary/RMID.java
index 0663fdf..e963c45 100644
--- a/jdk/test/java/rmi/testlibrary/RMID.java
+++ b/jdk/test/java/rmi/testlibrary/RMID.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,6 @@
 import java.io.*;
 import java.rmi.*;
 import java.rmi.activation.*;
-import java.util.Properties;
 
 /**
  * Utility class that creates an instance of rmid with a policy
@@ -133,7 +132,7 @@
                                   boolean debugExec)
     {
         return createRMID(out, err, debugExec, true,
-                          TestLibrary.RMID_PORT);
+                          TestLibrary.getUnusedRandomPort());
     }
 
     public static RMID createRMID(OutputStream out, OutputStream err,
@@ -208,7 +207,7 @@
         // if rmid is already running, then the test will fail with
         // a well recognized exception (port already in use...).
 
-        mesg("starting rmid...");
+        mesg("starting rmid on port #" + port + "...");
         super.start();
 
         int slopFactor = 1;
@@ -218,20 +217,38 @@
         } catch (NumberFormatException ignore) {}
         waitTime = waitTime * slopFactor;
 
-        // give rmid time to come up
+        // We check several times (as many as provides passed waitTime) to
+        // see if Rmid is currently running. Waiting steps last 100 msecs.
+        final long rmidStartSleepTime = 100;
         do {
+            // Sleeping for another rmidStartSleepTime time slice.
             try {
-                Thread.sleep(Math.min(waitTime, 10000));
+                Thread.sleep(Math.min(waitTime, rmidStartSleepTime));
             } catch (InterruptedException ie) {
                 Thread.currentThread().interrupt();
+                mesg("Thread interrupted while checking for start of Activation System. Giving up check.");
+                mesg("Activation System state unknown");
+                return;
             }
-            waitTime -= 10000;
+            waitTime -= rmidStartSleepTime;
 
-            // is rmid present?
+            // Checking if rmid is present
             if (ActivationLibrary.rmidRunning(port)) {
+                /**
+                 * We need to set the java.rmi.activation.port value as the
+                 * activation system will use the property to determine the
+                 * port #.  The activation system will use this value if set.
+                 * If it isn't set, the activation system will set it to an
+                 * incorrect value.
+                 */
+                System.setProperty("java.rmi.activation.port", Integer.toString(port));
                 mesg("finished starting rmid.");
                 return;
             }
+            else {
+                mesg("rmid still not started");
+            }
+
         } while (waitTime > 0);
         TestLibrary.bomb("start rmid failed... giving up", null);
     }
@@ -249,10 +266,6 @@
      * Shutdown does not nullify possible references to the rmid
      * process object (destroy does though).
      */
-    public static void shutdown() {
-        shutdown(TestLibrary.RMID_PORT);
-    }
-
     public static void shutdown(int port) {
 
         try {
@@ -264,6 +277,8 @@
                     port +
                     "/java.rmi.activation.ActivationSystem");
                 mesg("obtained a reference to the activation system");
+            } catch (RemoteException re) {
+                mesg("could not contact registry while trying to shutdown activation system");
             } catch (java.net.MalformedURLException mue) {
             }
 
@@ -272,19 +287,14 @@
             }
             system.shutdown();
 
+        } catch (RemoteException re) {
+            mesg("shutting down the activation daemon failed");
         } catch (Exception e) {
             mesg("caught exception trying to shutdown rmid");
             mesg(e.getMessage());
             e.printStackTrace();
         }
 
-        try {
-            // wait for the shutdown to happen
-            Thread.sleep(5000);
-        } catch (InterruptedException ie) {
-            Thread.currentThread().interrupt();
-        }
-
         mesg("testlibrary finished shutting down rmid");
     }
 
@@ -294,25 +304,52 @@
      * if rmid is a child process of the current VM.
      */
     public void destroy() {
-
-        // attempt graceful shutdown of the activation system on
-        // TestLibrary.RMID_PORT
+        // attempt graceful shutdown of the activation system
         shutdown(port);
 
         if (vm != null) {
             try {
-                // destroy rmid if it is still running...
-                try {
-                    vm.exitValue();
-                    mesg("rmid exited on shutdown request");
-                } catch (IllegalThreadStateException illegal) {
-                    mesg("Had to destroy RMID's process " +
-                         "using Process.destroy()");
+                /* Waiting for distant RMID process to shutdown.
+                 * Waiting is bounded at a hardcoded max of 60 secs (1 min).
+                 * Waiting by steps of 200 msecs, thus at most 300 such attempts
+                 * for termination of distant RMID process. If process is not
+                 * known to be terminated properly after that time,
+                 * we give up for a gracefull termination, and thus go for
+                 * forcibly destroying the process.
+                 */
+                boolean vmEnded = false;
+                int waitingTrials = 0;
+                final int maxTrials = 300;
+                final long vmProcessEndWaitInterval = 200;
+                int vmExitValue;
+                do {
+                    try {
+                        Thread.sleep(vmProcessEndWaitInterval);
+                        waitingTrials++;
+                        vmExitValue = vm.exitValue();
+                        mesg("rmid exited on shutdown request");
+                        vmEnded = true;
+                    } catch (IllegalThreadStateException illegal) {
+                        mesg("RMID's process still not terminated after more than " +
+                             (waitingTrials * vmProcessEndWaitInterval) + " milliseconds");
+                    }
+                }
+                while (!vmEnded &&
+                       (waitingTrials < maxTrials));
+
+                if (waitingTrials >= maxTrials) {
+                    mesg("RMID's process still not terminated after more than " +
+                         (waitingTrials * vmProcessEndWaitInterval) + " milliseconds." +
+                         "Givinp up gracefull termination...");
+                    mesg("destroying RMID's process using Process.destroy()");
                     super.destroy();
                 }
 
+            } catch (InterruptedException ie) {
+                Thread.currentThread().interrupt();
+                mesg("Thread interrupted while checking for termination of distant rmid vm. Giving up check.");
             } catch (Exception e) {
-                mesg("caught exception trying to destroy rmid: " +
+                mesg("caught unexpected exception trying to destroy rmid: " +
                      e.getMessage());
                 e.printStackTrace();
             }
@@ -321,4 +358,6 @@
             vm = null;
         }
     }
+
+    public int getPort() {return port;}
 }
diff --git a/jdk/test/java/rmi/testlibrary/RegistryRunner.java b/jdk/test/java/rmi/testlibrary/RegistryRunner.java
index 20fd38b..6290c79 100644
--- a/jdk/test/java/rmi/testlibrary/RegistryRunner.java
+++ b/jdk/test/java/rmi/testlibrary/RegistryRunner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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
@@ -56,12 +56,13 @@
      * Request that the registry process exit and handle
      * related exceptions.
      */
-    public static void requestExit() {
+    public static void requestExit(int port) {
+
         try {
             RemoteExiter exiter =
                 (RemoteExiter)
                 Naming.lookup("rmi://localhost:" +
-                              TestLibrary.REGISTRY_PORT +
+                              port +
                               "/RemoteExiter");
             try {
                 exiter.exit();
@@ -84,7 +85,7 @@
                 System.err.println("Usage: <port>");
                 System.exit(0);
             }
-            int port = TestLibrary.REGISTRY_PORT;
+            int port = -1;
             try {
                 port = Integer.parseInt(args[0]);
             } catch (NumberFormatException nfe) {
diff --git a/jdk/test/java/rmi/testlibrary/StreamPipe.java b/jdk/test/java/rmi/testlibrary/StreamPipe.java
index e68eefe..275c3c1 100644
--- a/jdk/test/java/rmi/testlibrary/StreamPipe.java
+++ b/jdk/test/java/rmi/testlibrary/StreamPipe.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -35,46 +35,89 @@
     private InputStream in;
     private OutputStream out;
     private String preamble;
+    private JavaVM javaVM;
     private static Object lock = new Object();
     private static int count = 0;
 
-    public StreamPipe(InputStream in, OutputStream out, String name) {
+
+    /* StreamPipe constructor : should only be called by plugTogether() method !!
+     * If passed vm is not null :
+     * -  This is StreamPipe usage when streams to pipe come from a given
+     *    vm (JavaVM) process (the vm process must be started with a prefixed
+     *    "-showversion" option to be able to determine as soon as possible when
+     *    the vm process is started through the redirection of the streams).
+     *    There must be a close connection between the StreamPipe instance and
+     *    the JavaVM object on which a start() call has been done.
+     *    run() method will flag distant JavaVM as started.
+     * If passed vm is null :
+     * -  We don't have control on the process which we want to redirect the passed
+     *    streams.
+     *    run() method will ignore distant process.
+     */
+    private StreamPipe(JavaVM vm, InputStream in, OutputStream out, String name) {
         super(name);
         this.in  = in;
         this.out = out;
         this.preamble = "# ";
+        this.javaVM = vm;
     }
 
-    public void run() {
-        BufferedReader r = new BufferedReader(new InputStreamReader(in), 1);
-        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(out));
-        byte[] buf = new byte[256];
-        boolean bol = true;     // beginning-of-line
-        int count;
-
-        try {
-            String line;
-            while ((line = r.readLine()) != null) {
-                w.write(preamble);
-                w.write(line);
-                w.newLine();
-                w.flush();
-            }
-        } catch (IOException e) {
-            System.err.println("*** IOException in StreamPipe.run:");
-            e.printStackTrace();
-        }
-    }
-
-    public static void plugTogether(InputStream in, OutputStream out) {
+    // Install redirection of passed InputStream and OutputStream from passed JavaVM
+    // to this vm standard output and input streams.
+    public static void plugTogether(JavaVM vm, InputStream in, OutputStream out) {
         String name = null;
 
         synchronized (lock) {
             name = "TestLibrary: StreamPipe-" + (count ++ );
         }
 
-        Thread pipe = new StreamPipe(in, out, name);
+        Thread pipe = new StreamPipe(vm, in, out, name);
         pipe.setDaemon(true);
         pipe.start();
     }
+
+    /* Redirects the InputStream and OutputStream passed by caller to this
+     * vm standard output and input streams.
+     * (we just have to use fully parametered plugTogether() call with a null
+     *  JavaVM input to do this).
+     */
+    public static void plugTogether(InputStream in, OutputStream out) {
+        plugTogether(null, in, out);
+    }
+
+    // Starts redirection of streams.
+    public void run() {
+        BufferedReader r = new BufferedReader(new InputStreamReader(in), 1);
+        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(out));
+        byte[] buf = new byte[256];
+
+        try {
+            String line;
+
+            /* This is to check that the distant vm has started,
+             * if such a vm has been provided at construction :
+             * - As soon as we can read something from r BufferedReader,
+             *   that means the distant vm is already started.
+             * Thus we signal associated JavaVM object that it is now started.
+             */
+            if (((line = r.readLine()) != null) &&
+                (javaVM != null)) {
+                javaVM.setStarted();
+            }
+
+            // Redirects r on w.
+            while (line != null) {
+                w.write(preamble);
+                w.write(line);
+                w.newLine();
+                w.flush();
+                line = r.readLine();
+            }
+
+        } catch (IOException e) {
+            System.err.println("*** IOException in StreamPipe.run:");
+            e.printStackTrace();
+        }
+    }
+
 }
diff --git a/jdk/test/java/rmi/testlibrary/TestLibrary.java b/jdk/test/java/rmi/testlibrary/TestLibrary.java
index 7c82cd9..734d805 100644
--- a/jdk/test/java/rmi/testlibrary/TestLibrary.java
+++ b/jdk/test/java/rmi/testlibrary/TestLibrary.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -36,37 +36,62 @@
  * not make use of packages.
  */
 
+import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.io.PrintStream;
-import java.net.URL;
 import java.net.MalformedURLException;
-import java.rmi.activation.Activatable;
-import java.rmi.activation.ActivationID;
+import java.net.ServerSocket;
+import java.net.URL;
 import java.rmi.NoSuchObjectException;
-import java.rmi.registry.Registry;
 import java.rmi.Remote;
+import java.rmi.RemoteException;
+import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
+import java.rmi.server.RemoteRef;
 import java.rmi.server.UnicastRemoteObject;
 import java.util.Enumeration;
-import java.util.Hashtable;
 import java.util.Properties;
-import java.io.ByteArrayOutputStream;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
+import sun.rmi.registry.RegistryImpl;
+import sun.rmi.server.UnicastServerRef;
+import sun.rmi.transport.Endpoint;
+import sun.rmi.transport.LiveRef;
+import sun.rmi.transport.tcp.TCPEndpoint;
 
 /**
  * Class of utility/library methods (i.e. procedures) that assist with
  * the writing and maintainance of rmi regression tests.
  */
 public class TestLibrary {
-
-    /** standard test port number for registry */
-    public final static int REGISTRY_PORT = 2006;
-    /** port for rmid necessary: not used to actually start rmid */
-    public final static int RMID_PORT = 1098;
+    /**
+     *                       IMPORTANT!
+     *
+     * RMI tests are run concurrently and port conflicts result when a single
+     * port number is used by multiple tests.  When needing a port, use
+     * getUnusedRandomPort() wherever possible.  If getUnusedRandomPort() cannot
+     * be used, reserve and specify a port to use for your test here.   This
+     * will ensure there are no port conflicts amongst the RMI tests.  The
+     * port numbers specified here may also be specified in the respective
+     * tests.  Do not change the reserved port numbers here without also
+     * changing the port numbers in the respective tests.
+     *
+     * When needing an instance of the RMIRegistry, use
+     * createRegistryOnUnusedPort wherever possible to prevent port conflicts.
+     *
+     * Reserved port range: FIXED_PORT_MIN to FIXED_PORT_MAX (inclusive) for
+     * tests which cannot use a random port.  If new fixed ports are added below
+     * FIXED_PORT_MIN or above FIXED_PORT_MAX, then adjust
+     * FIXED_PORT_MIN/MAX appropriately.
+     */
+    public final static int FIXED_PORT_MIN = 64001;
+    public final static int FIXED_PORT_MAX = 64010;
+    public final static int RMIDVIAINHERITEDCHANNEL_ACTIVATION_PORT = 64001;
+    public final static int RMIDVIAINHERITEDCHANNEL_REGISTRY_PORT = 64002;
+    public final static int INHERITEDCHANNELNOTSERVERSOCKET_ACTIVATION_PORT = 64003;
+    public final static int INHERITEDCHANNELNOTSERVERSOCKET_REGISTRY_PORT = 64004;
+    public final static int READTEST_REGISTRY_PORT = 64005;
 
     static void mesg(Object mesg) {
         System.err.println("TEST_LIBRARY: " + mesg.toString());
@@ -340,6 +365,83 @@
     }
 
     /**
+     * Creates an RMI {@link Registry} on a random, un-reserved port.
+     *
+     * @returns an RMI Registry, using a random port.
+     * @throws RemoteException if there was a problem creating a Registry.
+     */
+    public static Registry createRegistryOnUnusedPort() throws RemoteException {
+        return LocateRegistry.createRegistry(getUnusedRandomPort());
+    }
+
+    /**
+     * Returns the port number the RMI {@link Registry} is running on.
+     *
+     * @param registry the registry to find the port of.
+     * @return the port number the registry is using.
+     * @throws RuntimeException if there was a problem getting the port number.
+     */
+    public static int getRegistryPort(Registry registry) {
+        int port = -1;
+
+        try {
+            RemoteRef remoteRef = ((RegistryImpl)registry).getRef();
+            LiveRef liveRef = ((UnicastServerRef)remoteRef).getLiveRef();
+            Endpoint endpoint = liveRef.getChannel().getEndpoint();
+            TCPEndpoint tcpEndpoint = (TCPEndpoint) endpoint;
+            port = tcpEndpoint.getPort();
+        } catch (Exception ex) {
+            throw new RuntimeException("Error getting registry port.", ex);
+        }
+
+        return port;
+    }
+
+    /**
+     * Returns an unused random port number which is not a reserved port.  Will
+     * try up to 10 times to get a random port before giving up and throwing a
+     * RuntimeException.
+     *
+     * @return an unused random port number.
+     * @throws RuntimeException if there was a problem getting a port.
+     */
+    public static int getUnusedRandomPort() {
+        int numTries = 0;
+        int unusedRandomPort = FIXED_PORT_MIN;
+        Exception ex = null;
+
+        while (numTries++ < 10) {
+            ex = null; //reset
+
+            try (ServerSocket ss = new ServerSocket(0)) {
+                unusedRandomPort = ss.getLocalPort();
+            } catch (Exception e) {
+                ex = e;
+            }
+
+            if (!isReservedPort(unusedRandomPort)) {
+                return unusedRandomPort;
+            }
+        }
+
+        // If we're here, then either an exception was thrown or the port is
+        // a reserved port.
+        throw new RuntimeException("Error getting unused random port.", ex);
+    }
+
+    /**
+     * Determines if a port is one of the reserved port numbers.
+     *
+     * @param port the port to test.
+     * @return {@code true} if the port is a reserved port, otherwise
+     *         {@code false}.
+     */
+    public static boolean isReservedPort(int port) {
+        return ((port >= FIXED_PORT_MIN) && (port <= FIXED_PORT_MAX) ||
+                (port == 1099));
+    }
+
+    /**
      * Method to capture the stack trace of an exception and return it
      * as a string.
      */
diff --git a/jdk/test/java/rmi/transport/acceptLoop/CloseServerSocketOnTermination.java b/jdk/test/java/rmi/transport/acceptLoop/CloseServerSocketOnTermination.java
index a236137..b4d86c4 100644
--- a/jdk/test/java/rmi/transport/acceptLoop/CloseServerSocketOnTermination.java
+++ b/jdk/test/java/rmi/transport/acceptLoop/CloseServerSocketOnTermination.java
@@ -31,7 +31,6 @@
  * exception for which it doesn't even consult the RMIFailureHandler.
  * @author Peter Jones
  *
- * @build CloseServerSocketOnTermination
  * @run main/othervm CloseServerSocketOnTermination
  */
 
diff --git a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java
index 880b700..9660f53 100644
--- a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java
+++ b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDN.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,7 @@
  * @author Laird Dornin
  *
  * @library ../../testlibrary
- * @build CheckFQDN CheckFQDNClient CheckFQDN_Stub TellServerName
+ * @build TestLibrary CheckFQDNClient CheckFQDN_Stub TellServerName
  * @run main/othervm/timeout=120 CheckFQDN
  */
 
@@ -63,7 +63,7 @@
  */
 public class CheckFQDN extends UnicastRemoteObject
     implements TellServerName {
-
+    public static int REGISTRY_PORT =-1;
     static String propertyBeingTested = null;
     static String propertyBeingTestedValue = null;
 
@@ -77,8 +77,8 @@
             System.err.println
                 ("\nRegression test for bug/rfe 4115683\n");
 
-            Registry registry = java.rmi.registry.LocateRegistry.
-                createRegistry(TestLibrary.REGISTRY_PORT);
+            Registry registry = TestLibrary.createRegistryOnUnusedPort();
+            REGISTRY_PORT = TestLibrary.getRegistryPort(registry);
             registry.bind("CheckFQDN", checkFQDN);
 
             /* test the host name scheme in different environments.*/
@@ -117,7 +117,9 @@
             JavaVM jvm = new JavaVM("CheckFQDNClient",
                                     propOption + property +
                                     equal +
-                                    propertyValue + extraProp,
+                                    propertyValue + extraProp +
+                                    " -Drmi.registry.port=" +
+                                    REGISTRY_PORT,
                                     "");
 
             propertyBeingTested=property;
diff --git a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDNClient.java b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDNClient.java
index c1666f4..37d9b97 100644
--- a/jdk/test/java/rmi/transport/checkFQDN/CheckFQDNClient.java
+++ b/jdk/test/java/rmi/transport/checkFQDN/CheckFQDNClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -58,8 +58,9 @@
             System.err.println("Client host name: " +
                                hostname);
 
+            int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
             tell = (TellServerName) Naming.lookup("rmi://:" +
-                                                  TestLibrary.REGISTRY_PORT
+                                                  registryPort
                                                   + "/CheckFQDN");
             tell.tellServerName(hostname);
             System.err.println("client has exited");
diff --git a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java
index 34dd9c9..52fd7df 100644
--- a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java
+++ b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/CheckLeaseLeak.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,7 +28,7 @@
  * @author Laird Dornin
  *
  * @library ../../testlibrary
- * @build CheckLeaseLeak CheckLeaseLeak_Stub LeaseLeakClient LeaseLeak
+ * @build TestLibrary CheckLeaseLeak_Stub LeaseLeakClient LeaseLeak
  * @run main/othervm/timeout=240 CheckLeaseLeak
  *
  */
@@ -57,7 +57,6 @@
 import java.rmi.registry.*;
 
 public class CheckLeaseLeak extends UnicastRemoteObject implements LeaseLeak {
-
     public CheckLeaseLeak() throws RemoteException { }
     public void ping () throws RemoteException { }
 
@@ -87,8 +86,8 @@
 
         try {
             Registry registry =
-                java.rmi.registry.LocateRegistry.
-                    createRegistry(TestLibrary.REGISTRY_PORT);
+                TestLibrary.createRegistryOnUnusedPort();
+            int registryPort = TestLibrary.getRegistryPort(registry);
 
             leakServer = new CheckLeaseLeak();
             registry.rebind("/LeaseLeak", leakServer);
@@ -99,7 +98,10 @@
 
                 JavaVM jvm = new JavaVM("LeaseLeakClient",
                                         " -Djava.security.policy=" +
-                                        TestParams.defaultPolicy, "");
+                                        TestParams.defaultPolicy +
+                                        " -Drmi.registry.port=" +
+                                        registryPort,
+                                        "");
                 jvm.start();
 
                 if (jvm.getVM().waitFor() == 1 ) {
diff --git a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeakClient.java b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeakClient.java
index c8e5c75..d9cf9fa 100644
--- a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeakClient.java
+++ b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/LeaseLeakClient.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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 @@
 
         try {
             LeaseLeak leaseLeak = null;
+            int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
 
             // put a reference on a remote object.
             Registry registry =
-                java.rmi.registry.LocateRegistry.getRegistry(
-                    TestLibrary.REGISTRY_PORT);
+                java.rmi.registry.LocateRegistry.getRegistry(registryPort);
             leaseLeak = (LeaseLeak) registry.lookup("/LeaseLeak");
             leaseLeak.ping();
 
diff --git a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/security.policy b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/security.policy
index 8dd6d5d..cc5811f 100644
--- a/jdk/test/java/rmi/transport/checkLeaseInfoLeak/security.policy
+++ b/jdk/test/java/rmi/transport/checkLeaseInfoLeak/security.policy
@@ -19,6 +19,7 @@
   permission java.util.PropertyPermission "user.dir", "read";
   permission java.util.PropertyPermission "java.home", "read";
 
+  permission java.util.PropertyPermission "rmi.registry.port", "read";
   permission java.util.PropertyPermission "java.security.policy", "read";
   permission java.util.PropertyPermission "java.security.manager", "read";
 
diff --git a/jdk/test/java/rmi/transport/closeServerSocket/CloseServerSocket.java b/jdk/test/java/rmi/transport/closeServerSocket/CloseServerSocket.java
index 1feb597..2b1f1ee 100644
--- a/jdk/test/java/rmi/transport/closeServerSocket/CloseServerSocket.java
+++ b/jdk/test/java/rmi/transport/closeServerSocket/CloseServerSocket.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,8 @@
  * the local port is released).
  * @author Peter Jones
  *
- * @build CloseServerSocket
+ * @library ../../testlibrary
+ * @build TestLibrary
  * @run main/othervm CloseServerSocket
  */
 
@@ -44,8 +45,7 @@
 import java.rmi.server.UnicastRemoteObject;
 
 public class CloseServerSocket implements Remote {
-
-    private static final int PORT = 2020;
+    private static final int PORT = TestLibrary.getUnusedRandomPort();
 
     private CloseServerSocket() { }
 
@@ -88,7 +88,7 @@
     }
 
     private static void verifyPortFree(int port) throws IOException {
-        ServerSocket ss = new ServerSocket(PORT);
+        ServerSocket ss = new ServerSocket(port);
         ss.close();
         System.err.println("- port " + port + " is free");
     }
diff --git a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java
index 2d530db..bcd58a0 100644
--- a/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/DGCDeadLock.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -28,10 +28,7 @@
  * @author Laird Dornin
  *
  * @library ../../testlibrary
- * @build DGCDeadLock
- * @build Test
- * @build TestImpl
- * @build TestImpl_Stub
+ * @build TestLibrary Test TestImpl TestImpl_Stub
  * @run main/othervm/policy=security.policy/timeout=360 DGCDeadLock
  */
 
@@ -53,7 +50,7 @@
 import java.io.*;
 
 public class DGCDeadLock implements Runnable {
-
+    private static final int REGISTRY_PORT = TestLibrary.getUnusedRandomPort();
     final static public int HOLD_TARGET_TIME = 25000;
     public static int TEST_FAIL_TIME = HOLD_TARGET_TIME + 30000;
     public static boolean finished = false;
@@ -75,7 +72,9 @@
                 TestParams.defaultPolicy +
                 " -Djava.rmi.dgc.leaseValue=500000" +
                 "  -Dsun.rmi.dgc.checkInterval=" +
-                (HOLD_TARGET_TIME - 5000) + "";
+                (HOLD_TARGET_TIME - 5000) +
+                "   -Drmi.registry.port=" + REGISTRY_PORT +
+                "" ;
 
             testImplVM = new JavaVM("TestImpl", options, "");
             testImplVM.start();
@@ -112,7 +111,7 @@
 
             // create a test client
             Test foo = (Test) Naming.lookup("rmi://:" +
-                                            TestLibrary.REGISTRY_PORT +
+                                            REGISTRY_PORT +
                                             "/Foo");
             echo = foo.echo("Hello world");
             System.err.println("Test object created.");
@@ -131,7 +130,7 @@
 
             //import "Bar"
             Test bar = (Test) Naming.lookup("rmi://:" +
-                                            TestLibrary.REGISTRY_PORT +
+                                            REGISTRY_PORT +
                                             "/Bar");
 
             /* infinite loop to show the liveness of Client,
diff --git a/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java b/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java
index e9a734d..774e38a 100644
--- a/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java
+++ b/jdk/test/java/rmi/transport/dgcDeadLock/TestImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -36,7 +36,6 @@
 
 public class TestImpl extends UnicastRemoteObject
     implements Test {
-
     static Thread locker = null;
     static TestImpl foo = null;
     static TestImpl bar = null;
@@ -57,20 +56,21 @@
         Registry registry = null;
 
         try {
+            int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
             registry = java.rmi.registry.LocateRegistry.
-                createRegistry(TestLibrary.REGISTRY_PORT);
+                createRegistry(registryPort);
 
             //export "Foo"
             foo = new TestImpl();
             Naming.rebind("rmi://:" +
-                          TestLibrary.REGISTRY_PORT
+                          registryPort
                           + "/Foo", foo);
 
             try {
                 //export "Bar" after leases have been expired.
                 bar = new TestImpl();
                 Naming.rebind("rmi://localhost:" +
-                              TestLibrary.REGISTRY_PORT
+                              registryPort
                               + "/Bar", bar);
             } catch (Exception e) {
                 throw new RemoteException(e.getMessage());
diff --git a/jdk/test/java/rmi/transport/handshakeFailure/HandshakeFailure.java b/jdk/test/java/rmi/transport/handshakeFailure/HandshakeFailure.java
index f379baa..ed1ba8e 100644
--- a/jdk/test/java/rmi/transport/handshakeFailure/HandshakeFailure.java
+++ b/jdk/test/java/rmi/transport/handshakeFailure/HandshakeFailure.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -30,7 +30,8 @@
  * java.rmi.ConnectException or ConnectIOException, not a MarshalException.
  * @author Peter Jones
  *
- * @build HandshakeFailure
+ * @library ../../testlibrary
+ * @build TestLibrary
  * @run main/othervm HandshakeFailure
  */
 
@@ -44,7 +45,7 @@
 
 public class HandshakeFailure {
 
-    private static final int PORT = 2020;
+    private static final int PORT = TestLibrary.getUnusedRandomPort();
     private static final int TIMEOUT = 10000;
 
     public static void main(String[] args) throws Exception {
diff --git a/jdk/test/java/rmi/transport/handshakeTimeout/HandshakeTimeout.java b/jdk/test/java/rmi/transport/handshakeTimeout/HandshakeTimeout.java
index 13cffe6..ba492f4 100644
--- a/jdk/test/java/rmi/transport/handshakeTimeout/HandshakeTimeout.java
+++ b/jdk/test/java/rmi/transport/handshakeTimeout/HandshakeTimeout.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,8 @@
  * this point (because no data for the invocation has yet been written).
  * @author Peter Jones
  *
- * @build HandshakeTimeout
+ * @library ../../testlibrary
+ * @build TestLibrary
  * @run main/othervm HandshakeTimeout
  */
 
@@ -46,7 +47,7 @@
 
 public class HandshakeTimeout {
 
-    private static final int PORT = 2020;
+    private static final int PORT = TestLibrary.getUnusedRandomPort();
     private static final int TIMEOUT = 10000;
 
     public static void main(String[] args) throws Exception {
diff --git a/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java b/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java
index c9b4d4e..032c4cd 100644
--- a/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java
+++ b/jdk/test/java/rmi/transport/httpSocket/HttpSocketTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,7 @@
  * @author Dana Burns
  *
  * @library ../../testlibrary
- * @build HttpSocketTest HttpSocketTest_Stub
+ * @build TestLibrary HttpSocketTest HttpSocketTest_Stub
  * @run main/othervm/policy=security.policy HttpSocketTest
  */
 
@@ -56,10 +56,7 @@
 public class HttpSocketTest extends UnicastRemoteObject
     implements MyRemoteInterface
 {
-
     private static final String NAME = "HttpSocketTest";
-    private static final String REGNAME =
-        "//:" + TestLibrary.REGISTRY_PORT + "/" + NAME;
 
     public HttpSocketTest() throws RemoteException{}
 
@@ -76,21 +73,20 @@
         // Set the socket factory.
         System.err.println("installing socket factory");
         RMISocketFactory.setSocketFactory(new RMIHttpToPortSocketFactory());
+        int registryPort = -1;
 
         try {
-
             System.err.println("Starting registry");
-            registry = LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
-
+            registry = TestLibrary.createRegistryOnUnusedPort();
+            registryPort = TestLibrary.getRegistryPort(registry);
         } catch (Exception e) {
             TestLibrary.bomb(e);
         }
 
         try {
-
             registry.rebind( NAME, new HttpSocketTest() );
             MyRemoteInterface httpTest =
-                (MyRemoteInterface)Naming.lookup( REGNAME );
+                (MyRemoteInterface)Naming.lookup("//:" + registryPort + "/" + NAME);
             httpTest.setRemoteObject( new HttpSocketTest() );
             Remote r = httpTest.getRemoteObject();
 
diff --git a/jdk/test/java/rmi/transport/httpSocket/security.policy b/jdk/test/java/rmi/transport/httpSocket/security.policy
index 476bbaa..a0e93200 100644
--- a/jdk/test/java/rmi/transport/httpSocket/security.policy
+++ b/jdk/test/java/rmi/transport/httpSocket/security.policy
@@ -4,6 +4,10 @@
 
 grant {
     permission java.net.SocketPermission "*:1024-", "accept,connect,listen";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.registry";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.server";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport";
     permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.proxy";
+    permission java.lang.RuntimePermission "accessClassInPackage.sun.rmi.transport.tcp";
     permission java.lang.RuntimePermission "setFactory";
 };
diff --git a/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java b/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java
index ef17960..99357ff 100644
--- a/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java
+++ b/jdk/test/java/rmi/transport/pinClientSocketFactory/PinClientSocketFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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,6 +31,8 @@
  * should become unreachable too (through the RMI implementation).
  * @author Peter Jones
  *
+ * @library ../../testlibrary
+ * @build TestLibrary
  * @run main/othervm -Dsun.rmi.transport.connectionTimeout=2000
  *     PinClientSocketFactory
  */
@@ -56,7 +58,7 @@
 
 public class PinClientSocketFactory {
 
-    private static final int PORT = 2345;
+    private static final int PORT = TestLibrary.getUnusedRandomPort();
     private static final int SESSIONS = 50;
 
     public interface Factory extends Remote {
diff --git a/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java b/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java
index 445bdf3..f825602 100644
--- a/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java
+++ b/jdk/test/java/rmi/transport/pinLastArguments/PinLastArguments.java
@@ -78,10 +78,15 @@
         }
         impl = null;
 
-        System.gc();
-
-        if (ref.get() != null) {
-            throw new Error("TEST FAILED: impl not garbage collected");
+        // Might require multiple calls to System.gc() for weak-references
+        // processing to be complete. If the weak-reference is not cleared as
+        // expected we will hang here until timed out by the test harness.
+        while (true) {
+            System.gc();
+            Thread.sleep(20);
+            if (ref.get() == null) {
+                break;
+            }
         }
 
         System.err.println("TEST PASSED");
diff --git a/jdk/test/java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java b/jdk/test/java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java
index 9e722ba..4080bfa 100644
--- a/jdk/test/java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java
+++ b/jdk/test/java/rmi/transport/rapidExportUnexport/RapidExportUnexport.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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,7 +31,8 @@
  * procedure (which sleeps 10 seconds after 10 rapid failures).
  * @author Peter Jones
  *
- * @build RapidExportUnexport
+ * @library ../../testlibrary
+ * @build TestLibrary
  * @run main/othervm RapidExportUnexport
  */
 
@@ -39,9 +40,7 @@
 import java.rmi.server.UnicastRemoteObject;
 
 public class RapidExportUnexport {
-
-    private static final int PORT = 2055;
-
+    private static final int PORT = TestLibrary.getUnusedRandomPort();
     private static final int REPS = 100;
     private static final long TIMEOUT = 60000;
 
diff --git a/jdk/test/java/rmi/transport/readTimeout/ReadTimeoutTest.java b/jdk/test/java/rmi/transport/readTimeout/ReadTimeoutTest.java
index f72fea3..3a0bfa1 100644
--- a/jdk/test/java/rmi/transport/readTimeout/ReadTimeoutTest.java
+++ b/jdk/test/java/rmi/transport/readTimeout/ReadTimeoutTest.java
@@ -27,12 +27,9 @@
  * @summary Incoming connections should be subject to timeout
  * @author Adrian Colley
  *
- * @library ../../testlibrary
- * @build TestIface
- * @build TestImpl
- * @build TestImpl_Stub
- * @build ReadTimeoutTest
- * @run main/othervm/policy=security.policy/timeout=60 -Dsun.rmi.transport.tcp.readTimeout=5000 ReadTimeoutTest
+ * @build TestIface TestImpl TestImpl_Stub
+ * @run main/othervm/policy=security.policy/timeout=60
+ *     -Dsun.rmi.transport.tcp.readTimeout=5000 ReadTimeoutTest
  */
 
 /* This test sets a very short read timeout, exports an object, and then
diff --git a/jdk/test/java/rmi/transport/reuseDefaultPort/ReuseDefaultPort.java b/jdk/test/java/rmi/transport/reuseDefaultPort/ReuseDefaultPort.java
index d75257e..e5e7d80 100644
--- a/jdk/test/java/rmi/transport/reuseDefaultPort/ReuseDefaultPort.java
+++ b/jdk/test/java/rmi/transport/reuseDefaultPort/ReuseDefaultPort.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -33,7 +33,8 @@
  * continue to work because existing applications might depend on it.
  * @author Peter Jones
  *
- * @build ReuseDefaultPort
+ * @library ../../testlibrary
+ * @build TestLibrary
  * @run main/othervm ReuseDefaultPort
  */
 
@@ -48,7 +49,7 @@
 
 public class ReuseDefaultPort implements Remote {
 
-    private static final int PORT = 2223;
+    private static final int PORT = TestLibrary.getUnusedRandomPort();
 
     private ReuseDefaultPort() { }
 
diff --git a/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java b/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java
index 04a931d..ac48077 100644
--- a/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java
+++ b/jdk/test/java/rmi/transport/runtimeThreadInheritanceLeak/RuntimeThreadInheritanceLeak.java
@@ -38,7 +38,6 @@
  * subsystems also not holding on to the loader in their daemon threads.]
  * @author Peter Jones
  *
- * @build RuntimeThreadInheritanceLeak
  * @build RuntimeThreadInheritanceLeak_Stub
  * @run main/othervm RuntimeThreadInheritanceLeak
  */
diff --git a/jdk/test/java/security/BasicPermission/PermClass.java b/jdk/test/java/security/BasicPermission/PermClass.java
index bfbf999..3d7ee9d 100644
--- a/jdk/test/java/security/BasicPermission/PermClass.java
+++ b/jdk/test/java/security/BasicPermission/PermClass.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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,7 +23,7 @@
 
 /*
  * @test
- * @bug 4511601
+ * @bug 4511601 7054918
  * @summary BasicPermissionCollection does not set permClass
  *              during deserialization
  */
@@ -55,59 +55,66 @@
 
         // read in a 1.2.1 BasicPermissionCollection
         File sFile = new File(dir, "PermClass.1.2.1");
-        ObjectInputStream ois = new ObjectInputStream
-                (new FileInputStream(sFile));
-        PermissionCollection pc = (PermissionCollection)ois.readObject();
-        System.out.println("1.2.1 collection = " + pc);
+        try (FileInputStream fis = new FileInputStream(sFile);
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            PermissionCollection pc = (PermissionCollection) ois.readObject();
+            System.out.println("1.2.1 collection = " + pc);
 
-        if (pc.implies(mp)) {
-            System.out.println("JDK 1.2.1 test passed");
-        } else {
-            throw new Exception("JDK 1.2.1 test failed");
+            if (pc.implies(mp)) {
+                System.out.println("JDK 1.2.1 test passed");
+            } else {
+                throw new Exception("JDK 1.2.1 test failed");
+            }
         }
 
         // read in a 1.3.1 BasicPermissionCollection
         sFile = new File(dir, "PermClass.1.3.1");
-        ois = new ObjectInputStream(new FileInputStream(sFile));
-        pc = (PermissionCollection)ois.readObject();
-        System.out.println("1.3.1 collection = " + pc);
+        try (FileInputStream fis = new FileInputStream(sFile);
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            PermissionCollection pc = (PermissionCollection)ois.readObject();
+            System.out.println("1.3.1 collection = " + pc);
 
-        if (pc.implies(mp)) {
-            System.out.println("JDK 1.3.1 test passed");
-        } else {
-            throw new Exception("JDK 1.3.1 test failed");
+            if (pc.implies(mp)) {
+                System.out.println("JDK 1.3.1 test passed");
+            } else {
+                throw new Exception("JDK 1.3.1 test failed");
+            }
         }
 
         // read in a 1.4 BasicPermissionCollection
         sFile = new File(dir, "PermClass.1.4");
-        ois = new ObjectInputStream(new FileInputStream(sFile));
-        pc = (PermissionCollection)ois.readObject();
-        System.out.println("1.4 collection = " + pc);
+        try (FileInputStream fis = new FileInputStream(sFile);
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            PermissionCollection pc = (PermissionCollection)ois.readObject();
+            System.out.println("1.4 collection = " + pc);
 
-        if (pc.implies(mp)) {
-            System.out.println("JDK 1.4 test 1 passed");
-        } else {
-            throw new Exception("JDK 1.4 test 1 failed");
+            if (pc.implies(mp)) {
+                System.out.println("JDK 1.4 test 1 passed");
+            } else {
+                throw new Exception("JDK 1.4 test 1 failed");
+            }
         }
 
         // write out current BasicPermissionCollection
         PermissionCollection bpc = mp.newPermissionCollection();
         bpc.add(mp);
         sFile = new File(dir, "PermClass.current");
-        ObjectOutputStream oos = new ObjectOutputStream
-                (new FileOutputStream("PermClass.current"));
-        oos.writeObject(bpc);
-        oos.close();
+        try (FileOutputStream fos = new FileOutputStream("PermClass.current");
+                ObjectOutputStream oos = new ObjectOutputStream(fos)) {
+            oos.writeObject(bpc);
+        }
 
         // read in current BasicPermissionCollection
-        ois = new ObjectInputStream(new FileInputStream("PermClass.current"));
-        pc = (PermissionCollection)ois.readObject();
-        System.out.println("current collection = " + pc);
+        try (FileInputStream fis = new FileInputStream("PermClass.current");
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            PermissionCollection pc = (PermissionCollection)ois.readObject();
+            System.out.println("current collection = " + pc);
 
-        if (pc.implies(mp)) {
-            System.out.println("JDK 1.4 test 2 passed");
-        } else {
-            throw new Exception("JDK 1.4 test 2 failed");
+            if (pc.implies(mp)) {
+                System.out.println("JDK 1.4 test 2 passed");
+            } else {
+                throw new Exception("JDK 1.4 test 2 failed");
+            }
         }
     }
 }
diff --git a/jdk/test/java/security/BasicPermission/SerialVersion.java b/jdk/test/java/security/BasicPermission/SerialVersion.java
index 4ef0757..8c91735 100644
--- a/jdk/test/java/security/BasicPermission/SerialVersion.java
+++ b/jdk/test/java/security/BasicPermission/SerialVersion.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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,7 +23,7 @@
 
 /*
  * @test
- * @bug 4502729
+ * @bug 4502729 7054918
  * @summary BasicPermissionCollection serial version UID incorrect
  */
 
@@ -36,40 +36,44 @@
         String dir = System.getProperty("test.src");
         File  sFile =  new File (dir,"SerialVersion.1.2.1");
         // read in a 1.2.1 BasicPermissionCollection
-        ObjectInputStream ois = new ObjectInputStream
-                (new FileInputStream(sFile));
-        PermissionCollection pc = (PermissionCollection)ois.readObject();
-        System.out.println("1.2.1 collection = " + pc);
+        try (FileInputStream fis = new FileInputStream(sFile);
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            PermissionCollection pc = (PermissionCollection)ois.readObject();
+            System.out.println("1.2.1 collection = " + pc);
+        }
 
         // read in a 1.3.1 BasicPermissionCollection
         sFile =  new File (dir,"SerialVersion.1.3.1");
 
-        ois = new ObjectInputStream
-                (new FileInputStream(sFile));
-        pc = (PermissionCollection)ois.readObject();
-        System.out.println("1.3.1 collection = " + pc);
+        try (FileInputStream fis = new FileInputStream(sFile);
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            PermissionCollection pc = (PermissionCollection)ois.readObject();
+            System.out.println("1.3.1 collection = " + pc);
+        }
 
         // read in a 1.4 BasicPermissionCollection
         sFile =  new File (dir,"SerialVersion.1.4");
-        ois = new ObjectInputStream
-                (new FileInputStream(sFile));
-        pc = (PermissionCollection)ois.readObject();
-        System.out.println("1.4 collection = " + pc);
+        try (FileInputStream fis = new FileInputStream(sFile);
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            PermissionCollection pc = (PermissionCollection)ois.readObject();
+            System.out.println("1.4 collection = " + pc);
+        }
 
         // write out current BasicPermissionCollection
         MyPermission mp = new MyPermission("SerialVersionTest");
         PermissionCollection bpc = mp.newPermissionCollection();
         sFile =  new File (dir,"SerialVersion.current");
-        ObjectOutputStream oos = new ObjectOutputStream
-                (new FileOutputStream("SerialVersion.current"));
-        oos.writeObject(bpc);
-        oos.close();
+        try (FileOutputStream fos = new FileOutputStream("SerialVersion.current");
+                ObjectOutputStream oos = new ObjectOutputStream(fos)) {
+            oos.writeObject(bpc);
+        }
 
         // read in current BasicPermissionCollection
-        ois = new ObjectInputStream
-                (new FileInputStream("SerialVersion.current"));
-        pc = (PermissionCollection)ois.readObject();
-        System.out.println("current collection = " + pc);
+        try (FileInputStream fis = new FileInputStream("SerialVersion.current");
+                ObjectInputStream ois = new ObjectInputStream(fis)) {
+            PermissionCollection pc = (PermissionCollection)ois.readObject();
+            System.out.println("current collection = " + pc);
+        }
     }
 }
 
diff --git a/jdk/test/java/security/KeyFactory/Failover.java b/jdk/test/java/security/KeyFactory/Failover.java
index 4f27e96..ba5b980 100644
--- a/jdk/test/java/security/KeyFactory/Failover.java
+++ b/jdk/test/java/security/KeyFactory/Failover.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +23,8 @@
 
 /**
  * @test
- * @bug 4894125
+ * @bug 4894125 7054918
+ * @library ../testlibrary
  * @summary test that failover for KeyFactory works
  * @author Andreas Sterbenz
  */
@@ -37,6 +38,15 @@
 public class Failover {
 
     public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         Security.insertProviderAt(new ProviderFail(), 1);
         Security.addProvider(new ProviderPass());
         System.out.println(Arrays.asList(Security.getProviders()));
diff --git a/jdk/test/java/security/KeyPairGenerator/Failover.java b/jdk/test/java/security/KeyPairGenerator/Failover.java
index adb32ae..a28ad8b 100644
--- a/jdk/test/java/security/KeyPairGenerator/Failover.java
+++ b/jdk/test/java/security/KeyPairGenerator/Failover.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +23,8 @@
 
 /**
  * @test
- * @bug 4894125
+ * @bug 4894125 7054918
+ * @library ../testlibrary
  * @summary test that failover for KeyPairGenerator works
  * @author Andreas Sterbenz
  */
@@ -37,6 +38,15 @@
 public class Failover {
 
     public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         Security.insertProviderAt(new ProviderFail(), 1);
         Security.addProvider(new ProviderPass());
         System.out.println(Arrays.asList(Security.getProviders()));
diff --git a/jdk/test/java/security/Provider/ChangeProviders.java b/jdk/test/java/security/Provider/ChangeProviders.java
index e373ede..e795c97 100644
--- a/jdk/test/java/security/Provider/ChangeProviders.java
+++ b/jdk/test/java/security/Provider/ChangeProviders.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +23,8 @@
 
 /*
  * @test
- * @bug 4856968
+ * @bug 4856968 7054918
+ * @library ../testlibrary
  * @summary make sure add/insert/removeProvider() work correctly
  * @author Andreas Sterbenz
  */
@@ -43,6 +44,15 @@
     }
 
     public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         long start = System.currentTimeMillis();
         Provider p = new ChangeProviders();
 
diff --git a/jdk/test/java/security/Provider/GetInstance.java b/jdk/test/java/security/Provider/GetInstance.java
index 362ee49..b87578f 100644
--- a/jdk/test/java/security/Provider/GetInstance.java
+++ b/jdk/test/java/security/Provider/GetInstance.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +23,8 @@
 
 /*
  * @test
- * @bug 4856968
+ * @bug 4856968 7054918
+ * @library ../testlibrary
  * @summary make sure getInstance() works correctly, including failover
  *   and delayed provider selection for Signatures
  * @author Andreas Sterbenz
@@ -43,6 +44,15 @@
     }
 
     public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         long start = System.currentTimeMillis();
 
         Provider foo = new FooProvider();
diff --git a/jdk/test/java/security/Provider/RemoveProvider.java b/jdk/test/java/security/Provider/RemoveProvider.java
index 1628dad..111240d 100644
--- a/jdk/test/java/security/Provider/RemoveProvider.java
+++ b/jdk/test/java/security/Provider/RemoveProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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,7 +23,8 @@
 
 /*
  * @test
- * @bug 4190873
+ * @bug 4190873 7054918
+ * @library ../testlibrary
  * @summary Make sure provider instance can be removed from list of registered
  * providers, and "entrySet", "keySet", and "values" methods don't loop
  * indefinitely.
@@ -34,6 +35,15 @@
 public class RemoveProvider {
 
     public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
 
         // Add provider 1
         Provider p1 = new MyProvider("name1",1,"");
diff --git a/jdk/test/java/security/Provider/Turkish.java b/jdk/test/java/security/Provider/Turkish.java
index 071c58f..099f70a 100644
--- a/jdk/test/java/security/Provider/Turkish.java
+++ b/jdk/test/java/security/Provider/Turkish.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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,9 +23,8 @@
 
 /**
  * @test
- * @bug 6220064
+ * @bug 6220064 7054918
  * @summary make sure everything works ok in the Turkish local (dotted/dotless i problem)
- * @run main/othervm Turkish
  * @author Andreas Sterbenz
  */
 
@@ -41,54 +40,59 @@
         Provider p1 = new TProvider("T1");
         System.out.println(p1.getServices()); // trigger service parsing
 
-        Locale.setDefault(new Locale("tr", "TR"));
+        Locale loc = Locale.getDefault();
+        try {
+            Locale.setDefault(new Locale("tr", "TR"));
 
-        Provider p2 = new TProvider("T2");
-        System.out.println(p2.getServices()); // trigger service parsing
+            Provider p2 = new TProvider("T2");
+            System.out.println(p2.getServices()); // trigger service parsing
 
-        System.out.println(Signature.getInstance("MD5withRSA"));
-        System.out.println(Signature.getInstance("md5withrsa"));
-        System.out.println(Signature.getInstance("MD5WITHRSA"));
-        Service s1, s2;
-        s1 = p1.getService("Signature", "MD5withRSA");
-        check(s1, null);
-        check(s1, p1.getService("Signature", "md5withrsa"));
-        check(s1, p1.getService("Signature", "MD5WITHRSA"));
-        check(s1, p1.getService("Signature", "MD5RSA"));
-        check(s1, p1.getService("Signature", "md5rsa"));
-        check(s1, p1.getService("Signature", "MD5rsa"));
+            System.out.println(Signature.getInstance("MD5withRSA"));
+            System.out.println(Signature.getInstance("md5withrsa"));
+            System.out.println(Signature.getInstance("MD5WITHRSA"));
+            Service s1, s2;
+            s1 = p1.getService("Signature", "MD5withRSA");
+            check(s1, null);
+            check(s1, p1.getService("Signature", "md5withrsa"));
+            check(s1, p1.getService("Signature", "MD5WITHRSA"));
+            check(s1, p1.getService("Signature", "MD5RSA"));
+            check(s1, p1.getService("Signature", "md5rsa"));
+            check(s1, p1.getService("Signature", "MD5rsa"));
 
-        s1 = p1.getService("Signature", "SHAwithRSA");
-        check(s1, null);
-        check(s1, p1.getService("Signature", "shawithrsa"));
-        check(s1, p1.getService("Signature", "SHAWITHRSA"));
-        check(s1, p1.getService("Signature", "SHARSA"));
-        check(s1, p1.getService("Signature", "sharsa"));
-        check(s1, p1.getService("Signature", "SHArsa"));
-        check(s1, p1.getService("Signature", "SHA1RSA"));
-        check(s1, p1.getService("Signature", "sha1rsa"));
-        check(s1, p1.getService("Signature", "SHA1rsa"));
+            s1 = p1.getService("Signature", "SHAwithRSA");
+            check(s1, null);
+            check(s1, p1.getService("Signature", "shawithrsa"));
+            check(s1, p1.getService("Signature", "SHAWITHRSA"));
+            check(s1, p1.getService("Signature", "SHARSA"));
+            check(s1, p1.getService("Signature", "sharsa"));
+            check(s1, p1.getService("Signature", "SHArsa"));
+            check(s1, p1.getService("Signature", "SHA1RSA"));
+            check(s1, p1.getService("Signature", "sha1rsa"));
+            check(s1, p1.getService("Signature", "SHA1rsa"));
 
-        s1 = p2.getService("Signature", "MD5withRSA");
-        check(s1, null);
-        check(s1, p2.getService("Signature", "md5withrsa"));
-        check(s1, p2.getService("Signature", "MD5WITHRSA"));
-        check(s1, p2.getService("Signature", "MD5RSA"));
-        check(s1, p2.getService("Signature", "md5rsa"));
-        check(s1, p2.getService("Signature", "MD5rsa"));
+            s1 = p2.getService("Signature", "MD5withRSA");
+            check(s1, null);
+            check(s1, p2.getService("Signature", "md5withrsa"));
+            check(s1, p2.getService("Signature", "MD5WITHRSA"));
+            check(s1, p2.getService("Signature", "MD5RSA"));
+            check(s1, p2.getService("Signature", "md5rsa"));
+            check(s1, p2.getService("Signature", "MD5rsa"));
 
-        s1 = p2.getService("Signature", "SHAwithRSA");
-        check(s1, null);
-        check(s1, p2.getService("Signature", "shawithrsa"));
-        check(s1, p2.getService("Signature", "SHAWITHRSA"));
-        check(s1, p2.getService("Signature", "SHARSA"));
-        check(s1, p2.getService("Signature", "sharsa"));
-        check(s1, p2.getService("Signature", "SHArsa"));
-        check(s1, p2.getService("Signature", "SHA1RSA"));
-        check(s1, p2.getService("Signature", "sha1rsa"));
-        check(s1, p2.getService("Signature", "SHA1rsa"));
+            s1 = p2.getService("Signature", "SHAwithRSA");
+            check(s1, null);
+            check(s1, p2.getService("Signature", "shawithrsa"));
+            check(s1, p2.getService("Signature", "SHAWITHRSA"));
+            check(s1, p2.getService("Signature", "SHARSA"));
+            check(s1, p2.getService("Signature", "sharsa"));
+            check(s1, p2.getService("Signature", "SHArsa"));
+            check(s1, p2.getService("Signature", "SHA1RSA"));
+            check(s1, p2.getService("Signature", "sha1rsa"));
+            check(s1, p2.getService("Signature", "SHA1rsa"));
 
-        System.out.println("OK");
+            System.out.println("OK");
+        } finally {
+            Locale.setDefault(loc);
+        }
     }
 
     private static void check(Service s1, Service s2) throws Exception {
diff --git a/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh b/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh
index 35342ce..1109496 100644
--- a/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh
+++ b/jdk/test/java/security/Security/ClassLoaderDeadlock/Deadlock2.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, 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
@@ -58,6 +58,10 @@
     PATHSEP=":"
     FILESEP="/"
     ;;
+  CYGWIN* )
+    PATHSEP=";"
+    FILESEP="/"
+    ;;
   Darwin )
     PATHSEP=":"
     FILESEP="/"
diff --git a/jdk/test/java/security/Security/NoInstalledProviders.java b/jdk/test/java/security/Security/NoInstalledProviders.java
index c8fe02e..a410edb 100644
--- a/jdk/test/java/security/Security/NoInstalledProviders.java
+++ b/jdk/test/java/security/Security/NoInstalledProviders.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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,7 +23,8 @@
 
 /*
  * @test
- * @bug 4273454 7052537
+ * @bug 4273454 7054918 7052537
+ * @library ../testlibrary
  * @summary Make sure getProviders(filter) doesn't throw NPE
  * @run main/othervm NoInstalledProviders
  */
@@ -32,7 +33,16 @@
 
 public class NoInstalledProviders {
 
-    public static void main(String[] argv) {
+    public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
 
         Provider[] provs = Security.getProviders();
         // make sure there are no providers in the system
diff --git a/jdk/test/java/security/Security/SynchronizedAccess.java b/jdk/test/java/security/Security/SynchronizedAccess.java
index 8ab8dab..4321a80 100644
--- a/jdk/test/java/security/Security/SynchronizedAccess.java
+++ b/jdk/test/java/security/Security/SynchronizedAccess.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2012, 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,7 +23,8 @@
 
 /*
  * @test
- * @bug 4162583
+ * @bug 4162583 7054918
+ * @library ../testlibrary
  * @summary Make sure Provider api implementations are synchronized properly
  */
 
@@ -31,7 +32,16 @@
 
 public class SynchronizedAccess {
 
-    public static void main(String[] args) {
+    public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         AccessorThread[] acc = new AccessorThread[200];
         for (int i=0; i < acc.length; i++)
             acc[i] = new AccessorThread("thread"+i);
diff --git a/jdk/test/java/security/Security/removing/RemoveProviders.java b/jdk/test/java/security/Security/removing/RemoveProviders.java
index cd2bd13..87f0496 100644
--- a/jdk/test/java/security/Security/removing/RemoveProviders.java
+++ b/jdk/test/java/security/Security/removing/RemoveProviders.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +23,8 @@
 
 /**
  * @test
- * @bug 4963416
+ * @bug 4963416 7054918
+ * @library ../../testlibrary
  * @summary make sure removeProvider() always works correctly
  * @author Andreas Sterbenz
  */
@@ -35,6 +36,15 @@
 public class RemoveProviders {
 
     public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         Provider[] providers = Security.getProviders();
         System.out.println("Providers: " + Arrays.asList(providers));
 
diff --git a/jdk/test/java/security/Signature/VerifyRangeCheckOverflow.java b/jdk/test/java/security/Signature/VerifyRangeCheckOverflow.java
new file mode 100644
index 0000000..9077cc2
--- /dev/null
+++ b/jdk/test/java/security/Signature/VerifyRangeCheckOverflow.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test
+ * @bug 7172149
+ * @summary AIOOBE from Signature.verify after integer overflow
+ * @author Jonathan Lu
+ */
+
+import java.security.KeyPair;
+import java.security.KeyPairGenerator;
+import java.security.PublicKey;
+import java.security.Signature;
+
+public class VerifyRangeCheckOverflow {
+
+    public static void main(String[] args) throws Exception {
+        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("DSA");
+        keyPairGenerator.initialize(1024);
+        KeyPair keys = keyPairGenerator.generateKeyPair();
+        PublicKey publicKey = keys.getPublic();
+        byte[] sigBytes = new byte[100];
+
+        Signature signature = Signature.getInstance("SHA1withDSA");
+        signature.initVerify(publicKey);
+        try {
+            signature.verify(sigBytes, Integer.MAX_VALUE, 1);
+        } catch (IllegalArgumentException ex) {
+            // Expected
+        }
+    }
+}
diff --git a/jdk/test/java/security/UnresolvedPermission/Equals.java b/jdk/test/java/security/UnresolvedPermission/Equals.java
index 3a89e68..ec83218 100644
--- a/jdk/test/java/security/UnresolvedPermission/Equals.java
+++ b/jdk/test/java/security/UnresolvedPermission/Equals.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 4513737
+ * @run main/othervm Equals
  * @summary UnresolvedPermission.equals() throws NullPointerException
  */
 
diff --git a/jdk/test/java/security/spec/EllipticCurveMatch.java b/jdk/test/java/security/spec/EllipticCurveMatch.java
index 5190865..c3c7730 100644
--- a/jdk/test/java/security/spec/EllipticCurveMatch.java
+++ b/jdk/test/java/security/spec/EllipticCurveMatch.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,13 +25,12 @@
  * @test
  * @bug 6738532
  * @summary Check EllipticCurve.equals() does not compare seed value of curve.
- * @run main/othervm EllipticCurveMatch
  * @author Mike StJohns
  */
 
 import java.security.spec.*;
 import java.math.BigInteger;
-import java.security.SecureRandom;
+import java.util.Random;
 
 public class EllipticCurveMatch {
     static String primeP256 =
@@ -45,7 +44,7 @@
 
     private static EllipticCurve addSeedToCurve(EllipticCurve curve)
     {
-        SecureRandom rand = new SecureRandom();
+        Random rand = new Random();
         byte[] seed = new byte[12];
         rand.nextBytes(seed);
 
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/jdk/test/java/security/testlibrary/Providers.java
similarity index 67%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to jdk/test/java/security/testlibrary/Providers.java
index 077886f..3ba1944 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/jdk/test/java/security/testlibrary/Providers.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,18 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+import java.security.Provider;
+import java.security.Security;
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
+public class Providers {
+    public static void setAt(Provider p, int pos) throws Exception {
+        if (Security.getProvider(p.getName()) != null) {
+            Security.removeProvider(p.getName());
+        }
+        if (Security.insertProviderAt(p, pos) == -1) {
+            throw new Exception("cannot setAt");
+        }
     }
 }
diff --git a/jdk/test/java/security/testlibrary/ProvidersSnapshot.java b/jdk/test/java/security/testlibrary/ProvidersSnapshot.java
new file mode 100644
index 0000000..af2fe0d
--- /dev/null
+++ b/jdk/test/java/security/testlibrary/ProvidersSnapshot.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.security.Provider;
+import java.security.Security;
+
+public class ProvidersSnapshot {
+
+    private Provider[] oldProviders;
+
+    private ProvidersSnapshot() {
+        oldProviders = Security.getProviders();
+    }
+
+    public static ProvidersSnapshot create() {
+        return new ProvidersSnapshot();
+    }
+
+    public void restore() {
+        Provider[] newProviders = Security.getProviders();
+        for (Provider p: newProviders) {
+            Security.removeProvider(p.getName());
+        }
+        for (Provider p: oldProviders) {
+            Security.addProvider(p);
+        }
+    }
+}
diff --git a/jdk/test/java/util/AbstractCollection/ToArrayTest.java b/jdk/test/java/util/AbstractCollection/ToArrayTest.java
new file mode 100644
index 0000000..1cbf66f
--- /dev/null
+++ b/jdk/test/java/util/AbstractCollection/ToArrayTest.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright (c) 2012 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 7121314
+ * @summary AbstractCollection.toArray(T[]) doesn't return the given array
+ *           in concurrent modification.
+ * @author Ulf Zibis, David Holmes
+ */
+
+import java.util.AbstractCollection;
+import java.util.Arrays;
+import java.util.Iterator;
+
+public class ToArrayTest {
+
+    static class TestCollection<E> extends AbstractCollection<E> {
+        private final E[] elements;
+        private int[] sizes;
+        private int nextSize;
+
+        public TestCollection(E[] elements) {
+            this.elements = elements;
+            setSizeSequence(new int[] { elements.length });
+        }
+
+        /*
+         * Sets the values that size() will return on each use. The next
+         * call to size will return sizes[0], then sizes[1] etc. This allows us
+         * to emulate a concurrent change to the contents of the collection
+         * without having to perform concurrent changes. If sizes[n+1] contains
+         * a larger value, the collection will appear to have shrunk when
+         * iterated; if a smaller value then the collection will appear to have
+         * grown when iterated.
+         */
+        void setSizeSequence(int... sizes) {
+            this.sizes = sizes;
+            nextSize = 0;
+        }
+
+        /* can change collection's size after each invocation */
+        @Override
+        public int size() {
+            return sizes[nextSize == sizes.length - 1 ? nextSize : nextSize++];
+        }
+
+        @Override
+        public Iterator<E> iterator() {
+            return new Iterator<E>() {
+                int pos = 0;
+
+                public boolean hasNext() {
+                    return pos < sizes[nextSize];
+                }
+                public E next() {
+                    return elements[pos++];
+                }
+                public void remove() {
+                    throw new UnsupportedOperationException(
+                            "Not supported yet.");
+                }
+            };
+        }
+    }
+
+    static final Object[] OBJECTS = { new Object(), new Object(), new Object() };
+    static final TestCollection<?> CANDIDATE = new TestCollection<Object>(OBJECTS);
+    static final int CAP = OBJECTS.length; // capacity of the CANDIDATE
+    static final int LAST = CAP - 1; // last possible array index
+    Object[] a;
+    Object[] res;
+
+    int last() {
+        return a.length - 1;
+    }
+
+    protected void test() throws Throwable {
+        // Check array type conversion
+        res = new TestCollection<>(new Object[] { "1", "2" }).toArray(new String[0]);
+        check(res instanceof String[]);
+        check(res.length == 2);
+        check(res[1] == "2");
+
+        // Check incompatible type of target array
+        try {
+            res = CANDIDATE.toArray(new String[CAP]);
+            check(false);
+        } catch (Throwable t) {
+            check(t instanceof ArrayStoreException);
+        }
+
+        // Check more elements than a.length
+        a = new Object[CAP - 1]; // appears too small
+        res = CANDIDATE.toArray(a);
+        check(res != a);
+        check(res[LAST] != null);
+
+        // Check equal elements as a.length
+        a = new Object[CAP]; // appears to match
+        res = CANDIDATE.toArray(a);
+        check(res == a);
+        check(res[last()] != null);
+
+        // Check equal elements as a.length
+        a = new Object[CAP + 1]; // appears too big
+        res = CANDIDATE.toArray(a);
+        check(res == a);
+        check(res[last()] == null);
+
+        // Check less elements than expected, but more than a.length
+        a = new Object[CAP - 2]; // appears too small
+        CANDIDATE.setSizeSequence(CAP, CAP - 1);
+        res = CANDIDATE.toArray(a);
+        check(res != a);
+        check(res.length == CAP - 1);
+        check(res[LAST - 1] != null);
+
+        // Check less elements than expected, but equal as a.length
+        a = Arrays.copyOf(OBJECTS, CAP); // appears to match
+        CANDIDATE.setSizeSequence(CAP, CAP - 1);
+        res = CANDIDATE.toArray(a);
+        check(res == a);
+        check(res[last()] == null);
+
+        // Check more elements than expected and more than a.length
+        a = new Object[CAP - 1]; // appears to match
+        CANDIDATE.setSizeSequence(CAP - 1, CAP);
+        res = CANDIDATE.toArray(a);
+        check(res != a);
+        check(res[LAST] != null);
+
+        // Check more elements than expected, but equal as a.length
+        a = new Object[CAP - 1]; // appears to match
+        CANDIDATE.setSizeSequence(CAP - 2, CAP - 1);
+        res = CANDIDATE.toArray(a);
+        check(res == a);
+        check(res[last()] != null);
+
+        // Check more elements than expected, but less than a.length
+        a = Arrays.copyOf(OBJECTS, CAP); // appears to match
+        CANDIDATE.setSizeSequence(CAP - 2, CAP - 1);
+        res = CANDIDATE.toArray(a);
+        check(res == a);
+        check(res[last()] == null);
+
+        test_7121314();
+    }
+
+    /*
+     * Major target of this testcase, bug 7121314.
+     */
+    protected void test_7121314() throws Throwable {
+        // Check equal elements as a.length, but less than expected
+        a = new Object[CAP - 1]; // appears too small
+        CANDIDATE.setSizeSequence(CAP, CAP - 1);
+        res = CANDIDATE.toArray(a);
+        check(res == a);
+        check(res[last()] != null);
+
+        // Check less elements than a.length and less than expected
+        a = Arrays.copyOf(OBJECTS, CAP - 1); // appears too small
+        CANDIDATE.setSizeSequence(CAP, CAP - 2);
+        res = CANDIDATE.toArray(a);
+        check(res == a);
+        check(res[last()] == null);
+
+    }
+
+    public static void main(String[] args) throws Throwable {
+        ToArrayTest testcase = new ToArrayTest();
+        try {
+            testcase.test();
+        } catch (Throwable t) {
+            unexpected(t);
+        }
+
+        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
+        if (failed > 0) throw new Exception("Some tests failed");
+    }
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() { passed++; }
+    static void fail() { failed++; Thread.dumpStack(); }
+    static void fail(String msg) { System.out.println(msg); fail(); }
+    static void unexpected(Throwable t) { failed++; t.printStackTrace(); }
+    static void check(boolean cond) { if (cond) pass(); else fail(); }
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else {System.out.println(x + " not equal to " + y); fail(); }
+    }
+}
+
+
diff --git a/jdk/test/java/util/Map/Collisions.java b/jdk/test/java/util/Map/Collisions.java
index 93c3639..21f9e87 100644
--- a/jdk/test/java/util/Map/Collisions.java
+++ b/jdk/test/java/util/Map/Collisions.java
@@ -24,6 +24,8 @@
 /*
  * @test
  * @bug 7126277
+ * @run main Collisions -shortrun
+ * @run main/othervm -Djdk.map.althashing.threshold=0 Collisions -shortrun
  * @summary Ensure Maps behave well with lots of hashCode() collisions.
  * @author Mike Duigou
  */
@@ -33,6 +35,11 @@
 
 public class Collisions {
 
+    /**
+     * Number of elements per map.
+     */
+    private static final int TEST_SIZE = 5000;
+
     final static class HashableInteger implements Comparable<HashableInteger> {
 
         final int value;
@@ -64,20 +71,19 @@
             return value - o.value;
         }
 
+        @Override
         public String toString() {
             return Integer.toString(value);
         }
     }
-    private static final int ITEMS = 5000;
-    private static final Object KEYS[][];
 
-    static {
-        HashableInteger UNIQUE_OBJECTS[] = new HashableInteger[ITEMS];
-        HashableInteger COLLIDING_OBJECTS[] = new HashableInteger[ITEMS];
-        String UNIQUE_STRINGS[] = new String[ITEMS];
-        String COLLIDING_STRINGS[] = new String[ITEMS];
+    private static Object[][] makeTestData(int size) {
+        HashableInteger UNIQUE_OBJECTS[] = new HashableInteger[size];
+        HashableInteger COLLIDING_OBJECTS[] = new HashableInteger[size];
+        String UNIQUE_STRINGS[] = new String[size];
+        String COLLIDING_STRINGS[] = new String[size];
 
-        for (int i = 0; i < ITEMS; i++) {
+        for (int i = 0; i < size; i++) {
             UNIQUE_OBJECTS[i] = new HashableInteger(i, Integer.MAX_VALUE);
             COLLIDING_OBJECTS[i] = new HashableInteger(i, 10);
             UNIQUE_STRINGS[i] = unhash(i);
@@ -86,7 +92,7 @@
                     : "\u0000\u0000\u0000\u0000\u0000" + COLLIDING_STRINGS[i - 1];
         }
 
-     KEYS = new Object[][] {
+     return new Object[][] {
             new Object[]{"Unique Objects", UNIQUE_OBJECTS},
             new Object[]{"Colliding Objects", COLLIDING_OBJECTS},
             new Object[]{"Unique Strings", UNIQUE_STRINGS},
@@ -132,23 +138,29 @@
     }
 
     private static void realMain(String[] args) throws Throwable {
-        for (Object[] keys_desc : KEYS) {
-            Map<Object, Object>[] MAPS = (Map<Object, Object>[]) new Map[]{
-                        new Hashtable<>(),
+        boolean shortRun = args.length > 0 && args[0].equals("-shortrun");
+
+        Object[][] mapKeys = makeTestData(shortRun ? (TEST_SIZE / 2) : TEST_SIZE);
+
+        // loop through data sets
+        for (Object[] keys_desc : mapKeys) {
+            Map<Object, Object>[] maps = (Map<Object, Object>[]) new Map[]{
                         new HashMap<>(),
+                        new Hashtable<>(),
                         new IdentityHashMap<>(),
                         new LinkedHashMap<>(),
-                        new ConcurrentHashMap<>(),
-                        new WeakHashMap<>(),
                         new TreeMap<>(),
+                        new WeakHashMap<>(),
+                        new ConcurrentHashMap<>(),
                         new ConcurrentSkipListMap<>()
                     };
 
-            for (Map<Object, Object> map : MAPS) {
+            // for each map type.
+            for (Map<Object, Object> map : maps) {
                 String desc = (String) keys_desc[0];
                 Object[] keys = (Object[]) keys_desc[1];
                 try {
-                testMap(map, desc, keys);
+                    testMap(map, desc, keys);
                 } catch(Exception all) {
                     unexpected("Failed for " + map.getClass().getName() + " with " + desc, all);
                 }
@@ -397,7 +409,7 @@
     }
 
     public static void main(String[] args) throws Throwable {
-        Thread.currentThread().setName("Collisions");
+        Thread.currentThread().setName(Collisions.class.getName());
 //        Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
         try {
             realMain(args);
diff --git a/jdk/test/java/util/Map/EntryHashCode.java b/jdk/test/java/util/Map/EntryHashCode.java
new file mode 100644
index 0000000..f245c9b
--- /dev/null
+++ b/jdk/test/java/util/Map/EntryHashCode.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 8000955
+ * @summary Map.Entry implementations need to comply with Map.Entry.hashCode() defined behaviour.
+ * @author ngmr
+ * @run main/othervm -Djdk.map.althashing.threshold=1 EntryHashCode
+ */
+import java.util.*;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentSkipListMap;
+
+public class EntryHashCode {
+    private static final int TEST_SIZE = 100;
+
+    static final Object[][] entryData = {
+        new Object[TEST_SIZE],
+        new Object[TEST_SIZE]
+    };
+
+    @SuppressWarnings("unchecked")
+    static final Map<Object,Object>[] maps = (Map<Object,Object>[])new Map[] {
+        new HashMap<>(),
+        new Hashtable<>(),
+        new IdentityHashMap<>(),
+        new LinkedHashMap<>(),
+        new TreeMap<>(),
+        new WeakHashMap<>(),
+        new ConcurrentHashMap<>(),
+        new ConcurrentSkipListMap<>()
+    };
+
+    static {
+        for (int i = 0; i < entryData[0].length; i++) {
+            // key objects need to be Comparable for use in TreeMap
+            entryData[0][i] = new Comparable<Object>() {
+                public int compareTo(Object o) {
+                    return (hashCode() - o.hashCode());
+                }
+            };
+            entryData[1][i] = new Object();
+        }
+    }
+
+    private static void addTestData(Map<Object,Object> map) {
+        for (int i = 0; i < entryData[0].length; i++) {
+            map.put(entryData[0][i], entryData[1][i]);
+        }
+    }
+
+    public static void main(String[] args) throws Exception {
+        Exception failure = null;
+        for (Map<Object,Object> map: maps) {
+            addTestData(map);
+
+            try {
+                for (Map.Entry<Object,Object> e: map.entrySet()) {
+                    Object key = e.getKey();
+                    Object value = e.getValue();
+                    int expectedEntryHashCode =
+                        (Objects.hashCode(key) ^ Objects.hashCode(value));
+
+                    if (e.hashCode() != expectedEntryHashCode) {
+                        throw new Exception("FAILURE: " +
+                                e.getClass().getName() +
+                                ".hashCode() does not conform to defined" +
+                                " behaviour of java.util.Map.Entry.hashCode()");
+                    }
+                }
+            } catch (Exception e) {
+                if (failure == null) {
+                    failure = e;
+                } else {
+                    failure.addSuppressed(e);
+                }
+            } finally {
+                map.clear();
+            }
+        }
+        if (failure != null) {
+            throw failure;
+        }
+    }
+}
diff --git a/jdk/test/java/util/TimeZone/Bug6912560.java b/jdk/test/java/util/TimeZone/Bug6912560.java
index c641f33..e88ffb0 100644
--- a/jdk/test/java/util/TimeZone/Bug6912560.java
+++ b/jdk/test/java/util/TimeZone/Bug6912560.java
@@ -40,6 +40,9 @@
         // set the user.timezone property
         String tzname = "Asia/Tokyo";
         System.setProperty("user.timezone", tzname);
+        // make sure the timezone will be initialized by
+        // the next call to TimeZone.getDefault()
+        TimeZone.setDefault(null);
 
         System.setSecurityManager(new SecurityManager());
         TimeZone tz = TimeZone.getDefault();
diff --git a/jdk/test/java/util/TreeMap/Clone.java b/jdk/test/java/util/TreeMap/Clone.java
new file mode 100644
index 0000000..efffa6a
--- /dev/null
+++ b/jdk/test/java/util/TreeMap/Clone.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2012, 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 7198904
+ * @summary Verify that cloned TreeMap gets new keyset
+ * @author david.buck@oracle.com
+ * @run main/othervm Clone
+ * @run main/othervm -XX:+AggressiveOpts Clone
+ */
+
+import java.util.TreeMap;
+
+public class Clone  {
+
+    public static void main(String[] args) throws Exception {
+        TreeMap<String,Object> m1 = new TreeMap<String,Object>();
+        m1.put( "one", 1 );
+        m1.keySet();
+        TreeMap<String,Object> m2 = (TreeMap<String,Object>)m1.clone();
+        m1.put( "two", 2 );
+        m2.put( "three", 3 );
+        // iterate over the clone (m2) and we should get "one" and "three"
+        for( final String key : m2.keySet() ) {
+            if( !"one".equals( key ) && !"three".equals( key ) ) {
+                throw new IllegalStateException( "Unexpected key: " + key );
+            }
+        }
+        // iterate over the original (m1) and we should get "one" and "two"
+        for( final String key : m1.keySet() ) {
+            if( !"one".equals( key ) && !"two".equals( key ) ) {
+                throw new IllegalStateException( "Unexpected key: " + key );
+            }
+        }
+    }
+
+}
diff --git a/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java b/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java
index df50ef0..d8cf75f 100644
--- a/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java
+++ b/jdk/test/java/util/concurrent/BlockingQueue/LastElement.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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,7 +23,7 @@
 
 /*
  * @test
- * @bug 6215625
+ * @bug 6215625 7161229
  * @summary Check correct behavior when last element is removed.
  * @author Martin Buchholz
  */
@@ -38,9 +38,7 @@
         testQueue(new ArrayBlockingQueue<Integer>(10, true));
         testQueue(new ArrayBlockingQueue<Integer>(10, false));
         testQueue(new LinkedTransferQueue<Integer>());
-
-        System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
-        if (failed > 0) throw new Exception("Some tests failed");
+        testQueue(new PriorityBlockingQueue<Integer>());
     }
 
     void testQueue(BlockingQueue<Integer> q) throws Throwable {
@@ -59,6 +57,7 @@
         try {check(q.take() == three);}
         catch (Throwable t) {unexpected(t);}
         check(q.isEmpty() && q.size() == 0);
+        check(noRetention(q));
 
         // iterator().remove()
         q.clear();
@@ -77,6 +76,26 @@
         check(q.isEmpty() && q.size() == 0);
     }
 
+    boolean noRetention(BlockingQueue<?> q) {
+        if (q instanceof PriorityBlockingQueue) {
+            PriorityBlockingQueue<?> pbq = (PriorityBlockingQueue) q;
+            try {
+                java.lang.reflect.Field queue =
+                    PriorityBlockingQueue.class.getDeclaredField("queue");
+                queue.setAccessible(true);
+                Object[] a = (Object[]) queue.get(pbq);
+                return a[0] == null;
+            }
+            catch (NoSuchFieldException e) {
+                unexpected(e);
+            }
+            catch (IllegalAccessException e) {
+                // ignore - security manager must be installed
+            }
+        }
+        return true;
+    }
+
     //--------------------- Infrastructure ---------------------------
     volatile int passed = 0, failed = 0;
     void pass() {passed++;}
diff --git a/jdk/test/java/util/prefs/AddNodeChangeListener.java b/jdk/test/java/util/prefs/AddNodeChangeListener.java
new file mode 100644
index 0000000..8b506dc
--- /dev/null
+++ b/jdk/test/java/util/prefs/AddNodeChangeListener.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+ /* @test
+  * @bug  7160252
+  * @summary Checks if events are delivered to a listener
+  *          when a child node is added or removed
+  */
+
+import java.util.prefs.*;
+
+ public class AddNodeChangeListener {
+
+     private static boolean failed = false;
+     private static Preferences userRoot, N2;
+     private static NodeChangeListenerAdd ncla;
+
+     public static void main(String[] args)
+         throws BackingStoreException, InterruptedException
+     {
+        userRoot = Preferences.userRoot();
+        ncla = new NodeChangeListenerAdd();
+        userRoot.addNodeChangeListener(ncla);
+        //Should initiate a node added event
+        addNode();
+        // Should not initiate a node added event
+        addNode();
+        //Should initate a child removed event
+        removeNode();
+
+        if (failed)
+            throw new RuntimeException("Failed");
+    }
+
+    private static void addNode()
+        throws BackingStoreException, InterruptedException
+    {
+        N2 = userRoot.node("N2");
+        userRoot.flush();
+        Thread.sleep(3000);
+        if (ncla.getAddNumber() != 1)
+            failed = true;
+    }
+
+    private static void removeNode()
+        throws BackingStoreException, InterruptedException
+    {
+        N2.removeNode();
+        userRoot.flush();
+        Thread.sleep(3000);
+        if (ncla.getAddNumber() != 0)
+            failed = true;
+    }
+
+    private static class NodeChangeListenerAdd implements NodeChangeListener {
+        private int totalNode = 0;
+
+        @Override
+        public void childAdded(NodeChangeEvent evt) {
+            totalNode++;
+        }
+
+        @Override
+        public void childRemoved(NodeChangeEvent evt) {
+            totalNode--;
+        }
+
+        public int getAddNumber(){
+            return totalNode;
+        }
+    }
+ }
diff --git a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c b/jdk/test/java/util/prefs/CheckUserPrefFirst.java
similarity index 65%
copy from jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
copy to jdk/test/java/util/prefs/CheckUserPrefFirst.java
index 089afbd..d0ee277 100644
--- a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
+++ b/jdk/test/java/util/prefs/CheckUserPrefFirst.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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,22 +23,21 @@
  * questions.
  */
 
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
+import java.util.prefs.Preferences;
 
-#include "sun_rmi_server_MarshalInputStream.h"
-
-/*
- * Class:     sun_rmi_server_MarshalInputStream
- * Method:    latestUserDefinedLoader
- * Signature: ()Ljava/lang/ClassLoader;
+/**
  *
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
+ * @author khazra
+ * First class called by CheckUserPrefsStorage.sh to create and
+ * store a user preference
  */
-JNIEXPORT jobject JNICALL
-Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader(JNIEnv *env, jclass cls)
-{
-    return JVM_LatestUserDefinedLoader(env);
+
+public class CheckUserPrefFirst {
+
+    public static void main(String[] args) throws Exception {
+        Preferences prefs = Preferences.userNodeForPackage(CheckUserPrefFirst.class);
+        prefs.put("Check", "Success");
+        prefs.flush();
+    }
 }
+
diff --git a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c b/jdk/test/java/util/prefs/CheckUserPrefLater.java
similarity index 62%
copy from jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
copy to jdk/test/java/util/prefs/CheckUserPrefLater.java
index 089afbd..ba510cb 100644
--- a/jdk/src/share/native/sun/rmi/server/MarshalInputStream.c
+++ b/jdk/test/java/util/prefs/CheckUserPrefLater.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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,22 +23,23 @@
  * questions.
  */
 
-#include "jni.h"
-#include "jvm.h"
-#include "jni_util.h"
+import java.util.prefs.Preferences;
 
-#include "sun_rmi_server_MarshalInputStream.h"
-
-/*
- * Class:     sun_rmi_server_MarshalInputStream
- * Method:    latestUserDefinedLoader
- * Signature: ()Ljava/lang/ClassLoader;
- *
- * Returns the first non-null class loader up the execution stack, or null
- * if only code from the null class loader is on the stack.
+/**
+ * CheckUserPrefsStorage.sh uses this to check that preferences stored
+ * by CheckUserPrefFirst.java can be retrieved
+ * @author khazra
  */
-JNIEXPORT jobject JNICALL
-Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader(JNIEnv *env, jclass cls)
-{
-    return JVM_LatestUserDefinedLoader(env);
+
+public class CheckUserPrefLater {
+
+    public static void main(String[] args) throws Exception {
+        Preferences prefs = Preferences.userNodeForPackage(CheckUserPrefFirst.class);
+        String result = prefs.get("Check", null);
+        if ((result == null) || !(result.equals("Success")))
+            throw new RuntimeException("User pref not stored!");
+        prefs.remove("Check");
+        prefs.flush();
+    }
+
 }
diff --git a/jdk/test/java/util/prefs/CheckUserPrefsStorage.sh b/jdk/test/java/util/prefs/CheckUserPrefsStorage.sh
new file mode 100644
index 0000000..71ded59
--- /dev/null
+++ b/jdk/test/java/util/prefs/CheckUserPrefsStorage.sh
@@ -0,0 +1,68 @@
+#
+# Copyright (c) 2012, 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 7198073
+# @build CheckUserPrefFirst CheckUserPrefLater
+# @run shell CheckUserPrefsStorage.sh
+# @summary Tests that user preferences are stored in the 
+#          permanent storage
+#
+
+OS=`uname -s`
+case "$OS" in
+  SunOS | Linux | Darwin )
+    PS=":"
+    FS="/"
+    ;;
+  CYGWIN* )
+    PS=";"
+    FS="/"
+    ;;
+  Windows* )
+    PS=";"
+    FS="\\"
+    ;;
+  * )
+    echo "Unrecognized system!"
+    exit 1;
+    ;;
+esac
+
+# run CheckUserPrefFirst - creates and stores a user pref
+${TESTJAVA}${FS}bin${FS}java -cp ${TESTCLASSES} CheckUserPrefFirst
+result=$?
+if [ "$result" -ne "0" ]; then
+    exit 1
+fi
+
+# run CheckUserPrefLater - Looks for the stored pref
+${TESTJAVA}${FS}bin${FS}java -cp ${TESTCLASSES} CheckUserPrefLater
+result=$?
+if [ "$result" -ne "0" ]; then
+    exit 1
+fi
+
+# no failures, exit.
+exit 0
+
diff --git a/jdk/test/java/util/zip/TotalInOut.java b/jdk/test/java/util/zip/TotalInOut.java
new file mode 100644
index 0000000..8e6a1e8
--- /dev/null
+++ b/jdk/test/java/util/zip/TotalInOut.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/* @test
+ * @bug 7188852
+ * @summary Test De/Inflater.getBytesRead/Written()
+ */
+
+import java.io.*;
+import java.util.*;
+import java.util.zip.*;
+
+
+public class TotalInOut {
+     static final int BUF_SIZE= 1 * 1024 * 1024;
+
+     static void realMain (String[] args) throws Throwable {
+         long dataSize = 128L * 1024L * 1024L;      // 128MB
+         if (args.length > 0 && "large".equals(args[0]))
+             dataSize = 5L * 1024L * 1024L * 1024L; //  5GB
+
+         Deflater deflater = new Deflater();
+         Inflater inflater = new Inflater();
+
+         byte[] dataIn = new byte[BUF_SIZE];
+         byte[] dataOut = new byte[BUF_SIZE];
+         byte[] tmp = new byte[BUF_SIZE];
+
+         Random r = new Random();
+         r.nextBytes(dataIn);
+         long bytesReadDef    = 0;
+         long bytesWrittenDef = 0;
+         long bytesReadInf    = 0;
+         long bytesWrittenInf = 0;
+
+         deflater.setInput(dataIn, 0, dataIn.length);
+         while (bytesReadDef < dataSize || bytesWrittenInf < dataSize) {
+             int len = r.nextInt(BUF_SIZE/2) + BUF_SIZE / 2;
+             if (deflater.needsInput()) {
+                 bytesReadDef += dataIn.length;
+                 check(bytesReadDef == deflater.getBytesRead());
+                 deflater.setInput(dataIn, 0, dataIn.length);
+             }
+             int n = deflater.deflate(tmp, 0, len);
+             bytesWrittenDef += n;
+             check(bytesWrittenDef == deflater.getBytesWritten());
+
+             inflater.setInput(tmp, 0, n);
+             bytesReadInf += n;
+             while (!inflater.needsInput()) {
+                 bytesWrittenInf += inflater.inflate(dataOut, 0, dataOut.length);
+                 check(bytesWrittenInf == inflater.getBytesWritten());
+             }
+             check(bytesReadInf == inflater.getBytesRead());
+         }
+     }
+
+     //--------------------- Infrastructure ---------------------------
+     static volatile int passed = 0, failed = 0;
+     static void pass() {passed++;}
+     static void pass(String msg) {System.out.println(msg); passed++;}
+     static void fail() {failed++; Thread.dumpStack();}
+     static void fail(String msg) {System.out.println(msg); fail();}
+     static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+     static void unexpected(Throwable t, String msg) {
+         System.out.println(msg); failed++; t.printStackTrace();}
+     static boolean check(boolean cond) {if (cond) pass(); else fail(); return cond;}
+     static void equal(Object x, Object y) {
+          if (x == null ? y == null : x.equals(y)) pass();
+          else fail(x + " not equal to " + y);}
+     public static void main(String[] args) throws Throwable {
+          try {realMain(args);} catch (Throwable t) {unexpected(t);}
+          System.out.println("\nPassed = " + passed + " failed = " + failed);
+          if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/jdk/test/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java b/jdk/test/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java
index 7dc9128..a05ecc6 100644
--- a/jdk/test/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java
+++ b/jdk/test/javax/crypto/EncryptedPrivateKeyInfo/GetKeySpecException.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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,7 +23,8 @@
 
 /**
  * @test
- * @bug 4508341
+ * @bug 4508341 7055362
+ * @library ../../../java/security/testlibrary
  * @summary Test the error conditions of
  * EncryptedPrivateKeyInfo.getKeySpec(...) methods.
  * @author Valerie Peng
@@ -97,7 +98,16 @@
         }
     }
 
-    public static void main(String[] argv) throws Exception {
+    public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         if ((GOOD_PARAMS == null) || (BAD_PARAMS == null)) {
             throw new Exception("Static parameter generation failed");
         }
diff --git a/jdk/test/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java b/jdk/test/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java
index 434b3d3..084b33f 100644
--- a/jdk/test/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java
+++ b/jdk/test/javax/crypto/JceSecurity/SunJCE_BC_LoadOrdering.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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,7 +23,8 @@
 
 /*
  * @test
- * @bug 6377058
+ * @bug 6377058 7055362
+ * @library ../../../java/security/testlibrary
  * @summary SunJCE depends on sun.security.provider.SignatureImpl
  * behaviour, BC can't load into 1st slot.
  * @author Brad R. Wetmore
@@ -35,7 +36,16 @@
 
 public class SunJCE_BC_LoadOrdering {
 
-    public static void main(String args[]) throws Exception {
+    public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         /*
          * Generate a random key, and encrypt the data
          */
diff --git a/jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh b/jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh
index 1eb3d34..18ffc1c 100644
--- a/jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh
+++ b/jdk/test/javax/imageio/stream/StreamCloserLeak/run_test.sh
@@ -1,6 +1,6 @@
 #!/bin/ksh -p
 #
-# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -78,28 +78,44 @@
 case "$OS" in
    SunOS )
       VAR="One value for Sun"
-      DEFAULT_JDK=/usr/local/java/jdk1.2/solaris
+      DEFAULT_JDK=/
       FILESEP="/"
       PATHSEP=":"
       TMP="/tmp"
       ;;
 
-   Linux | Darwin )
+   Linux )
       VAR="A different value for Linux"
-      DEFAULT_JDK=/usr/local/java/jdk1.4/linux-i386
+      DEFAULT_JDK=/
       FILESEP="/"
       PATHSEP=":"
       TMP="/tmp"
       ;;
 
-   Windows_95 | Windows_98 | Windows_NT | Windows_ME | CYGWIN* )
+   Darwin )
+      VAR="A different value for MacOSX"
+      DEFAULT_JDK=/usr
+      FILESEP="/"
+      PATHSEP=":"
+      TMP="/tmp"
+      ;;
+
+   Windows* )
       VAR="A different value for Win32"
-      DEFAULT_JDK=/usr/local/java/jdk1.2/win32
+      DEFAULT_JDK="C:/Program Files/Java/jdk1.8.0"
       FILESEP="\\"
       PATHSEP=";"
       TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
       ;;
 
+    CYGWIN* )
+      VAR="A different value for Cygwin"
+      DEFAULT_JDK="/cygdrive/c/Program\ Files/Java/jdk1.8.0"
+      FILESEP="/"
+      PATHSEP=";"
+      TMP=`cd "${SystemRoot}/Temp"; echo ${PWD}`
+      ;;
+
    # catch all other OSs
    * )
       echo "Unrecognized system!  $OS"
diff --git a/jdk/test/javax/rmi/ssl/SocketFactoryTest.java b/jdk/test/javax/rmi/ssl/SocketFactoryTest.java
index cf88fd7..76bf51a 100644
--- a/jdk/test/javax/rmi/ssl/SocketFactoryTest.java
+++ b/jdk/test/javax/rmi/ssl/SocketFactoryTest.java
@@ -26,8 +26,7 @@
  * @bug 4932837 6582235
  * @summary Test SslRMI[Client|Server]SocketFactory equals() and hashCode().
  * @author Daniel Fuchs
- * @run clean SocketFactoryTest
- * @run build SocketFactoryTest
+ *
  * @run main SocketFactoryTest
  */
 
diff --git a/jdk/test/javax/security/auth/login/LoginContext/ResetConfigModule.java b/jdk/test/javax/security/auth/login/LoginContext/ResetConfigModule.java
index cb1af29..b0f372f 100644
--- a/jdk/test/javax/security/auth/login/LoginContext/ResetConfigModule.java
+++ b/jdk/test/javax/security/auth/login/LoginContext/ResetConfigModule.java
@@ -25,7 +25,6 @@
  * @test
  * @bug 4633622
  * @summary  bug in LoginContext when Configuration is subclassed
- *
  * @build ResetConfigModule ResetModule
  * @run main ResetConfigModule
  */
@@ -40,32 +39,42 @@
 
     public static void main(String[] args) throws Exception {
 
-        Configuration.setConfiguration(new MyConfig());
+        Configuration previousConf = Configuration.getConfiguration();
+        ClassLoader previousCL = Thread.currentThread().getContextClassLoader();
 
-        LoginContext lc = new LoginContext("test");
         try {
-            lc.login();
-            throw new SecurityException("test 1 failed");
-        } catch (LoginException le) {
-            if (le.getCause() != null &&
-                le.getCause() instanceof SecurityException) {
-                System.out.println("good so far");
-            } else {
-                throw le;
-            }
-        }
+            Thread.currentThread().setContextClassLoader(
+                    ResetConfigModule.class.getClassLoader());
+            Configuration.setConfiguration(new MyConfig());
 
-        LoginContext lc2 = new LoginContext("test2");
-        try {
-            lc2.login();
-            throw new SecurityException("test 2 failed");
-        } catch (LoginException le) {
-            if (le.getCause() != null &&
-                le.getCause()  instanceof SecurityException) {
-                System.out.println("test succeeded");
-            } else {
-                throw le;
+            LoginContext lc = new LoginContext("test");
+            try {
+                lc.login();
+                throw new SecurityException("test 1 failed");
+            } catch (LoginException le) {
+                if (le.getCause() != null &&
+                    le.getCause() instanceof SecurityException) {
+                    System.out.println("good so far");
+                } else {
+                    throw le;
+                }
             }
+
+            LoginContext lc2 = new LoginContext("test2");
+            try {
+                lc2.login();
+                throw new SecurityException("test 2 failed");
+            } catch (LoginException le) {
+                if (le.getCause() != null &&
+                    le.getCause()  instanceof SecurityException) {
+                    System.out.println("test succeeded");
+                } else {
+                    throw le;
+                }
+            }
+        } finally {
+            Configuration.setConfiguration(previousConf);
+            Thread.currentThread().setContextClassLoader(previousCL);
         }
     }
 }
diff --git a/jdk/test/javax/swing/AncestorNotifier/7193219/bug7193219.java b/jdk/test/javax/swing/AncestorNotifier/7193219/bug7193219.java
index 0db4839..9fc6a7d 100644
--- a/jdk/test/javax/swing/AncestorNotifier/7193219/bug7193219.java
+++ b/jdk/test/javax/swing/AncestorNotifier/7193219/bug7193219.java
@@ -30,6 +30,7 @@
 import java.io.*;
 
 import javax.swing.*;
+import javax.swing.plaf.metal.*;
 
 public class bug7193219 {
     private static byte[] serializeGUI() {
@@ -73,6 +74,7 @@
     }
 
     public static void main(String[] args) throws Exception {
+        UIManager.setLookAndFeel(new MetalLookAndFeel());
         SwingUtilities.invokeAndWait(new Runnable() {
             @Override
             public void run() {
diff --git a/jdk/test/javax/swing/JColorChooser/Test6827032.java b/jdk/test/javax/swing/JColorChooser/Test6827032.java
new file mode 100644
index 0000000..89c9d82
--- /dev/null
+++ b/jdk/test/javax/swing/JColorChooser/Test6827032.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (c) 2007, 2012, 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 6827032
+ * @summary Color chooser with drag enabled shouldn't throw NPE
+ * @author Peter Zhelezniakov
+ * @library ../regtesthelpers
+ */
+
+import sun.awt.SunToolkit;
+
+import java.awt.*;
+import java.awt.event.*;
+
+import javax.swing.*;
+import javax.swing.plaf.nimbus.NimbusLookAndFeel;
+
+
+public class Test6827032 {
+
+    private static volatile Point point;
+    private static JColorChooser cc;
+
+    public static void main(String[] args) throws Exception {
+        UIManager.setLookAndFeel(new NimbusLookAndFeel());
+
+        Robot robot = new Robot();
+        robot.setAutoDelay(50);
+
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                createAndShowGUI();
+            }
+        });
+
+        toolkit.realSync();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                Component previewPanel = Util.findSubComponent(cc, "javax.swing.colorchooser.DefaultPreviewPanel");
+                point = previewPanel.getLocationOnScreen();
+            }
+        });
+
+        point.translate(5, 5);
+
+        robot.mouseMove(point.x, point.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+    }
+
+
+    private static void createAndShowGUI() {
+        JFrame frame = new JFrame(Test6827032.class.getName());
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        cc = new JColorChooser();
+        cc.setDragEnabled(true);
+        frame.add(cc);
+        frame.pack();
+        frame.setVisible(true);
+    }
+}
diff --git a/jdk/test/javax/swing/JColorChooser/Test7194184.java b/jdk/test/javax/swing/JColorChooser/Test7194184.java
new file mode 100644
index 0000000..97599b1
--- /dev/null
+++ b/jdk/test/javax/swing/JColorChooser/Test7194184.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 7194184
+ * @summary Tests JColorChooser Swatch keyboard accessibility.
+ * @author Sean Chou
+ * @library ../regtesthelpers
+ * @build Util
+ * @run main Test7194184
+ */
+
+import java.awt.Component;
+import java.awt.AWTException;
+import java.awt.Color;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.KeyEvent;
+
+import javax.swing.JColorChooser;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+import java.util.concurrent.Callable;
+import sun.awt.SunToolkit;
+
+public class Test7194184 implements Runnable {
+    private static JFrame frame;
+    private static JColorChooser colorChooser;
+    private static Color selectedColor;
+
+    public static void main(String[] args) throws Exception {
+        testKeyBoardAccess();
+    }
+
+    private static void testKeyBoardAccess() throws Exception {
+        Robot robot = new Robot();
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        SwingUtilities.invokeLater(new Test7194184());
+        toolkit.realSync();
+
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                selectedColor = colorChooser.getColor();
+
+                Component recentSwatchPanel = Util.findSubComponent(colorChooser, "RecentSwatchPanel");
+                if (recentSwatchPanel == null) {
+                    throw new RuntimeException("RecentSwatchPanel not found");
+                }
+                recentSwatchPanel.requestFocusInWindow();
+            }
+        });
+
+        toolkit.realSync();
+
+        // Tab to move the focus to MainSwatch
+        Util.hitKeys(robot, KeyEvent.VK_SHIFT, KeyEvent.VK_TAB);
+
+        // Select the color on right
+        Util.hitKeys(robot, KeyEvent.VK_RIGHT);
+        Util.hitKeys(robot, KeyEvent.VK_RIGHT);
+        Util.hitKeys(robot, KeyEvent.VK_SPACE);
+        toolkit.realSync();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+                if (selectedColor == colorChooser.getColor()) {
+                    throw new RuntimeException("JColorChooser misses keyboard accessibility");
+                }
+            }
+        });
+    }
+
+    public void run() {
+        String title = getClass().getName();
+        frame = new JFrame(title);
+        colorChooser = new JColorChooser();
+
+        frame.add(colorChooser);
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+}
diff --git a/jdk/test/javax/swing/JComponent/7154030/bug7154030.java b/jdk/test/javax/swing/JComponent/7154030/bug7154030.java
new file mode 100644
index 0000000..5000743
--- /dev/null
+++ b/jdk/test/javax/swing/JComponent/7154030/bug7154030.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+import javax.swing.JButton;
+import javax.swing.JDesktopPane;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import sun.awt.SunToolkit;
+
+import java.awt.AWTException;
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.image.BufferedImage;
+
+/* @test 1.1 2012/04/12
+ * @bug 7154030
+ * @summary Swing components fail to hide after calling hide()
+ * @author Jonathan Lu
+ * @library ../../regtesthelpers/
+ * @build Util
+ * @run main bug7154030
+ */
+
+public class bug7154030 {
+
+    private static JButton button = null;
+
+    public static void main(String[] args) throws Exception {
+        BufferedImage imageInit = null;
+
+        BufferedImage imageShow = null;
+
+        BufferedImage imageHide = null;
+
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+        Robot robot = new Robot();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                JDesktopPane desktop = new JDesktopPane();
+                button = new JButton("button");
+                JFrame frame = new JFrame();
+
+                button.setSize(200, 200);
+                button.setLocation(100, 100);
+                button.setForeground(Color.RED);
+                button.setBackground(Color.RED);
+                button.setOpaque(true);
+                button.setVisible(false);
+                desktop.add(button);
+
+                frame.setContentPane(desktop);
+                frame.setSize(300, 300);
+                frame.setLocation(0, 0);
+                frame.setVisible(true);
+                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+            }
+        });
+
+        toolkit.realSync();
+        imageInit = robot.createScreenCapture(new Rectangle(0, 0, 300, 300));
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                button.show();
+            }
+        });
+
+        toolkit.realSync();
+        imageShow = robot.createScreenCapture(new Rectangle(0, 0, 300, 300));
+        if (Util.compareBufferedImages(imageInit, imageShow)) {
+            throw new Exception("Failed to show opaque button");
+        }
+
+        toolkit.realSync();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                button.hide();
+            }
+        });
+
+        toolkit.realSync();
+        imageHide = robot.createScreenCapture(new Rectangle(0, 0, 300, 300));
+
+        if (!Util.compareBufferedImages(imageInit, imageHide)) {
+            throw new Exception("Failed to hide opaque button");
+        }
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                button.setOpaque(false);
+                button.setBackground(new Color(128, 128, 0));
+                button.setVisible(false);
+            }
+        });
+
+        toolkit.realSync();
+        imageInit = robot.createScreenCapture(new Rectangle(0, 0, 300, 300));
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                button.show();
+            }
+        });
+
+        toolkit.realSync();
+        imageShow = robot.createScreenCapture(new Rectangle(0, 0, 300, 300));
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                button.hide();
+            }
+        });
+
+        if (Util.compareBufferedImages(imageInit, imageShow)) {
+            throw new Exception("Failed to show non-opaque button");
+        }
+
+        toolkit.realSync();
+        imageHide = robot.createScreenCapture(new Rectangle(0, 0, 300, 300));
+
+        if (!Util.compareBufferedImages(imageInit, imageHide)) {
+            throw new Exception("Failed to hide non-opaque button");
+        }
+    }
+}
diff --git a/jdk/test/javax/swing/JTabbedPane/4310381/bug4310381.html b/jdk/test/javax/swing/JTabbedPane/4310381/bug4310381.html
new file mode 100644
index 0000000..d60643e
--- /dev/null
+++ b/jdk/test/javax/swing/JTabbedPane/4310381/bug4310381.html
@@ -0,0 +1,6 @@
+<html>

+<body>

+<applet  code="bug4310381.class" width=150 height=150></applet>

+Observe that long Tab titles are clipped with dots at the end

+</body>

+</html> 

diff --git a/jdk/test/javax/swing/JTabbedPane/4310381/bug4310381.java b/jdk/test/javax/swing/JTabbedPane/4310381/bug4310381.java
new file mode 100644
index 0000000..aa57020
--- /dev/null
+++ b/jdk/test/javax/swing/JTabbedPane/4310381/bug4310381.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 4310381
+ * @summary Text in multi-row/col JTabbedPane tabs can be truncated/clipped
+ * @author Charles Lee
+   @run applet/manual=yesno bug4310381.html
+ */
+
+
+import javax.swing.*;
+import java.awt.*;
+import java.lang.reflect.InvocationTargetException;
+
+public class bug4310381 extends JApplet {
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                JFrame frame = new JFrame();
+
+                frame.setContentPane(createContentPane());
+                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
+                frame.setSize(150, 200);
+                frame.setLocationRelativeTo(null);
+
+                frame.setVisible(true);
+
+            }
+        });
+    }
+
+    @Override
+    public void init() {
+        try {
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    setContentPane(createContentPane());
+                }
+            });
+        } catch (InterruptedException | InvocationTargetException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private static Container createContentPane() {
+        JTabbedPane tab = new JTabbedPane();
+        String a2z = "abcdefghijklmnopqrstuvwxyz";
+
+        tab.addTab("0" + a2z + a2z, new JLabel("0"));
+        tab.addTab("1" + a2z, new JLabel("1" + a2z));
+        tab.addTab("2" + a2z, new JLabel("2" + a2z));
+        tab.addTab("3", new JLabel("3" + a2z)); // The last tab in Metal isn't truncated, that's ok
+
+        return tab;
+    }
+}
diff --git a/jdk/test/javax/swing/JTable/7055065/bug7055065.java b/jdk/test/javax/swing/JTable/7055065/bug7055065.java
new file mode 100644
index 0000000..119d9a5
--- /dev/null
+++ b/jdk/test/javax/swing/JTable/7055065/bug7055065.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test 1.1 2012/04/19
+ * @bug 7055065
+ * @summary NullPointerException when sorting JTable with empty cell
+ * @author Jonathan Lu
+ * @library ../../regtesthelpers/
+ * @build Util
+ * @run main bug7055065
+ */
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Robot;
+import java.awt.Toolkit;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableModel;
+import javax.swing.table.TableRowSorter;
+import sun.awt.SunToolkit;
+import java.util.concurrent.Callable;
+
+public class bug7055065 {
+
+    private static JTable table;
+
+    public static void main(String[] args) throws Exception {
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        Robot robot = new Robot();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            public void run() {
+                createAndShowUI();
+            }
+        });
+
+        toolkit.realSync();
+        clickCell(robot, 1, 1);
+        Util.hitKeys(robot, KeyEvent.VK_BACK_SPACE, KeyEvent.VK_BACK_SPACE,
+                KeyEvent.VK_BACK_SPACE);
+
+        toolkit.realSync();
+        clickColumnHeader(robot, 1);
+
+        toolkit.realSync();
+        clickColumnHeader(robot, 1);
+    }
+
+    private static void clickCell(Robot robot, final int row, final int column)
+        throws Exception {
+        Point point = Util.invokeOnEDT(new Callable<Point>() {
+            @Override
+            public Point call() throws Exception {
+                Rectangle rect = table.getCellRect(row, column, false);
+                Point point = new Point(rect.x + rect.width / 2, rect.y
+                    + rect.height / 2);
+                SwingUtilities.convertPointToScreen(point, table);
+                return point;
+            }
+        });
+
+        robot.mouseMove(point.x, point.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+    }
+
+    private static void clickColumnHeader(Robot robot, final int column)
+        throws Exception {
+        Point point = Util.invokeOnEDT(new Callable<Point>() {
+            @Override
+            public Point call() throws Exception {
+                Rectangle rect = table.getCellRect(0, column, false);
+                int headerHeight = table.getTableHeader().getHeight();
+                Point point = new Point(rect.x + rect.width / 2, rect.y
+                    - headerHeight / 2);
+                SwingUtilities.convertPointToScreen(point, table);
+                return point;
+            }
+        });
+
+        robot.mouseMove(point.x, point.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+    }
+
+    private static void createAndShowUI() {
+        JFrame frame = new JFrame("SimpleTableDemo");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+        JPanel newContentPane = new JPanel();
+        newContentPane.setOpaque(true);
+        frame.setContentPane(newContentPane);
+
+        final String[] columnNames = { "String", "Number" };
+        final Object[][] data = { { "aaaa", new Integer(1) },
+            { "bbbb", new Integer(3) }, { "cccc", new Integer(2) },
+            { "dddd", new Integer(4) }, { "eeee", new Integer(5) } };
+        table = new JTable(data, columnNames);
+
+        table.setPreferredScrollableViewportSize(new Dimension(500, 400));
+        table.setFillsViewportHeight(true);
+
+        TableModel dataModel = new AbstractTableModel() {
+
+            public int getColumnCount() {
+                return columnNames.length;
+            }
+
+            public int getRowCount() {
+                return data.length;
+            }
+
+            public Object getValueAt(int row, int col) {
+                return data[row][col];
+            }
+
+            public String getColumnName(int column) {
+                return columnNames[column];
+            }
+
+            public Class<?> getColumnClass(int c) {
+                return getValueAt(0, c).getClass();
+            }
+
+            public boolean isCellEditable(int row, int col) {
+                return col != 5;
+            }
+
+            public void setValueAt(Object aValue, int row, int column) {
+                data[row][column] = aValue;
+            }
+        };
+        table.setModel(dataModel);
+        TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(
+                dataModel);
+        table.setRowSorter(sorter);
+
+        JScrollPane scrollPane = new JScrollPane(table);
+        newContentPane.add(scrollPane);
+
+        frame.pack();
+        frame.setLocation(0, 0);
+        frame.setVisible(true);
+    }
+}
diff --git a/jdk/test/javax/swing/JTable/7188612/JTableAccessibleGetLocationOnScreen.java b/jdk/test/javax/swing/JTable/7188612/JTableAccessibleGetLocationOnScreen.java
new file mode 100644
index 0000000..51ea977
--- /dev/null
+++ b/jdk/test/javax/swing/JTable/7188612/JTableAccessibleGetLocationOnScreen.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test
+ * @bug 7188612
+ * @summary AccessibleTableHeader and AccessibleJTableCell should stick to
+ *    AccessibleComponent.getLocationOnScreen api.
+ * @author Frank Ding
+ */
+
+import javax.accessibility.AccessibleComponent;
+import javax.accessibility.AccessibleTable;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+
+public class JTableAccessibleGetLocationOnScreen {
+    private static JFrame frame;
+    private static JTable table;
+
+    public static void main(String[] args) throws Exception {
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+
+            @Override
+            public void run() {
+                constructInEDT();
+                try {
+                    assertGetLocation();
+                } finally {
+                    frame.dispose();
+                }
+            }
+        });
+
+    }
+
+    private static void constructInEDT() {
+        String[] columnNames = { "col1", "col2", };
+        Object[][] data = { { "row1, col1", "row1, col2" },
+                { "row2, col1", "row2, col2" }, };
+
+        frame = new JFrame(
+                "JTable AccessibleTableHeader and AccessibleJTableCell test");
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        table = new JTable(data, columnNames);
+        frame.add(table);
+        frame.pack();
+    }
+
+    private static void assertGetLocation() {
+        // the frame is now invisible
+        // test getLocationOnScreen() of
+        // JTable$AccessibleJTable$AccessibleJTableHeaderCell
+        // and JTable$AccessibleJTable$AccessibleJTableCell
+        AccessibleTable accessibleTable = (AccessibleTable) table
+                .getAccessibleContext();
+        AccessibleTable header = accessibleTable.getAccessibleColumnHeader();
+        AccessibleComponent accessibleComp1 = (AccessibleComponent) header
+                .getAccessibleAt(0, 0);
+        // getLocation() must be null according to its javadoc and no exception
+        // is thrown
+        if (null != accessibleComp1.getLocationOnScreen()) {
+            throw new RuntimeException(
+                    "JTable$AccessibleJTable$AccessibleJTableHeaderCell."
+                            + "getLocation() must be null");
+        }
+
+        JComponent.AccessibleJComponent accessibleJComponent =
+                (JComponent.AccessibleJComponent) table.getAccessibleContext();
+        AccessibleComponent accessibleComp2 = (AccessibleComponent)
+                accessibleJComponent.getAccessibleChild(3);
+        // getLocation() must be null according to its javadoc and no exception
+        // is thrown
+        if (null != accessibleComp2.getLocationOnScreen()) {
+            throw new RuntimeException("JTable$AccessibleJTable$"
+                    + "AccessibleJTableCell.getLocation() must be null");
+        }
+
+    }
+}
diff --git a/jdk/test/javax/swing/JTextArea/7049024/bug7049024.java b/jdk/test/javax/swing/JTextArea/7049024/bug7049024.java
new file mode 100644
index 0000000..e6398b2
--- /dev/null
+++ b/jdk/test/javax/swing/JTextArea/7049024/bug7049024.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+/*
+ * Portions Copyright (c) 2011 IBM Corporation
+ */
+
+/* @test
+ * @bug 7049024
+ * @summary DnD fails with JTextArea and JTextField
+ * @author Sean Chou
+ */
+
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import javax.swing.text.DefaultCaret;
+import java.awt.*;
+import java.awt.datatransfer.Clipboard;
+import java.awt.datatransfer.DataFlavor;
+
+public class bug7049024 {
+    public static Clipboard clipboard = null;
+
+    public static JTextField textField = null;
+
+    // This button is used to move focus away from textField.
+    public static JButton button = null;
+
+    public static JFrame frame = null;
+
+    public static DefaultCaret caret = null;
+
+    public static void main(String[] args) throws Exception {
+
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new JFrame("Test");
+                textField = new JTextField("test selection for textfield");
+                button = new JButton("To compete the focus");
+
+                frame.setLayout(new FlowLayout());
+                frame.getContentPane().add(textField);
+                frame.getContentPane().add(button);
+
+                frame.pack();
+                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+                frame.setVisible(true);
+            }
+        });
+        toolkit.realSync();
+
+        clipboard = textField.getToolkit().getSystemSelection();
+        if (null == clipboard) {
+            return;
+        }
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                textField.requestFocusInWindow();
+            }
+        });
+        toolkit.realSync();
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                caret = (DefaultCaret) textField.getCaret();
+                caret.setDot(2);
+                caret.moveDot(4);
+            }
+        });
+        toolkit.realSync();
+
+        String oldSelection = (String) clipboard.getData(DataFlavor.stringFlavor);
+        System.out.println("oldSelection is " + oldSelection);
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                button.requestFocusInWindow();
+            }
+        });
+        toolkit.realSync(); // So JTextField loses the focus.
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                caret.setDot(4);
+                caret.moveDot(6);
+            }
+        });
+        toolkit.realSync();
+
+        String newSelection = (String) clipboard.getData(DataFlavor.stringFlavor);
+        System.out.println("newSelection is " + newSelection);
+
+        boolean passed = newSelection.equals(oldSelection);
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame.dispose();
+            }
+        });
+
+        if (!passed) {
+            throw new RuntimeException("The test for bug 7049024 failed");
+        }
+    }
+}
diff --git a/jdk/test/javax/swing/JTree/8003830/bug8003830.java b/jdk/test/javax/swing/JTree/8003830/bug8003830.java
new file mode 100644
index 0000000..7851546
--- /dev/null
+++ b/jdk/test/javax/swing/JTree/8003830/bug8003830.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.EventQueue;
+import java.awt.Rectangle;
+import java.awt.event.ActionEvent;
+import javax.swing.JTree;
+import javax.swing.plaf.basic.BasicTreeUI;
+import javax.swing.tree.TreePath;
+
+
+/* Originally reported as NetBeans bug 222081.
+ *
+ * @test
+ * @bug 8003830
+ * @summary NullPointerException in BasicTreeUI.Actions when getPathBounds returns null
+ * @author Jaroslav Tulach
+ * @run main bug8003830
+ */
+
+public class bug8003830 implements Runnable {
+    public static void main(String[] args) throws Exception {
+        EventQueue.invokeAndWait(new bug8003830());
+    }
+    @Override
+    public void run() {
+        testNPEAtActionsPage();
+    }
+
+    public void testNPEAtActionsPage() {
+        JTree tree = new JTree();
+        BasicTreeUI ui = new NullReturningTreeUI();
+        tree.setUI(ui);
+        BasicTreeUI.TreePageAction tpa = ui.new TreePageAction(0, "down");
+        tpa.actionPerformed(new ActionEvent(tree, 0, ""));
+    }
+
+    private static final class NullReturningTreeUI extends BasicTreeUI {
+        @Override
+        public Rectangle getPathBounds(JTree tree, TreePath path) {
+            // the method can return null and callers have to be ready for
+            // that. Simulate the case by returning null for unknown reason.
+            return null;
+        }
+    }
+}
diff --git a/jdk/test/javax/swing/ToolTipManager/7123767/bug7123767.java b/jdk/test/javax/swing/ToolTipManager/7123767/bug7123767.java
new file mode 100644
index 0000000..4c7402d
--- /dev/null
+++ b/jdk/test/javax/swing/ToolTipManager/7123767/bug7123767.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (c) 2012, 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 7123767
+   @summary Wrong tooltip location in Multi-Monitor configurations
+   @author Vladislav Karnaukhov
+   @run main bug7123767
+*/
+
+import sun.awt.SunToolkit;
+
+import javax.swing.*;
+import javax.swing.plaf.metal.MetalLookAndFeel;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.lang.reflect.InvocationTargetException;
+
+public class bug7123767 extends JFrame {
+
+    private static class TestFactory extends PopupFactory {
+
+        private static TestFactory newFactory = new TestFactory();
+        private static PopupFactory oldFactory;
+
+        private TestFactory() {
+            super();
+        }
+
+        public static void install() {
+            if (oldFactory == null) {
+                oldFactory = getSharedInstance();
+                setSharedInstance(newFactory);
+            }
+        }
+
+        public static void uninstall() {
+            if (oldFactory != null) {
+                setSharedInstance(oldFactory);
+            }
+        }
+
+        // Actual test happens here
+        public Popup getPopup(Component owner, Component contents, int x, int y) {
+            GraphicsConfiguration mouseGC = testGC(MouseInfo.getPointerInfo().getLocation());
+            if (mouseGC == null) {
+                throw new RuntimeException("Can't find GraphicsConfiguration that mouse pointer belongs to");
+            }
+
+            GraphicsConfiguration tipGC = testGC(new Point(x, y));
+            if (tipGC == null) {
+                throw new RuntimeException("Can't find GraphicsConfiguration that tip belongs to");
+            }
+
+            if (!mouseGC.equals(tipGC)) {
+                throw new RuntimeException("Mouse and tip GCs are not equal");
+            }
+
+            return super.getPopup(owner, contents, x, y);
+        }
+
+        private static GraphicsConfiguration testGC(Point pt) {
+            GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
+            GraphicsDevice[] devices = environment.getScreenDevices();
+            for (GraphicsDevice device : devices) {
+                GraphicsConfiguration[] configs = device.getConfigurations();
+                for (GraphicsConfiguration config : configs) {
+                    Rectangle rect = config.getBounds();
+                    Insets insets = Toolkit.getDefaultToolkit().getScreenInsets(config);
+                    adjustInsets(rect, insets);
+                    if (rect.contains(pt))
+                        return config;
+                }
+            }
+
+            return null;
+        }
+    }
+
+    private static final int MARGIN = 10;
+    private static bug7123767 frame;
+    private static Robot robot;
+
+    public static void main(String[] args) throws Exception {
+        UIManager.setLookAndFeel(new MetalLookAndFeel());
+        setUp();
+        testToolTip();
+        TestFactory.uninstall();
+    }
+
+    // Creates a window that is stretched across all available monitors
+    // and adds itself as ContainerListener to track tooltips drawing
+    private bug7123767() {
+        super();
+
+        ToolTipManager.sharedInstance().setInitialDelay(0);
+        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+        TestFactory.install();
+
+        JLabel label1 = new JLabel("no preferred location");
+        label1.setToolTipText("tip");
+        add(label1, BorderLayout.WEST);
+
+        JLabel label2 = new JLabel("preferred location (20000, 20000)") {
+            public Point getToolTipLocation(MouseEvent event) {
+                return new Point(20000, 20000);
+            }
+        };
+
+        label2.setToolTipText("tip");
+        add(label2, BorderLayout.EAST);
+
+        setUndecorated(true);
+        pack();
+
+        Rectangle rect = new Rectangle();
+        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        GraphicsDevice[] devices = environment.getScreenDevices();
+        for (GraphicsDevice device : devices) {
+            GraphicsConfiguration[] configs = device.getConfigurations();
+            for (GraphicsConfiguration config : configs) {
+                Insets localInsets = Toolkit.getDefaultToolkit().getScreenInsets(config);
+                Rectangle localRect = config.getBounds();
+                adjustInsets(localRect, localInsets);
+                rect.add(localRect);
+            }
+        }
+        setBounds(rect);
+    }
+
+    private static void setUp() throws InterruptedException, InvocationTargetException {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                frame = new bug7123767();
+                frame.setVisible(true);
+            }
+        });
+    }
+
+    // Moves mouse pointer to the corners of every GraphicsConfiguration
+    private static void testToolTip() throws AWTException {
+        SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+        toolkit.realSync();
+
+        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        GraphicsDevice[] devices = environment.getScreenDevices();
+        for (GraphicsDevice device : devices) {
+            GraphicsConfiguration[] configs = device.getConfigurations();
+            for (GraphicsConfiguration config : configs) {
+                Rectangle rect = config.getBounds();
+                Insets insets = toolkit.getScreenInsets(config);
+                adjustInsets(rect, insets);
+
+                // Upper left
+                glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
+                        rect.x + MARGIN, rect.y + MARGIN);
+                toolkit.realSync();
+
+                // Lower left
+                glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
+                        rect.x + MARGIN, rect.y + rect.height - MARGIN);
+                toolkit.realSync();
+
+                // Upper right
+                glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
+                        rect.x + rect.width - MARGIN, rect.y + MARGIN);
+                toolkit.realSync();
+
+                // Lower right
+                glide(rect.x + rect.width / 2, rect.y + rect.height / 2,
+                        rect.x + rect.width - MARGIN, rect.y + rect.height - MARGIN);
+                toolkit.realSync();
+            }
+        }
+    }
+
+    private static void glide(int x0, int y0, int x1, int y1) throws AWTException {
+        if (robot == null) {
+            robot = new Robot();
+            robot.setAutoDelay(20);
+        }
+
+        float dmax = (float) Math.max(Math.abs(x1 - x0), Math.abs(y1 - y0));
+        float dx = (x1 - x0) / dmax;
+        float dy = (y1 - y0) / dmax;
+
+        robot.mouseMove(x0, y0);
+        for (int i = 1; i <= dmax; i += 10) {
+            robot.mouseMove((int) (x0 + dx * i), (int) (y0 + dy * i));
+        }
+    }
+
+    private static void adjustInsets(Rectangle rect, final Insets insets) {
+        rect.x += insets.left;
+        rect.y += insets.top;
+        rect.width -= (insets.left + insets.right);
+        rect.height -= (insets.top + insets.bottom);
+    }
+}
diff --git a/jdk/test/javax/swing/text/CSSBorder/6796710/bug6796710.java b/jdk/test/javax/swing/text/CSSBorder/6796710/bug6796710.java
index b59ba9f..dd8508b 100644
--- a/jdk/test/javax/swing/text/CSSBorder/6796710/bug6796710.java
+++ b/jdk/test/javax/swing/text/CSSBorder/6796710/bug6796710.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2012, 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,7 +23,7 @@
 
 /*
  * @test
- * @bug 6796710
+ * @bug 6796710 7124242
  * @summary Html content in JEditorPane is overlapping on swing components while resizing the application.
  * @library ../../../regtesthelpers
  * @build Util
@@ -31,11 +31,10 @@
    @run main bug6796710
  */
 
-import sun.awt.SunToolkit;
-
-import javax.swing.*;
 import java.awt.*;
 import java.awt.image.BufferedImage;
+import javax.swing.*;
+import sun.awt.SunToolkit;
 
 public class bug6796710 {
     // The page is inlined because we want to be sure that the JEditorPane filled synchronously
@@ -68,9 +67,12 @@
         robot = new Robot();
 
         SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
             public void run() {
                 frame = new JFrame();
 
+                frame.setUndecorated(true);
+
                 pnBottom = new JPanel();
                 pnBottom.add(new JLabel("Some label"));
                 pnBottom.add(new JButton("A button"));
@@ -95,9 +97,13 @@
 
         ((SunToolkit) SunToolkit.getDefaultToolkit()).realSync();
 
+        // This delay should be added for MacOSX, realSync is not enough
+        Thread.sleep(1000);
+
         BufferedImage bufferedImage = getPnBottomImage();
 
         SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
             public void run() {
                 frame.setSize(400, 150);
             }
diff --git a/jdk/test/javax/swing/text/DefaultCaret/6938583/bug6938583.java b/jdk/test/javax/swing/text/DefaultCaret/6938583/bug6938583.java
new file mode 100644
index 0000000..c5c4871
--- /dev/null
+++ b/jdk/test/javax/swing/text/DefaultCaret/6938583/bug6938583.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 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
+ * 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.
+ */
+
+/*
+ * Portions Copyright (c) 2011 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 6938583
+ * @summary Unexpected NullPointerException when use CodeIM demo on windows
+ * @author LittleE
+ */
+
+import javax.swing.*;
+import javax.swing.text.DefaultCaret;
+import java.awt.event.MouseEvent;
+
+public class bug6938583 {
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            public void run() {
+                JTextArea jta = new JTextArea();
+                DefaultCaret dc = new DefaultCaret();
+                jta.setCaret(dc);
+                dc.deinstall(jta);
+                dc.mouseClicked(new MouseEvent(jta, MouseEvent.MOUSE_CLICKED, 0, 0, 0, 0, 0, false));
+            }
+        });
+    }
+}
diff --git a/jdk/test/javax/swing/text/StyledEditorKit/4506788/bug4506788.html b/jdk/test/javax/swing/text/StyledEditorKit/4506788/bug4506788.html
new file mode 100644
index 0000000..690beee
--- /dev/null
+++ b/jdk/test/javax/swing/text/StyledEditorKit/4506788/bug4506788.html
@@ -0,0 +1,28 @@
+<!--
+ Copyright (c) 2012, 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.
+-->
+
+<Html>
+<Body>
+<APPLET  code="bug4506788.class" WIDTH = 600 HEIGHT = 400></APPLET>
+</Body>
+</Html>
diff --git a/jdk/test/javax/swing/text/StyledEditorKit/4506788/bug4506788.java b/jdk/test/javax/swing/text/StyledEditorKit/4506788/bug4506788.java
new file mode 100644
index 0000000..b5e0f9e
--- /dev/null
+++ b/jdk/test/javax/swing/text/StyledEditorKit/4506788/bug4506788.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright (c) 2012, 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 4506788 7147408
+ @summary  Tests if cursor gets stuck after insertion a character
+ @author Denis Sharypov
+ @run applet bug4506788.html
+ */
+import java.awt.*;
+import java.awt.event.*;
+import java.lang.reflect.InvocationTargetException;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import sun.awt.SunToolkit;
+
+public class bug4506788 extends JApplet {
+
+    private volatile boolean passed = false;
+    private JEditorPane jep;
+    private SunToolkit toolkit = (SunToolkit) Toolkit.getDefaultToolkit();
+
+    @Override
+    public void init() {
+        try {
+            SwingUtilities.invokeAndWait(new Runnable() {
+                @Override
+                public void run() {
+                    createAndShowGUI();
+                }
+            });
+        } catch (InterruptedException | InvocationTargetException ex) {
+            ex.printStackTrace();
+            throw new RuntimeException("FAILED: SwingUtilities.invokeAndWait method failed then creating and showing GUI");
+        }
+    }
+
+    @Override
+    public void start() {
+        Robot robot;
+        try {
+            robot = new Robot();
+        } catch (AWTException e) {
+            throw new RuntimeException("Robot could not be created");
+        }
+
+        toolkit.realSync();
+
+        Point p;
+        try {
+            p = getJEPLocOnScreen();
+        } catch (Exception e) {
+            throw new RuntimeException("Could not get JEditorPane location on screen");
+        }
+
+        robot.setAutoDelay(50);
+        robot.mouseMove(p.x, p.y);
+        robot.mousePress(InputEvent.BUTTON1_MASK);
+        robot.mouseRelease(InputEvent.BUTTON1_MASK);
+        robot.keyPress(KeyEvent.VK_RIGHT);
+        robot.keyRelease(KeyEvent.VK_RIGHT);
+        robot.keyPress(KeyEvent.VK_X);
+        robot.keyRelease(KeyEvent.VK_X);
+        robot.keyPress(KeyEvent.VK_RIGHT);
+        robot.keyRelease(KeyEvent.VK_RIGHT);
+
+        toolkit.realSync();
+
+        if (!passed) {
+            throw new RuntimeException("Test failed.");
+        }
+    }
+
+    private Point getJEPLocOnScreen() throws Exception {
+
+        final Point[] result = new Point[1];
+
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                result[0] = jep.getLocationOnScreen();
+            }
+        });
+
+        return result[0];
+    }
+
+    private void createAndShowGUI() {
+        jep = new JEditorPane();
+        String text = "abc";
+        JFrame f = new JFrame();
+        jep.setEditorKit(new StyledEditorKit());
+        jep.setText(text);
+        jep.addCaretListener(new CaretListener() {
+            @Override
+            public void caretUpdate(CaretEvent e) {
+                passed = (e.getDot() == 3);
+            }
+        });
+
+        DefaultStyledDocument doc = (DefaultStyledDocument) jep.getDocument();
+        MutableAttributeSet atr = new SimpleAttributeSet();
+        StyleConstants.setBold(atr, true);
+        doc.setCharacterAttributes(1, 1, atr, false);
+
+        f.getContentPane().add(jep);
+        f.setSize(100, 100);
+        f.setVisible(true);
+    }
+}
diff --git a/jdk/test/javax/swing/text/html/parser/Parser/6836089/bug6836089.java b/jdk/test/javax/swing/text/html/parser/Parser/6836089/bug6836089.java
new file mode 100644
index 0000000..cf41b8c
--- /dev/null
+++ b/jdk/test/javax/swing/text/html/parser/Parser/6836089/bug6836089.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2010, 2012, 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 6836089
+ * @summary Tests correct parsing of characters outside Base Multilingual Plane
+ * @author Vladislav Karnaukhov
+ */
+
+import javax.swing.*;
+import javax.swing.text.html.*;
+
+public class bug6836089 {
+
+    public static void main(String[] args) throws Exception {
+        SwingUtilities.invokeAndWait(new Runnable() {
+            @Override
+            public void run() {
+                JTextPane htmlPane = new JTextPane();
+                htmlPane.setEditorKit(new HTMLEditorKit());
+
+                htmlPane.setText("<html><head></head><body>&#131072;</body></html>");
+                String str = htmlPane.getText();
+                if (str.contains("&#0;")) {
+                    throw new RuntimeException("Test failed");
+                }
+            }
+        });
+    }
+}
diff --git a/jdk/test/sun/invoke/util/ValueConversionsTest.java b/jdk/test/sun/invoke/util/ValueConversionsTest.java
index 6b1253e..5b6d1bd 100644
--- a/jdk/test/sun/invoke/util/ValueConversionsTest.java
+++ b/jdk/test/sun/invoke/util/ValueConversionsTest.java
@@ -27,11 +27,9 @@
 import sun.invoke.util.Wrapper;
 import java.lang.invoke.MethodType;
 import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodHandles;
 import java.io.Serializable;
 import java.util.Arrays;
 import java.util.Collections;
-import org.junit.Ignore;
 import org.junit.Test;
 import static org.junit.Assert.*;
 
@@ -52,7 +50,7 @@
  * @author jrose
  */
 public class ValueConversionsTest {
-    private static final Class CLASS = ValueConversionsTest.class;
+    private static final Class<?> CLASS = ValueConversionsTest.class;
     private static final int MAX_ARITY = Integer.getInteger(CLASS.getSimpleName()+".MAX_ARITY", 40);
     private static final int START_ARITY = Integer.getInteger(CLASS.getSimpleName()+".START_ARITY", 0);
     private static final boolean EXHAUSTIVE = Boolean.getBoolean(CLASS.getSimpleName()+".EXHAUSTIVE");
@@ -124,36 +122,6 @@
     }
 
     @Test
-    public void testUnboxRaw() throws Throwable {
-        //System.out.println("unboxRaw");
-        for (Wrapper w : Wrapper.values()) {
-            if (w == Wrapper.OBJECT)  continue;  // skip this; no raw form
-            //System.out.println(w);
-            for (int n = -5; n < 10; n++) {
-                Object box = w.wrap(n);
-                long expResult = w.unwrapRaw(box);
-                Object box2 = w.wrapRaw(expResult);
-                assertEquals(box, box2);
-                MethodHandle unboxer = ValueConversions.unboxRaw(w.primitiveType());
-                long result = -1;
-                switch (w) {
-                    case INT:     result = (int)  unboxer.invokeExact(box); break;
-                    case LONG:    result = (long) unboxer.invokeExact(box); break;
-                    case FLOAT:   result = (int)  unboxer.invokeExact(box); break;
-                    case DOUBLE:  result = (long) unboxer.invokeExact(box); break;
-                    case CHAR:    result = (int)  unboxer.invokeExact(box); break;
-                    case BYTE:    result = (int)  unboxer.invokeExact(box); break;
-                    case SHORT:   result = (int)  unboxer.invokeExact(box); break;
-                    case BOOLEAN: result = (int)  unboxer.invokeExact(box); break;
-                    case VOID:    result = (int)  unboxer.invokeExact(box); break;
-                }
-                assertEquals("(w,n,box)="+Arrays.asList(w,n,box),
-                             expResult, result);
-            }
-        }
-    }
-
-    @Test
     public void testBox() throws Throwable {
         //System.out.println("box");
         for (Wrapper w : Wrapper.values()) {
@@ -165,7 +133,7 @@
                 Object expResult = box;
                 Object result = null;
                 switch (w) {
-                    case INT:     result = boxer.invokeExact((int)n); break;
+                    case INT:     result = boxer.invokeExact(/*int*/n); break;
                     case LONG:    result = boxer.invokeExact((long)n); break;
                     case FLOAT:   result = boxer.invokeExact((float)n); break;
                     case DOUBLE:  result = boxer.invokeExact((double)n); break;
@@ -182,65 +150,6 @@
     }
 
     @Test
-    public void testBoxRaw() throws Throwable {
-        //System.out.println("boxRaw");
-        for (Wrapper w : Wrapper.values()) {
-            if (w == Wrapper.VOID)  continue;  // skip this; no unboxed form
-            if (w == Wrapper.OBJECT)  continue;  // skip this; no raw form
-            //System.out.println(w);
-            for (int n = -5; n < 10; n++) {
-                Object box = w.wrap(n);
-                long   raw = w.unwrapRaw(box);
-                Object expResult = box;
-                MethodHandle boxer = ValueConversions.boxRaw(w.primitiveType());
-                Object result = null;
-                switch (w) {
-                case INT:     result = boxer.invokeExact((int)raw); break;
-                case LONG:    result = boxer.invokeExact(raw); break;
-                case FLOAT:   result = boxer.invokeExact((int)raw); break;
-                case DOUBLE:  result = boxer.invokeExact(raw); break;
-                case CHAR:    result = boxer.invokeExact((int)raw); break;
-                case BYTE:    result = boxer.invokeExact((int)raw); break;
-                case SHORT:   result = boxer.invokeExact((int)raw); break;
-                case BOOLEAN: result = boxer.invokeExact((int)raw); break;
-                }
-                assertEquals("(dst,src,n,box)="+Arrays.asList(w,w,n,box),
-                             expResult, result);
-            }
-        }
-    }
-
-    @Test
-    public void testReboxRaw() throws Throwable {
-        //System.out.println("reboxRaw");
-        for (Wrapper w : Wrapper.values()) {
-            Wrapper pw = Wrapper.forPrimitiveType(w.rawPrimitiveType());
-            if (w == Wrapper.VOID)  continue;  // skip this; no unboxed form
-            if (w == Wrapper.OBJECT)  continue;  // skip this; no raw form
-            //System.out.println(w);
-            for (int n = -5; n < 10; n++) {
-                Object box = w.wrap(n);
-                Object raw = pw.wrap(w.unwrapRaw(box));
-                Object expResult = box;
-                MethodHandle boxer = ValueConversions.rebox(w.primitiveType());
-                Object result = null;
-                switch (w) {
-                case INT:     result = boxer.invokeExact(raw); break;
-                case LONG:    result = boxer.invokeExact(raw); break;
-                case FLOAT:   result = boxer.invokeExact(raw); break;
-                case DOUBLE:  result = boxer.invokeExact(raw); break;
-                case CHAR:    result = boxer.invokeExact(raw); break;
-                case BYTE:    result = boxer.invokeExact(raw); break;
-                case SHORT:   result = boxer.invokeExact(raw); break;
-                case BOOLEAN: result = boxer.invokeExact(raw); break;
-                }
-                assertEquals("(dst,src,n,box)="+Arrays.asList(w,w,n,box),
-                             expResult, result);
-            }
-        }
-    }
-
-    @Test
     public void testCast() throws Throwable {
         //System.out.println("cast");
         Class<?>[] types = { Object.class, Serializable.class, String.class, Number.class, Integer.class };
@@ -250,14 +159,8 @@
             assertEquals(caster.type(), ValueConversions.identity().type());
             for (Object obj : objects) {
                 Class<?> src = obj.getClass();
-                boolean canCast;
-                if (dst.isInterface()) {
-                    canCast = true;
-                } else {
-                    canCast = dst.isAssignableFrom(src);
-                    assertEquals(canCast, dst.isInstance(obj));
-                }
-                //System.out.println("obj="+obj+" <: dst="+dst);
+                boolean canCast = dst.isAssignableFrom(src);
+                //System.out.println("obj="+obj+" <: dst="+dst+(canCast ? " (OK)" : " (will fail)"));
                 try {
                     Object result = caster.invokeExact(obj);
                     if (canCast)
@@ -283,6 +186,91 @@
     }
 
     @Test
+    public void testConvert() throws Throwable {
+        //System.out.println("convert");
+        for (long tval = 0, ctr = 0;;) {
+            if (++ctr > 99999)  throw new AssertionError("too many test values");
+            // next test value:
+            //System.out.println(Long.toHexString(tval)); // prints 3776 test patterns
+            tval = nextTestValue(tval);
+            if (tval == 0) {
+                //System.out.println("test value count = "+ctr);  // 3776 = 8*59*8
+                break;  // repeat
+            }
+        }
+        for (Wrapper src : Wrapper.values()) {
+            for (Wrapper dst : Wrapper.values()) {
+                testConvert(src, dst, 0);
+            }
+        }
+    }
+    static void testConvert(Wrapper src, Wrapper dst, long tval) throws Throwable {
+        //System.out.println(src+" => "+dst);
+        boolean testSingleCase = (tval != 0);
+        final long tvalInit = tval;
+        MethodHandle conv = ValueConversions.convertPrimitive(src, dst);
+        MethodType convType;
+        if (src == Wrapper.VOID)
+            convType = MethodType.methodType(dst.primitiveType() /* , void */);
+        else
+            convType = MethodType.methodType(dst.primitiveType(), src.primitiveType());
+        assertEquals(convType, conv.type());
+        MethodHandle converter = conv.asType(conv.type().changeReturnType(Object.class));
+        for (;;) {
+            long n = tval;
+            Object testValue = src.wrap(n);
+            Object expResult = dst.cast(testValue, dst.primitiveType());
+            Object result;
+            switch (src) {
+                case INT:     result = converter.invokeExact((int)n); break;
+                case LONG:    result = converter.invokeExact(/*long*/n); break;
+                case FLOAT:   result = converter.invokeExact((float)n); break;
+                case DOUBLE:  result = converter.invokeExact((double)n); break;
+                case CHAR:    result = converter.invokeExact((char)n); break;
+                case BYTE:    result = converter.invokeExact((byte)n); break;
+                case SHORT:   result = converter.invokeExact((short)n); break;
+                case OBJECT:  result = converter.invokeExact((Object)n); break;
+                case BOOLEAN: result = converter.invokeExact((n & 1) != 0); break;
+                case VOID:    result = converter.invokeExact(); break;
+                default:  throw new AssertionError();
+            }
+            assertEquals("(src,dst,n,testValue)="+Arrays.asList(src,dst,"0x"+Long.toHexString(n),testValue),
+                         expResult, result);
+            if (testSingleCase)  break;
+            // next test value:
+            tval = nextTestValue(tval);
+            if (tval == tvalInit)  break;  // repeat
+        }
+    }
+    static long tweakSign(long x) {
+        // Assuming that x is mostly zeroes, make those zeroes follow bit #62 (just below the sign).
+        // This function is self-inverse.
+        final long MID_SIGN_BIT = 62;
+        long sign = -((x >>> MID_SIGN_BIT) & 1);  // all ones or all zeroes
+        long flip = (sign >>> -MID_SIGN_BIT);  // apply the sign below the mid-bit
+        return x ^ flip;
+    }
+    static long nextTestValue(long x) {
+        // Produce 64 bits with three component bitfields:  [ high:3 | mid:58 | low:3 ].
+        // The high and low fields vary through all possible bit patterns.
+        // The middle field is either all zero or has a single bit set.
+        // For better coverage of the neighborhood of zero, an internal sign bit is xored downward also.
+        long ux = tweakSign(x);  // unsign the middle field
+        final long LOW_BITS  = 3, LOW_BITS_MASK  = (1L << LOW_BITS)-1;
+        final long HIGH_BITS = 3, HIGH_BITS_MASK = ~(-1L >>> HIGH_BITS);
+        if ((ux & LOW_BITS_MASK) != LOW_BITS_MASK) {
+            ++ux;
+        } else {
+            ux &= ~LOW_BITS_MASK;
+            long midBit = (ux & ~HIGH_BITS_MASK);
+            if (midBit == 0)
+                midBit = (1L<<LOW_BITS);  // introduce a low bit
+            ux += midBit;
+        }
+        return tweakSign(ux);
+    }
+
+    @Test
     public void testVarargsArray() throws Throwable {
         //System.out.println("varargsArray");
         final int MIN = START_ARITY;
@@ -334,7 +322,7 @@
     }
 
     private void testTypedVarargsArray(Class<?> arrayType) throws Throwable {
-        System.out.println(arrayType.getSimpleName());
+        //System.out.println(arrayType.getSimpleName());
         Class<?> elemType = arrayType.getComponentType();
         int MIN = START_ARITY;
         int MAX = MAX_ARITY-2;  // 253+1 would cause parameter overflow with 'this' added
@@ -361,6 +349,7 @@
             assert(stype == MethodType.methodType(arrayType, arrayType));
             if (nargs <= 5) {
                 // invoke target as a spreader also:
+                @SuppressWarnings("cast")
                 Object res2 = spreader.invokeWithArguments((Object)res);
                 String res2String = toArrayString(res2);
                 assertEquals(Arrays.toString(args), res2String);
diff --git a/jdk/test/sun/java2d/DirectX/DrawBitmaskToSurfaceTest.java b/jdk/test/sun/java2d/DirectX/DrawBitmaskToSurfaceTest.java
new file mode 100644
index 0000000..3f37e5c
--- /dev/null
+++ b/jdk/test/sun/java2d/DirectX/DrawBitmaskToSurfaceTest.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 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
+ * 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     6997116
+ * @summary Test verifies that rendering of images with bitmap transparency
+ *          to a D3D surface does not cause an ClassCastException.
+ *
+ * @run main/othervm -Dsun.java2d.d3d=True DrawBitmaskToSurfaceTest
+ */
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.image.BufferedImage;
+import java.awt.image.IndexColorModel;
+import java.util.concurrent.CountDownLatch;
+import javax.swing.JFrame;
+
+public class DrawBitmaskToSurfaceTest extends JFrame {
+
+    private final Image src;
+    private static java.util.concurrent.CountDownLatch latch = null;
+    private static Throwable theError = null;
+
+    public DrawBitmaskToSurfaceTest() {
+        src = createTestImage();
+    }
+
+    private static Image createTestImage() {
+        byte[] r = new byte[]{(byte)0x00, (byte)0x80, (byte)0xff, (byte)0xff};
+        byte[] g = new byte[]{(byte)0x00, (byte)0x80, (byte)0xff, (byte)0x00};
+        byte[] b = new byte[]{(byte)0x00, (byte)0x80, (byte)0xff, (byte)0x00};
+
+        IndexColorModel icm = new IndexColorModel(2, 4, r, g, b, 3);
+
+        BufferedImage img = new BufferedImage(100, 100,
+                                              BufferedImage.TYPE_BYTE_INDEXED,
+                                              icm);
+        return img;
+    }
+
+    @Override
+    public void paint(final Graphics g) {
+        try {
+            System.err.println("paint frame....");
+            g.drawImage(src, 30, 30, this);
+        } catch (Throwable e) {
+            theError = e;
+        } finally {
+            if (latch != null) {
+                latch.countDown();
+            }
+        }
+    }
+
+    public static void main(final String[] args) throws Exception {
+        final JFrame frame = new DrawBitmaskToSurfaceTest();
+        frame.setBounds(10, 350, 200, 200);
+        frame.setVisible(true);
+
+        Thread.sleep(2000);
+
+        System.err.println("Change frame bounds...");
+        latch = new CountDownLatch(1);
+        frame.setBounds(10, 350, 90, 90);
+        frame.repaint();
+
+        try {
+            if (latch.getCount() > 0) {
+                latch.await();
+            }
+        } catch (InterruptedException e) {
+        }
+
+        frame.dispose();
+
+        if (theError != null) {
+            throw new RuntimeException("Test failed.", theError);
+        }
+
+        System.err.println("Test passed");
+    }
+}
diff --git a/jdk/test/sun/java2d/OpenGL/CustomCompositeTest.java b/jdk/test/sun/java2d/OpenGL/CustomCompositeTest.java
new file mode 100644
index 0000000..3977270
--- /dev/null
+++ b/jdk/test/sun/java2d/OpenGL/CustomCompositeTest.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (c) 2012, 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     7124347
+ * @summary Verifies that rendering with XOR composite, and arbitraty
+ *          custom composite doesn not cause internal errors.
+ *
+ * @run     main/othervm -Dsun.java2d.opengl=True CustomCompositeTest
+ */
+
+import java.awt.AWTException;
+import java.awt.Color;
+import java.awt.Composite;
+import java.awt.CompositeContext;
+import java.awt.Dimension;
+import java.awt.GradientPaint;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.ImageCapabilities;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBufferInt;
+import java.awt.image.Raster;
+import java.awt.image.SinglePixelPackedSampleModel;
+import java.awt.image.VolatileImage;
+import java.awt.image.WritableRaster;
+import java.util.concurrent.CountDownLatch;
+import javax.swing.JComponent;
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+
+public class CustomCompositeTest {
+
+    private static JFrame frame;
+    private static CountDownLatch paintLatch;
+    private static Throwable paintError;
+
+    public static void main(String[] args) {
+
+        paintLatch = new CountDownLatch(1);
+        paintError = null;
+
+        SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+                initGUI();
+            }
+        });
+
+        try {
+            paintLatch.await();
+        } catch (InterruptedException e) {
+        };
+        System.out.println("Paint is done!");
+        if (paintError != null) {
+            frame.dispose();
+            throw new RuntimeException("Test FAILED.", paintError);
+        }
+
+        System.out.println("Phase 1: PASSED.");
+
+        // now resise the frame in order to cause re-paint with accelerated
+        // source images.
+        paintError = null;
+        paintLatch = new CountDownLatch(1);
+
+        SwingUtilities.invokeLater(new Runnable() {
+            @Override
+            public void run() {
+                Dimension size = frame.getSize();
+                size.width += 50;
+                size.height += 50;
+
+                frame.setSize(size);
+            }
+        });
+
+        try {
+            paintLatch.await();
+        } catch (InterruptedException e) {
+        };
+        if (paintError != null) {
+            frame.dispose();
+            throw new RuntimeException("Resize test FAILED.", paintError);
+        }
+        frame.dispose();
+        System.out.println("Phase 2: PASSED.");
+
+        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        GraphicsConfiguration cfg = env.getDefaultScreenDevice().getDefaultConfiguration();
+        // test rendering to accelerated volatile image
+        testVolatileImage(cfg, true);
+        System.out.println("Phase 3: PASSED.");
+
+        // test rendering to unaccelerated volatile image
+        testVolatileImage(cfg, false);
+        System.out.println("Phase 4: PASSED.");
+    }
+
+    private static void testVolatileImage(GraphicsConfiguration cfg,
+            boolean accelerated)
+    {
+        VolatileImage dst = null;
+        try {
+            dst = cfg.createCompatibleVolatileImage(640, 480,
+                new ImageCapabilities(accelerated));
+        } catch (AWTException e) {
+            System.out.println("Unable to create volatile image, skip the test.");
+            return;
+        }
+        renderToVolatileImage(dst);
+    }
+
+    private static void renderToVolatileImage(VolatileImage dst) {
+        Graphics2D g = dst.createGraphics();
+        do {
+            System.out.println("Render to volatile image..");
+            try {
+                MyComp.renderTest(g, dst.getHeight(), dst.getHeight());
+            } catch (Throwable e) {
+                throw new RuntimeException("Test FAILED.", e);
+            }
+        } while (dst.contentsLost());
+        System.out.println("Done.");
+    }
+
+    private static void initGUI() {
+        frame = new JFrame("Silly composite");
+        frame.getContentPane().add(new MyComp());
+        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        frame.pack();
+        frame.setVisible(true);
+    }
+
+    private static class MyComp extends JComponent {
+
+        private static BufferedImage theImage;
+
+        public MyComp() {
+        }
+
+        private static BufferedImage getTestImage() {
+            if (theImage == null) {
+                theImage = new BufferedImage(256, 256, BufferedImage.TYPE_INT_ARGB);
+                Graphics2D g2d = theImage.createGraphics();
+                g2d.setColor(Color.red);
+                g2d.fillRect(0, 0, 256, 256);
+
+                g2d.setPaint(new GradientPaint(0, 0, Color.red, 256, 256, Color.blue));
+                g2d.fillRect(0, 100, 256, 256);
+                g2d.dispose();
+            }
+            return theImage;
+        }
+
+        public Dimension getPreferredSize() {
+            return new Dimension(640, 375);
+        }
+
+        public void paintComponent(Graphics g) {
+
+
+            Graphics2D g2d = (Graphics2D) g;
+            try {
+                renderTest(g2d, getWidth(), getHeight());
+            } catch (Throwable e) {
+                paintError = e;
+            }
+            if (paintLatch != null) {
+                paintLatch.countDown();
+            }
+        }
+
+        public static void renderTest(Graphics2D g2d, int w, int h) {
+            g2d.setColor(Color.yellow);
+            g2d.fillRect(0, 0, w, h);
+
+            BufferedImage image = getTestImage();
+            // draw original image
+            g2d.drawRenderedImage(image, null);
+
+            // draw image with custom composite
+            g2d.translate(175, 25);
+            Composite currentComposite = g2d.getComposite();
+            g2d.setComposite(new TestComposite());
+            g2d.drawRenderedImage(image, null);
+            g2d.setComposite(currentComposite);
+
+            // draw image with XOR
+            g2d.translate(175, 25);
+            g2d.setXORMode(Color.red);
+            g2d.drawRenderedImage(image, null);
+
+
+            System.out.println("Painting is done...");
+        }
+    }
+
+    // A silly custom Composite to demonstrate the problem - just inverts the RGB
+    private static class TestComposite implements Composite {
+
+        public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel, RenderingHints hints) {
+            return new TestCompositeContext();
+        }
+    }
+
+    private static class TestCompositeContext implements CompositeContext {
+
+        public void dispose() {
+        }
+
+        public void compose(Raster src, Raster dstIn, WritableRaster dstOut) {
+            int w = src.getWidth();
+            int h = src.getHeight();
+
+            DataBufferInt srcDB = (DataBufferInt) src.getDataBuffer();
+            DataBufferInt dstOutDB = (DataBufferInt) dstOut.getDataBuffer();
+            int srcRGB[] = srcDB.getBankData()[0];
+            int dstOutRGB[] = dstOutDB.getBankData()[0];
+            int srcOffset = srcDB.getOffset();
+            int dstOutOffset = dstOutDB.getOffset();
+            int srcScanStride = ((SinglePixelPackedSampleModel) src.getSampleModel()).getScanlineStride();
+            int dstOutScanStride = ((SinglePixelPackedSampleModel) dstOut.getSampleModel()).getScanlineStride();
+            int srcAdjust = srcScanStride - w;
+            int dstOutAdjust = dstOutScanStride - w;
+
+            int si = srcOffset;
+            int doi = dstOutOffset;
+
+            for (int i = 0; i < h; i++) {
+                for (int j = 0; j < w; j++) {
+                    dstOutRGB[doi] = srcRGB[si] ^ 0x00ffffff;
+                    si++;
+                    doi++;
+                }
+
+                si += srcAdjust;
+                doi += dstOutAdjust;
+            }
+        }
+    }
+}
diff --git a/jdk/test/sun/java2d/OpenGL/bug7181438.java b/jdk/test/sun/java2d/OpenGL/bug7181438.java
new file mode 100644
index 0000000..3aa6738
--- /dev/null
+++ b/jdk/test/sun/java2d/OpenGL/bug7181438.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.GraphicsConfiguration;
+import java.awt.GraphicsEnvironment;
+import java.awt.Transparency;
+import java.awt.image.BufferedImage;
+import java.awt.image.VolatileImage;
+
+/**
+ * @test
+ * @bug 7181438
+ * @summary Verifies that we get correct alpha, when we draw opaque
+ * BufferedImage to non opaque VolatileImage via intermediate opaque texture.
+ * @author Sergey Bylokhov
+ * @run main/othervm -Dsun.java2d.accthreshold=0 bug7181438
+ */
+public final class bug7181438 {
+
+    private static final int SIZE = 500;
+
+    public static void main(final String[] args) {
+
+        final BufferedImage bi = createBufferedImage();
+        final VolatileImage vi = createVolatileImage();
+        final Graphics s2dVi = vi.getGraphics();
+
+        //sw->texture->surface blit
+        s2dVi.drawImage(bi, 0, 0, null);
+
+        final BufferedImage results = vi.getSnapshot();
+        for (int i = 0; i < SIZE; ++i) {
+            for (int j = 0; j < SIZE; ++j) {
+                //Image should be opaque: (black color and alpha = 255)
+                if (results.getRGB(i, j) != 0xFF000000) {
+                    throw new RuntimeException("Failed: Wrong alpha");
+                }
+            }
+        }
+        System.out.println("Passed");
+    }
+
+
+    private static VolatileImage createVolatileImage() {
+        final GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+        final GraphicsConfiguration gc = ge.getDefaultScreenDevice().getDefaultConfiguration();
+        return gc.createCompatibleVolatileImage(SIZE, SIZE,
+                                                Transparency.TRANSLUCENT);
+    }
+
+    private static BufferedImage createBufferedImage() {
+        final BufferedImage bi = new BufferedImage(SIZE, SIZE,
+                                                   BufferedImage.TYPE_INT_RGB);
+        final Graphics bg = bi.getGraphics();
+        //Black color and alpha = 0
+        bg.setColor(new Color(0, 0, 0, 0));
+        bg.fillRect(0, 0, SIZE, SIZE);
+        bg.dispose();
+        return bi;
+    }
+}
diff --git a/jdk/test/sun/management/AgentCMETest.java b/jdk/test/sun/management/AgentCMETest.java
new file mode 100644
index 0000000..f8bfd53
--- /dev/null
+++ b/jdk/test/sun/management/AgentCMETest.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/**
+ * @test
+ * @bug 7164191
+ * @summary properties.putAll API may fail with ConcurrentModifcationException on multi-thread scenario
+ * @author Deven You
+ */
+
+import java.util.Properties;
+import sun.management.Agent;
+
+public class AgentCMETest {
+    static Class<?> agentClass;
+
+    /**
+     * In sun.management.Agent.loadManagementProperties(), call
+     * properties.putAll API may fail with ConcurrentModifcationException if the
+     * system properties are modified simultaneously by another thread
+     *
+     * @param args
+     * @throws Exception
+     */
+    public static void main(String[] args) throws Exception {
+        System.out.println("Start...");
+
+        final Properties properties = System.getProperties();
+        Thread t1 = new Thread(new Runnable() {
+            public void run() {
+                for (int i = 0; i < 100; i++) {
+                    properties.put(String.valueOf(i), "");
+                    try {
+                        Thread.sleep(1);
+                    } catch (InterruptedException e) {
+                        // do nothing
+                    }
+                }
+            }
+        });
+        t1.start();
+
+        for (int i = 0; i < 10000; i++) {
+            Agent.loadManagementProperties();
+        }
+
+        System.out.println("Finished...");
+    }
+}
diff --git a/jdk/test/sun/misc/IoTrace/IoTraceAgent.java b/jdk/test/sun/misc/IoTrace/IoTraceAgent.java
new file mode 100644
index 0000000..8b67048
--- /dev/null
+++ b/jdk/test/sun/misc/IoTrace/IoTraceAgent.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.ACC_FINAL;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.ACC_PRIVATE;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.ACC_PUBLIC;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.ACC_STATIC;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.ACC_SUPER;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.ILOAD;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.INVOKESPECIAL;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.INVOKESTATIC;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.IRETURN;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.RETURN;
+import static com.sun.xml.internal.ws.org.objectweb.asm.Opcodes.V1_6;
+
+import java.lang.instrument.ClassDefinition;
+import java.lang.instrument.Instrumentation;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.InetAddress;
+
+import com.sun.xml.internal.ws.org.objectweb.asm.ClassWriter;
+import com.sun.xml.internal.ws.org.objectweb.asm.MethodVisitor;
+import com.sun.xml.internal.ws.org.objectweb.asm.Type;
+import sun.misc.IoTrace;
+
+public class IoTraceAgent {
+
+    private static IoTraceListener listener;
+
+    public static void setListener(IoTraceListener l) {
+        listener = l;
+    }
+
+    public static Object socketReadBegin(InetAddress address, int port,
+            int timeout) {
+        IoTraceListener l = listener;
+        if (l != null) {
+            return l.socketReadBegin(address, port, timeout);
+        }
+        return null;
+    }
+
+    public static void socketReadEnd(Object context, long bytesRead) {
+        IoTraceListener l = listener;
+        if (l != null) {
+            l.socketReadEnd(context, bytesRead);
+        }
+    }
+
+    public static Object socketWriteBegin(InetAddress address, int port) {
+        IoTraceListener l = listener;
+        if (l != null) {
+            return l.socketWriteBegin(address, port);
+        }
+        return null;
+    }
+
+    public static void socketWriteEnd(Object context, long bytesWritten) {
+        IoTraceListener l = listener;
+        if (l != null) {
+            l.socketWriteEnd(context, bytesWritten);
+        }
+    }
+
+    public static Object fileReadBegin(String path) {
+        IoTraceListener l = listener;
+        if (l != null) {
+            return l.fileReadBegin(path);
+        }
+        return null;
+    }
+
+    public static void fileReadEnd(Object context, long bytesRead) {
+        IoTraceListener l = listener;
+        if (l != null) {
+            l.fileReadEnd(context, bytesRead);
+        }
+    }
+
+    public static Object fileWriteBegin(String path) {
+        IoTraceListener l = listener;
+        if (l != null) {
+            return l.fileWriteBegin(path);
+        }
+        return null;
+    }
+
+    public static void fileWriteEnd(Object context, long bytesWritten) {
+        IoTraceListener l = listener;
+        if (l != null) {
+            l.fileWriteEnd(context, bytesWritten);
+        }
+    }
+
+    public static void premain(String agentArgs, Instrumentation inst)
+            throws Exception {
+        ClassDefinition cd = new ClassDefinition(IoTrace.class,
+                generateClassAsm());
+        inst.redefineClasses(cd);
+    }
+
+    private static byte[] generateClassAsm() {
+        ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS);
+        cw.visit(V1_6, ACC_PUBLIC | ACC_SUPER | ACC_FINAL, "sun/misc/IoTrace",
+                null, "java/lang/Object", null);
+
+        // for all methods in the existing IoTrace class
+        // we want to create a method in the new version of it which call
+        // IoTraceAgent
+        //
+        // 0: aload_0
+        // 1: iload_1
+        // 2: iload_2
+        // 3: invokestatic #16 // Method
+        // IoTraceAgent.socketReadBegin:(Ljava/net/InetAddress;II)Ljava/lang/Object;
+        // 6: areturn
+
+        for (Method om : IoTrace.class.getDeclaredMethods()) {
+            if (!Modifier.isStatic(om.getModifiers())) {
+                continue;
+            }
+
+            // create a method with the same signature as the
+            // original method
+            MethodVisitor mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC,
+                    om.getName(), Type.getMethodDescriptor(om), null, null);
+            mv.visitCode();
+
+            // get the return type and argument list types
+            Type[] argTypes = Type.getArgumentTypes(om);
+            Type retType = Type.getReturnType(om);
+
+            // load all the arguments
+            int i = 0;
+            for (Type t : argTypes) {
+                mv.visitVarInsn(t.getOpcode(ILOAD), i++);
+            }
+
+            // call a method with the same signature (but in a different class)
+            // with all the arguments
+            mv.visitMethodInsn(INVOKESTATIC, "IoTraceAgent", om.getName(),
+                    Type.getMethodDescriptor(om));
+
+            // return the value from the called method
+            mv.visitInsn(retType.getOpcode(IRETURN));
+            mv.visitEnd();
+        }
+
+        // empty private constructor
+        MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "<init>", "()V", null,
+                null);
+        mv.visitCode();
+        mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
+        mv.visitInsn(RETURN);
+        mv.visitEnd();
+
+        cw.visitEnd();
+        return cw.toByteArray();
+    }
+}
diff --git a/jdk/test/sun/misc/IoTrace/IoTraceBase.java b/jdk/test/sun/misc/IoTrace/IoTraceBase.java
new file mode 100644
index 0000000..4e1d189
--- /dev/null
+++ b/jdk/test/sun/misc/IoTrace/IoTraceBase.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.net.InetAddress;
+
+
+public class IoTraceBase implements IoTraceListener {
+
+    protected static final Object my_context = new Object() {
+    };
+
+    private String path;
+    private long bytesRead;
+    private long bytesWritten;
+    private Object context;
+    private InetAddress address;
+    private int port;
+    private int timeout;
+
+    protected void clear() {
+        context = null;
+        bytesRead = 0;
+        bytesWritten = 0;
+        address = null;
+        port = 0;
+        timeout = 0;
+        path = null;
+    }
+
+    @Override
+    public Object fileWriteBegin(String p) {
+        path = p;
+        return my_context;
+    }
+
+    @Override
+    public void fileWriteEnd(Object ctx, long bw) {
+        context = ctx;
+        bytesWritten = bw;
+    }
+
+    @Override
+    public Object fileReadBegin(String p) {
+        path = p;
+        return my_context;
+    }
+
+    @Override
+    public void fileReadEnd(Object ctx, long br) {
+        context = ctx;
+        bytesRead = br;
+    }
+
+    @Override
+    public Object socketReadBegin(InetAddress address, int port,
+            int timeout) {
+        this.address = address;
+        this.port = port;
+        this.timeout = timeout;
+        return my_context;
+    }
+
+    @Override
+    public void socketReadEnd(Object context, long bytesRead) {
+        this.context = context;
+        this.bytesRead = bytesRead;
+    }
+
+    @Override
+    public Object socketWriteBegin(InetAddress address, int port) {
+        this.address = address;
+        this.port = port;
+        return my_context;
+    }
+
+    @Override
+    public void socketWriteEnd(Object context, long bytesWritten) {
+        this.context = context;
+        this.bytesWritten = bytesWritten;
+    }
+
+    protected void expectFileRead(long br, File f) throws Exception {
+        expectFile(0, br, f);
+    }
+
+    protected void expectFileWrite(long bw, File f) throws Exception {
+        expectFile(bw, 0, f);
+    }
+
+    protected void expectFile(long bw, long br, File f) throws Exception {
+        if (context != my_context) {
+            throw new Exception("Wrong context: " + context);
+        }
+        if (bytesWritten != bw) {
+            throw new Exception("Expected " + bw + " byte to be read, got: "
+                    + bytesWritten);
+        }
+        if (bytesRead != br) {
+            throw new Exception("Expected " + br + " byte to be read, got: "
+                    + bytesWritten);
+        }
+        if (!path.equals(f.getPath())) {
+            throw new Exception("Incorrect path: " + path + ". Expected: "
+                    + f.getPath());
+        }
+    }
+
+    protected void expectSocket(int br, int bw, InetAddress ia, int p, int t)
+            throws Exception {
+        if (context != my_context) {
+            throw new Exception("Wrong context: " + context);
+        }
+        if (bytesWritten != bw) {
+            throw new Exception("Expected " + bw + " byte to be written, got: "
+                    + bytesWritten);
+        }
+        if (bytesRead != br) {
+            throw new Exception("Expected " + br + " byte to be read, got: "
+                    + bytesWritten);
+        }
+        if (!address.equals(ia)) {
+            throw new Exception("Incorrect address: " + address
+                    + ". Expected: " + ia);
+        }
+        if (port != p) {
+            throw new Exception("Expected " + p + " port, got: " + port);
+        }
+        if (timeout != t) {
+            throw new Exception("Expected " + t + " timeout, got: " + timeout);
+        }
+    }
+}
\ No newline at end of file
diff --git a/jdk/test/sun/misc/IoTrace/IoTraceFileChannelReadWrite.java b/jdk/test/sun/misc/IoTrace/IoTraceFileChannelReadWrite.java
new file mode 100644
index 0000000..c6e172e
--- /dev/null
+++ b/jdk/test/sun/misc/IoTrace/IoTraceFileChannelReadWrite.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.nio.file.StandardOpenOption;
+
+/*
+ * @test
+ * @bug 8003322
+ * @run shell ioTraceTest.sh IoTraceFileChannelReadWrite
+ */
+public class IoTraceFileChannelReadWrite extends IoTraceBase {
+
+    private void testWrite(File f) throws IOException, FileNotFoundException,
+            Exception {
+        try (FileChannel fc = FileChannel.open(f.toPath(),
+                StandardOpenOption.WRITE)) {
+            ByteBuffer bb = ByteBuffer.allocate(1);
+            bb.put((byte) 11);
+            bb.flip();
+            fc.write(bb);
+        }
+        expectFile(1, 0, f);
+    }
+
+    private void testRead(File f) throws IOException, FileNotFoundException,
+            Exception {
+        try (FileChannel fc = FileChannel.open(f.toPath(),
+                StandardOpenOption.READ)) {
+            ByteBuffer bb = ByteBuffer.allocate(1);
+            fc.read(bb);
+        }
+        expectFile(0, 1, f);
+    }
+
+    public void test() throws Exception {
+        IoTraceAgent.setListener(this);
+        File f = File.createTempFile("IoTraceFileChannelReadWrite", ".bin");
+        try {
+            clear();
+            testWrite(f);
+            clear();
+            testRead(f);
+        } finally {
+            f.delete();
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        IoTraceFileChannelReadWrite t = new IoTraceFileChannelReadWrite();
+        t.test();
+    }
+}
diff --git a/jdk/test/sun/misc/IoTrace/IoTraceFileReadWrite.java b/jdk/test/sun/misc/IoTrace/IoTraceFileReadWrite.java
new file mode 100644
index 0000000..32e5bb2
--- /dev/null
+++ b/jdk/test/sun/misc/IoTrace/IoTraceFileReadWrite.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+
+/*
+ * @test
+ * @bug 8003322
+ * @run shell ioTraceTest.sh IoTraceFileReadWrite
+ */
+public class IoTraceFileReadWrite extends IoTraceBase {
+
+    private void testWrite(File f) throws IOException, FileNotFoundException,
+            Exception {
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            fos.write(11);
+        }
+        expectFile(1, 0, f);
+    }
+
+
+    private void testRead(File f) throws IOException, FileNotFoundException,
+            Exception {
+        try (FileInputStream fos = new FileInputStream(f)) {
+            fos.read();
+        }
+        expectFile(0, 1, f);
+    }
+
+    private void testRandomAccessWrite(File f) throws Exception {
+        try (RandomAccessFile raf = new RandomAccessFile(f, "rw")) {
+            raf.write(11);
+        }
+        expectFile(1, 0, f);
+    }
+
+    private void testRandomAccessRead(File f) throws Exception {
+        try (RandomAccessFile raf = new RandomAccessFile(f, "r")) {
+            raf.read();
+        }
+        expectFile(0, 1, f);
+    }
+
+    public void test() throws Exception {
+        IoTraceAgent.setListener(this);
+        File f = File.createTempFile("IoTraceFileReadWrite", ".bin");
+        try {
+            clear();
+            testWrite(f);
+            clear();
+            testRead(f);
+            clear();
+            testRandomAccessWrite(f);
+            clear();
+            testRandomAccessRead(f);
+        } finally {
+            f.delete();
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        IoTraceFileReadWrite t = new IoTraceFileReadWrite();
+        t.test();
+    }
+}
diff --git a/jdk/test/sun/misc/IoTrace/IoTraceListener.java b/jdk/test/sun/misc/IoTrace/IoTraceListener.java
new file mode 100644
index 0000000..e32d97b
--- /dev/null
+++ b/jdk/test/sun/misc/IoTrace/IoTraceListener.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.net.InetAddress;
+
+import sun.misc.IoTrace;
+
+/**
+ * Implementations of this interface can be registered with
+ * {@link IoTrace#setListener(IoTraceListener)} to receive callbacks when file
+ * and socket operations are performed.
+ * <p>
+ * The xxBegin() methods return a "context". This can be any Object. This
+ * context will be passed to the corresponding xxEnd() method. This way, an
+ * implementation can correlate the beginning of an operation with the end.
+ * <p>
+ * It is possible for a xxEnd() method to be called with a null handle. This
+ * happens if tracing was started between the call to xxBegin() and xxEnd(), in
+ * which case xxBegin() would not have been called. It is the implementation's
+ * responsibility to not throw an exception in this case.
+ * <p>
+ * Implementations should never throw exceptions since this will cause
+ * disruptions to the I/O operations.
+ * <p>
+ * An xxBegin() call is not guaranteed to be followed by an xxEnd() call, since
+ * the listener in IoTrace can be reset at any time.
+ */
+public interface IoTraceListener {
+
+    /**
+     * Called before data is read from a socket.
+     *
+     * @param address
+     *            the remote address the socket is bound to
+     * @param port
+     *            the remote port the socket is bound to
+     * @param timeout
+     *            the SO_TIMEOUT value of the socket (in milliseconds) or 0 if
+     *            there is no timeout set
+     * @return a context object
+     */
+    public Object socketReadBegin(InetAddress address, int port, int timeout);
+
+    /**
+     * Called after data is read from the socket.
+     *
+     * @param context
+     *            the context returned by the previous call to socketReadBegin()
+     * @param bytesRead
+     *            the number of bytes read from the socket, 0 if there was an
+     *            error reading from the socket
+     */
+    public void socketReadEnd(Object context, long bytesRead);
+
+    /**
+     * Called before data is written to a socket.
+     *
+     * @param address
+     *            the remote address the socket is bound to
+     * @param port
+     *            the remote port the socket is bound to
+     * @return a context object
+     */
+    public Object socketWriteBegin(InetAddress address, int port);
+
+    /**
+     * Called after data is written to a socket.
+     *
+     * @param context
+     *            the context returned by the previous call to
+     *            socketWriteBegin()
+     * @param bytesWritten
+     *            the number of bytes written to the socket, 0 if there was an
+     *            error writing to the socket
+     */
+    public void socketWriteEnd(Object context, long bytesWritten);
+
+    /**
+     * Called before data is read from a file.
+     *
+     * @param path
+     *            the path of the file
+     * @return a context object
+     */
+    public Object fileReadBegin(String path);
+
+    /**
+     * Called after data is read from a file.
+     *
+     * @param context
+     *            the context returned by the previous call to fileReadBegin()
+     * @param bytesRead
+     *            the number of bytes written to the file, 0 if there was an
+     *            error writing to the file
+     */
+    public void fileReadEnd(Object context, long bytesRead);
+
+    /**
+     * Called before data is written to a file.
+     *
+     * @param path
+     *            the path of the file
+     * @return a context object
+     */
+    public Object fileWriteBegin(String path);
+
+    /**
+     * Called after data is written to a file.
+     *
+     * @param context
+     *            the context returned by the previous call to fileReadBegin()
+     * @param bytesWritten
+     *            the number of bytes written to the file, 0 if there was an
+     *            error writing to the file
+     */
+    public void fileWriteEnd(Object context, long bytesWritten);
+}
diff --git a/jdk/test/sun/misc/IoTrace/IoTraceSocketReadWrite.java b/jdk/test/sun/misc/IoTrace/IoTraceSocketReadWrite.java
new file mode 100644
index 0000000..3ad1d86
--- /dev/null
+++ b/jdk/test/sun/misc/IoTrace/IoTraceSocketReadWrite.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/*
+ * @test
+ * @bug 8003322
+ * @run shell ioTraceTest.sh IoTraceSocketReadWrite
+ */
+public class IoTraceSocketReadWrite extends IoTraceBase {
+
+    public void test() throws Exception {
+        IoTraceAgent.setListener(this);
+
+        ServerSocket ss = null;
+        Socket s1 = null, s2 = null;
+        OutputStream os = null;
+        InputStream is = null;
+
+        try {
+            InetAddress iaddr = InetAddress.getLocalHost();
+            ss = new ServerSocket(0);
+            s1 = new Socket(iaddr, ss.getLocalPort());
+            s2 = ss.accept();
+
+            os = s1.getOutputStream();
+            is = s2.getInputStream();
+
+            os.write((byte) 11);
+            is.read();
+
+            expectSocket(1, 1, s2.getInetAddress(), s2.getPort(), 0);
+
+        } finally {
+            if (ss != null) {
+                ss.close();
+            }
+            if (s1 != null) {
+                s1.close();
+            }
+            if (s2 != null) {
+                s2.close();
+            }
+        }
+    }
+
+    public static void main(String... args) throws Exception {
+        IoTraceSocketReadWrite t = new IoTraceSocketReadWrite();
+        t.test();
+    }
+}
\ No newline at end of file
diff --git a/jdk/make/sun/rmi/rmi/mapfile-vers b/jdk/test/sun/misc/IoTrace/ioTraceTest.sh
similarity index 66%
copy from jdk/make/sun/rmi/rmi/mapfile-vers
copy to jdk/test/sun/misc/IoTrace/ioTraceTest.sh
index dc33402..e1506fa 100644
--- a/jdk/make/sun/rmi/rmi/mapfile-vers
+++ b/jdk/test/sun/misc/IoTrace/ioTraceTest.sh
@@ -1,12 +1,10 @@
 #
-# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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.
+# 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
@@ -23,11 +21,14 @@
 # questions.
 #
 
-# Define library interface.
+set -x
+PWD=`pwd`
 
-SUNWprivate_1.1 {
-	global:
-	    Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader;
-	local:
-	    *;
-};
+cd ${TESTSRC}
+${TESTJAVA}/bin/javac -XDignore.symbol.file=true -d ${TESTCLASSES} *.java
+
+cd ${TESTCLASSES}
+${TESTJAVA}/bin/jar cfm iotraceagent.jar ${TESTSRC}/iotraceagent.mf IoTraceAgent.class IoTraceListener.class
+
+cd ${PWD}
+${TESTJAVA}/bin/java ${TESTVMOPTS} -javaagent:${TESTCLASSES}/iotraceagent.jar -cp ${TESTCLASSES} $*
diff --git a/jdk/test/sun/misc/IoTrace/iotraceagent.mf b/jdk/test/sun/misc/IoTrace/iotraceagent.mf
new file mode 100644
index 0000000..add05c8
--- /dev/null
+++ b/jdk/test/sun/misc/IoTrace/iotraceagent.mf
@@ -0,0 +1,3 @@
+Premain-Class: IoTraceAgent
+Can-Redefine-Classes: true
+Boot-Class-Path: iotraceagent.jar
diff --git a/jdk/test/sun/net/www/messageheader/HTest.java b/jdk/test/sun/net/www/MessageHeaderTest.java
similarity index 70%
rename from jdk/test/sun/net/www/messageheader/HTest.java
rename to jdk/test/sun/net/www/MessageHeaderTest.java
index 8898ccd..aceb635 100644
--- a/jdk/test/sun/net/www/messageheader/HTest.java
+++ b/jdk/test/sun/net/www/MessageHeaderTest.java
@@ -24,30 +24,21 @@
 /**
  * @test
  * @bug 8003948
- * @run main HTest
+ * @run main MessageHeaderTest
  */
 import java.io.*;
 import sun.net.www.MessageHeader;
 
-public class HTest {
+public class MessageHeaderTest {
     public static void main (String[] args) throws Exception {
-        String prefix = System.getProperty("test.src");
-        System.out.println ("TEST.SRC = " + prefix);
         for (int i=0; i<7; i++) {
-            File f = new File(prefix, Integer.toString(i));
-            FileInputStream fis = new FileInputStream(f);
-            MessageHeader h = new MessageHeader(fis);
+            ByteArrayInputStream bis = new ByteArrayInputStream(headers[i].getBytes());
+            MessageHeader h = new MessageHeader(bis);
             String before = h.toString();
             before = before.substring(before.indexOf('{'));
-            System.out.println ("Before");
-            System.out.println (before);
             boolean result = h.filterNTLMResponses("WWW-Authenticate");
             String after = h.toString();
             after = after.substring(after.indexOf('{'));
-            System.out.println ("After");
-            System.out.println (after);
-            System.out.println ("Expected");
-            System.out.println (expected[i]);
             if (!expected[i].equals(after)) {
                 throw new RuntimeException(Integer.toString(i) + " expected != after");
             }
@@ -70,4 +61,14 @@
     static boolean[] expectedResult = {
         false, false, true, true, true, false, false
     };
+
+    static String[] headers = {
+        "HTTP/1.1 200 Ok\r\nFoo: bar\r\nBar: foo\r\nWWW-Authenticate: NTLM sdsds",
+        "HTTP/1.1 200 Ok\r\nFoo: bar\r\nBar: foo\r\nWWW-Authenticate:",
+        "HTTP/1.1 200 Ok\r\nFoo: bar\r\nBar: foo\r\nWWW-Authenticate: NTLM sdsds\r\nWWW-Authenticate: Negotiate",
+        "HTTP/1.1 200 Ok\r\nFoo: bar\r\nBar: foo\r\nWWW-Authenticate: NTLM sdsds\r\nWWW-Authenticate: Negotiate\r\nWWW-Authenticate: Kerberos",
+        "HTTP/1.1 200 Ok\r\nWWW-Authenticate: Negotiate\r\nFoo: bar\r\nBar: foo\r\nWWW-Authenticate: NTLM sdsds\r\nBar: foo\r\nWWW-Authenticate: Kerberos",
+        "HTTP/1.1 200 Ok\r\nWWW-Authenticate: Negotiate\r\nFoo: bar\r\nBar: foo\r\nWWW-Authenticate: NTLM\r\nBar: foo\r\nWWW-Authenticate: Kerberos",
+        "HTTP/1.1 200 Ok\r\nFoo: foo\r\nBar:\r\nWWW-Authenticate: NTLM blob\r\nBar: foo blob"
+    };
 }
diff --git a/jdk/test/sun/net/www/messageheader/0 b/jdk/test/sun/net/www/messageheader/0
deleted file mode 100644
index 46eb68d..0000000
--- a/jdk/test/sun/net/www/messageheader/0
+++ /dev/null
@@ -1,4 +0,0 @@
-HTTP/1.1 200 Ok

-Foo: bar

-Bar: foo

-WWW-Authenticate: NTLM sdsds

diff --git a/jdk/test/sun/net/www/messageheader/1 b/jdk/test/sun/net/www/messageheader/1
deleted file mode 100644
index 5d1bb35..0000000
--- a/jdk/test/sun/net/www/messageheader/1
+++ /dev/null
@@ -1,4 +0,0 @@
-HTTP/1.1 200 Ok

-Foo: bar

-Bar: foo

-WWW-Authenticate:

diff --git a/jdk/test/sun/net/www/messageheader/2 b/jdk/test/sun/net/www/messageheader/2
deleted file mode 100644
index 713ac49..0000000
--- a/jdk/test/sun/net/www/messageheader/2
+++ /dev/null
@@ -1,5 +0,0 @@
-HTTP/1.1 200 Ok

-Foo: bar

-Bar: foo

-WWW-Authenticate: NTLM sdsds

-WWW-Authenticate: Negotiate

diff --git a/jdk/test/sun/net/www/messageheader/3 b/jdk/test/sun/net/www/messageheader/3
deleted file mode 100644
index e35d2bf..0000000
--- a/jdk/test/sun/net/www/messageheader/3
+++ /dev/null
@@ -1,6 +0,0 @@
-HTTP/1.1 200 Ok

-Foo: bar

-Bar: foo

-WWW-Authenticate: NTLM sdsds

-WWW-Authenticate: Negotiate

-WWW-Authenticate: Kerberos

diff --git a/jdk/test/sun/net/www/messageheader/4 b/jdk/test/sun/net/www/messageheader/4
deleted file mode 100644
index 7bff354..0000000
--- a/jdk/test/sun/net/www/messageheader/4
+++ /dev/null
@@ -1,7 +0,0 @@
-HTTP/1.1 200 Ok

-WWW-Authenticate: Negotiate

-Foo: bar

-Bar: foo

-WWW-Authenticate: NTLM sdsds

-Bar: foo

-WWW-Authenticate: Kerberos

diff --git a/jdk/test/sun/net/www/messageheader/5 b/jdk/test/sun/net/www/messageheader/5
deleted file mode 100644
index 30938ea..0000000
--- a/jdk/test/sun/net/www/messageheader/5
+++ /dev/null
@@ -1,7 +0,0 @@
-HTTP/1.1 200 Ok

-WWW-Authenticate: Negotiate

-Foo: bar

-Bar: foo

-WWW-Authenticate: NTLM

-Bar: foo

-WWW-Authenticate: Kerberos

diff --git a/jdk/test/sun/net/www/messageheader/6 b/jdk/test/sun/net/www/messageheader/6
deleted file mode 100644
index fb220d1..0000000
--- a/jdk/test/sun/net/www/messageheader/6
+++ /dev/null
@@ -1,5 +0,0 @@
-HTTP/1.1 200 Ok

-Foo: foo

-Bar:

-WWW-Authenticate: NTLM blob

-Bar: foo blob

diff --git a/jdk/test/sun/nio/ch/SelProvider.java b/jdk/test/sun/nio/ch/SelProvider.java
index d0682b6..1674120 100644
--- a/jdk/test/sun/nio/ch/SelProvider.java
+++ b/jdk/test/sun/nio/ch/SelProvider.java
@@ -31,19 +31,23 @@
 
 public class SelProvider {
     public static void main(String[] args) throws Exception {
-        String osname = System.getProperty("os.name");
-        String osver = System.getProperty("os.version");
-        String spName = SelectorProvider.provider().getClass().getName();
-        String expected = null;
-        if ("SunOS".equals(osname)) {
-            expected = "sun.nio.ch.DevPollSelectorProvider";
-        } else if ("Linux".equals(osname)) {
-            expected = "sun.nio.ch.EPollSelectorProvider";
-        } else if (osname.contains("OS X")) {
-            expected = "sun.nio.ch.KQueueSelectorProvider";
-        } else
-            return;
-        if (!spName.equals(expected))
+        String expected = System.getProperty("java.nio.channels.spi.SelectorProvider");
+        if (expected == null) {
+            String osname = System.getProperty("os.name");
+            String osver = System.getProperty("os.version");
+            if ("SunOS".equals(osname)) {
+                expected = "sun.nio.ch.DevPollSelectorProvider";
+            } else if ("Linux".equals(osname)) {
+                expected = "sun.nio.ch.EPollSelectorProvider";
+            } else if (osname.contains("OS X")) {
+                expected = "sun.nio.ch.KQueueSelectorProvider";
+            } else {
+                return;
+            }
+        }
+        String cn = SelectorProvider.provider().getClass().getName();
+        System.out.println(cn);
+        if (!cn.equals(expected))
             throw new Exception("failed");
     }
 }
diff --git a/jdk/test/sun/rmi/log/ReliableLog/LogAlignmentTest.java b/jdk/test/sun/rmi/log/ReliableLog/LogAlignmentTest.java
index 04d2fd9..012c0b8 100644
--- a/jdk/test/sun/rmi/log/ReliableLog/LogAlignmentTest.java
+++ b/jdk/test/sun/rmi/log/ReliableLog/LogAlignmentTest.java
@@ -22,8 +22,10 @@
  */
 
 /* @test
-   @bug 4094889
-   @summary rmid can have a corrupted log
+ * @bug 4094889
+ * @summary rmid can have a corrupted log
+ *
+ * @run main LogAlignmentTest
  */
 
 /* Fault: ReliableLog used RandomAccessFile.skipBytes() to seek past the end
diff --git a/jdk/test/sun/rmi/log/ReliableLog/SnapshotSize.java b/jdk/test/sun/rmi/log/ReliableLog/SnapshotSize.java
index f1febfc..592ef5e 100644
--- a/jdk/test/sun/rmi/log/ReliableLog/SnapshotSize.java
+++ b/jdk/test/sun/rmi/log/ReliableLog/SnapshotSize.java
@@ -25,6 +25,8 @@
  * @bug 4319866
  * @summary Verify that ReliableLog.snapshotSize() returns correct snapshot
  *          file size even if LogHandler doesn't flush.
+ *
+ * @run main SnapshotSize
  */
 
 import java.io.ByteArrayOutputStream;
diff --git a/jdk/test/sun/rmi/rmic/RMIGenerator/RmicDefault.java b/jdk/test/sun/rmi/rmic/RMIGenerator/RmicDefault.java
index ad24841..5f4587e 100644
--- a/jdk/test/sun/rmi/rmic/RMIGenerator/RmicDefault.java
+++ b/jdk/test/sun/rmi/rmic/RMIGenerator/RmicDefault.java
@@ -28,7 +28,6 @@
  * @library ../../../../java/rmi/testlibrary
  *
  * @build StreamPipe
- * @build RmicDefault
  * @run main RmicDefault
  */
 
diff --git a/jdk/test/sun/rmi/rmic/classpath/RMICClassPathTest.java b/jdk/test/sun/rmi/rmic/classpath/RMICClassPathTest.java
new file mode 100644
index 0000000..a79d21b
--- /dev/null
+++ b/jdk/test/sun/rmi/rmic/classpath/RMICClassPathTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/* @test
+ * @bug 6610897
+ * @summary New constructor in sun.tools.java.ClassPath builds a path using
+ *          File.separator instead of File.pathSeparator
+ * @run main RMICClassPathTest
+ */
+
+import java.io.File;
+
+import sun.rmi.rmic.BatchEnvironment;
+
+public class RMICClassPathTest {
+    public static void main(String[] args) throws Exception {
+        String sysPath = "/home/~user/jdk/jre/lib/rt.jar";
+        String extDir = "";
+        String clPath = "/home/~user/user.jar" + File.pathSeparator +
+            "/home/~user/user2.jar" + File.pathSeparator +
+            "/home/~user/user3.jar";
+
+        String cpStr = BatchEnvironment.createClassPath(clPath, sysPath, extDir).toString();
+
+        String[] paths = cpStr.split(File.pathSeparator);
+
+        if (paths.length != 4) {
+            throw new Exception("ClassPath length is not correct: the expected length is 4 and the actual length is " + paths.length);
+        }
+    }
+}
diff --git a/jdk/test/sun/rmi/rmic/newrmic/equivalence/AppleUserImpl.java b/jdk/test/sun/rmi/rmic/newrmic/equivalence/AppleUserImpl.java
index 041aa33..ee34213 100644
--- a/jdk/test/sun/rmi/rmic/newrmic/equivalence/AppleUserImpl.java
+++ b/jdk/test/sun/rmi/rmic/newrmic/equivalence/AppleUserImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 import java.rmi.Naming;
 import java.rmi.server.UnicastRemoteObject;
 import java.rmi.registry.LocateRegistry;
+import java.rmi.registry.Registry;
 import java.util.Random;
 import java.util.ArrayList;
 import java.util.Date;
@@ -249,11 +250,12 @@
         }
 
         synchronized (user) {
+            int port = -1;
             // create new registry and bind new AppleUserImpl in registry
             try {
-                LocateRegistry.createRegistry(1099); //TestLibrary.REGISTRY_PORT);
-                Naming.rebind("rmi://localhost:1099/AppleUser",user);
-                              //TestLibrary.REGISTRY_PORT + "/AppleUser", user);
+                Registry registry = TestLibrary.createRegistryOnUnusedPort();
+                port = TestLibrary.getRegistryPort(registry);
+                Naming.rebind("rmi://localhost:" + port + "/AppleUser",user);
             } catch (RemoteException e) {
                 //TestLibrary.bomb("Failed to bind AppleUser", e);
             } catch (java.net.MalformedURLException e) {
@@ -263,10 +265,9 @@
             // start the other server if available
             try {
                 Class app = Class.forName("ApplicationServer");
-                server = new Thread((Runnable) app.newInstance());
-                logger.log(Level.INFO, "Starting application server " +
-                    "in same process");
-                server.start();
+                java.lang.reflect.Constructor appConstructor =
+                        app.getDeclaredConstructor(new Class[] {Integer.TYPE});
+                server = new Thread((Runnable) appConstructor.newInstance(port));
             } catch (ClassNotFoundException e) {
                 // assume the other server is running in a separate process
                 logger.log(Level.INFO, "Application server must be " +
diff --git a/jdk/test/sun/rmi/rmic/newrmic/equivalence/run.sh b/jdk/test/sun/rmi/rmic/newrmic/equivalence/run.sh
index 839c0ce..27c8604 100644
--- a/jdk/test/sun/rmi/rmic/newrmic/equivalence/run.sh
+++ b/jdk/test/sun/rmi/rmic/newrmic/equivalence/run.sh
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -28,18 +28,22 @@
 # of sample input classes.
 # @author Peter Jones
 #
-# @build AgentServerImpl
-# @build AppleImpl
-# @build AppleUserImpl
-# @build ComputeServerImpl
-# @build CountServerImpl
-# @build DayTimeServerImpl
-# @build G1Impl
-# @build MyObjectImpl
-# @build NotActivatableServerImpl
-# @build OrangeEchoImpl
-# @build OrangeImpl
-# @build ServerImpl
+# @library ../../../../../java/rmi/testlibrary
+#
+# @build TestLibrary
+#     AgentServerImpl
+#     AppleImpl
+#     AppleUserImpl
+#     ComputeServerImpl
+#     CountServerImpl
+#     DayTimeServerImpl
+#     G1Impl
+#     MyObjectImpl
+#     NotActivatableServerImpl
+#     OrangeEchoImpl
+#     OrangeImpl
+#     ServerImpl
+#
 # @run shell run.sh
 
 if [ "${TESTJAVA}" = "" ]
diff --git a/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java b/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java
index 7ecfd5e..afcc135 100644
--- a/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java
+++ b/jdk/test/sun/rmi/runtime/Log/6409194/NoConsoleOutput.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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,8 +31,7 @@
  * @author Peter Jones
  *
  * @library ../../../../../java/rmi/testlibrary
- * @build JavaVM
- * @build NoConsoleOutput
+ * @build TestLibrary JavaVM
  * @run main/othervm NoConsoleOutput
  */
 
@@ -60,9 +59,12 @@
             File.separatorChar + "logging.properties";
         ByteArrayOutputStream out = new ByteArrayOutputStream();
         ByteArrayOutputStream err = new ByteArrayOutputStream();
+
+        // We instantiate a JavaVM that should not produce any console output
+        // (neither on standard output, nor on standard err streams).
         JavaVM vm = new JavaVM(DoRMIStuff.class.getName(),
             "-Djava.util.logging.config.file=" + loggingPropertiesFile,
-                               "", out, err);
+                               "", out, err, false);
         vm.start();
         vm.getVM().waitFor();
 
@@ -87,7 +89,6 @@
     }
 
     public static class DoRMIStuff {
-        private static final int PORT = 2020;
         private interface Foo extends Remote {
             Object echo(Object obj) throws RemoteException;
         }
@@ -96,8 +97,9 @@
             public Object echo(Object obj) { return obj; }
         }
         public static void main(String[] args) throws Exception {
-            LocateRegistry.createRegistry(PORT);
-            Registry reg = LocateRegistry.getRegistry("", PORT);
+            Registry registry = TestLibrary.createRegistryOnUnusedPort();
+            int registryPort = TestLibrary.getRegistryPort(registry);
+            Registry reg = LocateRegistry.getRegistry("", registryPort);
             FooImpl fooimpl = new FooImpl();
             UnicastRemoteObject.exportObject(fooimpl, 0);
             reg.rebind("foo", fooimpl);
diff --git a/jdk/test/sun/rmi/runtime/Log/checkLogging/CheckLogStreams.java b/jdk/test/sun/rmi/runtime/Log/checkLogging/CheckLogStreams.java
index 34cfc48..1e95953 100644
--- a/jdk/test/sun/rmi/runtime/Log/checkLogging/CheckLogStreams.java
+++ b/jdk/test/sun/rmi/runtime/Log/checkLogging/CheckLogStreams.java
@@ -28,11 +28,7 @@
  * @author Laird Dornin
  *
  * @library ../../../../../java/rmi/testlibrary
- * @build TestLibrary
- * @build TestParams
- * @build TestFailedException
- * @build CheckLogging
- * @build CheckLogStreams
+ * @build TestLibrary CheckLogging
  * @run main/othervm -Dsun.rmi.log.useOld=true CheckLogStreams
  */
 
diff --git a/jdk/test/sun/rmi/runtime/Log/checkLogging/CheckLogging.java b/jdk/test/sun/rmi/runtime/Log/checkLogging/CheckLogging.java
index 7039c13..347725a 100644
--- a/jdk/test/sun/rmi/runtime/Log/checkLogging/CheckLogging.java
+++ b/jdk/test/sun/rmi/runtime/Log/checkLogging/CheckLogging.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -29,9 +29,6 @@
  *
  * @library ../../../../../java/rmi/testlibrary
  * @build TestLibrary
- * @build TestParams
- * @build TestFailedException
- * @build CheckLogging
  * @run main/othervm CheckLogging
  */
 
@@ -77,8 +74,9 @@
  * logger output is non-null.
  */
 public class CheckLogging {
-    private static final String LOCATION =
-        "rmi://localhost:" + TestLibrary.REGISTRY_PORT + "/";
+    private static int REGISTRY_PORT = -1;
+    private static String LOCATION;
+
     private static final ByteArrayOutputStream clientCallOut =
         new ByteArrayOutputStream();
 
@@ -100,7 +98,9 @@
     private static Registry registry;
     static {
         try {
-            registry = LocateRegistry.createRegistry(TestLibrary.REGISTRY_PORT);
+            registry = TestLibrary.createRegistryOnUnusedPort();
+            REGISTRY_PORT = TestLibrary.getRegistryPort(registry);
+            LOCATION = "rmi://localhost:" + REGISTRY_PORT + "/";
         } catch (Exception e) {
             TestLibrary.bomb("could not create registry");
         }
diff --git a/jdk/test/sun/rmi/server/MarshalOutputStream/marshalForeignStub/MarshalForeignStub.java b/jdk/test/sun/rmi/server/MarshalOutputStream/marshalForeignStub/MarshalForeignStub.java
index 165dfbe1..bf1eb11 100644
--- a/jdk/test/sun/rmi/server/MarshalOutputStream/marshalForeignStub/MarshalForeignStub.java
+++ b/jdk/test/sun/rmi/server/MarshalOutputStream/marshalForeignStub/MarshalForeignStub.java
@@ -31,11 +31,7 @@
  * @author Ann Wollrath
  *
  * @library ../../../../../java/rmi/testlibrary
- * @build TestLibrary
- * @build TestFailedException
- * @build MarshalForeignStub
- * @build Receiver
- * @build MarshalForeignStub_Stub
+ * @build TestLibrary Receiver MarshalForeignStub_Stub
  * @run main/othervm/policy=security.policy MarshalForeignStub
  */
 
diff --git a/jdk/test/sun/rmi/transport/proxy/EagerHttpFallback.java b/jdk/test/sun/rmi/transport/proxy/EagerHttpFallback.java
index 049ed1a..3879c66 100644
--- a/jdk/test/sun/rmi/transport/proxy/EagerHttpFallback.java
+++ b/jdk/test/sun/rmi/transport/proxy/EagerHttpFallback.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,9 @@
  * @bug 4290727
  * @summary Verify that ConnectException will trigger HTTP fallback if
  *          sun.rmi.transport.proxy.eagerHttpFallback system property is set.
+ *
+ * @library ../../../../java/rmi/testlibrary
+ * @build TestLibrary
  * @run main/othervm EagerHttpFallback
  */
 
@@ -33,8 +36,8 @@
 
 public class EagerHttpFallback {
 
-    static final int INITIAL_PORT = 7070;
-    static final int FALLBACK_PORT = 7071;
+    static final int INITIAL_PORT = TestLibrary.getUnusedRandomPort();
+    static final int FALLBACK_PORT = TestLibrary.getUnusedRandomPort();
 
     public static void main(String[] args) throws Exception {
         System.setProperty("http.proxyHost", "127.0.0.1");
diff --git a/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java b/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java
index 533c4aa..7bcd5a7 100644
--- a/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java
+++ b/jdk/test/sun/rmi/transport/tcp/DeadCachedConnection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,9 +25,7 @@
  * @bug 4094891
  * @summary unable to retry call if cached connection to server is used
  * @library ../../../../java/rmi/testlibrary
- * @build DeadCachedConnection
- * @build JavaVM
- * @build TestLibrary
+ * @build TestLibrary JavaVM
  * @run main/othervm DeadCachedConnection
  */
 
@@ -58,7 +56,7 @@
 import java.rmi.server.*;
 
 public class DeadCachedConnection {
-    static public final int regport = 17340;
+    static public final int regport = TestLibrary.getUnusedRandomPort();
 
     static public void main(String[] argv)
         throws Exception {
diff --git a/jdk/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java b/jdk/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java
index af41bf0..1624f68 100644
--- a/jdk/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java
+++ b/jdk/test/sun/rmi/transport/tcp/blockAccept/BlockAcceptTest.java
@@ -27,11 +27,8 @@
  * @summary RMI blocks in HttpAwareServerSocket.accept() if you telnet to it
  * @author Adrian Colley
  *
- * @library ../../../../../java/rmi/testlibrary/
- * @build TestIface
- * @build TestImpl
- * @build TestImpl_Stub
- * @build BlockAcceptTest
+ * @library ../../../../../java/rmi/testlibrary
+ * @build TestIface TestImpl TestImpl_Stub
  * @run main/othervm/policy=security.policy/timeout=60 BlockAcceptTest
  */
 
diff --git a/jdk/test/sun/rmi/transport/tcp/disableMultiplexing/DisableMultiplexing.java b/jdk/test/sun/rmi/transport/tcp/disableMultiplexing/DisableMultiplexing.java
index 51dbeec..805c798 100644
--- a/jdk/test/sun/rmi/transport/tcp/disableMultiplexing/DisableMultiplexing.java
+++ b/jdk/test/sun/rmi/transport/tcp/disableMultiplexing/DisableMultiplexing.java
@@ -28,7 +28,6 @@
  * on that port, rather than engage in the deprecated "multiplexing protocol".
  * @author Peter Jones
  *
- * @build DisableMultiplexing
  * @build DisableMultiplexing_Stub
  * @run main/othervm DisableMultiplexing
  */
diff --git a/jdk/test/sun/security/ec/TestEC.java b/jdk/test/sun/security/ec/TestEC.java
index 3c4a895..c23980d 100644
--- a/jdk/test/sun/security/ec/TestEC.java
+++ b/jdk/test/sun/security/ec/TestEC.java
@@ -28,11 +28,13 @@
  * @library ../pkcs11
  * @library ../pkcs11/ec
  * @library ../pkcs11/sslecc
+ * @library ../../../java/security/testlibrary
  * @compile -XDignore.symbol.file TestEC.java
  * @run main TestEC
  */
 
 import java.security.Provider;
+import java.security.Security;
 
 /*
  * Leverage the collection of EC tests used by PKCS11
@@ -51,6 +53,15 @@
 public class TestEC {
 
     public static void main(String[] args) throws Exception {
+        ProvidersSnapshot snapshot = ProvidersSnapshot.create();
+        try {
+            main0(args);
+        } finally {
+            snapshot.restore();
+        }
+    }
+
+    public static void main0(String[] args) throws Exception {
         Provider p = new sun.security.ec.SunEC();
         System.out.println("Running tests with " + p.getName() +
             " provider...\n");
@@ -67,6 +78,11 @@
         new TestECGenSpec().main(p);
         new ReadPKCS12().main(p);
         new ReadCertificates().main(p);
+
+        // ClientJSSEServerJSSE fails on Solaris 11 when both SunEC and
+        // SunPKCS11-Solaris providers are enabled.
+        // Workaround:
+        // Security.removeProvider("SunPKCS11-Solaris");
         new ClientJSSEServerJSSE().main(p);
 
         long stop = System.currentTimeMillis();
diff --git a/jdk/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java b/jdk/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java
index 998f50d..2dcedc4 100644
--- a/jdk/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java
+++ b/jdk/test/sun/security/jgss/spnego/NoSpnegoAsDefMech.java
@@ -36,7 +36,7 @@
     public static void main(String[] argv) throws Exception {
         System.setProperty("sun.security.jgss.mechanism", GSSUtil.GSS_SPNEGO_MECH_OID.toString());
         try {
-            GSSManager.getInstance().createName("service@host", GSSName.NT_HOSTBASED_SERVICE, new Oid("1.3.6.1.5.5.2"));
+            GSSManager.getInstance().createName("service@localhost", GSSName.NT_HOSTBASED_SERVICE, new Oid("1.3.6.1.5.5.2"));
         } catch (GSSException e) {
             // This is OK, for example, krb5.conf is missing or other problems
         }
diff --git a/jdk/test/sun/security/krb5/auto/BadKdc.java b/jdk/test/sun/security/krb5/auto/BadKdc.java
index 55a4d99..7a2ec47 100644
--- a/jdk/test/sun/security/krb5/auto/BadKdc.java
+++ b/jdk/test/sun/security/krb5/auto/BadKdc.java
@@ -67,7 +67,7 @@
      *       This is tough.
      *    c. Feed the KDC a UDP packet first. The current "solution".
      */
-    public static void go(int[]... expected)
+    public static void go(String... expected)
             throws Exception {
         try {
             go0(expected);
@@ -83,7 +83,7 @@
         }
     }
 
-    public static void go0(int[]... expected)
+    public static void go0(String... expected)
             throws Exception {
         System.setProperty("sun.security.krb5.debug", "true");
 
@@ -135,8 +135,9 @@
         return k;
     }
 
-    private static void test(int... expected) throws Exception {
+    private static void test(String expected) throws Exception {
         ByteArrayOutputStream bo = new ByteArrayOutputStream();
+        System.out.println("----------------- TEST -----------------");
         try {
             test0(bo, expected);
         } catch (Exception e) {
@@ -151,31 +152,34 @@
      * One round of test for max_retries and timeout.
      * @param expected the expected kdc# timeout kdc# timeout...
      */
-    private static void test0(ByteArrayOutputStream bo, int... expected)
+    private static void test0(ByteArrayOutputStream bo, String expected)
             throws Exception {
         PrintStream oldout = System.out;
+        boolean failed = false;
         System.setOut(new PrintStream(bo));
         try {
             Context.fromUserPass(OneKDC.USER, OneKDC.PASS, false);
+        } catch (Exception e) {
+            failed = true;
         } finally {
             System.setOut(oldout);
         }
 
         String[] lines = new String(bo.toByteArray()).split("\n");
-        System.out.println("----------------- TEST -----------------");
-        int count = 0;
+        StringBuilder sb = new StringBuilder();
         for (String line: lines) {
             Matcher m = re.matcher(line);
             if (m.find()) {
                 System.out.println(line);
-                if (Integer.parseInt(m.group(1)) != expected[count++] ||
-                        Integer.parseInt(m.group(2)) != expected[count++]) {
-                    throw new Exception("Fail here");
-                }
+                sb.append(m.group(1)).append(m.group(2));
             }
         }
-        if (count != expected.length) {
-            throw new Exception("Less rounds");
+        if (failed) sb.append('-');
+
+        String output = sb.toString();
+        System.out.println("Expected: " + expected + ", actual " + output);
+        if (!output.matches(expected)) {
+            throw new Exception("Does not match");
         }
     }
 }
diff --git a/jdk/test/sun/security/krb5/auto/BadKdc1.java b/jdk/test/sun/security/krb5/auto/BadKdc1.java
index a4f52b4..bc96d05 100644
--- a/jdk/test/sun/security/krb5/auto/BadKdc1.java
+++ b/jdk/test/sun/security/krb5/auto/BadKdc1.java
@@ -37,16 +37,16 @@
            throws Exception {
        Security.setProperty("krb5.kdc.bad.policy", "tryLess");
        BadKdc.go(
-               new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
-               // The above line means try kdc1 for 2 seconds, then kdc1
-               // for 2 seconds,..., finally kdc3 for 2 seconds.
-               new int[]{1,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
+               "121212222222(32){1,2}1222(32){1,2}", // 1 2
+               // The above line means try kdc1 for 2 seconds then kdc1
+               // for 2 seconds... finally kdc3 for 2 seconds.
+               "1222(32){1,2}1222(32){1,2}",    // 1 2
                // refresh
-               new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,2,2,3,2}, // 1, 2
-               // k3 off, k2 on
-               new int[]{1,2,2,2,1,2,2,2}, // 1
+               "121212222222(32){1,2}1222(32){1,2}",  // 1 2
+               // k3 off k2 on
+               "(122212(22){1,2}|1222323232-)", // 1
                // k1 on
-               new int[]{1,2,1,2}  // empty
+               "(12(12){1,2}|122232-)"  // empty
        );
    }
 }
diff --git a/jdk/test/sun/security/krb5/auto/BadKdc2.java b/jdk/test/sun/security/krb5/auto/BadKdc2.java
index 9a55642..26e001b 100644
--- a/jdk/test/sun/security/krb5/auto/BadKdc2.java
+++ b/jdk/test/sun/security/krb5/auto/BadKdc2.java
@@ -37,14 +37,14 @@
             throws Exception {
         Security.setProperty("krb5.kdc.bad.policy", "tryLess:2,1000");
         BadKdc.go(
-                new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
-                new int[]{1,1,1,1,2,1,2,1,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
+                "121212222222(32){1,2}11112121(32){1,2}", // 1 2
+                "11112121(32){1,2}11112121(32){1,2}", // 1 2
                 // refresh
-                new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,1,1,1,2,1,2,1,3,2}, // 1, 2
-                // k3 off, k2 on
-                new int[]{1,1,1,1,2,1,1,1,1,1,2,2}, // 1
+                "121212222222(32){1,2}11112121(32){1,2}", // 1 2
+                // k3 off k2 on
+                "1111(21){1,2}1111(22){1,2}", // 1
                 // k1 on
-                new int[]{1,1,1,2}  // empty
+                "(11){1,2}(12){1,2}"  // empty
         );
     }
 }
diff --git a/jdk/test/sun/security/krb5/auto/BadKdc3.java b/jdk/test/sun/security/krb5/auto/BadKdc3.java
index c9ce4db..8381602 100644
--- a/jdk/test/sun/security/krb5/auto/BadKdc3.java
+++ b/jdk/test/sun/security/krb5/auto/BadKdc3.java
@@ -37,14 +37,14 @@
             throws Exception {
         Security.setProperty("krb5.kdc.bad.policy", "tryLast");
         BadKdc.go(
-                new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,3,2}, // 1, 2
-                new int[]{3,2,3,2}, // 1, 2
+                "121212222222(32){2,4}", // 1 2
+                "(32){2,4}", // 1 2
                 // refresh
-                new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,3,2}, // 1, 2
-                // k3 off, k2 on
-                new int[]{3,2,3,2,3,2,1,2,1,2,1,2,2,2,2,2}, // 1, 3
+                "121212222222(32){2,4}", // 1 2
+                // k3 off k2 on
+                "323232121212(22){2,4}", // 1 3
                 // k1 on
-                new int[]{2,2,2,2}  // 1, 3
+                "(22){2,4}"  // 1 3
         );
     }
 }
diff --git a/jdk/test/sun/security/krb5/auto/BadKdc4.java b/jdk/test/sun/security/krb5/auto/BadKdc4.java
index eef77f2..bbd4047 100644
--- a/jdk/test/sun/security/krb5/auto/BadKdc4.java
+++ b/jdk/test/sun/security/krb5/auto/BadKdc4.java
@@ -37,14 +37,14 @@
             throws Exception {
         Security.setProperty("krb5.kdc.bad.policy", "");
         BadKdc.go(
-            new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
-            new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
+            "121212222222(32){1,2}121212222222(32){1,2}",
+            "121212222222(32){1,2}121212222222(32){1,2}",
             // refresh
-            new int[]{1,2,1,2,1,2,2,2,2,2,2,2,3,2,1,2,1,2,1,2,2,2,2,2,2,2,3,2},
-            // k3 off, k2 on
-            new int[]{1,2,1,2,1,2,2,2,1,2,1,2,1,2,2,2},
+            "121212222222(32){1,2}121212222222(32){1,2}",
+            // k3 off k2 on
+            "121212(22){1,2}121212(22){1,2}",
             // k1 on
-            new int[]{1,2,1,2}
+            "(12){2,4}"
         );
     }
 }
diff --git a/jdk/test/sun/security/krb5/auto/FileKeyTab.java b/jdk/test/sun/security/krb5/auto/FileKeyTab.java
new file mode 100644
index 0000000..a8e8377
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/FileKeyTab.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2012, 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 7152121
+ * @summary Krb5LoginModule no longer handles keyTabNames with "file:" prefix
+ * @compile -XDignore.symbol.file FileKeyTab.java
+ * @run main/othervm FileKeyTab
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import sun.security.jgss.GSSUtil;
+
+// The basic krb5 test skeleton you can copy from
+public class FileKeyTab {
+
+    public static void main(String[] args) throws Exception {
+        new OneKDC(null).writeJAASConf();
+        String ktab = new File(OneKDC.KTAB).getAbsolutePath().replace('\\', '/');
+        File f = new File(OneKDC.JAAS_CONF);
+        try (FileOutputStream fos = new FileOutputStream(f)) {
+            fos.write((
+                "server {\n" +
+                "    com.sun.security.auth.module.Krb5LoginModule required\n" +
+                "    principal=\"" + OneKDC.SERVER + "\"\n" +
+                "    useKeyTab=true\n" +
+                "    keyTab=\"file:" + ktab + "\"\n" +
+                "    storeKey=true;\n};\n"
+                ).getBytes());
+        }
+        Context.fromJAAS("server");
+    }
+}
diff --git a/jdk/test/sun/security/krb5/auto/UseCacheAndStoreKey.java b/jdk/test/sun/security/krb5/auto/UseCacheAndStoreKey.java
new file mode 100644
index 0000000..3769643
--- /dev/null
+++ b/jdk/test/sun/security/krb5/auto/UseCacheAndStoreKey.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2012, 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 7201053
+ * @summary Krb5LoginModule shows NPE when both useTicketCache and storeKey
+ *          are set to true
+ * @compile -XDignore.symbol.file UseCacheAndStoreKey.java
+ * @run main/othervm UseCacheAndStoreKey
+ */
+
+import java.io.FileOutputStream;
+import javax.security.auth.login.LoginException;
+
+// The basic krb5 test skeleton you can copy from
+public class UseCacheAndStoreKey {
+
+    public static void main(String[] args) throws Exception {
+
+        new OneKDC(null).writeJAASConf();
+
+        // KDC would save ccache for client
+        System.setProperty("test.kdc.save.ccache", "cache.here");
+        try (FileOutputStream fos = new FileOutputStream(OneKDC.JAAS_CONF)) {
+            fos.write((
+                "me {\n" +
+                "    com.sun.security.auth.module.Krb5LoginModule required\n" +
+                "    principal=\"" + OneKDC.USER + "\"\n" +
+                "    useTicketCache=true\n" +
+                "    ticketCache=cache.here\n" +
+                "    isInitiator=true\n" +
+                "    storeKey=true;\n};\n"
+                ).getBytes());
+        }
+
+        // The first login will use default callback and succeed
+        Context.fromJAAS("me");
+
+        // The second login uses ccache and won't be able to store the keys
+        try {
+            Context.fromJAAS("me");
+            throw new Exception("Should fail");
+        } catch (LoginException le) {
+            if (le.getMessage().indexOf("NullPointerException") >= 0
+                    || le.getCause() instanceof NullPointerException) {
+                throw new Exception("NPE");
+            }
+        }
+    }
+}
diff --git a/jdk/test/sun/security/krb5/ccache/EmptyCC.java b/jdk/test/sun/security/krb5/ccache/EmptyCC.java
new file mode 100644
index 0000000..a0cd759
--- /dev/null
+++ b/jdk/test/sun/security/krb5/ccache/EmptyCC.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright (c) 2012, 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 7158329
+ * @bug 8001208
+ * @summary NPE in sun.security.krb5.Credentials.acquireDefaultCreds()
+ * @compile -XDignore.symbol.file EmptyCC.java
+ * @run main EmptyCC tmpcc
+ * @run main EmptyCC FILE:tmpcc
+ */
+import java.io.File;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import sun.security.krb5.Credentials;
+import sun.security.krb5.PrincipalName;
+import sun.security.krb5.internal.ccache.CredentialsCache;
+
+public class EmptyCC {
+    public static void main(String[] args) throws Exception {
+        final PrincipalName pn = new PrincipalName("dummy@FOO.COM");
+        final String ccache = args[0];
+
+        if (args.length == 1) {
+            // Main process, write the ccache and launch sub process
+            CredentialsCache cache = CredentialsCache.create(pn, ccache);
+            cache.save();
+
+            // java -cp $test.classes EmptyCC readcc
+            ProcessBuilder pb = new ProcessBuilder(
+                    new File(new File(System.getProperty("java.home"), "bin"),
+                        "java").getPath(),
+                    "-cp",
+                    System.getProperty("test.classes"),
+                    "EmptyCC",
+                    ccache,
+                    "readcc"
+                    );
+
+            pb.environment().put("KRB5CCNAME", ccache);
+            pb.redirectErrorStream(true);
+
+            Process p = pb.start();
+            try (InputStream ins = p.getInputStream()) {
+                byte[] buf = new byte[8192];
+                int n;
+                while ((n = ins.read(buf)) > 0) {
+                    System.out.write(buf, 0, n);
+                }
+            }
+            if (p.waitFor() != 0) {
+                throw new Exception("Test failed");
+            }
+        } else {
+            // Sub process, read the ccache
+            String cc = System.getenv("KRB5CCNAME");
+            if (!cc.equals(ccache)) {
+                throw new Exception("env not set correctly");
+            }
+            // 8001208: Fix for KRB5CCNAME not complete
+            // Make sure the ccache is created with bare file name
+            if (CredentialsCache.getInstance() == null) {
+                throw new Exception("Cache not instantiated");
+            }
+            if (!new File("tmpcc").exists()) {
+                throw new Exception("File not found");
+            }
+            Credentials.acquireTGTFromCache(pn, null);
+        }
+    }
+}
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/jdk/test/sun/security/krb5/config/DNS.java
similarity index 61%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to jdk/test/sun/security/krb5/config/DNS.java
index 077886f..8c574be 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/jdk/test/sun/security/krb5/config/DNS.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,20 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+// See dns.sh.
+import sun.security.krb5.Config;
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
+public class DNS {
+    public static void main(String[] args) throws Exception {
+        System.setProperty("java.security.krb5.conf",
+                System.getProperty("test.src", ".") +"/nothing.conf");
+        Config config = Config.getInstance();
+        String kdcs = config.getKDCList("X");
+        if (!kdcs.equals("a.com.:88 b.com.:99") &&
+                !kdcs.equals("a.com. b.com.:99")) {
+            throw new Exception("Strange KDC: [" + kdcs + "]");
+        };
     }
 }
diff --git a/jdk/test/sun/security/krb5/config/NamingManager.java b/jdk/test/sun/security/krb5/config/NamingManager.java
new file mode 100644
index 0000000..47f4f41
--- /dev/null
+++ b/jdk/test/sun/security/krb5/config/NamingManager.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package javax.naming.spi;
+
+import com.sun.jndi.dns.DnsContext;
+import java.util.Hashtable;
+import javax.naming.Context;
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+
+/**
+ * A fake javax.naming.spi.NamingManager. It allows reading a DNS
+ * record without contacting a real server.
+ *
+ * See DNS.java and dns.sh.
+ */
+public class NamingManager {
+    NamingManager() {}
+    public static Context getURLContext(
+            String scheme, Hashtable<?,?> environment)
+            throws NamingException {
+        return new DnsContext("", null, new Hashtable<String,String>()) {
+            public Attributes getAttributes(String name, String[] attrIds)
+                    throws NamingException {
+                return new BasicAttributes() {
+                    public Attribute get(String attrID) {
+                        BasicAttribute ba  = new BasicAttribute(attrID);
+                        ba.add("1 1 99 b.com.");
+                        ba.add("0 0 88 a.com.");    // 2nd has higher priority
+                        return ba;
+                    }
+                };
+            }
+        };
+    }
+}
diff --git a/jdk/make/sun/rmi/rmi/mapfile-vers b/jdk/test/sun/security/krb5/config/dns.sh
similarity index 64%
copy from jdk/make/sun/rmi/rmi/mapfile-vers
copy to jdk/test/sun/security/krb5/config/dns.sh
index dc33402..5c85f8a 100644
--- a/jdk/make/sun/rmi/rmi/mapfile-vers
+++ b/jdk/test/sun/security/krb5/config/dns.sh
@@ -1,12 +1,10 @@
 #
-# Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2012, 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.
+# 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
@@ -23,11 +21,21 @@
 # questions.
 #
 
-# Define library interface.
+# @test
+# @bug 8002344
+# @summary Krb5LoginModule config class does not return proper KDC list from DNS
+#
 
-SUNWprivate_1.1 {
-	global:
-	    Java_sun_rmi_server_MarshalInputStream_latestUserDefinedLoader;
-	local:
-	    *;
-};
+if [ "${TESTJAVA}" = "" ] ; then
+  JAVAC_CMD=`which javac`
+  TESTJAVA=`dirname $JAVAC_CMD`/..
+fi
+
+if [ "${TESTSRC}" = "" ] ; then
+   TESTSRC="."
+fi
+
+$TESTJAVA/bin/javac -d . \
+        ${TESTSRC}/NamingManager.java ${TESTSRC}/DNS.java
+$TESTJAVA/bin/java -Xbootclasspath/p:. DNS
+
diff --git a/jdk/test/sun/security/pkcs11/PKCS11Test.java b/jdk/test/sun/security/pkcs11/PKCS11Test.java
index 820435c..fc0eae0 100644
--- a/jdk/test/sun/security/pkcs11/PKCS11Test.java
+++ b/jdk/test/sun/security/pkcs11/PKCS11Test.java
@@ -72,10 +72,33 @@
     }
 
     public static void main(PKCS11Test test) throws Exception {
-        System.out.println("Beginning test run " + test.getClass().getName() + "...");
-        testDefault(test);
-        testNSS(test);
-        testDeimos(test);
+        Provider[] oldProviders = Security.getProviders();
+        try {
+            System.out.println("Beginning test run " + test.getClass().getName() + "...");
+            testDefault(test);
+            testNSS(test);
+            testDeimos(test);
+        } finally {
+            Provider[] newProviders = Security.getProviders();
+            // Do not restore providers if nothing changed. This is especailly
+            // useful for ./Provider/Login.sh, where a SecurityManager exists.
+            if (oldProviders.length == newProviders.length) {
+                boolean found = false;
+                for (int i = 0; i<oldProviders.length; i++) {
+                    if (oldProviders[i] != newProviders[i]) {
+                        found = true;
+                        break;
+                    }
+                }
+                if (!found) return;
+            }
+            for (Provider p: newProviders) {
+                Security.removeProvider(p.getName());
+            }
+            for (Provider p: oldProviders) {
+                Security.addProvider(p);
+            }
+        }
     }
 
     public static void testDeimos(PKCS11Test test) throws Exception {
@@ -153,21 +176,21 @@
         return libdir;
     }
 
+    protected static void safeReload(String lib) throws Exception {
+        try {
+            System.load(lib);
+        } catch (UnsatisfiedLinkError e) {
+            if (e.getMessage().contains("already loaded")) {
+                return;
+            }
+        }
+    }
+
     static boolean loadNSPR(String libdir) throws Exception {
         // load NSS softoken dependencies in advance to avoid resolver issues
-        try {
-            System.load(libdir + System.mapLibraryName(NSPR_PREFIX + "nspr4"));
-        } catch (UnsatisfiedLinkError e) {
-            // GLIBC problem on older linux-amd64 machines
-            if (libdir.contains("linux-amd64")) {
-                System.out.println(e);
-                System.out.println("NSS does not work on this platform, skipping.");
-                return false;
-            }
-            throw e;
-        }
-        System.load(libdir + System.mapLibraryName(NSPR_PREFIX + "plc4"));
-        System.load(libdir + System.mapLibraryName(NSPR_PREFIX + "plds4"));
+        safeReload(libdir + System.mapLibraryName(NSPR_PREFIX + "nspr4"));
+        safeReload(libdir + System.mapLibraryName(NSPR_PREFIX + "plc4"));
+        safeReload(libdir + System.mapLibraryName(NSPR_PREFIX + "plds4"));
         return true;
     }
 
diff --git a/jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java b/jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java
index 3171dc1..a192d52 100644
--- a/jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java
+++ b/jdk/test/sun/security/pkcs11/Secmod/AddPrivateKey.java
@@ -27,6 +27,7 @@
  * @summary Test that the PKCS#11 KeyStore handles RSA, DSA, and EC keys
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm AddPrivateKey
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java b/jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java
index 363ca04..2b43c3b 100644
--- a/jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java
+++ b/jdk/test/sun/security/pkcs11/Secmod/AddTrustedCert.java
@@ -27,6 +27,7 @@
  * @summary make sure we can add a trusted cert to the NSS KeyStore module
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm AddTrustedCert
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/pkcs11/Secmod/Crypto.java b/jdk/test/sun/security/pkcs11/Secmod/Crypto.java
index acc0647..97085c3 100644
--- a/jdk/test/sun/security/pkcs11/Secmod/Crypto.java
+++ b/jdk/test/sun/security/pkcs11/Secmod/Crypto.java
@@ -27,6 +27,7 @@
  * @summary verify that NSS no-db mode works correctly
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm Crypto
  */
 
 import java.util.*;
diff --git a/jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java b/jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java
index 9cdf93a..ec130ac 100644
--- a/jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java
+++ b/jdk/test/sun/security/pkcs11/Secmod/GetPrivateKey.java
@@ -27,6 +27,7 @@
  * @summary make sure we can access the NSS softtoken KeyStore and use a private key
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm GetPrivateKey
  */
 
 import java.util.*;
diff --git a/jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java b/jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java
index 8efdc16..d302aad 100644
--- a/jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java
+++ b/jdk/test/sun/security/pkcs11/Secmod/JksSetPrivateKey.java
@@ -27,6 +27,7 @@
  * @summary store a NSS PKCS11 PrivateKeyEntry to JKS KeyStore throws confusing NPE
  * @author Wang Weijun
  * @library ..
+ * @run main/othervm JksSetPrivateKey
  */
 
 import java.util.*;
diff --git a/jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java b/jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java
index 4b0c80e..3d15b3f 100644
--- a/jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java
+++ b/jdk/test/sun/security/pkcs11/Secmod/TrustAnchors.java
@@ -27,6 +27,7 @@
  * @summary make sure we can access the NSS trust anchor module
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm TrustAnchors
  */
 
 import java.util.*;
diff --git a/jdk/test/sun/security/pkcs11/SecmodTest.java b/jdk/test/sun/security/pkcs11/SecmodTest.java
index 5f48e29..76f68da 100644
--- a/jdk/test/sun/security/pkcs11/SecmodTest.java
+++ b/jdk/test/sun/security/pkcs11/SecmodTest.java
@@ -44,8 +44,8 @@
         if (loadNSPR(LIBPATH) == false) {
             return false;
         }
-        System.load(LIBPATH + System.mapLibraryName("softokn3"));
-        System.load(LIBPATH + System.mapLibraryName("nssckbi"));
+        safeReload(LIBPATH + System.mapLibraryName("softokn3"));
+        safeReload(LIBPATH + System.mapLibraryName("nssckbi"));
 
         DBDIR = System.getProperty("test.classes", ".") + SEP + "tmpdb";
         System.setProperty("pkcs11test.nss.db", DBDIR);
diff --git a/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java b/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java
index 87109b2..2aa38a9 100644
--- a/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java
+++ b/jdk/test/sun/security/pkcs11/ec/ReadCertificates.java
@@ -28,6 +28,7 @@
  *   and verify their signatures
  * @author Andreas Sterbenz
  * @library ..
+ * @library ../../../../java/security/testlibrary
  */
 
 import java.io.*;
@@ -62,7 +63,7 @@
             System.out.println("Provider does not support ECDSA, skipping...");
             return;
         }
-        Security.insertProviderAt(p, 1);
+        Providers.setAt(p, 1);
 
         random = new SecureRandom();
         factory = CertificateFactory.getInstance("X.509");
diff --git a/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java b/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java
index f172e45..979783e 100644
--- a/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java
+++ b/jdk/test/sun/security/pkcs11/ec/ReadPKCS12.java
@@ -27,6 +27,7 @@
  * @summary Verify that we can parse ECPrivateKeys from PKCS#12 and use them
  * @author Andreas Sterbenz
  * @library ..
+ * @library ../../../../java/security/testlibrary
  */
 
 import java.io.*;
@@ -52,7 +53,7 @@
             System.out.println("Provider does not support ECDSA, skipping...");
             return;
         }
-        Security.insertProviderAt(p, 1);
+        Providers.setAt(p, 1);
 
         CertificateFactory factory = CertificateFactory.getInstance("X.509");
         try {
diff --git a/jdk/test/sun/security/pkcs11/ec/TestECDH.java b/jdk/test/sun/security/pkcs11/ec/TestECDH.java
index e48b01a..3182cff 100644
--- a/jdk/test/sun/security/pkcs11/ec/TestECDH.java
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDH.java
@@ -27,6 +27,7 @@
  * @summary Basic known answer test for ECDH
  * @author Andreas Sterbenz
  * @library ..
+ * @library ../../../../java/security/testlibrary
  */
 
 import java.io.*;
@@ -59,7 +60,7 @@
             System.out.println("Provider does not support ECDH, skipping");
             return;
         }
-        Security.insertProviderAt(p, 1);
+        Providers.setAt(p, 1);
 
         if (false) {
             KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", p);
diff --git a/jdk/test/sun/security/pkcs11/ec/TestECDSA.java b/jdk/test/sun/security/pkcs11/ec/TestECDSA.java
index a08fa4e..0514d1d 100644
--- a/jdk/test/sun/security/pkcs11/ec/TestECDSA.java
+++ b/jdk/test/sun/security/pkcs11/ec/TestECDSA.java
@@ -27,6 +27,7 @@
  * @summary basic test of SHA1withECDSA and NONEwithECDSA signing/verifying
  * @author Andreas Sterbenz
  * @library ..
+ * @library ../../../../java/security/testlibrary
  */
 
 import java.io.*;
@@ -115,7 +116,7 @@
             System.out.println("ECDSA not supported, skipping");
             return;
         }
-        Security.insertProviderAt(provider, 1);
+        Providers.setAt(provider, 1);
 
         if (false) {
             KeyPairGenerator kpg = KeyPairGenerator.getInstance("EC", provider);
diff --git a/jdk/test/sun/security/pkcs11/fips/CipherTest.java b/jdk/test/sun/security/pkcs11/fips/CipherTest.java
index 8dad4a7..0d9f8b3 100644
--- a/jdk/test/sun/security/pkcs11/fips/CipherTest.java
+++ b/jdk/test/sun/security/pkcs11/fips/CipherTest.java
@@ -394,47 +394,52 @@
 
     public static void main(PeerFactory peerFactory, KeyStore keyStore,
             String[] args) throws Exception {
+        SSLContext reservedSSLContext = SSLContext.getDefault();
+        try {
+            long time = System.currentTimeMillis();
+            String relPath;
+            if ((args != null) && (args.length > 0) && args[0].equals("sh")) {
+                relPath = pathToStoresSH;
+            } else {
+                relPath = pathToStores;
+            }
+            PATH = new File(System.getProperty("test.src", "."), relPath);
+            CipherTest.peerFactory = peerFactory;
+            System.out.print(
+                "Initializing test '" + peerFactory.getName() + "'...");
+//          secureRandom = new SecureRandom();
+//          secureRandom.nextInt();
+//          trustStore = readKeyStore(trustStoreFile);
+            CipherTest.keyStore = keyStore;
+//          keyStore = readKeyStore(keyStoreFile);
+            KeyManagerFactory keyFactory =
+                KeyManagerFactory.getInstance(
+                    KeyManagerFactory.getDefaultAlgorithm());
+            keyFactory.init(keyStore, "test12".toCharArray());
+            keyManager = (X509ExtendedKeyManager)keyFactory.getKeyManagers()[0];
 
-        long time = System.currentTimeMillis();
-        String relPath;
-        if ((args != null) && (args.length > 0) && args[0].equals("sh")) {
-            relPath = pathToStoresSH;
-        } else {
-            relPath = pathToStores;
+            TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
+            tmf.init(keyStore);
+            trustManager = (X509TrustManager)tmf.getTrustManagers()[0];
+
+//          trustManager = new AlwaysTrustManager();
+            SSLContext context = SSLContext.getInstance("TLS");
+            context.init(new KeyManager[] {keyManager},
+                    new TrustManager[] {trustManager}, null);
+            SSLContext.setDefault(context);
+
+            CipherTest cipherTest = new CipherTest(peerFactory);
+            Thread serverThread = new Thread(peerFactory.newServer(cipherTest),
+                "Server");
+            serverThread.setDaemon(true);
+            serverThread.start();
+            System.out.println("Done");
+            cipherTest.run();
+            time = System.currentTimeMillis() - time;
+            System.out.println("Done. (" + time + " ms)");
+        } finally {
+            SSLContext.setDefault(reservedSSLContext);
         }
-        PATH = new File(System.getProperty("test.src", "."), relPath);
-        CipherTest.peerFactory = peerFactory;
-        System.out.print(
-            "Initializing test '" + peerFactory.getName() + "'...");
-//      secureRandom = new SecureRandom();
-//      secureRandom.nextInt();
-//      trustStore = readKeyStore(trustStoreFile);
-        CipherTest.keyStore = keyStore;
-//      keyStore = readKeyStore(keyStoreFile);
-        KeyManagerFactory keyFactory =
-            KeyManagerFactory.getInstance(
-                KeyManagerFactory.getDefaultAlgorithm());
-        keyFactory.init(keyStore, "test12".toCharArray());
-        keyManager = (X509ExtendedKeyManager)keyFactory.getKeyManagers()[0];
-
-        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
-        tmf.init(keyStore);
-        trustManager = (X509TrustManager)tmf.getTrustManagers()[0];
-
-//      trustManager = new AlwaysTrustManager();
-        SSLContext context = SSLContext.getInstance("TLS");
-        context.init(new KeyManager[] {keyManager}, new TrustManager[] {trustManager}, null);
-        SSLContext.setDefault(context);
-
-        CipherTest cipherTest = new CipherTest(peerFactory);
-        Thread serverThread = new Thread(peerFactory.newServer(cipherTest),
-            "Server");
-        serverThread.setDaemon(true);
-        serverThread.start();
-        System.out.println("Done");
-        cipherTest.run();
-        time = System.currentTimeMillis() - time;
-        System.out.println("Done. (" + time + " ms)");
     }
 
     static abstract class PeerFactory {
diff --git a/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java b/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java
index 5362f59..d9119e2 100644
--- a/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java
+++ b/jdk/test/sun/security/pkcs11/fips/ClientJSSEServerJSSE.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,10 +25,11 @@
  * @test
  * @bug 6313675 6323647
  * @summary Verify that all ciphersuites work in FIPS mode
+ * @library ..
  * @ignore JSSE supported cipher suites are changed with CR 6916074,
  *     need to update this test case in JDK 7 soon
+ * @run main/othervm ClientJSSEServerJSSE
  * @author Andreas Sterbenz
- * @library ..
  */
 
 import java.security.*;
diff --git a/jdk/test/sun/security/pkcs11/fips/TrustManagerTest.java b/jdk/test/sun/security/pkcs11/fips/TrustManagerTest.java
index b476afc..81fba23 100644
--- a/jdk/test/sun/security/pkcs11/fips/TrustManagerTest.java
+++ b/jdk/test/sun/security/pkcs11/fips/TrustManagerTest.java
@@ -27,6 +27,7 @@
  * @summary Verify that the SunJSSE trustmanager works correctly in FIPS mode
  * @author Andreas Sterbenz
  * @library ..
+ * @run main/othervm TrustManagerTest
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java b/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java
index 02ec40c..188b94c 100644
--- a/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java
+++ b/jdk/test/sun/security/pkcs11/rsa/TestCACerts.java
@@ -48,32 +48,35 @@
     public void main(Provider p) throws Exception {
         long start = System.currentTimeMillis();
         Security.addProvider(p);
-        String PROVIDER = p.getName();
-        String javaHome = System.getProperty("java.home");
-        String caCerts = javaHome + SEP + "lib" + SEP + "security" + SEP + "cacerts";
-        InputStream in = new FileInputStream(caCerts);
-        KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
-        ks.load(in, null);
-        in.close();
-        for (Enumeration e = ks.aliases(); e.hasMoreElements(); ) {
-            String alias = (String)e.nextElement();
-            if (ks.isCertificateEntry(alias)) {
-                System.out.println("* Testing " + alias + "...");
-                X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
-                PublicKey key = cert.getPublicKey();
-                String alg = key.getAlgorithm();
-                if (alg.equals("RSA")) {
-                    System.out.println("Signature algorithm: " + cert.getSigAlgName());
-                    cert.verify(key, PROVIDER);
+        try {
+            String PROVIDER = p.getName();
+            String javaHome = System.getProperty("java.home");
+            String caCerts = javaHome + SEP + "lib" + SEP + "security" + SEP + "cacerts";
+            InputStream in = new FileInputStream(caCerts);
+            KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+            ks.load(in, null);
+            in.close();
+            for (Enumeration e = ks.aliases(); e.hasMoreElements(); ) {
+                String alias = (String)e.nextElement();
+                if (ks.isCertificateEntry(alias)) {
+                    System.out.println("* Testing " + alias + "...");
+                    X509Certificate cert = (X509Certificate)ks.getCertificate(alias);
+                    PublicKey key = cert.getPublicKey();
+                    String alg = key.getAlgorithm();
+                    if (alg.equals("RSA")) {
+                        System.out.println("Signature algorithm: " + cert.getSigAlgName());
+                        cert.verify(key, PROVIDER);
+                    } else {
+                        System.out.println("Skipping cert with key: " + alg);
+                    }
                 } else {
-                    System.out.println("Skipping cert with key: " + alg);
+                    System.out.println("Skipping alias " + alias);
                 }
-            } else {
-                System.out.println("Skipping alias " + alias);
             }
+            long stop = System.currentTimeMillis();
+            System.out.println("All tests passed (" + (stop - start) + " ms).");
+        } finally {
+            Security.removeProvider(p.getName());
         }
-        long stop = System.currentTimeMillis();
-        System.out.println("All tests passed (" + (stop - start) + " ms).");
     }
-
 }
diff --git a/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java b/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java
index 0f2c360..c940d56 100644
--- a/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java
+++ b/jdk/test/sun/security/pkcs11/sslecc/ClientJSSEServerJSSE.java
@@ -27,6 +27,7 @@
  * @summary Verify that all ciphersuites work (incl. ECC using NSS crypto)
  * @author Andreas Sterbenz
  * @library ..
+ * @library ../../../../java/security/testlibrary
  */
 
 import java.security.*;
@@ -45,7 +46,7 @@
             System.out.println("Provider does not support EC, skipping");
             return;
         }
-        Security.insertProviderAt(p, 1);
+        Providers.setAt(p, 1);
         CipherTest.main(new JSSEFactory(), cmdArgs);
         Security.removeProvider(p.getName());
     }
diff --git a/jdk/test/sun/security/pkcs12/PKCS12SameKeyId.java b/jdk/test/sun/security/pkcs12/PKCS12SameKeyId.java
index a7d5f51..0d06d73 100644
--- a/jdk/test/sun/security/pkcs12/PKCS12SameKeyId.java
+++ b/jdk/test/sun/security/pkcs12/PKCS12SameKeyId.java
@@ -86,7 +86,9 @@
 
         // Reads from JKS keystore and pre-calculate
         KeyStore ks = KeyStore.getInstance("jks");
-        ks.load(new FileInputStream(JKSFILE), PASSWORD);
+        try (FileInputStream fis = new FileInputStream(JKSFILE)) {
+            ks.load(fis, PASSWORD);
+        }
         for (int i=0; i<SIZE; i++) {
             aliases[i] = "p" + i;
             byte[] enckey = cipher.doFinal(
@@ -103,11 +105,15 @@
         for (int i=0; i<SIZE; i++) {
             p12.setKeyEntry(aliases[i], keys[i], certChains[i]);
         }
-        p12.store(new FileOutputStream(P12FILE), PASSWORD);
+        try (FileOutputStream fos = new FileOutputStream(P12FILE)) {
+            p12.store(fos, PASSWORD);
+        }
 
         // Check private keys still match certs
         p12 = KeyStore.getInstance("pkcs12");
-        p12.load(new FileInputStream(P12FILE), PASSWORD);
+        try (FileInputStream fis = new FileInputStream(P12FILE)) {
+            p12.load(fis, PASSWORD);
+        }
         for (int i=0; i<SIZE; i++) {
             String a = "p" + i;
             X509Certificate x = (X509Certificate)p12.getCertificate(a);
diff --git a/jdk/test/sun/security/provider/PolicyFile/Comparator.java b/jdk/test/sun/security/provider/PolicyFile/Comparator.java
index 1220aa6..41d8938 100644
--- a/jdk/test/sun/security/provider/PolicyFile/Comparator.java
+++ b/jdk/test/sun/security/provider/PolicyFile/Comparator.java
@@ -24,6 +24,7 @@
 /*
  * @test
  * @bug 5037004
+ * @run main/othervm Comparator
  * @summary Frivolous ClassCastExceptions thrown by SubjectCodeSource.implies
  *
  * Note:  if you want to see the java.security.debug output,
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/SSLSecurity/ProviderTest.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/SSLSecurity/ProviderTest.java
index 5246049..e0530ed 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/SSLSecurity/ProviderTest.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/SSLSecurity/ProviderTest.java
@@ -40,28 +40,32 @@
         TrustManagerFactory tmf;
         KeyManagerFactory kmf;
 
-        Security.addProvider(new MyProvider());
+        Provider extraProvider = new MyProvider();
+        Security.addProvider(extraProvider);
+        try {
+            System.out.println("getting a javax SSLContext");
+            sslc = SSLContext.getInstance("javax");
+            sslc.init(null, null, null);
+            System.out.println("\ngetting a com SSLContext");
+            sslc = SSLContext.getInstance("com");
+            sslc.init(null, null, null);
 
-        System.out.println("getting a javax SSLContext");
-        sslc = SSLContext.getInstance("javax");
-        sslc.init(null, null, null);
-        System.out.println("\ngetting a com SSLContext");
-        sslc = SSLContext.getInstance("com");
-        sslc.init(null, null, null);
+            System.out.println("\ngetting a javax TrustManagerFactory");
+            tmf = TrustManagerFactory.getInstance("javax");
+            tmf.init((KeyStore) null);
+            System.out.println("\ngetting a com TrustManagerFactory");
+            tmf = TrustManagerFactory.getInstance("com");
+            tmf.init((KeyStore) null);
 
-        System.out.println("\ngetting a javax TrustManagerFactory");
-        tmf = TrustManagerFactory.getInstance("javax");
-        tmf.init((KeyStore) null);
-        System.out.println("\ngetting a com TrustManagerFactory");
-        tmf = TrustManagerFactory.getInstance("com");
-        tmf.init((KeyStore) null);
-
-        System.out.println("\ngetting a javax KeyManagerFactory");
-        kmf = KeyManagerFactory.getInstance("javax");
-        kmf.init((KeyStore) null, null);
-        System.out.println("\ngetting a com KeyManagerFactory");
-        kmf = KeyManagerFactory.getInstance("com");
-        kmf.init((KeyStore) null, null);
+            System.out.println("\ngetting a javax KeyManagerFactory");
+            kmf = KeyManagerFactory.getInstance("javax");
+            kmf.init((KeyStore) null, null);
+            System.out.println("\ngetting a com KeyManagerFactory");
+            kmf = KeyManagerFactory.getInstance("com");
+            kmf.init((KeyStore) null, null);
+        } finally {
+            Security.removeProvider(extraProvider.getName());
+        }
     }
 }
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadBlocksClose.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadBlocksClose.java
index 38b4c84..a4604e2 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadBlocksClose.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadBlocksClose.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to
+// re-use system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4814140
  * @summary AppInputStream: read can block a close
+ * @run main/othervm ReadBlocksClose
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadHandshake.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadHandshake.java
index 7f44e8a..dec757d 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadHandshake.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadHandshake.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4514971
  * @summary Verify applications do not read handshake data after failure
+ * @run main/othervm ReadHandshake
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadZeroBytes.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadZeroBytes.java
index f08d7b4..545c658 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadZeroBytes.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/ReadZeroBytes.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6697270
  * @summary Inputstream dosent behave correct
+ * @run main/othervm ReadZeroBytes
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/RemoveMarkReset.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/RemoveMarkReset.java
index a402890..4bbc1d3 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/RemoveMarkReset.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppInputStream/RemoveMarkReset.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4413664
  * @summary remove mark/reset functionality from AppInputStream
+ * @run main/othervm RemoveMarkReset
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppOutputStream/NoExceptionOnClose.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppOutputStream/NoExceptionOnClose.java
index c4793b8..6e2b5bc 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppOutputStream/NoExceptionOnClose.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/AppOutputStream/NoExceptionOnClose.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test 1.3 01/03/08
  * @bug 4378397
  * @summary  JSSE socket output stream doesn't throw after socket is closed
+ * @run main/othervm NoExceptionOnClose
  * @author Jaya Hangal
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/CipherSuiteOrder.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/CipherSuiteOrder.java
index 0a221fe..f4bc04d 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/CipherSuiteOrder.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/CipherSuiteOrder.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test 1.3 01/03/08
  * @bug 4330535
  * @summary  Client should follow suite order in
  *           SSLSocket.setEnabledCipherSuites()
+ * @run main/othervm CipherSuiteOrder
  * @author Jaya Hangal
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/RSAExport.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/RSAExport.java
index 306ff18..447857b 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/RSAExport.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ClientHandshaker/RSAExport.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6690018
  * @summary RSAClientKeyExchange NullPointerException
+ * @run main/othervm RSAExport
  */
 
 /*
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java
index 432aed4..15b1845 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/GenSSLConfigs/main.java
@@ -5,8 +5,13 @@
  * @summary Make sure that different configurations of SSL sockets work
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
- * Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2012, 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
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/HandshakeOutStream/NullCerts.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/HandshakeOutStream/NullCerts.java
index 4cc63bc..23edf56 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/HandshakeOutStream/NullCerts.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/HandshakeOutStream/NullCerts.java
@@ -21,10 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4453053
- * @summary If a server shuts down correctly during handshaking, the client doesn't see it.
+ * @summary If a server shuts down correctly during handshaking, the client
+ *     doesn't see it.
+ * @run main/othervm NullCerts
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/ClientHelloRead.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/ClientHelloRead.java
index 169474f..4b3f5a7 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/ClientHelloRead.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/ClientHelloRead.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4432868
  * @summary A client-hello message may not always be read correctly
+ * @run main/othervm ClientHelloRead
  */
 
 import java.io.*;
@@ -154,23 +160,29 @@
          * we want to avoid URLspoofCheck failures in cases where the cert
          * DN name does not match the hostname in the URL.
          */
-        HttpsURLConnection.setDefaultHostnameVerifier(
-                                      new NameVerifier());
-        URL url = new URL("https://" + "localhost:" + serverPort
-                                + "/index.html");
-        BufferedReader in = null;
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            in = new BufferedReader(new InputStreamReader(
-                               url.openStream()));
-            String inputLine;
-            System.out.print("Client recieved from the server: ");
-            while ((inputLine = in.readLine()) != null)
-                System.out.println(inputLine);
-            in.close();
-        } catch (SSLException e) {
-            if (in != null)
+            HttpsURLConnection.setDefaultHostnameVerifier(
+                                          new NameVerifier());
+            URL url = new URL("https://" + "localhost:" + serverPort
+                                    + "/index.html");
+            BufferedReader in = null;
+            try {
+                in = new BufferedReader(new InputStreamReader(
+                                   url.openStream()));
+                String inputLine;
+                System.out.print("Client recieved from the server: ");
+                while ((inputLine = in.readLine()) != null)
+                    System.out.println(inputLine);
                 in.close();
-            throw e;
+            } catch (SSLException e) {
+                if (in != null)
+                    in.close();
+                throw e;
+            }
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/InterruptedIO.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/InterruptedIO.java
deleted file mode 100644
index e87ed35..0000000
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/InterruptedIO.java
+++ /dev/null
@@ -1,183 +0,0 @@
-/*
- * Copyright (c) 2001, 2003, 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 4393337
- * @summary [TEST RUNS ON SOLARIS ONLY] Throw an InterruptedIOException
- * when read on SSLSocket is * interrupted.
- */
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.io.InterruptedIOException;
-import java.net.Socket;
-import javax.net.ssl.*;
-
-/**
- * Interrupts an SSL socket that is blocked on a read. An
- * InterruptedIOException will be thrown and handled within the test if the
- * test completes correctly.
- */
-
-public class InterruptedIO {
-
-    /**
-     * Starts a client and a server thread. Gives the client enough time to
-     * block in a read, then interrupts it.
-     */
-    public static void main(String[] args) throws Exception {
-
-        String reason =
-            "Test valid only on SunOS.\n" +
-            "=========================\n" +
-            "It was determined that Thread.interrupt() could \n" +
-            "not be reliably return InterruptedIOException \n" +
-            "on non-Solaris implementations.  Thread.interrupt() \n" +
-            "API was updated in merlin (JDK 1.4) to reflect this.\n";
-        System.out.println(reason);
-
-        String osName = System.getProperty("os.name", "");
-        if (!osName.equalsIgnoreCase("SunOS")) {
-            System.out.println("Ignoring test on '" + osName + "'");
-            return;
-        }
-
-        String testRoot = System.getProperty("test.src", ".");
-        System.setProperty("javax.net.ssl.keyStore",
-                           testRoot +
-                           "/../../../../../../../etc/keystore");
-        System.setProperty("javax.net.ssl.keyStorePassword",
-                           "passphrase");
-        System.setProperty("javax.net.ssl.trustStore",
-                           testRoot +
-                           "/../../../../../../../etc/truststore");
-
-        Server server = new Server();
-        server.start();
-
-        Client client = new Client(server.getPort()); // Will do handshake
-        client.start(); // Will block in read
-
-        // sleep for 5 seconds
-        System.out.println("Main - Pausing for 5 seconds...");
-        Thread.sleep(5 * 1000);
-
-        System.out.println("Main - Interrupting client reader thread");
-        client.interrupt();
-        client.join(); // Wait for client thread to complete
-
-        if (client.failed())
-            throw new Exception("Main - Test InterruptedIO failed "
-                                + "on client side.");
-        else
-            System.out.println("Main - Test InterruptedIO successful!");
-    }
-
-    /**
-     * Accepts an incoming SSL Connection. Then blocks in a read.
-     */
-    static class Server extends Thread {
-
-        private SSLServerSocket ss;
-
-        public Server() throws Exception {
-            ss = (SSLServerSocket) SSLServerSocketFactory.getDefault().
-                createServerSocket(0);
-        }
-
-        public int getPort() {
-            return ss.getLocalPort();
-        }
-
-        public void run() {
-            try {
-                System.out.println("Server - Will accept connections on port "
-                                   + getPort());
-                Socket s = ss.accept();
-                InputStream is = s.getInputStream();
-                // We want the client to block so deadlock
-                is.read();
-            } catch (IOException e) {
-                // Happens when client closese connection.
-                // If an error occurs, Client will detect problem
-            }
-        }
-    }
-
-    /**
-     * Initiates an SSL connection to a server. Then blocks in a read. It
-     * should be interrupted by another thread. An InterruptedIOException
-     * is expected to be thrown.
-     */
-    static class Client extends Thread {
-
-        private SSLSocket socket;
-        private InputStream inStream;
-        private boolean failed = false;
-
-        public Client(int port) throws Exception {
-            socket = (SSLSocket) SSLSocketFactory.getDefault().
-                createSocket("localhost", port);
-            inStream = socket.getInputStream();
-            System.out.println("Client - "
-                               + "Connected to: localhost" + ":" + port);
-            System.out.println("Client - "
-                               + "Doing SSL Handshake...");
-            socket.startHandshake(); // Asynchronous call
-            System.out.println("Client - Done with SSL Handshake");
-        }
-
-        public void run() {
-
-            try {
-                System.out.println("Client - Reading from input stream ...");
-                if (inStream.read() == -1) {
-                    System.out.println("Client - End-of-stream detected");
-                    failed = true;
-                }
-            } catch (InterruptedIOException e) {
-                System.out.println("Client - "
-                                   + "As expected, InterruptedIOException "
-                                   + "was thrown. Message: "
-                                   + e.getMessage());
-            } catch (Exception e) {
-                System.out.println("Client - Unexpected exception:");
-                e.printStackTrace();
-                failed = true;
-            } finally {
-                try {
-                    socket.close();
-                } catch (IOException e) {
-                    // Squelch it
-                }
-            }
-        }
-
-        public boolean failed() {
-            return failed;
-        }
-
-    }
-
-}
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/SSLSocketTimeoutNulls.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/SSLSocketTimeoutNulls.java
index b881c38..4863e3e 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/SSLSocketTimeoutNulls.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/InputRecord/SSLSocketTimeoutNulls.java
@@ -21,13 +21,18 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4456039
  * @summary Setting timeouts on SSLSockets immediately return null
  *      after timeout occurs.  This bug was fixed as part of 4393337,
  *      but this is another bug we want to check regressions against.
- * @run main/timeout=140 SSLSocketTimeoutNulls
+ * @run main/othervm/timeout=140 SSLSocketTimeoutNulls
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ProtocolVersion/HttpsProtocols.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ProtocolVersion/HttpsProtocols.java
index c220c12..68f8341 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ProtocolVersion/HttpsProtocols.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ProtocolVersion/HttpsProtocols.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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
@@ -147,12 +147,18 @@
             Thread.sleep(50);
         }
 
-        HttpsURLConnection.setDefaultHostnameVerifier(this);
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
+        try {
+            HttpsURLConnection.setDefaultHostnameVerifier(this);
 
-        URL url = new URL("https://localhost:" + serverPort + "/");
-        HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
+            URL url = new URL("https://localhost:" + serverPort + "/");
+            HttpURLConnection urlc = (HttpURLConnection) url.openConnection();
 
-        System.out.println("response is " + urlc.getResponseCode());
+            System.out.println("response is " + urlc.getResponseCode());
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
+        }
     }
 
     public boolean verify(String hostname, SSLSession session) {
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/BadKSProvider.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/BadKSProvider.java
index ce9d70c..6edec53 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/BadKSProvider.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/BadKSProvider.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4919147
  * @summary Support for token-based KeyStores
+ * @run main/othervm BadKSProvider
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/BadTSProvider.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/BadTSProvider.java
index 2ae2ad1..429ed57 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/BadTSProvider.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/BadTSProvider.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4919147
  * @summary Support for token-based KeyStores
+ * @run main/othervm BadTSProvider
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/GoodProvider.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/GoodProvider.java
index 6473037..87d4d9e 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/GoodProvider.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLContextImpl/GoodProvider.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4919147
  * @summary Support for token-based KeyStores
+ * @run main/othervm GoodProvider
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
index 5ca0653..8d85b78 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/RehandshakeFinished.java
@@ -21,24 +21,31 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6207322
  * @summary SSLEngine is returning a premature FINISHED message when doing
  * an abbreviated handshake.
- *
+ * @run main/othervm RehandshakeFinished
+ * @author Brad Wetmore
+ */
+
+/*
  * This test may need some updating if the messages change order.
  * Currently I'm expecting that there is a simple renegotiation, with
  * each message being contained in a single SSL packet.
  *
- *      ClientHello
- *                              Server Hello
- *                              CCS
- *                              FINISHED
- *      CCS
- *      FINISHED
- *
- * @author Brad Wetmore
+ *     ClientHello
+ *                             Server Hello
+ *                             CCS
+ *                             FINISHED
+ *     CCS
+ *     FINISHED
  */
 
 /**
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineDeadlock.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineDeadlock.java
index 0e5e240..fb9d4f7 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineDeadlock.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLEngineImpl/SSLEngineDeadlock.java
@@ -21,11 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6492872
  * @summary Deadlock in SSLEngine
- *
+ * @run main/othervm SSLEngineDeadlock
  * @author Brad R. Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSessionImpl/HashCodeMissing.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSessionImpl/HashCodeMissing.java
index 60b5ea8..08bd696 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSessionImpl/HashCodeMissing.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSessionImpl/HashCodeMissing.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4910892
  * @summary 4518403 was not properly fixed.   hashcode should be hashCode.
+ * @run main/othervm HashCodeMissing
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java
index 93542c3..3cf2dd6 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/AsyncSSLSocketClose.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6447412
  * @summary Issue with socket.close() for ssl sockets when poweroff on
  *          other system
+ * @run main/othervm AsyncSSLSocketClose
  */
 
 import javax.net.ssl.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientModeClientAuth.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientModeClientAuth.java
index 11185af..d205378 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientModeClientAuth.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientModeClientAuth.java
@@ -21,11 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4390659
- * @run main/othervm -Djavax.net.debug=all ClientModeClientAuth
  * @summary setNeedClientAuth() isn't working after a handshaker is established
+ * @run main/othervm ClientModeClientAuth
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientTimeout.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientTimeout.java
index 652bbf9..c200fb2 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientTimeout.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ClientTimeout.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4836493
  * @summary Socket timeouts for SSLSockets causes data corruption.
+ * @run main/othervm ClientTimeout
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/CloseSocketException.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/CloseSocketException.java
index 8a70002..1c40ec9 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/CloseSocketException.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/CloseSocketException.java
@@ -21,16 +21,23 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4969799
  * @summary javax.net.ssl.SSLSocket.SSLSocket(InetAddress,int) shouldn't
  *              throw exception
- *
+ * @run main/othervm CloseSocketException
+ * @author Brad Wetmore
+ */
+
+/*
  * This is making sure that starting a new handshake throws the right
  * exception.  There is a similar test for SSLEngine.
- *
- * @author Brad Wetmore
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java
index 6954f84..2733d93 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/InvalidateServerSessionRenegotiate.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4403428
  * @summary Invalidating JSSE session on server causes SSLProtocolException
+ * @run main/othervm InvalidateServerSessionRenegotiate
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NewSocketMethods.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NewSocketMethods.java
index 2340ef0..8b94e4b 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NewSocketMethods.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NewSocketMethods.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4429176
  * @summary need to sync up SSL sockets with merlin java.net changes
+ * @run main/othervm NewSocketMethods
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NonAutoClose.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NonAutoClose.java
index 272db32..1556eb3 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NonAutoClose.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/NonAutoClose.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4404399
  * @summary When a layered SSL socket is closed, it should wait for close_notify
+ * @run main/othervm NonAutoClose
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ReuseAddr.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ReuseAddr.java
index 8008180..6efbc2e 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ReuseAddr.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ReuseAddr.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4482446
  * @summary java.net.SocketTimeoutException on 98, NT, 2000 for JSSE
+ * @run main/othervm ReuseAddr
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ReverseNameLookup.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ReverseNameLookup.java
index 6e9047c..64181f5 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ReverseNameLookup.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ReverseNameLookup.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4748292
  * @summary Prevent/Disable reverse name lookups with JSSE SSL sockets
+ * @run main/othervm ReverseNameLookup
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/SSLSocketImplThrowsWrongExceptions.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/SSLSocketImplThrowsWrongExceptions.java
index a1df6c0..01cdf9a 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/SSLSocketImplThrowsWrongExceptions.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/SSLSocketImplThrowsWrongExceptions.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4361124 4325806
  * @summary SSLServerSocket isn't throwing exceptions when negotiations are
  *      failing & java.net.SocketException: occures in Auth and clientmode
+ * @run main/othervm SSLSocketImplThrowsWrongExceptions
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ServerTimeout.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ServerTimeout.java
index cecf720..dbc6093 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ServerTimeout.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/ServerTimeout.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4836493
  * @summary Socket timeouts for SSLSockets causes data corruption.
+ * @run main/othervm ServerTimeout
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/SetClientMode.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/SetClientMode.java
index ff5bce1..8092798 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/SetClientMode.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/SetClientMode.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6223624
  * @summary SSLSocket.setUseClientMode() fails to throw expected
  *        IllegalArgumentException
+ * @run main/othervm SetClientMode
  */
 
 /*
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/UnconnectedSocketWrongExceptions.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/UnconnectedSocketWrongExceptions.java
index 4c26b24..4d50fdd 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/UnconnectedSocketWrongExceptions.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SSLSocketImpl/UnconnectedSocketWrongExceptions.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4480441
  * @summary startHandshake giving wrong message when unconnected.
+ * @run main/othervm UnconnectedSocketWrongExceptions
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java
index bf78b18..ee1f9b6 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ServerHandshaker/AnonCipherWithWantClientAuth.java
@@ -21,11 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4392475
  * @summary Calling setWantClientAuth(true) disables anonymous suites
- * @run main/timeout=180 AnonCipherWithWantClientAuth
+ * @run main/othervm/timeout=180 AnonCipherWithWantClientAuth
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ServerHandshaker/GetPeerHost.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ServerHandshaker/GetPeerHost.java
index c28f6c6..a70007d 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ServerHandshaker/GetPeerHost.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/ServerHandshaker/GetPeerHost.java
@@ -21,11 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /**
- *@test
- *@bug 4302026
- *@run main GetPeerHost
- *@summary make sure the server side doesn't do DNS lookup.
+ * @test
+ * @bug 4302026
+ * @run main/othervm GetPeerHost
+ * @summary make sure the server side doesn't do DNS lookup.
  */
 import javax.net.*;
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SocketCreation/SocketCreation.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SocketCreation/SocketCreation.java
index bf7b94d..e89c17c 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SocketCreation/SocketCreation.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/SocketCreation/SocketCreation.java
@@ -21,13 +21,18 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4414843
  * @summary This test tries all the different ways in which an SSL
  * connection can be established to exercise different SSLSocketImpl
  * constructors.
- * @run main/timeout=300 SocketCreation
+ * @run main/othervm/timeout=300 SocketCreation
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/CertRequestOverflow.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/CertRequestOverflow.java
new file mode 100644
index 0000000..883f979
--- /dev/null
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/CertRequestOverflow.java
@@ -0,0 +1,402 @@
+/*
+ * Copyright (c) 2012, 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.
+ */
+
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
+/*
+ * @test
+ * @bug 7200295
+ * @summary CertificateRequest message is wrapping when using large
+ *          numbers of Certs
+ * @run main/othervm CertRequestOverflow
+ */
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import javax.net.ssl.*;
+import java.security.cert.*;
+import java.security.*;
+
+public class CertRequestOverflow {
+
+    /*
+     * =============================================================
+     * Set the various variables needed for the tests, then
+     * specify what tests to run on each side.
+     */
+
+    /*
+     * Should we run the client or server in a separate thread?
+     * Both sides can throw exceptions, but do you have a preference
+     * as to which side should be the main thread.
+     */
+    static boolean separateServerThread = false;
+
+    /*
+     * Where do we find the keystores?
+     */
+    static String pathToStores = "../../../../../../../etc";
+    static String keyStoreFile = "keystore";
+    static String trustStoreFile = "truststore";
+    static String passwd = "passphrase";
+    private final static char[] cpasswd = "passphrase".toCharArray();
+
+    /*
+     * Is the server ready to serve?
+     */
+    volatile static boolean serverReady = false;
+
+    /*
+     * Turn on SSL debugging?
+     */
+    static boolean debug = false;
+
+    /*
+     * If the client or server is doing some kind of object creation
+     * that the other side depends on, and that thread prematurely
+     * exits, you may experience a hang.  The test harness will
+     * terminate all hung threads after its timeout has expired,
+     * currently 3 minutes by default, but you might try to be
+     * smart about it....
+     */
+
+    /*
+     * Define the server side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    void doServerSide() throws Exception {
+        SSLServerSocketFactory sslssf =
+                                getContext(true).getServerSocketFactory();
+        SSLServerSocket sslServerSocket =
+            (SSLServerSocket) sslssf.createServerSocket(serverPort);
+        serverPort = sslServerSocket.getLocalPort();
+
+        // enable endpoint identification
+        // ignore, we may test the feature when known how to parse client
+        // hostname
+        //SSLParameters params = sslServerSocket.getSSLParameters();
+        //params.setEndpointIdentificationAlgorithm("HTTPS");
+        //sslServerSocket.setSSLParameters(params);
+
+        /*
+         * Signal Client, we're ready for his connect.
+         */
+        serverReady = true;
+
+        SSLSocket sslSocket = (SSLSocket) sslServerSocket.accept();
+        sslSocket.setNeedClientAuth(true);
+        InputStream sslIS = sslSocket.getInputStream();
+        OutputStream sslOS = sslSocket.getOutputStream();
+
+        try {
+            sslIS.read();
+            sslOS.write(85);
+            sslOS.flush();
+
+            throw new Exception("SERVER TEST FAILED!  " +
+                        "It is expected to fail with field length overflow");
+        } catch (SSLException ssle) {
+            Throwable cause = ssle.getCause();
+            if (!(cause instanceof RuntimeException)) {
+                System.out.println("We are expecting a RuntimeException!");
+                throw ssle;
+            }
+            System.out.println("The expected exception!  " + ssle);
+        } finally {
+            sslSocket.close();
+        }
+
+        System.out.println("SERVER TEST PASSED!");
+    }
+
+    /*
+     * Define the client side of the test.
+     *
+     * If the server prematurely exits, serverReady will be set to true
+     * to avoid infinite hangs.
+     */
+    void doClientSide() throws Exception {
+
+        /*
+         * Wait for server to get started.
+         */
+        while (!serverReady) {
+            Thread.sleep(50);
+        }
+
+        SSLSocketFactory sslsf = getContext(false).getSocketFactory();
+        SSLSocket sslSocket = (SSLSocket)
+            sslsf.createSocket("localhost", serverPort);
+
+        // enable endpoint identification
+        SSLParameters params = sslSocket.getSSLParameters();
+        params.setEndpointIdentificationAlgorithm("HTTPS");
+        sslSocket.setSSLParameters(params);
+
+        InputStream sslIS = sslSocket.getInputStream();
+        OutputStream sslOS = sslSocket.getOutputStream();
+
+        try {
+            sslOS.write(280);
+            sslOS.flush();
+            sslIS.read();
+        } catch (SSLException ssle) {
+            System.out.println("An expected exception!");
+        } finally {
+            sslSocket.close();
+        }
+    }
+
+    MyExtendedX509TM serverTM;
+    MyExtendedX509TM clientTM;
+
+    private SSLContext getContext(boolean server) throws Exception {
+        String keyFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + keyStoreFile;
+        String trustFilename =
+            System.getProperty("test.src", "./") + "/" + pathToStores +
+                "/" + trustStoreFile;
+
+        KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
+        KeyStore ks = KeyStore.getInstance("JKS");
+        ks.load(new FileInputStream(keyFilename), cpasswd);
+        kmf.init(ks, cpasswd);
+
+        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
+        KeyStore ts = KeyStore.getInstance("JKS");
+        ts.load(new FileInputStream(trustFilename), cpasswd);
+        tmf.init(ts);
+
+        TrustManager tms[] = tmf.getTrustManagers();
+        if (tms == null || tms.length == 0) {
+            throw new Exception("unexpected trust manager implementation");
+        } else {
+           if (!(tms[0] instanceof X509TrustManager)) {
+            throw new Exception("unexpected trust manager implementation: "
+                                + tms[0].getClass().getCanonicalName());
+           }
+        }
+
+        if (server) {
+            serverTM = new MyExtendedX509TM((X509TrustManager)tms[0]);
+
+            tms = new TrustManager[] {serverTM};
+        } else {
+            clientTM = new MyExtendedX509TM((X509TrustManager)tms[0]);
+
+            tms = new TrustManager[] {clientTM};
+        }
+
+        SSLContext ctx = SSLContext.getInstance("TLS");
+        ctx.init(kmf.getKeyManagers(), tms, null);
+
+        return ctx;
+    }
+
+    static class MyExtendedX509TM extends X509ExtendedTrustManager
+            implements X509TrustManager {
+
+        X509TrustManager tm;
+
+        boolean clientChecked;
+        boolean serverChecked;
+
+        MyExtendedX509TM(X509TrustManager tm) {
+            clientChecked = false;
+            serverChecked = false;
+
+            this.tm = tm;
+        }
+
+        public boolean wasClientChecked() {
+            return clientChecked;
+        }
+
+        public boolean wasServerChecked() {
+            return serverChecked;
+        }
+
+
+        public void checkClientTrusted(X509Certificate chain[], String authType)
+                throws CertificateException {
+            tm.checkClientTrusted(chain, authType);
+        }
+
+        public void checkServerTrusted(X509Certificate chain[], String authType)
+                throws CertificateException {
+            tm.checkServerTrusted(chain, authType);
+        }
+
+        public X509Certificate[] getAcceptedIssuers() {
+            // (hack code) increase the size of the returned array to make a
+            // overflow CertificateRequest.
+            List<X509Certificate> issuersList = new LinkedList<>();
+            X509Certificate[] issuers = tm.getAcceptedIssuers();
+            for (int i = 0; i < 800; i += issuers.length) {
+                for (X509Certificate issuer : issuers) {
+                    issuersList.add(issuer);
+                }
+            }
+
+            return issuersList.toArray(issuers);
+        }
+
+        public void checkClientTrusted(X509Certificate[] chain, String authType,
+                Socket socket) throws CertificateException {
+            clientChecked = true;
+            tm.checkClientTrusted(chain, authType);
+        }
+
+        public void checkServerTrusted(X509Certificate[] chain, String authType,
+                Socket socket) throws CertificateException {
+            serverChecked = true;
+            tm.checkServerTrusted(chain, authType);
+        }
+
+        public void checkClientTrusted(X509Certificate[] chain, String authType,
+            SSLEngine engine) throws CertificateException {
+            clientChecked = true;
+            tm.checkClientTrusted(chain, authType);
+        }
+
+        public void checkServerTrusted(X509Certificate[] chain, String authType,
+            SSLEngine engine) throws CertificateException {
+            serverChecked = true;
+            tm.checkServerTrusted(chain, authType);
+        }
+    }
+
+    /*
+     * =============================================================
+     * The remainder is just support stuff
+     */
+
+    // use any free port by default
+    volatile int serverPort = 0;
+
+    volatile Exception serverException = null;
+    volatile Exception clientException = null;
+
+    public static void main(String[] args) throws Exception {
+
+        if (debug)
+            System.setProperty("javax.net.debug", "all");
+
+        /*
+         * Start the tests.
+         */
+        new CertRequestOverflow();
+    }
+
+    Thread clientThread = null;
+    Thread serverThread = null;
+
+    /*
+     * Primary constructor, used to drive remainder of the test.
+     *
+     * Fork off the other side, then do your work.
+     */
+    CertRequestOverflow() throws Exception {
+        if (separateServerThread) {
+            startServer(true);
+            startClient(false);
+        } else {
+            startClient(true);
+            startServer(false);
+        }
+
+        /*
+         * Wait for other side to close down.
+         */
+        if (separateServerThread) {
+            serverThread.join();
+        } else {
+            clientThread.join();
+        }
+
+        /*
+         * When we get here, the test is pretty much over.
+         *
+         * If the main thread excepted, that propagates back
+         * immediately.  If the other thread threw an exception, we
+         * should report back.
+         */
+        if (serverException != null)
+            throw serverException;
+        if (clientException != null)
+            throw clientException;
+    }
+
+    void startServer(boolean newThread) throws Exception {
+        if (newThread) {
+            serverThread = new Thread() {
+                public void run() {
+                    try {
+                        doServerSide();
+                    } catch (Exception e) {
+                        /*
+                         * Our server thread just died.
+                         *
+                         * Release the client, if not active already...
+                         */
+                        System.err.println("Server died...");
+                        serverReady = true;
+                        serverException = e;
+                    }
+                }
+            };
+            serverThread.start();
+        } else {
+            doServerSide();
+        }
+    }
+
+    void startClient(boolean newThread) throws Exception {
+        if (newThread) {
+            clientThread = new Thread() {
+                public void run() {
+                    try {
+                        doClientSide();
+                    } catch (Exception e) {
+                        /*
+              * Our client thread just died.
+                         */
+                        System.err.println("Client died...");
+                        clientException = e;
+                    }
+                }
+            };
+            clientThread.start();
+        } else {
+            doClientSide();
+        }
+    }
+}
+
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/ClientServer.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/ClientServer.java
index 1c2eb6b..c35a58c 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/ClientServer.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/ClientServer.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4717766
  * @summary 1.0.3 JsseX509TrustManager erroneously calls isClientTrusted()
+ * @run main/othervm ClientServer
  * @ignore JSSE supports algorithm constraints with CR 6916074,
  *     need to update this test case in JDK 7 soon
  * @author Brad Wetmore
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/PKIXExtendedTM.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/PKIXExtendedTM.java
index d29ef31..9edf17e 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/PKIXExtendedTM.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/PKIXExtendedTM.java
@@ -21,11 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
 
 /*
  * @test
  * @bug 6916074
  * @summary Add support for TLS 1.2
+ * @run main/othervm PKIXExtendedTM
  */
 
 import java.net.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SelfIssuedCert.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SelfIssuedCert.java
index 202237d..b3ae930 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SelfIssuedCert.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SelfIssuedCert.java
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6822460
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SunX509ExtendedTM.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SunX509ExtendedTM.java
index 19eb41a..8508228 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SunX509ExtendedTM.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/SunX509ExtendedTM.java
@@ -21,11 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6916074
- * @run main/othervm -Djavax.net.debug=all SunX509ExtendedTM
  * @summary Add support for TLS 1.2
+ * @run main/othervm SunX509ExtendedTM
  */
 
 import java.net.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java
index 5796abe..b2129ce 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/X509TrustManagerImpl/X509ExtendedTMEnabled.java
@@ -21,12 +21,18 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+// Ensure that the SunJSSE provider enables the X509ExtendedTrustManager.
+//
+
 /*
  * @test
  * @bug 6916074
  * @summary Add support for TLS 1.2
- *
- * Ensure that the SunJSSE provider enables the X509ExtendedTrustManager.
+ * @run main/othervm X509ExtendedTMEnabled
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/spi/ProviderInit.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/spi/ProviderInit.java
index 5840dc2..ab59c85 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/spi/ProviderInit.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/ssl/spi/ProviderInit.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test 1.3 01/03/08
  * @bug 4522550
  * @summary SSLContext TrustMananagerFactory and KeyManagerFactory
  *              should throw if not init
+ * @run main/othervm ProviderInit
  * @author Jaya Hangal
  */
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ProxyAuthTest.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ProxyAuthTest.java
index 13033fe..cec7ddc 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ProxyAuthTest.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ProxyAuthTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,7 +25,11 @@
  * @test
  * @bug 4323990 4413069
  * @summary HttpsURLConnection doesn't send Proxy-Authorization on CONNECT
- * Incorrect checking of proxy server response
+ *     Incorrect checking of proxy server response
+ * @run main/othervm ProxyAuthTest
+ *
+ *     No way to reserve and restore java.lang.Authenticator, need to run this
+ *     test in othervm mode.
  */
 
 import java.io.*;
@@ -77,8 +81,7 @@
     /*
      * Main method to create the server and the client
      */
-    public static void main(String args[]) throws Exception
-    {
+    public static void main(String args[]) throws Exception {
         String keyFilename =
             System.getProperty("test.src", "./") + "/" + pathToStores +
                 "/" + keyStoreFile;
@@ -110,10 +113,9 @@
         try {
             doClientSide();
         } catch (Exception e) {
-            System.out.println("Client side failed: " +
-                                e.getMessage());
+            System.out.println("Client side failed: " + e.getMessage());
             throw e;
-          }
+        }
     }
 
     private static ServerSocketFactory getServerSocketFactory
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ServerIdentityTest.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ServerIdentityTest.java
index 999591a..1e414e7 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ServerIdentityTest.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsClient/ServerIdentityTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4328195
  * @summary Need to include the alternate subject DN for certs,
  *          https should check for this
+ * @run main/othervm ServerIdentityTest
  * @author Yingxian Wang
  */
 
@@ -136,39 +142,45 @@
     volatile Exception clientException = null;
 
     public static void main(String[] args) throws Exception {
-        for (int i = 0; i < keyStoreFiles.length; i++) {
-            String keyFilename =
-                System.getProperty("test.src", ".") + "/" + pathToStores +
-                "/" + keyStoreFiles[i];
-            String trustFilename =
-                System.getProperty("test.src", ".") + "/" + pathToStores +
-                "/" + trustStoreFiles[i];
+        SSLSocketFactory reservedSFactory =
+                HttpsURLConnection.getDefaultSSLSocketFactory();
+        try {
+            for (int i = 0; i < keyStoreFiles.length; i++) {
+                String keyFilename =
+                    System.getProperty("test.src", ".") + "/" + pathToStores +
+                    "/" + keyStoreFiles[i];
+                String trustFilename =
+                    System.getProperty("test.src", ".") + "/" + pathToStores +
+                    "/" + trustStoreFiles[i];
 
-            System.setProperty("javax.net.ssl.keyStore", keyFilename);
-            System.setProperty("javax.net.ssl.keyStorePassword", passwd);
-            System.setProperty("javax.net.ssl.trustStore", trustFilename);
-            System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+                System.setProperty("javax.net.ssl.keyStore", keyFilename);
+                System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+                System.setProperty("javax.net.ssl.trustStore", trustFilename);
+                System.setProperty("javax.net.ssl.trustStorePassword", passwd);
 
-            if (debug)
-                System.setProperty("javax.net.debug", "all");
-            SSLContext context = SSLContext.getInstance("SSL");
+                if (debug)
+                    System.setProperty("javax.net.debug", "all");
+                SSLContext context = SSLContext.getInstance("SSL");
 
-            KeyManager[] kms = new KeyManager[1];
-            KeyStore ks = KeyStore.getInstance("JKS");
-            FileInputStream fis = new FileInputStream(keyFilename);
-            ks.load(fis, passwd.toCharArray());
-            fis.close();
-            KeyManager km = new MyKeyManager(ks, passwd.toCharArray());
-            kms[0] = km;
-            context.init(kms, null, null);
-            HttpsURLConnection.setDefaultSSLSocketFactory(
-                 context.getSocketFactory());
+                KeyManager[] kms = new KeyManager[1];
+                KeyStore ks = KeyStore.getInstance("JKS");
+                FileInputStream fis = new FileInputStream(keyFilename);
+                ks.load(fis, passwd.toCharArray());
+                fis.close();
+                KeyManager km = new MyKeyManager(ks, passwd.toCharArray());
+                kms[0] = km;
+                context.init(kms, null, null);
+                HttpsURLConnection.setDefaultSSLSocketFactory(
+                     context.getSocketFactory());
 
-            /*
-             * Start the tests.
-             */
-            System.out.println("Testing " + keyFilename);
-            new ServerIdentityTest(context, keyStoreFiles[i]);
+                /*
+                 * Start the tests.
+                 */
+                System.out.println("Testing " + keyFilename);
+                new ServerIdentityTest(context, keyStoreFiles[i]);
+            }
+        } finally {
+            HttpsURLConnection.setDefaultSSLSocketFactory(reservedSFactory);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java
index bb16d19..d852ced 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/CriticalSubjectAltName.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6668231
  * @summary Presence of a critical subjectAltName causes JSSE's SunX509 to
  *          fail trusted checks
+ * @run main/othervm CriticalSubjectAltName
  * @author Xuelei Fan
  *
  * This test depends on binary keystore, crisubn.jks and trusted.jks. Because
diff --git a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/GetResponseCode.java b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/GetResponseCode.java
index d50efae..ffce8af 100644
--- a/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/GetResponseCode.java
+++ b/jdk/test/sun/security/ssl/com/sun/net/ssl/internal/www/protocol/https/HttpsURLConnection/GetResponseCode.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4482187
  * @summary HttpsClient tests are failing for build 71
+ * @run main/othervm GetResponseCode
  * @author Yingxian Wang
  */
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/Fix5070632.java b/jdk/test/sun/security/ssl/javax/net/ssl/Fix5070632.java
index a3044af..f6a7206 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/Fix5070632.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/Fix5070632.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2012, 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
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 5070632
  * @summary Default SSLSockeFactory override createSocket() now
+ * @run main/othervm Fix5070632
  * @author Weijun Wang
  */
 
@@ -35,8 +41,13 @@
 
 public class Fix5070632 {
     public static void main(String[] args) throws Exception {
+        // reserve the security properties
+        String reservedSFacProvider =
+            Security.getProperty("ssl.SocketFactory.provider");
+
         // use a non-existing provider so that the DefaultSSLSocketFactory
         // will be used, and then test against it.
+
         Security.setProperty("ssl.SocketFactory.provider", "foo.NonExistant");
         SSLSocketFactory fac = (SSLSocketFactory)SSLSocketFactory.getDefault();
         try {
@@ -46,8 +57,16 @@
             System.out.println("Throw SocketException");
             se.printStackTrace();
             return;
+        } finally {
+            // restore the security properties
+            if (reservedSFacProvider == null) {
+                reservedSFacProvider = "";
+            }
+            Security.setProperty("ssl.SocketFactory.provider",
+                                                reservedSFacProvider);
         }
-        throw new Exception("should throw SocketException");
+
         // if not caught, or other exception caught, then it's error
+        throw new Exception("should throw SocketException");
     }
 }
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/ComURLNulls.java b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/ComURLNulls.java
index 3220f64..38bdc10 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/ComURLNulls.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/ComURLNulls.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -21,12 +21,18 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4387882 4451038
  * @summary Need to revisit the javadocs for JSSE, especially the
  *      promoted classes, and HttpsURLConnection.getCipherSuite throws
  *      NullPointerException
+ * @run main/othervm ComURLNulls
  * @author Brad Wetmore
  */
 
@@ -34,6 +40,7 @@
 import java.io.*;
 import javax.net.ssl.*;
 import com.sun.net.ssl.HttpsURLConnection;
+import com.sun.net.ssl.HostnameVerifier;
 
 /*
  * Tests that the com null argument changes made it in ok.
@@ -42,59 +49,64 @@
 public class ComURLNulls {
 
     public static void main(String[] args) throws Exception {
-
-        System.setProperty("java.protocol.handler.pkgs",
-                                "com.sun.net.ssl.internal.www.protocol");
-        /**
-         * This test does not establish any connection to the specified
-         * URL, hence a dummy URL is used.
-         */
-        URL foobar = new URL("https://example.com/");
-
-        HttpsURLConnection urlc =
-            (HttpsURLConnection) foobar.openConnection();
-
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            urlc.getCipherSuite();
-        } catch (IllegalStateException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            System.setProperty("java.protocol.handler.pkgs",
+                                    "com.sun.net.ssl.internal.www.protocol");
+            /**
+             * This test does not establish any connection to the specified
+             * URL, hence a dummy URL is used.
+             */
+            URL foobar = new URL("https://example.com/");
 
-        try {
-            urlc.getServerCertificateChain();
-        } catch (IllegalStateException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            HttpsURLConnection urlc =
+                (HttpsURLConnection) foobar.openConnection();
 
-        try {
-            urlc.setDefaultHostnameVerifier(null);
-        } catch (IllegalArgumentException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            try {
+                urlc.getCipherSuite();
+            } catch (IllegalStateException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
 
-        try {
-            urlc.setHostnameVerifier(null);
-        } catch (IllegalArgumentException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            try {
+                urlc.getServerCertificateChain();
+            } catch (IllegalStateException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
 
-        try {
-            urlc.setDefaultSSLSocketFactory(null);
-        } catch (IllegalArgumentException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            try {
+                urlc.setDefaultHostnameVerifier(null);
+            } catch (IllegalArgumentException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
 
-        try {
-            urlc.setSSLSocketFactory(null);
-        } catch (IllegalArgumentException e) {
-            System.out.print("Caught proper exception");
-            System.out.println(e.getMessage());
+            try {
+                urlc.setHostnameVerifier(null);
+            } catch (IllegalArgumentException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
+
+            try {
+                urlc.setDefaultSSLSocketFactory(null);
+            } catch (IllegalArgumentException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
+
+            try {
+                urlc.setSSLSocketFactory(null);
+            } catch (IllegalArgumentException e) {
+                System.out.print("Caught proper exception");
+                System.out.println(e.getMessage());
+            }
+            System.out.println("TESTS PASSED");
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
-        System.out.println("TESTS PASSED");
     }
 }
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/ImplicitHandshake.java b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/ImplicitHandshake.java
index deaf3a9..5253ad1 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/ImplicitHandshake.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/ImplicitHandshake.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4387882
  * @summary Need to revisit the javadocs for JSSE, especially the
  *      promoted classes.
+ * @run main/othervm ImplicitHandshake
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/JavaxURLNulls.java b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/JavaxURLNulls.java
index 7c32ff9..4e1cfe1 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/JavaxURLNulls.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/JavaxURLNulls.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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,63 +42,69 @@
 
     public static void main(String[] args) throws Exception {
 
-        /**
-         * This test does not establish any connection to the specified
-         * URL, hence a dummy URL is used.
-         */
-        URL foobar = new URL("https://example.com/");
-
-        HttpsURLConnection urlc =
-            (HttpsURLConnection) foobar.openConnection();
-
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            urlc.getCipherSuite();
-        } catch (IllegalStateException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            /**
+             * This test does not establish any connection to the specified
+             * URL, hence a dummy URL is used.
+             */
+            URL foobar = new URL("https://example.com/");
 
-        try {
-            urlc.getLocalCertificates();
-        } catch (IllegalStateException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            HttpsURLConnection urlc =
+                (HttpsURLConnection) foobar.openConnection();
 
-        try {
-            urlc.getServerCertificates();
-        } catch (IllegalStateException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            try {
+                urlc.getCipherSuite();
+            } catch (IllegalStateException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
 
-        try {
-            urlc.setDefaultHostnameVerifier(null);
-        } catch (IllegalArgumentException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            try {
+                urlc.getLocalCertificates();
+            } catch (IllegalStateException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
 
-        try {
-            urlc.setHostnameVerifier(null);
-        } catch (IllegalArgumentException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            try {
+                urlc.getServerCertificates();
+            } catch (IllegalStateException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
 
-        try {
-            urlc.setDefaultSSLSocketFactory(null);
-        } catch (IllegalArgumentException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
-        }
+            try {
+                urlc.setDefaultHostnameVerifier(null);
+            } catch (IllegalArgumentException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
 
-        try {
-            urlc.setSSLSocketFactory(null);
-        } catch (IllegalArgumentException e) {
-            System.out.print("Caught proper exception: ");
-            System.out.println(e.getMessage());
+            try {
+                urlc.setHostnameVerifier(null);
+            } catch (IllegalArgumentException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
+
+            try {
+                urlc.setDefaultSSLSocketFactory(null);
+            } catch (IllegalArgumentException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
+
+            try {
+                urlc.setSSLSocketFactory(null);
+            } catch (IllegalArgumentException e) {
+                System.out.print("Caught proper exception: ");
+                System.out.println(e.getMessage());
+            }
+            System.out.println("TESTS PASSED");
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
-        System.out.println("TESTS PASSED");
     }
 }
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/SSLSessionNulls.java b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/SSLSessionNulls.java
index 59a6005..9964cb3 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/SSLSessionNulls.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/SSLSessionNulls.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4387882
  * @summary Need to revisit the javadocs for JSSE, especially the
  *      promoted classes.
+ * @run main/othervm SSLSessionNulls
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/SSLSocketInherit.java b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/SSLSocketInherit.java
index 0b622ea..6fba98d 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/SSLSocketInherit.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/FixingJavadocs/SSLSocketInherit.java
@@ -21,12 +21,18 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4387882
  * @summary Need to revisit the javadocs for JSSE, especially the
  *      promoted classes.  This test checks to see if the settings
  *      on the server sockets get propagated to the sockets.
+ * @run main/othervm SSLSocketInherit
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/CheckMyTrustedKeystore.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/CheckMyTrustedKeystore.java
index 925be00..4d67e18 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/CheckMyTrustedKeystore.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/CheckMyTrustedKeystore.java
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4329114
  * @summary Need better way of reflecting the reason when a chain is
  *      rejected as untrusted.
+ * @run main/othervm CheckMyTrustedKeystore
  * @ignore JSSE supports algorithm constraints with CR 6916074,
  *     need to update this test case in JDK 7 soon
  * This is a serious hack job!
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/HttpsURLConnectionLocalCertificateChain.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/HttpsURLConnectionLocalCertificateChain.java
index e3548ee..e30f04f 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/HttpsURLConnectionLocalCertificateChain.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/HttpsURLConnectionLocalCertificateChain.java
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4395238 4354003 4387961 4395266
@@ -30,6 +35,7 @@
  *      Fixed 4354003: Need API to get client certificate chain
  *      Fixed 4387961: HostnameVerifier needs to pass various hostnames
  *      Fixed 4395266: HttpsURLConnection should be made protected
+ * @run main/othervm HttpsURLConnectionLocalCertificateChain
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java
index 8bf2f02..f871ed2 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/JSSERenegotiate.java
@@ -21,12 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4280338
  * @summary "Unsupported SSL message version" SSLProtocolException
  *      w/SSL_RSA_WITH_NULL_MD5
- *
+ * @run main/othervm JSSERenegotiate
  * @author Ram Marti
  * @author Brad Wetmore
  */
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/KeyManagerTrustManager.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/KeyManagerTrustManager.java
index 2226a0a..4927c73 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/KeyManagerTrustManager.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/KeyManagerTrustManager.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4387949 4302197 4396290 4395286
@@ -35,6 +40,7 @@
  * 4396290: Need a way to pass algorithm specific parameters to TM's and KM's
  * 4395286: The property for setting the default
  *      KeyManagerFactory/TrustManagerFactory algorithms needs real name
+ * @run main/othervm KeyManagerTrustManager
  * @author Brad Wetmore
  */
 
@@ -77,17 +83,40 @@
         String kmfAlg = null;
         String tmfAlg = null;
 
-        Security.setProperty("ssl.KeyManagerFactory.algorithm", "hello");
-        Security.setProperty("ssl.TrustManagerFactory.algorithm", "goodbye");
+        // reserve the security properties
+        String reservedKMFacAlg =
+            Security.getProperty("ssl.KeyManagerFactory.algorithm");
+        String reservedTMFacAlg =
+            Security.getProperty("ssl.TrustManagerFactory.algorithm");
 
-        kmfAlg = KeyManagerFactory.getDefaultAlgorithm();
-        tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
+        try {
+            Security.setProperty("ssl.KeyManagerFactory.algorithm", "hello");
+            Security.setProperty("ssl.TrustManagerFactory.algorithm",
+                                                                "goodbye");
 
-        if (!kmfAlg.equals("hello")) {
-            throw new Exception("ssl.KeyManagerFactory.algorithm not set");
-        }
-        if (!tmfAlg.equals("goodbye")) {
-            throw new Exception("ssl.TrustManagerFactory.algorithm not set");
+            kmfAlg = KeyManagerFactory.getDefaultAlgorithm();
+            tmfAlg = TrustManagerFactory.getDefaultAlgorithm();
+
+            if (!kmfAlg.equals("hello")) {
+                throw new Exception("ssl.KeyManagerFactory.algorithm not set");
+            }
+            if (!tmfAlg.equals("goodbye")) {
+                throw new Exception(
+                        "ssl.TrustManagerFactory.algorithm not set");
+            }
+        } finally {
+            // restore the security properties
+            if (reservedKMFacAlg == null) {
+                reservedKMFacAlg = "";
+            }
+
+            if (reservedTMFacAlg == null) {
+                reservedTMFacAlg = "";
+            }
+            Security.setProperty("ssl.KeyManagerFactory.algorithm",
+                                                            reservedKMFacAlg);
+            Security.setProperty("ssl.TrustManagerFactory.algorithm",
+                                                            reservedTMFacAlg);
         }
     }
 }
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLCtxAccessToSessCtx.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLCtxAccessToSessCtx.java
index 8ec01a9..9d113f1 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLCtxAccessToSessCtx.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLCtxAccessToSessCtx.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4473210
  * @summary SSLSessionContext should be accessible from SSLContext
+ * @run main/othervm SSLCtxAccessToSessCtx
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/AcceptLargeFragments.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/AcceptLargeFragments.java
index 468ca82..55f4f2c 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/AcceptLargeFragments.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/AcceptLargeFragments.java
@@ -21,17 +21,24 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6388456
  * @summary Need adjustable TLS max record size for interoperability
  *      with non-compliant stacks
- *
- * Check the system property "jsse.SSLEngine.acceptLargeFragments"
- *
+ * @run main/othervm AcceptLargeFragments
  * @author xuelei fan
  */
 
+/*
+ * Check the system property "jsse.SSLEngine.acceptLargeFragments"
+ */
+
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLSession;
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ExtendedKeySocket.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ExtendedKeySocket.java
index d255d28..fb30055 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ExtendedKeySocket.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/ExtendedKeySocket.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4981697
  * @summary Rework the X509KeyManager to avoid incompatibility issues
+ * @run main/othervm ExtendedKeySocket
  * @author Brad R. Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java
index a58e19a..5437318 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/LargePacket.java
@@ -21,13 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  *
  * @bug 6388456
  * @summary Need adjustable TLS max record size for interoperability
  *      with non-compliant
- *
  * @run main/othervm -Djsse.enableCBCProtection=false LargePacket
  *
  * @author Xuelei Fan
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java
index 44a3437..1551dd7 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SSLEngine/NoAuthClientAuth.java
@@ -21,11 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4495742
  * @summary Demonstrate SSLEngine switch from no client auth to client auth.
- *
+ * @run main/othervm NoAuthClientAuth
  * @author Brad R. Wetmore
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java
index 64b2f6d..d2a250c 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionCacheSizeTests.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug   4366807
  * @summary Need new APIs to get/set session timeout and session cache size.
+ * @run main/othervm SessionCacheSizeTests
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java
index fc918a7c..4474181 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/SessionTimeOutTests.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug   4366807
  * @summary Need new APIs to get/set session timeout and session cache size.
+ * @run main/othervm SessionTimeOutTests
  */
 
 import java.io.*;
@@ -207,7 +213,7 @@
                 timeout = sessCtx.getSessionTimeout();
                 System.out.println("timeout is changed to: " + timeout);
                 System.out.println();
-            }
+           }
         }
 
         // check the ids returned by the enumerator
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/testEnabledProtocols.java b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/testEnabledProtocols.java
index e7a5b23..87ef3d8 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/testEnabledProtocols.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/NewAPIs/testEnabledProtocols.java
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4416068 4478803 4479736
@@ -30,6 +35,7 @@
  *                  session
  *          4701722 protocol mismatch exceptions should be consistent between
  *                  SSLv3 and TLSv1
+ * @run main/othervm testEnabledProtocols
  * @author Ram Marti
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/SSLServerSocket/DefaultSSLServSocketFac.java b/jdk/test/sun/security/ssl/javax/net/ssl/SSLServerSocket/DefaultSSLServSocketFac.java
index 755cf67..d682550 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/SSLServerSocket/DefaultSSLServSocketFac.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/SSLServerSocket/DefaultSSLServSocketFac.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2007, 2012, 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
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /**
  * @test
  * @bug 6449579
  * @summary DefaultSSLServerSocketFactory does not override createServerSocket()
+ * @run main/othervm DefaultSSLServSocketFac
  */
 import java.security.Security;
 import javax.net.ServerSocketFactory;
@@ -33,6 +39,10 @@
 
 public class DefaultSSLServSocketFac {
     public static void main(String[] args) throws Exception {
+        // reserve the security properties
+        String reservedSSFacProvider =
+            Security.getProperty("ssl.ServerSocketFactory.provider");
+
         try {
             Security.setProperty("ssl.ServerSocketFactory.provider", "oops");
             ServerSocketFactory ssocketFactory =
@@ -44,6 +54,13 @@
                 throw e;
             }
             // get the expected exception
+        } finally {
+            // restore the security properties
+            if (reservedSSFacProvider == null) {
+                reservedSSFacProvider = "";
+            }
+            Security.setProperty("ssl.ServerSocketFactory.provider",
+                                                    reservedSSFacProvider);
         }
     }
 }
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/EmptyCertificateAuthorities.java b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/EmptyCertificateAuthorities.java
index 5afb004..905979c 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/EmptyCertificateAuthorities.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/EmptyCertificateAuthorities.java
@@ -23,12 +23,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4873188
  * @summary Support TLS 1.1
- * @run main/othervm -Djavax.net.debug=all EmptyCertificateAuthorities
- *
+ * @run main/othervm EmptyCertificateAuthorities
  * @author Xuelei Fan
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableBlockCipher.java b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableBlockCipher.java
index e3e30c6..576ce38 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableBlockCipher.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableBlockCipher.java
@@ -23,12 +23,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4873188
  * @summary Support TLS 1.1
- * @run main/othervm -Djavax.net.debug=all ExportableBlockCipher
- *
+ * @run main/othervm ExportableBlockCipher
  * @author Xuelei Fan
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableStreamCipher.java b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableStreamCipher.java
index 11d91fa..24c494d 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableStreamCipher.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/ExportableStreamCipher.java
@@ -23,12 +23,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4873188
  * @summary Support TLS 1.1
- * @run main/othervm -Djavax.net.debug=all ExportableStreamCipher
- *
+ * @run main/othervm ExportableStreamCipher
  * @author Xuelei Fan
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericBlockCipher.java b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericBlockCipher.java
index b56d3f1..394c388 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericBlockCipher.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericBlockCipher.java
@@ -23,12 +23,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4873188
  * @summary Support TLS 1.1
- * @run main/othervm -Djavax.net.debug=all GenericBlockCipher
- *
+ * @run main/othervm GenericBlockCipher
  * @author Xuelei Fan
  */
 
diff --git a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java
index f402ee1..05bb52f 100644
--- a/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java
+++ b/jdk/test/sun/security/ssl/javax/net/ssl/TLSv11/GenericStreamCipher.java
@@ -23,12 +23,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4873188
  * @summary Support TLS 1.1
- * @run main/othervm -Djavax.net.debug=all GenericStreamCipher
- *
+ * @run main/othervm GenericStreamCipher
  * @author Xuelei Fan
  */
 
diff --git a/jdk/test/sun/security/ssl/sanity/pluggability/CheckSSLContextExport.java b/jdk/test/sun/security/ssl/sanity/pluggability/CheckSSLContextExport.java
index f5292c9..3527c06 100644
--- a/jdk/test/sun/security/ssl/sanity/pluggability/CheckSSLContextExport.java
+++ b/jdk/test/sun/security/ssl/sanity/pluggability/CheckSSLContextExport.java
@@ -64,8 +64,8 @@
             default:
                 throw new Exception("Internal Test Error!");
             }
-            System.out.println("Testing with " + (standardCiphers ? "standard" : "custom") +
-                               " cipher suites");
+            System.out.println("Testing with " +
+                (standardCiphers ? "standard" : "custom") + " cipher suites");
             for (int j = 0; j < 4; j++) {
                 String clsName = null;
                 try {
@@ -107,11 +107,16 @@
 
     public static void main(String[] argv) throws Exception {
         String protocols[] = { "SSL", "TLS" };
-        Security.insertProviderAt(new CheckSSLContextExport(protocols), 1);
-        for (int i = 0; i < protocols.length; i++) {
-            System.out.println("Testing " + protocols[i] + "'s SSLContext");
-            test(protocols[i]);
+        Provider extraProvider = new CheckSSLContextExport(protocols);
+        Security.insertProviderAt(extraProvider, 1);
+        try {
+            for (int i = 0; i < protocols.length; i++) {
+                System.out.println("Testing " + protocols[i] + "'s SSLContext");
+                test(protocols[i]);
+            }
+            System.out.println("Test Passed");
+        } finally {
+            Security.removeProvider(extraProvider.getName());
         }
-        System.out.println("Test Passed");
     }
 }
diff --git a/jdk/test/sun/security/ssl/sanity/pluggability/CheckSockFacExport1.java b/jdk/test/sun/security/ssl/sanity/pluggability/CheckSockFacExport1.java
index 89ed727..a452d80 100644
--- a/jdk/test/sun/security/ssl/sanity/pluggability/CheckSockFacExport1.java
+++ b/jdk/test/sun/security/ssl/sanity/pluggability/CheckSockFacExport1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4635454 6208022
  * @summary Check pluggability of SSLSocketFactory and
  * SSLServerSocketFactory classes.
+ * @run main/othervm CheckSockFacExport1
  */
 
 import java.util.*;
@@ -37,36 +43,57 @@
 public class CheckSockFacExport1 {
 
     public static void main(String argv[]) throws Exception {
-        Security.setProperty("ssl.SocketFactory.provider",
-                             "MySSLSocketFacImpl");
-        MySSLSocketFacImpl.useCustomCipherSuites();
-        Security.setProperty("ssl.ServerSocketFactory.provider",
-            "MySSLServerSocketFacImpl");
-        MySSLServerSocketFacImpl.useCustomCipherSuites();
+        // reserve the security properties
+        String reservedSFacAlg =
+            Security.getProperty("ssl.SocketFactory.provider");
+        String reservedSSFacAlg =
+            Security.getProperty("ssl.ServerSocketFactory.provider");
 
-        String[] supportedCS = null;
-        for (int i = 0; i < 2; i++) {
-            switch (i) {
-            case 0:
-                System.out.println("Testing SSLSocketFactory:");
-                SSLSocketFactory sf = (SSLSocketFactory)
-                    SSLSocketFactory.getDefault();
-                supportedCS = sf.getSupportedCipherSuites();
-                break;
-            case 1:
-                System.out.println("Testing SSLServerSocketFactory:");
-                SSLServerSocketFactory ssf = (SSLServerSocketFactory)
-                    SSLServerSocketFactory.getDefault();
-                supportedCS = ssf.getSupportedCipherSuites();
-                break;
-            default:
-                throw new Exception("Internal Test Error");
+        try {
+            Security.setProperty("ssl.SocketFactory.provider",
+                                 "MySSLSocketFacImpl");
+            MySSLSocketFacImpl.useCustomCipherSuites();
+            Security.setProperty("ssl.ServerSocketFactory.provider",
+                "MySSLServerSocketFacImpl");
+            MySSLServerSocketFacImpl.useCustomCipherSuites();
+
+            String[] supportedCS = null;
+            for (int i = 0; i < 2; i++) {
+                switch (i) {
+                case 0:
+                    System.out.println("Testing SSLSocketFactory:");
+                    SSLSocketFactory sf = (SSLSocketFactory)
+                        SSLSocketFactory.getDefault();
+                    supportedCS = sf.getSupportedCipherSuites();
+                    break;
+                case 1:
+                    System.out.println("Testing SSLServerSocketFactory:");
+                    SSLServerSocketFactory ssf = (SSLServerSocketFactory)
+                        SSLServerSocketFactory.getDefault();
+                    supportedCS = ssf.getSupportedCipherSuites();
+                    break;
+                default:
+                    throw new Exception("Internal Test Error");
+                }
+                System.out.println(Arrays.asList(supportedCS));
+                if (supportedCS.length == 0) {
+                    throw new Exception("supported ciphersuites are empty");
+                }
             }
-            System.out.println(Arrays.asList(supportedCS));
-            if (supportedCS.length == 0) {
-                throw new Exception("supported ciphersuites are empty");
+            System.out.println("Test Passed");
+        } finally {
+            // restore the security properties
+            if (reservedSFacAlg == null) {
+                reservedSFacAlg = "";
             }
+
+            if (reservedSSFacAlg == null) {
+                reservedSSFacAlg = "";
+            }
+            Security.setProperty("ssl.SocketFactory.provider",
+                                                            reservedSFacAlg);
+            Security.setProperty("ssl.ServerSocketFactory.provider",
+                                                            reservedSSFacAlg);
         }
-        System.out.println("Test Passed");
     }
 }
diff --git a/jdk/test/sun/security/ssl/sanity/pluggability/CheckSockFacExport2.java b/jdk/test/sun/security/ssl/sanity/pluggability/CheckSockFacExport2.java
index d8c21e1..4f8b182 100644
--- a/jdk/test/sun/security/ssl/sanity/pluggability/CheckSockFacExport2.java
+++ b/jdk/test/sun/security/ssl/sanity/pluggability/CheckSockFacExport2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4635454
  * @summary Check pluggability of SSLSocketFactory and
- * SSLServerSocketFactory classes.
+ *     SSLServerSocketFactory classes.
+ * @run main/othervm CheckSockFacExport2
  */
 import java.security.*;
 import java.net.*;
@@ -34,38 +40,59 @@
 public class CheckSockFacExport2 {
 
     public static void main(String argv[]) throws Exception {
-        Security.setProperty("ssl.SocketFactory.provider",
-            "MySSLSocketFacImpl");
-        MySSLSocketFacImpl.useStandardCipherSuites();
-        Security.setProperty("ssl.ServerSocketFactory.provider",
-            "MySSLServerSocketFacImpl");
-        MySSLServerSocketFacImpl.useStandardCipherSuites();
+        // reserve the security properties
+        String reservedSFacAlg =
+            Security.getProperty("ssl.SocketFactory.provider");
+        String reservedSSFacAlg =
+            Security.getProperty("ssl.ServerSocketFactory.provider");
 
-        boolean result = false;
-        for (int i = 0; i < 2; i++) {
-            switch (i) {
-            case 0:
-                System.out.println("Testing SSLSocketFactory:");
-                SSLSocketFactory sf = (SSLSocketFactory)
-                    SSLSocketFactory.getDefault();
-                result = (sf instanceof MySSLSocketFacImpl);
-                break;
+        try {
+            Security.setProperty("ssl.SocketFactory.provider",
+                "MySSLSocketFacImpl");
+            MySSLSocketFacImpl.useStandardCipherSuites();
+            Security.setProperty("ssl.ServerSocketFactory.provider",
+                "MySSLServerSocketFacImpl");
+            MySSLServerSocketFacImpl.useStandardCipherSuites();
 
-            case 1:
-                System.out.println("Testing SSLServerSocketFactory:");
-                SSLServerSocketFactory ssf = (SSLServerSocketFactory)
-                    SSLServerSocketFactory.getDefault();
-                result = (ssf instanceof MySSLServerSocketFacImpl);
-                break;
-            default:
-                throw new Exception("Internal Test Error");
+            boolean result = false;
+            for (int i = 0; i < 2; i++) {
+                switch (i) {
+                case 0:
+                    System.out.println("Testing SSLSocketFactory:");
+                    SSLSocketFactory sf = (SSLSocketFactory)
+                        SSLSocketFactory.getDefault();
+                    result = (sf instanceof MySSLSocketFacImpl);
+                    break;
+
+                case 1:
+                    System.out.println("Testing SSLServerSocketFactory:");
+                    SSLServerSocketFactory ssf = (SSLServerSocketFactory)
+                        SSLServerSocketFactory.getDefault();
+                    result = (ssf instanceof MySSLServerSocketFacImpl);
+                    break;
+                default:
+                    throw new Exception("Internal Test Error");
+                }
+                if (result) {
+                    System.out.println("...accepted valid SFs");
+                } else {
+                    throw new Exception("...wrong SF is used");
+                }
             }
-            if (result) {
-                System.out.println("...accepted valid SFs");
-            } else {
-                throw new Exception("...wrong SF is used");
+            System.out.println("Test Passed");
+        } finally {
+            // restore the security properties
+            if (reservedSFacAlg == null) {
+                reservedSFacAlg = "";
             }
+
+            if (reservedSSFacAlg == null) {
+                reservedSSFacAlg = "";
+            }
+            Security.setProperty("ssl.SocketFactory.provider",
+                                                            reservedSFacAlg);
+            Security.setProperty("ssl.ServerSocketFactory.provider",
+                                                            reservedSSFacAlg);
         }
-        System.out.println("Test Passed");
     }
 }
diff --git a/jdk/test/sun/security/ssl/sun/net/www/http/ChunkedOutputStream/Test.java b/jdk/test/sun/security/ssl/sun/net/www/http/ChunkedOutputStream/Test.java
index a093dba..5195fef 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/http/ChunkedOutputStream/Test.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/http/ChunkedOutputStream/Test.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2012, 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
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /**
  * @test
  * @bug 5026745
@@ -283,31 +288,37 @@
             System.getProperty("test.src", "./") + "/" + pathToStores +
                 "/" + trustStoreFile;
 
-        System.setProperty("javax.net.ssl.keyStore", keyFilename);
-        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
-        System.setProperty("javax.net.ssl.trustStore", trustFilename);
-        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
-        HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
-
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            server = new HttpServer (new Test(), 1, 10, 0);
-            System.out.println ("Server started: listening on port: " + server.getLocalPort());
-            // the test server doesn't support keep-alive yet
-            // test1("http://localhost:"+server.getLocalPort()+"/d0");
-            test1("https://localhost:"+server.getLocalPort()+"/d01");
-            test3("https://localhost:"+server.getLocalPort()+"/d3");
-            test4("https://localhost:"+server.getLocalPort()+"/d4");
-            test5("https://localhost:"+server.getLocalPort()+"/d5");
-            test6("https://localhost:"+server.getLocalPort()+"/d6");
-            test7("https://localhost:"+server.getLocalPort()+"/d7");
-            test8("https://localhost:"+server.getLocalPort()+"/d8");
-        } catch (Exception e) {
-            if (server != null) {
-                server.terminate();
+            System.setProperty("javax.net.ssl.keyStore", keyFilename);
+            System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+            System.setProperty("javax.net.ssl.trustStore", trustFilename);
+            System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+            HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+
+            try {
+                server = new HttpServer (new Test(), 1, 10, 0);
+                System.out.println ("Server started: listening on port: " + server.getLocalPort());
+                // the test server doesn't support keep-alive yet
+                // test1("http://localhost:"+server.getLocalPort()+"/d0");
+                test1("https://localhost:"+server.getLocalPort()+"/d01");
+                test3("https://localhost:"+server.getLocalPort()+"/d3");
+                test4("https://localhost:"+server.getLocalPort()+"/d4");
+                test5("https://localhost:"+server.getLocalPort()+"/d5");
+                test6("https://localhost:"+server.getLocalPort()+"/d6");
+                test7("https://localhost:"+server.getLocalPort()+"/d7");
+                test8("https://localhost:"+server.getLocalPort()+"/d8");
+            } catch (Exception e) {
+                if (server != null) {
+                    server.terminate();
+                }
+                throw e;
             }
-            throw e;
+            server.terminate();
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
-        server.terminate();
     }
 
     static class NameVerifier implements HostnameVerifier {
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java
index e2168cd..16737d8 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/B6216082.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2012, 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
@@ -21,14 +21,19 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6216082
  * @library ../../../httpstest/
  * @build HttpCallback HttpServer ClosedChannelList HttpTransaction TunnelProxy
- * @run main/othervm B6216082
  * @summary  Redirect problem with HttpsURLConnection using a proxy
-*/
+ * @run main/othervm B6216082
+ */
 
 import java.io.*;
 import java.net.*;
@@ -46,20 +51,27 @@
     static InetAddress firstNonLoAddress = null;
 
     public static void main(String[] args) throws Exception {
-        // XXX workaround for CNFE
-        Class.forName("java.nio.channels.ClosedByInterruptException");
-        setupEnv();
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
+        try {
+            // XXX workaround for CNFE
+            Class.forName("java.nio.channels.ClosedByInterruptException");
+            setupEnv();
 
-        startHttpServer();
+            startHttpServer();
 
-        // https.proxyPort can only be set after the TunnelProxy has been
-        // created as it will use an ephemeral port.
-        System.setProperty( "https.proxyPort", (new Integer(proxy.getLocalPort())).toString() );
+            // https.proxyPort can only be set after the TunnelProxy has been
+            // created as it will use an ephemeral port.
+            System.setProperty("https.proxyPort",
+                        (new Integer(proxy.getLocalPort())).toString() );
 
-        makeHttpCall();
+            makeHttpCall();
 
-        if (httpTrans.hasBadRequest) {
-            throw new RuntimeException("Test failed : bad http request");
+            if (httpTrans.hasBadRequest) {
+                throw new RuntimeException("Test failed : bad http request");
+            }
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java
index 48193b5..fc29b87 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CloseKeepAliveCached.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2008, 2012, 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
@@ -21,13 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6618387
  * @summary SSL client sessions do not close cleanly. A TCP reset occurs
  *      instead of a close_notify alert.
- * @run main/othervm -Djavax.net.debug=ssl CloseKeepAliveCached
- *
+ * @run main/othervm CloseKeepAliveCached
  * @ignore
  *    After run the test manually, at the end of the debug output,
  *    if "MainThread, called close()" found, the test passed. Otherwise,
@@ -140,13 +144,15 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-
         /*
          * Wait for server to get started.
          */
         while (!serverReady) {
             Thread.sleep(50);
         }
+
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
             HttpsURLConnection http = null;
 
@@ -180,6 +186,8 @@
             if (sslServerSocket != null)
                 sslServerSocket.close();
             throw ioex;
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHandlerTest.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHandlerTest.java
index 6663720..224ad61 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHandlerTest.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHandlerTest.java
@@ -21,9 +21,15 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /* @test
- * @summary Unit test for java.net.CookieHandler
  * @bug 4696506 4942650
+ * @summary Unit test for java.net.CookieHandler
+ * @run main/othervm CookieHandlerTest
  * @author Yingxian Wang
  */
 
@@ -182,26 +188,34 @@
             System.getProperty("test.src", "./") + "/" + pathToStores +
                 "/" + trustStoreFile;
 
-        System.setProperty("javax.net.ssl.keyStore", keyFilename);
-        System.setProperty("javax.net.ssl.keyStorePassword", passwd);
-        System.setProperty("javax.net.ssl.trustStore", trustFilename);
-        System.setProperty("javax.net.ssl.trustStorePassword", passwd);
+        CookieHandler reservedCookieHandler = CookieHandler.getDefault();
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
+        try {
+            System.setProperty("javax.net.ssl.keyStore", keyFilename);
+            System.setProperty("javax.net.ssl.keyStorePassword", passwd);
+            System.setProperty("javax.net.ssl.trustStore", trustFilename);
+            System.setProperty("javax.net.ssl.trustStorePassword", passwd);
 
-        if (debug)
-            System.setProperty("javax.net.debug", "all");
+            if (debug)
+                System.setProperty("javax.net.debug", "all");
 
-        /*
-         * Start the tests.
-         */
-        cookies = new HashMap<String, String>();
-        cookies.put("Cookie",
-              "$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"");
-        cookies.put("Set-Cookie2",
-          "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\"; " +
-          "$Path=\"/acme/ammo\"; Part_Number=\"Rocket_Launcher_0001\"; "+
-          "$Path=\"/acme\"");
-        CookieHandler.setDefault(new MyCookieHandler());
-        new CookieHandlerTest();
+            /*
+             * Start the tests.
+             */
+            cookies = new HashMap<String, String>();
+            cookies.put("Cookie",
+                "$Version=\"1\"; Customer=\"WILE_E_COYOTE\"; $Path=\"/acme\"");
+            cookies.put("Set-Cookie2",
+              "$Version=\"1\"; Part_Number=\"Riding_Rocket_0023\"; " +
+              "$Path=\"/acme/ammo\"; Part_Number=\"Rocket_Launcher_0001\"; "+
+              "$Path=\"/acme\"");
+            CookieHandler.setDefault(new MyCookieHandler());
+            new CookieHandlerTest();
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
+            CookieHandler.setDefault(reservedCookieHandler);
+        }
     }
 
     Thread clientThread = null;
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java
index 6996ca0..d563937 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/CookieHttpsClientTest.java
@@ -26,6 +26,7 @@
  * @bug 7129083
  * @summary Cookiemanager does not store cookies if url is read
  *          before setting cookiemanager
+ * @run main/othervm CookieHttpsClientTest
  */
 
 import java.net.CookieHandler;
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/DNSIdentities.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/DNSIdentities.java
index 68104f3..f0154c6 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/DNSIdentities.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/DNSIdentities.java
@@ -21,9 +21,15 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /* @test
- * @summary X509 certificate hostname checking is broken in JDK1.6.0_10
  * @bug 6766775
+ * @summary X509 certificate hostname checking is broken in JDK1.6.0_10
+ * @run main/othervm DNSIdentities
  * @author Xuelei Fan
  */
 
@@ -691,34 +697,39 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-        SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
-            clientModulus, clientPrivateExponent, passphrase);
-
-        SSLContext.setDefault(context);
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        HttpsURLConnection http = null;
-
-        /* establish http connection to server */
-        URL url = new URL("https://localhost:" + serverPort+"/");
-        System.out.println("url is "+url.toString());
-
+        SSLContext reservedSSLContext = SSLContext.getDefault();
         try {
-            http = (HttpsURLConnection)url.openConnection();
+            SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
+                clientModulus, clientPrivateExponent, passphrase);
 
-            int respCode = http.getResponseCode();
-            System.out.println("respCode = "+respCode);
-        } finally {
-            if (http != null) {
-                http.disconnect();
+            SSLContext.setDefault(context);
+
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
             }
-            closeReady = true;
+
+            HttpsURLConnection http = null;
+
+            /* establish http connection to server */
+            URL url = new URL("https://localhost:" + serverPort+"/");
+            System.out.println("url is "+url.toString());
+
+            try {
+                http = (HttpsURLConnection)url.openConnection();
+
+                int respCode = http.getResponseCode();
+                System.out.println("respCode = "+respCode);
+            } finally {
+                if (http != null) {
+                    http.disconnect();
+                }
+                closeReady = true;
+            }
+        } finally {
+            SSLContext.setDefault(reservedSSLContext);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java
index 39e7c132..19ed317 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsCreateSockTest.java
@@ -21,10 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /**
  * @test
  * @bug 6771432
- * @summary createSocket() - smpatch fails using 1.6.0_10 because of "Unconnected sockets not implemented"
+ * @summary createSocket() - smpatch fails using 1.6.0_10 because of
+ *     "Unconnected sockets not implemented"
+ * @run main/othervm HttpsCreateSockTest
  */
 
 import javax.net.SocketFactory;
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsPost.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsPost.java
index a7ac995..49a572c 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsPost.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsPost.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4423074
  * @summary Need to rebase all the duplicated classes from Merlin.
  *          This test will check out http POST
+ * @run main/othervm HttpsPost
  */
 
 import java.io.*;
@@ -140,34 +146,38 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        // Send HTTP POST request to server
-        URL url = new URL("https://localhost:"+serverPort);
-
-        HttpsURLConnection.setDefaultHostnameVerifier(
-                                      new NameVerifier());
-        HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
-        http.setDoOutput(true);
-
-        http.setRequestMethod("POST");
-        PrintStream ps = new PrintStream(http.getOutputStream());
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            ps.println(postMsg);
-            ps.flush();
-            if (http.getResponseCode() != 200) {
-                throw new RuntimeException("test Failed");
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
+            }
+
+            // Send HTTP POST request to server
+            URL url = new URL("https://localhost:"+serverPort);
+
+            HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+            HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
+            http.setDoOutput(true);
+
+            http.setRequestMethod("POST");
+            PrintStream ps = new PrintStream(http.getOutputStream());
+            try {
+                ps.println(postMsg);
+                ps.flush();
+                if (http.getResponseCode() != 200) {
+                    throw new RuntimeException("test Failed");
+                }
+            } finally {
+                ps.close();
+                http.disconnect();
+                closeReady = true;
             }
         } finally {
-            ps.close();
-            http.disconnect();
-            closeReady = true;
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsProxyStackOverflow.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsProxyStackOverflow.java
index e588bca..aae0964 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsProxyStackOverflow.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsProxyStackOverflow.java
@@ -21,10 +21,13 @@
  * questions.
  */
 
+// No way to reserve default Authenticator, need to run in othervm mode.
+
 /*
  * @test
  * @bug 6670868
  * @summary StackOverFlow with bad authenticated Proxy tunnels
+ * @run main/othervm HttpsProxyStackOverflow
  */
 
 import java.io.IOException;
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java
index 41ad61f..c79cd87 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/HttpsSocketFacTest.java
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 6614957
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java
index eac7383..6530f7b 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressDNSIdentities.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -21,9 +21,15 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /* @test
- * @summary X509 certificate hostname checking is broken in JDK1.6.0_10
  * @bug 6766775
+ * @summary X509 certificate hostname checking is broken in JDK1.6.0_10
+ * @run main/othervm IPAddressDNSIdentities
  * @author Xuelei Fan
  */
 
@@ -691,43 +697,48 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-        SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
-            clientModulus, clientPrivateExponent, passphrase);
-
-        SSLContext.setDefault(context);
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        HttpsURLConnection http = null;
-
-        /* establish http connection to server */
-        URL url = new URL("https://127.0.0.1:" + serverPort+"/");
-        System.out.println("url is "+url.toString());
-
+        SSLContext reservedSSLContext = SSLContext.getDefault();
         try {
-            http = (HttpsURLConnection)url.openConnection();
+            SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
+                clientModulus, clientPrivateExponent, passphrase);
 
-            int respCode = http.getResponseCode();
-            System.out.println("respCode = " + respCode);
+            SSLContext.setDefault(context);
 
-            throw new Exception("Unexpectly found subject alternative name " +
-                                "matching IP address");
-        } catch (SSLHandshakeException sslhe) {
-            // no subject alternative names matching IP address 127.0.0.1 found
-            // that's the expected exception, ignore it.
-        } catch (IOException ioe) {
-            // HttpsClient may throw IOE during checking URL spoofing,
-            // that's the expected exception, ignore it.
-        } finally {
-            if (http != null) {
-                http.disconnect();
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
             }
-            closeReady = true;
+
+            HttpsURLConnection http = null;
+
+            /* establish http connection to server */
+            URL url = new URL("https://127.0.0.1:" + serverPort+"/");
+            System.out.println("url is "+url.toString());
+
+            try {
+                http = (HttpsURLConnection)url.openConnection();
+
+                int respCode = http.getResponseCode();
+                System.out.println("respCode = " + respCode);
+
+                throw new Exception("Unexpectly found " +
+                        "subject alternative name matching IP address");
+            } catch (SSLHandshakeException sslhe) {
+                // no subject alternative names matching IP address 127.0.0.1
+                // found that's the expected exception, ignore it.
+            } catch (IOException ioe) {
+                // HttpsClient may throw IOE during checking URL spoofing,
+                // that's the expected exception, ignore it.
+            } finally {
+                if (http != null) {
+                    http.disconnect();
+                }
+                closeReady = true;
+            }
+        } finally {
+            SSLContext.setDefault(reservedSSLContext);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressIPIdentities.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressIPIdentities.java
index 1695233..511309d 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressIPIdentities.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPAddressIPIdentities.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -21,9 +21,15 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /* @test
  * @summary X509 certificate hostname checking is broken in JDK1.6.0_10
  * @bug 6766775
+ * @run main/othervm IPAddressIPIdentities
  * @author Xuelei Fan
  */
 
@@ -692,34 +698,39 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-        SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
-            clientModulus, clientPrivateExponent, passphrase);
-
-        SSLContext.setDefault(context);
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        HttpsURLConnection http = null;
-
-        /* establish http connection to server */
-        URL url = new URL("https://127.0.0.1:" + serverPort+"/");
-        System.out.println("url is "+url.toString());
-
+        SSLContext reservedSSLContext = SSLContext.getDefault();
         try {
-            http = (HttpsURLConnection)url.openConnection();
+            SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
+                clientModulus, clientPrivateExponent, passphrase);
 
-            int respCode = http.getResponseCode();
-            System.out.println("respCode = "+respCode);
-        } finally {
-            if (http != null) {
-                http.disconnect();
+            SSLContext.setDefault(context);
+
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
             }
-            closeReady = true;
+
+            HttpsURLConnection http = null;
+
+            /* establish http connection to server */
+            URL url = new URL("https://127.0.0.1:" + serverPort+"/");
+            System.out.println("url is "+url.toString());
+
+            try {
+                http = (HttpsURLConnection)url.openConnection();
+
+                int respCode = http.getResponseCode();
+                System.out.println("respCode = "+respCode);
+            } finally {
+                if (http != null) {
+                    http.disconnect();
+                }
+                closeReady = true;
+            }
+        } finally {
+            SSLContext.setDefault(reservedSSLContext);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPIdentities.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPIdentities.java
index 632fa15..ef4e263 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPIdentities.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/IPIdentities.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -21,9 +21,15 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /* @test
  * @summary X509 certificate hostname checking is broken in JDK1.6.0_10
  * @bug 6766775
+ * @run main/othervm IPIdentities
  * @author Xuelei Fan
  */
 
@@ -692,34 +698,38 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-        SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
-            clientModulus, clientPrivateExponent, passphrase);
-
-        SSLContext.setDefault(context);
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        HttpsURLConnection http = null;
-
-        /* establish http connection to server */
-        URL url = new URL("https://localhost:" + serverPort+"/");
-        System.out.println("url is "+url.toString());
-
+        SSLContext reservedSSLContext = SSLContext.getDefault();
         try {
-            http = (HttpsURLConnection)url.openConnection();
+            SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
+                clientModulus, clientPrivateExponent, passphrase);
+            SSLContext.setDefault(context);
 
-            int respCode = http.getResponseCode();
-            System.out.println("respCode = "+respCode);
-        } finally {
-            if (http != null) {
-                http.disconnect();
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
             }
-            closeReady = true;
+
+            HttpsURLConnection http = null;
+
+            /* establish http connection to server */
+            URL url = new URL("https://localhost:" + serverPort+"/");
+            System.out.println("url is "+url.toString());
+
+            try {
+                http = (HttpsURLConnection)url.openConnection();
+
+                int respCode = http.getResponseCode();
+                System.out.println("respCode = "+respCode);
+            } finally {
+                if (http != null) {
+                    http.disconnect();
+                }
+                closeReady = true;
+            }
+        } finally {
+            SSLContext.setDefault(reservedSSLContext);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Identities.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Identities.java
index 4992805..27fc99c 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Identities.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Identities.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -21,9 +21,15 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /* @test
- * @summary X509 certificate hostname checking is broken in JDK1.6.0_10
  * @bug 6766775
+ * @summary X509 certificate hostname checking is broken in JDK1.6.0_10
+ * @run main/othervm Identities
  * @author Xuelei Fan
  */
 
@@ -691,34 +697,39 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-        SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
-            clientModulus, clientPrivateExponent, passphrase);
-
-        SSLContext.setDefault(context);
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        HttpsURLConnection http = null;
-
-        /* establish http connection to server */
-        URL url = new URL("https://localhost:" + serverPort+"/");
-        System.out.println("url is "+url.toString());
-
+        SSLContext reservedSSLContext = SSLContext.getDefault();
         try {
-            http = (HttpsURLConnection)url.openConnection();
+            SSLContext context = getSSLContext(trusedCertStr, clientCertStr,
+                clientModulus, clientPrivateExponent, passphrase);
 
-            int respCode = http.getResponseCode();
-            System.out.println("respCode = "+respCode);
-        } finally {
-            if (http != null) {
-                http.disconnect();
+            SSLContext.setDefault(context);
+
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
             }
-            closeReady = true;
+
+            HttpsURLConnection http = null;
+
+            /* establish http connection to server */
+            URL url = new URL("https://localhost:" + serverPort+"/");
+            System.out.println("url is "+url.toString());
+
+            try {
+                http = (HttpsURLConnection)url.openConnection();
+
+                int respCode = http.getResponseCode();
+                System.out.println("respCode = "+respCode);
+            } finally {
+                if (http != null) {
+                    http.disconnect();
+                }
+                closeReady = true;
+            }
+        } finally {
+            SSLContext.setDefault(reservedSSLContext);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java
index 35031ca..565e366 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/PostThruProxy.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2005, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -147,44 +147,50 @@
     static String postMsg = "Testing HTTP post on a https server";
 
     static void doClientSide(String hostname) throws Exception {
-        /*
-         * setup up a proxy
-         */
-        setupProxy();
-
-        /*
-         * we want to avoid URLspoofCheck failures in cases where the cert
-         * DN name does not match the hostname in the URL.
-         */
-        HttpsURLConnection.setDefaultHostnameVerifier(
-                                      new NameVerifier());
-        URL url = new URL("https://" + hostname+ ":" + serverPort);
-
-        HttpsURLConnection https = (HttpsURLConnection)url.openConnection();
-        https.setDoOutput(true);
-        https.setRequestMethod("POST");
-        PrintStream ps = null;
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-           ps = new PrintStream(https.getOutputStream());
-           ps.println(postMsg);
-           ps.flush();
-           if (https.getResponseCode() != 200) {
-                throw new RuntimeException("test Failed");
-           }
-           ps.close();
+            /*
+             * setup up a proxy
+             */
+            setupProxy();
 
-           // clear the pipe
-           BufferedReader in = new BufferedReader(
-                                new InputStreamReader(
-                                https.getInputStream()));
-           String inputLine;
-           while ((inputLine = in.readLine()) != null)
-                System.out.println("Client received: " + inputLine);
-           in.close();
-        } catch (SSLException e) {
-            if (ps != null)
-                ps.close();
-            throw e;
+            /*
+             * we want to avoid URLspoofCheck failures in cases where the cert
+             * DN name does not match the hostname in the URL.
+             */
+            HttpsURLConnection.setDefaultHostnameVerifier(
+                                          new NameVerifier());
+            URL url = new URL("https://" + hostname+ ":" + serverPort);
+
+            HttpsURLConnection https = (HttpsURLConnection)url.openConnection();
+            https.setDoOutput(true);
+            https.setRequestMethod("POST");
+            PrintStream ps = null;
+            try {
+               ps = new PrintStream(https.getOutputStream());
+               ps.println(postMsg);
+               ps.flush();
+               if (https.getResponseCode() != 200) {
+                    throw new RuntimeException("test Failed");
+               }
+               ps.close();
+
+               // clear the pipe
+               BufferedReader in = new BufferedReader(
+                                    new InputStreamReader(
+                                    https.getInputStream()));
+               String inputLine;
+               while ((inputLine = in.readLine()) != null)
+                    System.out.println("Client received: " + inputLine);
+               in.close();
+            } catch (SSLException e) {
+                if (ps != null)
+                    ps.close();
+                throw e;
+            }
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java
index 413ca42..367d217 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/ReadTimeout.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -21,10 +21,18 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4811482 4700777 4905410
- * @summary sun.net.client.defaultConnectTimeout should work with HttpsURLConnection; HTTP client: Connect and read timeouts; Https needs to support new tiger features that went into http
+ * @summary sun.net.client.defaultConnectTimeout should work with
+ *     HttpsURLConnection; HTTP client: Connect and read timeouts;
+ *     Https needs to support new tiger features that went into http
+ * @run main/othervm ReadTimeout
  */
 
 import java.io.*;
@@ -143,44 +151,48 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-        HttpsURLConnection http = null;
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            URL url = new URL("https://localhost:"+serverPort);
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
+            }
+            HttpsURLConnection http = null;
+            try {
+                URL url = new URL("https://localhost:"+serverPort);
 
-            // set read timeout through system property
-            System.setProperty("sun.net.client.defaultReadTimeout", "2000");
-            HttpsURLConnection.setDefaultHostnameVerifier(
-                                      new NameVerifier());
-            http = (HttpsURLConnection)url.openConnection();
+                // set read timeout through system property
+                System.setProperty("sun.net.client.defaultReadTimeout", "2000");
+                HttpsURLConnection.setDefaultHostnameVerifier(
+                                          new NameVerifier());
+                http = (HttpsURLConnection)url.openConnection();
 
-            InputStream is = http.getInputStream ();
-        } catch (SocketTimeoutException stex) {
-            done();
-            http.disconnect();
+                InputStream is = http.getInputStream ();
+            } catch (SocketTimeoutException stex) {
+                done();
+                http.disconnect();
+            }
+
+            try {
+                URL url = new URL("https://localhost:"+serverPort);
+
+                HttpsURLConnection.setDefaultHostnameVerifier(
+                                          new NameVerifier());
+                http = (HttpsURLConnection)url.openConnection();
+                // set read timeout through API
+                http.setReadTimeout(2000);
+
+                InputStream is = http.getInputStream ();
+            } catch (SocketTimeoutException stex) {
+                done();
+                http.disconnect();
+            }
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
-
-        try {
-            URL url = new URL("https://localhost:"+serverPort);
-
-            HttpsURLConnection.setDefaultHostnameVerifier(
-                                      new NameVerifier());
-            http = (HttpsURLConnection)url.openConnection();
-            // set read timeout through API
-            http.setReadTimeout(2000);
-
-            InputStream is = http.getInputStream ();
-        } catch (SocketTimeoutException stex) {
-            done();
-            http.disconnect();
-        }
-
     }
 
     static class NameVerifier implements HostnameVerifier {
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java
index f2764ab..27585e4 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/Redirect.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -21,11 +21,17 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4423074
  * @summary Need to rebase all the duplicated classes from Merlin.
  *          This test will check out http POST
+ * @run main/othervm Redirect
  */
 
 import java.io.*;
@@ -139,28 +145,33 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        // Send HTTP POST request to server
-        URL url = new URL("https://localhost:"+serverPort);
-
-        HttpsURLConnection.setDefaultHostnameVerifier(
-                                      new NameVerifier());
-        HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            System.out.println("response header: "+http.getHeaderField(0));
-            if (http.getResponseCode() != 200) {
-                throw new RuntimeException("test Failed");
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
+            }
+
+            // Send HTTP POST request to server
+            URL url = new URL("https://localhost:"+serverPort);
+
+            HttpsURLConnection.setDefaultHostnameVerifier(
+                                          new NameVerifier());
+            HttpsURLConnection http = (HttpsURLConnection)url.openConnection();
+            try {
+                System.out.println("response header: "+http.getHeaderField(0));
+                if (http.getResponseCode() != 200) {
+                    throw new RuntimeException("test Failed");
+                }
+            } finally {
+                http.disconnect();
+                closeReady = true;
             }
         } finally {
-            http.disconnect();
-            closeReady = true;
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/RetryHttps.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/RetryHttps.java
index af7b908..d41d19d 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/RetryHttps.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/HttpsURLConnection/RetryHttps.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2012, 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
@@ -21,9 +21,15 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /* @test
- * @summary Https can not retry request
  * @bug 4799427
+ * @summary Https can not retry request
+ * @run main/othervm RetryHttps
  * @author Yingxian Wang
  */
 
@@ -129,36 +135,41 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-        HttpsURLConnection http = null;
-        /* establish http connection to server */
-        URL url = new URL("https://localhost:" + serverPort+"/file1");
-        System.out.println("url is "+url.toString());
-        HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
-        http = (HttpsURLConnection)url.openConnection();
-        int respCode = http.getResponseCode();
-        int cl = http.getContentLength();
-        InputStream is = http.getInputStream ();
-        int count = 0;
-        while (is.read() != -1 && count++ < cl);
-        System.out.println("respCode1 = "+respCode);
-        Thread.sleep(2000);
-        url = new URL("https://localhost:" + serverPort+"/file2");
-        http = (HttpsURLConnection)url.openConnection();
-        respCode = http.getResponseCode();
-        System.out.println("respCode2 = "+respCode);
-
-        } catch (IOException ioex) {
-            if (sslServerSocket != null)
-                sslServerSocket.close();
-            throw ioex;
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
+            }
+            try {
+                HttpsURLConnection http = null;
+                /* establish http connection to server */
+                URL url = new URL("https://localhost:" + serverPort+"/file1");
+                System.out.println("url is "+url.toString());
+                HttpsURLConnection.setDefaultHostnameVerifier(
+                                                        new NameVerifier());
+                http = (HttpsURLConnection)url.openConnection();
+                int respCode = http.getResponseCode();
+                int cl = http.getContentLength();
+                InputStream is = http.getInputStream ();
+                int count = 0;
+                while (is.read() != -1 && count++ < cl);
+                System.out.println("respCode1 = "+respCode);
+                Thread.sleep(2000);
+                url = new URL("https://localhost:" + serverPort+"/file2");
+                http = (HttpsURLConnection)url.openConnection();
+                respCode = http.getResponseCode();
+                System.out.println("respCode2 = "+respCode);
+            } catch (IOException ioex) {
+                if (sslServerSocket != null)
+                    sslServerSocket.close();
+                throw ioex;
+            }
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
     }
 
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHTTPSConnection.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHTTPSConnection.java
index 1a2fc3e..a55f3c3 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHTTPSConnection.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHTTPSConnection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4474255
  * @summary Can no longer obtain a com.sun.net.ssl.HttpsURLConnection
+ * @run main/othervm ComHTTPSConnection
  * @author Brad Wetmore
  */
 
@@ -198,44 +204,50 @@
             Thread.sleep(50);
         }
 
-        System.setProperty("java.protocol.handler.pkgs",
-            "com.sun.net.ssl.internal.www.protocol");
-        HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
-
-        URL url = new URL("https://" + "localhost:" + serverPort +
-                                "/etc/hosts");
-        URLConnection urlc = url.openConnection();
-
-        if (!(urlc instanceof com.sun.net.ssl.HttpsURLConnection)) {
-            throw new Exception(
-                "URLConnection ! instanceof " +
-                "com.sun.net.ssl.HttpsURLConnection");
-        }
-
-        BufferedReader in = null;
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            in = new BufferedReader(new InputStreamReader(
-                               urlc.getInputStream()));
-            String inputLine;
-            System.out.print("Client reading... ");
-            while ((inputLine = in.readLine()) != null)
-                System.out.println(inputLine);
+            System.setProperty("java.protocol.handler.pkgs",
+                "com.sun.net.ssl.internal.www.protocol");
+            HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
 
-            System.out.println("Cipher Suite: " +
-                ((HttpsURLConnection)urlc).getCipherSuite());
-            X509Certificate[] certs =
-                ((HttpsURLConnection)urlc).getServerCertificateChain();
-            for (int i = 0; i < certs.length; i++) {
-                System.out.println(certs[0]);
+            URL url = new URL("https://" + "localhost:" + serverPort +
+                                    "/etc/hosts");
+            URLConnection urlc = url.openConnection();
+
+            if (!(urlc instanceof com.sun.net.ssl.HttpsURLConnection)) {
+                throw new Exception(
+                    "URLConnection ! instanceof " +
+                    "com.sun.net.ssl.HttpsURLConnection");
             }
 
-            in.close();
-        } catch (SSLException e) {
-            if (in != null)
+            BufferedReader in = null;
+            try {
+                in = new BufferedReader(new InputStreamReader(
+                                   urlc.getInputStream()));
+                String inputLine;
+                System.out.print("Client reading... ");
+                while ((inputLine = in.readLine()) != null)
+                    System.out.println(inputLine);
+
+                System.out.println("Cipher Suite: " +
+                    ((HttpsURLConnection)urlc).getCipherSuite());
+                X509Certificate[] certs =
+                    ((HttpsURLConnection)urlc).getServerCertificateChain();
+                for (int i = 0; i < certs.length; i++) {
+                    System.out.println(certs[0]);
+                }
+
                 in.close();
-            throw e;
+            } catch (SSLException e) {
+                if (in != null)
+                    in.close();
+                throw e;
+            }
+            System.out.println("Client reports:  SUCCESS");
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
-        System.out.println("Client reports:  SUCCESS");
     }
 
     static class NameVerifier implements HostnameVerifier {
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java
index 2122bd2..19549e7 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/ComHostnameVerifier.java
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4474255
@@ -28,6 +33,7 @@
  * @bug 4484246
  * @summary When an application enables anonymous SSL cipher suite,
  *        Hostname verification is not required
+ * @run main/othervm ComHostnameVerifier
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHTTPSConnection.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHTTPSConnection.java
index a547943..f3b8926 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHTTPSConnection.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHTTPSConnection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2012, 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
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4474255
  * @summary Can no longer obtain a com.sun.net.ssl.HttpsURLConnection
+ * @run main/othervm JavaxHTTPSConnection
  * @author Brad Wetmore
  */
 
@@ -189,47 +195,53 @@
      * to avoid infinite hangs.
      */
     void doClientSide() throws Exception {
-        /*
-         * Wait for server to get started.
-         */
-        while (!serverReady) {
-            Thread.sleep(50);
-        }
-
-        HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
-        URL url = new URL("https://" + "localhost:" + serverPort +
-                                "/etc/hosts");
-        URLConnection urlc = url.openConnection();
-
-        if (!(urlc instanceof javax.net.ssl.HttpsURLConnection)) {
-            throw new Exception(
-                "URLConnection ! instanceof javax.net.ssl.HttpsURLConnection");
-        }
-
-        BufferedReader in = null;
+        HostnameVerifier reservedHV =
+            HttpsURLConnection.getDefaultHostnameVerifier();
         try {
-            in = new BufferedReader(new InputStreamReader(
-                               urlc.getInputStream()));
-            String inputLine;
-            System.out.print("Client reading... ");
-            while ((inputLine = in.readLine()) != null)
-                System.out.println(inputLine);
-
-            System.out.println("Cipher Suite: " +
-                ((HttpsURLConnection)urlc).getCipherSuite());
-            Certificate[] certs =
-                ((HttpsURLConnection)urlc).getServerCertificates();
-            for (int i = 0; i < certs.length; i++) {
-                System.out.println(certs[0]);
+            /*
+             * Wait for server to get started.
+             */
+            while (!serverReady) {
+                Thread.sleep(50);
             }
 
-            in.close();
-        } catch (SSLException e) {
-            if (in != null)
+            HttpsURLConnection.setDefaultHostnameVerifier(new NameVerifier());
+            URL url = new URL("https://" + "localhost:" + serverPort +
+                                    "/etc/hosts");
+            URLConnection urlc = url.openConnection();
+
+            if (!(urlc instanceof javax.net.ssl.HttpsURLConnection)) {
+                throw new Exception("URLConnection ! instanceof " +
+                                    "javax.net.ssl.HttpsURLConnection");
+            }
+
+            BufferedReader in = null;
+            try {
+                in = new BufferedReader(new InputStreamReader(
+                                   urlc.getInputStream()));
+                String inputLine;
+                System.out.print("Client reading... ");
+                while ((inputLine = in.readLine()) != null)
+                    System.out.println(inputLine);
+
+                System.out.println("Cipher Suite: " +
+                    ((HttpsURLConnection)urlc).getCipherSuite());
+                Certificate[] certs =
+                    ((HttpsURLConnection)urlc).getServerCertificates();
+                for (int i = 0; i < certs.length; i++) {
+                    System.out.println(certs[0]);
+                }
+
                 in.close();
-            throw e;
+            } catch (SSLException e) {
+                if (in != null)
+                    in.close();
+                throw e;
+            }
+            System.out.println("Client reports:  SUCCESS");
+        } finally {
+            HttpsURLConnection.setDefaultHostnameVerifier(reservedHV);
         }
-        System.out.println("Client reports:  SUCCESS");
     }
 
     static class NameVerifier implements HostnameVerifier {
diff --git a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHostnameVerifier.java b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHostnameVerifier.java
index 343bfbe..b270973 100644
--- a/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHostnameVerifier.java
+++ b/jdk/test/sun/security/ssl/sun/net/www/protocol/https/NewImpl/JavaxHostnameVerifier.java
@@ -21,6 +21,11 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 4474255
@@ -28,6 +33,7 @@
  * @bug 4484246
  * @summary When an application enables anonymous SSL cipher suite,
  *        Hostname verification is not required
+ * @run main/othervm JavaxHostnameVerifier
  */
 
 import java.io.*;
diff --git a/jdk/test/sun/security/ssl/templates/SSLEngineTemplate.java b/jdk/test/sun/security/ssl/templates/SSLEngineTemplate.java
index 57ced15..f3c63cb 100644
--- a/jdk/test/sun/security/ssl/templates/SSLEngineTemplate.java
+++ b/jdk/test/sun/security/ssl/templates/SSLEngineTemplate.java
@@ -21,11 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 1234567
  * @summary SSLEngine has not yet caused Solaris kernel to panic
- *
+ * @run main/othervm SSLEngineTemplate
  */
 
 /**
diff --git a/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java b/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java
index 743c991..d0788d9 100644
--- a/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java
+++ b/jdk/test/sun/security/ssl/templates/SSLSocketTemplate.java
@@ -21,10 +21,16 @@
  * questions.
  */
 
+//
+// SunJSSE does not support dynamic system properties, no way to re-use
+// system properties in samevm/agentvm mode.
+//
+
 /*
  * @test
  * @bug 1234567
  * @summary Use this template to help speed your client/server tests.
+ * @run main/othervm SSLSocketTemplate
  * @author Brad Wetmore
  */
 
diff --git a/jdk/test/sun/security/tools/keytool/StartDateTest.java b/jdk/test/sun/security/tools/keytool/StartDateTest.java
index d68561e..bb64480 100644
--- a/jdk/test/sun/security/tools/keytool/StartDateTest.java
+++ b/jdk/test/sun/security/tools/keytool/StartDateTest.java
@@ -132,7 +132,9 @@
 
     static Date getIssueDate() throws Exception {
         KeyStore ks = KeyStore.getInstance("jks");
-        ks.load(new FileInputStream("jks"), "changeit".toCharArray());
+        try (FileInputStream fis = new FileInputStream("jks")) {
+            ks.load(fis, "changeit".toCharArray());
+        }
         X509Certificate cert = (X509Certificate)ks.getCertificate("me");
         return cert.getNotBefore();
     }
diff --git a/jdk/test/sun/security/util/Oid/S11N.sh b/jdk/test/sun/security/util/Oid/S11N.sh
index 6d3c30c..48a3711 100644
--- a/jdk/test/sun/security/util/Oid/S11N.sh
+++ b/jdk/test/sun/security/util/Oid/S11N.sh
@@ -71,7 +71,7 @@
       i[3-6]86 )
         PF="linux-i586"
         ;;
-      amd64* )
+      amd64* | x86_64 )
         PF="linux-amd64"
         ;;
       * )
@@ -97,15 +97,29 @@
     ;;
 esac
 
+echo "==================================================="
+echo "Try to set ALT_JAVA_RE_JDK if you see timeout error"
+echo "==================================================="
+
 # the test code
 
 ${TESTJAVA}${FS}bin${FS}javac -target 1.4 -source 1.4 \
         -d . ${TESTSRC}${FS}SerialTest.java || exit 10
 
+# You can set ALT_JAVA_RE_JDK to another location that contains the
+# binaries for older JDK releases. You can set it to a non-existent
+# directory to skip the interop tests between different versions.
+
+if [ "$ALT_JAVA_RE_JDK" = "" ]; then
+    JAVA_RE_JDK=/java/re/j2se
+else
+    JAVA_RE_JDK=$ALT_JAVA_RE_JDK
+fi
+
 OLDJAVA="
-    /java/re/j2se/1.6.0/latest/binaries/${PF}
-    /java/re/j2se/1.5.0/latest/binaries/${PF}
-    /java/re/j2se/1.4.2/latest/binaries/${PF}
+    $JAVA_RE_JDK/1.6.0/latest/binaries/${PF}
+    $JAVA_RE_JDK/1.5.0/latest/binaries/${PF}
+    $JAVA_RE_JDK/1.4.2/latest/binaries/${PF}
 "
 
 SMALL="
diff --git a/jdk/test/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java b/jdk/test/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java
index 747d090..b1ce9b7 100644
--- a/jdk/test/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java
+++ b/jdk/test/sun/security/x509/AlgorithmId/ExtensibleAlgorithmId.java
@@ -24,9 +24,12 @@
 /*
  * @test
  * @bug 4162868
+ * @run main/othervm ExtensibleAlgorithmId
  * @summary Algorithm Name-to-OID mapping needs to be made extensible.
  */
 
+// Run in othervm, coz AlgorithmId.oidTable is only initialized once
+
 import java.security.*;
 import sun.security.x509.AlgorithmId;
 
diff --git a/jdk/test/sun/text/resources/LocaleData b/jdk/test/sun/text/resources/LocaleData
index 00960071..eb715f0 100644
--- a/jdk/test/sun/text/resources/LocaleData
+++ b/jdk/test/sun/text/resources/LocaleData
@@ -656,7 +656,6 @@
 FormatData/es_UY/NumberElements/2=;
 CurrencyNames/es_VE/VEB=Bs
 # bug 6570259
-CurrencyNames/es_VE/VEF=BsF.
 FormatData/es_VE/NumberPatterns/0=#,##0.###;-#,##0.###
 # FormatData/es_VE/NumberPatterns/1=Bs#,##0.00;Bs -#,##0.00 # Changed; see bug 4122840
 FormatData/es_VE/NumberPatterns/2=#,##0%
@@ -7003,6 +7002,13 @@
 CurrencyNames/zh_CN/tmt=\u571f\u5e93\u66fc\u65af\u5766\u65b0\u9a6c\u7eb3\u7279
 CurrencyNames/zh_CN/zwl=\u6d25\u5df4\u5e03\u97e6\u5143 (2009)
 
+# bug 7189611
+CurrencyNames/es_VE/VEF=Bs.F.
 CurrencyNames/zh_TW/cuc=\u53e4\u5df4\u53ef\u8f49\u63db\u62ab\u7d22
 CurrencyNames/zh_TW/tmt=\u571f\u5eab\u66fc\u65b0\u99ac\u7d0d\u7279
 CurrencyNames/zh_TW/zwl=\u8f9b\u5df4\u5a01\u5143 (2009)
+
+# bug 7171028
+FormatData/sl/DateTimePatterns/4=EEEE, dd. MMMM y
+FormatData/sl/DateTimePatterns/5=dd. MMMM y
+
diff --git a/jdk/test/sun/text/resources/LocaleDataTest.java b/jdk/test/sun/text/resources/LocaleDataTest.java
index 6ec4236..c4c867b 100644
--- a/jdk/test/sun/text/resources/LocaleDataTest.java
+++ b/jdk/test/sun/text/resources/LocaleDataTest.java
@@ -33,7 +33,8 @@
  *      6379214 6485516 6486607 4225362 4494727 6533691 6531591 6531593 6570259
  *      6509039 6609737 6610748 6645271 6507067 6873931 6450945 6645268 6646611
  *      6645405 6650730 6910489 6573250 6870908 6585666 6716626 6914413 6916787
- *      6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203
+ *      6919624 6998391 7019267 7020960 7025837 7020583 7036905 7066203 7189611
+ *      7171028
  * @summary Verify locale data
  *
  */
diff --git a/jdk/test/sun/tools/jcmd/help_help.out b/jdk/test/sun/tools/jcmd/help_help.out
index e247468..beaf0f3 100644
--- a/jdk/test/sun/tools/jcmd/help_help.out
+++ b/jdk/test/sun/tools/jcmd/help_help.out
@@ -1,7 +1,7 @@
 help
 For more information about a specific command use 'help <command>'. With no argument this will show a list of available commands. 'help all' will show help for all commands.
 
-Impact: Low: 
+Impact: Low 
 
 Syntax : help [options] [<command name>]
 
diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java
deleted file mode 100644
index 0827766..0000000
--- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/**
- *
- *
- *  This isn't the test case: ImmutableResourceTest.sh is.
- *  Refer to ImmutableResourceTest.sh when running this test.
- *
- *  @bug        6287579
- *  @summary    SubClasses of ListResourceBundle should fix getContents()
- */
-import java.util.ResourceBundle;
-
-public class ImmutableResourceTest {
-
-    public static void main(String[] args) throws Exception {
-
-        /* Reach under the covers and get the message strings */
-        sun.tools.jconsole.resources.JConsoleResources jcr =
-            new sun.tools.jconsole.resources.JConsoleResources ();
-        Object [][] testData = jcr.getContents();
-
-        /* Shred our copy of the message strings */
-        for (int ii = 0; ii < testData.length; ii++) {
-            testData[ii][0] = "xxx";
-            testData[ii][1] = "yyy";
-        }
-
-        /*
-         * Try a lookup for the shredded key.
-         * If this is successful we have a problem.
-         */
-        String ss = sun.tools.jconsole.Resources.getText("xxx");
-        if ("yyy".equals(ss)) {
-            throw new Exception ("SubClasses of ListResourceBundle should fix getContents()");
-        }
-        System.out.println("...Finished.");
-    }
-}
diff --git a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh b/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh
deleted file mode 100644
index 414d02b..0000000
--- a/jdk/test/sun/tools/jconsole/ImmutableResourceTest.sh
+++ /dev/null
@@ -1,111 +0,0 @@
-#
-# Copyright (c) 2005, 2007, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-#   @test
-#   @bug        6287579
-#   @summary    SubClasses of ListResourceBundle should fix getContents()
-#
-#   @run shell ImmutableResourceTest.sh
-
-# Beginning of subroutines:
-status=1
-
-#Call this from anywhere to fail the test with an error message
-# usage: fail "reason why the test failed"
-fail()
- { echo "The test failed :-("
-   echo "$*" 1>&2
-   echo "exit status was $status"
-   exit $status
- } #end of fail()
-
-#Call this from anywhere to pass the test with a message
-# usage: pass "reason why the test passed if applicable"
-pass()
- { echo "The test passed!!!"
-   echo "$*" 1>&2
-   exit 0
- } #end of pass()
-
-# end of subroutines
-
-# The beginning of the script proper
-
-OS=`uname -s`
-case "$OS" in
-   SunOS | Linux | Darwin )
-      PATHSEP=":"
-      ;;
-
-   Windows* | CYGWIN*)
-      PATHSEP=";"
-      ;;
-
-   # catch all other OSs
-   * )
-      echo "Unrecognized system!  $OS"
-      fail "Unrecognized system!  $OS"
-      ;;
-esac
-
-TARGETCLASS="ImmutableResourceTest"
-if [ -z "${TESTJAVA}" ] ; then
-   # TESTJAVA is not set, so the test is running stand-alone.
-   # TESTJAVA holds the path to the root directory of the build of the JDK
-   # to be tested.  That is, any java files run explicitly in this shell
-   # should use TESTJAVA in the path to the java interpreter.
-   # So, we'll set this to the JDK spec'd on the command line.  If none
-   # is given on the command line, tell the user that and use a default.
-   # THIS IS THE JDK BEING TESTED.
-   if [ -n "$1" ] ; then
-          TESTJAVA=$1
-      else
-          TESTJAVA=$JAVA_HOME
-   fi
-   TESTSRC=.
-   TESTCLASSES=.
-   #Deal with .class files:
-fi
-#
-echo "JDK under test is: $TESTJAVA"
-#
-CP="-classpath ${TESTCLASSES}${PATHSEP}${TESTJAVA}/lib/jconsole.jar"
-# Compile the test class using the classpath we need:
-#
-env
-#
-set -vx
-#
-#Compile.  jconsole.jar is required on the classpath.
-${TESTJAVA}/bin/javac -d "${TESTCLASSES}" ${CP} -g \
-                         "${TESTSRC}"/"${TARGETCLASS}".java
-#
-#Run the test class, again with the classpath we need:
-${TESTJAVA}/bin/java ${CP} ${TARGETCLASS}
-status=$?
-echo "test status was: $status"
-if [ $status -eq "0" ];
-   then pass ""
-
-   else fail "unspecified test failure"
-fi
diff --git a/jdk/test/sun/tools/jinfo/Basic.sh b/jdk/test/sun/tools/jinfo/Basic.sh
index 9d5cb46..61a3003 100644
--- a/jdk/test/sun/tools/jinfo/Basic.sh
+++ b/jdk/test/sun/tools/jinfo/Basic.sh
@@ -44,7 +44,20 @@
 
 failed=0
 
-if [ $isWindows = false ]; then
+# Skip SA options for now, see 7175133
+runSA=false
+
+if [ $isLinux = true ]; then
+    # Some Linux systems disable non-child ptrace (see 7050524)
+    ptrace_scope=`/sbin/sysctl -n kernel.yama.ptrace_scope`
+    if [ $? = 0 ]; then
+        if [ $ptrace_scope = 1 ]; then
+            runSA=false
+        fi
+    fi
+fi
+
+if [ $runSA = true ]; then
     # -sysprops option
     ${JINFO} -J-XX:+UsePerfData -sysprops $appJavaPid
     if [ $? != 0 ]; then failed=1; fi
diff --git a/jdk/test/tools/jar/JarBackSlash.java b/jdk/test/tools/jar/JarBackSlash.java
new file mode 100644
index 0000000..4062913
--- /dev/null
+++ b/jdk/test/tools/jar/JarBackSlash.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2012 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug 7201156
+ * @summary jar tool fails to convert file separation characters for list and extract
+ * @author Sean Chou
+ */
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PipedInputStream;
+import java.io.PipedOutputStream;
+import java.io.PrintStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+
+import sun.tools.jar.Main;
+
+public class JarBackSlash {
+
+    // used construct an entry JarBackSlash/dir/file.txt
+    private static String JARBACKSLASH = "JarBackSlash";
+    private static String DIR = "dir";
+    private static String FILENAME = "file.txt";
+
+    private static File createJarFile() throws IOException {
+        File jarFile = File.createTempFile("JarBackSlashTest", ".jar");
+        jarFile.deleteOnExit();
+
+        try (JarOutputStream output = new JarOutputStream(new FileOutputStream(jarFile))) {
+            JarEntry entry = new JarEntry(JARBACKSLASH + "/" + DIR + "/" + FILENAME);
+            output.putNextEntry(entry);
+        }
+
+        return jarFile;
+    }
+
+    private static void testJarList(String jarFile) throws IOException {
+        List<String> argList = new ArrayList<String>();
+        argList.add("-tvf");
+        argList.add(jarFile);
+        argList.add(JARBACKSLASH + File.separatorChar + DIR + File.separatorChar + FILENAME);
+
+        String jarArgs[] = new String[argList.size()];
+        jarArgs = argList.toArray(jarArgs);
+
+        PipedOutputStream pipedOutput = new PipedOutputStream();
+        PipedInputStream pipedInput = new PipedInputStream(pipedOutput);
+        PrintStream out = new PrintStream(pipedOutput);
+
+        Main jarTool = new Main(out, System.err, "jar");
+        if (!jarTool.run(jarArgs)) {
+            fail("Could not list jar file.");
+        }
+
+        out.flush();
+        check(pipedInput.available() > 0);
+    }
+
+
+    private static void testJarExtract(String jarFile) throws IOException {
+        List<String> argList = new ArrayList<String>();
+        argList.add("-xvf");
+        argList.add(jarFile);
+        argList.add(JARBACKSLASH + File.separatorChar + DIR + File.separatorChar + FILENAME);
+
+        String jarArgs[] = new String[argList.size()];
+        jarArgs = argList.toArray(jarArgs);
+
+        PipedOutputStream pipedOutput = new PipedOutputStream();
+        PipedInputStream pipedInput = new PipedInputStream(pipedOutput);
+        PrintStream out = new PrintStream(pipedOutput);
+
+        Main jarTool = new Main(out, System.err, "jar");
+        if (!jarTool.run(jarArgs)) {
+            fail("Could not list jar file.");
+        }
+
+        out.flush();
+        check(pipedInput.available() > 0);
+    }
+
+    public static void realMain(String[] args) throws Throwable {
+        File tmpJarFile = createJarFile();
+        String tmpJarFilePath = tmpJarFile.getAbsolutePath();
+
+        testJarList(tmpJarFilePath);
+        testJarExtract(tmpJarFilePath);
+    }
+
+
+    //--------------------- Infrastructure ---------------------------
+    static volatile int passed = 0, failed = 0;
+    static void pass() {passed++;}
+    static void fail() {failed++; Thread.dumpStack();}
+    static void fail(String msg) {System.out.println(msg); fail();}
+    static void unexpected(Throwable t) {failed++; t.printStackTrace();}
+    static void check(boolean cond) {if (cond) pass(); else fail();}
+    static void equal(Object x, Object y) {
+        if (x == null ? y == null : x.equals(y)) pass();
+        else fail(x + " not equal to " + y);}
+    public static void main(String[] args) throws Throwable {
+        try {realMain(args);} catch (Throwable t) {unexpected(t);}
+        System.out.println("\nPassed = " + passed + " failed = " + failed);
+        if (failed > 0) throw new AssertionError("Some tests failed");}
+}
diff --git a/jdk/test/tools/launcher/Arrrghs.java b/jdk/test/tools/launcher/Arrrghs.java
index e93bd3e..503e448 100644
--- a/jdk/test/tools/launcher/Arrrghs.java
+++ b/jdk/test/tools/launcher/Arrrghs.java
@@ -24,7 +24,7 @@
 /**
  * @test
  * @bug 5030233 6214916 6356475 6571029 6684582 6742159 4459600 6758881 6753938
- *      6894719 6968053
+ *      6894719 6968053 7151434 7146424
  * @summary Argument parsing validation.
  * @compile -XDignore.symbol.file Arrrghs.java
  * @run main Arrrghs
@@ -573,6 +573,14 @@
         tr.isNotZeroOutput();
         if (!tr.testStatus)
             System.out.println(tr);
+
+        // 7151434, test for non-negative exit value for an incorrectly formed
+        // command line, '% java -jar -W', note the bogus -W
+        tr = doExec(javaCmd, "-jar", "-W");
+        tr.checkNegative();
+        tr.contains("Unrecognized option: -W");
+        if (!tr.testStatus)
+            System.out.println(tr);
     }
 
     /*
diff --git a/jdk/test/tools/launcher/TestHelper.java b/jdk/test/tools/launcher/TestHelper.java
index c799a13..0b2b720 100644
--- a/jdk/test/tools/launcher/TestHelper.java
+++ b/jdk/test/tools/launcher/TestHelper.java
@@ -189,13 +189,15 @@
                     m.invoke(this, (Object[]) null);
                     System.out.println(m.getName() + ": OK");
                     passed++;
+                    System.out.printf("Passed: %d, Failed: %d, ExitValue: %d%n",
+                                       passed, failed, testExitValue);
                 } catch (Throwable ex) {
                     System.out.printf("Test %s failed: %s %n", m, ex.getCause());
                     failed++;
                 }
             }
         }
-        System.out.printf("Passed: %d, Failed %d%n", passed, failed);
+        System.out.printf("Total: Passed: %d, Failed %d%n", passed, failed);
         if (failed > 0) {
             throw new RuntimeException("Tests failed: " + failed);
         }
@@ -456,6 +458,8 @@
         }
 
         void appendError(String x) {
+            testStatus = false;
+            testExitValue++;
             status.println(TEST_PREFIX + x);
         }
 
@@ -466,16 +470,12 @@
         void checkNegative() {
             if (exitValue == 0) {
                 appendError("test must not return 0 exit value");
-                testStatus = false;
-                testExitValue++;
             }
         }
 
         void checkPositive() {
             if (exitValue != 0) {
-                testStatus = false;
                 appendError("test did not return 0 exit value");
-                testExitValue++;
             }
         }
 
@@ -485,9 +485,7 @@
 
         boolean isZeroOutput() {
             if (!testOutput.isEmpty()) {
-                testStatus = false;
                 appendError("No message from cmd please");
-                testExitValue++;
                 return false;
             }
             return true;
@@ -495,9 +493,7 @@
 
         boolean isNotZeroOutput() {
             if (testOutput.isEmpty()) {
-                testStatus = false;
                 appendError("Missing message");
-                testExitValue++;
                 return false;
             }
             return true;
@@ -534,7 +530,6 @@
                 }
             }
             appendError("string <" + str + "> not found");
-            testExitValue++;
             return false;
         }
 
@@ -545,7 +540,6 @@
                 }
             }
             appendError("string <" + stringToMatch + "> not found");
-            testExitValue++;
             return false;
         }
     }
diff --git a/langtools/.hgtags b/langtools/.hgtags
index 9707171..23cbe92 100644
--- a/langtools/.hgtags
+++ b/langtools/.hgtags
@@ -199,6 +199,7 @@
 dd3e29d8892fcaba6d76431d5fa9d49e7c088f76 jdk7u6-b23
 6aac89e84fc96d15bb78b13aa71c9e6b73d7237e jdk7u6-b24
 bcd1d067d525065630deb98b678bc00b499adbe1 jdk7u6-b30
+2d6017454236d4e95aad7feaff5fc92a612598f4 jdk7u6-b31
 2d6017454236d4e95aad7feaff5fc92a612598f4 jdk7u7-b10
 27041587508dbc4e08c956ba98a11ce0d5608dc4 jdk7u7-b30
 b92a9f4f6bce4ec500ed3adb8203e6424b579f94 jdk7u7-b11
@@ -212,12 +213,19 @@
 0d4cb328938002fa9a2efc8190ea97beae3230a9 jdk7u9-b02
 9148cdb9a18b55ad7d51bb9644b6db812de34eea jdk7u9-b04
 1de4a0865a714076b4922a9a7119adb98aee23f2 jdk7u9-b05
-8dfbebb98865d822ddd9e0b9641d21e8bdb8a866 jdk7u10-b10
-01c6dde274bd520067264231b3015c37e8e62d24 jdk7u10-b11
-1fb02747d3bce646374c2cab95048c516cec6b01 jdk7u10-b12
-14735b3d8bdffc7892f1db04b6262bdaad2eb9d7 jdk7u10-b13
-f555fcdbd07156ee11b25fb4ac106065bbf496b4 jdk7u10-b14
-dfcd16ac3fbcabed815b8ef4e792716cce0bce21 jdk7u10-b15
-eaa8a0141c35edc382d7ce0b1148912db8422b16 jdk7u10-b16
-7101b3e80e96b000b0b4f0bd7fe4dd7910d02f74 jdk7u10-b17
-4f529e320d83f517a55065b4710c7f1e5ff692c9 jdk7u10-b18
+a35ca56cf8d09b92511f0cd71208a2ea05c8a338 jdk7u8-b01
+41bc8da868e58f7182d26b2ab9b6f8a4b09894ed jdk7u8-b02
+df5cbe436d3460af4667d416877e03400de54524 jdk7u8-b03
+d4296a07e45a0cffbca17c608916ff6bcec78d75 jdk7u8-b04
+1b7eaaffd58359639346661196309005a374192f jdk7u8-b05
+e1f380574f5490ef785282b81b6b38626109444b jdk7u10-b06
+cd18b83736af19afbccce4b7351c5a3c857356ac jdk7u10-b07
+3204f355a32d83ffceeed1c0c8a52a2d834ae29f jdk7u10-b08
+0b90d3480dbfc16aa3901df249b3cb21bcfa0b32 jdk7u10-b09
+87683444edad33cc9f4bbcd9008d98ba34350ded jdk7u12-b01
+12996c33d506d741ae7c3cc8e2aa2f650a36b839 jdk7u12-b02
+3fe61a8a2cfb02ee2b1cd4cd257b76c5b8668cd3 jdk7u12-b03
+e2adb6f53caaa618521bdf965bc484c7ffae190f jdk7u12-b04
+454ce2fa72e9ad14e83ebf54636c196d75e35509 jdk7u12-b05
+ab820babd394eed07c58bc2bffc58b0d92ca39b8 jdk7u12-b06
+382bab6d9682eefa2185a1643dfa32d65b6c20e5 jdk7u12-b07
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
index 38cf715..7985d93 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/formats/html/ConfigurationImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1998, 2012, 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
@@ -227,46 +227,44 @@
             String[] os = options[oi];
             String opt = os[0].toLowerCase();
             if (opt.equals("-footer")) {
-                footer =  os[1];
-            } else  if (opt.equals("-header")) {
-                header =  os[1];
-            } else  if (opt.equals("-packagesheader")) {
-                packagesheader =  os[1];
-            } else  if (opt.equals("-doctitle")) {
-                doctitle =  os[1];
-            } else  if (opt.equals("-windowtitle")) {
-                windowtitle =  os[1];
-            } else  if (opt.equals("-top")) {
-                top =  os[1];
-            } else  if (opt.equals("-bottom")) {
-                bottom =  os[1];
-            } else  if (opt.equals("-helpfile")) {
-                helpfile =  os[1];
-            } else  if (opt.equals("-stylesheetfile")) {
-                stylesheetfile =  os[1];
-            } else  if (opt.equals("-charset")) {
-                charset =  os[1];
+                footer = os[1];
+            } else if (opt.equals("-header")) {
+                header = os[1];
+            } else if (opt.equals("-packagesheader")) {
+                packagesheader = os[1];
+            } else if (opt.equals("-doctitle")) {
+                doctitle = os[1];
+            } else if (opt.equals("-windowtitle")) {
+                windowtitle = os[1];
+            } else if (opt.equals("-top")) {
+                top = os[1];
+            } else if (opt.equals("-bottom")) {
+                bottom = os[1];
+            } else if (opt.equals("-helpfile")) {
+                helpfile = os[1];
+            } else if (opt.equals("-stylesheetfile")) {
+                stylesheetfile = os[1];
+            } else if (opt.equals("-charset")) {
+                charset = os[1];
             } else if (opt.equals("-xdocrootparent")) {
                 docrootparent = os[1];
-            } else  if (opt.equals("-nohelp")) {
+            } else if (opt.equals("-nohelp")) {
                 nohelp = true;
-            } else  if (opt.equals("-splitindex")) {
+            } else if (opt.equals("-splitindex")) {
                 splitindex = true;
-            } else  if (opt.equals("-noindex")) {
+            } else if (opt.equals("-noindex")) {
                 createindex = false;
-            } else  if (opt.equals("-use")) {
+            } else if (opt.equals("-use")) {
                 classuse = true;
-            } else  if (opt.equals("-notree")) {
+            } else if (opt.equals("-notree")) {
                 createtree = false;
-            } else  if (opt.equals("-nodeprecatedlist")) {
+            } else if (opt.equals("-nodeprecatedlist")) {
                 nodeprecatedlist = true;
-            } else  if (opt.equals("-nosince")) {
-                nosince = true;
-            } else  if (opt.equals("-nonavbar")) {
+            } else if (opt.equals("-nonavbar")) {
                 nonavbar = true;
-            } else  if (opt.equals("-nooverview")) {
+            } else if (opt.equals("-nooverview")) {
                 nooverview = true;
-            } else  if (opt.equals("-overview")) {
+            } else if (opt.equals("-overview")) {
                 overview = true;
             }
         }
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
index 6d0196f..e140e93 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/Configuration.java
@@ -364,19 +364,21 @@
             if (opt.equals("-d")) {
                 destDirName = addTrailingFileSep(os[1]);
                 docFileDestDirName = destDirName;
-            } else  if (opt.equals("-docfilessubdirs")) {
+            } else if (opt.equals("-docfilessubdirs")) {
                 copydocfilesubdirs = true;
-            } else  if (opt.equals("-docencoding")) {
+            } else if (opt.equals("-docencoding")) {
                 docencoding = os[1];
-            } else  if (opt.equals("-encoding")) {
+            } else if (opt.equals("-encoding")) {
                 encoding = os[1];
-            } else  if (opt.equals("-author")) {
+            } else if (opt.equals("-author")) {
                 showauthor = true;
-            } else  if (opt.equals("-version")) {
+            } else if (opt.equals("-nosince")) {
+                nosince = true;
+            } else if (opt.equals("-version")) {
                 showversion = true;
-            } else  if (opt.equals("-nodeprecated")) {
+            } else if (opt.equals("-nodeprecated")) {
                 nodeprecated = true;
-            } else  if (opt.equals("-sourcepath")) {
+            } else if (opt.equals("-sourcepath")) {
                 sourcepath = os[1];
             } else if (opt.equals("-classpath") &&
                        sourcepath.length() == 0) {
@@ -400,17 +402,17 @@
                     message.warning("doclet.sourcetab_warning");
                     sourcetab = DocletConstants.DEFAULT_TAB_STOP_LENGTH;
                 }
-            } else  if (opt.equals("-notimestamp")) {
+            } else if (opt.equals("-notimestamp")) {
                 notimestamp = true;
-            } else  if (opt.equals("-nocomment")) {
+            } else if (opt.equals("-nocomment")) {
                 nocomment = true;
             } else if (opt.equals("-tag") || opt.equals("-taglet")) {
                 customTagStrs.add(os);
             } else if (opt.equals("-tagletpath")) {
                 tagletpath = os[1];
-            } else  if (opt.equals("-keywords")) {
+            } else if (opt.equals("-keywords")) {
                 keywords = true;
-            } else  if (opt.equals("-serialwarn")) {
+            } else if (opt.equals("-serialwarn")) {
                 serialwarn = true;
             } else if (opt.equals("-group")) {
                 group.checkPackageGroups(os[1], os[2]);
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java
index 842ee76..aa5a976 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/ExpertTaglet.java
@@ -1,6 +1,26 @@
 /*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
- * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
+ * Copyright (c) 2006, 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  */
 
 package com.sun.tools.doclets.internal.toolkit.taglets;
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
index 7e55d70..7f0599d 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/taglets/TagletManager.java
@@ -600,6 +600,7 @@
         ArrayList<Taglet> mTags = new ArrayList<Taglet>(customTags.size());
         ArrayList<Taglet> iTags = new ArrayList<Taglet>(customTags.size());
         ArrayList<Taglet> oTags = new ArrayList<Taglet>(customTags.size());
+        ArrayList<Taglet> sTags = new ArrayList<Taglet>();
         Taglet current;
         while (it.hasNext()) {
             current = it.next();
@@ -634,11 +635,12 @@
         inlineTags = iTags.toArray(new Taglet[] {});
 
         //Init the serialized form tags
-        serializedFormTags = new Taglet[4];
-        serializedFormTags[0] = customTags.get("serialData");
-        serializedFormTags[1] = customTags.get("throws");
-        serializedFormTags[2] = customTags.get("since");
-        serializedFormTags[3] = customTags.get("see");
+        sTags.add(customTags.get("serialData"));
+        sTags.add(customTags.get("throws"));
+        if (!nosince)
+            sTags.add(customTags.get("since"));
+        sTags.add(customTags.get("see"));
+        serializedFormTags = sTags.toArray(new Taglet[] {});
     }
 
     /**
diff --git a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
index 8386ff4..cbba5b8 100644
--- a/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
+++ b/langtools/src/share/classes/com/sun/tools/doclets/internal/toolkit/util/Util.java
@@ -372,7 +372,13 @@
                     while((n = in.read(buf))>0) out.write(buf,0,n);
                 } else {
                     BufferedReader reader = new BufferedReader(new InputStreamReader(in));
-                    BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out));
+                    BufferedWriter writer;
+                    if (configuration.docencoding == null) {
+                        writer = new BufferedWriter(new OutputStreamWriter(out));
+                    } else {
+                        writer = new BufferedWriter(new OutputStreamWriter(out,
+                            configuration.docencoding));
+                    }
                     try {
                         String line;
                         while ((line = reader.readLine()) != null) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
index 27fc8e8..a57c0aa 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/Types.java
@@ -1616,9 +1616,14 @@
      * type parameters in t are deleted.
      */
     public Type erasure(Type t) {
-        return erasure(t, false);
+        return eraseNotNeeded(t)? t : erasure(t, false);
     }
     //where
+    private boolean eraseNotNeeded(Type t) {
+        return (t.tag <= lastBaseTag) || (syms.stringType.tsym == t.tsym);
+    }
+
+    //where
     private Type erasure(Type t, boolean recurse) {
         if (t.tag <= lastBaseTag)
             return t; /* fast special case */
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
index eadca8e..1a48675 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Check.java
@@ -1649,13 +1649,15 @@
         for (Scope.Entry e1 = t1.tsym.members().elems; e1 != null; e1 = e1.sibling) {
             Symbol s1 = e1.sym;
             Type st1 = null;
-            if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types)) continue;
+            if (s1.kind != MTH || !s1.isInheritedIn(site.tsym, types) ||
+                    (s1.flags() & SYNTHETIC) != 0) continue;
             Symbol impl = ((MethodSymbol)s1).implementation(site.tsym, types, false);
             if (impl != null && (impl.flags() & ABSTRACT) == 0) continue;
             for (Scope.Entry e2 = t2.tsym.members().lookup(s1.name); e2.scope != null; e2 = e2.next()) {
                 Symbol s2 = e2.sym;
                 if (s1 == s2) continue;
-                if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types)) continue;
+                if (s2.kind != MTH || !s2.isInheritedIn(site.tsym, types) ||
+                        (s2.flags() & SYNTHETIC) != 0) continue;
                 if (st1 == null) st1 = types.memberType(t1, s1);
                 Type st2 = types.memberType(t2, s2);
                 if (types.overrideEquivalent(st1, st2)) {
diff --git a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
index 6c687fb..577aa1e 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Lower.java
@@ -3458,7 +3458,6 @@
                 JCExpression expression = oneCase.getExpression();
 
                 if (expression != null) { // expression for a "default" case is null
-                    expression = TreeInfo.skipParens(expression);
                     String labelExpr = (String) expression.type.constValue();
                     Integer mapping = caseLabelToPosition.put(labelExpr, casePosition);
                     Assert.checkNull(mapping);
diff --git a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
index c37a561..912be8b 100644
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java
@@ -247,7 +247,7 @@
             JCTry t = (JCTry) tree;
             return endPos((t.finalizer != null)
                           ? t.finalizer
-                          : t.catchers.last().body);
+                          : (t.catchers.isEmpty()? t.body : t.catchers.last().body));
         } else
             return tree.pos;
     }
diff --git a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java
index ebd1444..e1cf29c 100644
--- a/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java
+++ b/langtools/src/share/classes/com/sun/tools/javah/JavahTask.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2012, 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,7 @@
         List<String> opts = new ArrayList<String>();
         opts.add("-proc:only");
         opts.addAll(javac_extras);
-        CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, internalize(classes), null);
+        CompilationTask t = c.getTask(log, fileManager, diagnosticListener, opts, classes, null);
         JavahProcessor p = new JavahProcessor(g);
         t.setProcessors(Collections.singleton(p));
 
@@ -516,14 +516,6 @@
         return ok;
     }
 
-    private List<String> internalize(List<String> classes) {
-        List<String> l = new ArrayList<String>();
-        for (String c: classes) {
-            l.add(c.replace('$', '.'));
-        }
-        return l;
-    }
-
     private List<File> pathToFiles(String path) {
         List<File> files = new ArrayList<File>();
         for (String f: path.split(File.pathSeparator)) {
diff --git a/langtools/test/com/sun/javadoc/testDocEncoding/TestDocEncoding.java b/langtools/test/com/sun/javadoc/testDocEncoding/TestDocEncoding.java
new file mode 100644
index 0000000..e11976a
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testDocEncoding/TestDocEncoding.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (c) 2002, 2012, 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.
+ */
+
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
+
+/*
+ * @test
+ * @bug      8000743
+ * @summary  Run tests on -docencoding to see if the value is
+             used for stylesheet as well.
+ * @author   jayashree viswanathan
+ * @library  ../lib/
+ * @build    JavadocTester TestDocEncoding
+ * @run main TestDocEncoding
+ */
+
+public class TestDocEncoding extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "8000743";
+
+    //Javadoc arguments.
+    private static final String[] ARGS = new String[] {
+        "-d", BUG_ID, "-docencoding", "Cp930",
+        "-sourcepath", SRC_DIR, "pkg"
+    };
+
+    private static final String[][] TEST = NO_TEST;
+
+    private static final String[][] NEGATED_TEST = {
+        {BUG_ID + FS + "stylesheet.css",
+            "body {" + NL + "    background-color:#ffffff;"}
+    };
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestDocEncoding tester = new TestDocEncoding();
+        run(tester, ARGS, TEST, NEGATED_TEST);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
+
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/com/sun/javadoc/testDocEncoding/pkg/Test.java
similarity index 76%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/com/sun/javadoc/testDocEncoding/pkg/Test.java
index 077886f..134fda2 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/com/sun/javadoc/testDocEncoding/pkg/Test.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,13 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+/*
+ * Portions Copyright (c) 2012 IBM Corporation
+ */
 
-    public FileFormatException() {
-        super();
-    }
+package pkg;
 
-    public FileFormatException(String s) {
-        super(s);
-    }
-}
+public class Test {}
+
diff --git a/langtools/test/com/sun/javadoc/testSinceTag/TestSinceTag.java b/langtools/test/com/sun/javadoc/testSinceTag/TestSinceTag.java
new file mode 100644
index 0000000..c340431
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testSinceTag/TestSinceTag.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2012, 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      7180906
+ * @summary  Test to make sure that the since tag works correctly
+ * @author   Bhavesh Patel
+ * @library  ../lib/
+ * @build    JavadocTester TestSinceTag
+ * @run main TestSinceTag
+ */
+
+public class TestSinceTag extends JavadocTester {
+
+    //Test information.
+    private static final String BUG_ID = "7180906";
+
+    //Javadoc arguments.
+    private static final String[] ARGS1 = new String[] {
+        "-d", BUG_ID, "-sourcepath", SRC_DIR, "pkg1"
+    };
+
+    private static final String[] ARGS2 = new String[] {
+        "-d", BUG_ID, "-sourcepath", SRC_DIR, "-nosince", "pkg1"
+    };
+
+    //Input for string search tests.
+    private static final String[][] TEST = {
+        {BUG_ID + FS + "pkg1" + FS + "C1.html",
+            "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
+            "  <dd>JDK1.0</dd>"
+        },
+        {BUG_ID + FS + "serialized-form.html",
+            "<dl><dt><span class=\"strong\">Since:</span></dt>" + NL +
+            "  <dd>1.4</dd>"
+        }
+    };
+
+    /**
+     * The entry point of the test.
+     * @param args the array of command line arguments.
+     */
+    public static void main(String[] args) {
+        TestSinceTag tester = new TestSinceTag();
+        run(tester, ARGS1, TEST, NO_TEST);
+        run(tester, ARGS2, NO_TEST, TEST);
+        tester.printSummary();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugId() {
+        return BUG_ID;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    public String getBugName() {
+        return getClass().getName();
+    }
+}
diff --git a/langtools/test/com/sun/javadoc/testSinceTag/pkg1/C1.java b/langtools/test/com/sun/javadoc/testSinceTag/pkg1/C1.java
new file mode 100644
index 0000000..4fe46e5
--- /dev/null
+++ b/langtools/test/com/sun/javadoc/testSinceTag/pkg1/C1.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package pkg1;
+
+import java.io.IOException;
+import java.io.Serializable;
+
+/**
+ * A class comment for testing.
+ *
+ * @author      Bhavesh Patel
+ * @since       JDK1.0
+ */
+public class C1 implements Serializable {
+
+    /**
+     * This field indicates whether the C1 is undecorated.
+     *
+     * @see #setUndecorated(boolean)
+     * @since 1.4
+     * @serial
+     * @deprecated As of JDK version 1.5, replaced by
+     * {@link C1#setUndecorated(boolean) setUndecorated(boolean)}.
+     */
+    @Deprecated
+    public boolean undecorated = false;
+
+    /**
+     * This enum specifies the possible modal exclusion types.
+     *
+     * @since 1.6
+     */
+    public static enum ModalExclusionType {
+
+        /**
+         * No modal exclusion.
+         */
+        NO_EXCLUDE,
+        /**
+         * <code>APPLICATION_EXCLUDE</code> indicates that a top-level window
+         * won't be blocked by any application-modal dialogs. Also, it isn't
+         * blocked by document-modal dialogs from outside of its child hierarchy.
+         */
+        APPLICATION_EXCLUDE
+    };
+
+    /**
+     * Constructor.
+     *
+     * @param title the title
+     * @param test boolean value
+     * @exception IllegalArgumentException if the <code>owner</code>'s
+     *     <code>GraphicsConfiguration</code> is not from a screen device
+     * @exception HeadlessException
+     */
+    public C1(String title, boolean test) {
+    }
+
+    public C1(String title) {
+    }
+
+    /**
+     * Method comments.
+     * @param  undecorated <code>true</code> if no decorations are
+     *         to be enabled;
+     *         <code>false</code> if decorations are to be enabled.
+     * @see    #readObject()
+     * @since 1.4
+     */
+    public void setUndecorated(boolean undecorated) {
+        /* Make sure we don't run in the middle of peer creation.*/
+    }
+
+    /**
+     * @see #setUndecorated(boolean)
+     */
+    public void readObject() throws IOException {
+    }
+}
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/tools/javac/StringsInSwitch/7181320/BinOpInCaseLabel.java
similarity index 70%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/tools/javac/StringsInSwitch/7181320/BinOpInCaseLabel.java
index 077886f..f44c1d6 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/BinOpInCaseLabel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,20 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+/*
+ * @test
+ * @bug     7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile BinOpInCaseLabel.java
+ */
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
+public class BinOpInCaseLabel {
+    public static void main(String [] args) {
+        switch (args[0]) {
+            case "hello" + "world":
+                break;
+        }
     }
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/tools/javac/StringsInSwitch/7181320/CastInCaseLabel.java
similarity index 70%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/tools/javac/StringsInSwitch/7181320/CastInCaseLabel.java
index 077886f..2125d88 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/CastInCaseLabel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,20 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+/*
+ * @test
+ * @bug     7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile CastInCaseLabel.java
+ */
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
+public class CastInCaseLabel {
+    public static void main(String [] args) {
+        switch (args[0]) {
+            case (String)"hello":
+                break;
+        }
     }
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel.java
similarity index 67%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel.java
index 077886f..6049ec7 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,21 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+/*
+ * @test
+ * @bug     7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile CondExprInCaseLabel.java
+ */
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
+public class CondExprInCaseLabel {
+    public static void main(String [] args) {
+        final boolean cond = true;
+        switch (args[0]) {
+            case cond ? "hello" : "world":
+                break;
+        }
     }
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel1.java
similarity index 67%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel1.java
index 077886f..37b0292 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel1.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,21 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+/*
+ * @test
+ * @bug     7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile CondExprInCaseLabel1.java
+ */
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
+public class CondExprInCaseLabel1 {
+    public static void main(String [] args) {
+        final boolean cond = true;
+        switch (args[0]) {
+            case cond ? (String)"hello" : "world":
+                break;
+        }
     }
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel2.java
similarity index 67%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel2.java
index 077886f..b5ef26d 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/tools/javac/StringsInSwitch/7181320/CondExprInCaseLabel2.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,21 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+/*
+ * @test
+ * @bug     7181320
+ * @summary javac NullPointerException for switch labels with cast to String expressions
+ * @compile CondExprInCaseLabel2.java
+ */
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
+public class CondExprInCaseLabel2 {
+    public static void main(String [] args) {
+        final boolean cond = true;
+        switch (args[0]) {
+            case cond ? "hello" : (String)"world":
+                break;
+        }
     }
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/tools/javac/TryWithResources/T7178324.java
similarity index 64%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/tools/javac/TryWithResources/T7178324.java
index 077886f..0e2fc10 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/tools/javac/TryWithResources/T7178324.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,25 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+/*
+ * @test
+ * @bug 7178324
+ * @summary Crash when compiling for(i : x) try(AutoCloseable x = ...) {}
+ * @compile T7178324.java
+ */
 
-    public FileFormatException() {
-        super();
-    }
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.ArrayList;
+import java.util.List;
 
-    public FileFormatException(String s) {
-        super(s);
+class T7178324 {
+    public static void main(String[] args) throws Exception {
+        List<File> files = new ArrayList<>();
+        for (File f : files)
+            try (FileInputStream is = new FileInputStream(f)) {
+        }
     }
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/tools/javac/generics/8004094/B.java
similarity index 67%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/tools/javac/generics/8004094/B.java
index 077886f..735a7fd 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/tools/javac/generics/8004094/B.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,29 @@
  * 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.
- *
  */
+abstract class A {
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+    private static String s = null;
 
-    public FileFormatException() {
-        super();
+    static void test() {
+        new Object() {
+            void m() {
+                Object o = s;
+            }
+        };
     }
+}
 
-    public FileFormatException(String s) {
-        super(s);
+public abstract class B<T> extends A {
+
+    private static Integer i = null;
+
+    static void test() {
+        new Object() {
+            void m() {
+                Object o = i;
+            }
+        };
     }
 }
diff --git a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java b/langtools/test/tools/javac/generics/8004094/T8004094.java
similarity index 76%
copy from hotspot/src/share/tools/ProjectCreator/FileFormatException.java
copy to langtools/test/tools/javac/generics/8004094/T8004094.java
index 077886f..76c54d2 100644
--- a/hotspot/src/share/tools/ProjectCreator/FileFormatException.java
+++ b/langtools/test/tools/javac/generics/8004094/T8004094.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 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
@@ -19,17 +19,14 @@
  * 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.
- *
  */
 
-@SuppressWarnings("serial")
-public class FileFormatException extends Exception {
+/*
+ * @test
+ * @bug 8004094
+ * @summary Javac compiler error - synthetic method accessor generated with duplicate name
+ *
+ * @compile B.java T8004094.java
+ */
 
-    public FileFormatException() {
-        super();
-    }
-
-    public FileFormatException(String s) {
-        super(s);
-    }
-}
+public class T8004094 extends B<Object> { }
diff --git a/langtools/test/tools/javac/processing/6348499/T6348499.java b/langtools/test/tools/javac/processing/6348499/T6348499.java
index 25e2a07..d85a39d 100644
--- a/langtools/test/tools/javac/processing/6348499/T6348499.java
+++ b/langtools/test/tools/javac/processing/6348499/T6348499.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -47,6 +47,7 @@
     public static void main(String... args) {
         String testSrc = System.getProperty("test.src", ".");
         String testClasses = System.getProperty("test.classes");
+        String testClassPath = System.getProperty("test.class.path", testClasses);
         String A_java = new File(testSrc, "A.java").getPath();
         JavacTool tool = JavacTool.create();
         MyDiagListener dl = new MyDiagListener();
@@ -55,7 +56,7 @@
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java")));
         Iterable<String> opts = Arrays.asList("-proc:only",
                                               "-processor", "A",
-                                              "-processorpath", testClasses);
+                                              "-processorpath", testClassPath);
         StringWriter out = new StringWriter();
         JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
         task.call();
diff --git a/langtools/test/tools/javac/processing/6414633/T6414633.java b/langtools/test/tools/javac/processing/6414633/T6414633.java
index 0ae3951..06729a68 100644
--- a/langtools/test/tools/javac/processing/6414633/T6414633.java
+++ b/langtools/test/tools/javac/processing/6414633/T6414633.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -43,20 +43,20 @@
     public static void main(String... args) {
         String testSrc = System.getProperty("test.src", ".");
         String testClasses = System.getProperty("test.classes", ".");
+        String testClassPath = System.getProperty("test.class.path", testClasses);
 
         JavacTool tool = JavacTool.create();
         MyDiagListener dl = new MyDiagListener();
         StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
         try {
-            fm.setLocation(StandardLocation.CLASS_PATH, Arrays.asList(new File(testClasses)));
+            fm.setLocation(StandardLocation.CLASS_PATH, pathToFiles(testClassPath));
         } catch (IOException e) {
             throw new AssertionError(e);
         }
         Iterable<? extends JavaFileObject> files =
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java")));
         String[] opts = { "-proc:only",
-                          "-processor", A.class.getName(),
-                          "-classpath", testClasses + System.getProperty("path.separator") + "../../lib" };
+                          "-processor", A.class.getName() };
         JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files);
         task.call();
 
@@ -65,6 +65,15 @@
             throw new AssertionError(dl.diags + " diagnostics reported");
     }
 
+    private static List<File> pathToFiles(String path) {
+        List<File> list = new ArrayList<File>();
+        for (String s: path.split(File.pathSeparator)) {
+            if (!s.isEmpty())
+                list.add(new File(s));
+        }
+        return list;
+    }
+
     private static class MyDiagListener implements DiagnosticListener<JavaFileObject>
     {
         public void report(Diagnostic d) {
diff --git a/langtools/test/tools/javac/processing/6430209/T6430209.java b/langtools/test/tools/javac/processing/6430209/T6430209.java
index 0f65f86..0f7c259 100644
--- a/langtools/test/tools/javac/processing/6430209/T6430209.java
+++ b/langtools/test/tools/javac/processing/6430209/T6430209.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2012, 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
@@ -56,6 +56,7 @@
         // -proc:only -processor b6341534 -cp . ./src/*.java
         String testSrc = System.getProperty("test.src", ".");
         String testClasses = System.getProperty("test.classes") + System.getProperty("path.separator") + "../../lib";
+        String testClassPath = System.getProperty("test.class.path", testClasses);
         JavacTool tool = JavacTool.create();
         MyDiagListener dl = new MyDiagListener();
         StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
@@ -64,7 +65,7 @@
             new File(testSrc, "test0.java"), new File(testSrc, "test1.java")));
         Iterable<String> opts = Arrays.asList("-proc:only",
                                               "-processor", "b6341534",
-                                              "-processorpath", testClasses);
+                                              "-processorpath", testClassPath);
         StringWriter out = new StringWriter();
         JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
         task.call();
diff --git a/langtools/test/tools/javac/processing/T6920317.java b/langtools/test/tools/javac/processing/T6920317.java
index 1f005090..2308f62 100644
--- a/langtools/test/tools/javac/processing/T6920317.java
+++ b/langtools/test/tools/javac/processing/T6920317.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 2012, 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
@@ -156,7 +156,9 @@
         String expect = null;
 
         opts.add("-processorpath");
-        opts.add(System.getProperty("test.classes"));
+        String testClasses = System.getProperty("test.classes");
+        String testClassPath = System.getProperty("test.class.path", testClasses);
+        opts.add(testClassPath);
         opts.add("-processor");
         opts.add(Processor.class.getName());
         opts.add("-proc:only");
diff --git a/langtools/test/tools/javah/T7185778.java b/langtools/test/tools/javah/T7185778.java
new file mode 100644
index 0000000..0f45f2b
--- /dev/null
+++ b/langtools/test/tools/javah/T7185778.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2012, 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 7185778
+ * @summary javah error "Not a valid class name" on class names with dollar signs
+ *   The first two tests are on an inner class name whose name does not contain $.
+ *   The second two tests are on an inner class name whose name does contain $.
+ *   The last test is on an outer class whose name contains $.
+ * @run main T7185778 T7185778$inner
+ * @run main T7185778 T7185778.inner
+ * @run main T7185778 T7185778$inner$
+ * @run main T7185778 T7185778.inner$
+ * @run main T7185778 xx$yy
+ */
+
+public class T7185778 {
+    class inner {
+        native byte[] xxxxx(String name);
+    }
+    class inner$ {
+        native byte[] xxxxx(String name);
+    }
+
+    static public void main(String[] args) {
+        int rc = com.sun.tools.javah.Main.run(args, null);
+        if ( rc != 0) {
+            throw new Error("javah returned non zero: " + rc);
+        }
+    }
+}
+
+class xx$yy {
+    native byte[] xxxxx(String name);
+}
diff --git a/make/jprt.properties b/make/jprt.properties
index 633108a..2dad7bc 100644
--- a/make/jprt.properties
+++ b/make/jprt.properties
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2012, 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
@@ -79,20 +79,17 @@
     ${jprt.my.test.target.set:TESTNAME=jdk_util},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_io},			\
     ${jprt.my.test.target.set:TESTNAME=jdk_net},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_nio1},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_nio2},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_nio3},		\
+    ${jprt.my.test.target.set:TESTNAME=jdk_nio},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_security1},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_security2},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_security3},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_rmi},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_management1},	\
-    ${jprt.my.test.target.set:TESTNAME=jdk_management2},	\
+    ${jprt.my.test.target.set:TESTNAME=jdk_management},	\
+    ${jprt.my.test.target.set:TESTNAME=jdk_jmx},	\
     ${jprt.my.test.target.set:TESTNAME=jdk_text},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_tools1},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_tools2},		\
+    ${jprt.my.test.target.set:TESTNAME=jdk_tools},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_jfr},		\
-    ${jprt.my.test.target.set:TESTNAME=jdk_misc}
+    ${jprt.my.test.target.set:TESTNAME=jdk_other}
 
 # All vm test targets (testset=all)
 jprt.vm.all.test.targets=    					\
@@ -107,6 +104,7 @@
     ${jprt.my.test.target.set:TESTNAME=jdk_beans1}		\
     ${jprt.my.test.target.set:TESTNAME=jdk_beans2},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_beans3},		\
+    ${jprt.my.test.target.set:TESTNAME=jdk_jdi},		\
     ${jprt.my.test.target.set:TESTNAME=jdk_sound},              \
     ${jprt.my.test.target.set:TESTNAME=jdk_swing}
 
diff --git a/make/scripts/hgforest.sh b/make/scripts/hgforest.sh
index 7834826..ed937f3 100644
--- a/make/scripts/hgforest.sh
+++ b/make/scripts/hgforest.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2009, 2012, 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
@@ -24,6 +24,8 @@
 #
 
 # Shell script for a fast parallel forest command
+command="$1"
+pull_extra_base="$2"
 
 tmp=/tmp/forest.$$
 rm -f -r ${tmp}
@@ -35,40 +37,58 @@
 
 # Only look in specific locations for possible forests (avoids long searches)
 pull_default=""
-if [ "$1" = "clone" -o "$1" = "fclone" ] ; then
+repos=""
+repos_extra=""
+if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
   subrepos="corba jaxp jaxws langtools jdk hotspot"
   if [ -f .hg/hgrc ] ; then
     pull_default=`hg paths default`
+    if [ "${pull_default}" = "" ] ; then
+      echo "ERROR: Need initial clone with 'hg paths default' defined"
+      exit 1
+    fi
   fi
   if [ "${pull_default}" = "" ] ; then
-    echo "ERROR: Need initial clone with 'hg paths default' defined"
+    echo "ERROR: Need initial repository to use this script"
     exit 1
   fi
-  repos=""
   for i in ${subrepos} ; do
     if [ ! -f ${i}/.hg/hgrc ] ; then
       repos="${repos} ${i}"
     fi
   done
+  if [ "${pull_extra_base}" != "" ] ; then
+    subrepos_extra="jdk/src/closed jdk/make/closed jdk/test/closed hotspot/make/closed hotspot/src/closed hotspot/test/closed deploy install sponsors pubs"
+    pull_default_tail=`echo ${pull_default} | sed -e 's@^.*://[^/]*/\(.*\)@\1@'`
+    pull_extra="${pull_extra_base}/${pull_default_tail}"
+    for i in ${subrepos_extra} ; do
+      if [ ! -f ${i}/.hg/hgrc ] ; then
+        repos_extra="${repos_extra} ${i}"
+      fi
+    done
+  fi
   at_a_time=2
+  # Any repos to deal with?
+  if [ "${repos}" = "" -a "${repos_extra}" = "" ] ; then
+    echo "No repositories to clone."
+    exit
+  fi
 else
   hgdirs=`ls -d ./.hg ./*/.hg ./*/*/.hg ./*/*/*/.hg ./*/*/*/*/.hg 2>/dev/null`
   # Derive repository names from the .hg directory locations
-  repos=""
   for i in ${hgdirs} ; do
     repos="${repos} `echo ${i} | sed -e 's@/.hg$@@'`"
   done
   at_a_time=8
+  # Any repos to deal with?
+  if [ "${repos}" = "" ] ; then
+    echo "No repositories to process."
+    exit
+  fi
 fi
 
-# Any repos to deal with?
-if [ "${repos}" = "" ] ; then
-  echo "No repositories to process."
-  exit
-fi
-
-# Echo out what repositories we will process
-echo "# Repos: ${repos}"
+# Echo out what repositories we will clone
+echo "# Repos: ${repos} ${repos_extra}"
 
 # Run the supplied command on all repos in parallel, save output until end
 n=0
@@ -77,8 +97,9 @@
   n=`expr ${n} '+' 1`
   (
     (
-      if [ "$1" = "clone" -o "$1" = "fclone" ] ; then
-        cline="hg $* ${pull_default}/${i} ${i}"
+      if [ "${command}" = "clone" -o "${command}" = "fclone" ] ; then
+        pull_newrepo="`echo ${pull_default}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
+        cline="hg clone ${pull_newrepo} ${i}"
         echo "# ${cline}"
         ( eval "${cline}" )
       else
@@ -92,10 +113,29 @@
     sleep 5
   fi
 done
-
 # Wait for all hg commands to complete
 wait
 
+if [ "${repos_extra}" != "" ] ; then
+  for i in ${repos_extra} ; do
+    echo "Starting on ${i}"
+    n=`expr ${n} '+' 1`
+    (
+      (
+          pull_newextrarepo="`echo ${pull_extra}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
+          cline="hg clone ${pull_newextrarepo} ${i}"
+          echo "# ${cline}"
+          ( eval "${cline}" )
+        echo "# exit code $?"
+      ) > ${tmp}/repo.${n} 2>&1 ; cat ${tmp}/repo.${n} ) &
+    if [ `expr ${n} '%' ${at_a_time}` -eq 0 ] ; then
+      sleep 5
+    fi
+  done
+  # Wait for all hg commands to complete
+  wait
+fi
+
 # Cleanup
 rm -f -r ${tmp}
 
diff --git a/make/scripts/normalizer.pl b/make/scripts/normalizer.pl
new file mode 100644
index 0000000..184248a
--- /dev/null
+++ b/make/scripts/normalizer.pl
@@ -0,0 +1,208 @@
+#!/usr/bin/perl
+
+#
+# Copyright (c) 2009, 2012, 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.
+#
+
+#
+# Parses java files:
+#   1. Removes from the end of lines spaces and TABs
+#   2. Replaces TABs by spaces
+#   3. Replaces all NewLine separators by Unix NewLine separators
+#   4. Makes one and only one empty line at the end of each file
+
+if ($#ARGV < 0) {
+    &usage;
+    
+    die;
+}
+
+use Cwd 'abs_path';
+
+my @extensions = ("java");
+
+# Read options
+my $dirpos = 0;
+
+while ($dirpos < $#ARGV) {
+    if ($ARGV[$dirpos] eq "-e") {
+        @extensions = split(/,/, $ARGV[$dirpos + 1]);
+    } else {
+        last;
+    }
+
+    $dirpos += 2;
+}
+
+if ($dirpos > $#ARGV) {
+    &usage;
+
+    die;
+}
+
+use Cwd;
+my $currdir = getcwd;
+
+my $allfiles = 0;
+
+my $filecount = 0;
+
+my @tabvalues;
+
+# Init tabvalues
+push (@tabvalues, " ");
+
+for (my $i = 1; $i < 8; $i++) {
+    push(@tabvalues, $tabvalues[$i - 1] . " ");
+}
+
+open(FILELIST, ">$currdir/filelist") or die "Failed while open $currdir/filelist: $!\n";
+
+while ($dirpos <= $#ARGV) {
+    use File::Find;
+
+    find(\&parse_file, abs_path($ARGV[$dirpos]));
+
+    $dirpos += 1;
+}
+
+close(FILELIST);
+
+use Cwd 'chdir';
+chdir $currdir;
+
+print "Checked $allfiles file(s)\n";
+print "Modified $filecount file(s)\n";
+print "See results in the file $currdir/filelist\n";
+
+sub parse_file {
+    my $filename = $File::Find::name;
+
+    # Skip directories
+    return if -d;
+    
+    # Skip SCCS files
+    return if ($filename =~ /\/SCCS\//);
+
+    # Skip files with invalid extensions
+    my $accepted = 0;
+    foreach my $ext (@extensions) {
+        if ($_ =~ /\.$ext$/i) {
+            $accepted = 1;
+
+            last;
+        }
+    }
+    return if ($accepted == 0);
+
+    use File::Basename;
+    my $dirname = dirname($filename);
+
+    use Cwd 'chdir';
+    chdir $dirname;
+
+    open(FILE, $filename) or die "Failed while open $filename: $!\n";
+    
+    # Read file
+    my @content;
+    my $line;
+    my $emptylinescount = 0;
+    my $modified = 0;
+    
+    while ($line = <FILE>) {
+        my $originalline = $line;
+
+        # Process line
+        
+        # Remove from the end of the line spaces and return character
+        while ($line =~ /\s$/) {
+            chop($line);
+        }
+
+        # Replace TABs
+        for (my $i = 0; $i < length($line); $i++) {
+            if (substr($line, $i, 1) =~ /\t/) {
+                $line = substr($line, 0, $i) . $tabvalues[7 - ($i % 8)] . substr($line, $i + 1);
+            }
+        }
+        
+        if (length($line) == 0) {
+            $emptylinescount++;
+        } else {
+            while ($emptylinescount > 0) {
+                push(@content, "");
+                
+                $emptylinescount--;
+            }
+            
+            push(@content, $line);
+        }
+
+        if ($originalline ne ($line . "\n")) {
+            $modified = 1;
+        }
+
+    }
+    
+    $allfiles++;
+    
+    if ($emptylinescount > 0) {
+        $modified = 1;
+    }
+
+    close(FILE);
+    
+    if ($modified != 0) {
+        # Write file
+        open(FILE, ">$filename") or die "Failed while open $filename: $!\n";
+    
+        for (my $i = 0; $i <= $#content; $i++) {
+            print FILE "$content[$i]\n";
+        }
+    
+        close(FILE);
+
+        # Print name from current dir
+        if (index($filename, $currdir) == 0) {
+           print FILELIST substr($filename, length($currdir) + 1);
+        } else {
+           print FILELIST $filename;
+        }
+        print FILELIST "\n";
+
+        $filecount++;
+
+        print "$filename: modified\n";
+    }
+}
+
+sub usage {
+    print "Usage:\n";
+    print "  normalizer.pl [-options] <dir> [dir2 dir3 ...]\n";
+    print "  Available options:\n";
+    print "    -e    comma separated files extensions. By default accepts only java files\n";
+    print "\n";
+    print "Examples:\n";
+    print "  normalizer.pl -e c,cpp,h,hpp .\n";
+}
+
+
diff --git a/test/Makefile b/test/Makefile
index 0cdfc35..ddbd079 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,5 +1,5 @@
 #
-# Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2010, 2012, 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
@@ -57,15 +57,17 @@
 	jdk_beans1 jdk_beans2 jdk_beans3  \
 	jdk_io  \
 	jdk_lang  \
-	jdk_management1 jdk_management2  \
+	jdk_management \
+	jdk_jmx \
 	jdk_math  \
-	jdk_misc  \
+	jdk_other  \
 	jdk_net  \
-	jdk_nio1 jdk_nio2 jdk_nio3  \
+	jdk_nio \
 	jdk_security1 jdk_security2 jdk_security3  \
 	jdk_sound  \
 	jdk_text  \
-	jdk_tools1 jdk_tools2  \
+	jdk_tools \
+	jdk_jdi \
 	jdk_jfr \
 	jdk_util